diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index e8842e81f24..d11cc95810b 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -27,7 +27,7 @@ if (Datum.is_processing) {\ PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occured on [#Processor]."); \ }\ } else {\ - Datum.is_processing = #Processor;\ + Datum.is_processing = Processor._internal_name;\ Processor.processing += Datum;\ } @@ -125,6 +125,9 @@ if(Datum.is_processing) {\ NEW_SS_GLOBAL(SS##X);\ PreInit();\ }\ +/datum/controller/subsystem/##X{\ + _internal_name = "SS" + #X;\ +}\ /datum/controller/subsystem/##X #define PROCESSING_SUBSYSTEM_DEF(X) var/global/datum/controller/subsystem/processing/##X/SS##X;\ @@ -137,4 +140,5 @@ if(Datum.is_processing) {\ processing = SS##X.processing; \ }\ }\ -/datum/controller/subsystem/processing/##X +/datum/controller/subsystem/processing/##X/_internal_name = "SS" + #X;\ +/datum/controller/subsystem/processing/##X \ No newline at end of file diff --git a/code/__defines/ZAS.dm b/code/__defines/ZAS.dm index 166e23560b9..9564643bee1 100644 --- a/code/__defines/ZAS.dm +++ b/code/__defines/ZAS.dm @@ -40,12 +40,28 @@ #define TURF_HAS_VALID_ZONE(T) (isturf(T) && T:zone && !T:zone:invalid) #define SHOULD_PARTICIPATE_IN_ZONES(T) (isturf(T) && T:zone_membership_candidate && (!T:external_atmosphere_participation || !T:is_outside())) +#define ATMOS_CANPASS_MOVABLE(ret, AM, TARG_TURF) \ + switch (AM.atmos_canpass) { \ + if (CANPASS_ALWAYS) { } \ + if (CANPASS_DENSITY) { \ + if (AM.density) { \ + ret |= AIR_BLOCKED; \ + } \ + } \ + if (CANPASS_PROC) { \ + ret |= (AIR_BLOCKED * !AM.CanPass(null, TARG_TURF, 0, 0)) | (ZONE_BLOCKED * !AM.CanPass(null, TARG_TURF, 1.5, 1)); \ + } \ + if (CANPASS_NEVER) { \ + ret = BLOCKED; \ + } \ + } + #ifdef MULTIZAS var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTHUP, EASTUP, WESTUP, SOUTHUP, NORTHDOWN, EASTDOWN, WESTDOWN, SOUTHDOWN) var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN) -#define ATMOS_CANPASS_TURF(ret,A,B) \ +#define ATMOS_CANPASS_TURF(ret, A, B) \ if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \ ret = BLOCKED; \ } \ @@ -64,22 +80,7 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN) ret = 0;\ for (var/thing in A) { \ var/atom/movable/AM = thing; \ - switch (AM.atmos_canpass) { \ - if (CANPASS_ALWAYS) { \ - continue; \ - } \ - if (CANPASS_DENSITY) { \ - if (AM.density) { \ - ret |= AIR_BLOCKED; \ - } \ - } \ - if (CANPASS_PROC) { \ - ret |= (AIR_BLOCKED * !AM.CanPass(null, B, 0, 0)) | (ZONE_BLOCKED * !AM.CanPass(null, B, 1.5, 1)); \ - } \ - if (CANPASS_NEVER) { \ - ret = BLOCKED; \ - } \ - } \ + ATMOS_CANPASS_MOVABLE(ret, AM, B); \ if (ret == BLOCKED) { \ break;\ }\ @@ -90,7 +91,7 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST, UP, DOWN) var/global/list/csrfz_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST) -#define ATMOS_CANPASS_TURF(ret,A,B) \ +#define ATMOS_CANPASS_TURF(ret, A, B) \ if (A.blocks_air & AIR_BLOCKED || B.blocks_air & AIR_BLOCKED) { \ ret = BLOCKED; \ } \ @@ -101,22 +102,7 @@ var/global/list/gzn_check = list(NORTH, SOUTH, EAST, WEST) ret = 0;\ for (var/thing in A) { \ var/atom/movable/AM = thing; \ - switch (AM.atmos_canpass) { \ - if (CANPASS_ALWAYS) { \ - continue; \ - } \ - if (CANPASS_DENSITY) { \ - if (AM.density) { \ - ret |= AIR_BLOCKED; \ - } \ - } \ - if (CANPASS_PROC) { \ - ret |= (AIR_BLOCKED * !AM.CanPass(null, B, 0, 0)) | (ZONE_BLOCKED * !AM.CanPass(null, B, 1.5, 1)); \ - } \ - if (CANPASS_NEVER) { \ - ret = BLOCKED; \ - } \ - } \ + ATMOS_CANPASS_MOVABLE(ret, AM, B); \ if (ret == BLOCKED) { \ break;\ }\ diff --git a/code/__defines/_byond_version_compat.dm b/code/__defines/_byond_version_compat.dm new file mode 100644 index 00000000000..72ad8942ae7 --- /dev/null +++ b/code/__defines/_byond_version_compat.dm @@ -0,0 +1,47 @@ +#define REQUIRED_DM_VERSION 514 + +#if DM_VERSION < REQUIRED_DM_VERSION +#warn Nebula is not tested on BYOND versions older than 514. The code may not compile, and if it does compile it may have severe problems. +#endif + +// 515 split call for external libraries into call_ext +#if DM_VERSION < 515 +#define LIBCALL call +#else +#define LIBCALL call_ext +#endif + +// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof() +// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global. + +#if DM_VERSION < 515 + +/// Call by name proc references, checks if the proc exists on either this type or as a global proc. +#define PROC_REF(X) (.proc/##X) +/// Call by name verb references, checks if the verb exists on either this type or as a global verb. +#define VERB_REF(X) (.verb/##X) + +/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc +#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X) +/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb +#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X) + +/// Call by name proc reference, checks if the proc is an existing global proc +#define GLOBAL_PROC_REF(X) (/proc/##X) + +#else + +/// Call by name proc references, checks if the proc exists on either this type or as a global proc. +#define PROC_REF(X) (nameof(.proc/##X)) +/// Call by name verb references, checks if the verb exists on either this type or as a global verb. +#define VERB_REF(X) (nameof(.verb/##X)) + +/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc +#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X)) +/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb +#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X)) + +/// Call by name proc reference, checks if the proc is an existing global proc +#define GLOBAL_PROC_REF(X) (/proc/##X) + +#endif \ No newline at end of file diff --git a/code/__defines/_compile_options.dm b/code/__defines/_compile_options.dm index a4788ec0da6..d2f61e13dca 100644 --- a/code/__defines/_compile_options.dm +++ b/code/__defines/_compile_options.dm @@ -1,9 +1,3 @@ // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary. // 1 will enable set background. 0 will disable set background. #define BACKGROUND_ENABLED 0 - -#define REQUIRED_DM_VERSION 514 - -#if DM_VERSION < REQUIRED_DM_VERSION -#warn Nebula is not tested on BYOND versions older than 514. The code may not compile, and if it does compile it may have severe problems. -#endif diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 3d24c1a3306..b21714df2f1 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -61,10 +61,12 @@ #define MAT_SOLVENT_MILD 1 #define MAT_SOLVENT_MODERATE 2 #define MAT_SOLVENT_STRONG 3 +#define MAT_SOLVENT_IMMUNE INFINITY -#define DIRTINESS_STERILE -2 -#define DIRTINESS_CLEAN -1 -#define DIRTINESS_NEUTRAL 0 +#define DIRTINESS_DECONTAMINATE -3 +#define DIRTINESS_STERILE -2 +#define DIRTINESS_CLEAN -1 +#define DIRTINESS_NEUTRAL 0 #define DEFAULT_GAS_ACCELERANT /decl/material/gas/hydrogen #define DEFAULT_GAS_OXIDIZER /decl/material/gas/oxygen diff --git a/code/__defines/colors.dm b/code/__defines/colors.dm index 6d7dc906014..599cbbe26a8 100644 --- a/code/__defines/colors.dm +++ b/code/__defines/colors.dm @@ -39,6 +39,7 @@ #define COLOR_GREEN_GRAY "#8daf6a" #define COLOR_DARK_GREEN_GRAY "#54654c" #define COLOR_BLUE_GRAY "#6a97b0" +#define COLOR_MID_BLUE_GRAY "#666699" #define COLOR_DARK_BLUE_GRAY "#3e4855" #define COLOR_SURGERY_BLUE "#e0f2f6" #define COLOR_SUN "#ec8b2f" @@ -92,6 +93,12 @@ #define COLOR_CRYSTAL "#00c8a5" #define COLOR_ASTEROID_ROCK "#735555" #define COLOR_DIAMOND "#d8d4ea" +#define COLOR_BLOOD_RED "#990000" +#define COLOR_PALE_GOLD "#cc9900" +#define COLOR_ROYAL_BLUE "#0033ff" +#define COLOR_VERDANT_GREEN "#287d00" +#define COLOR_SCIENCE_PURPLE "#6633cc" + #define PIPE_COLOR_GREY "#808080" #define PIPE_COLOR_RED "#ff0000" diff --git a/code/__defines/fluids.dm b/code/__defines/fluids.dm index 6cbd4a3da36..af7851add91 100644 --- a/code/__defines/fluids.dm +++ b/code/__defines/fluids.dm @@ -6,31 +6,45 @@ #define FLUID_DEEP 800 // Depth deep icon is used #define FLUID_MAX_DEPTH FLUID_DEEP*4 // Arbitrary max value for flooding. #define FLUID_PUSH_THRESHOLD 20 // Amount of flow needed to push items. +/turf + var/_fluid_source_is_active = FALSE + var/_fluid_turf_is_active = FALSE -// Expects /turf for T. -#define ADD_ACTIVE_FLUID_SOURCE(T) if(!T.changing_turf) { SSfluids.water_sources[T] = TRUE; } -#define REMOVE_ACTIVE_FLUID_SOURCE(T) SSfluids.water_sources -= T +// Expects /turf for TURF. +#define ADD_ACTIVE_FLUID_SOURCE(TURF) \ +if(!QDELETED(TURF) && !TURF.changing_turf && !TURF._fluid_source_is_active) { \ + TURF._fluid_source_is_active = TRUE; \ + SSfluids.water_sources += TURF; \ +} -// Expects /obj/effect/fluid for F. -#define ADD_ACTIVE_FLUID(F) if(!QDELETED(F)) { SSfluids.active_fluids[F] = TRUE; } -#define REMOVE_ACTIVE_FLUID(F) SSfluids.active_fluids -= F +#define REMOVE_ACTIVE_FLUID_SOURCE(TURF) \ +if(!QDELETED(TURF) && TURF._fluid_source_is_active) { \ + TURF._fluid_source_is_active = FALSE; \ + SSfluids.water_sources -= TURF; \ +} -// Expects turf for T, -#define UPDATE_FLUID_BLOCKED_DIRS(T) \ - if(isnull(T.fluid_blocked_dirs)) {\ - T.fluid_blocked_dirs = 0; \ - for(var/obj/structure/window/W in T) { \ - if(W.density) T.fluid_blocked_dirs |= W.dir; \ - } \ - for(var/obj/machinery/door/window/D in T) {\ - if(D.density) T.fluid_blocked_dirs |= D.dir; \ - } \ - } +#define ADD_ACTIVE_FLUID(TURF) \ +if(!QDELETED(TURF) && !TURF._fluid_turf_is_active) { \ + TURF._fluid_turf_is_active = TRUE; \ + SSfluids.active_fluids += TURF; \ +} -// We share overlays for all fluid turfs to sync icon animation. -#define APPLY_FLUID_OVERLAY(img_state) \ - if(!SSfluids.fluid_images[img_state]) SSfluids.fluid_images[img_state] = image('icons/effects/liquids.dmi',img_state); \ - add_overlay(SSfluids.fluid_images[img_state]); +#define REMOVE_ACTIVE_FLUID(TURF) \ +if(!QDELETED(TURF) && TURF._fluid_turf_is_active) { \ + TURF._fluid_turf_is_active = FALSE; \ + SSfluids.active_fluids -= TURF; \ +} + +#define UPDATE_FLUID_BLOCKED_DIRS(TURF) \ +if(isnull(TURF.fluid_blocked_dirs)) { \ + TURF.fluid_blocked_dirs = 0; \ + for(var/obj/structure/window/W in TURF) { \ + if(W.density) TURF.fluid_blocked_dirs |= W.dir; \ + } \ + for(var/obj/machinery/door/window/D in TURF) { \ + if(D.density) TURF.fluid_blocked_dirs |= D.dir; \ + } \ +} #define FLUID_MAX_ALPHA 200 #define FLUID_MIN_ALPHA 96 diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index 779c0e6fd1a..25f2ed8c213 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -157,10 +157,10 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define MCS_BLOCK 2 // Failed to change, but action was performed #define FABRICATOR_EXTRA_COST_FACTOR 1.25 -#define FAB_HACKED 1 -#define FAB_DISABLED 2 -#define FAB_SHOCKED 4 -#define FAB_BUSY 8 +#define FAB_HACKED BITFLAG(0) +#define FAB_DISABLED BITFLAG(1) +#define FAB_SHOCKED BITFLAG(2) +#define FAB_BUSY BITFLAG(3) #define PART_CPU /obj/item/stock_parts/computer/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once. #define PART_NETWORK /obj/item/stock_parts/computer/network_card // Network Card component of this computer. Allows connection to network diff --git a/code/__defines/mapping.dm b/code/__defines/mapping.dm index 47b24b30658..c5ad65832e3 100644 --- a/code/__defines/mapping.dm +++ b/code/__defines/mapping.dm @@ -33,9 +33,10 @@ if(other_init) { \ #define ADJUST_TAG_VAR(variable, map_hash) (istext(variable) && (variable += map_hash)) /// Map template categories for mass retrieval. -#define MAP_TEMPLATE_CATEGORY_EXOPLANET "exoplanet_template" -#define MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE "exoplanet_site_template" -#define MAP_TEMPLATE_CATEGORY_PLANET "planet_template" -#define MAP_TEMPLATE_CATEGORY_PLANET_SITE "planet_site_template" -#define MAP_TEMPLATE_CATEGORY_SPACE "space_template" -#define MAP_TEMPLATE_CATEGORY_AWAYSITE "awaysite_template" +#define MAP_TEMPLATE_CATEGORY_EXOPLANET "exoplanet_template" +#define MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE "exoplanet_site_template" +#define MAP_TEMPLATE_CATEGORY_PLANET "planet_template" +#define MAP_TEMPLATE_CATEGORY_PLANET_SITE "planet_site_template" +#define MAP_TEMPLATE_CATEGORY_SPACE "space_template" +#define MAP_TEMPLATE_CATEGORY_AWAYSITE "awaysite_template" +#define MAP_TEMPLATE_CATEGORY_LANDMARK_LOADED "landmark_template" \ No newline at end of file diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 369e940edca..7204c94f87d 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -1,16 +1,16 @@ #define DEBUG // Turf-only flags. -#define TURF_FLAG_NOJAUNT BITFLAG(0) // This is used in literally one place, turf.dm, to block ethereal jaunt. -#define TURF_FLAG_NORUINS BITFLAG(1) // Used by the ruin generator to skip placing loaded ruins on this turf. -#define TURF_FLAG_BACKGROUND BITFLAG(2) // Used by shuttle movement to determine if it should be ignored by turf translation. -#define TURF_IS_HOLOMAP_OBSTACLE BITFLAG(3) -#define TURF_IS_HOLOMAP_PATH BITFLAG(4) -#define TURF_IS_HOLOMAP_ROCK BITFLAG(5) +#define TURF_FLAG_NOJAUNT BITFLAG(0) // This is used in literally one place, turf.dm, to block ethereal jaunt. +#define TURF_FLAG_NO_POINTS_OF_INTEREST BITFLAG(1) // Used by the level subtemplate generator to skip placing loaded templates on this turf. +#define TURF_FLAG_BACKGROUND BITFLAG(2) // Used by shuttle movement to determine if it should be ignored by turf translation. +#define TURF_IS_HOLOMAP_OBSTACLE BITFLAG(3) +#define TURF_IS_HOLOMAP_PATH BITFLAG(4) +#define TURF_IS_HOLOMAP_ROCK BITFLAG(5) ///Width or height of a transition edge area along the map's borders where transition edge turfs are placed to connect levels together. #define TRANSITIONEDGE 7 -///Extra spacing needed between any random ruins and the transition edge of a level. -#define RUIN_MAP_EDGE_PAD 15 +///Extra spacing needed between any random level templates and the transition edge of a level. +#define TEMPLATE_TAG_MAP_EDGE_PAD 15 ///Enum value for a level edge that's to be untouched #define LEVEL_EDGE_NONE 0 @@ -195,11 +195,6 @@ #define WRINKLES_WRINKLY 1 #define WRINKLES_NONE 2 -//detergent states for clothes -#define SMELL_DEFAULT 0 -#define SMELL_CLEAN 1 -#define SMELL_STINKY 2 - //Shuttle mission stages #define SHUTTLE_MISSION_PLANNED 1 #define SHUTTLE_MISSION_STARTED 2 @@ -267,6 +262,10 @@ #define ICON_STATE_INV "inventory" #define hex2num(X) text2num(X, 16) +/// Returns the hex value of a number given a value assumed to be a base-ten value, padded to a minimum length of 2. +#define num2hex(num) num2text(num, 2, 16) +/// Returns the hex value of a number given a value assumed to be a base-ten value, padded to a supplied minimum length. +#define num2hex_padded(num, len) num2text(num, len, 16) #define Z_ALL_TURFS(Z) block(locate(1, 1, Z), locate(world.maxx, world.maxy, Z)) diff --git a/code/__defines/mob_status.dm b/code/__defines/mob_status.dm index 1e8ac3ef70c..42bc8854a7a 100644 --- a/code/__defines/mob_status.dm +++ b/code/__defines/mob_status.dm @@ -2,4 +2,4 @@ #define GET_STATUS(MOB, COND) (LAZYACCESS(MOB.status_counters, COND)) #define HAS_STATUS(MOB, COND) (GET_STATUS(MOB, COND) > 0) #define ADJ_STATUS(MOB, COND, AMT) (MOB.set_status(COND, PENDING_STATUS(MOB, COND) + AMT)) -#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status(COND, max(PENDING_STATUS(MOB, COND), AMT))) +#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status(COND, max(PENDING_STATUS(MOB, COND), AMT))) \ No newline at end of file diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 16ad514c2cd..3c168317126 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -137,8 +137,8 @@ #define FLASH_PROTECTION_MODERATE 2 #define FLASH_PROTECTION_MAJOR 3 -#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6) -#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3) +#define ANIMAL_SPAWN_DELAY round(get_config_value(/decl/config/num/respawn_delay) / 6) +#define DRONE_SPAWN_DELAY round(get_config_value(/decl/config/num/respawn_delay) / 3) // Incapacitation flags, used by the mob/proc/incapacitated() proc #define INCAPACITATION_NONE 0 @@ -182,7 +182,6 @@ #define BP_ACETONE "acetone reactor" // Robo Organs. -#define BP_POSIBRAIN "posibrain" #define BP_VOICE "vocal synthesiser" #define BP_STACK "stack" #define BP_OPTICS "optics" @@ -298,9 +297,6 @@ #define MOB_FLAG_HOLY_BAD BITFLAG(0) // If this mob is allergic to holiness -#define MARKING_TARGET_SKIN 0 // Draw a /decl/sprite_accessory/marking to the mob's body, eg. tattoos -#define MARKING_TARGET_HAIR 1 // Draw a /decl/sprite_accessory/marking to the mob's hair, eg. ears & horns - #define DEXTERITY_NONE 0 #define DEXTERITY_SIMPLE_MACHINES BITFLAG(0) #define DEXTERITY_HOLD_ITEM BITFLAG(1) @@ -330,7 +326,7 @@ var/global/list/dexterity_levels = list( #define INJECTION_PORT 2 #define INJECTION_PORT_DELAY 3 SECONDS // used by injectors to apply delay due to searching for a port on the injectee's suit -#define ADJUSTED_GLIDE_SIZE(DELAY) (NONUNIT_CEILING((WORLD_ICON_SIZE / max((DELAY), world.tick_lag) * world.tick_lag) - world.tick_lag, 1) + (config.glide_size_delay)) +#define ADJUSTED_GLIDE_SIZE(DELAY) (NONUNIT_CEILING((WORLD_ICON_SIZE / max((DELAY), world.tick_lag) * world.tick_lag) - world.tick_lag, 1) + (get_config_value(/decl/config/num/movement_glide_size))) #define PREF_MEM_RECORD "memory" #define PREF_SEC_RECORD "sec_record" @@ -379,4 +375,13 @@ var/global/list/dexterity_levels = list( // Underlay defines; vestigal implementation currently. #define HU_TAIL_LAYER 1 -#define TOTAL_UNDER_LAYERS 1 \ No newline at end of file +#define TOTAL_UNDER_LAYERS 1 + +// Enum for result of an attempt to eat/eat from an item. +#define EATEN_INVALID 0 +#define EATEN_UNABLE 1 +#define EATEN_SUCCESS 2 + +// Enum for type of consumption, largely just cosmetic currently. +#define EATING_METHOD_EAT 0 +#define EATING_METHOD_DRINK 1 diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index aaecaaaf4bf..48a9f0e0973 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -23,13 +23,13 @@ #define QDESTROYING(X) (isnull(X) || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) //Qdel helper macros. -#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, /datum/proc/qdel_self), time, TIMER_STOPPABLE)} -#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, /datum/proc/qdel_self), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)} +#define QDEL_IN(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE)} +#define QDEL_IN_CLIENT_TIME(item, time) if(!isnull(item)) {addtimer(CALLBACK(item, TYPE_PROC_REF(/datum, qdel_self)), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)} #define QDEL_NULL(item) if(item) {qdel(item); item = null} #define QDEL_NULL_SCREEN(item) if(client) { client.screen -= item; }; QDEL_NULL(item) #define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) }}; if(x) {x.Cut(); x = null } // Second x check to handle items that LAZYREMOVE on qdel. #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } -#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) +#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } diff --git a/code/__defines/reactions.dm b/code/__defines/reactions.dm new file mode 100644 index 00000000000..5edc12eb62f --- /dev/null +++ b/code/__defines/reactions.dm @@ -0,0 +1,5 @@ +#define REACTION_TYPE_PHARMACEUTICAL 1 +#define REACTION_TYPE_ALLOYING 2 +#define REACTION_TYPE_COMPOUND 3 +#define REACTION_TYPE_SYNTHESIS 4 +#define REACTION_TYPE_RECIPE 5 \ No newline at end of file diff --git a/code/__defines/ruin_tags.dm b/code/__defines/ruin_tags.dm deleted file mode 100644 index caf6e3cf7fb..00000000000 --- a/code/__defines/ruin_tags.dm +++ /dev/null @@ -1,8 +0,0 @@ -//Flags for exoplanet ruin picking - -#define RUIN_HABITAT 1 //long term habitat -#define RUIN_HUMAN 2 //human-made structure -#define RUIN_ALIEN 4 //artificial structure of an unknown origin -#define RUIN_WRECK 8 //crashed vessel -#define RUIN_NATURAL 16 //naturally occuring structure -#define RUIN_WATER 32 //ruin depending on planet having water accessible \ No newline at end of file diff --git a/code/__defines/template_tags.dm b/code/__defines/template_tags.dm new file mode 100644 index 00000000000..1da57b5307f --- /dev/null +++ b/code/__defines/template_tags.dm @@ -0,0 +1,9 @@ +//Flags for exoplanet ruin picking + +#define TEMPLATE_TAG_HABITAT BITFLAG(0) //long term habitat +#define TEMPLATE_TAG_HUMAN BITFLAG(1) //human-made structure +#define TEMPLATE_TAG_ALIEN BITFLAG(2) //artificial structure of an unknown origin +#define TEMPLATE_TAG_WRECK BITFLAG(3) //crashed vessel +#define TEMPLATE_TAG_NATURAL BITFLAG(4) //naturally occuring structure +#define TEMPLATE_TAG_WATER BITFLAG(5) //ruin depending on planet having water accessible +#define TEMPLATE_TAG_HABITABLE BITFLAG(6) //ruin depending on planet being habitable diff --git a/code/__defines/tools.dm b/code/__defines/tools.dm index 31f2f62419d..89e081fb21b 100644 --- a/code/__defines/tools.dm +++ b/code/__defines/tools.dm @@ -22,6 +22,7 @@ #define TOOL_SURGICAL_DRILL /decl/tool_archetype/surgical_drill // Tool qualities (positive multplier) +#define TOOL_QUALITY_NONE 0 #define TOOL_QUALITY_WORST 0.1 #define TOOL_QUALITY_BAD 0.5 #define TOOL_QUALITY_MEDIOCRE 0.75 diff --git a/code/__defines/webhooks.dm b/code/__defines/webhooks.dm index eaf65014d92..57fe27fefc0 100644 --- a/code/__defines/webhooks.dm +++ b/code/__defines/webhooks.dm @@ -7,3 +7,4 @@ #define WEBHOOK_CUSTOM_EVENT "webhook_custom_event" #define WEBHOOK_ELEVATOR_FALL "webhook_elevator_fall" #define WEBHOOK_AHELP_SENT "webhook_ahelp_sent" +#define WEBHOOK_FAX_SENT "webhook_fax_sent" diff --git a/code/__defines/zmimic.dm b/code/__defines/zmimic.dm index 06481ac74ec..71982547c3e 100644 --- a/code/__defines/zmimic.dm +++ b/code/__defines/zmimic.dm @@ -1,19 +1,42 @@ +#define ZM_DESTRUCTION_TIMER(TARGET) addtimer(CALLBACK(TARGET, TYPE_PROC_REF(/datum, qdel_self)), 10 SECONDS, TIMER_STOPPABLE) #define TURF_IS_MIMICKING(T) (isturf(T) && (T:z_flags & ZM_MIMIC_BELOW)) -#define CHECK_OO_EXISTENCE(OO) if (OO && !TURF_IS_MIMICKING(OO.loc)) { qdel(OO); } +#define CHECK_OO_EXISTENCE(OO) if (OO && !MOVABLE_IS_ON_ZTURF(OO) && !OO.destruction_timer) { OO.destruction_timer = ZM_DESTRUCTION_TIMER(OO); } #define UPDATE_OO_IF_PRESENT CHECK_OO_EXISTENCE(bound_overlay); if (bound_overlay) { update_above(); } +// I do not apologize. + +// These aren't intended to be used anywhere else, they just can't be undef'd because DM is dum. +#define ZM_INTERNAL_SCAN_LOOKAHEAD(M,VTR,F) ((get_step(M, M:dir)?:VTR & F) || (get_step(M, turn(M:dir, 180))?:VTR & F)) +#define ZM_INTERNAL_SCAN_LOOKBESIDE(M,VTR,F) ((get_step(M, turn(M:dir, 90))?:VTR & F) || (get_step(M, turn(M:dir, -90))?:VTR & F)) + +/// Is this movable visible from a turf that is mimicking below? Note: this does not necessarily mean *directly* below. +#define MOVABLE_IS_BELOW_ZTURF(M) (\ + isturf(M:loc) && (TURF_IS_MIMICKING(M:loc:above) \ + || ((M:z_flags & ZMM_LOOKAHEAD) && ZM_INTERNAL_SCAN_LOOKAHEAD(M, above?:z_flags, ZM_MIMIC_BELOW)) \ + || ((M:z_flags & ZMM_LOOKBESIDE) && ZM_INTERNAL_SCAN_LOOKBESIDE(M, above?:z_flags, ZM_MIMIC_BELOW))) \ +) +/// Is this movable located on a turf that is mimicking below? Note: this does not necessarily mean *directly* on. +#define MOVABLE_IS_ON_ZTURF(M) (\ + (TURF_IS_MIMICKING(M:loc) \ + || ((M:z_flags & ZMM_LOOKAHEAD) && ZM_INTERNAL_SCAN_LOOKAHEAD(M, z_flags, ZM_MIMIC_BELOW)) \ + || ((M:z_flags & ZMM_LOOKBESIDE) && ZM_INTERNAL_SCAN_LOOKBESIDE(M, z_flags, ZM_MIMIC_BELOW))) \ +) +#define MOVABLE_SHALL_MIMIC(AM) (!(AM.z_flags & ZMM_IGNORE) && MOVABLE_IS_BELOW_ZTURF(AM)) + // Turf MZ flags. #define ZM_MIMIC_BELOW 1 //! If this turf should mimic the turf on the Z below. #define ZM_MIMIC_OVERWRITE 2 //! If this turf is Z-mimicking, overwrite the turf's appearance instead of using a movable. This is faster, but means the turf cannot have its own appearance (say, edges or a translucent sprite). #define ZM_ALLOW_LIGHTING 4 //! If this turf should permit passage of lighting. #define ZM_ALLOW_ATMOS 8 //! If this turf permits passage of air. -#define ZM_MIMIC_NO_AO 16 //! If the turf shouldn't apply regular turf AO and only do Z-mimic AO. -#define ZM_NO_OCCLUDE 32 //! Don't occlude below atoms if we're a non-mimic z-turf. -#define ZM_MIMIC_BASETURF 64 //! Mimic baseturf instead of the below atom. Sometimes useful for elevators. -#define ZM_PARTITION_STACK 128 //! If this turf counts as the top of its z-stack for some checks (e.g. is_outside). +#define ZM_MIMIC_NO_AO 16 //! If the turf shouldn't apply regular turf AO and only do Z-mimic AO. +#define ZM_NO_OCCLUDE 32 //! Don't occlude below atoms if we're a non-mimic z-turf. +#define ZM_OVERRIDE 64 //! Copy only z_appearance or baseturf and bail, do not attempt to copy movables. This is significantly cheaper and allows you to override the mimic, but results in movables not being visible. +#define ZM_NO_SHADOW 128 //! If this turf is being copied, hide the shadower. +#define ZM_TERMINATOR 256 //! Consider this turf the terminus of a Z-group, like the bottom of a Z-group or a ZM_OVERRIDE turf. -// Convenience flag. -#define ZM_MIMIC_DEFAULTS (ZM_MIMIC_BELOW|ZM_ALLOW_LIGHTING) +// Convenience flags. +#define ZM_MIMIC_DEFAULTS (ZM_MIMIC_BELOW|ZM_ALLOW_LIGHTING) //! Common defaults for zturfs. +#define ZMM_WIDE_LOAD (ZMM_LOOKAHEAD | ZMM_LOOKBESIDE) //! Atom is big and needs to scan one extra turf in both X and Y. This only extends the range by one turf. Cheap, but not free. // For debug purposes, should contain the above defines in ascending order. var/global/list/mimic_defines = list( @@ -23,9 +46,13 @@ var/global/list/mimic_defines = list( "ZM_ALLOW_ATMOS", "ZM_MIMIC_NO_AO", "ZM_NO_OCCLUDE", - "ZM_MIMIC_BASETURF" + "ZM_OVERRIDE", + "ZM_NO_SHADOW", + "ZM_TERMINATOR" ) // Movable flags. -#define ZMM_IGNORE 1 //! Do not copy this movable. -#define ZMM_MANGLE_PLANES 2 //! Check this movable's overlays/underlays for explicit plane use and mangle for compatibility with Z-Mimic. If you're using emissive overlays, you probably should be using this flag. Expensive, only use if necessary. +#define ZMM_IGNORE 1 //! Do not copy this movable. +#define ZMM_MANGLE_PLANES 2 //! Check this movable's overlays/underlays for explicit plane use and mangle for compatibility with Z-Mimic. If you're using emissive overlays, you probably should be using this flag. Expensive, only use if necessary. +#define ZMM_LOOKAHEAD 3 //! Look one turf ahead and one turf back when considering z-turfs that might be seeing this atom. Cheap, but not free. +#define ZMM_LOOKBESIDE 4 //! Look one turf beside (left/right) when considering z-turfs that might be seeing this atom. Cheap, but not free. diff --git a/code/_global_vars/logging.dm b/code/_global_vars/logging.dm index 120f43d48bb..43ea604377c 100644 --- a/code/_global_vars/logging.dm +++ b/code/_global_vars/logging.dm @@ -1,11 +1,3 @@ -var/global/list/combatlog = list() -var/global/list/IClog = list() -var/global/list/OOClog = list() -var/global/list/adminlog = list() - -var/global/datum/configuration/config = null -var/global/list/jobMax = list() - var/global/diary = null GLOBAL_PROTECTED_UNTYPED(log_directory, null) diff --git a/code/_helpers/animations.dm b/code/_helpers/animations.dm index 163b235e898..b6fcccda02d 100644 --- a/code/_helpers/animations.dm +++ b/code/_helpers/animations.dm @@ -5,7 +5,7 @@ /proc/fade_out(image/I, list/show_to) animate(I, alpha = 0, time = 0.5 SECONDS, easing = EASE_IN) - addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_images_from_clients, I, show_to), 0.5 SECONDS) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_images_from_clients), I, show_to), 0.5 SECONDS) /proc/animate_speech_bubble(image/I, list/show_to, duration) if(!I) @@ -17,7 +17,7 @@ for(var/client/C in show_to) C.images += I animate(I, transform = 0, alpha = 255, time = 0.2 SECONDS, easing = EASE_IN) - addtimer(CALLBACK(GLOBAL_PROC, .proc/fade_out, I, show_to), (duration - 0.5 SECONDS)) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(fade_out), I, show_to), (duration - 0.5 SECONDS)) /proc/animate_receive_damage(atom/A) var/pixel_x_diff = rand(-2,2) @@ -53,7 +53,7 @@ /proc/flick_overlay(image/I, list/show_to, duration) for(var/client/C in show_to) C.images += I - addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_images_from_clients, I, show_to), duration) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_images_from_clients), I, show_to), duration) /atom/movable/proc/do_attack_effect(atom/A, effect) //Simple effects for telegraphing or marking attack locations if (effect) diff --git a/code/_helpers/auxtools.dm b/code/_helpers/auxtools.dm index a7345891c7a..26ac67f7b50 100644 --- a/code/_helpers/auxtools.dm +++ b/code/_helpers/auxtools.dm @@ -11,11 +11,11 @@ var/global/auxtools_debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") /hook/startup/proc/auxtools_init() if (global.auxtools_debug_server) - call(global.auxtools_debug_server, "auxtools_init")() + LIBCALL(global.auxtools_debug_server, "auxtools_init")() enable_debugging() return TRUE /hook/shutdown/proc/auxtools_shutdown() if (global.auxtools_debug_server) - call(global.auxtools_debug_server, "auxtools_shutdown")() + LIBCALL(global.auxtools_debug_server, "auxtools_shutdown")() return TRUE diff --git a/code/_helpers/cmp.dm b/code/_helpers/cmp.dm index 1e9f0b6a0df..be876f23e92 100644 --- a/code/_helpers/cmp.dm +++ b/code/_helpers/cmp.dm @@ -134,5 +134,8 @@ /proc/cmp_gripper_asc(datum/inventory_slot/gripper/a, datum/inventory_slot/gripper/b) return a.hand_sort_priority - b.hand_sort_priority +/proc/cmp_decl_uid_asc(decl/a, decl/b) + return sorttext(b.uid, a.uid) + /proc/cmp_inventory_slot_desc(datum/inventory_slot/a, datum/inventory_slot/b) return b.quick_equip_priority - a.quick_equip_priority diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 079db432b43..fa69c6a25d4 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -392,16 +392,31 @@ * Gets the highest and lowest pressures from the tiles in cardinal directions * around us, then checks the difference. */ -/proc/getOPressureDifferential(var/turf/loc) - var/minp=16777216; - var/maxp=0; +/proc/get_surrounding_pressure_differential(var/turf/loc, atom/originator) + var/minp = INFINITY + var/maxp = 0 + var/has_neighbour = FALSE + var/airblock // zeroed by ATMOS_CANPASS_TURF, declared early as microopt for(var/dir in global.cardinal) - var/turf/T = get_step(loc,dir) - var/datum/gas_mixture/environment = T.return_air() - var/cp = environment?.return_pressure() - if(cpmaxp)maxp=cp - return abs(minp-maxp) + var/turf/neighbour = get_step(loc,dir) + if(!neighbour) + continue + for(var/obj/O in loc) + if(originator && O == originator) + continue + ATMOS_CANPASS_MOVABLE(airblock, O, neighbour) + . |= airblock + if(airblock & AIR_BLOCKED) + continue + ATMOS_CANPASS_TURF(airblock, neighbour, loc) + if(airblock & AIR_BLOCKED) + continue + var/datum/gas_mixture/environment = neighbour.return_air() + var/cp = environment ? environment.return_pressure() : 0 + has_neighbour = TRUE + minp = min(minp, cp) + maxp = max(maxp, cp) + return has_neighbour ? abs(minp-maxp) : 0 /proc/convert_k2c(var/temp) return ((temp - T0C)) @@ -441,7 +456,7 @@ /proc/SecondsToTicks(var/seconds) return seconds * 10 -/proc/round_is_spooky(var/spookiness_threshold = config.cult_ghostwriter_req_cultists) +/proc/round_is_spooky(var/spookiness_threshold = get_config_value(/decl/config/num/cult_ghostwriter_req_cultists)) var/decl/special_role/cult = GET_DECL(/decl/special_role/cultist) return (cult.current_antagonists.len > spookiness_threshold) diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index b67971ebb86..2ac38629b6a 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -33,11 +33,11 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" /proc/log_admin(text) global.admin_log.Add(text) - if (config.log_admin) + if (get_config_value(/decl/config/toggle/log_admin)) game_log("ADMIN", text) /proc/log_debug(text) - if (config.log_debug) + if (get_config_value(/decl/config/toggle/log_debug)) game_log("DEBUG", text) to_debug_listeners(text) @@ -58,47 +58,47 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" to_chat(C, "[prefix]: [text]") /proc/log_game(text) - if (config.log_game) + if (get_config_value(/decl/config/toggle/log_game)) game_log("GAME", text) /proc/log_vote(text) - if (config.log_vote) + if (get_config_value(/decl/config/toggle/log_vote)) game_log("VOTE", text) /proc/log_access(text) - if (config.log_access) + if (get_config_value(/decl/config/toggle/log_access)) game_log("ACCESS", text) /proc/log_say(text) - if (config.log_say) + if (get_config_value(/decl/config/toggle/log_say)) game_log("SAY", text) /proc/log_ooc(text) - if (config.log_ooc) + if (get_config_value(/decl/config/toggle/log_ooc)) game_log("OOC", text) /proc/log_whisper(text) - if (config.log_whisper) + if (get_config_value(/decl/config/toggle/log_whisper)) game_log("WHISPER", text) /proc/log_emote(text) - if (config.log_emote) + if (get_config_value(/decl/config/toggle/log_emotes)) game_log("EMOTE", text) /proc/log_attack(text) - if (config.log_attack) + if (get_config_value(/decl/config/toggle/log_attack)) game_log("ATTACK", text) /proc/log_adminsay(text) - if (config.log_adminchat) + if (get_config_value(/decl/config/toggle/log_adminchat)) game_log("ADMINSAY", text) /proc/log_adminwarn(text) - if (config.log_adminwarn) + if (get_config_value(/decl/config/toggle/log_adminwarn)) game_log("ADMINWARN", text) /proc/log_pda(text) - if (config.log_pda) + if (get_config_value(/decl/config/toggle/log_pda)) game_log("PDA", text) /proc/log_misc(text) @@ -114,7 +114,7 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" //This replaces world.log so it displays both in DD and the file /proc/log_world(text) to_world_log(text) //this comes before the config check because it can't possibly runtime - if(config.log_world_output) + if(get_config_value(/decl/config/toggle/log_world_output)) game_log("DD_OUTPUT", text) //pretty print a direction bitflag, can be useful for debugging. diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 9d714318131..1aca669617a 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -113,7 +113,7 @@ if (progbar) qdel(progbar) -/proc/do_after(mob/user, delay, atom/target = null, check_holding = 1, progress = 1, incapacitation_flags = INCAPACITATION_DEFAULT, same_direction = 0, can_move = 0, max_distance, check_in_view = 0) +/proc/do_after(mob/user, delay, atom/target = null, check_holding = TRUE, progress = TRUE, incapacitation_flags = INCAPACITATION_DEFAULT, same_direction = FALSE, can_move = FALSE, max_distance, check_in_view = FALSE, set_cooldown = FALSE) if(!user) return 0 var/atom/target_loc = null @@ -137,6 +137,9 @@ if (progress) progbar = new(user, delay, target) + if(set_cooldown && delay) + user.setClickCooldown(delay) + var/endtime = world.time + delay var/starttime = world.time . = 1 @@ -311,3 +314,15 @@ var/global/list/bodypart_coverage_cache = list() /proc/get_sorted_mob_list() . = sortTim(SSmobs.mob_list.Copy(), /proc/cmp_name_asc) . = sortTim(., /proc/cmp_mob_sortvalue_asc) + +/proc/transfer_key_from_mob_to_mob(var/mob/from_mob, var/mob/to_mob) + if(!from_mob || !from_mob.key || !to_mob) + return FALSE + var/initial_key = from_mob.key + if(to_mob.key) + to_mob.ghostize() + if(from_mob.mind) + from_mob.mind.transfer_to(to_mob) + if(initial_key && to_mob.key != initial_key) + to_mob.key = initial_key + return to_mob.key == initial_key diff --git a/code/_helpers/names.dm b/code/_helpers/names.dm index 4146cdc9e44..26e4dbd4793 100644 --- a/code/_helpers/names.dm +++ b/code/_helpers/names.dm @@ -52,7 +52,7 @@ var/global/religion_name = null /proc/station_name() if(!global.using_map) - return config.server_name + return get_config_value(/decl/config/text/server_name) if (global.using_map.station_name) return global.using_map.station_name @@ -90,8 +90,9 @@ var/global/religion_name = null if(5) global.using_map.station_name += pick(global.numbers_as_words) - if (config && config.server_name) - world.name = "[config.server_name]: [name]" + var/config_server_name = get_config_value(/decl/config/text/server_name) + if (config_server_name) + world.name = "[config_server_name]: [name]" else world.name = global.using_map.station_name @@ -100,8 +101,9 @@ var/global/religion_name = null /proc/world_name(var/name) global.using_map.station_name = name - if (config && config.server_name) - world.name = "[config.server_name]: [name]" + var/config_server_name = get_config_value(/decl/config/text/server_name) + if (config_server_name) + world.name = "[config_server_name]: [name]" else world.name = name diff --git a/code/_helpers/profiling.dm b/code/_helpers/profiling.dm index 54f0400edf0..ac6b571adce 100644 --- a/code/_helpers/profiling.dm +++ b/code/_helpers/profiling.dm @@ -107,7 +107,7 @@ if(UNIX) lib = "libprof.so" else CRASH("unsupported platform") - var/init = call(lib, "init")() + var/init = LIBCALL(lib, "init")() if("0" != init) CRASH("[lib] init error: [init]") /world/New() diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index 385edc0c61f..a4f89cd94d8 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -120,7 +120,7 @@ if(ignore_background && (source.turf_flags & TURF_FLAG_BACKGROUND)) continue var/old_turf = source.prev_type || base_turf || get_base_turf_by_area(source) - source.ChangeTurf(old_turf) + source.ChangeTurf(old_turf, keep_air_below = TRUE) //Transports a turf from a source turf to a target turf, moving all of the turf's contents and making the target a copy of the source. //If ignore_background is set to true, turfs with TURF_FLAG_BACKGROUND set will only translate anchored contents. diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 8c47ac8734b..087d6d5a979 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -1,7 +1,6 @@ /* * Holds procs designed to change one type of value, into another. * Contains: - * hex2num & num2hex * text2list & list2text * file2list * angle2dir @@ -9,32 +8,6 @@ * worldtime2text */ -// Returns the hex value of a number given a value assumed to be a base-ten value -/proc/num2hex(num, len=2) - if(!isnum(num)) - num = 0 - num = round(abs(num)) - . = "" - var/i=0 - while(1) - if(len<=0) - if(!num) - break - else - if(i>=len) - break - var/remainder = num/16 - num = round(remainder) - remainder = (remainder - num) * 16 - switch(remainder) - if(9,8,7,6,5,4,3,2,1) - . = "[remainder]" + . - if(10,11,12,13,14,15) - . = ascii2text(remainder+87) + . - else - . = "0" + . - i++ - /proc/text2numlist(text, delimiter="\n") var/list/num_list = list() for(var/x in splittext(text, delimiter)) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 7833ad6825d..a83bee9c88f 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -773,16 +773,10 @@ var/global/list/WALLITEMS = list( return 0 /proc/get_random_colour(var/simple = FALSE, var/lower = 0, var/upper = 255) - var/colour if(simple) - colour = pick(list("ff0000","ff7f00","ffff00","00ff00","0000ff","4b0082","8f00ff")) + return pick(list("#ff0000","#ff7f00","#ffff00","#00ff00","#0000ff","#4b0082","#8f00ff")) else - for(var/i=1;i<=3;i++) - var/temp_col = "[num2hex(rand(lower,upper))]" - if(length(temp_col )<2) - temp_col = "0[temp_col]" - colour += temp_col - return "#[colour]" + return rgb(rand(lower, upper), rand(lower, upper), rand(lower, upper)) // call to generate a stack trace and print to runtime logs /proc/get_stack_trace(msg, file, line) diff --git a/code/_helpers/washing.dm b/code/_helpers/washing.dm index 63d8e80d6f4..487afbd8700 100644 --- a/code/_helpers/washing.dm +++ b/code/_helpers/washing.dm @@ -1,100 +1,9 @@ /proc/wash_mob(var/mob/living/washing) - if(!istype(washing)) return - var/mob/living/L = washing - if(L.on_fire) L.visible_message("A cloud of steam rises up as the water hits \the [L]!") L.ExtinguishMob() - L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily - - if(!iscarbon(washing)) - washing.clean_blood() - return - - var/mob/living/carbon/M = washing - for(var/obj/item/thing in M.get_held_items()) - thing.clean_blood() - - var/obj/item/back = M.get_equipped_item(slot_back_str) - if(back) - back.clean_blood() - - //flush away reagents on the skin - var/datum/reagents/touching_reagents = M.get_contact_reagents() - if(touching_reagents) - var/remove_amount = touching_reagents.maximum_volume * M.reagent_permeability() //take off your suit first - touching_reagents.remove_any(remove_amount) - - if(!ishuman(M)) - var/obj/item/mask = M.get_equipped_item(slot_wear_mask_str) - if(mask) - mask.clean_blood() - M.clean_blood() - return - - var/mob/living/carbon/human/H = M - var/washgloves = 1 - var/washshoes = 1 - var/washmask = 1 - var/washears = 1 - var/washglasses = 1 - - var/obj/item/suit = H.get_equipped_item(slot_wear_suit_str) - if(suit) - washgloves = !(suit.flags_inv & HIDEGLOVES) - washshoes = !(suit.flags_inv & HIDESHOES) - - var/obj/item/head = H.get_equipped_item(slot_head_str) - if(head) - washmask = !(head.flags_inv & HIDEMASK) - washglasses = !(head.flags_inv & HIDEEYES) - washears = !(head.flags_inv & HIDEEARS) - - var/obj/item/mask = M.get_equipped_item(slot_wear_mask_str) - if(mask) - if (washears) - washears = !(mask.flags_inv & HIDEEARS) - if (washglasses) - washglasses = !(mask.flags_inv & HIDEEYES) - - if(head) - head.clean_blood() - - if(suit) - suit.clean_blood() - else - var/obj/item/uniform = H.get_equipped_item(slot_w_uniform_str) - if(uniform) - uniform.clean_blood() - - if(washgloves) - var/obj/item/gloves = H.get_equipped_item(slot_gloves_str) - if(gloves) - gloves.clean_blood() - - var/obj/item/shoes = H.get_equipped_item(slot_shoes_str) - if(shoes && washshoes) - shoes.clean_blood() - if(mask && washmask) - mask.clean_blood() - if(washglasses) - var/obj/item/glasses = H.get_equipped_item(slot_glasses_str) - if(glasses) - glasses.clean_blood() - - if(washears) - var/obj/item/ear = H.get_equipped_item(slot_l_ear_str) - if(ear) - ear.clean_blood() - ear = H.get_equipped_item(slot_r_ear_str) - if(ear) - ear.clean_blood() - - var/obj/item/belt = H.get_equipped_item(slot_belt_str) - if(belt) - belt.clean_blood() - H.clean_blood(washshoes) + washing.clean() diff --git a/code/_macros.dm b/code/_macros.dm index f3b68314775..f8fca61761d 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -24,7 +24,7 @@ #define isatom(A) isloc(A) -#define isbrain(A) istype(A, /mob/living/carbon/brain) +#define isbrain(A) istype(A, /mob/living/brain) #define iscarbon(A) istype(A, /mob/living/carbon) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 59e60a2f38f..86877e2c1d6 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -161,7 +161,7 @@ next_move = max(world.time + timeout, next_move) /mob/proc/canClick() - if(config.no_click_cooldown || next_move <= world.time) + if(get_config_value(/decl/config/toggle/no_click_cooldown) || next_move <= world.time) return 1 return 0 diff --git a/code/_onclick/click_handling.dm b/code/_onclick/click_handling.dm index 472249544ec..08d1ec3b579 100644 --- a/code/_onclick/click_handling.dm +++ b/code/_onclick/click_handling.dm @@ -28,11 +28,11 @@ var/global/const/CLICK_HANDLER_ALL = (CLICK_HANDLER_NONE|CLICK_ ..() src.user = user if(flags & (CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT)) - events_repository.register(/decl/observ/logged_out, user, src, /datum/click_handler/proc/OnMobLogout) + events_repository.register(/decl/observ/logged_out, user, src, TYPE_PROC_REF(/datum/click_handler, OnMobLogout)) /datum/click_handler/Destroy() if(flags & (CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT)) - events_repository.unregister(/decl/observ/logged_out, user, src, /datum/click_handler/proc/OnMobLogout) + events_repository.unregister(/decl/observ/logged_out, user, src, TYPE_PROC_REF(/datum/click_handler, OnMobLogout)) user = null . = ..() diff --git a/code/_onclick/ghost.dm b/code/_onclick/ghost.dm index 8a93cd5118f..da5d187674d 100644 --- a/code/_onclick/ghost.dm +++ b/code/_onclick/ghost.dm @@ -28,7 +28,7 @@ if(!canClick()) return setClickCooldown(DEFAULT_QUICK_COOLDOWN) - // You are responsible for checking config.ghost_interaction when you override this function + // You are responsible for checking ghost_interaction when you override this function // Not all of them require checking, see below var/list/modifiers = params2list(params) if(modifiers["alt"]) diff --git a/code/_onclick/hud/ai_hud.dm b/code/_onclick/hud/ai_hud.dm index fa4e2200bb6..b8edcf540c4 100644 --- a/code/_onclick/hud/ai_hud.dm +++ b/code/_onclick/hud/ai_hud.dm @@ -11,70 +11,70 @@ screen_loc = ui_ai_core name = "AI Core" icon_state = "ai_core" - proc_path = /mob/living/silicon/ai/proc/core + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, core) /decl/ai_hud/ai_announcement screen_loc = ui_ai_announcement name = "AI Announcement" icon_state = "announcement" - proc_path = /mob/living/silicon/ai/proc/ai_announcement + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_announcement) /decl/ai_hud/ai_cam_track screen_loc = ui_ai_cam_track name = "Track With Camera" icon_state = "track" - proc_path = /mob/living/silicon/ai/proc/ai_camera_track + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_camera_track) input_procs = list(/mob/living/silicon/ai/proc/trackable_mobs = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION)) /decl/ai_hud/ai_cam_light screen_loc = ui_ai_cam_light name = "Toggle Camera Lights" icon_state = "camera_light" - proc_path = /mob/living/silicon/ai/proc/toggle_camera_light + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, toggle_camera_light) /decl/ai_hud/ai_cam_change_channel screen_loc = ui_ai_cam_change_channel name = "Jump to Camera Channel" icon_state = "camera" - proc_path = /mob/living/silicon/ai/proc/ai_channel_change + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_channel_change) input_procs = list(/mob/living/silicon/ai/proc/get_camera_channel_list = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION)) /decl/ai_hud/ai_sensor screen_loc = ui_ai_sensor name = "Set Sensor Mode" icon_state = "ai_sensor" - proc_path = /mob/living/silicon/ai/proc/sensor_mode + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, sensor_mode) /decl/ai_hud/ai_manifest screen_loc = ui_ai_crew_manifest name = "Show Crew Manifest" icon_state = "manifest" - proc_path = /mob/living/silicon/ai/proc/run_program + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, run_program) input_args = list("crewmanifest") /decl/ai_hud/ai_take_image screen_loc = ui_ai_take_image name = "Toggle Camera Mode" icon_state = "take_picture" - proc_path = /mob/living/silicon/ai/proc/ai_take_image + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_take_image) /decl/ai_hud/ai_view_images screen_loc = ui_ai_view_images name = "View Images" icon_state = "view_images" - proc_path = /mob/living/silicon/ai/proc/ai_view_images + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_view_images) /decl/ai_hud/ai_laws screen_loc = ui_ai_state_laws name = "State Laws" icon_state = "state_laws" - proc_path = /mob/living/silicon/ai/proc/ai_checklaws + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_checklaws) /decl/ai_hud/ai_call_shuttle screen_loc = ui_ai_call_shuttle name = "Call Shuttle" icon_state = "call_shuttle" - proc_path = /mob/living/silicon/ai/proc/ai_call_shuttle + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_call_shuttle) /decl/ai_hud/ai_up screen_loc = ui_ai_up @@ -92,53 +92,53 @@ screen_loc = ui_ai_color name = "Change Floor Color" icon_state = "ai_floor" - proc_path = /mob/living/silicon/ai/proc/change_floor + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, change_floor) /decl/ai_hud/ai_hologram screen_loc = ui_ai_holo_change name = "Change Hologram" icon_state = "ai_holo_change" - proc_path = /mob/living/silicon/ai/proc/ai_hologram_change + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_hologram_change) /decl/ai_hud/ai_crew_monitor screen_loc = ui_ai_crew_mon name = "Crew Monitor" icon_state = "crew_monitor" - proc_path = /mob/living/silicon/ai/proc/run_program + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, run_program) input_args = list("sensormonitor") /decl/ai_hud/ai_power_override screen_loc = ui_ai_power_override name = "Toggle Power Override" icon_state = "ai_p_override" - proc_path = /mob/living/silicon/ai/proc/ai_power_override + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_power_override) /decl/ai_hud/ai_shutdown screen_loc = ui_ai_shutdown name = "Shutdown" icon_state = "ai_shutdown" - proc_path = /mob/living/silicon/ai/proc/ai_shutdown + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_shutdown) /decl/ai_hud/ai_move_hologram screen_loc = ui_ai_holo_mov name = "Toggle Hologram Movement" icon_state = "ai_holo_mov" - proc_path = /mob/living/silicon/ai/proc/toggle_hologram_movement + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, toggle_hologram_movement) /decl/ai_hud/ai_core_icon screen_loc = ui_ai_core_icon name = "Pick Icon" icon_state = "ai_core_pick" - proc_path = /mob/living/silicon/ai/proc/pick_icon + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, pick_icon) /decl/ai_hud/ai_status screen_loc = ui_ai_status name = "Pick Status" icon_state = "ai_status" - proc_path = /mob/living/silicon/ai/proc/ai_statuschange + proc_path = TYPE_PROC_REF(/mob/living/silicon/ai, ai_statuschange) /decl/ai_hud/ai_inbuilt_comp screen_loc = ui_ai_crew_rec name = "Inbuilt Computer" icon_state = "ai_crew_rec" - proc_path = /mob/living/silicon/proc/access_computer + proc_path = TYPE_PROC_REF(/mob/living/silicon, access_computer) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 100eabb9071..b5b67503230 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -152,7 +152,7 @@ gripper_datums += mymob.get_inventory_slot_datum(hand_tag) gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc) - for(var/datum/inventory_slot/inv_slot in gripper_datums) + for(var/datum/inventory_slot/gripper/inv_slot in gripper_datums) // Re-order the held slot list so it aligns with the display order. var/hand_tag = inv_slot.slot_id @@ -176,7 +176,7 @@ inv_box.icon_state = "hand_base" inv_box.cut_overlays() - inv_box.add_overlay("hand_[hand_tag]", TRUE) + inv_box.add_overlay("hand_[inv_slot.hand_overlay || hand_tag]", TRUE) if(inv_slot.ui_label) inv_box.add_overlay("hand_[inv_slot.ui_label]", TRUE) inv_box.update_icon() @@ -211,8 +211,8 @@ inv_box = sublist[2] inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]" hand_y_offset += world.icon_size - if(mymob.client) - mymob.client.screen |= inv_box + if(mymob.client) + mymob.client.screen |= hand_hud_objects // Make sure all held items are on the screen and set to the correct screen loc. var/datum/inventory_slot/inv_slot diff --git a/code/_onclick/hud/screen/screen_click_catcher.dm b/code/_onclick/hud/screen/screen_click_catcher.dm index 7a53f887d83..4584120a02a 100644 --- a/code/_onclick/hud/screen/screen_click_catcher.dm +++ b/code/_onclick/hud/screen/screen_click_catcher.dm @@ -1,12 +1,14 @@ var/global/list/click_catchers /proc/get_click_catchers() if(!global.click_catchers) + var/client_max_x = get_config_value(/decl/config/num/clients/max_client_view_x) + var/client_max_y = get_config_value(/decl/config/num/clients/max_client_view_y) global.click_catchers = list() - var/ox = -(round(config.max_client_view_x*0.5)) - for(var/i = 0 to config.max_client_view_x) - var/oy = -(round(config.max_client_view_y*0.5)) + var/ox = -(round(client_max_x*0.5)) + for(var/i = 0 to client_max_x) + var/oy = -(round(client_max_y*0.5)) var/tx = ox + i - for(var/j = 0 to config.max_client_view_y) + for(var/j = 0 to client_max_y) var/ty = oy + j var/obj/screen/click_catcher/CC = new CC.screen_loc = "CENTER[tx < 0 ? tx : "+[tx]"],CENTER[ty < 0 ? ty : "+[ty]"]" diff --git a/code/_onclick/hud/screen/screen_lighting.dm b/code/_onclick/hud/screen/screen_lighting.dm index 4822823aed9..0354ad4a0cb 100644 --- a/code/_onclick/hud/screen/screen_lighting.dm +++ b/code/_onclick/hud/screen/screen_lighting.dm @@ -6,6 +6,6 @@ blend_mode = BLEND_MULTIPLY alpha = 255 -/obj/screen/lighting_plane_master/proc/set_alpha(var/newalpha) - if(alpha != newalpha) - animate(src, alpha = newalpha, time = SSmobs.wait) +/obj/screen/lighting_plane_master/set_alpha(var/new_alpha) + if(alpha != new_alpha) + animate(src, alpha = new_alpha, time = SSmobs.wait) \ No newline at end of file diff --git a/code/_onclick/hud/screen/screen_setup.dm b/code/_onclick/hud/screen/screen_setup.dm index 62906dc9b20..cbd2279d24b 100644 --- a/code/_onclick/hud/screen/screen_setup.dm +++ b/code/_onclick/hud/screen/screen_setup.dm @@ -1,5 +1,6 @@ // Character setup stuff /obj/screen/setup_preview + icon = 'icons/effects/32x32.dmi' plane = DEFAULT_PLANE layer = MOB_LAYER requires_owner = FALSE @@ -14,7 +15,9 @@ layer = TURF_LAYER mouse_over_pointer = MOUSE_HAND_POINTER -/obj/screen/setup_preview/bg/handle_click(mob/user, params) +// Uses Click() instead of handle_click() due to being accessed by new_player mobs. +/obj/screen/setup_preview/bg/Click(location, control, params) if(pref) pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options) pref.update_preview_icon() + return ..() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index e9c5a42cbfa..3e6f983e699 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -80,6 +80,10 @@ avoid code duplication. This includes items that may sometimes act as a standard //I would prefer to rename this attack_as_weapon(), but that would involve touching hundreds of files. /obj/item/proc/attack(mob/living/M, mob/living/user, var/target_zone, animate = TRUE) + + if(user?.a_intent != I_HURT && is_edible(M) && handle_eaten_by_mob(user, M) != EATEN_INVALID) + return TRUE + if(item_flags & ITEM_FLAG_NO_BLUDGEON) return FALSE diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm index 7813f9d5d3c..8dd8799e561 100644 --- a/code/_onclick/rig.dm +++ b/code/_onclick/rig.dm @@ -28,9 +28,6 @@ /mob/living/carbon/human/can_use_rig() return 1 -/mob/living/carbon/brain/can_use_rig() - return istype(loc, /obj/item/mmi) - /mob/living/silicon/ai/can_use_rig() return carded diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm index b609a369ffb..c37a4784fe0 100644 --- a/code/controllers/autotransfer.dm +++ b/code/controllers/autotransfer.dm @@ -4,7 +4,7 @@ var/global/datum/controller/transfer_controller/transfer_controller var/timerbuffer = 0 //buffer for time check /datum/controller/transfer_controller/New() - timerbuffer = config.vote_autotransfer_initial + timerbuffer = get_config_value(/decl/config/num/vote_autotransfer_initial) START_PROCESSING(SSprocessing, src) /datum/controller/transfer_controller/Destroy() @@ -14,7 +14,7 @@ var/global/datum/controller/transfer_controller/transfer_controller /datum/controller/transfer_controller/Process() if (time_till_transfer_vote() <= 0) SSvote.initiate_vote(/datum/vote/transfer, automatic = 1) - timerbuffer += config.vote_autotransfer_interval + timerbuffer += get_config_value(/decl/config/num/vote_autotransfer_interval) /datum/controller/transfer_controller/proc/time_till_transfer_vote() return timerbuffer - round_duration_in_ticks - (1 MINUTE) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm deleted file mode 100644 index 33189d3b70c..00000000000 --- a/code/controllers/configuration.dm +++ /dev/null @@ -1,1032 +0,0 @@ -/datum/configuration - var/server_name = "Nebula 13" // server name (for world name / status) - var/server_suffix = 0 // generate numeric suffix based on server port - - var/log_ooc = 0 // log OOC channel - var/log_access = 0 // log login/logout - var/log_say = 0 // log client say - var/log_admin = 0 // log admin actions - var/log_debug = 1 // log debug output - var/log_game = 0 // log game events - var/log_vote = 0 // log voting - var/log_whisper = 0 // log client whisper - var/log_emote = 0 // log emotes - var/log_attack = 0 // log attack messages - var/log_adminchat = 0 // log admin chat messages - var/log_adminwarn = 0 // log warnings admins get about bomb construction and such - var/log_pda = 0 // log pda messages - var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits - var/log_runtime = 0 // logs world.log to a file - var/log_world_output = 0 // log to_world_log(messages) - var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour - var/allow_vote_restart = 0 // allow votes to restart - var/ert_admin_call_only = 0 - var/allow_vote_mode = 0 // allow votes to change mode - var/allow_admin_jump = 1 // allows admin jumping - var/allow_admin_spawning = 1 // allows admin item spawning - var/allow_admin_rev = 1 // allows admin revives - var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) - var/vote_period = 600 // length of voting period (deciseconds, default 1 minute) - var/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called - var/vote_autotransfer_interval = 18000 // length of time before next sequential autotransfer vote - var/vote_autogamemode_timeleft = 100 //Length of time before round start when autogamemode vote is called (in seconds, default 100). - var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) - var/vote_no_dead = 0 // dead people can't vote (tbi) - var/vote_no_dead_crew_transfer = 0 // dead people can't vote on crew transfer votes -// var/enable_authentication = 0 // goon authentication - var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard - var/traitor_scaling = 0 //if amount of traitors scales based on amount of players - var/objectives_disabled = 0 //if objectives are disabled or not - var/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other - var/continous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. - var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. - var/allow_holidays = FALSE - var/fps = 20 - var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling - var/list/resource_urls = null - var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. - var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. - var/list/mode_names = list() - var/list/modes = list() // allowed modes - var/list/votable_modes = list() // votable modes - var/list/probabilities = list() // relative probability of each mode - var/secret_hide_possibilities = FALSE // Whether or not secret modes show list of possible round types - var/humans_need_surnames = 0 - var/allow_random_events = 0 // enables random events mid-round when set to 1 - var/allow_ai = 1 // allow ai job - var/hostedby = null - var/respawn_delay = 30 - var/guest_jobban = 1 - var/usewhitelist = 0 - var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 - var/mods_can_tempban = 0 - var/mods_can_job_tempban = 0 - var/mod_tempban_max = 1440 - var/mod_job_tempban_max = 1440 - var/load_jobs_from_txt = 0 - var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. - - var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... - var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. - - var/character_slots = 10 // The number of available character slots - var/loadout_slots = 3 // The number of loadout slots per character - - var/max_maint_drones = 5 //This many drones can spawn, - var/allow_drone_spawn = 1 //assuming the admin allow them to. - var/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes. - - var/disable_player_mice = 0 - var/uneducated_mice = 0 //Set to 1 to prevent newly-spawned mice from understanding human speech - - var/usealienwhitelist = 0 - var/usealienwhitelistSQL = 0; - var/limitalienplayers = 0 - var/alien_to_human_ratio = 0.5 - var/allow_extra_antags = 0 - var/guests_allowed = 1 - var/debugparanoid = 0 - - var/serverurl - var/server - var/banappeals - var/wikiurl - var/forumurl - var/discordurl - var/githuburl - var/issuereporturl - - var/forbid_singulo_possession = 0 - - //game_options.txt configs - - var/show_human_death_message = FALSE - var/health_threshold_dead = -100 - - var/organ_health_multiplier = 0.9 - var/organ_regeneration_multiplier = 0.25 - var/organs_decay - - //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, - //so that it's similar to PAIN. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. - var/organ_damage_spillover_multiplier = 0.5 - - var/bones_can_break = 1 - var/limbs_can_break = 1 - - var/revival_pod_plants = 1 - var/revival_cloning = 1 - var/revival_brain_life = -1 - - var/use_loyalty_implants = 0 - var/max_character_aspects = 5 - - var/welder_vision = 1 - ///If false, skips all level generation. - var/roundstart_level_generation = 1 - var/no_click_cooldown = 0 - - //Used for modifying movement speed for mobs. - //Unversal modifiers - var/run_delay = 2 - var/walk_delay = 4 - var/creep_delay = 6 - var/minimum_sprint_cost = 0.8 - var/skill_sprint_cost_range = 0.8 - var/minimum_stamina_recovery = 1 - var/maximum_stamina_recovery = 3 - var/glide_size_delay = 1 - - //Mob specific modifiers. NOTE: These will affect different mob types in different ways - var/human_delay = 0 - var/robot_delay = 0 - var/monkey_delay = 0 - var/alien_delay = 0 - var/slime_delay = 0 - var/animal_delay = 0 - var/maximum_mushrooms = 15 //After this amount alive, mushrooms will not boom boom - - - var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt - var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt - var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database - var/use_age_restriction_for_antags = 0 //Do antags use account age restrictions? --requires database - - var/use_iterative_explosions //Defines whether the server uses iterative or circular explosions. - var/iterative_explosives_z_threshold = 10 - var/iterative_explosives_z_multiplier = 0.75 - - var/assistant_maint = 0 //Do assistants get maint access? - var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour. - var/ghost_interaction = 0 - - var/comms_password = null - var/ban_comms_password = null - var/list/forbidden_versions = list() // Clients with these byond versions will be autobanned. Format: string "byond_version.byond_build"; separate with ; in config, e.g. 512.1234;512.1235 - var/minimum_byond_version = 0 - var/minimum_byond_build = 0 - - var/login_export_addr = null - - var/enter_allowed = 1 - var/player_limit = 0 - - var/use_irc_bot = 0 - var/irc_bot_host = "" - var/main_irc = "" - var/admin_irc = "" - var/announce_shuttle_dock_to_irc = FALSE - - var/custom_item_icon_location // File location to look for custom items icons, needs to be relative to the executing binary. - var/custom_icon_icon_location // File location to look for custom icons, needs to be relative to the executing binary. - - // Event settings - var/expected_round_length = 3 * 60 * 60 * 10 // 3 hours - // If the first delay has a custom start time - // No custom time, no custom time, between 80 to 100 minutes respectively. - var/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 48000, "upper" = 60000)) - // The lowest delay until next event - // 10, 30, 50 minutes respectively - var/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 6000, EVENT_LEVEL_MODERATE = 18000, EVENT_LEVEL_MAJOR = 30000) - // The upper delay until next event - // 15, 45, 70 minutes respectively - var/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000) - - var/aliens_allowed = 0 - var/alien_eggs_allowed = 0 - var/ninjas_allowed = 0 - var/abandon_allowed = 1 - var/ooc_allowed = 1 - var/looc_allowed = 1 - var/dooc_allowed = 1 - var/dsay_allowed = 1 - var/aooc_allowed = 1 - - var/exterior_ambient_light = 0 // The strength of ambient light applied to outside turfs - - var/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" - - var/aggressive_changelog = 0 - var/disable_webhook_embeds = FALSE - - var/ghosts_can_possess_animals = 0 - var/delist_when_no_admins = FALSE - - var/allow_map_switching = 0 // Whether map switching is allowed - var/auto_map_vote = 0 // Automatically call a map vote at end of round and switch to the selected map - var/wait_for_sigusr1_reboot = 0 // Don't allow reboot unless it was caused by SIGUSR1 - - var/radiation_decay_rate = 1 //How much radiation is reduced by each tick - var/radiation_resistance_multiplier = 1.25 - var/radiation_material_resistance_divisor = 2 //A turf's possible radiation resistance is divided by this number, to get the real value. - var/radiation_lower_limit = 0.15 //If the radiation level for a turf would be below this, ignore it. - - var/auto_local_admin = TRUE // If true, connections from 127.0.0.1 get automatic admin. - var/autostealth = 0 // Staff get automatic stealth after this many minutes - - var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error - var/error_limit = 50 // How many occurrences before the next will silence them - var/error_silence_time = 6000 // How long a unique error will be silenced for - var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error - - var/max_gear_cost = 10 // Used in chargen for accessory loadout limit. 0 disables loadout, negative allows infinite points. - - var/allow_ic_printing = TRUE //Whether players should be allowed to print IC circuits from scripts. - - var/allow_unsafe_narrates = FALSE //Whether admins can use unsanitized narration; when true, allows HTML etc. - - var/do_not_prevent_spam = FALSE //If this is true, skips spam prevention for user actions; inputs, verbs, macros, etc. - var/max_acts_per_interval = 140 //Number of actions per interval permitted for spam protection. - var/act_interval = 0.1 SECONDS //Interval for spam prevention. - - var/panic_bunker = FALSE //is the panic bunker enabled? - var/panic_bunker_message = "Sorry! The panic bunker is enabled. Please head to our Discord or forum to get yourself added to the panic bunker bypass." - - var/lock_client_view_x - var/lock_client_view_y - var/max_client_view_x = MAX_VIEW - var/max_client_view_y = MAX_VIEW - - var/allow_diagonal_movement = FALSE - - var/no_throttle_localhost - - var/dex_malus_brainloss_threshold = 30 //The threshold of when brainloss begins to affect dexterity. - var/grant_default_darksight = FALSE - var/default_darksight_range = 2 - var/default_darksight_effectiveness = 0.05 - - var/static/list/protected_vars = list( - "comms_password", - "ban_comms_password", - "login_export_addr" - ) - - var/expanded_alt_interactions = FALSE // Set to true to enable look, grab, drop, etc. in the alt interaction menu. - - var/show_typing_indicator_for_whispers = FALSE // Do whispers show typing indicators overhead? - - // Stress-related healing vars. - var/adjust_healing_from_stress = FALSE - var/stress_shock_recovery_constant = 0.5 - var/stress_healing_recovery_constant = 0.3 - var/stress_blood_recovery_constant = 0.3 - - var/exoplanet_min_day_duration = 10 MINUTES - var/exoplanet_max_day_duration = 40 MINUTES - ///If true, exoplanets won't have daycycles - var/disable_daycycle = FALSE - /// Whether or not you will show a message when examining something. - var/visible_examine = TRUE - /// Whether or not loadout options will get free name and desc entry by default. - var/allow_loadout_customization = FALSE - -/datum/configuration/VV_hidden() - . = ..() | protected_vars - -/datum/configuration/New() - var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) - for (var/mode_type in all_modes) - var/decl/game_mode/game_mode = all_modes[mode_type] - if (!game_mode.uid || !(game_mode.uid in modes)) - continue - log_misc("Adding game mode [game_mode.name] ([game_mode.uid]) to configuration.") - src.modes += game_mode.uid - src.mode_names[game_mode.uid] = game_mode.name - src.probabilities[game_mode.uid] = game_mode.probability - if (game_mode.votable) - src.votable_modes += game_mode.uid - src.votable_modes += "secret" - -/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist - var/list/Lines = file2list(filename) - - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - if(type == "config") - switch (name) - if ("resource_urls") - config.resource_urls = splittext(value, " ") - - if ("admin_legacy_system") - config.admin_legacy_system = 1 - - if ("ban_legacy_system") - config.ban_legacy_system = 1 - - if ("use_age_restriction_for_jobs") - config.use_age_restriction_for_jobs = 1 - - if ("use_age_restriction_for_antags") - config.use_age_restriction_for_antags = 1 - - if ("jobs_have_minimal_access") - config.jobs_have_minimal_access = 1 - - if ("use_iterative_explosions") - use_iterative_explosions = 1 - - if ("expanded_alt_interactions") - expanded_alt_interactions = 1 - - if ("explosion_z_threshold") - iterative_explosives_z_threshold = text2num(value) - - if ("explosion_z_mult") - iterative_explosives_z_multiplier = text2num(value) - - if ("custom_item_icon_location") - config.custom_item_icon_location = value - - if ("custom_icon_icon_location") - config.custom_icon_icon_location = value - - if ("log_ooc") - config.log_ooc = 1 - - if ("log_access") - config.log_access = 1 - - if ("log_say") - config.log_say = 1 - - if ("debug_paranoid") - config.debugparanoid = 1 - - if ("log_admin") - config.log_admin = 1 - - if ("log_debug") - config.log_debug = text2num(value) - - if ("log_game") - config.log_game = 1 - - if ("log_vote") - config.log_vote = 1 - - if ("log_whisper") - config.log_whisper = 1 - - if ("log_attack") - config.log_attack = 1 - - if ("log_emote") - config.log_emote = 1 - - if ("log_adminchat") - config.log_adminchat = 1 - - if ("log_adminwarn") - config.log_adminwarn = 1 - - if ("log_pda") - config.log_pda = 1 - - if ("log_world_output") - config.log_world_output = 1 - - if ("log_hrefs") - config.log_hrefs = 1 - - if ("log_runtime") - config.log_runtime = 1 - - if ("roundstart_level_generation") - config.roundstart_level_generation = text2num(value) - - if ("no_click_cooldown") - config.no_click_cooldown = 1 - - if("allow_admin_ooccolor") - config.allow_admin_ooccolor = 1 - - if ("allow_vote_restart") - config.allow_vote_restart = 1 - - if ("allow_vote_mode") - config.allow_vote_mode = 1 - - if ("allow_admin_jump") - config.allow_admin_jump = 1 - - if("allow_admin_rev") - config.allow_admin_rev = 1 - - if ("allow_admin_spawning") - config.allow_admin_spawning = 1 - - if ("no_dead_vote") - config.vote_no_dead = 1 - - if ("no_dead_vote_crew_transfer") - config.vote_no_dead_crew_transfer = 1 - - if ("default_no_vote") - config.vote_no_default = 1 - - if ("vote_delay") - config.vote_delay = text2num(value) - - if ("vote_period") - config.vote_period = text2num(value) - - if ("vote_autotransfer_initial") - config.vote_autotransfer_initial = text2num(value) - - if ("vote_autotransfer_interval") - config.vote_autotransfer_interval = text2num(value) - - if ("vote_autogamemode_timeleft") - config.vote_autogamemode_timeleft = text2num(value) - - if("ert_admin_only") - config.ert_admin_call_only = 1 - - if ("allow_ai") - config.allow_ai = 1 - -// if ("authentication") -// config.enable_authentication = 1 - - if ("respawn_delay") - config.respawn_delay = text2num(value) - config.respawn_delay = config.respawn_delay > 0 ? config.respawn_delay : 0 - - if ("servername") - config.server_name = value - - if ("serversuffix") - config.server_suffix = 1 - - if ("hostedby") - config.hostedby = value - - if ("serverurl") - config.serverurl = value - - if ("server") - config.server = value - - if ("banappeals") - config.banappeals = value - - if ("wikiurl") - config.wikiurl = value - - if ("forumurl") - config.forumurl = value - - if ("discordurl") - config.discordurl = value - - if ("githuburl") - config.githuburl = value - - if ("issuereporturl") - config.issuereporturl = value - - if ("ghosts_can_possess_animals") - config.ghosts_can_possess_animals = value - - if ("guest_jobban") - config.guest_jobban = 1 - - if ("guest_ban") - config.guests_allowed = 0 - - if ("disable_ooc") - config.ooc_allowed = 0 - - if ("disable_looc") - config.looc_allowed = 0 - - if ("disable_aooc") - config.aooc_allowed = 0 - - if ("disable_entry") - config.enter_allowed = 0 - - if ("disable_dead_ooc") - config.dooc_allowed = 0 - - if ("disable_dsay") - config.dsay_allowed = 0 - - if ("disable_respawn") - config.abandon_allowed = 0 - - if ("usewhitelist") - config.usewhitelist = 1 - - if ("feature_object_spell_system") - config.feature_object_spell_system = 1 - - if ("traitor_scaling") - config.traitor_scaling = 1 - - if ("aliens_allowed") - config.aliens_allowed = 1 - - if("alien_eggs_allowed") - config.alien_eggs_allowed = 1 - - if ("ninjas_allowed") - config.ninjas_allowed = 1 - - if ("objectives_disabled") - if(!value) - log_misc("Could not find value for objectives_disabled in configuration.") - config.objectives_disabled = CONFIG_OBJECTIVE_NONE - else - switch(value) - if("none") - config.objectives_disabled = CONFIG_OBJECTIVE_NONE - if("verb") - config.objectives_disabled = CONFIG_OBJECTIVE_VERB - if("all") - config.objectives_disabled = CONFIG_OBJECTIVE_ALL - else - log_misc("Incorrect objective disabled definition: [value]") - config.objectives_disabled = CONFIG_OBJECTIVE_NONE - if("protect_roles_from_antagonist") - config.protect_roles_from_antagonist = 1 - - if ("probability") - var/prob_pos = findtext(value, " ") - var/prob_name = null - var/prob_value = null - - if (prob_pos) - prob_name = lowertext(copytext(value, 1, prob_pos)) - prob_value = copytext(value, prob_pos + 1) - if (prob_name in config.modes) - config.probabilities[prob_name] = text2num(prob_value) - else - log_misc("Unknown game mode probability configuration definition: [prob_name].") - else - log_misc("Incorrect probability configuration definition: [prob_name] [prob_value].") - - if("allow_random_events") - config.allow_random_events = 1 - - if("kick_inactive") - config.kick_inactive = text2num(value) - - if("mods_can_tempban") - config.mods_can_tempban = 1 - - if("mods_can_job_tempban") - config.mods_can_job_tempban = 1 - - if("mod_tempban_max") - config.mod_tempban_max = text2num(value) - - if("mod_job_tempban_max") - config.mod_job_tempban_max = text2num(value) - - if("load_jobs_from_txt") - load_jobs_from_txt = 1 - - if("forbid_singulo_possession") - forbid_singulo_possession = 1 - - if("popup_admin_pm") - config.popup_admin_pm = 1 - - if("allow_holidays") - config.allow_holidays = 1 - - if("use_irc_bot") - use_irc_bot = 1 - - if("ticklag") - var/ticklag = text2num(value) - if(ticklag > 0) - fps = 10 / ticklag - - if("fps") - fps = text2num(value) - - if("tick_limit_mc_init") - tick_limit_mc_init = text2num(value) - - if("allow_antag_hud") - config.antag_hud_allowed = 1 - if("antag_hud_restricted") - config.antag_hud_restricted = 1 - - if("secret_hide_possibilities") - secret_hide_possibilities = TRUE - - if("humans_need_surnames") - humans_need_surnames = 1 - - if("usealienwhitelist") - usealienwhitelist = 1 - if("usealienwhitelist_sql") // above need to be enabled as well - usealienwhitelistSQL = 1; - if("alien_player_ratio") - limitalienplayers = 1 - alien_to_human_ratio = text2num(value) - - if("assistant_maint") - config.assistant_maint = 1 - - if("gateway_delay") - config.gateway_delay = text2num(value) - - if("continuous_rounds") - config.continous_rounds = 1 - - if("ghost_interaction") - config.ghost_interaction = 1 - - if("disable_player_mice") - config.disable_player_mice = 1 - - if("uneducated_mice") - config.uneducated_mice = 1 - - if("comms_password") - config.comms_password = value - - if("ban_comms_password") - config.ban_comms_password = value - - if("forbidden_versions") - config.forbidden_versions = splittext(value, ";") - - if("minimum_byond_version") - config.minimum_byond_version = text2num(value) - - if("minimum_byond_build") - config.minimum_byond_build = text2num(value) - - if("login_export_addr") - config.login_export_addr = value - - if("irc_bot_host") - config.irc_bot_host = value - - if("main_irc") - config.main_irc = value - - if("admin_irc") - config.admin_irc = value - - if("announce_shuttle_dock_to_irc") - config.announce_shuttle_dock_to_irc = TRUE - - if("allow_cult_ghostwriter") - config.cult_ghostwriter = 1 - - if("req_cult_ghostwriter") - config.cult_ghostwriter_req_cultists = text2num(value) - - if("character_slots") - config.character_slots = text2num(value) - - if("loadout_slots") - config.loadout_slots = text2num(value) - - if("allow_drone_spawn") - config.allow_drone_spawn = text2num(value) - - if("drone_build_time") - config.drone_build_time = text2num(value) - - if("max_maint_drones") - config.max_maint_drones = text2num(value) - - if("expected_round_length") - config.expected_round_length = MinutesToTicks(text2num(value)) - - if("disable_welder_vision") - config.welder_vision = 0 - - if("disable_circuit_printing") - config.allow_ic_printing = FALSE - - if("allow_extra_antags") - config.allow_extra_antags = 1 - - if("event_custom_start_mundane") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_custom_start_moderate") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_custom_start_major") - var/values = text2numlist(value, ";") - config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) - - if("event_delay_lower") - var/values = text2numlist(value, ";") - config.event_delay_lower[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) - config.event_delay_lower[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) - config.event_delay_lower[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) - - if("event_delay_upper") - var/values = text2numlist(value, ";") - config.event_delay_upper[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1]) - config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) - config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) - - if("exterior_ambient_light") - value = text2num(value) - config.exterior_ambient_light = value >= 0 ? value : 0 - - if("law_zero") - law_zero = value - - if("aggressive_changelog") - config.aggressive_changelog = 1 - - if("delist_when_no_admins") - config.delist_when_no_admins = TRUE - - if("map_switching") - config.allow_map_switching = 1 - - if("disable_webhook_embeds") - config.disable_webhook_embeds = TRUE - - if("auto_map_vote") - config.auto_map_vote = 1 - - if("wait_for_sigusr1") - config.wait_for_sigusr1_reboot = 1 - - if("autostealth") - config.autostealth = text2num(value) - - if("auto_local_admin") - config.auto_local_admin = text2num(value) - - if("radiation_lower_limit") - radiation_lower_limit = text2num(value) - - if("error_cooldown") - error_cooldown = text2num(value) - if("error_limit") - error_limit = text2num(value) - if("error_silence_time") - error_silence_time = text2num(value) - if("error_msg_delay") - error_msg_delay = text2num(value) - - if("max_gear_cost") - max_gear_cost = text2num(value) - if(max_gear_cost < 0) - max_gear_cost = INFINITY - if("radiation_decay_rate") - radiation_decay_rate = text2num(value) - if("radiation_resistance_multiplier") - radiation_resistance_multiplier = text2num(value) - if("radiation_material_resistance_divisor") - radiation_material_resistance_divisor = text2num(value) - if("radiation_lower_limit") - radiation_lower_limit = text2num(value) - if("player_limit") - player_limit = text2num(value) - if("hub") - world.update_hub_visibility() - - if ("allow_unsafe_narrates") - config.allow_unsafe_narrates = TRUE - - if ("do_not_prevent_spam") - config.do_not_prevent_spam = TRUE - if ("max_acts_per_interval") - config.max_acts_per_interval = text2num(value) - if ("act_interval") - config.act_interval = text2num(value) SECONDS - - if("panic_bunker") - config.panic_bunker = TRUE - if("panic_bunker_message") - config.panic_bunker_message = value - - if("no_throttle_localhost") - config.no_throttle_localhost = TRUE - - if("show_typing_indicator_for_whispers") - config.show_typing_indicator_for_whispers = TRUE - - if("visible_examine") - config.visible_examine = text2num(value) - - if("allow_loadout_customization") - config.allow_loadout_customization = TRUE - - else - //crappy hook to get modpacks to load any extra config - if(!load_mod_config(name, value)) - log_misc("Unknown setting in configuration: '[name]'") - - else if(type == "game_options") - if(!value) - log_misc("Unknown value for setting [name] in [filename].") - value = text2num(value) - - switch(name) - if("show_human_death_message") - config.show_human_death_message = TRUE - if ("max_character_aspects") - config.max_character_aspects = text2num(value) - if("health_threshold_dead") - config.health_threshold_dead = value - if("revival_pod_plants") - config.revival_pod_plants = value - if("revival_cloning") - config.revival_cloning = value - if("revival_brain_life") - config.revival_brain_life = value - if("organ_health_multiplier") - config.organ_health_multiplier = value / 100 - if("organ_regeneration_multiplier") - config.organ_regeneration_multiplier = value / 100 - if("organ_damage_spillover_multiplier") - config.organ_damage_spillover_multiplier = value / 100 - if("organs_can_decay") - config.organs_decay = 1 - if("bones_can_break") - config.bones_can_break = value - if("limbs_can_break") - config.limbs_can_break = value - - if("run_delay") - config.run_delay = value - if("walk_delay") - config.walk_delay = value - if("creep_delay") - config.creep_delay = value - if("glide_size_delay") - config.glide_size_delay = value - if("minimum_sprint_cost") - config.minimum_sprint_cost = value - if("skill_sprint_cost_range") - config.skill_sprint_cost_range = value - if("minimum_stamina_recovery") - config.minimum_stamina_recovery = value - if("maximum_stamina_recovery") - config.maximum_stamina_recovery = value - - if("human_delay") - config.human_delay = value - if("robot_delay") - config.robot_delay = value - if("monkey_delay") - config.monkey_delay = value - if("alien_delay") - config.alien_delay = value - if("slime_delay") - config.slime_delay = value - if("animal_delay") - config.animal_delay = value - if("maximum_mushrooms") - config.maximum_mushrooms = value - - if("lock_client_view_x") - config.lock_client_view_x = text2num(value) - if("lock_client_view_y") - config.lock_client_view_y = text2num(value) - if("max_client_view_x") - config.max_client_view_x = text2num(value) - if("max_client_view_y") - config.max_client_view_y = text2num(value) - - if("allow_diagonal_movement") - config.allow_diagonal_movement = TRUE - - if("use_loyalty_implants") - config.use_loyalty_implants = 1 - if("dexterity_malus_brainloss_threshold") - config.dex_malus_brainloss_threshold = text2num(value) - if("grant_default_darksight") - config.grant_default_darksight = TRUE - if("default_darksight_range") - config.default_darksight_range = max(text2num(value), 0) - if("default_darksight_effectiveness") - config.default_darksight_effectiveness = clamp(text2num(value), 0, 1) - - if("adjust_healing_from_stress") - config.adjust_healing_from_stress = TRUE - if("stress_shock_recovery_constant") - config.stress_shock_recovery_constant = text2num(value) - if("stress_healing_recovery_constant") - config.stress_healing_recovery_constant = text2num(value) - if("stress_blood_recovery_constant") - config.stress_blood_recovery_constant = text2num(value) - - - - if("exoplanet_min_day_duration") - config.exoplanet_min_day_duration = text2num(value) - if("exoplanet_max_day_duration") - config.exoplanet_max_day_duration = text2num(value) - if("disable_daycycle") - config.disable_daycycle = TRUE - - else - //crappy hook to get modpacks to load any extra config - if(!load_mod_config(name, value)) - log_misc("Unknown setting in game_options configuration: '[name]'") - - fps = round(fps) - if(fps <= 0) - fps = initial(fps) - -/datum/configuration/proc/loadsql(filename) // -- TLE - var/list/Lines = file2list(filename) - for(var/t in Lines) - if(!t) continue - - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if (!name) - continue - - switch (name) - if ("enabled") - sqlenabled = TRUE - if ("address") - sqladdress = value - if ("port") - sqlport = value - if ("database") - sqldb = value - if ("login") - sqllogin = value - if ("password") - sqlpass = value - else - //crappy hook to get modpacks to load any extra config - if(!load_mod_dbconfig(name, value)) - log_misc("Unknown setting in DB configuration: '[name]'") - -/datum/configuration/proc/get_runnable_modes() - . = list() - var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) - for(var/mode_type in all_modes) - var/decl/game_mode/game_mode = all_modes[mode_type] - if(!game_mode.startRequirements() && !isnull(config.probabilities[game_mode.uid]) && config.probabilities[game_mode.uid] > 0) - .[game_mode.uid] = config.probabilities[game_mode.uid] - -/datum/configuration/proc/load_event(filename) - var/event_info = safe_file2text(filename, FALSE) - if(event_info) - custom_event_msg = event_info - -///Hook stub for loading modpack specific configs. Just override in modpack. -/datum/configuration/proc/load_mod_config(var/name, var/value) - //Force it to run parents overrides, so other modpacks don't just completely break config loading for one another - SHOULD_CALL_PARENT(TRUE) - return - -///Hook stub for loading modpack specific game_options. Just override in modpack. -/datum/configuration/proc/load_mod_game_options(var/name, var/value) - SHOULD_CALL_PARENT(TRUE) - return - -///Hook stub for loading modpack specific dbconfig. Just override in modpack. -/datum/configuration/proc/load_mod_dbconfig(var/name, var/value) - SHOULD_CALL_PARENT(TRUE) - return diff --git a/code/controllers/evacuation/evacuation.dm b/code/controllers/evacuation/evacuation.dm index 31495e484d5..69eeb9bc5bc 100644 --- a/code/controllers/evacuation/evacuation.dm +++ b/code/controllers/evacuation/evacuation.dm @@ -131,7 +131,7 @@ evac_waiting.Announce(replacetext(global.using_map.emergency_shuttle_docked_message, "%ETD%", "[estimated_time] minute\s"), new_sound = sound('sound/effects/Evacuation.ogg', volume = 35)) else priority_announcement.Announce(replacetext(replacetext(global.using_map.shuttle_docked_message, "%dock_name%", "[global.using_map.dock_name]"), "%ETD%", "[estimated_time] minute\s")) - if(config.announce_shuttle_dock_to_irc) + if(get_config_value(/decl/config/toggle/announce_shuttle_dock_to_irc)) send2mainirc("The shuttle has docked with the station. It will depart in approximately [estimated_time] minute\s.") /datum/evacuation_controller/proc/launch_evacuation() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 5555d4efcef..fc55af0e232 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -176,7 +176,7 @@ var/global/datum/controller/master/Master = new var/start_timeofday = REALTIMEOFDAY // Initialize subsystems. - current_ticklimit = config.tick_limit_mc_init + current_ticklimit = get_config_value(/decl/config/num/tick_limit_mc_init) for (var/datum/controller/subsystem/SS in subsystems) if (SS.flags & SS_NO_INIT) continue @@ -202,11 +202,12 @@ var/global/datum/controller/master/Master = new #else world.sleep_offline = TRUE #endif - if(world.fps != config.fps) - world.fps = config.fps + var/old_fps = world.fps + world.fps = get_config_value(/decl/config/num/fps) + if(old_fps != world.fps) SStimer.reset_buckets() - var/initialized_tod = REALTIMEOFDAY + var/initialized_tod = REALTIMEOFDAY initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 // Loop. Master.StartProcessing(0) diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index a595e9fda63..cb1858d43f1 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -43,6 +43,8 @@ var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out! + var/_internal_name //! A stringified version of the variable name for this subsystem. Used by the processing subsystem to make sure is_processing is unset properly. + //Do not override ///datum/controller/subsystem/New() diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index 9b4686505cb..582d653bd73 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -172,6 +172,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun var/list/curr_hotspot = processing_hotspots var/list/curr_zones = zones_to_update + var/airblock // zeroed by ATMOS_CANPASS_TURF, declared early as microopt while (curr_tiles.len) var/turf/T = curr_tiles[curr_tiles.len] curr_tiles.len-- @@ -185,9 +186,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun continue //check if the turf is self-zone-blocked - var/c_airblock - ATMOS_CANPASS_TURF(c_airblock, T, T) - if(c_airblock & ZONE_BLOCKED) + ATMOS_CANPASS_TURF(airblock, T, T) + if(airblock & ZONE_BLOCKED) deferred += T if (no_mc_tick) CHECK_TICK diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 67b1de5e258..a8330cb1d9f 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -66,6 +66,7 @@ SUBSYSTEM_DEF(atoms) for(var/I in late_loaders) var/atom/A = I A.LateInitialize(arglist(late_loaders[A])) + CHECK_TICK report_progress("Late initialized [late_loaders.len] atom\s") late_loaders.Cut() diff --git a/code/controllers/subsystems/configuration.dm b/code/controllers/subsystems/configuration.dm new file mode 100644 index 00000000000..b342f71f85d --- /dev/null +++ b/code/controllers/subsystems/configuration.dm @@ -0,0 +1,156 @@ +SUBSYSTEM_DEF(configuration) + name = "Configuration" + flags = SS_NO_FIRE | SS_NO_INIT + var/list/configuration_file_locations = list() + var/load_sql_from = "config/dbconfig.txt" + var/load_event_from = "config/custom_event.txt" + +/datum/controller/subsystem/configuration/proc/load_all_configuration() + + // Assemble a list of all the files we are expected to load this run. + var/list/all_config = decls_repository.get_decls_of_subtype(/decl/configuration_category) + for(var/config_cat_type in all_config) + var/decl/configuration_category/config_cat = all_config[config_cat_type] + configuration_file_locations |= config_cat.configuration_file_location + + load_files() + load_sql() + load_event() + + for(var/client/C) + C.update_post_config_load() + +/client/proc/update_post_config_load() + if(get_config_value(/decl/config/toggle/allow_character_comments)) + verbs |= /client/proc/view_character_information + else + verbs -= /client/proc/view_character_information + +/datum/controller/subsystem/configuration/proc/write_default_configuration(var/list/specific_files, var/modify_write_prefix) + + if(!specific_files) + specific_files = configuration_file_locations + else if(!islist(specific_files)) + specific_files = list(specific_files) + + if(!length(specific_files)) + return + + var/list/config_lines = list() + var/list/all_config = decls_repository.get_decls_of_subtype(/decl/configuration_category) + var/list/sorted_config = list() + for(var/config_type in all_config) + sorted_config += all_config[config_type] + for(var/decl/configuration_category/config_cat as anything in sortTim(sorted_config, /proc/cmp_name_asc)) + if(!(config_cat.configuration_file_location in specific_files)) + continue + LAZYADD(config_lines["[modify_write_prefix][config_cat.configuration_file_location]"], config_cat.get_config_category_text()) + + . = list() + for(var/filename in config_lines) + if(fexists(filename)) + fdel(filename) + var/write_file = file(filename) + to_file(write_file, jointext(config_lines[filename], "\n\n")) + . += filename + return length(.) ? english_list(.) : "NULL" + +/datum/controller/subsystem/configuration/proc/load_files() + + // Load values from file into an assoc list. + var/list/loaded_values = list() + var/list/write_defaults = list() + for(var/filename in configuration_file_locations) + + if(!fexists(filename)) + write_defaults += filename + continue + + var/list/lines = file2list(filename) + for(var/line in lines) + line = trim(line) + if(!line || length(line) == 0 || copytext(line, 1, 2) == "#") + continue + var/pos = findtext(line, " ") + var/config_key + var/config_value + if(pos) + config_key = copytext(line, 1, pos) + config_value = copytext(line, pos + 1) + else + config_key = line + config_value = TRUE + if(config_key) + config_key = lowertext(trim(config_key)) + if(config_key in loaded_values) + PRINT_STACK_TRACE("Duplicate config value loaded for key '[config_key]' from file '[filename]'.") + loaded_values[config_key] = config_value + + // Write any defaults that aren't already populated. + if(length(write_defaults)) + write_default_configuration(write_defaults) + + // Set our config values on the decls. + var/list/config_to_refresh = list() + var/list/all_config_decls = decls_repository.get_decls_of_subtype(/decl/config) + for(var/config_type in all_config_decls) + var/decl/config/config_option = all_config_decls[config_type] + if(config_option.uid in loaded_values) + if(set_config_value(config_type, loaded_values[config_option.uid], defer_config_refresh = TRUE)) + config_to_refresh += config_option + loaded_values -= config_option.uid + + // Do a refresh now that all values are populated. + for(var/decl/config/config_option as anything in config_to_refresh) + config_option.update_post_value_set() + +/datum/controller/subsystem/configuration/proc/load_event(filename) + var/event_info = safe_file2text(filename, FALSE) + if(event_info) + global.custom_event_msg = event_info + +/datum/controller/subsystem/configuration/proc/load_sql() + var/list/lines = file2list(load_sql_from) + for(var/line in lines) + if(!line) + continue + line = trim(line) + if (length(line) == 0 || copytext(line, 1, 2) == "#") + continue + + var/pos = findtext(line, " ") + var/name = null + var/value = null + if (pos) + name = lowertext(copytext(line, 1, pos)) + value = copytext(line, pos + 1) + else + name = lowertext(line) + if (!name) + continue + + switch (name) + if ("enabled") + sqlenabled = TRUE + if ("address") + sqladdress = value + if ("port") + sqlport = value + if ("database") + sqldb = value + if ("login") + sqllogin = value + if ("password") + sqlpass = value + else + log_misc("Unknown setting in configuration: '[name]'") + +/datum/admins/proc/dump_configuration() + set category = "Admin" + set name = "Dump Configuration" + set desc = "Writes out the current configuration to file." + if(!ishost(usr?.client)) + to_chat(usr, SPAN_WARNING("This verb can only be used by the host.")) + return + var/write_loc = SSconfiguration.write_default_configuration(modify_write_prefix = "temp/") + to_chat(usr, SPAN_NOTICE("All done! The configuration file has been written to [write_loc] on your host.")) diff --git a/code/controllers/subsystems/daycycle.dm b/code/controllers/subsystems/daycycle.dm index 5a725b0c625..15ba9d24bdf 100644 --- a/code/controllers/subsystems/daycycle.dm +++ b/code/controllers/subsystems/daycycle.dm @@ -13,7 +13,7 @@ SUBSYSTEM_DEF(daycyle) ///Adds a set of levels that should all be updated at the same time and share the same day state /datum/controller/subsystem/daycyle/proc/add_linked_levels(var/list/level_ids, var/start_at_night = FALSE, var/update_interval = 5 MINUTES) - if(global.config.disable_daycycle) + if(get_config_value(/decl/config/toggle/disable_daycycle)) return //If disabled, we don't add anything var/topmost_level_id = level_ids[1] if(LAZYISIN(registered_levels, topmost_level_id)) @@ -26,7 +26,7 @@ SUBSYSTEM_DEF(daycyle) LAZYREMOVE(registered_levels, topmost_level_id) /datum/controller/subsystem/daycyle/fire(resumed = 0) - if(global.config.disable_daycycle) + if(get_config_value(/decl/config/toggle/disable_daycycle)) disable() LAZYCLEARLIST(current_run) return //If disabled, we shouldn't fire diff --git a/code/controllers/subsystems/event.dm b/code/controllers/subsystems/event.dm index 96c0b4a2cad..f3a5bd29ca3 100644 --- a/code/controllers/subsystems/event.dm +++ b/code/controllers/subsystems/event.dm @@ -60,7 +60,7 @@ SUBSYSTEM_DEF(event) while (pos <= EVENT_LEVEL_MAJOR) event_containers[pos].process() pos++ - + if (MC_TICK_CHECK) return @@ -109,17 +109,18 @@ SUBSYSTEM_DEF(event) if(E.isRunning) message += "and is still running." else - if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes + if(E.endedAt - E.startedAt > 5 MINUTES) // Only mention end time if the entire duration was more than 5 minutes message += "and ended at [worldtime2stationtime(E.endedAt)]." else message += "and ran to completion." to_world(message) -//Event manager UI +//Event manager UI /datum/controller/subsystem/event/proc/GetInteractWindow() + var/allow_random_events = get_config_value(/decl/config/toggle/allow_random_events) var/html = "Refresh" - html += "Pause All - [config.allow_random_events ? "Pause" : "Resume"]" + html += "Pause All - [allow_random_events ? "Pause" : "Resume"]" if(selected_event_container) var/event_time = max(0, selected_event_container.next_event_time - world.time) @@ -253,8 +254,8 @@ SUBSYSTEM_DEF(event) EC.delayed = !EC.delayed log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.") else if(href_list["pause_all"]) - config.allow_random_events = text2num(href_list["pause_all"]) - log_and_message_admins("has [config.allow_random_events ? "resumed" : "paused"] countdown for all events.") + set_config_value(/decl/config/toggle/allow_random_events, text2num(href_list["pause_all"])) + log_and_message_admins("has [get_config_value(/decl/config/toggle/allow_random_events) ? "resumed" : "paused"] countdown for all events.") else if(href_list["interval"]) var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null if(delay && delay > 0) diff --git a/code/controllers/subsystems/fluids.dm b/code/controllers/subsystems/fluids.dm index f9671d442ed..547a1029c01 100644 --- a/code/controllers/subsystems/fluids.dm +++ b/code/controllers/subsystems/fluids.dm @@ -3,6 +3,7 @@ SUBSYSTEM_DEF(fluids) wait = 1 SECOND priority = SS_PRIORITY_FLUIDS flags = SS_NO_INIT + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT // So we can flush our queued activity during lobby setup on ocean maps. var/tmp/list/water_sources = list() var/tmp/fluid_sources_copied_yet = FALSE @@ -20,7 +21,6 @@ SUBSYSTEM_DEF(fluids) var/tmp/active_fluids_copied_yet = FALSE var/tmp/list/processing_fluids - var/tmp/list/fluid_images = list() var/tmp/list/checked_targets = list() var/tmp/list/gurgles = list( 'sound/effects/gurgle1.ogg', @@ -34,27 +34,6 @@ SUBSYSTEM_DEF(fluids) /datum/controller/subsystem/fluids/fire(resumed = 0) - // Predeclaring a bunch of vars for performance purposes. - var/obj/effect/fluid/other_fluid = null - var/obj/effect/fluid/current_fluid = null - var/datum/reagents/reagent_holder = null - var/list/candidates = null - var/turf/below = null - var/turf/current_turf = null - var/turf/neighbor = null - var/turf/lowest_neighbor = null - - var/removing = 0 - var/spread_dir = 0 - var/coming_from = 0 - var/flow_amount = 0 - var/current_depth = 0 - var/current_turf_depth = 0 - var/neighbor_depth = 0 - var/lowest_neighbor_flow = 0 - var/flooded_a_neighbor = FALSE - var/lowest_neighbor_depth = INFINITY - if(!resumed) active_fluids_copied_yet = FALSE holders_copied_yet = FALSE @@ -66,17 +45,25 @@ SUBSYSTEM_DEF(fluids) fluid_sources_copied_yet = TRUE processing_sources = water_sources.Copy() - while(processing_sources.len) - - current_turf = processing_sources[processing_sources.len] - processing_sources.len-- + // Predeclaring a bunch of vars for performance purposes. + var/flooded_a_neighbor = FALSE + var/spread_dir = 0 + var/i = 0 + var/turf/current_fluid_holder = null + var/datum/reagents/reagent_holder = null + var/turf/neighbor = null + var/turf/lowest_neighbor = null + + while(i < processing_sources.len) + i++ + current_fluid_holder = processing_sources[i] flooded_a_neighbor = FALSE - UPDATE_FLUID_BLOCKED_DIRS(current_turf) + UPDATE_FLUID_BLOCKED_DIRS(current_fluid_holder) for(spread_dir in global.cardinal) - if(current_turf.fluid_blocked_dirs & spread_dir) + if(current_fluid_holder.fluid_blocked_dirs & spread_dir) continue - neighbor = get_step(current_turf, spread_dir) + neighbor = get_step(current_fluid_holder, spread_dir) if(!istype(neighbor) || neighbor.flooded) continue UPDATE_FLUID_BLOCKED_DIRS(neighbor) @@ -84,158 +71,170 @@ SUBSYSTEM_DEF(fluids) continue checked_targets[neighbor] = TRUE flooded_a_neighbor = TRUE - neighbor.add_fluid(/decl/material/liquid/water, FLUID_MAX_DEPTH) + neighbor.add_to_reagents(current_fluid_holder.flooded, FLUID_MAX_DEPTH) if(!flooded_a_neighbor) - REMOVE_ACTIVE_FLUID_SOURCE(current_turf) + REMOVE_ACTIVE_FLUID_SOURCE(current_fluid_holder) if (MC_TICK_CHECK) + processing_sources.Cut(1, i+1) return + processing_sources.Cut() if(!active_fluids_copied_yet) active_fluids_copied_yet = TRUE processing_fluids = active_fluids.Copy() - while(processing_fluids.len) - - current_fluid = processing_fluids[processing_fluids.len] - processing_fluids.len-- - - REMOVE_ACTIVE_FLUID(current_fluid) // This will be refreshed if our level changes at all in this iteration of the subsystem. - - if(QDELETED(current_fluid)) + var/removing = 0 + var/coming_from = 0 + var/flow_amount = 0 + var/current_depth = 0 + var/current_turf_depth = 0 + var/neighbor_depth = 0 + var/lowest_neighbor_flow = 0 + var/lowest_neighbor_depth = INFINITY + var/turf/other_fluid_holder = null + + i = 0 + while(i < processing_fluids.len) + i++ + current_fluid_holder = processing_fluids[i] + + if(QDELETED(current_fluid_holder) || !current_fluid_holder.reagents?.total_volume) + REMOVE_ACTIVE_FLUID(current_fluid_holder) continue - current_turf = current_fluid.loc - if(!current_turf.CanFluidPass()) - qdel(current_fluid) + if(!current_fluid_holder.CanFluidPass()) + current_fluid_holder.displace_all_reagents() continue - reagent_holder = current_fluid.reagents - UPDATE_FLUID_BLOCKED_DIRS(current_turf) + reagent_holder = current_fluid_holder.reagents + UPDATE_FLUID_BLOCKED_DIRS(current_fluid_holder) current_depth = reagent_holder?.total_volume || 0 // How is this happening if(QDELETED(reagent_holder) || current_depth == -1.#IND || current_depth == 1.#IND) - qdel(current_fluid) + REMOVE_ACTIVE_FLUID(current_fluid_holder) continue - // Evaporation: todo, move liquid into current_turf.zone air contents if applicable. + // Evaporation: todo, move liquid into current_fluid_holder.zone air contents if applicable. if(current_depth <= FLUID_PUDDLE && prob(60)) - current_turf.remove_fluids(min(current_depth, 1), defer_update = TRUE) - current_depth = current_turf.get_fluid_depth() + current_fluid_holder.remove_fluids(min(current_depth, 1), defer_update = TRUE) + current_depth = current_fluid_holder.get_fluid_depth() if(current_depth <= FLUID_QDEL_POINT) - qdel(current_fluid) + current_fluid_holder.reagents?.clear_reagents() + REMOVE_ACTIVE_FLUID(current_fluid_holder) continue // Wash our turf. - current_turf.fluid_act(reagent_holder) + current_fluid_holder.fluid_act(reagent_holder) - if(isspaceturf(current_turf) || istype(current_turf, /turf/exterior)) + if(isspaceturf(current_fluid_holder) || istype(current_fluid_holder, /turf/exterior)) removing = round(current_depth * 0.5) if(removing > 0) - current_turf.remove_fluids(removing, defer_update = TRUE) + current_fluid_holder.remove_fluids(removing, defer_update = TRUE) else reagent_holder.clear_reagents() - current_depth = current_turf.get_fluid_depth() + current_depth = current_fluid_holder.get_fluid_depth() if(current_depth <= FLUID_QDEL_POINT) - qdel(current_fluid) + current_fluid_holder.reagents?.clear_reagents() + REMOVE_ACTIVE_FLUID(current_fluid_holder) continue - if(!(current_turf.fluid_blocked_dirs & DOWN) && current_turf.CanFluidPass(DOWN) && current_turf.is_open() && current_turf.has_gravity()) - below = GetBelow(current_turf) - if(below) - UPDATE_FLUID_BLOCKED_DIRS(below) - if(!(below.fluid_blocked_dirs & UP) && below.CanFluidPass(UP)) - other_fluid = locate() in below - if(!other_fluid) - other_fluid = new(below) - if(!QDELETED(other_fluid) && other_fluid.reagents.total_volume < FLUID_MAX_DEPTH) - current_turf.transfer_fluids_to(below, min(FLOOR(current_depth*0.5), FLUID_MAX_DEPTH - other_fluid.reagents.total_volume), defer_update = TRUE) - current_depth = current_turf.get_fluid_depth() - - if(current_depth <= FLUID_PUDDLE) - continue + if(!(current_fluid_holder.fluid_blocked_dirs & DOWN) && current_fluid_holder.CanFluidPass(DOWN) && current_fluid_holder.is_open() && current_fluid_holder.has_gravity()) + other_fluid_holder = GetBelow(current_fluid_holder) + if(other_fluid_holder) + UPDATE_FLUID_BLOCKED_DIRS(other_fluid_holder) + if(!(other_fluid_holder.fluid_blocked_dirs & UP) && other_fluid_holder.CanFluidPass(UP)) + if(!QDELETED(other_fluid_holder) && other_fluid_holder.reagents?.total_volume < FLUID_MAX_DEPTH) + current_fluid_holder.transfer_fluids_to(other_fluid_holder, min(FLOOR(current_depth*0.5), FLUID_MAX_DEPTH - other_fluid_holder.reagents?.total_volume), defer_update = TRUE) + current_depth = current_fluid_holder.get_fluid_depth() // Flow into the lowest level neighbor. lowest_neighbor_depth = INFINITY lowest_neighbor_flow = 0 - candidates = list() - current_turf_depth = current_depth + current_turf.get_physical_height() + current_turf_depth = current_depth + current_fluid_holder.get_physical_height() for(spread_dir in global.cardinal) - if(current_turf.fluid_blocked_dirs & spread_dir) + if(current_fluid_holder.fluid_blocked_dirs & spread_dir) continue - neighbor = get_step(current_turf, spread_dir) + neighbor = get_step(current_fluid_holder, spread_dir) if(!neighbor) continue UPDATE_FLUID_BLOCKED_DIRS(neighbor) coming_from = global.reverse_dir[spread_dir] if((neighbor.fluid_blocked_dirs & coming_from) || !neighbor.CanFluidPass(coming_from) || neighbor.is_flooded(absolute = TRUE) || !neighbor.CanFluidPass(global.reverse_dir[spread_dir])) continue - other_fluid = locate() in neighbor - - neighbor_depth = (other_fluid?.reagents?.total_volume || 0) + neighbor.get_physical_height() + other_fluid_holder = neighbor + neighbor_depth = (other_fluid_holder?.reagents?.total_volume || 0) + neighbor.get_physical_height() flow_amount = round((current_turf_depth - neighbor_depth)*0.5) - + // TODO: multiply flow amount or minimum transfer amount by some + // viscosity calculation to allow for piles of jelly vs piles of water. if(flow_amount <= FLUID_MINIMUM_TRANSFER) continue - if(neighbor_depth < lowest_neighbor_depth) - candidates = list(neighbor) + ADD_ACTIVE_FLUID(neighbor) + if(neighbor_depth < lowest_neighbor_depth || (neighbor_depth == lowest_neighbor_depth && prob(50))) + lowest_neighbor = neighbor lowest_neighbor_depth = neighbor_depth lowest_neighbor_flow = flow_amount - else if(neighbor_depth == lowest_neighbor_depth) - candidates += neighbor - if(length(candidates)) - lowest_neighbor = pick(candidates) - current_turf.transfer_fluids_to(lowest_neighbor, lowest_neighbor_flow, defer_update = TRUE) - pending_flows[current_fluid] = TRUE + if(current_depth <= FLUID_PUDDLE) + continue - if(lowest_neighbor_flow >= FLUID_PUSH_THRESHOLD) - current_fluid.last_flow_strength = lowest_neighbor_flow - current_fluid.last_flow_dir = get_dir(current_turf, lowest_neighbor) + if(lowest_neighbor) + current_fluid_holder.transfer_fluids_to(lowest_neighbor, lowest_neighbor_flow, defer_update = TRUE) + pending_flows[current_fluid_holder] = TRUE + if(lowest_neighbor_flow >= FLUID_PUSH_THRESHOLD) + current_fluid_holder.last_flow_strength = lowest_neighbor_flow + current_fluid_holder.last_flow_dir = get_dir(current_fluid_holder, lowest_neighbor) + else + current_fluid_holder.last_flow_strength = 0 + current_fluid_holder.last_flow_dir = 0 else - current_fluid.last_flow_strength = 0 - current_fluid.last_flow_dir = 0 + // We aren't interacting with a neighbor this time, so we can likely sleep. + REMOVE_ACTIVE_FLUID(current_fluid_holder) if (MC_TICK_CHECK) - break + processing_fluids.Cut(1, i+1) + return + processing_fluids.Cut() if(!holders_copied_yet) holders_copied_yet = TRUE processing_holders = holders_to_update.Copy() - while(processing_holders.len) - reagent_holder = processing_holders[processing_holders.len] - processing_holders.len-- - if(!QDELETED(reagent_holder)) - reagent_holder.handle_update() - else - holders_to_update -= reagent_holder + i = 0 + while(i < processing_holders.len) + i++ + reagent_holder = processing_holders[i] + reagent_holder.handle_update() if(MC_TICK_CHECK) + processing_holders.Cut(1, i+1) return + processing_holders.Cut() if(!flows_copied_yet) flows_copied_yet = TRUE processing_flows = pending_flows.Copy() - while(processing_flows.len) - current_fluid = processing_flows[processing_flows.len] - processing_flows.len-- - if(!istype(current_fluid) || QDELETED(current_fluid) || !isturf(current_fluid.loc)) + i = 0 + while(i < processing_flows.len) + i++ + current_fluid_holder = processing_flows[i] + if(!istype(current_fluid_holder) || QDELETED(current_fluid_holder)) continue - reagent_holder = current_fluid.reagents - current_turf = current_fluid.loc + reagent_holder = current_fluid_holder.reagents var/pushed_something = FALSE - if(reagent_holder.total_volume > FLUID_SHALLOW && current_fluid.last_flow_strength >= 10) - for(var/atom/movable/AM as anything in current_turf.get_contained_external_atoms()) - if(AM.is_fluid_pushable(current_fluid.last_flow_strength)) - AM.pushed(current_fluid.last_flow_dir) + if(reagent_holder.total_volume > FLUID_SHALLOW && current_fluid_holder.last_flow_strength >= 10) + for(var/atom/movable/AM as anything in current_fluid_holder.get_contained_external_atoms()) + if(AM.is_fluid_pushable(current_fluid_holder.last_flow_strength)) + AM.pushed(current_fluid_holder.last_flow_dir) pushed_something = TRUE if(pushed_something && prob(1)) - playsound(current_fluid.loc, 'sound/effects/slosh.ogg', 25, 1) + playsound(current_fluid_holder, 'sound/effects/slosh.ogg', 25, 1) if(MC_TICK_CHECK) + processing_flows.Cut(1, i+1) return + processing_flows.Cut() /datum/controller/subsystem/fluids/StartLoadingMap() suspend() diff --git a/code/controllers/subsystems/inactivity.dm b/code/controllers/subsystems/inactivity.dm index 5e80377274c..8ba84003468 100644 --- a/code/controllers/subsystems/inactivity.dm +++ b/code/controllers/subsystems/inactivity.dm @@ -7,7 +7,8 @@ SUBSYSTEM_DEF(inactivity) var/number_kicked = 0 /datum/controller/subsystem/inactivity/fire(resumed = FALSE) - if (!config.kick_inactive) + var/kick_inactive_time = get_config_value(/decl/config/num/kick_inactive) MINUTES + if (!kick_inactive_time) suspend() return if (!resumed) @@ -16,9 +17,9 @@ SUBSYSTEM_DEF(inactivity) while(client_list.len) var/client/C = client_list[client_list.len] client_list.len-- - if(!C.holder && C.is_afk(config.kick_inactive MINUTES) && !isobserver(C.mob)) + if(!C.holder && C.is_afk(kick_inactive_time) && !isobserver(C.mob)) log_access("AFK: [key_name(C)]") - to_chat(C, "You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.") + to_chat(C, SPAN_WARNING("You have been inactive for more than [kick_inactive_time] minute\s and have been disconnected.")) qdel(C) number_kicked++ if (MC_TICK_CHECK) diff --git a/code/controllers/subsystems/initialization/character_info.dm b/code/controllers/subsystems/initialization/character_info.dm new file mode 100644 index 00000000000..813f1fda5d8 --- /dev/null +++ b/code/controllers/subsystems/initialization/character_info.dm @@ -0,0 +1,189 @@ +// Holder subsystem for character comment records. +SUBSYSTEM_DEF(character_info) + name = "Character Information" + flags = SS_NEEDS_SHUTDOWN + init_order = SS_INIT_EARLY + wait = 1 SECOND + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT // We want to save changes made during pre-round lobby. + var/static/comments_source = "data/character_info/" + var/list/_comment_holders_by_id = list() + var/list/_ids_to_save = list() + +/datum/controller/subsystem/character_info/Initialize() + . = ..() + if(!get_config_value(/decl/config/toggle/allow_character_comments)) + report_progress("Skipping mass load of character records as character comments are disabled.") + return + if(!fexists(comments_source)) + report_progress("Character information directory [comments_source] does not exist, no character comments will be saved or loaded.") + return + var/loaded_json_manifest = load_text_from_directory(comments_source, ".json") + if(!islist(loaded_json_manifest) || !length(loaded_json_manifest["files"])) + return + var/list/loaded_files = loaded_json_manifest["files"] + var/loaded_comments = 0 + for(var/loaded_file in loaded_files) + var/datum/character_information/comments = load_record(loaded_files[loaded_file]) + if(!istext(comments.record_id)) + PRINT_STACK_TRACE("Deserialized character information had invalid id '[comments.record_id || "NULL"]'!") + continue + + // Remove any pre-created records (early joiners, etc.) + if(_comment_holders_by_id[comments.record_id]) + var/old_record = _comment_holders_by_id[comments.record_id] + _comment_holders_by_id -= comments.record_id + qdel(old_record) + + comments.file_location = loaded_file + _comment_holders_by_id[comments.record_id] = comments + loaded_comments += length(comments.comments) + report_progress("Loaded [loaded_comments] record\s for [length(_comment_holders_by_id)] character\s.") + +/datum/controller/subsystem/character_info/Shutdown() + . = ..() + for(var/id in _comment_holders_by_id) + save_record(id) + +/datum/controller/subsystem/character_info/stat_entry(msg) + ..("R:[_comment_holders_by_id.len]Q:[_ids_to_save.len][msg]") + +/datum/controller/subsystem/character_info/fire(resumed = FALSE, no_mc_tick = FALSE) + while(_ids_to_save.len) + var/id = _ids_to_save[1] + _ids_to_save -= id + save_record(id) + if(TICK_CHECK) + return + +/datum/controller/subsystem/character_info/proc/queue_to_save(var/record_id) + if(istext(record_id) && length(record_id)) + _ids_to_save |= record_id + +/datum/controller/subsystem/character_info/proc/save_record(var/record_id) + if(!istext(record_id) || !record_id) + return + var/datum/character_information/comments = get_record(record_id, TRUE) + if(!istype(comments)) + return + if(!comments.file_location) + comments.file_location = "[comments_source][ckey(comments.record_id)].json" + try + if(fexists(comments.file_location)) + fdel(comments.file_location) + to_file(file(comments.file_location), comments.serialize_to_json()) + catch(var/exception/E) + PRINT_STACK_TRACE("Exception when writing out character information file to [comments?.file_location || "NULL"]: [E]") + +/datum/controller/subsystem/character_info/proc/load_record(var/load_from) + var/datum/character_information/comments = new(cached_json_decode(load_from)) + _comment_holders_by_id[comments.record_id] = comments + return comments + +/datum/controller/subsystem/character_info/proc/reload_record(var/record_id) + var/datum/character_information/comments = get_record(record_id, TRUE) + if(comments && comments.file_location && fexists(comments.file_location)) + var/reload_from = comments.file_location + _comment_holders_by_id -= comments.record_id + qdel(comments) + try + . = load_record(safe_file2text(reload_from)) + catch(var/exception/E) + PRINT_STACK_TRACE("Exception when reloading record from [reload_from]: [E]") + +/datum/controller/subsystem/character_info/proc/clear_record(var/record_id) + var/datum/character_information/comments = get_record(record_id, TRUE) + if(comments) + comments.comments.Cut() + comments.ic_info = null + comments.ooc_info = null + +/datum/controller/subsystem/character_info/proc/get_record_id(var/record_id) + return trim(lowertext(record_id)) + +/datum/controller/subsystem/character_info/proc/get_record(var/record_id, var/override_prefs, var/discard_archived_record) + record_id = get_record_id(record_id) + if(!record_id) + CRASH("Attempt to retrieve null character information ID.") + var/datum/character_information/comments = _comment_holders_by_id[record_id] + if(istype(comments) && (override_prefs || (get_config_value(/decl/config/toggle/allow_character_comments) && comments.allow_comments) || comments.show_info_on_examine)) + return comments + +/datum/controller/subsystem/character_info/proc/get_or_create_record(var/record_id, var/override_prefs) + . = get_record(record_id, override_prefs) + if(!. && initialized) + // Let's assume they'll populate it if so desired. + var/datum/character_information/comments = new + comments.record_id = get_record_id(record_id) + _comment_holders_by_id[comments.record_id] = comments + . = comments + +/datum/controller/subsystem/character_info/proc/search_records(var/search_for) + search_for = ckey(lowertext(trim(search_for))) + for(var/id in _comment_holders_by_id) + var/datum/character_information/comments = _comment_holders_by_id[id] + for(var/checkstring in list(comments.name, comments.ckey, comments.record_id)) + if(findtext(ckey(lowertext(trim(checkstring))), search_for) > 0) + LAZYADD(., comments) + break + +/datum/controller/subsystem/character_info/Topic(href, href_list) + . = ..() + if(!. && href_list["download_manifest"] && usr && check_rights(R_ADMIN)) + try + var/dump_file_name = "[comments_source]dump_character_manifest.html" + if(fexists(dump_file_name)) + fdel(dump_file_name) + text2file(JOINTEXT(SScharacter_info.get_character_manifest_html(apply_striping = FALSE)), dump_file_name) + if(fexists(dump_file_name)) + direct_output(usr, ftp(dump_file_name, "dump_manifest.html")) + return TOPIC_HANDLED + catch(var/exception/E) + log_debug("Exception when dumping character relationship manifest: [E]") + +#define COMMENT_CANDYSTRIPE_ONE "#343434" +#define COMMENT_CANDYSTRIPE_TWO "#454545" +/datum/controller/subsystem/character_info/proc/get_character_manifest_html(var/apply_striping = TRUE) + var/list/records_with_an_entry = list() + for(var/id in _comment_holders_by_id) + var/datum/character_information/comments = _comment_holders_by_id[id] + for(var/datum/character_comment/comment in comments.comments) + if(comment.is_stale()) + continue + records_with_an_entry |= comment.author_id + sortTim(records_with_an_entry, /proc/cmp_text_asc) + . = list("") + if(apply_striping) + . += "" + else + . += "" + . += "" + for(var/column_id in records_with_an_entry) + var/datum/character_information/column = _comment_holders_by_id[column_id] + . += "" + . += "" + var/ticker = FALSE + for(var/row_id in records_with_an_entry) + if(apply_striping) + . += "" + ticker = !ticker + else + . += "" + var/datum/character_information/row = _comment_holders_by_id[row_id] + . += "" + for(var/column_id in records_with_an_entry) + var/datum/character_information/column = _comment_holders_by_id[column_id] + var/found_comment = FALSE + for(var/datum/character_comment/comment in column.comments) + if(comment.author_id == row_id && !comment.is_stale()) + found_comment = TRUE + var/mood_title = comment.main_mood.name + if(comment.border_mood) + mood_title = "[mood_title] ([comment.border_mood.name])" + . += "" + break + if(!found_comment) + . += "" + . += "" + . += "
Character Relationship Matrix
[column.char_name]
[column.ckey]
[row.char_name]
[row.ckey]
[comment.body]
" +#undef COMMENT_CANDYSTRIPE_ONE +#undef COMMENT_CANDYSTRIPE_TWO \ No newline at end of file diff --git a/code/controllers/subsystems/initialization/codex.dm b/code/controllers/subsystems/initialization/codex.dm index 878d9ba30c0..1948ba42ccd 100644 --- a/code/controllers/subsystems/initialization/codex.dm +++ b/code/controllers/subsystems/initialization/codex.dm @@ -84,9 +84,17 @@ SUBSYSTEM_DEF(codex) popup.set_content(parse_links(jointext(entry.get_codex_body(presenting_to), null), presenting_to)) popup.open() -/datum/controller/subsystem/codex/proc/get_guide(var/category) - var/decl/codex_category/cat = GET_DECL(category) - . = cat?.guide_html +/datum/controller/subsystem/codex/proc/get_manual_text(var/guide_id) + if(ispath(guide_id, /decl/codex_category)) + var/decl/codex_category/cat = GET_DECL(guide_id) + . = cat?.guide_html + else if(guide_id) + var/datum/codex_entry/entry + if(ispath(guide_id, /datum/codex_entry)) + entry = guide_id + guide_id = initial(entry.name) + entry = get_codex_entry(guide_id) + . = entry?.guide_html /datum/controller/subsystem/codex/proc/retrieve_entries_for_string(var/searching) diff --git a/code/controllers/subsystems/initialization/customitems.dm b/code/controllers/subsystems/initialization/customitems.dm index d9283b81fb4..ae4262be0c3 100644 --- a/code/controllers/subsystems/initialization/customitems.dm +++ b/code/controllers/subsystems/initialization/customitems.dm @@ -91,8 +91,9 @@ SUBSYSTEM_DEF(customitems) character_name = lowertext(character_name) for(var/icon_id in ids_to_icons) var/icon_loc = ids_to_icons[icon_id] - if(config.custom_icon_icon_location) - icon_loc = "[config.custom_icon_icon_location]/[icon_loc]" + var/config_icon_loc = get_config_value(/decl/config/text/custom_icon_icon_location) + if(config_icon_loc) + icon_loc = "[config_icon_loc]/[icon_loc]" ids_to_icons[icon_id] = file(icon_loc) /datum/custom_icon/proc/validate() @@ -134,8 +135,9 @@ SUBSYSTEM_DEF(customitems) item_path = item_path && text2path(item_path) apply_to_target_type = apply_to_target_type && text2path(apply_to_target_type) if(item_icon) - if(config.custom_item_icon_location) - item_icon = "[config.custom_item_icon_location]/[item_path]" + var/config_item_loc = get_config_value(/decl/config/text/custom_item_icon_location) + if(config_item_loc) + item_icon = "[config_item_loc]/[item_path]" if(fexists(item_icon)) item_icon = file(item_icon) diff --git a/code/controllers/subsystems/initialization/fabrication.dm b/code/controllers/subsystems/initialization/fabrication.dm index 2c288555d40..b63786543bc 100644 --- a/code/controllers/subsystems/initialization/fabrication.dm +++ b/code/controllers/subsystems/initialization/fabrication.dm @@ -33,6 +33,7 @@ SUBSYSTEM_DEF(fabrication) LAZYADD(locked_recipes[fab_type], recipe) else LAZYADD(initial_recipes[fab_type], recipe) + CHECK_TICK // Slapcrafting trees. var/list/all_crafting_handlers = decls_repository.get_decls_of_subtype(/decl/crafting_stage) diff --git a/code/controllers/subsystems/initialization/robots.dm b/code/controllers/subsystems/initialization/robots.dm index b71138afa75..75c70a7fe4c 100644 --- a/code/controllers/subsystems/initialization/robots.dm +++ b/code/controllers/subsystems/initialization/robots.dm @@ -10,18 +10,15 @@ SUBSYSTEM_DEF(robots) var/list/robot_alt_titles = list() var/list/mob_types_by_title = list( - "robot, flying" = /mob/living/silicon/robot/flying, - "drone, flying" = /mob/living/silicon/robot/flying, - "cyborg, flying" = /mob/living/silicon/robot/flying + "cyborg, flying" = /mob/living/silicon/robot/flying, + "robot, flying" = /mob/living/silicon/robot/flying ) var/list/mmi_types_by_title = list( - "cyborg" = /obj/item/mmi, - "robot" = /obj/item/organ/internal/posibrain, - "drone" = /obj/item/mmi/digital/robot, - "cyborg, flying" = /obj/item/mmi, - "robot, flying" = /obj/item/organ/internal/posibrain, - "drone, flying" = /obj/item/mmi/digital/robot + "cyborg" = /obj/item/organ/internal/brain_interface, + "robot" = /obj/item/organ/internal/brain/robotic, + "cyborg, flying" = /obj/item/organ/internal/brain_interface, + "robot, flying" = /obj/item/organ/internal/brain/robotic ) /datum/controller/subsystem/robots/Initialize() @@ -60,8 +57,8 @@ SUBSYSTEM_DEF(robots) if(modules[include_override]) .[include_override] = modules[include_override] -/datum/controller/subsystem/robots/proc/get_mmi_type_by_title(var/check_title) - . = mmi_types_by_title[lowertext(trim(check_title))] || /obj/item/mmi +/datum/controller/subsystem/robots/proc/get_brain_type_by_title(var/check_title) + . = mmi_types_by_title[lowertext(trim(check_title))] || /obj/item/organ/internal/brain/robotic /datum/controller/subsystem/robots/proc/get_mob_type_by_title(var/check_title) . = mob_types_by_title[lowertext(trim(check_title))] || /mob/living/silicon/robot \ No newline at end of file diff --git a/code/controllers/subsystems/jobs.dm b/code/controllers/subsystems/jobs.dm index 554fa6acfbe..1a0798e84f1 100644 --- a/code/controllers/subsystems/jobs.dm +++ b/code/controllers/subsystems/jobs.dm @@ -60,7 +60,7 @@ SUBSYSTEM_DEF(jobs) submap_archetypes = sortTim(submap_archetypes, /proc/cmp_submap_archetype_asc, TRUE) // Load job configuration (is this even used anymore?) - if(job_config_file && config.load_jobs_from_txt) + if(job_config_file && get_config_value(/decl/config/toggle/load_jobs_from_txt)) var/list/jobEntries = file2list(job_config_file) for(var/job in jobEntries) if(!job) @@ -174,7 +174,7 @@ SUBSYSTEM_DEF(jobs) if(!job.is_position_available()) to_chat(joining, "Unfortunately, that job is no longer available.") return FALSE - if(!config.enter_allowed) + if(!get_config_value(/decl/config/toggle/on/enter_allowed)) to_chat(joining, "There is an administrative lock on entering the game!") return FALSE if(SSticker.mode && SSticker.mode.station_explosion_in_progress) @@ -291,7 +291,7 @@ SUBSYSTEM_DEF(jobs) if(age < job.minimum_character_age) // Nope. continue switch(age - job.ideal_character_age) - if(0 to -10) + if(-INFINITY to -10) if(age < (job.minimum_character_age+10)) weightedCandidates[V] = 3 // Still a bit young. else @@ -611,7 +611,7 @@ SUBSYSTEM_DEF(jobs) T.maptext = "[copytext_char(text, 1, i)] " sleep(1) - addtimer(CALLBACK(GLOBAL_PROC, .proc/fade_location_blurb, src, T), duration) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(fade_location_blurb), src, T), duration) /proc/fade_location_blurb(client/C, obj/T) animate(T, alpha = 0, time = 5) diff --git a/code/controllers/subsystems/managed_instance.dm b/code/controllers/subsystems/managed_instance.dm index dbf7cebf69f..92197745772 100644 --- a/code/controllers/subsystems/managed_instance.dm +++ b/code/controllers/subsystems/managed_instance.dm @@ -34,7 +34,7 @@ SUBSYSTEM_DEF(managed_instances) PRINT_STACK_TRACE("Managed instance was queued for deletion during init! [managed_instance]") category_list[cache_id] -= managed_instance else - events_repository.register(/decl/observ/destroyed, managed_instance, src, /datum/controller/subsystem/managed_instances/proc/clear) + events_repository.register(/decl/observ/destroyed, managed_instance, src, TYPE_PROC_REF(/datum/controller/subsystem/managed_instances, clear)) . = managed_instance // This is costly, but it also shouldn't be common for managed instances to get qdeleted post-storage. diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index b9df9686e98..0d0adb2eebd 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(mapping) var/list/map_templates_by_category = list() var/list/map_templates_by_type = list() var/list/banned_maps = list() - var/list/banned_ruin_names = list() + var/list/banned_template_names = list() // Listing .dmm filenames in the file at this location will blacklist any templates that include them from being used. // Maps must be the full file path to be properly included. ex. "maps/random_ruins/away_sites/example.dmm" @@ -71,6 +71,11 @@ SUBSYSTEM_DEF(mapping) for(var/datum/map_template/MT as anything in get_all_template_instances()) register_map_template(MT) + // Load any queued map template markers. + for(var/obj/abstract/landmark/map_load_mark/queued_mark in queued_markers) + queued_mark.load_subtemplate() + queued_markers.Cut() + // Populate overmap. if(length(global.using_map.overmap_ids)) for(var/overmap_id in global.using_map.overmap_ids) @@ -121,7 +126,7 @@ SUBSYSTEM_DEF(mapping) // Initialize z-level objects. #ifdef UNIT_TEST - config.roundstart_level_generation = FALSE //#FIXME: Shouldn't this be set before running level_data/setup_level_data()? + set_config_value(/decl/config/toggle/roundstart_level_generation, FALSE) //#FIXME: Shouldn't this be set before running level_data/setup_level_data()? #endif . = ..() diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm index 00efee1ef03..5d704ae9aad 100644 --- a/code/controllers/subsystems/plants.dm +++ b/code/controllers/subsystems/plants.dm @@ -6,8 +6,6 @@ PROCESSING_SUBSYSTEM_DEF(plants) init_order = SS_INIT_PLANTS wait = 60 - process_proc = /obj/machinery/portable_atmospherics/hydroponics/Process - var/list/product_descs = list() // Stores generated fruit descs. var/list/seeds = list() // All seed data stored here. var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness. diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm index 77a852de19c..a1812f5d758 100644 --- a/code/controllers/subsystems/processing/mobs.dm +++ b/code/controllers/subsystems/processing/mobs.dm @@ -5,7 +5,7 @@ PROCESSING_SUBSYSTEM_DEF(mobs) runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME wait = 2 SECONDS - process_proc = /mob/proc/Life + process_proc = TYPE_PROC_REF(/mob, Life) var/list/mob_list diff --git a/code/controllers/subsystems/processing/processing.dm b/code/controllers/subsystems/processing/processing.dm index ba9ca0fd657..594dc8a1985 100644 --- a/code/controllers/subsystems/processing/processing.dm +++ b/code/controllers/subsystems/processing/processing.dm @@ -8,7 +8,7 @@ SUBSYSTEM_DEF(processing) var/list/processing = list() var/list/current_run = list() - var/process_proc = /datum/proc/Process + var/process_proc = TYPE_PROC_REF(/datum, Process) var/debug_last_thing var/debug_original_process_proc // initial() does not work with procs @@ -28,7 +28,7 @@ SUBSYSTEM_DEF(processing) var/datum/thing = current_run[current_run.len] current_run.len-- if(QDELETED(thing) || (call(thing, process_proc)(wait, times_fired, src) == PROCESS_KILL)) - if(thing) + if(thing?.is_processing == _internal_name) thing.is_processing = null processing -= thing if (MC_TICK_CHECK) @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(processing) debug_original_process_proc = null else debug_original_process_proc = process_proc - process_proc = /datum/proc/DebugSubsystemProcess + process_proc = TYPE_PROC_REF(/datum, DebugSubsystemProcess) to_chat(usr, "[name] - Debug mode [debug_original_process_proc ? "en" : "dis"]abled") diff --git a/code/controllers/subsystems/processing/temperature.dm b/code/controllers/subsystems/processing/temperature.dm index 377c8283660..4f14fc03788 100644 --- a/code/controllers/subsystems/processing/temperature.dm +++ b/code/controllers/subsystems/processing/temperature.dm @@ -2,4 +2,4 @@ PROCESSING_SUBSYSTEM_DEF(temperature) name = "Temperature" priority = SS_PRIORITY_TEMPERATURE wait = 5 SECONDS - process_proc = /atom/proc/ProcessAtomTemperature + process_proc = TYPE_PROC_REF(/atom, ProcessAtomTemperature) diff --git a/code/controllers/subsystems/processing/vines.dm b/code/controllers/subsystems/processing/vines.dm index 56e24d30f27..1e59ccf5a6f 100644 --- a/code/controllers/subsystems/processing/vines.dm +++ b/code/controllers/subsystems/processing/vines.dm @@ -5,8 +5,6 @@ PROCESSING_SUBSYSTEM_DEF(vines) runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME wait = 80 - process_proc = /obj/effect/vine/Process - var/list/vine_list /datum/controller/subsystem/processing/vines/PreInit() diff --git a/code/controllers/subsystems/radiation.dm b/code/controllers/subsystems/radiation.dm index 3e0b0747a13..5865d8f28a4 100644 --- a/code/controllers/subsystems/radiation.dm +++ b/code/controllers/subsystems/radiation.dm @@ -18,6 +18,7 @@ SUBSYSTEM_DEF(radiation) current_res_cache = resistance_cache.Copy() listeners = global.living_mob_list_.Copy() + var/rad_decay_rate = get_config_value(/decl/config/num/radiation_decay_rate) while(current_sources.len) var/datum/radiation_source/S = current_sources[current_sources.len] current_sources.len-- @@ -25,7 +26,7 @@ SUBSYSTEM_DEF(radiation) if(QDELETED(S)) sources -= S else if(S.decay) - S.update_rad_power(S.rad_power - config.radiation_decay_rate) + S.update_rad_power(S.rad_power - rad_decay_rate) if (MC_TICK_CHECK) return @@ -87,12 +88,13 @@ SUBSYSTEM_DEF(radiation) // Okay, now ray trace to find resistence! var/turf/origin = source.source_turf var/working = source.rad_power + var/rad_mult = get_config_value(/decl/config/num/radiation_resistance_multiplier) while(origin != T) origin = get_step_towards(origin, T) //Raytracing if(!resistance_cache[origin]) //Only get the resistance if we don't already know it. origin.calc_rad_resistance() if(origin.cached_rad_resistance) - working = round((working / (origin.cached_rad_resistance * config.radiation_resistance_multiplier)), 0.1) + working = round((working / (origin.cached_rad_resistance * rad_mult)), 0.1) if((working <= .) || (working <= RADIATION_THRESHOLD_CUTOFF)) break // Already affected by a stronger source (or its zero...) . = max((working / (dist ** 2)), .) //Butchered version of the inverse square law. Works for this purpose diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index ef71515dbf0..bf2d38aa0cb 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -46,6 +46,7 @@ SUBSYSTEM_DEF(supply) for(var/decl/hierarchy/supply_pack/spc in sp.get_descendents()) spc.setup() master_supply_list += spc + CHECK_TICK // Just add points over time. /datum/controller/subsystem/supply/fire() diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 78ada4556d7..4926e5e6635 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -52,7 +52,7 @@ SUBSYSTEM_DEF(ticker) Master.SetRunLevel(RUNLEVEL_SETUP) return - if(!bypass_gamemode_vote && (pregame_timeleft <= config.vote_autogamemode_timeleft SECONDS) && !gamemode_vote_results) + if(!bypass_gamemode_vote && (pregame_timeleft <= get_config_value(/decl/config/num/vote_autogamemode_timeleft) SECONDS) && !gamemode_vote_results) if(!SSvote.active_vote) SSvote.initiate_vote(/datum/vote/gamemode, automatic = 1) @@ -111,8 +111,8 @@ SUBSYSTEM_DEF(ticker) if(mode_finished && game_finished()) Master.SetRunLevel(RUNLEVEL_POSTGAME) end_game_state = END_GAME_READY_TO_END - INVOKE_ASYNC(src, .proc/declare_completion) - if(config.allow_map_switching && config.auto_map_vote && global.all_maps.len > 1) + INVOKE_ASYNC(src, PROC_REF(declare_completion)) + if(get_config_value(/decl/config/toggle/allow_map_switching) && get_config_value(/decl/config/toggle/auto_map_vote) && global.all_maps.len > 1) SSvote.initiate_vote(/datum/vote/map/end_game, automatic = 1) else if(mode_finished && (end_game_state <= END_GAME_NOT_OVER)) @@ -222,8 +222,13 @@ Helpers if(mode_to_try in bad_modes) return - //Find the relevant datum, resolving secret in the process. - var/list/base_runnable_modes = config.get_runnable_modes() //format: list(uid = weight) + var/list/base_runnable_modes = list() + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + if(game_mode.probability > 0 && !game_mode.startRequirements()) + base_runnable_modes[game_mode.uid] = game_mode.probability + if((mode_to_try=="random") || (mode_to_try=="secret")) var/list/runnable_modes = base_runnable_modes - bad_modes if(secret_force_mode != "secret") // Config option to force secret to be a specific mode. @@ -263,8 +268,8 @@ Helpers for (var/mode_tag in base_runnable_modes) var/decl/game_mode/M = decls_repository.get_decl_by_id(mode_tag, validate_decl_type = FALSE) if(M) - mode_names += M.name - if (config.secret_hide_possibilities) + mode_names |= M.name + if (get_config_value(/decl/config/toggle/secret_hide_possibilities)) message_admins("Possibilities: [english_list(mode_names)]") else to_world("Possibilities: [english_list(mode_names)]") @@ -344,13 +349,13 @@ Helpers /datum/controller/subsystem/ticker/proc/game_finished() if(mode.station_explosion_in_progress) return 0 - if(config.continous_rounds) + if(get_config_value(/decl/config/toggle/continuous_rounds)) return SSevac.evacuation_controller?.round_over() || mode.station_was_nuked else return mode.check_finished() || (SSevac.evacuation_controller && SSevac.evacuation_controller.round_over() && SSevac.evacuation_controller.emergency_evacuation) || universe_has_ended /datum/controller/subsystem/ticker/proc/mode_finished() - if(config.continous_rounds) + if(get_config_value(/decl/config/toggle/continuous_rounds)) return mode.check_finished() else return game_finished() diff --git a/code/controllers/subsystems/timer.dm b/code/controllers/subsystems/timer.dm index 75c3ab724e0..2511520c920 100644 --- a/code/controllers/subsystems/timer.dm +++ b/code/controllers/subsystems/timer.dm @@ -273,7 +273,7 @@ SUBSYSTEM_DEF(timer) return // Sort all timers by time to run - sortTim(alltimers, .proc/cmp_timer) + sortTim(alltimers, PROC_REF(cmp_timer)) // Get the earliest timer, and if the TTR is earlier than the current world.time, // then set the head offset appropriately to be the earliest time tracked by the diff --git a/code/controllers/subsystems/typing.dm b/code/controllers/subsystems/typing.dm index 8f68fa0e711..d44ba9a14de 100644 --- a/code/controllers/subsystems/typing.dm +++ b/code/controllers/subsystems/typing.dm @@ -22,7 +22,7 @@ SUBSYSTEM_DEF(typing) var/static/regex/match_verbs /// A list of clients waiting to be polled for input state. var/list/client/queue = list() - /// A list of ckey to list, containing current state data. See .proc/get_entry for details. + /// A list of ckey to list, containing current state data. See get_entry() for details. var/list/status = list() /* example of an entry: (ckey = list( @@ -35,7 +35,7 @@ SUBSYSTEM_DEF(typing) */ /datum/controller/subsystem/typing/Initialize(start_timeofday) - if(config.show_typing_indicator_for_whispers) + if(get_config_value(/decl/config/toggle/show_typing_indicator_for_whispers)) match_verbs = regex("^(Me|Say|Whisper) +\"?\\w+") else match_verbs = regex("^(Me|Say) +\"?\\w+") diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm index e5d4b025ff7..0c69d7d1c24 100644 --- a/code/controllers/subsystems/vote.dm +++ b/code/controllers/subsystems/vote.dm @@ -69,7 +69,7 @@ SUBSYSTEM_DEF(vote) return FALSE if(last_started_time != null && !(is_admin(creator) || automatic)) - var/next_allowed_time = (last_started_time + config.vote_delay) + var/next_allowed_time = (last_started_time + get_config_value(/decl/config/num/vote_delay)) if(next_allowed_time > world.time) return FALSE @@ -176,7 +176,7 @@ SUBSYSTEM_DEF(vote) // Helper proc for determining whether addantag vote can be called. /datum/controller/subsystem/vote/proc/is_addantag_allowed(mob/creator, automatic) - if(!config.allow_extra_antags) + if(!get_config_value(/decl/config/toggle/allow_extra_antags)) return 0 // Gamemode has to be determined before we can add antagonists, so we can respect gamemode's add antag vote settings. if((GAME_STATE <= RUNLEVEL_SETUP) || !SSticker.mode) diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index 058afaa1f3d..c5715af524b 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -9,6 +9,18 @@ #define SHADOWER_DARKENING_FACTOR 0.6 // The multiplication factor for openturf shadower darkness. Lighting will be multiplied by this. #define SHADOWER_DARKENING_COLOR "#999999" // The above, but as an RGB string for lighting-less turfs. +//#define ZM_RECORD_STATS // This doesn't work on O7/Neb right now. + +#ifdef ZM_RECORD_STATS +#define ZM_RECORD_START STAT_START_STOPWATCH +#define ZM_RECORD_STOP STAT_STOP_STOPWATCH +#define ZM_RECORD_WRITE(X...) STAT_LOG_ENTRY(##X) +#else +#define ZM_RECORD_START +#define ZM_RECORD_STOP +#define ZM_RECORD_WRITE(X...) +#endif + SUBSYSTEM_DEF(zcopy) name = "Z-Copy" wait = 1 @@ -25,8 +37,19 @@ SUBSYSTEM_DEF(zcopy) var/openspace_turfs = 0 var/multiqueue_skips_turf = 0 + var/multiqueue_skips_discovery = 0 var/multiqueue_skips_object = 0 + var/total_updates_turf = 0 + var/total_updates_discovery = 0 + var/total_updates_object = 0 + +#ifdef ZM_RECORD_STATS + var/list/turf_stats = list() + var/list/discovery_stats = list() + var/list/mimic_stats = list() +#endif + // Highest Z level in a given Z-group for absolute layering. // zstm[zlev] = group_max var/list/zlev_maximums = list() @@ -108,14 +131,38 @@ SUBSYSTEM_DEF(zcopy) /datum/controller/subsystem/zcopy/stat_entry() var/list/entries = list( - "Mx:[json_encode(zlev_maximums)]", + "", // newline + "ZSt: [build_zstack_display()]", // This is a human-readable list of the z-stacks known to ZM. + "ZMx: [zlev_maximums.Join(", ")]", // And this is the raw internal state. + // This one gets broken out from the below because it's more important. "Q: { T: [queued_turfs.len - (qt_idex - 1)] O: [queued_overlays.len - (qo_idex - 1)] }", - "T: { T: [openspace_turfs] O: [openspace_overlays] }", - "Sk: { T: [multiqueue_skips_turf] O: [multiqueue_skips_object] }", + // In order: Total, Queued, Skipped + "T(O): { T: [openspace_turfs] O: [openspace_overlays] }", + "T(U): { T: [total_updates_turf] D: [total_updates_discovery] O: [total_updates_object] }", + "Sk: { T: [multiqueue_skips_turf] D: [multiqueue_skips_discovery] O: [multiqueue_skips_object] }", "F: { H: [fixup_hit] M: [fixup_miss] N: [fixup_noop] FC: [fixup_cache.len] FKG: [fixup_known_good.len] }" ) ..(entries.Join("\n\t")) +// 1, 2, 3..=7, 8 +/datum/controller/subsystem/zcopy/proc/build_zstack_display() + if (!zlev_maximums.len) + return "" + var/list/zmx = list() + var/idx = 1 + var/span_ctr = 0 + do + if (zlev_maximums[idx] != idx) + span_ctr += 1 + else if (span_ctr) + zmx += "[idx - span_ctr]..=[idx]" + span_ctr = 0 + else + zmx += "[idx]" + idx += 1 + while (idx <= zlev_maximums.len) + return jointext(zmx, ", ") + /datum/controller/subsystem/zcopy/Initialize(timeofday) calculate_zstack_limits() // Flush the queue. @@ -169,8 +216,16 @@ SUBSYSTEM_DEF(zcopy) if (!no_mc_tick) MC_SPLIT_TICK + tick_turfs(no_mc_tick) + + if (!no_mc_tick) + MC_SPLIT_TICK + + tick_mimic(no_mc_tick) + +// - Turf mimic - +/datum/controller/subsystem/zcopy/proc/tick_turfs(no_mc_tick) var/list/curr_turfs = queued_turfs - var/list/curr_ov = queued_overlays while (qt_idex <= curr_turfs.len) var/turf/T = curr_turfs[qt_idex] @@ -188,6 +243,7 @@ SUBSYSTEM_DEF(zcopy) if (T.z_queued > 1) T.z_queued -= 1 multiqueue_skips_turf += 1 + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -197,12 +253,23 @@ SUBSYSTEM_DEF(zcopy) // Z-Turf on the bottom-most level, just fake-copy space (or baseturf). // It's impossible for anything to be on the synthetic turf, so ignore the rest of the ZM machinery. if (!T.below) + ZM_RECORD_START flush_z_state(T) - if (T.z_flags & ZM_MIMIC_BASETURF) + if (T.z_flags & ZM_OVERRIDE) simple_appearance_copy(T, get_base_turf_by_area(T), OPENTURF_MAX_PLANE) else simple_appearance_copy(T, SSskybox.dust_cache["[((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25]"]) + T.z_generation += 1 + T.z_queued -= 1 + total_updates_turf += 1 + + if (T.above) + T.above.update_mimic() + + ZM_RECORD_STOP + ZM_RECORD_WRITE(turf_stats, "Fake: [T.type] on [T.z]") + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -215,9 +282,12 @@ SUBSYSTEM_DEF(zcopy) T.z_generation += 1 + ZM_RECORD_START + // Get the bottom-most turf, the one we want to mimic. + // Baseturf mimics act as false bottoms of the stack. var/turf/Td = T - while (Td.below) + while (Td.below && !(Td.z_flags & (ZM_OVERRIDE|ZM_TERMINATOR))) Td = Td.below // Depth must be the depth of the *visible* turf, not self. @@ -227,9 +297,18 @@ SUBSYSTEM_DEF(zcopy) var/t_target = OPENTURF_MAX_PLANE - turf_depth // This is where the turf (but not the copied atoms) gets put. // Turf is set to mimic baseturf, handle that and bail. - if (T.z_flags & ZM_MIMIC_BASETURF) + if (T.z_flags & ZM_OVERRIDE) flush_z_state(T) - simple_appearance_copy(T, get_base_turf_by_area(T), t_target) + simple_appearance_copy(T, Td.z_appearance || get_base_turf_by_area(T), t_target) + + if (T.above) + T.above.update_mimic() + + total_updates_turf += 1 + T.z_queued -= 1 + + ZM_RECORD_STOP + ZM_RECORD_WRITE(turf_stats, "Simple: [T.type] on [T.z]") if (no_mc_tick) CHECK_TICK @@ -237,7 +316,7 @@ SUBSYSTEM_DEF(zcopy) break continue - // If we previously were ZM_MIMIC_BASETURF, there might be an orphaned proxy. + // If we previously were ZM_OVERRIDE, there might be an orphaned proxy. else if (T.mimic_underlay) QDEL_NULL(T.mimic_underlay) @@ -250,7 +329,7 @@ SUBSYSTEM_DEF(zcopy) // This openturf doesn't care about its icon, so we can just overwrite it. if (T.below.mimic_proxy) QDEL_NULL(T.below.mimic_proxy) - T.appearance = T.below + T.appearance = Td.z_appearance || Td T.name = initial(T.name) T.desc = initial(T.desc) T.gender = initial(T.gender) @@ -261,7 +340,7 @@ SUBSYSTEM_DEF(zcopy) if (!T.below.mimic_proxy) T.below.mimic_proxy = new(T) var/atom/movable/openspace/turf_proxy/TO = T.below.mimic_proxy - TO.appearance = Td + TO.appearance = Td.z_appearance || Td TO.name = T.name TO.gender = T.gender // Need to grab this too so PLURAL works properly in examine. TO.opacity = FALSE @@ -286,75 +365,46 @@ SUBSYSTEM_DEF(zcopy) // Handle below atoms. - // Add everything below us to the update queue. + var/shadower_set = FALSE + + // Add everything below us to the discovery queue. for (var/thing in T.below) var/atom/movable/object = thing if (QDELETED(object) || (object.z_flags & ZMM_IGNORE) || object.loc != T.below || object.invisibility == INVISIBILITY_ABSTRACT) - // Don't queue deleted stuff, stuff that's not visible, blacklisted stuff, or stuff that's centered on another tile but intersects ours. + /* Don't queue: + - (q)deleted objects + - Explicitly ignored objects + - Objects not rooted on this turf (multitiles) + - Always-invisible atoms + */ continue // Special case: these are merged into the shadower to reduce memory usage. if (object.type == /atom/movable/lighting_overlay) - T.shadower.copy_lighting(object) + T.shadower.copy_lighting(object, !(T.below.z_flags & ZM_NO_SHADOW)) + shadower_set = TRUE continue - if (!object.bound_overlay) // Generate a new overlay if the atom doesn't already have one. - object.bound_overlay = new(T) - object.bound_overlay.associated_atom = object - - var/override_depth - var/original_type = object.type - var/original_z = object.z - var/have_performed_fixup = FALSE - - switch (object.type) - // Layering for recursive mimic needs to be inherited. - if (/atom/movable/openspace/mimic) - var/atom/movable/openspace/mimic/OOO = object - original_type = OOO.mimiced_type - override_depth = OOO.override_depth - original_z = OOO.original_z - have_performed_fixup = OOO.have_performed_fixup - - // If this is a turf proxy (the mimic for a non-OVERWRITE turf), it needs to respect space parallax if relevant. - if (/atom/movable/openspace/turf_proxy) - if (T.z_eventually_space) - // Yes, this is an awful hack; I don't want to add yet another override_* var. - override_depth = OPENTURF_MAX_PLANE - SPACE_PLANE - - if (/atom/movable/openspace/turf_mimic) - original_z += 1 - - var/atom/movable/openspace/mimic/OO = object.bound_overlay - - // If the OO was queued for destruction but was claimed by another OT, stop the destruction timer. - if (OO.destruction_timer) - deltimer(OO.destruction_timer) - OO.destruction_timer = null - - OO.depth = override_depth || min(zlev_maximums[T.z] - original_z, OPENTURF_MAX_DEPTH) - - // These types need to be pushed a layer down for bigturfs to function correctly. - switch (original_type) - if (/atom/movable/openspace/multiplier, /atom/movable/openspace/turf_proxy) - if (OO.depth < OPENTURF_MAX_DEPTH) - OO.depth += 1 - - OO.mimiced_type = original_type - OO.override_depth = override_depth - OO.original_z = original_z - OO.have_performed_fixup ||= have_performed_fixup - - // Multi-queue to maintain ordering of updates to these - // queueing it multiple times will result in only the most recent - // actually processing. - OO.queued += 1 - queued_overlays += OO + // If an atom already has an overlay, we probably don't need to discover it again. + // ...but we need to force it if the object was salvaged from another zturf. + if (!object.bound_overlay || object.bound_overlay.destruction_timer) + discover_movable(object, T) + + if (!shadower_set) + if (T.below.z_flags & ZM_NO_SHADOW) + T.shadower.color = null + else + T.shadower.color = SHADOWER_DARKENING_COLOR T.z_queued -= 1 if (T.above) T.above.update_mimic() + total_updates_turf += 1 + + ZM_RECORD_STOP + ZM_RECORD_WRITE(turf_stats, "Complex: [T.type] on [T.z]") + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -364,9 +414,9 @@ SUBSYSTEM_DEF(zcopy) curr_turfs.Cut(1, qt_idex) qt_idex = 1 - if (!no_mc_tick) - MC_SPLIT_TICK - +// - Phase: Mimic update -- actually update the mimics' appearance, order sensitive - +/datum/controller/subsystem/zcopy/proc/tick_mimic(no_mc_tick) + var/list/curr_ov = queued_overlays while (qo_idex <= curr_ov.len) var/atom/movable/openspace/mimic/OO = curr_ov[qo_idex] curr_ov[qo_idex] = null @@ -379,8 +429,9 @@ SUBSYSTEM_DEF(zcopy) break continue - if (QDELETED(OO.associated_atom)) // This shouldn't happen, but just in-case. + if (QDELETED(OO.associated_atom)) // This shouldn't happen. qdel(OO) + log_debug("Z-Mimic: Received mimic with QDELETED parent ([OO.associated_atom || ""])") if (no_mc_tick) CHECK_TICK @@ -392,21 +443,24 @@ SUBSYSTEM_DEF(zcopy) if (OO.queued > 1) OO.queued -= 1 multiqueue_skips_object += 1 + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) break continue + ZM_RECORD_START + // Actually update the overlay. if (OO.dir != OO.associated_atom.dir) - OO.set_dir(OO.associated_atom.dir) + OO.dir = OO.associated_atom.dir // updates are propagated up another way, don't use set_dir + OO.appearance = OO.associated_atom + OO.z_flags = OO.associated_atom.z_flags if (OO.particles != OO.associated_atom.particles) OO.particles = OO.associated_atom.particles - OO.appearance = OO.associated_atom - OO.z_flags = OO.associated_atom.z_flags OO.plane = OPENTURF_MAX_PLANE - OO.depth OO.opacity = FALSE @@ -422,6 +476,11 @@ SUBSYSTEM_DEF(zcopy) if (OO.bound_overlay) // If we have a bound overlay, queue it too. OO.update_above() + total_updates_object += 1 + + ZM_RECORD_STOP + ZM_RECORD_WRITE(mimic_stats, OO.mimiced_type) + if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -431,15 +490,86 @@ SUBSYSTEM_DEF(zcopy) curr_ov.Cut(1, qo_idex) qo_idex = 1 +// return: is-invalid +/datum/controller/subsystem/zcopy/proc/discover_movable(atom/movable/object) + ASSERT(!QDELETED(object)) + + var/turf/Tloc = object.loc + if (!isturf(Tloc) || !Tloc.above) + return TRUE + + var/turf/T = Tloc.above + + ZM_RECORD_START + + if (!object.bound_overlay) + var/atom/movable/openspace/mimic/M = new(T) + object.bound_overlay = M + M.associated_atom = object + if (TURF_IS_MIMICKING(M.loc)) + .(M) + + var/override_depth + var/original_type = object.type + var/original_z = object.z + + switch (object.type) + // Layering for recursive mimic needs to be inherited. + if (/atom/movable/openspace/mimic) + var/atom/movable/openspace/mimic/OOO = object + original_type = OOO.mimiced_type + override_depth = OOO.override_depth + original_z = OOO.original_z + + // If this is a turf proxy (the mimic for a non-OVERWRITE turf), it needs to respect space parallax if relevant. + if (/atom/movable/openspace/turf_proxy) + if (T.z_eventually_space) + // Yes, this is an awful hack; I don't want to add yet another override_* var. + override_depth = OPENTURF_MAX_PLANE - SPACE_PLANE + + var/atom/movable/openspace/mimic/OO = object.bound_overlay + + // If the OO was queued for destruction but was claimed by another OT, stop the destruction timer. + if (OO.destruction_timer) + deltimer(OO.destruction_timer) + OO.destruction_timer = null + + OO.depth = override_depth || min(zlev_maximums[T.z] - original_z, OPENTURF_MAX_DEPTH) + + switch (original_type) + // These types need to be pushed a layer down for bigturfs to function correctly. + if (/atom/movable/openspace/turf_proxy, /atom/movable/openspace/turf_mimic) + OO.depth += 1 + if (/atom/movable/openspace/multiplier) + OO.depth += 1 + + OO.mimiced_type = original_type + OO.override_depth = override_depth + OO.original_z = original_z + + // Multi-queue to maintain ordering of updates to these + // queueing it multiple times will result in only the most recent + // actually processing. + OO.queued += 1 + queued_overlays += OO + + total_updates_discovery += 1 + + ZM_RECORD_STOP + ZM_RECORD_WRITE(discovery_stats, "Depth [OO.depth] on [OO.z]") + + return FALSE + /datum/controller/subsystem/zcopy/proc/flush_z_state(turf/T) - if(T.below) + if (T.below) // Z-Mimic turfs aren't necessarily above another turf. if (T.below.mimic_above_copy) QDEL_NULL(T.below.mimic_above_copy) if (T.below.mimic_proxy) QDEL_NULL(T.below.mimic_proxy) - for (var/atom/movable/openspace/OO in T) - if (istype(OO, /atom/movable/openspace/mimic)) - qdel(OO) + + QDEL_NULL(T.mimic_underlay) + for (var/atom/movable/openspace/mimic/OO in T) + qdel(OO) /datum/controller/subsystem/zcopy/proc/simple_appearance_copy(turf/T, new_appearance, target_plane) if (T.z_flags & ZM_MIMIC_OVERWRITE) @@ -524,7 +654,7 @@ SUBSYSTEM_DEF(zcopy) fixed_underlays[i] = fixed_appearance if (mutated) - for (var/i in 1 to fixed_overlays.len) + for (var/i in 1 to fixed_underlays.len) if (fixed_underlays[i] == null) fixed_underlays[i] = appearance:underlays[i] @@ -552,6 +682,7 @@ SUBSYSTEM_DEF(zcopy) return MA #define FMT_DEPTH(X) (X == null ? "(null)" : X) +#define FMT_OK(X) (X) ? "OK" : "MISMATCH" // This is a dummy object used so overlays can be shown in the analyzer. /atom/movable/openspace/debug @@ -584,7 +715,7 @@ SUBSYSTEM_DEF(zcopy) "", "

Analysis of [T] at [T.x],[T.y],[T.z]

", "Queue occurrences: [T.z_queued]", - "Above space: Apparent [T.z_eventually_space ? "Yes" : "No"], Actual [is_above_space ? "Yes" : "No"] - [T.z_eventually_space == is_above_space ? "OK" : "MISMATCH"]", + "Above space: Apparent [T.z_eventually_space ? "Yes" : "No"], Actual [is_above_space ? "Yes" : "No"] - [FMT_OK(T.z_eventually_space == is_above_space)]", "Z Flags: [english_list(bitfield2list(T.z_flags, global.mimic_defines), "(none)")]", "Has Shadower: [T.shadower ? "Yes" : "No"]", "Has turf proxy: [T.mimic_proxy ? "Yes" : "No"]", @@ -593,12 +724,14 @@ SUBSYSTEM_DEF(zcopy) "Below: [!T.below ? "(nothing)" : "[T.below] at [T.below.x],[T.below.y],[T.below.z]"]", "Depth: [FMT_DEPTH(T.z_depth)] [T.z_depth == OPENTURF_MAX_DEPTH ? "(max)" : ""]", "Generation: [T.z_generation]", - "Update count: Claimed [claimed_update_count], Actual [real_update_count] - [claimed_update_count == real_update_count ? "OK" : "MISMATCH"]", + "Update count: Claimed [claimed_update_count], Actual [real_update_count] - [FMT_OK(claimed_update_count == real_update_count)]", "
    " ) - if (T.z_flags & ZM_MIMIC_BASETURF) - out += "

    Using synthetic rendering (BASETURF).

    " + if (!T.below) + out += "

    Using synthetic rendering (Not Z).

    " + else if (T.z_flags & ZM_OVERRIDE) + out += "

    Using synthetic rendering (OVERRIDE).

    " var/list/found_oo = list(T) var/turf/Tbelow = T @@ -641,7 +774,7 @@ SUBSYSTEM_DEF(zcopy) for (var/d in 0 to OPENTURF_MAX_DEPTH) var/pl = OPENTURF_MAX_PLANE - d if (!atoms_list_list["[pl]"]) - out += "Depth [d], plane [pl] — empty" + out += "Depth [d], planes [pl] — empty" continue out += "Depth [d], plane [pl]" @@ -673,9 +806,13 @@ SUBSYSTEM_DEF(zcopy) /datum/controller/subsystem/zcopy/proc/debug_fmt_thing(atom/A, list/out, turf/original) if (istype(A, /atom/movable/openspace/mimic)) var/atom/movable/openspace/mimic/OO = A + var/base = "
  • [fmt_label("Mimic", A)] plane [A.plane], layer [A.layer], depth [FMT_DEPTH(OO.depth)]" + if (QDELETED(OO.associated_atom)) // This shouldn't happen, but can if the deletion hook is not working. + return "[base] - [OO.type] copying ([OO.mimiced_type]) - ORPHANED
  • " + var/atom/movable/AA = OO.associated_atom var/copied_type = AA.type == OO.mimiced_type ? "[AA.type] \[direct\]" : "[AA.type], eventually [OO.mimiced_type]" - return "
  • [fmt_label("Mimic", A)] plane [A.plane], layer [A.layer], depth [FMT_DEPTH(OO.depth)], fixup [OO.have_performed_fixup ? "Y" : "N"], associated Z-level [AA.z] - [OO.type] copying [AA] ([copied_type])
  • " + return "[base], associated Z-level [AA.z] - [OO.type] copying [AA] ([copied_type])" else if (istype(A, /atom/movable/openspace/turf_mimic)) var/atom/movable/openspace/turf_mimic/DC = A @@ -684,9 +821,11 @@ SUBSYSTEM_DEF(zcopy) else if (isturf(A)) if (A == original) return "
  • [fmt_label("Turf", A)] plane [A.plane], layer [A.layer], depth [FMT_DEPTH(A:z_depth)], Z-level [A.z] - [A] ([A.type]) - SELF
  • " + else // foreign turfs - not visible here, but sometimes good for figuring out layering -- showing these is currently not enabled return "
  • [fmt_label("Foreign Turf", A)] plane [A.plane], layer [A.layer], depth [FMT_DEPTH(A:z_depth)], Z-level [A.z] - [A] ([A.type]) - FOREIGN
  • " + else if (A.type == /atom/movable/openspace/multiplier) return "
  • [fmt_label("Shadower", A)] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type])
  • " @@ -695,7 +834,7 @@ SUBSYSTEM_DEF(zcopy) else if (A.type == /atom/movable/openspace/debug/turf) var/atom/movable/openspace/debug/turf/VTO = A - return "
  • [fmt_label("VTO", VTO.parent)] plane [VTO.plane], layer [VTO.layer], computed depth [FMT_DEPTH(VTO.computed_depth)] - [VTO.parent] ([VTO.parent.type]) - FOREIGN" + return "
  • [fmt_label("VTO", VTO.parent)] plane [VTO.plane], layer [VTO.layer], computed depth [FMT_DEPTH(VTO.computed_depth)] - [VTO.parent] ([VTO.parent.type]) - FOREIGN" else if (A.type == /atom/movable/openspace/turf_proxy) return "
  • [fmt_label("Turf Proxy", A)] plane [A.plane], layer [A.layer], Z-level [A.z] - [A] ([A.type])
  • " @@ -718,3 +857,38 @@ SUBSYSTEM_DEF(zcopy) out += "No atoms." #undef FMT_DEPTH +#undef FMT_OK +#undef ZM_RECORD_START +#undef ZM_RECORD_STOP +#undef ZM_RECORD_WRITE + +#ifdef ZM_RECORD_STATS +/client/proc/zms_display_turf() + set name = "ZM Stats - 1Turf" + set category = "Debug" + + if(!check_rights(R_DEBUG)) + return + + render_stats(SSzcopy.turf_stats, src) + +/client/proc/zms_display_discovery() + set name = "ZM Stats - 2Discovery" + set category = "Debug" + + if(!check_rights(R_DEBUG)) + return + + render_stats(SSzcopy.discovery_stats, src) + +/client/proc/zms_display_mimic() + set name = "ZM Stats - 3Mimic" + set category = "Debug" + + if(!check_rights(R_DEBUG)) + return + + render_stats(SSzcopy.mimic_stats, src) + + +#endif diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index dff70c19021..429ecfd060e 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -25,9 +25,6 @@ if("Radio") debug_variables(radio_controller) SSstatistics.add_field_details("admin_verb","DRadio") - if("Configuration") - debug_variables(config) - SSstatistics.add_field_details("admin_verb","DConf") if("pAI") debug_variables(paiController) SSstatistics.add_field_details("admin_verb","DpAI") diff --git a/code/datums/appearances/appearance_manager.dm b/code/datums/appearances/appearance_manager.dm index b5ce0b9e882..d196a89303d 100644 --- a/code/datums/appearances/appearance_manager.dm +++ b/code/datums/appearances/appearance_manager.dm @@ -6,8 +6,8 @@ if(!pq) pq = new /datum/priority_queue(/proc/cmp_appearance_data) appearances_[viewer] = pq - events_repository.register(/decl/observ/logged_in, viewer, src, /decl/appearance_manager/proc/apply_appearance_images) - events_repository.register(/decl/observ/destroyed, viewer, src, /decl/appearance_manager/proc/remove_appearances) + events_repository.register(/decl/observ/logged_in, viewer, src, TYPE_PROC_REF(/decl/appearance_manager, apply_appearance_images)) + events_repository.register(/decl/observ/destroyed, viewer, src, TYPE_PROC_REF(/decl/appearance_manager, remove_appearances)) pq.Enqueue(ad) reset_appearance_images(viewer) @@ -17,8 +17,8 @@ if(viewer.client) viewer.client.images -= ad.images if(!pq.Length()) - events_repository.unregister(/decl/observ/logged_in, viewer, src, /decl/appearance_manager/proc/apply_appearance_images) - events_repository.register(/decl/observ/destroyed, viewer, src, /decl/appearance_manager/proc/remove_appearances) + events_repository.unregister(/decl/observ/logged_in, viewer, src, TYPE_PROC_REF(/decl/appearance_manager, apply_appearance_images)) + events_repository.register(/decl/observ/destroyed, viewer, src, TYPE_PROC_REF(/decl/appearance_manager, remove_appearances)) appearances_ -= viewer /decl/appearance_manager/proc/remove_appearances(var/mob/viewer) diff --git a/code/datums/appearances/automatic/_base.dm b/code/datums/appearances/automatic/_base.dm index c4422652adc..03c71a126e5 100644 --- a/code/datums/appearances/automatic/_base.dm +++ b/code/datums/appearances/automatic/_base.dm @@ -6,7 +6,7 @@ if(source in appearance_sources) return FALSE appearance_sources[source] = new/datum/appearance_data(images, viewers, priority) - events_repository.register(/decl/observ/destroyed, source, src, /decl/appearance_handler/proc/RemoveAltAppearance) + events_repository.register(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/decl/appearance_handler, RemoveAltAppearance)) /decl/appearance_handler/proc/RemoveAltAppearance(var/source) var/datum/appearance_data/ad = appearance_sources[source] diff --git a/code/datums/appearances/automatic/cardborg.dm b/code/datums/appearances/automatic/cardborg.dm index 5a22f4763ea..42fcea16813 100644 --- a/code/datums/appearances/automatic/cardborg.dm +++ b/code/datums/appearances/automatic/cardborg.dm @@ -17,7 +17,7 @@ var/image/I = get_image_from_backpack(H) AddAltAppearance(H, I, global.silicon_mob_list+H) //you look like a robot to robots! (including yourself because you're totally a robot) - events_repository.register_global(/decl/observ/logged_in, src, /decl/appearance_handler/cardborg/proc/mob_joined) // Duplicate registration request are handled for us + events_repository.register_global(/decl/observ/logged_in, src, TYPE_PROC_REF(/decl/appearance_handler/cardborg, mob_joined)) // Duplicate registration request are handled for us /decl/appearance_handler/cardborg/proc/item_removed(var/obj/item/item, var/mob/user) if((istype(item, /obj/item/clothing/suit/cardborg) || istype(item, /obj/item/clothing/head/cardborg)) || istype(item, /obj/item/storage/backpack)) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index df3678803fe..e90b12f208b 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -153,7 +153,7 @@ return var/param = ref ? "\ref[ref]" : "null" - addtimer(CALLBACK(user, /mob/proc/post_onclose, windowid, param), 2) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, post_onclose), windowid, param), 2) /mob/proc/post_onclose(windowid, param) if(client) diff --git a/code/datums/callbacks.dm b/code/datums/callbacks.dm index 575a3f13959..869a5831bed 100644 --- a/code/datums/callbacks.dm +++ b/code/datums/callbacks.dm @@ -1,46 +1,44 @@ -// USAGE: -// -// var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn) -// var/timerid = addtimer(C, time, timertype) -// OR -// var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype) -// -// Note: proc strings can only be given for datum proc calls, global procs must be proc paths -// Also proc strings are strongly advised against because they don't compile error if the proc stops existing -// See the note on proc typepath shortcuts -// -// INVOKING THE CALLBACK: -// var/result = C.Invoke(args, to, add) //additional args are added after the ones given when the callback was created -// OR -// var/result = C.InvokeAsync(args, to, add) //Sleeps will not block, returns . on the first sleep (then continues on in the "background" after the sleep/block ends), otherwise operates normally. -// OR -// INVOKE_ASYNC() to immediately create and call InvokeAsync -// -// PROC TYPEPATH SHORTCUTS (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) -// -// global proc while in another global proc: -// .procname -// Example: -// CALLBACK(GLOBAL_PROC, .some_proc_here) -// -// proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents: -// .procname -// Example: -// CALLBACK(src, .some_proc_here) -// -// -// when the above doesn't apply: -// .proc/procname -// Example: -// CALLBACK(src, .proc/some_proc_here) -// -// proc defined on a parent of a some type: -// /some/type/.proc/some_proc_here -// -// -// -// Other wise you will have to do the full typepath of the proc (/type/of/thing/proc/procname) - +/** + *# Callback Datums + *A datum that holds a proc to be called on another object, used to track proccalls to other objects + * + * ## USAGE + * + * ``` + * var/datum/callback/C = new(object|null, PROC_REF(procname), arg1, arg2, ... argn) + * var/timerid = addtimer(C, time, timertype) + * you can also use the compiler define shorthand + * var/timerid = addtimer(CALLBACK(object|null, PROC_REF(procname), arg1, arg2, ... argn), time, timertype) + * ``` + * + * Note: proc strings can only be given for datum proc calls, global procs must be proc paths + * + * Also proc strings are strongly advised against because they don't compile error if the proc stops existing + * + * In some cases you can provide a shortform of the procname, see the proc typepath shortcuts documentation below + * + * ## INVOKING THE CALLBACK + *`var/result = C.Invoke(args, to, add)` additional args are added after the ones given when the callback was created + * + * `var/result = C.InvokeAsync(args, to, add)` Asynchronous - returns . on the first sleep then continues on in the background + * after the sleep/block ends, otherwise operates normally. + * + * ## PROC TYPEPATH SHORTCUTS + * (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) + * + * ### proc defined on current(src) object OR overridden at src or any of it's parents: + * PROC_REF(procname) + * + * `CALLBACK(src, PROC_REF(some_proc_here))` + * + * ### global proc + * GLOBAL_PROC_REF(procname) + * + * `CALLBACK(src, GLOBAL_PROC_REF(some_proc_here))` + * + * ### proc defined on some type + * TYPE_PROC_REF(/some/type/, some_proc_here) + */ /datum/callback var/datum/object = GLOBAL_PROC var/delegate diff --git a/code/datums/communication/aooc.dm b/code/datums/communication/aooc.dm index e6a3b9575b9..52ca16f4194 100644 --- a/code/datums/communication/aooc.dm +++ b/code/datums/communication/aooc.dm @@ -2,7 +2,7 @@ /decl/communication_channel/aooc name = "AOOC" - config_setting = "aooc_allowed" + config_setting = /decl/config/toggle/on/aooc_allowed expected_communicator_type = /client flags = COMMUNICATION_LOG_CHANNEL_NAME|COMMUNICATION_ADMIN_FOLLOW log_proc = /proc/log_ooc diff --git a/code/datums/communication/channel.dm b/code/datums/communication/channel.dm index 261a0bd658b..c9dc993cb37 100644 --- a/code/datums/communication/channel.dm +++ b/code/datums/communication/channel.dm @@ -48,7 +48,7 @@ log_debug("[log_info_line(communicator)] attempted to communicate over the channel [src] but was of an unexpected type.") return FALSE - if(config_setting && !config.vars[config_setting] && !check_rights(R_INVESTIGATE,0,communicator)) + if(config_setting && !get_config_value(config_setting) && !check_rights(R_INVESTIGATE,0,communicator)) to_chat(communicator, "[name] is globally muted.") return FALSE @@ -117,7 +117,7 @@ if (!message) return FALSE - if (!override_config && config_setting && !config.vars[config_setting]) + if (!override_config && config_setting && !get_config_value(config_setting)) return FALSE return TRUE diff --git a/code/datums/communication/dsay.dm b/code/datums/communication/dsay.dm index 67c01783178..c21705a672e 100644 --- a/code/datums/communication/dsay.dm +++ b/code/datums/communication/dsay.dm @@ -3,7 +3,7 @@ /decl/communication_channel/dsay name = "DSAY" - config_setting = "dsay_allowed" + config_setting = /decl/config/toggle/on/dsay_allowed expected_communicator_type = /client flags = COMMUNICATION_LOG_CHANNEL_NAME log_proc = /proc/log_say diff --git a/code/datums/communication/looc.dm b/code/datums/communication/looc.dm index 756c05f021a..925ccbeb1ac 100644 --- a/code/datums/communication/looc.dm +++ b/code/datums/communication/looc.dm @@ -1,6 +1,6 @@ /decl/communication_channel/ooc/looc name = "LOOC" - config_setting = "looc_allowed" + config_setting = /decl/config/toggle/on/looc_allowed flags = COMMUNICATION_NO_GUESTS|COMMUNICATION_LOG_CHANNEL_NAME|COMMUNICATION_ADMIN_FOLLOW show_preference_setting = /datum/client_preference/show_looc diff --git a/code/datums/communication/ooc.dm b/code/datums/communication/ooc.dm index 401c662e90b..2d206d206bc 100644 --- a/code/datums/communication/ooc.dm +++ b/code/datums/communication/ooc.dm @@ -1,6 +1,6 @@ /decl/communication_channel/ooc name = "OOC" - config_setting = "ooc_allowed" + config_setting = /decl/config/toggle/on/ooc_allowed expected_communicator_type = /client flags = COMMUNICATION_NO_GUESTS log_proc = /proc/log_ooc @@ -13,7 +13,7 @@ return if(!C.holder) - if(!config.dooc_allowed && (C.mob.stat == DEAD)) + if(!get_config_value(/decl/config/toggle/on/dooc_allowed) && (C.mob.stat == DEAD)) to_chat(C, "[name] for dead mobs has been turned off.") return FALSE if(findtext(message, "byond://")) diff --git a/code/datums/composite_sounds/_composite_sound.dm b/code/datums/composite_sounds/_composite_sound.dm index b7de5e43b9d..12790c6765c 100644 --- a/code/datums/composite_sounds/_composite_sound.dm +++ b/code/datums/composite_sounds/_composite_sound.dm @@ -64,7 +64,7 @@ if(!chance || prob(chance)) play(get_sound(starttime)) if(!timerid) - timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP) + timerid = addtimer(CALLBACK(src, PROC_REF(sound_loop), world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP) /datum/composite_sound/proc/play(soundfile) var/sound/S = sound(soundfile) @@ -81,7 +81,7 @@ if(start_sound) play(start_sound) start_wait = start_length - addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME) + addtimer(CALLBACK(src, PROC_REF(sound_loop)), start_wait, TIMER_CLIENT_TIME) /datum/composite_sound/proc/on_stop() if(end_sound) diff --git a/code/datums/config/_config.dm b/code/datums/config/_config.dm new file mode 100644 index 00000000000..0ffc1891a8b --- /dev/null +++ b/code/datums/config/_config.dm @@ -0,0 +1,152 @@ +#define CONFIG_FLAG_BOOL BITFLAG(0) +#define CONFIG_FLAG_NUM BITFLAG(1) +#define CONFIG_FLAG_ENUM BITFLAG(2) +#define CONFIG_FLAG_TEXT BITFLAG(3) +#define CONFIG_FLAG_LIST BITFLAG(4) +#define CONFIG_FLAG_HAS_VALUE BITFLAG(5) + +/proc/get_config_value(var/config_decl) + var/decl/config/config_option = GET_DECL(config_decl) + return config_option.value + +/proc/set_config_value(var/config_decl, var/new_value, var/defer_config_refresh = FALSE) + + // Get our actual value (loading from text etc. may change data type) + var/decl/config/config_option = GET_DECL(config_decl) + if((config_option.config_flags & CONFIG_FLAG_NUM) && istext(new_value)) + new_value = text2num(new_value) + else if((config_option.config_flags & (CONFIG_FLAG_ENUM|CONFIG_FLAG_TEXT)) && isnum(new_value)) + new_value = num2text(new_value) + + // Identical values, no point updating. + if(config_option.value == new_value) + return + + // Actually set the value. + var/old_value = config_option.value + config_option.set_value(new_value) + if(config_option.value != old_value && !defer_config_refresh) + config_option.update_post_value_set() + +/proc/toggle_config_value(var/config_decl) + var/decl/config/config_option = GET_DECL(config_decl) + if(!(config_option.config_flags & CONFIG_FLAG_BOOL)) + CRASH("Attempted to toggle non-boolean config entry [config_decl].") + set_config_value(config_decl, !config_option.value) + return config_option.value + +/decl/config + abstract_type = /decl/config + decl_flags = DECL_FLAG_MANDATORY_UID + var/desc + var/value + var/default_value + var/config_flags = CONFIG_FLAG_HAS_VALUE + var/protected = FALSE + + var/static/list/protected_vars = list( + "desc", + "value", + "default_value", + "config_flags", + "protected" + ) + +/decl/config/Initialize() + . = ..() + // Config options without values are assumed false and set to true if present in the loaded data. + // Otherwise we initialize to the default value. + if(!(config_flags & CONFIG_FLAG_HAS_VALUE)) + default_value = FALSE + if(desc) + desc += " Uncomment to enable." + else + desc = "Uncomment to enable." + value = default_value + +/decl/config/VV_hidden() + . = ..() + if(protected) + . |= protected_vars + +/decl/config/validate() + . = ..() + if(isnull(desc)) + . += "no config description set" + if(isnull(default_value)) + if(config_flags & CONFIG_FLAG_HAS_VALUE) + . += "null default value" + else + if((config_flags & (CONFIG_FLAG_NUM|CONFIG_FLAG_ENUM)) && !isnum(default_value)) + . += "has numeric or enum flag but not numeric default_value" + else if((config_flags & CONFIG_FLAG_TEXT) && !istext(default_value)) + . += "has text flag but not text default_value" + else if((config_flags & CONFIG_FLAG_LIST) && !islist(default_value)) + . += "has list flag but not list default_value" + set_value(handle_value_deconversion(default_value)) + if(!compare_values(value, default_value)) + . += "setting to default value via proc resulted in different value ([serialize_value(value)] != [serialize_value(default_value)])" + var/comparison_fail = default_value_serialize_comparison_fails() + if(comparison_fail) + . += "conversion and deconversion of default value does not equal default value ([comparison_fail])" + +/decl/config/proc/compare_values(var/value_one, var/value_two) + return value_one == value_two + +/decl/config/proc/default_value_serialize_comparison_fails() + var/new_val = handle_value_conversion(handle_value_deconversion(default_value)) + if(!compare_values(new_val, default_value)) + return "[new_val] != [default_value]" + +/decl/config/proc/sanitize_value() + SHOULD_CALL_PARENT(TRUE) + var/invalid_value = FALSE + if((config_flags & CONFIG_FLAG_BOOL) && value != TRUE && value != FALSE) + invalid_value = TRUE + else if((config_flags & (CONFIG_FLAG_NUM|CONFIG_FLAG_ENUM)) && !isnum(value)) + invalid_value = TRUE + else if((config_flags & CONFIG_FLAG_TEXT) && !istext(value)) + invalid_value = TRUE + else if((config_flags & CONFIG_FLAG_LIST) && !islist(value)) + invalid_value = TRUE + if(invalid_value) + value = default_value + +/decl/config/proc/update_post_value_set() + SHOULD_CALL_PARENT(TRUE) + return + +/decl/config/proc/get_config_file_text() + . = list() + if(desc) + if(islist(desc)) + for(var/config_line in desc) + . += "## [config_line]" + else + . += "## [desc]" + if(config_flags & CONFIG_FLAG_HAS_VALUE) + if(compare_values(value, default_value)) + . += "#[uppertext(uid)] [serialize_default_value()]" + else + . += "[uppertext(uid)] [serialize_value()]" + else if(value) + . += uppertext(uid) + else + . += "#[uppertext(uid)]" + return jointext(., "\n") + +/decl/config/proc/serialize_value() + return "[handle_value_deconversion(value)]" + +/decl/config/proc/serialize_default_value() + return "[handle_value_deconversion(default_value)]" + +/decl/config/proc/handle_value_conversion(var/new_value) + return new_value + +/decl/config/proc/handle_value_deconversion(var/new_value) + return new_value + +/decl/config/proc/set_value(var/new_value) + value = handle_value_conversion(new_value) + sanitize_value() diff --git a/code/datums/config/_config_categories.dm b/code/datums/config/_config_categories.dm new file mode 100644 index 00000000000..b9212994768 --- /dev/null +++ b/code/datums/config/_config_categories.dm @@ -0,0 +1,40 @@ +/decl/configuration_category + abstract_type = /decl/configuration_category + var/name + var/desc + var/configuration_file_location = "config/configuration.txt" + var/list/associated_configuration + +/decl/configuration_category/Initialize() + if(length(associated_configuration)) + for(var/decl_type in associated_configuration) + associated_configuration -= decl_type + associated_configuration += GET_DECL(decl_type) + return ..() + +/decl/configuration_category/validate() + . = ..() + if(!name) + . += "no name set" + if(!desc) + . += "no description supplied" + if(isnull(configuration_file_location)) + . += "null dump file target" + +/decl/configuration_category/proc/get_config_category_text() + + if(!length(associated_configuration)) + return "" + + var/list/header = list( + "##", + "# [uppertext(name)]", + "# [desc]", + "##" + ) + + . = list("[jointext(header, "\n")]") + associated_configuration = sortTim(associated_configuration, /proc/cmp_decl_uid_asc) + for(var/decl/config/config_option in associated_configuration) + . += config_option.get_config_file_text() + return jointext(., "\n\n") diff --git a/code/datums/config/config_enum.dm b/code/datums/config/config_enum.dm new file mode 100644 index 00000000000..ba61b07b6dd --- /dev/null +++ b/code/datums/config/config_enum.dm @@ -0,0 +1,32 @@ +/decl/config/enum + abstract_type = /decl/config/enum + default_value = 0 + config_flags = CONFIG_FLAG_ENUM | CONFIG_FLAG_HAS_VALUE + +/decl/config/enum/proc/get_enum_map() + return + +/decl/config/enum/validate() + . = ..() + if(!length(get_enum_map())) + . += "enum config has zero-length return to get_enum_map()" + +/decl/config/enum/Initialize() + . = ..() + var/list/enum_map = get_enum_map() + if(length(enum_map)) + if(desc) + desc = "[desc] Valid values: [english_list(enum_map)]." + else + desc = english_list(enum_map) + +/decl/config/enum/set_value(var/new_value) + if(istext(new_value)) + var/list/enum_map = get_enum_map() + new_value = trim(lowertext(new_value)) + if(new_value in enum_map) + new_value = enum_map[new_value] + else + log_error("Invalid key '[new_value]' supplied to [type].") + new_value = default_value + return ..(new_value) diff --git a/code/datums/config/config_list.dm b/code/datums/config/config_list.dm new file mode 100644 index 00000000000..a2c5893c39c --- /dev/null +++ b/code/datums/config/config_list.dm @@ -0,0 +1,25 @@ +/decl/config/lists + abstract_type = /decl/config/lists + default_value = list() + config_flags = CONFIG_FLAG_LIST | CONFIG_FLAG_HAS_VALUE + +/decl/config/lists/handle_value_deconversion(var/new_value) + return json_encode(new_value) + +/decl/config/lists/handle_value_conversion(var/new_value) + return json_decode(new_value) + +/decl/config/lists/compare_values(var/value_one, var/value_two) + if(!islist(value_one) || !islist(value_two)) + return ..(value_one, value_two) + if(length(value_one) != length(value_two)) + return FALSE + for(var/i = 1 to length(value_one)) + if(!same_entries(value_one[i], value_two[i]) && value_one[i] != value_two[i]) + return FALSE + return TRUE + +/decl/config/lists/default_value_serialize_comparison_fails() + var/list/new_value = handle_value_conversion(handle_value_deconversion(default_value)) + if(!compare_values(new_value, default_value)) + return "[json_encode(new_value)] != [json_encode(default_value)]" diff --git a/code/datums/config/config_num.dm b/code/datums/config/config_num.dm new file mode 100644 index 00000000000..9e28c6e5ec0 --- /dev/null +++ b/code/datums/config/config_num.dm @@ -0,0 +1,18 @@ +/decl/config/num + abstract_type = /decl/config/num + config_flags = CONFIG_FLAG_NUM | CONFIG_FLAG_HAS_VALUE + default_value = 0 + var/min_value = -(INFINITY) + var/max_value = INFINITY + var/rounding + +/decl/config/num/sanitize_value() + ..() + value = clamp(value, min_value, max_value) + if(!isnull(rounding)) + value = round(value, rounding) + +/decl/config/num/compare_values(value_one, value_two) + if(!isnum(value_one) || !isnum(value_two) || !rounding) + return ..(value_one, value_two) + return abs(value_one - value_two) < rounding // epsilon compare due to floating point issues \ No newline at end of file diff --git a/code/datums/config/config_num_client.dm b/code/datums/config/config_num_client.dm new file mode 100644 index 00000000000..4b1527c9fb5 --- /dev/null +++ b/code/datums/config/config_num_client.dm @@ -0,0 +1,7 @@ +/decl/config/num/clients + abstract_type = /decl/config/num/clients + +/decl/config/num/clients/update_post_value_set() + for(var/client/client) + client.OnResize() + . = ..() diff --git a/code/datums/config/config_text.dm b/code/datums/config/config_text.dm new file mode 100644 index 00000000000..4385399d4d7 --- /dev/null +++ b/code/datums/config/config_text.dm @@ -0,0 +1,4 @@ +/decl/config/text + abstract_type = /decl/config/text + config_flags = CONFIG_FLAG_TEXT | CONFIG_FLAG_HAS_VALUE + default_value = "" diff --git a/code/datums/config/config_toggle.dm b/code/datums/config/config_toggle.dm new file mode 100644 index 00000000000..ac859d2edb0 --- /dev/null +++ b/code/datums/config/config_toggle.dm @@ -0,0 +1,4 @@ +/decl/config/toggle + abstract_type = /decl/config/toggle + config_flags = CONFIG_FLAG_BOOL + default_value = FALSE diff --git a/code/datums/config/config_toggle_on.dm b/code/datums/config/config_toggle_on.dm new file mode 100644 index 00000000000..1f1910a1308 --- /dev/null +++ b/code/datums/config/config_toggle_on.dm @@ -0,0 +1,5 @@ + +/decl/config/toggle/on + abstract_type = /decl/config/toggle/on + default_value = TRUE + config_flags = CONFIG_FLAG_BOOL | CONFIG_FLAG_HAS_VALUE diff --git a/code/datums/config/config_types/config_admin.dm b/code/datums/config/config_types/config_admin.dm new file mode 100644 index 00000000000..c7515d4ea52 --- /dev/null +++ b/code/datums/config/config_types/config_admin.dm @@ -0,0 +1,79 @@ +/decl/configuration_category/admin + name = "Admin" + desc = "Configuration options relating to administration." + associated_configuration = list( + /decl/config/num/mod_tempban_max, + /decl/config/num/mod_job_tempban_max, + /decl/config/num/autostealth, + /decl/config/toggle/on/guest_jobban, + /decl/config/toggle/on/auto_local_admin, + /decl/config/toggle/on/admin_jump, + /decl/config/toggle/on/admin_spawning, + /decl/config/toggle/on/admin_revive, + /decl/config/toggle/admin_ooccolor, + /decl/config/toggle/mods_can_job_tempban, + /decl/config/toggle/mods_can_tempban, + /decl/config/toggle/allow_unsafe_narrates + ) + +/decl/config/num/mod_tempban_max + uid = "mod_tempban_max" + default_value = 1440 + desc = "Maximum mod tempban duration (in minutes)." + +/decl/config/num/mod_job_tempban_max + uid = "mod_job_tempban_max" + default_value = 1440 + desc = "Maximum mod job tempban duration (in minutes)." + +/decl/config/num/autostealth + uid = "autostealth" + default_value = 0 + desc = "Uncomment to enable auto-stealthing staff who are AFK for more than specified minutes." + +/decl/config/toggle/on/guest_jobban + uid = "guest_jobban" + desc = list( + "Set to jobban 'Guest-' accounts from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions.", + "Set to 1 to jobban them from those positions, set to 0 to allow them." + ) + +/decl/config/toggle/on/auto_local_admin + uid = "auto_local_admin" + desc = "Set to 0/1 to disable/enable automatic admin rights for users connecting from the host the server is running on." + +/decl/config/toggle/on/admin_jump + uid = "allow_admin_jump" + desc = "Allows admin jumping." + +/decl/config/toggle/on/admin_spawning + uid = "allow_admin_spawning" + desc = "Allows admin item spawning." + +/decl/config/toggle/on/admin_revive + uid = "allow_admin_rev" + desc = "Allows admin revives." + +/decl/config/toggle/admin_ooccolor + uid = "allow_admin_ooccolor" + desc = "Comment this out to stop admins being able to choose their personal OOC color." + +/decl/config/toggle/mods_can_tempban + uid = "mods_can_tempban" + desc = "Chooses whether mods have the ability to tempban or not." + +/decl/config/toggle/mods_can_job_tempban + uid = "mods_can_job_tempban" + desc = "Chooses whether mods have the ability to issue tempbans for jobs or not." + +/decl/config/toggle/allow_unsafe_narrates + uid = "allow_unsafe_narrates" + desc = "Uncomment this to allow admins to narrate using HTML tags." + +/decl/config/toggle/visible_examine + uid = "visible_examine" + desc = "Uncomment this to show a visible message when someone examines something ('Dave looks at you.')." + +/decl/config/toggle/allow_loadout_customization + uid = "loadout_customization" + desc = "Uncomment this to allow all loadout items to have name and desc customized by default." diff --git a/code/datums/config/config_types/config_client.dm b/code/datums/config/config_types/config_client.dm new file mode 100644 index 00000000000..cb6e8a5a359 --- /dev/null +++ b/code/datums/config/config_types/config_client.dm @@ -0,0 +1,60 @@ +/decl/configuration_category/events + name = "Client" + desc = "Configuration options relating to client settings." + associated_configuration = list( + /decl/config/num/clients/lock_client_view_x, + /decl/config/num/clients/lock_client_view_y, + /decl/config/num/clients/max_client_view_x, + /decl/config/num/clients/max_client_view_y, + /decl/config/toggle/popup_admin_pm, + /decl/config/toggle/aggressive_changelog, + /decl/config/lists/forbidden_versions + ) + +/decl/config/lists/forbidden_versions + uid = "forbidden_versions" + default_value = list("512.0001", "512.0002") + desc = "BYOND builds that will result the client using them to be banned." + +/decl/config/num/clients/lock_client_view_x + uid = "lock_client_view_x" + default_value = 0 + desc = "Uncomment and set to an integer to lock the automatic client view scaling on the X axis." + +/decl/config/num/clients/lock_client_view_y + uid = "lock_client_view_y" + default_value = 0 + desc = "Uncomment and set to an integer to lock the automatic client view scaling on the Y axis." + +/decl/config/num/clients/max_client_view_x + uid = "max_client_view_x" + default_value = MAX_VIEW + desc = "Change to set a maximum size for the client view X scaling." + +/decl/config/num/clients/max_client_view_x/update_post_value_set() + global.click_catchers = null + for(var/client/client) + client.reset_click_catchers() + . = ..() + +/decl/config/num/clients/max_client_view_y + uid = "max_client_view_y" + default_value = MAX_VIEW + desc = "Change to set a maximum size for the client view Y scaling." + +/decl/config/num/clients/max_client_view_y/update_post_value_set() + global.click_catchers = null + for(var/client/client) + client.reset_click_catchers() + . = ..() + +/decl/config/toggle/popup_admin_pm + uid = "popup_admin_pm" + desc = list( + "Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM.", + "The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off)." + ) + +/decl/config/toggle/aggressive_changelog + uid = "aggressive_changelog" + desc = "Uncomment to have the changelog file automatically open when a user connects and hasn't seen the latest changelog." diff --git a/code/datums/config/config_types/config_debug.dm b/code/datums/config/config_types/config_debug.dm new file mode 100644 index 00000000000..66f250dd8ea --- /dev/null +++ b/code/datums/config/config_types/config_debug.dm @@ -0,0 +1,38 @@ +/decl/configuration_category/debug + name = "Debug" + desc = "Configuration options relating to error reporting." + associated_configuration = list( + /decl/config/num/debug_error_cooldown, + /decl/config/num/debug_error_limit, + /decl/config/num/debug_error_silence_time, + /decl/config/num/debug_error_msg_delay, + /decl/config/toggle/paranoid + ) + +/decl/config/num/debug_error_cooldown + uid = "error_cooldown" + desc = "The \"cooldown\" time for each occurrence of a unique error." + default_value = 600 + +/decl/config/num/debug_error_limit + uid = "error_limit" + desc = "How many occurrences before the next will silence them." + default_value = 50 + +/decl/config/num/debug_error_silence_time + uid = "error_silence_time" + desc = "How long a unique error will be silenced for." + default_value = 6000 + +/decl/config/num/debug_error_msg_delay + uid = "error_msg_delay" + desc = "How long to wait between messaging admins about occurrences of a unique error." + default_value = 50 + +/decl/config/toggle/paranoid + uid = "debug_paranoid" + desc = list( + "Uncomment to make proccall require R_ADMIN instead of R_DEBUG", + "designed for environments where you have testers but don't want them", + "able to use the more powerful debug options." + ) diff --git a/code/datums/config/config_types/config_events.dm b/code/datums/config/config_types/config_events.dm new file mode 100644 index 00000000000..0b83e38fb2b --- /dev/null +++ b/code/datums/config/config_types/config_events.dm @@ -0,0 +1,50 @@ +/decl/configuration_category/events + name = "Events" + desc = "Configuration options relating to event timers and probabilities." + associated_configuration = list( + /decl/config/enum/objectives_disabled, + /decl/config/lists/event_first_run, + /decl/config/lists/event_delay_lower, + /decl/config/lists/event_delay_upper, + /decl/config/toggle/allow_random_events + ) + +//if objectives are disabled or not +/decl/config/enum/objectives_disabled + uid = "objectives_disabled" + default_value = CONFIG_OBJECTIVE_NONE + desc = "Determines if objectives are disabled." + +/decl/config/enum/objectives_disabled/get_enum_map() + var/static/list/obj_enum_map = list( + "none" = CONFIG_OBJECTIVE_NONE, + "verb" = CONFIG_OBJECTIVE_VERB, + "all" = CONFIG_OBJECTIVE_ALL + ) + return obj_enum_map + +// No custom time, no custom time, between 80 to 100 minutes respectively. +/decl/config/lists/event_first_run + uid = "event_first_run" + desc = "If the first delay has a custom start time. Defined in minutes." + default_value = list(null, null, list("lower" = 80, "upper" = 100)) + +/decl/config/lists/event_delay_lower + uid = "event_delay_lower" + default_value = list(10, 30, 50) + desc = list( + "The lower delay between events in minutes.", + "Affect mundane, moderate, and major events respectively." + ) + +/decl/config/lists/event_delay_upper + uid = "event_delay_upper" + default_value = list(15, 45, 70) + desc = list( + "The upper delay between events in minutes.", + "Affect mundane, moderate, and major events respectively." + ) + +/decl/config/toggle/allow_random_events + uid = "allow_random_events" + desc = "Hash out to disable random events during the round." diff --git a/code/datums/config/config_types/config_game_option.dm b/code/datums/config/config_types/config_game_option.dm new file mode 100644 index 00000000000..0d9754a354c --- /dev/null +++ b/code/datums/config/config_types/config_game_option.dm @@ -0,0 +1,174 @@ +/decl/configuration_category/game_options + name = "Game Options" + desc = "Configuration options relating to gameplay, such as movement, health and stamina." + associated_configuration = list( + /decl/config/num/movement_human, + /decl/config/num/movement_robot, + /decl/config/num/movement_animal, + /decl/config/num/movement_run, + /decl/config/num/movement_walk, + /decl/config/num/movement_creep, + /decl/config/num/movement_glide_size, + /decl/config/num/movement_min_sprint_cost, + /decl/config/num/movement_skill_sprint_cost_range, + /decl/config/num/movement_min_stamina_recovery, + /decl/config/num/movement_max_stamina_recovery, + /decl/config/num/max_gear_cost, + /decl/config/num/max_acts_per_interval, + /decl/config/num/act_interval, + /decl/config/num/dex_malus_brainloss_threshold, + /decl/config/num/default_darksight_range, + /decl/config/num/default_darksight_effectiveness, + /decl/config/toggle/grant_default_darksight, + /decl/config/num/expected_round_length, + /decl/config/toggle/allow_diagonal_movement, + /decl/config/toggle/expanded_alt_interactions, + /decl/config/toggle/ert_admin_call_only, + /decl/config/toggle/ghosts_can_possess_animals, + /decl/config/toggle/assistant_maint, + /decl/config/toggle/ghost_interaction, + /decl/config/toggle/aliens_allowed, + /decl/config/toggle/ninjas_allowed, + /decl/config/toggle/allow_character_comments, + /decl/config/num/hide_comments_older_than + ) + +/decl/config/num/movement_human + uid = "human_delay" + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_robot + uid = "robot_delay" + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_animal + uid = "animal_delay" + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_run + uid = "run_delay" + default_value = 2 + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_walk + uid = "walk_delay" + default_value = 4 + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_creep + uid = "creep_delay" + default_value = 6 + desc = "These modify the run/walk speed of all mobs before the mob-specific modifiers are applied." + +/decl/config/num/movement_glide_size + uid = "glide_size_delay" + default_value = 1 + desc = "Set this to 0 for perfectly smooth movement gliding, or 1 or more for delayed chess move style movements." + +/decl/config/num/movement_min_sprint_cost + uid = "minimum_sprint_cost" + default_value = 0.8 + rounding = 0.01 + desc = "Value used for expending stamina during sprinting." + +/decl/config/num/movement_skill_sprint_cost_range + uid = "skill_sprint_cost_range" + default_value = 0.8 + rounding = 0.01 + desc = "Determines the severity of athletics skill when applied to stamina cost." + +/decl/config/num/movement_min_stamina_recovery + uid = "minimum_stamina_recovery" + default_value = 1 + desc = "Minimum stamina recovered per tick when resting." + +/decl/config/num/movement_max_stamina_recovery + uid = "maximum_stamina_recovery" + default_value = 3 + desc = "Maximum stamina recovered per tick when resting." + +/decl/config/num/max_gear_cost + uid = "max_gear_cost" + default_value = 10 + desc = "How many loadout points are available. Use 0 to disable loadout, and any negative number to indicate infinite points." + +/decl/config/num/max_gear_cost/sanitize_value() + ..() + if(value < 0) + value = INFINITY + +/decl/config/num/max_acts_per_interval + uid = "max_acts_per_interval" + default_value = 140 + desc = "Uncomment this to modify the number of actions permitted per interval before being kicked for spam." + +/decl/config/num/act_interval + uid = "act_interval" + default_value = 0.1 + rounding = 0.01 + desc = "Uncomment this to modify the length of the spam kicking interval in seconds." + +/decl/config/num/dex_malus_brainloss_threshold + uid = "dex_malus_brainloss_threshold" + default_value = 30 + desc = "Threshold of where brain damage begins to affect dexterity (70 brainloss above this means zero dexterity). Default is 30." + +/decl/config/num/default_darksight_range + uid = "default_darksight_range" + default_value = 2 + desc = "The range of default darksight if above is uncommented." + +/decl/config/num/default_darksight_effectiveness + uid = "default_darksight_effectiveness" + default_value = 0.05 + rounding = 0.01 + desc = "The effectiveness of default darksight if above is uncommented." + +/decl/config/num/expected_round_length + uid = "expected_round_length" + default_value = 3 + desc = "Expected round length in hours." + +/decl/config/toggle/grant_default_darksight + uid = "grant_default_darksight" + desc = "Whether or not all human mobs have very basic darksight by default." + +/decl/config/toggle/allow_diagonal_movement + uid = "allow_diagonal_movement" + desc = "Allow multiple input keys to be pressed for diagonal movement." + +/decl/config/toggle/expanded_alt_interactions + uid = "expanded_alt_interactions" + desc = "Uncomment this to enable expanded alt interactions with objects." + +/decl/config/toggle/ert_admin_call_only + uid = "ert_admin_call_only" + desc = "Restricted ERT to be only called by admins." + +/decl/config/toggle/ghosts_can_possess_animals + uid = "ghosts_can_possess_animals" + desc = "Uncomment to allow ghosts to possess any animal." + +/decl/config/toggle/assistant_maint + uid = "assistant_maint" + desc = "Remove the # to give assistants maint access." + +/decl/config/toggle/ghost_interaction + uid = "ghost_interaction" + desc = "Remove the # to let ghosts spin chairs." + +/decl/config/toggle/aliens_allowed + uid = "aliens_allowed" + desc = "Remove the # to let aliens spawn." + +/decl/config/toggle/ninjas_allowed + uid = "ninjas_allowed" + desc = "Remove the # to let ninjas spawn." + +/decl/config/toggle/allow_character_comments + uid = "allow_character_comments" + desc = "Remove the # to allow people to leave public comments on each other's characters via the comments system." + +/decl/config/num/hide_comments_older_than + uid = "hide_comments_older_than" + desc = "Specify a number of days after which to hide comments on public profiles (to avoid bloat from retired characters)." diff --git a/code/datums/config/config_types/config_game_world.dm b/code/datums/config/config_types/config_game_world.dm new file mode 100644 index 00000000000..d81b963b1f6 --- /dev/null +++ b/code/datums/config/config_types/config_game_world.dm @@ -0,0 +1,127 @@ +/decl/configuration_category/game_world + name = "Game World" + desc = "Configuration options relating to the game world and simulation." + associated_configuration = list( + /decl/config/num/exterior_ambient_light, + /decl/config/num/radiation_decay_rate, + /decl/config/num/radiation_resistance_multiplier, + /decl/config/num/radiation_material_resistance_divisor, + /decl/config/num/radiation_lower_limit, + /decl/config/num/exoplanet_min_day_duration, + /decl/config/num/exoplanet_max_day_duration, + /decl/config/toggle/use_iterative_explosions, + /decl/config/num/iterative_explosives_z_threshold, + /decl/config/num/iterative_explosives_z_multiplier, + /decl/config/num/maximum_mushrooms, + /decl/config/num/gateway_delay, + /decl/config/text/law_zero, + /decl/config/toggle/on/welder_vision, + /decl/config/toggle/on/allow_ic_printing, + /decl/config/toggle/on/cult_ghostwriter, + /decl/config/toggle/allow_holidays, + /decl/config/toggle/humans_need_surnames, + /decl/config/toggle/roundstart_level_generation + ) + +/decl/config/num/exterior_ambient_light + uid = "exterior_ambient_light" + default_value = 0 + min_value = 0 + desc = "Percentile strength of exterior ambient light (such as starlight). 0.5 is 50% lit." + +/decl/config/num/radiation_decay_rate + uid = "radiation_decay_rate" + default_value = 1 + desc = "How much radiation levels self-reduce by each tick." + +/decl/config/num/radiation_resistance_multiplier + uid = "radiation_resistance_multiplier" + default_value = 1.25 + desc = "The amount of radiation resistance on a turf is multiplied by this value." + +/decl/config/num/radiation_material_resistance_divisor + uid = "radiation_material_resistance_divisor" + default_value = 2 + desc = "General material radiation resistance is divided by this value." + +/decl/config/num/radiation_lower_limit + uid = "radiation_lower_limit" + default_value = 0.15 + rounding = 0.1 + desc = list( + "Below this point, radiation is ignored.", + "Radiation weakens with distance from the source; stop calculating when the strength falls below this value. Lower values mean radiation reaches smaller (with increasingly trivial damage) at the cost of more CPU usage.", + "Max range = DISTANCE^2 * POWER / RADIATION_LOWER_LIMIT" + ) + +/decl/config/num/exoplanet_min_day_duration + uid = "exoplanet_min_day_duration" + default_value = 10 + desc = "The minimum duration of an exoplanet day, in minutes." + +/decl/config/num/exoplanet_max_day_duration + uid = "exoplanet_max_day_duration" + default_value = 40 + desc = "The maximum duration of an exoplanet day, in minutes." + +/decl/config/toggle/use_iterative_explosions + uid = "use_iterative_explosions" + desc = "Unhash this to use iterative explosions, keep it hashed to use circle explosions." + +/decl/config/num/iterative_explosives_z_threshold + uid = "iterative_explosives_z_threshold" + default_value = 10 + desc = "The power of explosion required for it to cross Z-levels." + +/decl/config/num/iterative_explosives_z_multiplier + uid = "iterative_explosives_z_multiplier" + default_value = 0.75 + rounding = 0.01 + desc = "What to multiply power by when crossing Z-levels." + +/decl/config/num/maximum_mushrooms + uid = "maximum_mushrooms" + desc = "After this amount alive, walking mushrooms spawned from botany will not reproduce." + default_value = 15 + +/decl/config/num/gateway_delay + uid = "gateway_delay" + default_value = 18000 + desc = "How long the delay is before the Away Mission gate opens. Default is half an hour." + +/decl/config/text/law_zero + uid = "law_zero" + default_value = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" + desc = "Defines how Law Zero is phrased. Primarily used in the Malfunction gamemode." + +/decl/config/toggle/on/welder_vision + uid = "welder_vision" + desc = "Uncomment to disable the restrictive weldervision overlay." + +/decl/config/toggle/on/allow_ic_printing + uid = "allow_ic_printing" + desc = "Uncomment this to prevent players from printing copy/pasted circuits." + +/decl/config/toggle/on/cult_ghostwriter + uid = "cult_ghostwriter" + desc = "Uncomment to allow ghosts to write in blood during Cult rounds." + +/decl/config/toggle/allow_holidays + uid = "allow_holidays" + desc = "Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR" + +/decl/config/toggle/allow_holidays/update_post_value_set() + . = ..() + update_holiday() + +/decl/config/toggle/humans_need_surnames + uid = "humans_need_surnames" + desc = "Humans are forced to have surnames if this is uncommented." + +/decl/config/toggle/disable_daycycle + uid = "disable_daycycle" + desc = "If true, exoplanets won't have daycycles." + +/decl/config/toggle/roundstart_level_generation + uid = "roundstart_level_generation" + desc = "Enable/Disable random level generation. Will behave strangely if turned off with a map that expects it on." diff --git a/code/datums/config/config_types/config_health.dm b/code/datums/config/config_types/config_health.dm new file mode 100644 index 00000000000..c5db9f04e7a --- /dev/null +++ b/code/datums/config/config_types/config_health.dm @@ -0,0 +1,90 @@ +/decl/configuration_category/health + name = "Health" + desc = "Configuration options relating to the health simulation." + associated_configuration = list( + /decl/config/num/health_stress_shock_recovery_constant, + /decl/config/num/health_stress_healing_recovery_constant, + /decl/config/num/health_stress_blood_recovery_constant, + /decl/config/num/health_health_threshold_dead, + /decl/config/num/health_organ_health_multiplier, + /decl/config/num/health_organ_regeneration_multiplier, + /decl/config/num/health_organ_damage_spillover_multiplier, + /decl/config/num/health_revival_brain_life, + /decl/config/toggle/on/health_bones_can_break, + /decl/config/toggle/on/health_limbs_can_break + ) + +/decl/config/toggle/health_adjust_healing_from_stress + uid = "adjust_healing_from_stress" + config_flags = CONFIG_FLAG_BOOL + desc = "Uncomment to allow stressors to impact shock, healing and blood recovery." + +/decl/config/toggle/health_show_human_death_message + uid = "show_human_death_message" + config_flags = CONFIG_FLAG_BOOL + desc = "Uncomment this line to enable humans showing a visible message upon death ('X seizes up then falls limp, eyes dead and lifeless')." + +/decl/config/toggle/health_organs_decay + uid = "organs_decay" + config_flags = CONFIG_FLAG_BOOL + desc = "Uncomment to enable organ decay outside of a body or storage item." + +/decl/config/toggle/on/health_bones_can_break + uid = "bones_can_break" + desc = list( + "Determines whether bones can be broken through excessive damage to the organ.", + "0 means bones can't break, 1 means they can." + ) + +/decl/config/toggle/on/health_limbs_can_break + uid = "limbs_can_break" + desc = list( + "Determines whether limbs can be amputated through excessive damage to the organ.", + "0 means limbs can't be amputated, 1 means they can." + ) + + +/decl/config/num/health_stress_shock_recovery_constant + uid = "stress_shock_recovery_constant" + default_value = 0.5 + rounding = 0.01 + desc = "A multiplier for the impact stress has on shock recovery - 0.3 means maximum stress imposes a 30% penalty on shock recovery." + +/decl/config/num/health_stress_healing_recovery_constant + uid = "stress_healing_recovery_constant" + default_value = 0.3 + rounding = 0.01 + desc = "A multiplier for the impact stress has on wound passive healing, as above." + +/decl/config/num/health_stress_blood_recovery_constant + uid = "stress_blood_recovery_constant" + default_value = 0.3 + rounding = 0.01 + desc = "A multiplier for the impact stress has on blood regeneration, as above." + +/decl/config/num/health_health_threshold_dead + uid = "health_threshold_dead" + default_value = -100 + desc = "Level of health at which a mob becomes dead." + +/decl/config/num/health_organ_health_multiplier + uid = "organ_health_multiplier" + default_value = 0.9 + rounding = 0.01 + desc = "Percentage multiplier which enables organs to take more damage before bones breaking or limbs being destroyed." + +/decl/config/num/health_organ_regeneration_multiplier + uid = "organ_regeneration_multiplier" + default_value = 0.25 + desc = "Percentage multiplier which influences how fast organs regenerate naturally." + +/decl/config/num/health_organ_damage_spillover_multiplier + uid = "organ_damage_spillover_multiplier" + desc = "Percentage multiplier that influences how damage spreads around organs. 100 means normal, 50 means half." + default_value = 0.5 + rounding = 0.01 + +/decl/config/num/health_revival_brain_life + uid = "revival_brain_life" + default_value = -1 + desc = "Amount of time (in hundredths of seconds) for which a brain retains the 'spark of life' after the person's death (set to -1 for infinite)." diff --git a/code/datums/config/config_types/config_logging.dm b/code/datums/config/config_types/config_logging.dm new file mode 100644 index 00000000000..8efc131bce0 --- /dev/null +++ b/code/datums/config/config_types/config_logging.dm @@ -0,0 +1,85 @@ +/decl/configuration_category/logging + name = "Logging" + desc = "Configuration options relating to logging." + associated_configuration = list( + /decl/config/toggle/log_ooc, + /decl/config/toggle/log_access, + /decl/config/toggle/log_say, + /decl/config/toggle/log_admin, + /decl/config/toggle/log_debug, + /decl/config/toggle/log_game, + /decl/config/toggle/log_vote, + /decl/config/toggle/log_whisper, + /decl/config/toggle/log_emotes, + /decl/config/toggle/log_attack, + /decl/config/toggle/log_adminchat, + /decl/config/toggle/log_adminwarn, + /decl/config/toggle/log_pda, + /decl/config/toggle/log_hrefs, + /decl/config/toggle/log_runtime, + /decl/config/toggle/log_world_output + ) + +/decl/config/toggle/log_ooc + uid = "log_ooc" + desc = "log OOC channel" + +/decl/config/toggle/log_access + uid = "log_access" + desc = "log client access (logon/logoff)" + +/decl/config/toggle/log_say + uid = "log_say" + desc = "log client Say" + +/decl/config/toggle/log_admin + uid = "log_admin" + desc = "log admin actions" + +/decl/config/toggle/log_debug + uid = "log_debug" + desc = "log debug output" + +/decl/config/toggle/log_game + uid = "log_game" + desc = "log game actions (start of round, results, etc.)" + +/decl/config/toggle/log_vote + uid = "log_vote" + desc = "log player votes" + +/decl/config/toggle/log_whisper + uid = "log_whisper" + desc = "log client Whisper" + +/decl/config/toggle/log_emotes + uid = "log_emote" + desc = "log emotes" + +/decl/config/toggle/log_attack + uid = "log_attack" + desc = "log attack messages" + +/decl/config/toggle/log_adminchat + uid = "log_adminchat" + desc = "log admin chat" + +/decl/config/toggle/log_adminwarn + uid = "log_adminwarn" + desc = "Log admin warning messages. Also duplicates a bunch of other messages." + +/decl/config/toggle/log_pda + uid = "log_pda" + desc = "Log PDA messages." + +/decl/config/toggle/log_hrefs + uid = "log_hrefs" + desc = "Log all Topic() calls (for use by coders in tracking down Topic issues)." + +/decl/config/toggle/log_runtime + uid = "log_runtime" + desc = "Log world.log and runtime errors to a file." + +/decl/config/toggle/log_world_output + uid = "log_world_output" + desc = "Log world.log messages." diff --git a/code/datums/config/config_types/config_mode.dm b/code/datums/config/config_types/config_mode.dm new file mode 100644 index 00000000000..7db16b2ca34 --- /dev/null +++ b/code/datums/config/config_types/config_mode.dm @@ -0,0 +1,130 @@ +/decl/configuration_category/modes + name = "Modes" + desc = "Configuration options relating to game modes." + associated_configuration = list( + /decl/config/lists/mode_names, + /decl/config/lists/mode_allowed, + /decl/config/lists/mode_votable, + /decl/config/lists/mode_probabilities, + /decl/config/toggle/feature_object_spell_system, + /decl/config/toggle/traitor_scaling, + /decl/config/toggle/protect_roles_from_antagonist, + /decl/config/toggle/continuous_rounds, + /decl/config/toggle/allow_extra_antags + ) + +/decl/config/lists/mode_names + uid = "mode_names" + desc = "Mode names." + default_value = list() + +/decl/config/lists/mode_names/Initialize() + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + default_value[game_mode.uid] = game_mode.name + return ..() + +/decl/config/lists/mode_allowed + uid = "modes" + desc = "Allowed modes." + default_value = list() + +/decl/config/lists/mode_allowed/Initialize() + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + if(game_mode.available_by_default) + default_value += game_mode.uid + default_value = sortTim(default_value, /proc/cmp_text_asc) + return ..() + +/decl/config/lists/mode_votable + uid = "votable_modes" + desc = "A list of modes that should be votable." + default_value = list() + +/decl/config/lists/mode_votable/Initialize() + default_value = list("secret") + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + if(game_mode.votable) + default_value += game_mode.uid + default_value = sortTim(default_value, /proc/cmp_text_asc) + return ..() + +/decl/config/lists/mode_votable/set_value(new_value) + . = ..() + LAZYDISTINCTADD(value, "secret") + value = sortTim(value, /proc/cmp_text_asc) + +/decl/config/lists/mode_probabilities + uid = "probabilities" + desc = "Relative probability of each mode." + default_value = list() + +/decl/config/lists/mode_probabilities/Initialize() + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + default_value[game_mode.uid] = initial(game_mode.probability) + return ..() + +/decl/config/lists/mode_probabilities/update_post_value_set() + . = ..() + var/list/all_modes = decls_repository.get_decls_of_subtype(/decl/game_mode) + for(var/mode_type in all_modes) + var/decl/game_mode/game_mode = all_modes[mode_type] + game_mode.probability = max(0, value[game_mode.uid]) + +/decl/config/toggle/feature_object_spell_system + uid = "feature_object_spell_system" + desc = "Spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard." + +/decl/config/toggle/traitor_scaling + uid = "traitor_scaling" + desc = "If amount of traitors scales or not." + +/decl/config/toggle/protect_roles_from_antagonist + uid = "protect_roles_from_antagonist" + desc = "If security is prohibited from being most antagonists." + +/decl/config/toggle/continuous_rounds + uid = "continuous_rounds" + desc = list( + "Remove the # to make rounds which end instantly (Rev, Wizard, Malf) to continue until the shuttle is called or the station is nuked.", + "Malf and Rev will let the shuttle be called when the antags/protags are dead." + ) + +/decl/config/toggle/antag_hud_allowed + uid = "antag_hud_allowed" + desc = "Allow ghosts to see antagonist through AntagHUD." + +/decl/config/toggle/antag_hud_allowed/update_post_value_set() + . = ..() + if(value) + for(var/mob/observer/ghost/g in get_ghosts()) + if(!g.client.holder) // Add the verb back for all non-admin ghosts + g.verbs += /mob/observer/ghost/verb/toggle_antagHUD + to_chat(g, SPAN_NOTICE("AntagHUD has been enabled!"))// Notify all observers they can now use AntagHUD + else + for(var/mob/observer/ghost/g in get_ghosts()) + if(!g.client.holder) //Remove the verb from non-admin ghosts + g.verbs -= /mob/observer/ghost/verb/toggle_antagHUD + if(g.antagHUD) + g.antagHUD = 0 // Disable it on those that have it enabled + g.has_enabled_antagHUD = 2 // We'll allow them to respawn + to_chat(g, SPAN_DANGER("AntagHUD has been disabled.")) + +/decl/config/toggle/antag_hud_restricted + uid = "antag_hud_restricted" + desc = "If ghosts use antagHUD they are no longer allowed to join the round." + +/decl/config/toggle/secret_hide_possibilities + uid = "secret_hide_possibilities" + desc = "If possible round types will be hidden from players for secret rounds." + +/decl/config/toggle/allow_extra_antags + uid = "allow_extra_antags" + desc = "If uncommented, votes can be called to add extra antags to the round." diff --git a/code/datums/config/config_types/config_protected.dm b/code/datums/config/config_types/config_protected.dm new file mode 100644 index 00000000000..40cfa3bdd0f --- /dev/null +++ b/code/datums/config/config_types/config_protected.dm @@ -0,0 +1,23 @@ +/decl/configuration_category/protected + name = "Protected" + desc = "Configuration options protected from manipulation on-server." + associated_configuration = list( + /decl/config/text/comms_password, + /decl/config/text/ban_comms_password, + /decl/config/text/login_export_addr + ) + +/decl/config/text/comms_password + uid = "comms_password" + protected = TRUE + desc = "Password used for authorizing ircbot and other external tools." + +/decl/config/text/ban_comms_password + uid = "ban_comms_password" + protected = TRUE + desc = "Password used for authorizing external tools that can apply bans." + +/decl/config/text/login_export_addr + uid = "login_export_addr" + protected = TRUE + desc = "Export address where external tools that monitor logins are located." diff --git a/code/datums/config/config_types/config_resources.dm b/code/datums/config/config_types/config_resources.dm new file mode 100644 index 00000000000..b1bfda325f3 --- /dev/null +++ b/code/datums/config/config_types/config_resources.dm @@ -0,0 +1,29 @@ +/decl/configuration_category/resources + name = "Resources" + desc = "Configuration options relating to server resources." + associated_configuration = list( + /decl/config/text/custom_item_icon_location, + /decl/config/text/custom_icon_icon_location, + /decl/config/lists/resource_urls + ) + +/decl/config/text/custom_item_icon_location + uid = "custom_item_icon_location" + default_value = "config/custom_items/icons" + desc = "Set this to a file path relative to the executing binary to prefix all custom item icon locations with this location ie. '\[CUSTOM_ITEM_ICON_LOCATION\]/\[custom item icon path value\]'" + +/decl/config/text/custom_icon_icon_location + uid = "custom_icon_icon_location" + default_value = "config/custom_icons/icons" + desc = "Uncomment this and set it to a file path relative to the executing binary to prefix all custom icon locations with this location ie. '\[CUSTOM_ICON_ICON_LOCATION\]/\[custom icon path value\]'" + +/decl/config/lists/resource_urls + uid = "resource_urls" + desc = list( + "Direct clients to preload the server resource file from a URL pointing to a .rsc file. NOTE: At this time (byond 512),", + "the client/resource_rsc var does not function as one would expect. See client_defines.dm, the 'preload_rsc' var's", + "comments on how to use it properly. If you use a resource URL, you must set preload_rsc to 0 at compile time or", + "clients will still download from the server *too*. This will randomly select one URL if more than one is provided.", + "Spaces are prohibited in each URL by spec, you must use encoded spaces.", + "ex. RESOURCE_URLS URL URL2 URL3" + ) diff --git a/code/datums/config/config_types/config_server.dm b/code/datums/config/config_types/config_server.dm new file mode 100644 index 00000000000..958fbf06070 --- /dev/null +++ b/code/datums/config/config_types/config_server.dm @@ -0,0 +1,365 @@ +/decl/configuration_category/server + name = "Server" + desc = "Configuration options relating to the server itself." + associated_configuration = list( + /decl/config/num/kick_inactive, + /decl/config/num/fps, + /decl/config/num/tick_limit_mc_init, + /decl/config/num/minimum_byond_version, + /decl/config/num/minimum_byond_build, + /decl/config/num/player_limit, + /decl/config/num/respawn_delay, + /decl/config/num/cult_ghostwriter_req_cultists, + /decl/config/num/character_slots, + /decl/config/num/loadout_slots, + /decl/config/num/max_maint_drones, + /decl/config/num/drone_build_time, + /decl/config/num/max_character_aspects, + /decl/config/text/irc_bot_host, + /decl/config/text/main_irc, + /decl/config/text/admin_irc, + /decl/config/text/server_name, + /decl/config/text/server, + /decl/config/text/serverurl, + /decl/config/text/banappeals, + /decl/config/text/wikiurl, + /decl/config/text/forumurl, + /decl/config/text/discordurl, + /decl/config/text/githuburl, + /decl/config/text/issuereporturl, + /decl/config/text/hosted_by, + /decl/config/toggle/panic_bunker, + /decl/config/text/panic_bunker_message, + /decl/config/toggle/do_not_prevent_spam, + /decl/config/toggle/no_throttle_localhost, + /decl/config/toggle/on/abandon_allowed, + /decl/config/toggle/on/ooc_allowed, + /decl/config/toggle/on/looc_allowed, + /decl/config/toggle/on/dooc_allowed, + /decl/config/toggle/on/dsay_allowed, + /decl/config/toggle/on/aooc_allowed, + /decl/config/toggle/on/enter_allowed, + /decl/config/toggle/on/allow_ai, + /decl/config/toggle/on/allow_drone_spawn, + /decl/config/toggle/hub_visibility, + /decl/config/toggle/usewhitelist, + /decl/config/toggle/load_jobs_from_txt, + /decl/config/toggle/disable_player_mice, + /decl/config/toggle/uneducated_mice, + /decl/config/toggle/use_alien_whitelist, + /decl/config/toggle/use_alien_whitelist_sql, + /decl/config/toggle/forbid_singulo_possession, + /decl/config/toggle/use_loyalty_implants, + /decl/config/toggle/no_click_cooldown, + /decl/config/toggle/disable_webhook_embeds, + /decl/config/toggle/delist_when_no_admins, + /decl/config/toggle/wait_for_sigusr1_reboot, + /decl/config/toggle/use_irc_bot, + /decl/config/toggle/show_typing_indicator_for_whispers, + /decl/config/toggle/announce_shuttle_dock_to_irc, + /decl/config/toggle/guests_allowed, + /decl/config/toggle/on/jobs_have_minimal_access, + /decl/config/toggle/on/admin_legacy_system, + /decl/config/toggle/on/ban_legacy_system + ) + +/decl/config/num/kick_inactive + uid = "kick_inactive" + desc = "Disconnect players who did nothing during the set amount of minutes." + +/decl/config/num/fps + uid = "fps" + default_value = 20 + desc = list( + "Defines world FPS. Defaults to 20.", + "Can also accept ticklag values (0.9, 0.5, etc) which will automatically be converted to FPS." + ) + +/decl/config/num/fps/sanitize_value() + ..() + if(value <= 0) + value = default_value + +/decl/config/num/fps/set_value(new_value) + // Handle ticklag-formatted FPS (0.7 etc) + if(new_value > 0 && new_value < 1) + new_value = round(10 / new_value) + return ..(new_value) + +/decl/config/num/fps/update_post_value_set() + world.fps = value + . = ..() + +/decl/config/num/tick_limit_mc_init + uid = "tick_limit_mc_init" + desc = "SSinitialization throttling." + default_value = TICK_LIMIT_MC_INIT_DEFAULT + +/decl/config/num/minimum_byond_version + uid = "minimum_byond_version" + default_value = 0 + desc = "Clients will be unable to connect unless their version is equal to or higher than this (a number, e.g. 511)." + +/decl/config/num/minimum_byond_build + uid = "minimum_byond_build" + default_value = 0 + desc = "Clients will be unable to connect unless their build is equal to or higher than this (a number, e.g. 1000)." + +/decl/config/num/player_limit + uid = "player_limit" + desc = "The maximum number of non-admin players online." + default_value = 0 + +/decl/config/num/use_age_restriction_for_jobs + uid = "use_age_restriction_for_jobs" + default_value = 0 + desc = list( + "Unhash this entry to have certain jobs require your account to be at least a certain number of days old to select. You can configure the exact age requirement for different jobs by editing", + "the minimal_player_age variable in the files in folder /code/game/jobs/job/.. for the job you want to edit. Set minimal_player_age to 0 to disable age requirement for that job.", + "REQUIRES the database set up to work. Keep it hashed if you don't have a database set up.", + "NOTE: If you have just set-up the database keep this DISABLED, as player age is determined from the first time they connect to the server with the database up. If you just set it up, it means", + "you have noone older than 0 days, since noone has been logged yet. Only turn this on once you have had the database up for 30 days." + ) + +/decl/config/num/use_age_restriction_for_antags + uid = "use_age_restriction_for_antags" + desc = list( + "Unhash this entry to have certain antag roles require your account to be at least a certain number of days old for round start and auto-spawn selection.", + "Non-automatic antagonist recruitment, such as being converted to cultism is not affected. Has the same database requirements and notes as USE_AGE_RESTRICTION_FOR_JOBS." + ) + +/decl/config/num/respawn_delay + uid = "respawn_delay" + default_value = 30 + min_value = 0 + desc = "Respawn delay in minutes before one may respawn as a crew member." + +/decl/config/num/cult_ghostwriter_req_cultists + uid = "cult_ghostwriter_req_cultists" + default_value = 10 + desc = "Sets the minimum number of cultists needed for ghosts to write in blood." + +/decl/config/num/character_slots + uid = "character_slots" + default_value = 10 + desc = "Sets the number of available character slots." + +/decl/config/num/loadout_slots + uid = "loadout_slots" + default_value = 3 + desc = "Sets the number of loadout slots per character." + +/decl/config/num/max_maint_drones + uid = "max_maint_drones" + desc = "This many drones can be active at the same time." + default_value = 5 + +/decl/config/num/drone_build_time + uid = "drone_build_time" + desc = "A drone will become available every X ticks since last drone spawn. Default is 2 minutes." + default_value = 1200 + +/decl/config/num/max_character_aspects + uid = "max_character_aspects" + default_value = 5 + desc = "Remove the # to define a different cap for aspect points in chargen." + +/decl/config/text/irc_bot_host + uid = "irc_bot_host" + default_value = "localhost" + desc = "Host where the IRC bot is hosted. Port 45678 needs to be open." + +/decl/config/text/main_irc + uid = "main_irc" + default_value = "#main" + desc = "IRC channel to send information to. Leave blank to disable." + +/decl/config/text/admin_irc + uid = "admin_irc" + desc = "IRC channel to send adminhelps to. Leave blank to disable adminhelps-to-irc." + +// server name (for world name / status) +/decl/config/text/server_name + uid = "server_name" + desc = "Server name: This appears at the top of the screen in-game." + default_value = "Nebula 13" + +/decl/config/text/server + uid = "server" + desc = "Set a server location for world reboot. Don't include the byond://, just give the address and port." + +/decl/config/text/serverurl + uid = "serverurl" + desc = list( + "Set a server URL for the IRC bot to use; like SERVER, don't include the byond://", + "Unlike SERVER, this one shouldn't break auto-reconnect." + ) + +/decl/config/text/banappeals + uid = "banappeals" + desc = "Ban appeals URL - usually for a forum or wherever people should go to contact your admins." + +/decl/config/text/wikiurl + uid = "wikiurl" + desc = "Wiki address." + +/decl/config/text/forumurl + uid = "forumurl" + desc = "Discussion forum address." + +/decl/config/text/discordurl + uid = "discordurl" + desc = "Discord server permanent invite address." + +/decl/config/text/githuburl + uid = "githuburl" + desc = "GitHub address." + +/decl/config/text/issuereporturl + uid = "issuereporturl" + desc = "GitHub new issue address." + +/decl/config/text/hosted_by + uid = "hostedby" + desc = "Set a hosted by name for UNIX platforms." + +/decl/config/toggle/panic_bunker + uid = "panic_bunker" + desc = "Is the panic bunker currently on by default?" + +/decl/config/text/panic_bunker_message + uid = "panic_bunker_message" + default_value = "Sorry! The panic bunker is enabled. Please head to our Discord or forum to get yourself added to the panic bunker bypass." + desc = "A message when user did not pass the panic bunker." + +/decl/config/toggle/do_not_prevent_spam + uid = "do_not_prevent_spam" + desc = "Uncomment this to DISABLE action spam kicking. Not recommended; this helps protect from spam attacks." + +/decl/config/toggle/no_throttle_localhost + uid = "no_throttle_localhost" + desc = list( + "Whether or not to make localhost immune to throttling.", + "Localhost will still be throttled internally; it just won't be affected by it." + ) + +/decl/config/toggle/on/abandon_allowed + uid = "abandon_allowed" + desc = "Comment to disable respawning by default." + +/decl/config/toggle/on/ooc_allowed + uid = "ooc_allowed" + desc = "Comment to disable the OOC channel by default." + +/decl/config/toggle/on/looc_allowed + uid = "looc_allowed" + desc = "Comment to disable the LOOC channel by default." + +/decl/config/toggle/on/dooc_allowed + uid = "dooc_allowed" + desc = "Comment to disable the dead OOC channel by default." + +/decl/config/toggle/on/dsay_allowed + uid = "dsay_allowed" + desc = "Comment to disable ghost chat by default." + +/decl/config/toggle/on/aooc_allowed + uid = "aooc_allowed" + desc = "Comment to disable the AOOC channel by default." + +/decl/config/toggle/on/enter_allowed + uid = "enter_allowed" + desc = "Comment to prevent anyone from joining the round by default." + +/decl/config/toggle/on/allow_ai + uid = "allow_ai" + desc = "Allow AI job." + +/decl/config/toggle/on/allow_drone_spawn + uid = "allow_drone_spawn" + desc = "Allow ghosts to join as maintenance drones." + +/decl/config/toggle/hub_visibility + uid = "hub_visibility" + desc = "Hub visibility: If you want to be visible on the hub, uncomment the below line and be sure that Dream Daemon is set to visible. This can be changed in-round as well with toggle-hub-visibility if Dream Daemon is set correctly." + +/decl/config/toggle/hub_visibility/update_post_value_set() + . = ..() + world.update_hub_visibility() + +/decl/config/toggle/usewhitelist + uid = "usewhitelist" + desc = list( + "Set to jobban everyone who's key is not listed in data/whitelist.txt from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions.", + "Uncomment to 1 to jobban, leave commented out to allow these positions for everyone (but see GUEST_JOBBAN above and regular jobbans)." + ) + +/decl/config/toggle/load_jobs_from_txt + uid = "load_jobs_from_txt" + desc = "Toggle for having jobs load up from the .txt" + +/decl/config/toggle/disable_player_mice + uid = "disable_player_mice" + +/decl/config/toggle/uneducated_mice + uid = "uneducated_mice" + desc = "Set to 1 to prevent newly-spawned mice from understanding human speech." + +/decl/config/toggle/use_alien_whitelist + uid = "usealienwhitelist" + desc = "Uncomment to restrict non-admins from using humanoid alien races." + +/decl/config/toggle/use_alien_whitelist_sql + uid = "usealienwhitelist_sql" + desc = "Uncomment to use the alien whitelist system with SQL instead. (requires the above uncommented as well)." + +/decl/config/toggle/forbid_singulo_possession + uid = "forbid_singulo_possession" + desc = "Remove the # mark infront of this to forbid admins from posssessing the singularity." + +/decl/config/toggle/use_loyalty_implants + uid = "use_loyalty_implants" + desc = "Remove the # in front of this config option to have loyalty implants spawn by default on your server." + +/decl/config/toggle/no_click_cooldown + uid = "no_click_cooldown" + +/decl/config/toggle/disable_webhook_embeds + uid = "disable_webhook_embeds" + desc = "Uncomment to make Discord webhooks send in plaintext rather than as embeds." + +/decl/config/toggle/delist_when_no_admins + uid = "delist_when_no_admins" + desc = "Uncomment this to remove the server from the hub." + +/decl/config/toggle/wait_for_sigusr1_reboot + uid = "wait_for_sigusr1_reboot" + desc = "Uncomment to make Dream Daemon refuse to reboot for any reason other than SIGUSR1." + +/decl/config/toggle/use_irc_bot + uid = "use_irc_bot" + desc = "Uncomment to enable sending data to the IRC bot." + +/decl/config/toggle/show_typing_indicator_for_whispers + uid = "show_typing_indicator_for_whispers" + desc = "Uncomment this to show a typing indicator for people writing whispers." + +/decl/config/toggle/announce_shuttle_dock_to_irc + uid = "announce_shuttle_dock_to_irc" + desc = "Uncomment this line to announce shuttle dock announcements to the main IRC channel, if MAIN_IRC has also been setup." + +/decl/config/toggle/guests_allowed + uid = "guests_allowed" + desc = "Uncomment this to stop people connecting to your server without a registered ckey. (i.e. guest-* are all blocked from connecting)." + +/decl/config/toggle/on/ban_legacy_system + uid = "ban_legacy_system" + desc = "Add a # infront of this if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system." + +/decl/config/toggle/on/admin_legacy_system + uid = "admin_legacy_system" + desc = "Add a # infront of this if you want to use the SQL based admin system, the legacy system uses admins.txt. You need to set up your database to use the SQL based system." + +/decl/config/toggle/on/jobs_have_minimal_access + uid = "jobs_have_minimal_access" + desc = "Add a # here if you wish to use the setup where jobs have more access. This is intended for servers with low populations - where there are not enough players to fill all roles, so players need to do more than just one job. Also for servers where they don't want people to hide in their own departments." diff --git a/code/datums/config/config_types/config_voting.dm b/code/datums/config/config_types/config_voting.dm new file mode 100644 index 00000000000..32f59f4cee2 --- /dev/null +++ b/code/datums/config/config_types/config_voting.dm @@ -0,0 +1,79 @@ +/decl/configuration_category/voting + name = "Voting" + desc = "Configuration options relating to votes at runtime." + associated_configuration = list( + /decl/config/num/vote_delay, + /decl/config/num/vote_period, + /decl/config/num/vote_autotransfer_initial, + /decl/config/num/vote_autotransfer_interval, + /decl/config/num/vote_autogamemode_timeleft, + /decl/config/num/vote_no_default, + /decl/config/num/vote_no_dead, + /decl/config/num/vote_no_dead_crew_transfer, + /decl/config/toggle/vote_restart, + /decl/config/toggle/vote_mode, + /decl/config/toggle/allow_map_switching, + /decl/config/toggle/auto_map_vote + ) + +/decl/config/num/vote_delay + uid = "vote_delay" + default_value = 6000 + desc = "Min delay (deciseconds) between voting sessions (default 10 minutes)." + +/decl/config/num/vote_period + uid = "vote_period" + default_value = 600 + desc = "Time period (deciseconds) which voting session will last (default 1 minute)." + +/decl/config/num/vote_autotransfer_initial + uid = "vote_autotransfer_initial" + default_value = 108000 + desc = "Autovote initial delay (deciseconds) before first automatic transfer vote call (default 180 minutes)." + +/decl/config/num/vote_autotransfer_interval + uid = "vote_autotransfer_interval" + default_value = 18000 + desc = "Autovote delay (deciseconds) before sequential automatic transfer votes are called (default 30 minutes)." + +/decl/config/num/vote_autogamemode_timeleft + uid = "vote_autogamemode_timeleft" + default_value = 100 + desc = "Time left (seconds) before round start when automatic gamemote vote is called (default 160)." + +/decl/config/num/vote_no_default + uid = "vote_no_default" + default_value = FALSE + config_flags = CONFIG_FLAG_BOOL | CONFIG_FLAG_HAS_VALUE + desc = "Players' votes default to 'No vote' (otherwise, default to 'No change')." + +/decl/config/num/vote_no_dead + uid = "vote_no_dead" + default_value = FALSE + config_flags = CONFIG_FLAG_BOOL | CONFIG_FLAG_HAS_VALUE + desc = "Prevents dead players from voting or starting votes." + +/decl/config/num/vote_no_dead_crew_transfer + uid = "vote_no_dead_crew_transfer" + default_value = FALSE + config_flags = CONFIG_FLAG_BOOL | CONFIG_FLAG_HAS_VALUE + desc = "Prevents players not in-round from voting on crew transfer votes." + +/decl/config/toggle/vote_restart + uid = "allow_vote_restart" + desc = "Allow players to initiate a restart vote." + +/decl/config/toggle/vote_mode + uid = "allow_vote_mode" + desc = "Allow players to initate a mode-change start." + +/decl/config/toggle/allow_map_switching + uid = "allow_map_switching" + desc = list( + "Uncomment to enable map voting; you'll need to use the script at tools/server.sh or an equivalent for it to take effect.", + "You'll also likely need to enable WAIT_FOR_SIGUSR1 below." + ) + +/decl/config/toggle/auto_map_vote + uid = "auto_map_vote" + desc = "Uncomment to enable an automatic map vote and switch at end of round. MAP_SWITCHING must also be enabled." diff --git a/code/datums/datum.dm b/code/datums/datum.dm index b812b9ec481..a1114baa8b9 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -7,6 +7,8 @@ var/tmp/is_processing = FALSE /// Used by the SStimer subsystem var/list/active_timers + /// Used to avoid unnecessary refstring creation in Destroy(). + var/tmp/has_state_machine = FALSE #ifdef TESTING var/tmp/running_find_references @@ -49,11 +51,12 @@ if (!isturf(src)) // Not great, but the 'correct' way to do it would add overhead for little benefit. cleanup_events(src) - var/list/machines = global.state_machines["\ref[src]"] - if(length(machines)) - for(var/base_type in machines) - qdel(machines[base_type]) - global.state_machines -= "\ref[src]" + if(has_state_machine) + var/list/machines = global.state_machines["\ref[src]"] + if(length(machines)) + for(var/base_type in machines) + qdel(machines[base_type]) + global.state_machines -= "\ref[src]" return QDEL_HINT_QUEUE diff --git a/code/datums/extensions/deity_be_near.dm b/code/datums/extensions/deity_be_near.dm index fa8f07b6a46..06d3616710d 100644 --- a/code/datums/extensions/deity_be_near.dm +++ b/code/datums/extensions/deity_be_near.dm @@ -9,9 +9,9 @@ /datum/extension/deity_be_near/New(var/datum/holder, var/mob/living/deity/connect) ..() - events_repository.register(/decl/observ/moved, holder,src, .proc/check_movement) + events_repository.register(/decl/observ/moved, holder,src, PROC_REF(check_movement)) connected_deity = connect - events_repository.register(/decl/observ/destroyed, holder, src, .proc/dead_deity) + events_repository.register(/decl/observ/destroyed, holder, src, PROC_REF(dead_deity)) var/obj/O = holder O.desc += "
    This item deals damage to its wielder the [keep_away_instead ? "closer" : "farther"] it is from a deity structure" diff --git a/code/datums/extensions/event_registration.dm b/code/datums/extensions/event_registration.dm index 4daa92636e3..b483bd79a25 100644 --- a/code/datums/extensions/event_registration.dm +++ b/code/datums/extensions/event_registration.dm @@ -10,8 +10,8 @@ /datum/extension/event_registration/New(datum/holder, decl/observ/event, datum/target, callproc) ..() - event.register(target, src, .proc/trigger) - events_repository.register(/decl/observ/destroyed, target, src, .proc/qdel_self) + event.register(target, src, PROC_REF(trigger)) + events_repository.register(/decl/observ/destroyed, target, src, PROC_REF(qdel_self)) src.event = event src.target = target src.callproc = callproc @@ -36,15 +36,15 @@ ..() src.given_area = given_area register_shuttles() - events_repository.register_global(/decl/observ/shuttle_added, src, .proc/shuttle_added) + events_repository.register_global(/decl/observ/shuttle_added, src, PROC_REF(shuttle_added)) /datum/extension/event_registration/shuttle_stationary/proc/register_shuttles() if(given_area in SSshuttle.shuttle_areas) for(var/shuttle_name in SSshuttle.shuttles) var/datum/shuttle/shuttle_datum = SSshuttle.shuttles[shuttle_name] if(given_area in shuttle_datum.shuttle_area) - events_repository.register(/decl/observ/shuttle_moved, shuttle_datum, src, .proc/shuttle_moved) - events_repository.register(/decl/observ/shuttle_pre_move, shuttle_datum, src, .proc/shuttle_pre_move) + events_repository.register(/decl/observ/shuttle_moved, shuttle_datum, src, PROC_REF(shuttle_moved)) + events_repository.register(/decl/observ/shuttle_pre_move, shuttle_datum, src, PROC_REF(shuttle_pre_move)) LAZYADD(shuttles_registered, shuttle_datum) /datum/extension/event_registration/shuttle_stationary/proc/unregister_shuttles() @@ -55,8 +55,8 @@ /datum/extension/event_registration/shuttle_stationary/proc/shuttle_added(datum/shuttle/shuttle) if(given_area in shuttle.shuttle_area) - events_repository.register(/decl/observ/shuttle_moved, shuttle, src, .proc/shuttle_moved) - events_repository.register(/decl/observ/shuttle_pre_move, shuttle, src, .proc/shuttle_pre_move) + events_repository.register(/decl/observ/shuttle_moved, shuttle, src, PROC_REF(shuttle_moved)) + events_repository.register(/decl/observ/shuttle_pre_move, shuttle, src, PROC_REF(shuttle_pre_move)) LAZYADD(shuttles_registered, shuttle) /datum/extension/event_registration/shuttle_stationary/Destroy() diff --git a/code/datums/extensions/eye/_eye.dm b/code/datums/extensions/eye/_eye.dm index 59fc3d66404..1676604607b 100644 --- a/code/datums/extensions/eye/_eye.dm +++ b/code/datums/extensions/eye/_eye.dm @@ -21,7 +21,7 @@ /datum/extension/eye/proc/look(var/mob/new_looker, var/list/eye_args) if(new_looker.eyeobj || current_looker) return FALSE - + LAZYINSERT(eye_args, get_turf(new_looker), 1) // Make sure that a loc is provided to the eye. if(!extension_eye) @@ -43,29 +43,29 @@ unlook_action.Grant(current_looker) // Checks for removing the user from the eye outside of unlook actions. - events_repository.register(/decl/observ/moved, holder, src, /datum/extension/eye/proc/unlook) - events_repository.register(/decl/observ/moved, current_looker, src, /datum/extension/eye/proc/unlook) + events_repository.register(/decl/observ/moved, holder, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.register(/decl/observ/moved, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) - events_repository.register(/decl/observ/destroyed, current_looker, src, /datum/extension/eye/proc/unlook) - events_repository.register(/decl/observ/destroyed, extension_eye, src, /datum/extension/eye/proc/unlook) + events_repository.register(/decl/observ/destroyed, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.register(/decl/observ/destroyed, extension_eye, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) if(isliving(current_looker)) - events_repository.register(/decl/observ/stat_set, current_looker, src, /datum/extension/eye/proc/unlook) - events_repository.register(/decl/observ/logged_out, current_looker, src, /datum/extension/eye/proc/unlook) + events_repository.register(/decl/observ/stat_set, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.register(/decl/observ/logged_out, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) return TRUE /datum/extension/eye/proc/unlook() - events_repository.unregister(/decl/observ/moved, holder, src, /datum/extension/eye/proc/unlook) - events_repository.unregister(/decl/observ/moved, current_looker, src, /datum/extension/eye/proc/unlook) - - events_repository.unregister(/decl/observ/destroyed, current_looker, src, /datum/extension/eye/proc/unlook) - events_repository.unregister(/decl/observ/destroyed, extension_eye, src, /datum/extension/eye/proc/unlook) + events_repository.unregister(/decl/observ/moved, holder, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.unregister(/decl/observ/moved, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + + events_repository.unregister(/decl/observ/destroyed, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.unregister(/decl/observ/destroyed, extension_eye, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) if(isliving(current_looker)) - events_repository.unregister(/decl/observ/stat_set, current_looker, src, /datum/extension/eye/proc/unlook) - events_repository.unregister(/decl/observ/logged_out, current_looker, src, /datum/extension/eye/proc/unlook) + events_repository.unregister(/decl/observ/stat_set, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) + events_repository.unregister(/decl/observ/logged_out, current_looker, src, TYPE_PROC_REF(/datum/extension/eye, unlook)) QDEL_NULL(extension_eye) diff --git a/code/datums/extensions/holster/holster.dm b/code/datums/extensions/holster/holster.dm index 6cfcba37dab..1442577ec67 100644 --- a/code/datums/extensions/holster/holster.dm +++ b/code/datums/extensions/holster/holster.dm @@ -53,14 +53,14 @@ user.visible_message("\The [user] holsters \the [holstered].", "You holster \the [holstered].") atom_holder.SetName("occupied [initial(atom_holder.name)]") atom_holder.update_icon() - events_repository.register(/decl/observ/moved, holstered, src, .proc/check_holster) - events_repository.register(/decl/observ/destroyed, holstered, src, .proc/clear_holster) + events_repository.register(/decl/observ/moved, holstered, src, PROC_REF(check_holster)) + events_repository.register(/decl/observ/destroyed, holstered, src, PROC_REF(clear_holster)) return 1 return 0 /datum/extension/holster/proc/clear_holster() - events_repository.unregister(/decl/observ/moved, holstered, src, .proc/check_holster) - events_repository.unregister(/decl/observ/destroyed, holstered, src, .proc/clear_holster) + events_repository.unregister(/decl/observ/moved, holstered, src, PROC_REF(check_holster)) + events_repository.unregister(/decl/observ/destroyed, holstered, src, PROC_REF(clear_holster)) holstered = null atom_holder.SetName(initial(atom_holder.name)) diff --git a/code/datums/extensions/lockable.dm b/code/datums/extensions/lockable.dm index c929c96b60a..581838e4e0a 100644 --- a/code/datums/extensions/lockable.dm +++ b/code/datums/extensions/lockable.dm @@ -125,7 +125,7 @@ if (prob(user.skill_fail_chance(SKILL_DEVICES, 40, SKILL_EXPERT))) l_setshort = FALSE user.show_message(SPAN_NOTICE("Internal memory reset. Please give it a few seconds to reinitialize."), 1) - addtimer(CALLBACK(src, /datum/extension/lockable/proc/reset_memory), 3 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/extension/lockable, reset_memory)), 3 SECONDS) return TRUE else user.show_message(SPAN_WARNING("Unable to reset internal memory."), 1) diff --git a/code/datums/extensions/scent/_scent.dm b/code/datums/extensions/scent/_scent.dm index b7ef9d3873d..3b1a52e50ee 100644 --- a/code/datums/extensions/scent/_scent.dm +++ b/code/datums/extensions/scent/_scent.dm @@ -6,7 +6,7 @@ Scent intensity *****/ /decl/scent_intensity - var/cooldown = 5 MINUTES + var/cooldown = 5 MINUTES var/intensity = 1 /decl/scent_intensity/proc/PrintMessage(var/mob/user, var/descriptor, var/scent) @@ -121,18 +121,24 @@ To add a scent extension to an atom using a reagent's info, where R. is the reag *****/ /proc/set_scent_by_reagents(var/atom/smelly_atom) + var/decl/material/smelliest = get_smelliest_reagent(smelly_atom.reagents) + if(smelliest) + set_extension(smelly_atom, /datum/extension/scent/custom, smelliest.scent, smelliest.scent_intensity, smelliest.scent_descriptor, smelliest.scent_range) + +// Returns the smelliest reagent of a reagent holder. +/proc/get_smelliest_reagent(var/datum/reagents/holder) var/decl/material/smelliest var/decl/material/scent_intensity - if(!smelly_atom.reagents || !smelly_atom.reagents.total_volume) + if(!holder || !holder.total_volume) return - for(var/reagent_type in smelly_atom.reagents.reagent_volumes) + for(var/reagent_type in holder.reagent_volumes) var/decl/material/R = GET_DECL(reagent_type) if(!R.scent) continue var/decl/scent_intensity/SI = GET_DECL(R.scent_intensity) - var/r_scent_intensity = REAGENT_VOLUME(smelly_atom.reagents, reagent_type) * SI.intensity + var/r_scent_intensity = REAGENT_VOLUME(holder, reagent_type) * SI.intensity if(r_scent_intensity > scent_intensity) smelliest = R - scent_intensity = r_scent_intensity - if(smelliest) - set_extension(smelly_atom, /datum/extension/scent/custom, smelliest.scent, smelliest.scent_intensity, smelliest.scent_descriptor, smelliest.scent_range) \ No newline at end of file + scent_intensity = r_scent_intensity + + return smelliest \ No newline at end of file diff --git a/code/datums/extensions/state_machine.dm b/code/datums/extensions/state_machine.dm index 914f633541e..32b8d6cd948 100644 --- a/code/datums/extensions/state_machine.dm +++ b/code/datums/extensions/state_machine.dm @@ -2,7 +2,7 @@ var/global/list/state_machines = list() /proc/get_state_machine(var/datum/holder, var/base_type) - if(istype(holder) && base_type) + if(istype(holder) && base_type && holder.has_state_machine) var/list/machines = global.state_machines["\ref[holder]"] return islist(machines) && machines[base_type] @@ -18,16 +18,18 @@ var/global/list/state_machines = list() fsm_type = base_type var/datum/state_machine/machine = new fsm_type(holder) machines[base_type] = machine + holder.has_state_machine = TRUE return machine /proc/remove_state_machine(var/datum/holder, var/base_type) - if(istype(holder) && base_type) + if(istype(holder) && base_type && holder.has_state_machine) var/holder_ref = "\ref[holder]" var/list/machines = global.state_machines[holder_ref] if(length(machines)) machines -= base_type if(!length(machines)) global.state_machines -= holder_ref + holder.has_state_machine = FALSE return TRUE return FALSE diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 5c7561285b1..37e7fb12bea 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -36,8 +36,8 @@ var/global/datum/getrev/revdata = new() to_chat(src, "Client Version: [byond_version]") if(revdata.revision) var/server_revision = revdata.revision - if(config.githuburl) - server_revision = "[server_revision]" + if(get_config_value(/decl/config/text/githuburl)) + server_revision = "[server_revision]" to_chat(src, "Server Revision: [server_revision] - [revdata.branch] - [revdata.date]") else to_chat(src, "Server Revision: Revision Unknown") diff --git a/code/datums/inventory_slots/inventory_gripper.dm b/code/datums/inventory_slots/inventory_gripper.dm index 66d0c12a9ac..df08bcdb02a 100644 --- a/code/datums/inventory_slots/inventory_gripper.dm +++ b/code/datums/inventory_slots/inventory_gripper.dm @@ -3,6 +3,8 @@ var/can_use_held_item = TRUE var/dexterity = DEXTERITY_FULL var/covering_slot_flags + /// If set, use this icon_state for the hand slot overlay; otherwise, use slot_id. + var/hand_overlay quick_equip_priority = -1 // you quick-equip stuff by holding it in a gripper, so this ought to be dead last // For reference, grippers do not use ui_loc, they have it set dynamically during /datum/hud/proc/rebuild_hands() diff --git a/code/datums/move_intent/move_intent.dm b/code/datums/move_intent/move_intent.dm index c9641068e71..87e521f5e33 100644 --- a/code/datums/move_intent/move_intent.dm +++ b/code/datums/move_intent/move_intent.dm @@ -21,7 +21,7 @@ /decl/move_intent/creep/Initialize() . = ..() - move_delay = config.creep_delay + move_delay = get_config_value(/decl/config/num/movement_creep) /decl/move_intent/walk name = "Walk" @@ -29,7 +29,7 @@ /decl/move_intent/walk/Initialize() . = ..() - move_delay = config.walk_delay + move_delay = get_config_value(/decl/config/num/movement_walk) /decl/move_intent/run name = "Run" @@ -38,4 +38,4 @@ /decl/move_intent/run/Initialize() . = ..() - move_delay = config.run_delay + move_delay = get_config_value(/decl/config/num/movement_run) diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm index b66388cab6a..6450f821a63 100644 --- a/code/datums/movement/mob.dm +++ b/code/datums/movement/mob.dm @@ -217,7 +217,7 @@ else mod *= 0.8 - return config.minimum_sprint_cost + (config.skill_sprint_cost_range * mod) + return get_config_value(/decl/config/num/movement_min_sprint_cost) + get_config_value(/decl/config/num/movement_skill_sprint_cost_range) * mod // Misc. helpers /mob/proc/MayEnterTurf(var/turf/T) diff --git a/code/datums/observation/dir_set.dm b/code/datums/observation/dir_set.dm index 03e221a365c..edec53d036d 100644 --- a/code/datums/observation/dir_set.dm +++ b/code/datums/observation/dir_set.dm @@ -18,7 +18,7 @@ // Listen to the parent if possible. if(. && istype(dir_changer.loc, /atom/movable)) // We don't care about registering to turfs. - register(dir_changer.loc, dir_changer, /atom/proc/recursive_dir_set) + register(dir_changer.loc, dir_changer, TYPE_PROC_REF(/atom, recursive_dir_set)) /********************* * Direction Handling * @@ -28,8 +28,8 @@ . = ..() var/decl/observ/dir_set/dir_set_event = GET_DECL(/decl/observ/dir_set) if(dir_set_event.has_listeners(am)) - events_repository.register(/decl/observ/dir_set, src, am, /atom/proc/recursive_dir_set) + events_repository.register(/decl/observ/dir_set, src, am, TYPE_PROC_REF(/atom, recursive_dir_set)) /atom/movable/Exited(var/atom/movable/am, atom/new_loc) . = ..() - events_repository.unregister(/decl/observ/dir_set, src, am, /atom/proc/recursive_dir_set) + events_repository.unregister(/decl/observ/dir_set, src, am, TYPE_PROC_REF(/atom, recursive_dir_set)) diff --git a/code/datums/observation/helpers.dm b/code/datums/observation/helpers.dm index b0a04383972..89330ecc50b 100644 --- a/code/datums/observation/helpers.dm +++ b/code/datums/observation/helpers.dm @@ -24,9 +24,9 @@ qdel(src) /proc/register_all_movement(var/event_source, var/listener) - events_repository.register(/decl/observ/moved, event_source, listener, /atom/movable/proc/recursive_move) - events_repository.register(/decl/observ/dir_set, event_source, listener, /atom/proc/recursive_dir_set) + events_repository.register(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) + events_repository.register(/decl/observ/dir_set, event_source, listener, TYPE_PROC_REF(/atom, recursive_dir_set)) /proc/unregister_all_movement(var/event_source, var/listener) - events_repository.unregister(/decl/observ/moved, event_source, listener, /atom/movable/proc/recursive_move) - events_repository.unregister(/decl/observ/dir_set, event_source, listener, /atom/proc/recursive_dir_set) + events_repository.unregister(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) + events_repository.unregister(/decl/observ/dir_set, event_source, listener, TYPE_PROC_REF(/atom, recursive_dir_set)) diff --git a/code/datums/observation/moved.dm b/code/datums/observation/moved.dm index b61aefffd4a..19557c43c5e 100644 --- a/code/datums/observation/moved.dm +++ b/code/datums/observation/moved.dm @@ -18,7 +18,7 @@ // Listen to the parent if possible. if(. && istype(mover.loc, expected_type)) - register(mover.loc, mover, /atom/movable/proc/recursive_move) + register(mover.loc, mover, TYPE_PROC_REF(/atom/movable, recursive_move)) /******************** * Movement Handling * @@ -32,8 +32,8 @@ . = ..() var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) if(moved_event.has_listeners(am)) - events_repository.register(/decl/observ/moved, src, am, /atom/movable/proc/recursive_move) + events_repository.register(/decl/observ/moved, src, am, TYPE_PROC_REF(/atom/movable, recursive_move)) /atom/movable/Exited(var/atom/movable/am, atom/new_loc) . = ..() - events_repository.unregister(/decl/observ/moved, src, am, /atom/movable/proc/recursive_move) + events_repository.unregister(/decl/observ/moved, src, am, TYPE_PROC_REF(/atom/movable, recursive_move)) diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 447a0aaa107..9685f39741a 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -1,31 +1,30 @@ var/global/list/global_listen_count = list() -var/global/list/event_sources_count = list() -var/global/list/event_listen_count = list() -/proc/cleanup_events(var/source) +/datum + /// Tracks how many event registrations are listening to us. Used in cleanup to prevent dangling references. + var/event_source_count = 0 + /// Tracks how many event registrations we are listening to. Used in cleanup to prevent dangling references. + var/event_listen_count = 0 + +/proc/cleanup_events(var/datum/source) if(global.global_listen_count && global.global_listen_count[source]) cleanup_global_listener(source, global.global_listen_count[source]) - if(global.event_sources_count && global.event_sources_count[source]) - cleanup_source_listeners(source, global.event_sources_count[source]) - if(global.event_listen_count && global.event_listen_count[source]) - cleanup_event_listener(source, global.event_listen_count[source]) + if(source?.event_source_count > 0) + cleanup_source_listeners(source, source?.event_source_count) + if(source?.event_listen_count > 0) + cleanup_event_listener(source, source?.event_listen_count) /decl/observ/register(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() if(.) - global.event_sources_count[event_source] += 1 - global.event_listen_count[listener] += 1 + event_source.event_source_count++ + listener.event_listen_count++ /decl/observ/unregister(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() // returns the number of events removed if(.) - global.event_sources_count[event_source] -= . - global.event_listen_count[listener] -= . - - if(global.event_sources_count[event_source] <= 0) - global.event_sources_count -= event_source - if(global.event_listen_count[listener] <= 0) - global.event_listen_count -= listener + event_source.event_source_count -= . + listener.event_listen_count -= . /decl/observ/register_global(var/datum/listener, var/proc_call) . = ..() @@ -52,8 +51,8 @@ var/global/list/event_listen_count = list() if(listen_count > 0) CRASH("Failed to clean up all global listener entries!") -/proc/cleanup_source_listeners(event_source, source_listener_count) - global.event_sources_count -= event_source +/proc/cleanup_source_listeners(datum/event_source, source_listener_count) + event_source.event_source_count = 0 var/events_removed for(var/entry in global.all_observable_events) var/decl/observ/event = entry @@ -69,8 +68,8 @@ var/global/list/event_listen_count = list() if(source_listener_count > 0) CRASH("Failed to clean up all event source entries!") -/proc/cleanup_event_listener(listener, listener_count) - global.event_listen_count -= listener +/proc/cleanup_event_listener(datum/listener, listener_count) + listener.event_listen_count = 0 var/events_removed for(var/entry in global.all_observable_events) var/decl/observ/event = entry diff --git a/code/datums/outfits/tournament.dm b/code/datums/outfits/tournament.dm index 82c11e3a442..161bc1a277b 100644 --- a/code/datums/outfits/tournament.dm +++ b/code/datums/outfits/tournament.dm @@ -57,4 +57,4 @@ ..() var/obj/item/chems/glass/bucket/bucket = locate(/obj/item/chems/glass/bucket) in H if(bucket) - bucket.reagents.add_reagent(/decl/material/liquid/water, 70) + bucket.add_to_reagents(/decl/material/liquid/water, 70) diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index 190c09cbc53..0bbfc28b7a7 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -42,7 +42,8 @@ pixel_y = _pixel_y /datum/position/proc/return_turf() - return locate(x, y, z) + var/turf/T = locate(x, y, z) + return T?.resolve_to_actual_turf() /datum/position/proc/return_px() return pixel_x @@ -111,7 +112,8 @@ AM.pixel_y = return_py() /datum/point/proc/return_turf() - return locate(CEILING(x / world.icon_size), CEILING(y / world.icon_size), z) + var/turf/T = locate(CEILING(x / world.icon_size), CEILING(y / world.icon_size), z) + return T?.resolve_to_actual_turf() /datum/point/proc/return_coordinates() //[turf_x, turf_y, z] return list(CEILING(x / world.icon_size), CEILING(y / world.icon_size), z) diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 8976ec73557..9b3efb28d36 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -83,7 +83,7 @@ LAZYREMOVE(user.progressbars, bar.loc) animate(bar, alpha = 0, time = PROGRESSBAR_ANIMATION_TIME) - addtimer(CALLBACK(src, .proc/remove_from_client), PROGRESSBAR_ANIMATION_TIME, TIMER_CLIENT_TIME) + addtimer(CALLBACK(src, PROC_REF(remove_from_client)), PROGRESSBAR_ANIMATION_TIME, TIMER_CLIENT_TIME) QDEL_IN(bar, PROGRESSBAR_ANIMATION_TIME * 2) //for garbage collection safety . = ..() diff --git a/code/datums/proximity_trigger/proximity_trigger.dm b/code/datums/proximity_trigger/proximity_trigger.dm index 63233efef75..8a4f2b3780c 100644 --- a/code/datums/proximity_trigger/proximity_trigger.dm +++ b/code/datums/proximity_trigger/proximity_trigger.dm @@ -84,30 +84,30 @@ var/global/const/PROXIMITY_EXCLUDE_HOLDER_TURF = 1 // When acquiring turfs to mo /datum/proximity_trigger/proc/register_turfs() if(ismovable(holder)) - events_repository.register(/decl/observ/moved, holder, src, /datum/proximity_trigger/proc/on_holder_moved) - events_repository.register(/decl/observ/dir_set, holder, src, /datum/proximity_trigger/proc/register_turfs) // Changing direction might alter the relevant turfs + events_repository.register(/decl/observ/moved, holder, src, TYPE_PROC_REF(/datum/proximity_trigger, on_holder_moved)) + events_repository.register(/decl/observ/dir_set, holder, src, TYPE_PROC_REF(/datum/proximity_trigger, register_turfs)) // Changing direction might alter the relevant turfs var/list/new_turfs = acquire_relevant_turfs() if(listequal(turfs_in_range, new_turfs)) return for(var/t in (turfs_in_range - new_turfs)) - events_repository.unregister(/decl/observ/opacity_set, t, src, /datum/proximity_trigger/proc/on_turf_visibility_changed) + events_repository.unregister(/decl/observ/opacity_set, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_visibility_changed)) for(var/t in (new_turfs - turfs_in_range)) - events_repository.register(/decl/observ/opacity_set, t, src, /datum/proximity_trigger/proc/on_turf_visibility_changed) + events_repository.register(/decl/observ/opacity_set, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_visibility_changed)) turfs_in_range = new_turfs on_turf_visibility_changed() /datum/proximity_trigger/proc/unregister_turfs() if(ismovable(holder)) - events_repository.unregister(/decl/observ/moved, holder, src, /datum/proximity_trigger/proc/on_holder_moved) - events_repository.unregister(/decl/observ/dir_set, holder, src, /datum/proximity_trigger/proc/register_turfs) + events_repository.unregister(/decl/observ/moved, holder, src, TYPE_PROC_REF(/datum/proximity_trigger, on_holder_moved)) + events_repository.unregister(/decl/observ/dir_set, holder, src, TYPE_PROC_REF(/datum/proximity_trigger, register_turfs)) for(var/t in turfs_in_range) - events_repository.unregister(/decl/observ/opacity_set, t, src, /datum/proximity_trigger/proc/on_turf_visibility_changed) + events_repository.unregister(/decl/observ/opacity_set, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_visibility_changed)) for(var/t in seen_turfs_) - events_repository.unregister(/decl/observ/entered, t, src, /datum/proximity_trigger/proc/on_turf_entered) + events_repository.unregister(/decl/observ/entered, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_entered)) call(proc_owner, on_turfs_changed)(seen_turfs_.Copy(), list()) @@ -122,9 +122,9 @@ var/global/const/PROXIMITY_EXCLUDE_HOLDER_TURF = 1 // When acquiring turfs to mo call(proc_owner, on_turfs_changed)(seen_turfs_.Copy(), new_seen_turfs_.Copy()) for(var/t in (seen_turfs_ - new_seen_turfs_)) - events_repository.unregister(/decl/observ/entered, t, src, /datum/proximity_trigger/proc/on_turf_entered) + events_repository.unregister(/decl/observ/entered, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_entered)) for(var/t in (new_seen_turfs_ - seen_turfs_)) - events_repository.register(/decl/observ/entered, t, src, /datum/proximity_trigger/proc/on_turf_entered) + events_repository.register(/decl/observ/entered, t, src, TYPE_PROC_REF(/datum/proximity_trigger, on_turf_entered)) seen_turfs_ = new_seen_turfs_ @@ -141,18 +141,18 @@ var/global/const/PROXIMITY_EXCLUDE_HOLDER_TURF = 1 // When acquiring turfs to mo return // For opaque movables, we need to recheck visibility on destruction, when their opacity is changed, or when they move out of range. if(enterer.opacity) - events_repository.register(/decl/observ/opacity_set, enterer, src, /datum/proximity_trigger/proc/update_opaque_atom) - events_repository.register(/decl/observ/destroyed, enterer, src, /datum/proximity_trigger/proc/update_opaque_atom) - events_repository.register(/decl/observ/moved, enterer, src, /datum/proximity_trigger/proc/update_opaque_atom) + events_repository.register(/decl/observ/opacity_set, enterer, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) + events_repository.register(/decl/observ/destroyed, enterer, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) + events_repository.register(/decl/observ/moved, enterer, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) on_turf_visibility_changed() call(proc_owner, on_turf_entered)(enterer) /datum/proximity_trigger/proc/update_opaque_atom(var/atom/opaque_atom) var/turf/atom_loc = get_turf(opaque_atom) if(QDELETED(opaque_atom) || !opaque_atom.opacity || !atom_loc || !(atom_loc in turfs_in_range)) - events_repository.unregister(/decl/observ/opacity_set, opaque_atom, src, /datum/proximity_trigger/proc/update_opaque_atom) - events_repository.unregister(/decl/observ/destroyed, opaque_atom, src, /datum/proximity_trigger/proc/update_opaque_atom) - events_repository.unregister(/decl/observ/moved, opaque_atom, src, /datum/proximity_trigger/proc/update_opaque_atom) + events_repository.unregister(/decl/observ/opacity_set, opaque_atom, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) + events_repository.unregister(/decl/observ/destroyed, opaque_atom, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) + events_repository.unregister(/decl/observ/moved, opaque_atom, src, TYPE_PROC_REF(/datum/proximity_trigger, update_opaque_atom)) on_turf_visibility_changed() /datum/proximity_trigger/proc/get_seen_turfs() @@ -186,7 +186,7 @@ var/global/const/PROXIMITY_EXCLUDE_HOLDER_TURF = 1 // When acquiring turfs to mo /obj/item/proxy_debug/Initialize() . = ..() overlay = image('icons/misc/mark.dmi', icon_state = "x3") - var/datum/proximity_trigger/a = new proxy_type(src, /obj/item/proxy_debug/proc/turf_entered, /obj/item/proxy_debug/proc/update_turfs) + var/datum/proximity_trigger/a = new proxy_type(src, TYPE_PROC_REF(/obj/item/proxy_debug, turf_entered), TYPE_PROC_REF(/obj/item/proxy_debug, update_turfs)) a.register_turfs() /obj/item/proxy_debug/proc/turf_entered(var/atom/A) diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index 4322477d68b..09b9f50364b 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -292,6 +292,8 @@ for(var/obj/item/chems/food/food in results) food.cooked_food = TRUE + if(!QDELETED(food.plate)) + QDEL_NULL(food.plate) // crafted food should not have plates by default return results diff --git a/code/datums/repositories/atom_info.dm b/code/datums/repositories/atom_info.dm index a15c4fd3739..7037a3dd9a8 100644 --- a/code/datums/repositories/atom_info.dm +++ b/code/datums/repositories/atom_info.dm @@ -26,7 +26,7 @@ var/global/repository/atom_info/atom_info_repository = new() var/atom/instance if(!matter_cache[key]) instance = get_instance_of(path, material, amount) - matter_cache[key] = instance.get_contained_matter() + matter_cache[key] = instance.get_contained_matter() || list() if(!combined_worth_cache[key]) instance = instance || get_instance_of(path, material, amount) combined_worth_cache[key] = instance.get_combined_monetary_worth() diff --git a/code/datums/repositories/follow.dm b/code/datums/repositories/follow.dm index c4d037f70be..11393225a41 100644 --- a/code/datums/repositories/follow.dm +++ b/code/datums/repositories/follow.dm @@ -36,7 +36,7 @@ var/global/repository/follow/follow_repository = new() followed_objects_assoc[AM] = follow_holder followed_objects.Add(follow_holder) - events_repository.register(/decl/observ/destroyed, AM, src, /repository/follow/proc/remove_subject) + events_repository.register(/decl/observ/destroyed, AM, src, TYPE_PROC_REF(/repository/follow, remove_subject)) /repository/follow/proc/remove_subject(var/atom/movable/AM) cache = null @@ -46,7 +46,7 @@ var/global/repository/follow/follow_repository = new() followed_objects_assoc -= AM followed_objects.Remove(follow_holder) - events_repository.unregister(/decl/observ/destroyed, AM, src, /repository/follow/proc/remove_subject) + events_repository.unregister(/decl/observ/destroyed, AM, src, TYPE_PROC_REF(/repository/follow, remove_subject)) qdel(follow_holder) @@ -175,7 +175,7 @@ var/global/repository/follow/follow_repository = new() /datum/follow_holder/brain sort_order = 3 - followed_type = /mob/living/carbon/brain + followed_type = /mob/living/brain suffix = "Brain" /datum/follow_holder/alien diff --git a/code/datums/sound_player.dm b/code/datums/sound_player.dm index 82cc8890e2c..3c93089fb07 100644 --- a/code/datums/sound_player.dm +++ b/code/datums/sound_player.dm @@ -128,10 +128,10 @@ listeners = list() listener_status = list() - events_repository.register(/decl/observ/destroyed, source, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/datum, qdel_self)) if(ismovable(source)) - proxy_listener = new(source, /datum/sound_token/proc/PrivAddListener, /datum/sound_token/proc/PrivLocateListeners, range, proc_owner = src) + proxy_listener = new(source, TYPE_PROC_REF(/datum/sound_token, PrivAddListener), TYPE_PROC_REF(/datum/sound_token, PrivLocateListeners), range, proc_owner = src) proxy_listener.register_turfs() /datum/sound_token/Destroy() @@ -169,7 +169,7 @@ listeners = null listener_status = null - events_repository.unregister(/decl/observ/destroyed, source, src, /datum/proc/qdel_self) + events_repository.unregister(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/datum, qdel_self)) QDEL_NULL(proxy_listener) source = null @@ -217,16 +217,16 @@ listeners += listener - events_repository.register(/decl/observ/moved, listener, src, /datum/sound_token/proc/PrivUpdateListenerLoc) - events_repository.register(/decl/observ/destroyed, listener, src, /datum/sound_token/proc/PrivRemoveListener) + events_repository.register(/decl/observ/moved, listener, src, TYPE_PROC_REF(/datum/sound_token, PrivUpdateListenerLoc)) + events_repository.register(/decl/observ/destroyed, listener, src, TYPE_PROC_REF(/datum/sound_token, PrivRemoveListener)) PrivUpdateListenerLoc(listener, FALSE) /datum/sound_token/proc/PrivRemoveListener(var/atom/listener, var/sound/null_sound) null_sound = null_sound || new(channel = sound.channel) sound_to(listener, null_sound) - events_repository.unregister(/decl/observ/moved, listener, src, /datum/sound_token/proc/PrivUpdateListenerLoc) - events_repository.unregister(/decl/observ/destroyed, listener, src, /datum/sound_token/proc/PrivRemoveListener) + events_repository.unregister(/decl/observ/moved, listener, src, TYPE_PROC_REF(/datum/sound_token, PrivUpdateListenerLoc)) + events_repository.unregister(/decl/observ/destroyed, listener, src, TYPE_PROC_REF(/datum/sound_token, PrivRemoveListener)) listeners -= listener listener_status -= listener diff --git a/code/datums/supplypacks/galley.dm b/code/datums/supplypacks/galley.dm index 6f09cdb49f5..c662ff7c913 100644 --- a/code/datums/supplypacks/galley.dm +++ b/code/datums/supplypacks/galley.dm @@ -6,7 +6,7 @@ contains = list(/obj/item/chems/condiment/flour = 6, /obj/item/chems/drinks/milk = 4, /obj/item/chems/drinks/soymilk = 2, - /obj/item/storage/fancy/egg_box = 2, + /obj/item/storage/box/fancy/egg_box = 2, /obj/item/chems/food/tofu = 4, /obj/item/chems/food/meat = 4, /obj/item/chems/condiment/enzyme = 1 @@ -45,7 +45,7 @@ /decl/hierarchy/supply_pack/galley/eggs name = "Perishables - Eggs" - contains = list(/obj/item/storage/fancy/egg_box = 2) + contains = list(/obj/item/storage/box/fancy/egg_box = 2) containertype = /obj/structure/closet/crate/freezer containername = "egg crate" @@ -93,7 +93,7 @@ /obj/item/chems/drinks/bottle/patron, /obj/item/chems/drinks/bottle/goldschlager, /obj/item/chems/drinks/bottle/agedwhiskey, - /obj/item/storage/fancy/cigarettes/dromedaryco, + /obj/item/storage/box/fancy/cigarettes/dromedaryco, /obj/random/lipstick, /obj/item/chems/drinks/bottle/small/ale = 2, /obj/item/chems/drinks/bottle/small/beer = 4, diff --git a/code/datums/supplypacks/livecargo.dm b/code/datums/supplypacks/livecargo.dm index 0723b926372..13078d3ab1e 100644 --- a/code/datums/supplypacks/livecargo.dm +++ b/code/datums/supplypacks/livecargo.dm @@ -51,3 +51,10 @@ containertype = /obj/structure/largecrate/animal containername = "chicken crate" access = access_hydroponics + +/decl/hierarchy/supply_pack/livecargo/duck + name = "Live - Duck" + contains = list(/mob/living/simple_animal/fowl/duck = 3) + containertype = /obj/structure/largecrate/animal + containername = "duck crate" + access = access_hydroponics diff --git a/code/datums/supplypacks/nonessent.dm b/code/datums/supplypacks/nonessent.dm index 4e03952f164..565b6c8662d 100644 --- a/code/datums/supplypacks/nonessent.dm +++ b/code/datums/supplypacks/nonessent.dm @@ -11,7 +11,7 @@ /decl/hierarchy/supply_pack/nonessent/artscrafts name = "Art - Arts and Crafts supplies" contains = list( - /obj/item/storage/fancy/crayons, + /obj/item/storage/box/fancy/crayons, /obj/item/camera, /obj/item/camera_film = 2, /obj/item/storage/photo_album, diff --git a/code/datums/trading/traders/ai.dm b/code/datums/trading/traders/ai.dm index 0ef61515c4f..9a0759cdba5 100644 --- a/code/datums/trading/traders/ai.dm +++ b/code/datums/trading/traders/ai.dm @@ -48,7 +48,7 @@ They sell generic supplies and ask for generic supplies. /obj/item/storage/backpack/dufflebag/syndie = TRADER_BLACKLIST_SUB, /obj/item/storage/belt/champion = TRADER_THIS_TYPE, /obj/item/storage/briefcase = TRADER_THIS_TYPE, - /obj/item/storage/fancy = TRADER_SUBTYPES_ONLY, + /obj/item/storage/box/fancy = TRADER_SUBTYPES_ONLY, /obj/item/storage/laundry_basket = TRADER_THIS_TYPE, /obj/item/storage/secure/briefcase = TRADER_THIS_TYPE, /obj/item/storage/plants = TRADER_THIS_TYPE, diff --git a/code/datums/trading/traders/food.dm b/code/datums/trading/traders/food.dm index 7a6c4aee8d4..4d87e5d0c3a 100644 --- a/code/datums/trading/traders/food.dm +++ b/code/datums/trading/traders/food.dm @@ -37,7 +37,9 @@ var/obj/item/pizzabox/box = new(location) M.forceMove(box) box.pizza = M - box.boxtag = "A special order from [origin]" + box.box_tag = "A special order from [origin]!" + box.update_strings() + box.update_icon() /datum/trader/ship/chinese name = "Chinese Restaurant" @@ -114,7 +116,6 @@ /obj/item/chems/drinks/cans = TRADER_SUBTYPES_ONLY, /obj/item/chems/drinks/bottle = TRADER_SUBTYPES_ONLY, /obj/item/chems/drinks/bottle/small = TRADER_BLACKLIST, - /obj/item/chems/food/checker = TRADER_BLACKLIST_ALL, /obj/item/chems/food/fruit_slice = TRADER_BLACKLIST, /obj/item/chems/food/slice = TRADER_BLACKLIST_ALL, /obj/item/chems/food/grown = TRADER_BLACKLIST_ALL, diff --git a/code/datums/trading/traders/goods.dm b/code/datums/trading/traders/goods.dm index 76c338c2815..7f6948e5249 100644 --- a/code/datums/trading/traders/goods.dm +++ b/code/datums/trading/traders/goods.dm @@ -218,43 +218,43 @@ Sells devices, odds and ends, and medical stuff "McGillicuddy's" ) possible_trading_items = list( - /obj/item/flashlight = TRADER_ALL, - /obj/item/kit/paint = TRADER_SUBTYPES_ONLY, - /obj/item/aicard = TRADER_THIS_TYPE, - /obj/item/binoculars = TRADER_THIS_TYPE, - /obj/item/cable_painter = TRADER_THIS_TYPE, - /obj/item/flash = TRADER_THIS_TYPE, - /obj/item/paint_sprayer = TRADER_THIS_TYPE, - /obj/item/multitool = TRADER_THIS_TYPE, - /obj/item/lightreplacer = TRADER_THIS_TYPE, - /obj/item/megaphone = TRADER_THIS_TYPE, - /obj/item/paicard = TRADER_THIS_TYPE, - /obj/item/scanner/health = TRADER_THIS_TYPE, - /obj/item/scanner/breath = TRADER_THIS_TYPE, - /obj/item/scanner/gas = TRADER_ALL, - /obj/item/scanner/spectrometer = TRADER_ALL, - /obj/item/scanner/reagent = TRADER_ALL, - /obj/item/scanner/xenobio = TRADER_THIS_TYPE, - /obj/item/suit_cooling_unit = TRADER_THIS_TYPE, - /obj/item/t_scanner = TRADER_THIS_TYPE, - /obj/item/taperecorder = TRADER_THIS_TYPE, - /obj/item/batterer = TRADER_THIS_TYPE, - /obj/item/synthesized_instrument/violin = TRADER_THIS_TYPE, - /obj/item/hailer = TRADER_THIS_TYPE, - /obj/item/uv_light = TRADER_THIS_TYPE, - /obj/item/mmi = TRADER_ALL, - /obj/item/robotanalyzer = TRADER_THIS_TYPE, - /obj/item/chems/toner_cartridge = TRADER_THIS_TYPE, - /obj/item/camera_film = TRADER_THIS_TYPE, - /obj/item/camera = TRADER_THIS_TYPE, - /obj/item/destTagger = TRADER_THIS_TYPE, - /obj/item/gps = TRADER_THIS_TYPE, - /obj/item/measuring_tape = TRADER_THIS_TYPE, - /obj/item/ano_scanner = TRADER_THIS_TYPE, - /obj/item/core_sampler = TRADER_THIS_TYPE, - /obj/item/depth_scanner = TRADER_THIS_TYPE, - /obj/item/pinpointer/radio = TRADER_THIS_TYPE, - /obj/item/stack/medical/advanced = TRADER_BLACKLIST + /obj/item/flashlight = TRADER_ALL, + /obj/item/kit/paint = TRADER_SUBTYPES_ONLY, + /obj/item/aicard = TRADER_THIS_TYPE, + /obj/item/binoculars = TRADER_THIS_TYPE, + /obj/item/cable_painter = TRADER_THIS_TYPE, + /obj/item/flash = TRADER_THIS_TYPE, + /obj/item/paint_sprayer = TRADER_THIS_TYPE, + /obj/item/multitool = TRADER_THIS_TYPE, + /obj/item/lightreplacer = TRADER_THIS_TYPE, + /obj/item/megaphone = TRADER_THIS_TYPE, + /obj/item/paicard = TRADER_THIS_TYPE, + /obj/item/scanner/health = TRADER_THIS_TYPE, + /obj/item/scanner/breath = TRADER_THIS_TYPE, + /obj/item/scanner/gas = TRADER_ALL, + /obj/item/scanner/spectrometer = TRADER_ALL, + /obj/item/scanner/reagent = TRADER_ALL, + /obj/item/scanner/xenobio = TRADER_THIS_TYPE, + /obj/item/suit_cooling_unit = TRADER_THIS_TYPE, + /obj/item/t_scanner = TRADER_THIS_TYPE, + /obj/item/taperecorder = TRADER_THIS_TYPE, + /obj/item/batterer = TRADER_THIS_TYPE, + /obj/item/synthesized_instrument/violin = TRADER_THIS_TYPE, + /obj/item/hailer = TRADER_THIS_TYPE, + /obj/item/uv_light = TRADER_THIS_TYPE, + /obj/item/organ/internal/brain_interface = TRADER_SUBTYPES_ONLY, + /obj/item/robotanalyzer = TRADER_THIS_TYPE, + /obj/item/chems/toner_cartridge = TRADER_THIS_TYPE, + /obj/item/camera_film = TRADER_THIS_TYPE, + /obj/item/camera = TRADER_THIS_TYPE, + /obj/item/destTagger = TRADER_THIS_TYPE, + /obj/item/gps = TRADER_THIS_TYPE, + /obj/item/measuring_tape = TRADER_THIS_TYPE, + /obj/item/ano_scanner = TRADER_THIS_TYPE, + /obj/item/core_sampler = TRADER_THIS_TYPE, + /obj/item/depth_scanner = TRADER_THIS_TYPE, + /obj/item/pinpointer/radio = TRADER_THIS_TYPE, + /obj/item/stack/medical/advanced = TRADER_BLACKLIST ) speech = list( TRADER_HAIL_GENERIC = "Hello, hello! Bits and bobs and everything in between, I hope you find what you're looking for!", @@ -383,7 +383,7 @@ Sells devices, odds and ends, and medical stuff /obj/item/organ/internal/kidneys = TRADER_THIS_TYPE, /obj/item/organ/internal/lungs = TRADER_THIS_TYPE, /obj/item/organ/internal/heart = TRADER_THIS_TYPE, - /obj/item/storage/fancy/cigarettes = TRADER_ALL + /obj/item/storage/box/fancy/cigarettes = TRADER_ALL ) possible_trading_items = list( diff --git a/code/datums/trading/traders/misc.dm b/code/datums/trading/traders/misc.dm index 75bdacd68bb..136fd64b3a7 100644 --- a/code/datums/trading/traders/misc.dm +++ b/code/datums/trading/traders/misc.dm @@ -38,7 +38,8 @@ /mob/living/simple_animal/tomato = TRADER_THIS_TYPE, /mob/living/simple_animal/cow = TRADER_THIS_TYPE, /mob/living/simple_animal/chick = TRADER_THIS_TYPE, - /mob/living/simple_animal/chicken = TRADER_THIS_TYPE, + /mob/living/simple_animal/fowl/chicken = TRADER_THIS_TYPE, + /mob/living/simple_animal/fowl/duck = TRADER_THIS_TYPE, /mob/living/simple_animal/yithian = TRADER_THIS_TYPE, /mob/living/simple_animal/hostile/retaliate/beast/diyaab = TRADER_THIS_TYPE, /mob/living/simple_animal/hostile/bear = TRADER_THIS_TYPE, @@ -60,7 +61,8 @@ /mob/living/simple_animal/tomato = TRADER_THIS_TYPE, /mob/living/simple_animal/cow = TRADER_THIS_TYPE, /mob/living/simple_animal/chick = TRADER_THIS_TYPE, - /mob/living/simple_animal/chicken = TRADER_THIS_TYPE, + /mob/living/simple_animal/fowl/chicken = TRADER_THIS_TYPE, + /mob/living/simple_animal/fowl/duck = TRADER_THIS_TYPE, /mob/living/simple_animal/yithian = TRADER_THIS_TYPE, /mob/living/simple_animal/hostile/retaliate/beast/diyaab = TRADER_THIS_TYPE, /mob/living/simple_animal/hostile/bear = TRADER_THIS_TYPE, diff --git a/code/datums/type_cloning.dm b/code/datums/type_cloning.dm index b0aeb132fb2..4ceeea67dfe 100644 --- a/code/datums/type_cloning.dm +++ b/code/datums/type_cloning.dm @@ -6,3 +6,5 @@ /matrix/GetCloneArgs() return list(src) //Matrices handle copies themselves +/image/GetCloneArgs() + return list(src) //Same for images \ No newline at end of file diff --git a/code/datums/uplink/services.dm b/code/datums/uplink/services.dm index 3a81c4f9149..6bec9ead893 100644 --- a/code/datums/uplink/services.dm +++ b/code/datums/uplink/services.dm @@ -41,7 +41,7 @@ /datum/uplink_item/item/services/fake_update_annoncement/New() ..() item_cost = round(DEFAULT_TELECRYSTAL_AMOUNT / 2) - addtimer(CALLBACK(src, .proc/finalize_announce), 2) + addtimer(CALLBACK(src, PROC_REF(finalize_announce)), 2) /datum/uplink_item/item/services/fake_update_annoncement/proc/finalize_announce() name = "[command_name()] Update Announcement" @@ -98,7 +98,7 @@ log_and_message_admins("has activated the service '[service_label]'", user) if(service_duration) - addtimer(CALLBACK(src,/obj/item/uplink_service/proc/deactivate), service_duration) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/uplink_service, deactivate)), service_duration) else deactivate() diff --git a/code/datums/vending/stored_item.dm b/code/datums/vending/stored_item.dm index 26a5828289c..8575eb91b16 100644 --- a/code/datums/vending/stored_item.dm +++ b/code/datums/vending/stored_item.dm @@ -5,13 +5,17 @@ var/list/instances //What items are actually stored var/atom/storing_object -/datum/stored_items/New(var/atom/storing_object, var/path, var/name = null, var/amount = 0) +/datum/stored_items/New(atom/_storing_object, _path, _name, _amount = 1) + if(_storing_object) + storing_object = _storing_object if(!istype(storing_object)) - CRASH("Unexpected storing object.") - src.storing_object = storing_object - src.item_path = path - src.amount = amount - src.item_name = name || atom_info_repository.get_name_for(path) + CRASH("Unexpected storing object: [storing_object]") + if(_path) + item_path = _path + if(!ispath(item_path)) + CRASH("Unexpected item path: [item_path || "NULL"]") + item_name = _name || atom_info_repository.get_name_for(item_path) + amount = _amount ..() /datum/stored_items/Destroy() diff --git a/code/datums/vending/vending.dm b/code/datums/vending/vending.dm index f000eaac3f1..d92e8d483e1 100644 --- a/code/datums/vending/vending.dm +++ b/code/datums/vending/vending.dm @@ -6,13 +6,11 @@ */ /datum/stored_items/vending_products - item_name = "generic" // Display name for the product - var/price = 0 // Price to buy one - var/display_color = null // Display color for vending machine listing - var/category = CAT_NORMAL // CAT_HIDDEN for contraband - -/datum/stored_items/vending_products/New(var/atom/storing_object, var/path, var/name = null, var/amount = 0, var/price = 0, var/color = null, var/category = CAT_NORMAL) - ..() - src.price = price - src.display_color = color - src.category = category + /// Display name for the product + item_name = "generic" + /// Price to buy one + var/price = 0 + /// Display color for vending machine listing + var/display_color = null + // CAT_HIDDEN for contraband + var/category = CAT_NORMAL diff --git a/code/datums/vote/add_antag.dm b/code/datums/vote/add_antag.dm index 1d04ea08cbd..f9b82057ce2 100644 --- a/code/datums/vote/add_antag.dm +++ b/code/datums/vote/add_antag.dm @@ -43,7 +43,7 @@ global.additional_antag_types |= antag_type return - INVOKE_ASYNC(src, .proc/spawn_antags) //There is a sleep in this proc. + INVOKE_ASYNC(src, PROC_REF(spawn_antags)) //There is a sleep in this proc. /datum/vote/add_antagonist/proc/spawn_antags() @@ -58,7 +58,7 @@ antag_add_finished = 1 if(automatic) // the buffer will already have half an hour added to it, so we'll give it one more - transfer_controller.timerbuffer += config.vote_autotransfer_interval + transfer_controller.timerbuffer += get_config_value(/decl/config/num/vote_autotransfer_initial) else to_world("No antags were added.") if(automatic) diff --git a/code/datums/vote/gamemode.dm b/code/datums/vote/gamemode.dm index bb05d20a73d..663de74d6c0 100644 --- a/code/datums/vote/gamemode.dm +++ b/code/datums/vote/gamemode.dm @@ -6,7 +6,7 @@ show_leading = TRUE /datum/vote/gamemode/can_run(mob/creator, automatic) - if(!automatic && (!config.allow_vote_mode || !is_admin(creator))) + if(!automatic && (!get_config_value(/decl/config/toggle/vote_mode) || !is_admin(creator))) return FALSE // Admins and autovotes bypass the config setting. if(GAME_STATE >= RUNLEVEL_GAME) return FALSE @@ -20,7 +20,7 @@ /datum/vote/gamemode/setup_vote(mob/creator, automatic) ..() - choices += config.votable_modes + choices += get_config_value(/decl/config/lists/mode_votable) for (var/F in choices) var/decl/game_mode/M = decls_repository.get_decl_by_id(F, validate_decl_type = FALSE) if(!M) @@ -50,8 +50,8 @@ SSticker.gamemode_vote_results = result.Copy() /datum/vote/gamemode/check_toggle() - return config.allow_vote_mode ? "Allowed" : "Disallowed" + return get_config_value(/decl/config/toggle/vote_mode) ? "Allowed" : "Disallowed" /datum/vote/gamemode/toggle(mob/user) if(is_admin(user)) - config.allow_vote_mode = !config.allow_vote_mode \ No newline at end of file + toggle_config_value(/decl/config/toggle/vote_mode) diff --git a/code/datums/vote/map.dm b/code/datums/vote/map.dm index 6eccbb34d31..9e64ac63bcb 100644 --- a/code/datums/vote/map.dm +++ b/code/datums/vote/map.dm @@ -2,7 +2,7 @@ name = "map" /datum/vote/map/can_run(mob/creator, automatic) - if(!config.allow_map_switching) + if(!get_config_value(/decl/config/toggle/allow_map_switching)) return FALSE if(!automatic && !is_admin(creator)) return FALSE // Must be an admin. diff --git a/code/datums/vote/restart.dm b/code/datums/vote/restart.dm index a3e49a04fbb..75a564d6d59 100644 --- a/code/datums/vote/restart.dm +++ b/code/datums/vote/restart.dm @@ -6,7 +6,7 @@ results_length = 1 /datum/vote/restart/can_run(mob/creator, automatic) - if(!automatic && !config.allow_vote_restart && !is_admin(creator)) + if(!automatic && !get_config_value(/decl/config/toggle/vote_restart) && !is_admin(creator)) return FALSE // Admins and autovotes bypass the config setting. return ..() diff --git a/code/datums/vote/transfer.dm b/code/datums/vote/transfer.dm index 52de1c72e4c..b009162dcc4 100644 --- a/code/datums/vote/transfer.dm +++ b/code/datums/vote/transfer.dm @@ -7,7 +7,7 @@ return if(!SSevac.evacuation_controller || !SSevac.evacuation_controller.should_call_autotransfer_vote()) return FALSE - if(!automatic && !config.allow_vote_restart && !is_admin(creator)) + if(!automatic && !get_config_value(/decl/config/toggle/vote_restart) && !is_admin(creator)) return FALSE // Admins and autovotes bypass the config setting. if(check_rights(R_INVESTIGATE, 0, creator)) return //Mods bypass further checks. @@ -18,13 +18,13 @@ return FALSE /datum/vote/transfer/setup_vote(mob/creator, automatic) - choices = list("Initiate Crew Transfer", "Extend the Round ([config.vote_autotransfer_interval / 600] minutes)") - if (config.allow_extra_antags && SSvote.is_addantag_allowed(creator, automatic)) + choices = list("Initiate Crew Transfer", "Extend the Round ([get_config_value(/decl/config/num/vote_autotransfer_interval) / 600] minutes)") + if (get_config_value(/decl/config/toggle/allow_extra_antags) && SSvote.is_addantag_allowed(creator, automatic)) choices += "Add Antagonist" ..() /datum/vote/transfer/handle_default_votes() - if(config.vote_no_default) + if(get_config_value(/decl/config/num/vote_no_default)) return var/factor = 0.5 switch(world.time / (1 MINUTE)) @@ -52,12 +52,12 @@ /datum/vote/transfer/mob_not_participating(mob/user) if((. = ..())) return - if(config.vote_no_dead_crew_transfer) + if(get_config_value(/decl/config/num/vote_no_dead_crew_transfer)) return !isliving(user) || ismouse(user) || isdrone(user) /datum/vote/transfer/check_toggle() - return config.allow_vote_restart ? "Allowed" : "Disallowed" + return get_config_value(/decl/config/toggle/vote_restart) ? "Allowed" : "Disallowed" /datum/vote/transfer/toggle(mob/user) if(is_admin(user)) - config.allow_vote_restart = !config.allow_vote_restart \ No newline at end of file + toggle_config_value(/decl/config/toggle/vote_restart) \ No newline at end of file diff --git a/code/datums/vote/vote.dm b/code/datums/vote/vote.dm index 27601e02718..df85565327f 100644 --- a/code/datums/vote/vote.dm +++ b/code/datums/vote/vote.dm @@ -53,7 +53,7 @@ /datum/vote/proc/start_vote() start_time = world.time - time_set = (time_set ? time_set : config.vote_period) + time_set = (time_set ? time_set : get_config_value(/decl/config/num/vote_period)) time_remaining = round(time_set / 10) status = VOTE_STATUS_ACTIVE @@ -68,7 +68,7 @@ //Modifies the vote totals based on non-voting mobs. /datum/vote/proc/handle_default_votes() - if(!config.vote_no_default) + if(!get_config_value(/decl/config/num/vote_no_default)) return length(global.clients) - length(voted) //Number of non-voters (might not be active, though; should be revisited if the config option is used. This is legacy code.) /datum/vote/proc/tally_result() @@ -130,7 +130,7 @@ // Checks if the mob is participating in the round sufficiently to vote, as per config settings. /datum/vote/proc/mob_not_participating(mob/voter) - if(config.vote_no_dead && voter.stat == DEAD && !voter.client.holder) + if(get_config_value(/decl/config/num/vote_no_dead) && voter.stat == DEAD && !voter.client.holder) return 1 //null = no toggle set. This is for UI purposes; a text return will give a link (toggle; currently "return") in the vote panel. diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index d8e207e3a19..951e79f60e8 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -170,7 +170,7 @@ var/global/const/AIRLOCK_WIRE_SPEAKER = 4096 A.aiControlDisabled = 1 else if(A.aiControlDisabled == -1) A.aiControlDisabled = 2 - addtimer(CALLBACK(src, .proc/reset_ai_control, A), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_ai_control), A), 1 SECOND) if(AIRLOCK_WIRE_ELECTRIFY) //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm index b8b7817e339..ddcce1fc75e 100644 --- a/code/datums/wires/alarm.dm +++ b/code/datums/wires/alarm.dm @@ -84,13 +84,13 @@ var/global/const/AALARM_WIRE_AALARM = 16 if(A.shorted == 0) A.shorted = 1 A.update_icon() - addtimer(CALLBACK(src, .proc/clear_shorted), 20 MINUTES) + addtimer(CALLBACK(src, PROC_REF(clear_shorted)), 20 MINUTES) if (AALARM_WIRE_AI_CONTROL) if (A.aidisabled == 0) A.aidisabled = 1 A.updateDialog() - addtimer(CALLBACK(src, .proc/clear_ai_disabled, 10 SECONDS)) + addtimer(CALLBACK(src, PROC_REF(clear_ai_disabled), 10 SECONDS)) if(AALARM_WIRE_SYPHON) if(A.mode == 1) // AALARM_MODE_SCRUB diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm index 4dbafcde5e4..b7d1221c081 100644 --- a/code/datums/wires/apc.dm +++ b/code/datums/wires/apc.dm @@ -5,7 +5,7 @@ /datum/wires/apc holder_type = /obj/machinery/power/apc - wire_count = 4 + wire_count = 4 descriptions = list( new /datum/wire_description(APC_WIRE_IDSCAN, "This wire is connected to the ID scanning panel.", SKILL_EXPERT), new /datum/wire_description(APC_WIRE_MAIN_POWER1, "This wire seems to be carrying a heavy current."), @@ -48,17 +48,17 @@ if(APC_WIRE_IDSCAN) A.locked = 0 - addtimer(CALLBACK(src, .proc/reset_locked), 30 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reset_locked)), 30 SECONDS) if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2) if(A.shorted == 0) A.shorted = 1 - addtimer(CALLBACK(src, .proc/reset_shorted), 2 MINUTES) - + addtimer(CALLBACK(src, PROC_REF(reset_shorted)), 2 MINUTES) + if (APC_WIRE_AI_CONTROL) if (A.aidisabled == 0) A.aidisabled = 1 - addtimer(CALLBACK(src, .proc/reset_ai_disabled), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_ai_disabled)), 1 SECOND) /datum/wires/apc/UpdateCut(var/index, var/mended) var/obj/machinery/power/apc/A = holder diff --git a/code/datums/wires/fabricator.dm b/code/datums/wires/fabricator.dm index f19c27f9e41..a9a040f6fee 100644 --- a/code/datums/wires/fabricator.dm +++ b/code/datums/wires/fabricator.dm @@ -60,21 +60,21 @@ A.fab_status_flags &= ~FAB_HACKED else A.fab_status_flags |= FAB_HACKED - addtimer(CALLBACK(src, .proc/reset_flag, index, FAB_HACKED), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reset_flag), index, FAB_HACKED), 5 SECONDS) if(AUTOLATHE_SHOCK_WIRE) if(A.fab_status_flags & FAB_SHOCKED) A.fab_status_flags &= ~FAB_SHOCKED else A.fab_status_flags |= FAB_SHOCKED - addtimer(CALLBACK(src, .proc/reset_flag, index, FAB_SHOCKED), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reset_flag), index, FAB_SHOCKED), 5 SECONDS) if(AUTOLATHE_DISABLE_WIRE) if(A.fab_status_flags & FAB_DISABLED) A.fab_status_flags &= ~FAB_DISABLED else A.fab_status_flags |= FAB_DISABLED - addtimer(CALLBACK(src, .proc/reset_flag, index, FAB_DISABLED), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reset_flag), index, FAB_DISABLED), 5 SECONDS) #undef AUTOLATHE_HACK_WIRE #undef AUTOLATHE_SHOCK_WIRE diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm index 0b7a0ca2397..06c679edfd2 100644 --- a/code/datums/wires/nuclearbomb.dm +++ b/code/datums/wires/nuclearbomb.dm @@ -53,14 +53,14 @@ var/global/const/NUCLEARBOMB_WIRE_SAFETY = 4 N.lighthack = !N.lighthack N.update_icon() toggle_hacked() - addtimer(CALLBACK(src, .proc/toggle_hacked), 10 SECONDS) + addtimer(CALLBACK(src, PROC_REF(toggle_hacked)), 10 SECONDS) if(NUCLEARBOMB_WIRE_TIMING) if(N.timing) log_and_explode("pulsed a nuclear bomb's detonation wire, causing it to explode.") if(NUCLEARBOMB_WIRE_SAFETY) N.safety = !N.safety - addtimer(CALLBACK(src, .proc/toggle_safety), 10 SECONDS) + addtimer(CALLBACK(src, PROC_REF(toggle_safety)), 10 SECONDS) /datum/wires/nuclearbomb/UpdateCut(var/index, var/mended) var/obj/machinery/nuclearbomb/N = holder diff --git a/code/datums/wires/smes.dm b/code/datums/wires/smes.dm index 16e0883f842..15eff146d15 100644 --- a/code/datums/wires/smes.dm +++ b/code/datums/wires/smes.dm @@ -63,7 +63,7 @@ var/global/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to r if(SMES_WIRE_RCON) if(S.RCon) S.RCon = 0 - addtimer(CALLBACK(src, .proc/reset_rcon), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_rcon)), 1 SECOND) if(SMES_WIRE_INPUT) S.toggle_input() if(SMES_WIRE_OUTPUT) @@ -73,4 +73,4 @@ var/global/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to r if(SMES_WIRE_FAILSAFES) if(S.safeties_enabled) S.safeties_enabled = 0 - addtimer(CALLBACK(src, .proc/reset_safeties), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_safeties)), 1 SECOND) diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 6a4919f951f..6aabe004cbe 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -92,7 +92,7 @@ get_starting_locations() if(!name_plural) name_plural = name - if(config.protect_roles_from_antagonist) + if(get_config_value(/decl/config/toggle/protect_roles_from_antagonist)) restricted_jobs |= protected_jobs if(antaghud_indicator) if(!global.hud_icon_reference) @@ -136,10 +136,11 @@ // Prune restricted status. Broke it up for readability. // Note that this is done before jobs are handed out. + var/age_restriction = get_config_value(/decl/config/num/use_age_restriction_for_antags) for(var/datum/mind/player in mode.get_players_for_role(type)) if(ghosts_only && !(isghostmind(player) || isnewplayer(player.current))) log_debug("[key_name(player)] is not eligible to become a [name]: Only ghosts may join as this role!") - else if(config.use_age_restriction_for_antags && player.current.client.player_age < minimum_player_age) + else if(age_restriction && player.current.client.player_age < minimum_player_age) log_debug("[key_name(player)] is not eligible to become a [name]: Is only [player.current.client.player_age] day\s old, has to be [minimum_player_age] day\s!") else if(player.assigned_special_role) log_debug("[key_name(player)] is not eligible to become a [name]: They already have a special role ([player.get_special_role_name("unknown role")])!") @@ -159,10 +160,11 @@ var/candidates = list() // Keeping broken up for readability + var/age_restriction = get_config_value(/decl/config/num/use_age_restriction_for_antags) for(var/datum/mind/player in mode.get_players_for_role(type)) if(ghosts_only && !(isghostmind(player) || isnewplayer(player.current))) continue - if(config.use_age_restriction_for_antags && player.current.client.player_age < minimum_player_age) + if(age_restriction && player.current.client.player_age < minimum_player_age) continue if(player.assigned_special_role) continue diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm index 8ecfb5a6c5b..df05b830089 100644 --- a/code/game/antagonist/antagonist_add.dm +++ b/code/game/antagonist/antagonist_add.dm @@ -60,7 +60,7 @@ if(faction_verb) player.current.verbs |= faction_verb - if(config.objectives_disabled == CONFIG_OBJECTIVE_VERB) + if(get_config_value(/decl/config/enum/objectives_disabled) == CONFIG_OBJECTIVE_VERB) player.current.verbs += /mob/proc/add_objectives if(player.current.client) diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm index cd86a919362..10c459c2c7d 100644 --- a/code/game/antagonist/antagonist_create.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -8,7 +8,7 @@ remove_antagonist(target) return 0 if(flags & ANTAG_CHOOSE_NAME) - INVOKE_ASYNC(src, .proc/set_antag_name, target.current) + INVOKE_ASYNC(src, PROC_REF(set_antag_name), target.current) if(move) place_mob(target.current) update_leader() @@ -75,7 +75,7 @@ to_chat(player.current, "[get_leader_welcome_text(player.current)]") else to_chat(player.current, "[get_welcome_text(player.current)]") - if (config.objectives_disabled == CONFIG_OBJECTIVE_NONE || !player.objectives.len) + if (get_config_value(/decl/config/enum/objectives_disabled) == CONFIG_OBJECTIVE_NONE || !player.objectives.len) to_chat(player.current, get_antag_text(player.current)) if((flags & ANTAG_HAS_NUKE) && !spawned_nuke) diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm index 6f7cbf938ca..f882c80efcd 100644 --- a/code/game/antagonist/antagonist_helpers.dm +++ b/code/game/antagonist/antagonist_helpers.dm @@ -12,7 +12,7 @@ if(player.current && player.current.client) var/client/C = player.current.client // Limits antag status to clients above player age, if the age system is being used. - if(C && config.use_age_restriction_for_jobs && isnum(C.player_age) && isnum(min_player_age) && (C.player_age < min_player_age)) + if(C && get_config_value(/decl/config/num/use_age_restriction_for_jobs) && isnum(C.player_age) && isnum(min_player_age) && (C.player_age < min_player_age)) return FALSE if(player.assigned_job) if(is_type_in_list(player.assigned_job, blacklisted_jobs) || is_type_in_list(player.assigned_job, restricted_jobs)) diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm index 019249fa72a..5e0f27068cf 100644 --- a/code/game/antagonist/antagonist_objectives.dm +++ b/code/game/antagonist/antagonist_objectives.dm @@ -1,12 +1,12 @@ /decl/special_role/proc/create_global_objectives(var/override=0) - if(config.objectives_disabled != CONFIG_OBJECTIVE_ALL && !override) + if(get_config_value(/decl/config/enum/objectives_disabled) != CONFIG_OBJECTIVE_ALL && !override) return 0 if(global_objectives && global_objectives.len) return 0 return 1 /decl/special_role/proc/create_objectives(var/datum/mind/player, var/override=0) - if(config.objectives_disabled != CONFIG_OBJECTIVE_ALL && !override) + if(get_config_value(/decl/config/enum/objectives_disabled) != CONFIG_OBJECTIVE_ALL && !override) return 0 if(create_global_objectives(override) || global_objectives.len) player.objectives |= global_objectives diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index dc90996ea1a..a11cfa5ae17 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -18,7 +18,7 @@ rig_type = /obj/item/rig/light/ninja /decl/special_role/ninja/attempt_random_spawn() - if(config.ninjas_allowed) + if(get_config_value(/decl/config/toggle/ninjas_allowed)) ..() /decl/special_role/ninja/create_objectives(var/datum/mind/ninja) diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm index 29b5bcc9722..b05e5f9a7b0 100644 --- a/code/game/antagonist/station/traitor.dm +++ b/code/game/antagonist/station/traitor.dm @@ -78,12 +78,21 @@ if(culture && prob(culture.subversive_potential)) dudes += man dudes -= player.current + for(var/datum/objective/obj in player.objectives) + dudes -= obj.owner?.current + dudes -= obj.target?.current if(length(dudes)) var/mob/living/carbon/human/M = pick(dudes) to_chat(player.current, "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them.") player.StoreMemory("Potential Collaborator: [M.real_name]", /decl/memory_options/system) + to_chat(M, "The subversive potential of your faction has been noticed, and you may be contacted for assistance soon...") + to_chat(M, "Code Phrase: [syndicate_code_phrase]") + to_chat(M, "Code Response: [syndicate_code_response]") + M.StoreMemory("Code Phrase: [syndicate_code_phrase]", /decl/memory_options/system) + M.StoreMemory("Code Response: [syndicate_code_response]", /decl/memory_options/system) + to_chat(M, "Listen for the code words, preferably in the order provided, during regular conversations to identify agents in need. Proceed with caution, however, as everyone is a potential foe.") to_chat(player.current, "Your employers provided you with the following information on how to identify possible allies:") to_chat(player.current, "Code Phrase: [syndicate_code_phrase]") diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 673d6a34234..f97c51be41c 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -132,6 +132,7 @@ var/global/list/areas = list() T.last_outside_check = OUTSIDE_UNCERTAIN if(T.is_outside == OUTSIDE_AREA && T.is_outside() != old_outside) T.update_weather() + T.update_external_atmos_participation() /turf/proc/update_registrations_on_adjacent_area_change() for(var/obj/machinery/door/firedoor/door in src) @@ -403,7 +404,7 @@ var/global/list/mob/living/forced_ambiance_list = new /area/proc/throw_unbuckled_occupants(var/maxrange, var/speed, var/direction) for(var/mob/M in src) - addtimer(CALLBACK(src, .proc/throw_unbuckled_occupant, M, maxrange, speed, direction), 0) + addtimer(CALLBACK(src, PROC_REF(throw_unbuckled_occupant), M, maxrange, speed, direction), 0) /area/proc/throw_unbuckled_occupant(var/mob/M, var/maxrange, var/speed, var/direction) if(iscarbon(M)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7498d17ea4a..02fb42f7cb1 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -143,7 +143,7 @@ Handle an atom entering this atom's proximity Called when an atom enters this atom's proximity. Both this and the other atom - need to have the PROXMOVE flag (as it helps reduce lag). + need to have the MOVABLE_FLAG_PROXMOVE flag (as it helps reduce lag). - `AM`: The atom entering proximity - Return: `TRUE` if proximity should continue to be handled, otherwise `FALSE` @@ -468,7 +468,7 @@ - `M?`: The mob whose blood will be used - Returns: TRUE if made bloody, otherwise FALSE */ -/atom/proc/add_blood(mob/living/carbon/human/M) +/atom/proc/add_blood(mob/living/M) if(atom_flags & ATOM_FLAG_NO_BLOOD) return FALSE @@ -482,7 +482,7 @@ M.dna = new /datum/dna() M.dna.real_name = M.real_name M.check_dna() - blood_color = M.species.get_blood_color(M) + blood_color = M.get_blood_color() return TRUE /** @@ -490,7 +490,7 @@ - Return: `TRUE` if blood with DNA was removed */ -/atom/proc/clean_blood() +/atom/proc/clean(clean_forensics = TRUE) SHOULD_CALL_PARENT(TRUE) if(!simulated) return @@ -504,6 +504,7 @@ forensics.remove_data(/datum/forensics/blood_dna) forensics.remove_data(/datum/forensics/gunshot_residue) return TRUE + return FALSE /// Only used by Sandbox_Spacemove, which is used by nothing /// - TODO: Remove this @@ -743,9 +744,27 @@ /atom/proc/get_color() return color -/// Set the color of this atom to `new_color`. -/atom/proc/set_color(new_color) - color = new_color +/* Set the atom colour. This is a stub effectively due to the broad use of direct setting. */ +// TODO: implement this everywhere that it should be used instead of direct setting. +/atom/proc/set_color(var/new_color) + if(isnull(new_color)) + return reset_color() + if(color != new_color) + color = new_color + return TRUE + return FALSE + +/atom/proc/reset_color() + if(!isnull(color)) + color = null + return TRUE + return FALSE + +/atom/proc/set_alpha(var/new_alpha) + if(alpha != new_alpha) + alpha = new_alpha + return TRUE + return FALSE /// Get any power cell associated with this atom. /atom/proc/get_cell() diff --git a/code/game/atoms_fluids.dm b/code/game/atoms_fluids.dm index 3211271a2e5..2af996d71bd 100644 --- a/code/game/atoms_fluids.dm +++ b/code/game/atoms_fluids.dm @@ -7,9 +7,6 @@ reagents.trans_to_holder(fluids, reagents.total_volume) fluids.trans_to_holder(reagents, min(fluids.total_volume, reagents.maximum_volume)) -/atom/proc/return_fluid() - return null - /atom/proc/check_fluid_depth(var/min) return 0 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 84c5bbad3d0..f15419425bc 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -10,7 +10,7 @@ var/buckle_layer_above = FALSE var/buckle_dir = 0 var/buckle_lying = -1 // bed-like behavior, forces mob.lying = buckle_lying if != -1 - var/buckle_pixel_shift // ex. @"{'x':0,'y':0,'z':0}" //where the buckled mob should be pixel shifted to, or null for no pixel shift control + var/buckle_pixel_shift // ex. @'{"x":0,"y":0,"z":0}' //where the buckled mob should be pixel shifted to, or null for no pixel shift control var/buckle_require_restraints = 0 // require people to be cuffed before being able to buckle. eg: pipes var/buckle_require_same_tile = FALSE var/buckle_sound @@ -144,7 +144,7 @@ if (A && yes) A.last_bumped = world.time - INVOKE_ASYNC(A, /atom/proc/Bumped, src) // Avoids bad actors sleeping or unexpected side effects, as the legacy behavior was to spawn here + INVOKE_ASYNC(A, TYPE_PROC_REF(/atom, Bumped), src) // Avoids bad actors sleeping or unexpected side effects, as the legacy behavior was to spawn here ..() /atom/movable/proc/forceMove(atom/destination) @@ -254,6 +254,15 @@ L = thing L.source_atom.update_light() + // Z-Mimic. + if (bound_overlay) + // The overlay will handle cleaning itself up on non-openspace turfs. + bound_overlay.forceMove(get_step(src, UP)) + if (bound_overlay.dir != dir) + bound_overlay.set_dir(dir) + else if (isturf(loc) && (!old_loc || !TURF_IS_MIMICKING(old_loc)) && MOVABLE_SHALL_MIMIC(src)) + SSzcopy.discover_movable(src) + //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, var/datum/thrownthing/TT) SHOULD_CALL_PARENT(TRUE) diff --git a/code/game/atoms_movable_interactions.dm b/code/game/atoms_movable_interactions.dm index dbc52b71a14..110c09afb82 100644 --- a/code/game/atoms_movable_interactions.dm +++ b/code/game/atoms_movable_interactions.dm @@ -1,6 +1,6 @@ /atom/movable/get_alt_interactions(var/mob/user) . = ..() - if(config.expanded_alt_interactions) + if(get_config_value(/decl/config/toggle/expanded_alt_interactions)) LAZYADD(., list( /decl/interaction_handler/look, /decl/interaction_handler/grab diff --git a/code/game/atoms_movable_overlay.dm b/code/game/atoms_movable_overlay.dm index a50abbb36a8..9d286c7913f 100644 --- a/code/game/atoms_movable_overlay.dm +++ b/code/game/atoms_movable_overlay.dm @@ -23,8 +23,8 @@ events_repository.register(/decl/observ/moved, master, src, follow_proc) SetInitLoc() - events_repository.register(/decl/observ/destroyed, master, src, /datum/proc/qdel_self) - events_repository.register(/decl/observ/dir_set, master, src, /atom/proc/recursive_dir_set) + events_repository.register(/decl/observ/destroyed, master, src, TYPE_PROC_REF(/datum, qdel_self)) + events_repository.register(/decl/observ/dir_set, master, src, TYPE_PROC_REF(/atom, recursive_dir_set)) . = ..() diff --git a/code/game/atoms_temperature.dm b/code/game/atoms_temperature.dm index e340bf91c44..609bac2f7b2 100644 --- a/code/game/atoms_temperature.dm +++ b/code/game/atoms_temperature.dm @@ -24,8 +24,8 @@ if(!ATOM_SHOULD_TEMPERATURE_ENQUEUE(src)) return FALSE - var/diff_temp = (adjust_temp - temperature) - if(diff_temp <= 0) + var/diff_temp = round(adjust_temp - temperature, 0.1) + if(diff_temp <= 0.1) return FALSE // Show a little message for people heating beakers with welding torches. diff --git a/code/game/base_turf.dm b/code/game/base_turf.dm index edb7d1006f7..671213c63e8 100644 --- a/code/game/base_turf.dm +++ b/code/game/base_turf.dm @@ -11,12 +11,30 @@ if(HasBelow(T.z)) if(istype(A) && A.open_turf) return A.open_turf + + // Find the first non-open turf below and use its open_turf_type. + var/z_stack_type = get_open_turf_type(T) + if(z_stack_type) + return z_stack_type + + // Otherwise, default to the open turf type set on the turf being removed. if(T.open_turf_type) return T.open_turf_type if(istype(A) && A.base_turf) return A.base_turf return get_base_turf(T.z) +// Returns the open turf of a Z-stack by finding the nearest non-open turf below. +/proc/get_open_turf_type(var/turf/T) + if(!HasBelow(T.z)) + return + var/turf/below = T + while ((below = GetBelow(below))) + if(!below.is_open() || !HasBelow(below.z)) + if(below.open_turf_type) + return below.open_turf_type + return + /client/proc/set_base_turf() set category = "Debug" set name = "Set Base Turf" diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 0121e88e2d2..103ddacb427 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -121,21 +121,25 @@ var/global/list/assigned_blocks[DNA_SE_LENGTH] // INITIALIZE! ResetUI(1) - SetUIValueRange(DNA_UI_HAIR_R, HEX_RED(character.hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR_G, HEX_GREEN(character.hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR_B, HEX_BLUE(character.hair_colour), 255, 1) - - SetUIValueRange(DNA_UI_BEARD_R, HEX_RED(character.facial_hair_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD_G, HEX_GREEN(character.facial_hair_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD_B, HEX_BLUE(character.facial_hair_colour), 255, 1) - - SetUIValueRange(DNA_UI_EYES_R, HEX_RED(character.eye_colour), 255, 1) - SetUIValueRange(DNA_UI_EYES_G, HEX_GREEN(character.eye_colour), 255, 1) - SetUIValueRange(DNA_UI_EYES_B, HEX_BLUE(character.eye_colour), 255, 1) - - SetUIValueRange(DNA_UI_SKIN_R, HEX_RED(character.skin_colour), 255, 1) - SetUIValueRange(DNA_UI_SKIN_G, HEX_GREEN(character.skin_colour), 255, 1) - SetUIValueRange(DNA_UI_SKIN_B, HEX_BLUE(character.skin_colour), 255, 1) + var/hair_colour = character.get_hair_colour() + SetUIValueRange(DNA_UI_HAIR_R, HEX_RED(hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR_G, HEX_GREEN(hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR_B, HEX_BLUE(hair_colour), 255, 1) + + var/facial_hair_colour = character.get_facial_hair_colour() + SetUIValueRange(DNA_UI_BEARD_R, HEX_RED(facial_hair_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD_G, HEX_GREEN(facial_hair_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD_B, HEX_BLUE(facial_hair_colour), 255, 1) + + var/eye_colour = character.get_eye_colour() + SetUIValueRange(DNA_UI_EYES_R, HEX_RED(eye_colour), 255, 1) + SetUIValueRange(DNA_UI_EYES_G, HEX_GREEN(eye_colour), 255, 1) + SetUIValueRange(DNA_UI_EYES_B, HEX_BLUE(eye_colour), 255, 1) + + var/skin_colour = character.get_skin_colour() + SetUIValueRange(DNA_UI_SKIN_R, HEX_RED(skin_colour), 255, 1) + SetUIValueRange(DNA_UI_SKIN_G, HEX_GREEN(skin_colour), 255, 1) + SetUIValueRange(DNA_UI_SKIN_B, HEX_BLUE(skin_colour), 255, 1) SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.skin_tone, 220, 1) // Value can be negative. @@ -146,11 +150,11 @@ var/global/list/assigned_blocks[DNA_SE_LENGTH] // Hair var/list/hair_types = decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/hair) - SetUIValueRange(DNA_UI_HAIR_STYLE, hair_types.Find(character.h_style), length(hair_types), 1) + SetUIValueRange(DNA_UI_HAIR_STYLE, hair_types.Find(character.get_hairstyle()), length(hair_types), 1) // Facial Hair var/list/beard_types = decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/facial_hair) - SetUIValueRange(DNA_UI_BEARD_STYLE, beard_types.Find(character.f_style), length(beard_types), 1) + SetUIValueRange(DNA_UI_BEARD_STYLE, beard_types.Find(character.get_facial_hairstyle()), length(beard_types), 1) body_markings.Cut() for(var/obj/item/organ/external/E in character.get_external_organs()) @@ -328,7 +332,7 @@ var/global/list/assigned_blocks[DNA_SE_LENGTH] SetSEBlock(block,newBlock,defer) /proc/EncodeDNABlock(var/value) - return add_zero2(num2hex(value,1), 3) + return num2hex_padded(value, 3) /datum/dna/proc/UpdateUI() src.uni_identity="" diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 48c4da795e0..bef63a12cea 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -2,16 +2,6 @@ // Helpers for DNA2 ///////////////////////////// -// Pads 0s to t until length == u -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - // DNA Gene activation boundaries, see dna2.dm. // Returns a list object with 4 numbers. /proc/GetDNABounds(var/block) @@ -143,13 +133,14 @@ dna.check_integrity() - fingerprint = dna.fingerprint - unique_enzymes = dna.unique_enzymes - hair_colour = rgb(dna.GetUIValueRange(DNA_UI_HAIR_R,255), dna.GetUIValueRange(DNA_UI_HAIR_G,255), dna.GetUIValueRange(DNA_UI_HAIR_B,255)) - facial_hair_colour = rgb(dna.GetUIValueRange(DNA_UI_BEARD_R,255), dna.GetUIValueRange(DNA_UI_BEARD_G,255), dna.GetUIValueRange(DNA_UI_BEARD_B,255)) - skin_colour = rgb(dna.GetUIValueRange(DNA_UI_SKIN_R,255), dna.GetUIValueRange(DNA_UI_SKIN_G,255), dna.GetUIValueRange(DNA_UI_SKIN_B,255)) - eye_colour = rgb(dna.GetUIValueRange(DNA_UI_EYES_R,255), dna.GetUIValueRange(DNA_UI_EYES_G,255), dna.GetUIValueRange(DNA_UI_EYES_B,255)) - skin_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. + fingerprint = dna.fingerprint + unique_enzymes = dna.unique_enzymes + set_skin_colour( rgb(dna.GetUIValueRange(DNA_UI_SKIN_R,255), dna.GetUIValueRange(DNA_UI_SKIN_G,255), dna.GetUIValueRange(DNA_UI_SKIN_B,255))) + set_eye_colour( rgb(dna.GetUIValueRange(DNA_UI_EYES_R,255), dna.GetUIValueRange(DNA_UI_EYES_G,255), dna.GetUIValueRange(DNA_UI_EYES_B,255))) + set_hair_colour( rgb(dna.GetUIValueRange(DNA_UI_HAIR_R,255), dna.GetUIValueRange(DNA_UI_HAIR_G,255), dna.GetUIValueRange(DNA_UI_HAIR_B,255))) + set_facial_hair_colour(rgb(dna.GetUIValueRange(DNA_UI_BEARD_R,255), dna.GetUIValueRange(DNA_UI_BEARD_G,255), dna.GetUIValueRange(DNA_UI_BEARD_B,255))) + skin_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. + // TODO: update DNA gender to not be a bool - use bodytype and pronouns //Body markings @@ -167,19 +158,23 @@ organ.set_dna(dna) //Hair + var/update_hair = FALSE var/list/hair_subtypes = decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/hair) var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE, length(hair_subtypes)) if(hair > 0 && hair <= length(hair_subtypes)) - h_style = hair_subtypes[hair] + set_hairstyle(hair_subtypes[hair], skip_update = TRUE) + update_hair = TRUE //Facial Hair var/list/beard_subtypes = decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/facial_hair) var/beard = dna.GetUIValueRange(DNA_UI_BEARD_STYLE, length(beard_subtypes)) if((0 < beard) && (beard <= length(beard_subtypes))) - f_style = beard_subtypes[beard] + set_facial_hairstyle(beard_subtypes[beard], skip_update = TRUE) + update_hair = TRUE force_update_limbs() - update_hair(update_icons = FALSE) + if(update_hair) + update_hair(update_icons = FALSE) update_eyes() return TRUE diff --git a/code/game/gamemodes/calamity/calamity.dm b/code/game/gamemodes/calamity/calamity.dm index 5c809eee420..860ae35eee9 100644 --- a/code/game/gamemodes/calamity/calamity.dm +++ b/code/game/gamemodes/calamity/calamity.dm @@ -9,6 +9,7 @@ votable = 0 event_delay_mod_moderate = 0.5 event_delay_mod_major = 0.75 + available_by_default = FALSE /decl/game_mode/calamity/create_antagonists() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 3e973359edd..02002444604 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -7,3 +7,4 @@ required_enemies = 3 end_on_antag_death = FALSE associated_antags = list(/decl/special_role/cultist) + probability = 1 diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 6d3194a0877..769fbc05658 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -117,7 +117,7 @@ /obj/effect/gateway/active/Initialize() . = ..() - addtimer(CALLBACK(src, .proc/create_and_delete), rand(30,60) SECONDS) + addtimer(CALLBACK(src, PROC_REF(create_and_delete)), rand(30,60) SECONDS) /obj/effect/gateway/active/proc/create_and_delete() @@ -150,8 +150,7 @@ if(isrobot(M)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) - qdel(Robot.mmi) + QDEL_NULL(Robot.central_processor) else for(var/obj/item/W in M) M.drop_from_inventory(W) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 9082adaf242..c8ab95e75ab 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -89,7 +89,7 @@ remove_blood_simple(cost * damage) if(locate(/obj/effect/rune) in T) return - var/obj/effect/rune/R = new rune(T, get_rune_color(), get_blood_name()) + var/obj/effect/rune/R = new rune(T, get_blood_color(), get_blood_name()) var/area/A = get_area(R) log_and_message_admins("created \an [R.cultname] rune at \the [A.proper_name].") R.add_fingerprint(src) @@ -129,12 +129,6 @@ /mob/living/carbon/human/mob_needs_tome() return 1 -/mob/proc/get_rune_color() - return "#c80000" - -/mob/living/carbon/human/get_rune_color() - return species.get_blood_color(src) - var/global/list/Tier1Runes = list( /mob/proc/convert_rune, /mob/proc/teleport_rune, diff --git a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm index d273379e59a..88708dee839 100644 --- a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm +++ b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm @@ -84,9 +84,9 @@ daddy = ndaddy set_dir(daddy.dir) appearance = daddy.appearance - events_repository.register(/decl/observ/moved, daddy, src, /obj/effect/bluegoast/proc/mirror) - events_repository.register(/decl/observ/dir_set, daddy, src, /obj/effect/bluegoast/proc/mirror_dir) - events_repository.register(/decl/observ/destroyed, daddy, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/moved, daddy, src, TYPE_PROC_REF(/obj/effect/bluegoast, mirror)) + events_repository.register(/decl/observ/dir_set, daddy, src, TYPE_PROC_REF(/obj/effect/bluegoast, mirror_dir)) + events_repository.register(/decl/observ/destroyed, daddy, src, TYPE_PROC_REF(/datum, qdel_self)) /obj/effect/bluegoast/Destroy() events_repository.unregister(/decl/observ/destroyed, daddy, src) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm index a3c8c357bd2..40a9036b8df 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm @@ -62,8 +62,8 @@ var/global/universe_has_ended = 0 if(length(global.endgame_exits)) spawned_exit = new /obj/effect/wormhole_exit(pick(global.endgame_exits)) - addtimer(CALLBACK(src, /datum/universal_state/supermatter_cascade/proc/announce_end_of_universe, spawned_exit), rand(30, 60) SECONDS) - addtimer(CALLBACK(src, /datum/universal_state/supermatter_cascade/proc/finalize_end_of_universe), 5 MINUTES) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/universal_state/supermatter_cascade, announce_end_of_universe), spawned_exit), rand(30, 60) SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/universal_state/supermatter_cascade, finalize_end_of_universe)), 5 MINUTES) /datum/universal_state/supermatter_cascade/proc/announce_end_of_universe(var/exit_exists) var/end_message = "Attn. [global.using_map.station_name]: Severe gravitational anomalies of unheard of scope have been detected in the local volume. Size and intensity of anomalies are increasing exponentially. Within the hour, a newborn black hole will have consumed everything in this sector." diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm index 40706050003..a7e6fb5abc5 100644 --- a/code/game/gamemodes/extended/extended.dm +++ b/code/game/gamemodes/extended/extended.dm @@ -5,3 +5,4 @@ round_description = "Just have fun and role-play!" extended_round_description = "There are no antagonists during extended, unless an admin decides to be cheeky. Just play your character, mess around with your job, and have fun." addantag_allowed = ADDANTAG_ADMIN // No add antag vote allowed on extended, except when manually called by admins. + probability = 1 diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 62299631a4e..8fca9e3f5cf 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -10,6 +10,7 @@ var/global/list/additional_antag_types = list() var/votable = TRUE var/probability = 0 + var/available_by_default = TRUE var/required_players = 0 // Minimum players for round to start if voted in. var/required_enemies = 0 // Minimum antagonists for round to start. var/end_on_antag_death = FALSE // Round will end when all antagonists are dead. @@ -473,7 +474,7 @@ var/global/list/additional_antag_types = list() /decl/game_mode/proc/create_antagonists() - if(!config.traitor_scaling) + if(!get_config_value(/decl/config/toggle/traitor_scaling)) antag_scaling_coeff = 0 if(length(associated_antags)) @@ -572,7 +573,7 @@ var/global/list/additional_antag_types = list() if(!player || !player.current) return - if(config.objectives_disabled == CONFIG_OBJECTIVE_NONE || !player.objectives.len) + if(get_config_value(/decl/config/enum/objectives_disabled) == CONFIG_OBJECTIVE_NONE || !player.objectives.len) return var/obj_count = 1 diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm index 802d83c3c00..8fd44e1744d 100644 --- a/code/game/gamemodes/game_mode_latespawn.dm +++ b/code/game/gamemodes/game_mode_latespawn.dm @@ -15,7 +15,7 @@ if(SSevac.evacuation_controller && (SSevac.evacuation_controller.is_evacuating() || SSevac.evacuation_controller.has_evacuated())) return FALSE // Don't create auto-antags in the last twenty minutes of the round, but only if the vote interval is longer than 20 minutes - if((config.vote_autotransfer_interval > 20 MINUTES) && (transfer_controller.time_till_transfer_vote() < 20 MINUTES)) + if((get_config_value(/decl/config/num/vote_autotransfer_interval) > 20 MINUTES) && (transfer_controller.time_till_transfer_vote() < 20 MINUTES)) return FALSE return TRUE diff --git a/code/game/gamemodes/godmode/form_items/narsie_items.dm b/code/game/gamemodes/godmode/form_items/narsie_items.dm index ff6855bcf6d..b191ef022be 100644 --- a/code/game/gamemodes/godmode/form_items/narsie_items.dm +++ b/code/game/gamemodes/godmode/form_items/narsie_items.dm @@ -56,7 +56,7 @@ if(ismob(a)) var/mob/M = a if(M.stat != DEAD) - events_repository.register(/decl/observ/death, M,src,/obj/item/twohanded/fireaxe/cult/proc/gain_power) + events_repository.register(/decl/observ/death, M,src, TYPE_PROC_REF(/obj/item/twohanded/fireaxe/cult, gain_power)) spawn(30) events_repository.unregister(/decl/observ/death, M,src) return ..() @@ -74,4 +74,4 @@ amount_per_transfer_from_this = 10 /obj/item/chems/drinks/zombiedrink/populate_reagents() - reagents.add_reagent(/decl/material/liquid/zombie, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/zombie, reagents.maximum_volume) diff --git a/code/game/gamemodes/godmode/form_items/starlight_structures.dm b/code/game/gamemodes/godmode/form_items/starlight_structures.dm index 406e463bb7e..51f3c734282 100644 --- a/code/game/gamemodes/godmode/form_items/starlight_structures.dm +++ b/code/game/gamemodes/godmode/form_items/starlight_structures.dm @@ -143,7 +143,7 @@ for(var/l in get_turf(linked_god)) if(istype(l, /mob/living/starlight_soul)) to_chat(l, "\The [src] is looking for a soul to become a [looking_for]. Accept? (Yes)") - addtimer(CALLBACK(src, .proc/stop_looking_for, FALSE), 30 SECONDS) + addtimer(CALLBACK(src, PROC_REF(stop_looking_for), FALSE), 30 SECONDS) show_browser(linked_god, null, "window=gateway") return TOPIC_HANDLED diff --git a/code/game/gamemodes/godmode/god_altar.dm b/code/game/gamemodes/godmode/god_altar.dm index 22c29581d91..34ddbfa847d 100644 --- a/code/game/gamemodes/godmode/god_altar.dm +++ b/code/game/gamemodes/godmode/god_altar.dm @@ -67,9 +67,9 @@ START_PROCESSING(SSobj, src) target = L update_icon() - events_repository.register(/decl/observ/destroyed, L,src,/obj/structure/deity/altar/proc/remove_target) - events_repository.register(/decl/observ/moved, L, src, /obj/structure/deity/altar/proc/remove_target) - events_repository.register(/decl/observ/death, L, src, /obj/structure/deity/altar/proc/remove_target) + events_repository.register(/decl/observ/destroyed, L,src, TYPE_PROC_REF(/obj/structure/deity/altar, remove_target)) + events_repository.register(/decl/observ/moved, L, src, TYPE_PROC_REF(/obj/structure/deity/altar, remove_target)) + events_repository.register(/decl/observ/death, L, src, TYPE_PROC_REF(/obj/structure/deity/altar, remove_target)) /obj/structure/deity/altar/proc/remove_target() STOP_PROCESSING(SSobj, src) diff --git a/code/game/gamemodes/godmode/god_pylon.dm b/code/game/gamemodes/godmode/god_pylon.dm index 14b50ce830d..cbbd31413fa 100644 --- a/code/game/gamemodes/godmode/god_pylon.dm +++ b/code/game/gamemodes/godmode/god_pylon.dm @@ -33,7 +33,7 @@ return to_chat(L, "You place your hands on \the [src], feeling yourself intune to its vibrations.") intuned += L - events_repository.register(/decl/observ/destroyed, L,src,/obj/structure/deity/pylon/proc/remove_intuned) + events_repository.register(/decl/observ/destroyed, L,src, TYPE_PROC_REF(/obj/structure/deity/pylon, remove_intuned)) /obj/structure/deity/pylon/proc/remove_intuned(var/mob/living/L) if(!(L in intuned)) diff --git a/code/game/gamemodes/godmode/god_trap.dm b/code/game/gamemodes/godmode/god_trap.dm index 323b3bf2e15..bcab3d15328 100644 --- a/code/game/gamemodes/godmode/god_trap.dm +++ b/code/game/gamemodes/godmode/god_trap.dm @@ -5,7 +5,7 @@ /obj/structure/deity/trap/Initialize() . = ..() - events_repository.register(/decl/observ/entered, get_turf(src),src,/obj/structure/deity/trap/proc/trigger) + events_repository.register(/decl/observ/entered, get_turf(src),src, TYPE_PROC_REF(/obj/structure/deity/trap, trigger)) /obj/structure/deity/trap/Destroy() events_repository.unregister(/decl/observ/entered, get_turf(src),src) @@ -14,7 +14,7 @@ /obj/structure/deity/trap/Move() events_repository.unregister(/decl/observ/entered, get_turf(src),src) . = ..() - events_repository.register(/decl/observ/entered, get_turf(src), src, /obj/structure/deity/trap/proc/trigger) + events_repository.register(/decl/observ/entered, get_turf(src), src, TYPE_PROC_REF(/obj/structure/deity/trap, trigger)) /obj/structure/deity/trap/attackby(obj/item/W, mob/user) trigger(user) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index 828322db8c9..35e25dc7f73 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -10,6 +10,8 @@ required_players = 15 // Definitely not good for low-pop votable = 1 shuttle_delay = 2 + available_by_default = FALSE + var/next_wave = INFINITY // Set in post_setup() correctly to take into account potential longer pre-start times. var/alert_sent = 0 var/meteor_severity = 1 // Slowly increases the tension at the beginning of meteor strikes. Prevents "tunguska on first wave" style problems. diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index f5b19a3e213..d774f6c9562 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -215,7 +215,7 @@ var/global/list/meteors_cataclysm = list(\ /obj/effect/meteor/proc/make_debris() if(meteordrop && dropamt) for(var/throws = dropamt, throws > 0, throws--) - addtimer(CALLBACK(new meteordrop(get_turf(src)), /atom/movable/proc/throw_at, dest, 5, 10), 0) + addtimer(CALLBACK(new meteordrop(get_turf(src)), TYPE_PROC_REF(/atom/movable, throw_at), dest, 5, 10), 0) /obj/effect/meteor/proc/meteor_effect() if(heavy) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 663767d11c0..410e50873a8 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -12,14 +12,15 @@ var/global/list/nuke_disks = list() required_players = 15 required_enemies = 1 end_on_antag_death = FALSE - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level + probability = 1 associated_antags = list(/decl/special_role/mercenary) cinematic_icon_states = list( "intro_nuke" = 35, "summary_nukewin", "summary_nukefail" ) + var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station + var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level //checks if L has a nuke disk on their person /decl/game_mode/nuclear/proc/check_mob(mob/living/L) @@ -30,7 +31,7 @@ var/global/list/nuke_disks = list() /decl/game_mode/nuclear/declare_completion() var/decl/special_role/merc = GET_DECL(/decl/special_role/mercenary) - if(config.objectives_disabled == CONFIG_OBJECTIVE_NONE || (merc && !merc.global_objectives.len)) + if(get_config_value(/decl/config/enum/objectives_disabled) == CONFIG_OBJECTIVE_NONE || (merc && !merc.global_objectives.len)) ..() return var/disk_rescued = TRUE diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 4e1d0b54e6c..72792403db1 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -7,3 +7,4 @@ required_enemies = 1 end_on_antag_death = FALSE associated_antags = list(/decl/special_role/wizard) + probability = 1 diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index c6466ac626c..0269e5f0bee 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -36,7 +36,7 @@ var/forced_spawnpoint // If set to a spawnpoint name, will use that spawn point for joining as this job. var/hud_icon // icon used for Sec HUD overlay - //Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access + //Job access. The use of minimal_access or access is determined by a config setting: jobs_have_minimal_access var/list/minimal_access = list() // Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population) var/list/access = list() // Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!) @@ -166,7 +166,7 @@ . = outfit.equip_outfit(H, alt_title || title, equip_adjustments = (OUTFIT_ADJUSTMENT_SKIP_POST_EQUIP|OUTFIT_ADJUSTMENT_SKIP_ID_PDA|additional_skips), job = src, rank = grade) /datum/job/proc/get_access() - if(minimal_access.len && (!config || config.jobs_have_minimal_access)) + if(minimal_access.len && get_config_value(/decl/config/toggle/on/jobs_have_minimal_access)) return minimal_access?.Copy() return access?.Copy() @@ -175,7 +175,7 @@ return (available_in_days(C) == 0) //Available in 0 days = available right now = player is old enough to play. /datum/job/proc/available_in_days(client/C) - if(C && config.use_age_restriction_for_jobs && isnull(C.holder) && isnum(C.player_age) && isnum(minimal_player_age)) + if(C && get_config_value(/decl/config/num/use_age_restriction_for_jobs) && isnull(C.holder) && isnum(C.player_age) && isnum(minimal_player_age)) return max(0, minimal_player_age - C.player_age) return 0 diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index 771dc6e7423..e8e49a0f68a 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -3,7 +3,7 @@ var/global/list/whitelist = list() /hook/startup/proc/loadWhitelist() - if(config.usewhitelist) + if(get_config_value(/decl/config/toggle/usewhitelist)) load_whitelist() return 1 @@ -20,8 +20,8 @@ var/global/list/whitelist = list() var/global/list/alien_whitelist = list() /hook/startup/proc/loadAlienWhitelist() - if(config.usealienwhitelist) - if(config.usealienwhitelistSQL) + if(get_config_value(/decl/config/toggle/use_alien_whitelist)) + if(get_config_value(/decl/config/toggle/use_alien_whitelist_sql)) if(!load_alienwhitelistSQL()) to_world_log("Could not load alienwhitelist via SQL") else @@ -74,7 +74,7 @@ var/global/list/alien_whitelist = list() var/decl/language/L = species if(L.flags & LANG_FLAG_RESTRICTED) return FALSE - if(!config.usealienwhitelist || !(L.flags & LANG_FLAG_WHITELISTED)) + if(!get_config_value(/decl/config/toggle/use_alien_whitelist) || !(L.flags & LANG_FLAG_WHITELISTED)) return TRUE return whitelist_lookup(L.name, M.ckey) @@ -82,7 +82,7 @@ var/global/list/alien_whitelist = list() var/decl/species/S = species if(S.spawn_flags & SPECIES_IS_RESTRICTED) return FALSE - if(!config.usealienwhitelist || !(S.spawn_flags & SPECIES_IS_WHITELISTED)) + if(!get_config_value(/decl/config/toggle/use_alien_whitelist) || !(S.spawn_flags & SPECIES_IS_WHITELISTED)) return TRUE return whitelist_lookup(S.get_root_species_name(M), M.ckey) @@ -92,7 +92,7 @@ var/global/list/alien_whitelist = list() if(!alien_whitelist) return FALSE - if(config.usealienwhitelistSQL) + if(get_config_value(/decl/config/toggle/use_alien_whitelist_sql)) //SQL Whitelist if(!(ckey in alien_whitelist)) return FALSE diff --git a/code/game/machinery/_machines_base/machine_construction/pipe.dm b/code/game/machinery/_machines_base/machine_construction/pipe.dm index 5ea202b73ea..4667327dd0e 100644 --- a/code/game/machinery/_machines_base/machine_construction/pipe.dm +++ b/code/game/machinery/_machines_base/machine_construction/pipe.dm @@ -44,7 +44,7 @@ return TRUE playsound(get_turf(machine), 'sound/items/Welder2.ogg', 50, 1) TRANSFER_STATE(/decl/machine_construction/default/deconstructed) - machine.visible_message(SPAN_NOTICE("\The [user] unwelds \the [src].")) + machine.visible_message(SPAN_NOTICE("\The [user] unwelds \the [machine].")) machine.dismantle() /decl/machine_construction/pipe/welder/mechanics_info() diff --git a/code/game/machinery/_machines_base/machinery_components.dm b/code/game/machinery/_machines_base/machinery_components.dm index 7d7dd280131..6ac1793eba4 100644 --- a/code/game/machinery/_machines_base/machinery_components.dm +++ b/code/game/machinery/_machines_base/machinery_components.dm @@ -152,7 +152,7 @@ var/global/list/machine_path_to_circuit_type CRASH("Tried to insert \a '[part]' twice in \the [src] ([x], [y], [z])!") LAZYADD(component_parts, part) part.on_install(src) - events_repository.register(/decl/observ/destroyed, part, src, .proc/component_destroyed) + events_repository.register(/decl/observ/destroyed, part, src, PROC_REF(component_destroyed)) else if(ispath(part)) LAZYINITLIST(uncreated_component_parts) uncreated_component_parts[part] += 1 diff --git a/code/game/machinery/_machines_base/machinery_power.dm b/code/game/machinery/_machines_base/machinery_power.dm index 338a9a7a452..9e3aaff8a48 100644 --- a/code/game/machinery/_machines_base/machinery_power.dm +++ b/code/game/machinery/_machines_base/machinery_power.dm @@ -87,10 +87,10 @@ This is /obj/machinery level code to properly manage power usage from the area. if(MACHINE_UPDATES_FROM_AREA_POWER) var/area/my_area = get_area(src) if(istype(my_area)) - events_repository.register(/decl/observ/area_power_change, my_area, src, .proc/power_change) + events_repository.register(/decl/observ/area_power_change, my_area, src, PROC_REF(power_change)) if(mapload) // currently outside mapload, movables trigger loc/Entered(src, null) in ..(), which will update power. REPORT_POWER_CONSUMPTION_CHANGE(0, get_power_usage()) - events_repository.register(/decl/observ/moved, src, src, .proc/update_power_on_move) + events_repository.register(/decl/observ/moved, src, src, PROC_REF(update_power_on_move)) power_init_complete = TRUE . = ..() @@ -99,8 +99,8 @@ This is /obj/machinery level code to properly manage power usage from the area. if(MACHINE_UPDATES_FROM_AREA_POWER) var/area/my_area = get_area(src) if(istype(my_area)) - events_repository.unregister(/decl/observ/area_power_change, my_area, src, .proc/power_change) - events_repository.unregister(/decl/observ/moved, src, src, .proc/update_power_on_move) + events_repository.unregister(/decl/observ/area_power_change, my_area, src, PROC_REF(power_change)) + events_repository.unregister(/decl/observ/moved, src, src, PROC_REF(update_power_on_move)) REPORT_POWER_CONSUMPTION_CHANGE(get_power_usage(), 0) . = ..() @@ -120,11 +120,11 @@ This is /obj/machinery level code to properly manage power usage from the area. if(old_area) old_area.power_use_change(power, 0, power_channel) if(MACHINE_UPDATES_FROM_AREA_POWER) - events_repository.unregister(/decl/observ/area_power_change, old_area, src, .proc/power_change) + events_repository.unregister(/decl/observ/area_power_change, old_area, src, PROC_REF(power_change)) if(new_area) new_area.power_use_change(0, power, power_channel) if(MACHINE_UPDATES_FROM_AREA_POWER) - events_repository.register(/decl/observ/area_power_change, new_area, src, .proc/power_change) + events_repository.register(/decl/observ/area_power_change, new_area, src, PROC_REF(power_change)) power_change() // Force check in case the old area was powered and the new one isn't or vice versa. diff --git a/code/game/machinery/_machines_base/machinery_public_vars.dm b/code/game/machinery/_machines_base/machinery_public_vars.dm index 27ef2d83efb..d1288ef7817 100644 --- a/code/game/machinery/_machines_base/machinery_public_vars.dm +++ b/code/game/machinery/_machines_base/machinery_public_vars.dm @@ -62,7 +62,7 @@ Must be implemented by subtypes. return islist(new_value) if(IC_FORMAT_INDEX) return isnum(new_value) - + /* Listener registration. You must unregister yourself if you are destroyed; the owner being destroyed will be handled automatically. */ @@ -75,7 +75,7 @@ Listener registration. You must unregister yourself if you are destroyed; the ow return // Can try and register, but updates aren't coming if(!listeners[owner]) listeners[owner] = list() - events_repository.register(/decl/observ/destroyed, owner, src, .proc/owner_destroyed) + events_repository.register(/decl/observ/destroyed, owner, src, PROC_REF(owner_destroyed)) LAZYADD(listeners[owner][listener], registered_proc) return TRUE diff --git a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm index ed87e48ab3f..7eb99203b77 100644 --- a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm +++ b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm @@ -4,7 +4,7 @@ name = "scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) base_type = /obj/item/stock_parts/scanning_module @@ -14,7 +14,7 @@ name = "micro-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "micro_mani" - origin_tech = "{'materials':1,'programming':1}" + origin_tech = @'{"materials":1,"programming":1}' material = /decl/material/solid/metal/steel base_type = /obj/item/stock_parts/manipulator w_class = ITEM_SIZE_TINY @@ -23,7 +23,7 @@ name = "micro-laser" desc = "A tiny laser used in certain devices." icon_state = "micro_laser" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) base_type = /obj/item/stock_parts/micro_laser @@ -33,7 +33,7 @@ name = "matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "matter_bin" - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel base_type = /obj/item/stock_parts/matter_bin @@ -41,7 +41,7 @@ name = "capacitor" desc = "A basic capacitor used in the construction of a variety of devices." icon_state = "capacitor" - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) var/charge = 0 @@ -69,7 +69,7 @@ name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "advanced_scan_module" - origin_tech = "{'magnets':3}" + origin_tech = @'{"magnets":3}' rating = 2 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) @@ -78,7 +78,7 @@ name = "nano-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "nano_mani" - origin_tech = "{'materials':3,'programming':2}" + origin_tech = @'{"materials":3,"programming":2}' rating = 2 material = /decl/material/solid/metal/steel @@ -86,7 +86,7 @@ name = "high-power micro-laser" desc = "A tiny laser used in certain devices." icon_state = "high_micro_laser" - origin_tech = "{'magnets':3}" + origin_tech = @'{"magnets":3}' rating = 2 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) @@ -95,14 +95,14 @@ name = "advanced matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "advanced_matter_bin" - origin_tech = "{'materials':3}" + origin_tech = @'{"materials":3}' rating = 2 material = /decl/material/solid/metal/steel /obj/item/stock_parts/capacitor/adv name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." - origin_tech = "{'powerstorage':3}" + origin_tech = @'{"powerstorage":3}' icon_state = "advanced_capacitor" rating = 2 @@ -112,7 +112,7 @@ name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." icon_state = "phasic_scan_module" - origin_tech = "{'magnets':5}" + origin_tech = @'{"magnets":5}' rating = 3 material = /decl/material/solid/metal/steel matter = list( @@ -124,7 +124,7 @@ name = "pico-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "pico_mani" - origin_tech = "{'materials':5,'programming':2}" + origin_tech = @'{"materials":5,"programming":2}' rating = 3 material = /decl/material/solid/metal/steel @@ -132,7 +132,7 @@ name = "ultra-high-power micro-laser" icon_state = "ultra_high_micro_laser" desc = "A tiny laser used in certain devices." - origin_tech = "{'magnets':5}" + origin_tech = @'{"magnets":5}' rating = 3 material = /decl/material/solid/metal/steel matter = list( @@ -144,7 +144,7 @@ name = "super matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "super_matter_bin" - origin_tech = "{'materials':5}" + origin_tech = @'{"materials":5}' rating = 3 material = /decl/material/solid/metal/steel @@ -152,7 +152,7 @@ name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." icon_state = "super_capacitor" - origin_tech = "{'powerstorage':5,'materials':4}" + origin_tech = @'{"powerstorage":5,"materials":4}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -166,7 +166,7 @@ name = "subspace ansible" icon_state = "subspace_ansible" desc = "A compact module capable of sensing extradimensional activity." - origin_tech = "{'programming':3,'magnets':5,'materials':4,'wormholes':2}" + origin_tech = @'{"programming":3,"magnets":5,"materials":4,"wormholes":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) @@ -174,7 +174,7 @@ name = "hyperwave filter" icon_state = "hyperwave_filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." - origin_tech = "{'programming':4,'magnets':2}" + origin_tech = @'{"programming":4,"magnets":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) @@ -182,7 +182,7 @@ name = "subspace amplifier" icon_state = "subspace_amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." - origin_tech = "{'programming':3,'magnets':4,'materials':4,'wormholes':2}" + origin_tech = @'{"programming":3,"magnets":4,"materials":4,"wormholes":2}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT, @@ -193,7 +193,7 @@ name = "subspace treatment disk" icon_state = "treatment_disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." - origin_tech = "{'programming':3,'magnets':2,'materials':5,'wormholes':2}" + origin_tech = @'{"programming":3,"magnets":2,"materials":5,"wormholes":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) @@ -201,7 +201,7 @@ name = "subspace wavelength analyzer" icon_state = "wavelength_analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." - origin_tech = "{'programming':3,'magnets':4,'materials':4,'wormholes':2}" + origin_tech = @'{"programming":3,"magnets":4,"materials":4,"wormholes":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT) @@ -209,7 +209,7 @@ name = "ansible crystal" icon_state = "ansible_crystal" desc = "A crystal made from pure glass used to transmit laser databursts to subspace." - origin_tech = "{'magnets':4,'materials':4,'wormholes':2}" + origin_tech = @'{"magnets":4,"materials":4,"wormholes":2}' material = /decl/material/solid/glass matter = list( /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, @@ -220,7 +220,7 @@ name = "subspace transmitter" icon_state = "subspace_transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." - origin_tech = "{'magnets':5,'materials':5,'wormholes':3}" + origin_tech = @'{"magnets":5,"materials":5,"wormholes":3}' material = /decl/material/solid/glass matter = list( /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/machinery/_machines_base/stock_parts/power/battery.dm b/code/game/machinery/_machines_base/stock_parts/power/battery.dm index b1ac9b50f09..f883e307f14 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/battery.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/battery.dm @@ -43,7 +43,7 @@ if(cell) return cell = new_cell - events_repository.register(/decl/observ/destroyed, cell, src, .proc/remove_cell) + events_repository.register(/decl/observ/destroyed, cell, src, PROC_REF(remove_cell)) if(!machine) machine = loc if(istype(machine)) diff --git a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm index c183753f25e..20d892e14ea 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm @@ -72,16 +72,16 @@ terminal = new_terminal terminal.master = src - events_repository.register(/decl/observ/destroyed, terminal, src, .proc/unset_terminal) + events_repository.register(/decl/observ/destroyed, terminal, src, PROC_REF(unset_terminal)) terminal.queue_icon_update() - set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), machine, .proc/machine_moved, get_area(src)) + set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), machine, PROC_REF(machine_moved), get_area(src)) set_status(machine, PART_STAT_CONNECTED) start_processing(machine) /obj/item/stock_parts/power/terminal/proc/machine_moved(var/obj/machinery/machine, var/turf/old_loc, var/turf/new_loc) if(!terminal) - events_repository.unregister(/decl/observ/moved, machine, src, .proc/machine_moved) + events_repository.unregister(/decl/observ/moved, machine, src, PROC_REF(machine_moved)) return if(istype(new_loc) && (terminal.loc == get_step(new_loc, terminal_dir))) return // This location is fine diff --git a/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm b/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm index 3ea9f96f1fa..e9d4feec331 100644 --- a/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm +++ b/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm @@ -15,7 +15,7 @@ if(!buffer) buffer = data if(latency) - addtimer(CALLBACK(src, .proc/transmit), latency) + addtimer(CALLBACK(src, PROC_REF(transmit)), latency) else transmit() else @@ -53,7 +53,7 @@ start_processing(machine) for(var/thing in transmit_on_change) var/decl/public_access/public_variable/variable = transmit_on_change[thing] - variable.register_listener(src, machine, .proc/var_changed) + variable.register_listener(src, machine, PROC_REF(var_changed)) /obj/item/stock_parts/radio/transmitter/basic/on_uninstall(obj/machinery/machine) for(var/thing in transmit_on_change) @@ -93,7 +93,7 @@ if(!is_valid_event(machine, event)) event = null if(event) - event.register_listener(src, machine, .proc/trigger_event) + event.register_listener(src, machine, PROC_REF(trigger_event)) /obj/item/stock_parts/radio/transmitter/on_event/on_uninstall(obj/machinery/machine) if(event) diff --git a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm index 22b01cce5db..b1aa3c32f90 100644 --- a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm +++ b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm @@ -2,7 +2,7 @@ name = "console screen" desc = "Used in the construction of computers and other devices with an interactive screen." icon_state = "output" - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/fiberglass base_type = /obj/item/stock_parts/console_screen part_flags = PART_FLAG_HAND_REMOVE @@ -22,7 +22,7 @@ name = "input controller" desc = "A standard part required by many machines to recieve user input." icon_state = "input" - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/organic/plastic base_type = /obj/item/stock_parts/keyboard part_flags = PART_FLAG_HAND_REMOVE diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index a866db0d66e..690b0344306 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -64,7 +64,7 @@ uncreated_component_parts = list(/obj/item/stock_parts/power/apc = 1) construct_state = /decl/machine_construction/wall_frame/panel_closed wires = /datum/wires/alarm - directional_offset = "{'NORTH':{'y':-21}, 'SOUTH':{'y':21}, 'EAST':{'x':-21}, 'WEST':{'x':21}}" + directional_offset = @'{"NORTH":{"y":-21}, "SOUTH":{"y":21}, "EAST":{"x":-21}, "WEST":{"x":21}}' var/alarm_id = null var/breach_detection = 1 // Whether to use automatic breach detection or not @@ -148,7 +148,8 @@ return // spawned in nullspace, presumably as a prototype for construction purposes. area_uid = alarm_area.uid - // breathable air according to human/Life() + // breathable air according to default human species + // TODO: make it use map default species? var/decl/material/gas_mat = GET_DECL(/decl/material/gas/oxygen) TLV[gas_mat.gas_name] = list(16, 19, 135, 140) // Partial pressure, kpa gas_mat = GET_DECL(/decl/material/gas/carbon_dioxide) @@ -797,13 +798,13 @@ if(old_area && old_area == alarm_area) alarm_area = null area_uid = null - events_repository.unregister(/decl/observ/name_set, old_area, src, .proc/change_area_name) + events_repository.unregister(/decl/observ/name_set, old_area, src, PROC_REF(change_area_name)) if(new_area) ASSERT(isnull(alarm_area)) alarm_area = new_area area_uid = new_area.uid change_area_name(alarm_area, null, alarm_area.name) - events_repository.register(/decl/observ/name_set, alarm_area, src, .proc/change_area_name) + events_repository.register(/decl/observ/name_set, alarm_area, src, PROC_REF(change_area_name)) for(var/device_tag in alarm_area.air_scrub_names + alarm_area.air_vent_names) send_signal(device_tag, list()) // ask for updates; they initialized before us and we didn't get the data @@ -826,7 +827,7 @@ FIRE ALARM frame_type = /obj/item/frame/fire_alarm uncreated_component_parts = list(/obj/item/stock_parts/power/apc = 1) construct_state = /decl/machine_construction/wall_frame/panel_closed - directional_offset = "{'NORTH':{'y':-21}, 'SOUTH':{'y':21}, 'EAST':{'x':21}, 'WEST':{'x':-21}}" + directional_offset = @'{"NORTH":{"y":-21}, "SOUTH":{"y":21}, "EAST":{"x":21}, "WEST":{"x":-21}}' var/detecting = TRUE var/working = TRUE @@ -844,38 +845,31 @@ FIRE ALARM var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) to_chat(user, "The current alert level is [security_state.current_security_level.name].") -/obj/machinery/firealarm/proc/get_cached_overlay(key) - if(!LAZYACCESS(overlays_cache, key)) - var/state - switch(key) - if(/decl/machine_construction/wall_frame/panel_open) - state = "b2" - if(/decl/machine_construction/wall_frame/no_wires) - state = "b1" - if(/decl/machine_construction/wall_frame/no_circuit) - state = "b0" - else - state = key - LAZYSET(overlays_cache, key, image(icon, state)) - return overlays_cache[key] - /obj/machinery/firealarm/on_update_icon() - overlays.Cut() + cut_overlays() icon_state = "casing" if(construct_state && !istype(construct_state, /decl/machine_construction/wall_frame/panel_closed)) - overlays += get_cached_overlay(construct_state.type) + var/construct_icon_state + switch(construct_state.type) + if(/decl/machine_construction/wall_frame/panel_open) + construct_icon_state = "b2" + if(/decl/machine_construction/wall_frame/no_wires) + construct_icon_state = "b1" + if(/decl/machine_construction/wall_frame/no_circuit) + construct_icon_state = "b0" + add_overlay(construct_icon_state) set_light(0) return if(stat & BROKEN) - overlays += get_cached_overlay("broken") + add_overlay("broken") set_light(0) else if(stat & NOPOWER) - overlays += get_cached_overlay("unpowered") + add_overlay("unpowered") set_light(0) else if(!detecting) - overlays += get_cached_overlay("fire1") + add_overlay("fire1") set_light(2, 0.25, COLOR_RED) else if(isContactLevel(z)) var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) @@ -886,14 +880,14 @@ FIRE ALARM if(sl.alarm_appearance.alarm_icon) var/image/alert1 = image(sl.icon, sl.alarm_appearance.alarm_icon) alert1.color = sl.alarm_appearance.alarm_icon_color - overlays |= alert1 + add_overlay(alert1) if(sl.alarm_appearance.alarm_icon_twotone) var/image/alert2 = image(sl.icon, sl.alarm_appearance.alarm_icon_twotone) alert2.color = sl.alarm_appearance.alarm_icon_twotone_color - overlays |= alert2 + add_overlay(alert2) else - overlays += get_cached_overlay("fire0") + add_overlay("fire0") /obj/machinery/firealarm/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(detecting && exposed_temperature > T0C+200) @@ -1037,7 +1031,7 @@ FIRE ALARM idle_power_usage = 2 active_power_usage = 6 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-21}, 'SOUTH':{'y':21}, 'EAST':{'x':21}, 'WEST':{'x':-21}}" + directional_offset = @'{"NORTH":{"y":-21}, "SOUTH":{"y":21}, "EAST":{"x":21}, "WEST":{"x":-21}}' var/time = 1 SECOND var/timing = FALSE var/working = TRUE diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 45aa2558c24..4dd3caeb6fd 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -32,7 +32,7 @@ /obj/machinery/meter/proc/set_target(atom/new_target) clear_target() target = new_target - events_repository.register(/decl/observ/destroyed, target, src, .proc/clear_target) + events_repository.register(/decl/observ/destroyed, target, src, PROC_REF(clear_target)) /obj/machinery/meter/proc/clear_target() if(target) diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index ecac219033c..2958d2eab9a 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -76,37 +76,33 @@ var/datum/extension/atmospherics_connection/connection = get_extension(src, /datum/extension/atmospherics_connection) connection?.update_connected_network() -/obj/machinery/portable_atmospherics/attackby(var/obj/item/W, var/mob/user) - if ((istype(W, /obj/item/tank) && !( src.destroyed ))) - if (src.holding) - return - if(!user.try_unequip(W, src)) - return - src.holding = W +/obj/machinery/portable_atmospherics/attackby(var/obj/item/used_item, var/mob/user) + if ((istype(used_item, /obj/item/tank) && !destroyed)) + if (holding) + return TRUE + if(!user.try_unequip(used_item, src)) + return TRUE + holding = used_item update_icon() - return + return TRUE - else if(IS_WRENCH(W) && !panel_open) + else if(IS_WRENCH(used_item) && !panel_open) if(disconnect()) - to_chat(user, "You disconnect \the [src] from the port.") + to_chat(user, SPAN_NOTICE("You disconnect \the [src] from the port.")) update_icon() - return - else - var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc - if(possible_port) - if(connect(possible_port)) - to_chat(user, "You connect \the [src] to the port.") - update_icon() - return - else - to_chat(user, "\The [src] failed to connect to the port.") - return - else - to_chat(user, "Nothing happens.") - return ..() - - else if (istype(W, /obj/item/scanner/gas)) - return + return TRUE + var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector) in loc + if(possible_port) + if(connect(possible_port)) + to_chat(user, SPAN_NOTICE("You connect \the [src] to the port.")) + update_icon() + return TRUE + to_chat(user, SPAN_NOTICE("\The [src] failed to connect to the port.")) + return TRUE + return ..() + + else if (istype(used_item, /obj/item/scanner/gas)) + return FALSE // allow the scanner's afterattack to run return ..() diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index a4210bcb185..fccbff4d1ed 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -29,7 +29,7 @@ /obj/item/chems/drinks/milk/smallcarton = 30, /obj/item/chems/drinks/milk = 50, /obj/item/chems/food/meat/syntiflesh = 50, - /obj/item/storage/fancy/egg_box = 300), + /obj/item/storage/box/fancy/egg_box = 300), "Nutrients" = list( /obj/item/chems/glass/bottle/eznutrient = 60, /obj/item/chems/glass/bottle/left4zed = 120, diff --git a/code/game/machinery/bodyscanner_console.dm b/code/game/machinery/bodyscanner_console.dm index f6aa9afebe7..f8864ab712e 100644 --- a/code/game/machinery/bodyscanner_console.dm +++ b/code/game/machinery/bodyscanner_console.dm @@ -27,17 +27,17 @@ src.connected = locate(/obj/machinery/bodyscanner, get_step(src, D)) if(src.connected) break - events_repository.register(/decl/observ/destroyed, connected, src, .proc/unlink_scanner) + events_repository.register(/decl/observ/destroyed, connected, src, PROC_REF(unlink_scanner)) /obj/machinery/body_scanconsole/proc/unlink_scanner(var/obj/machinery/bodyscanner/scanner) - events_repository.unregister(/decl/observ/destroyed, scanner, src, .proc/unlink_scanner) + events_repository.unregister(/decl/observ/destroyed, scanner, src, PROC_REF(unlink_scanner)) connected = null /obj/machinery/body_scanconsole/proc/FindDisplays() for(var/obj/machinery/body_scan_display/D in SSmachines.machinery) if(D.id_tag == connected.id_tag) connected_displays += D - events_repository.register(/decl/observ/destroyed, D, src, .proc/remove_display) + events_repository.register(/decl/observ/destroyed, D, src, PROC_REF(remove_display)) return !!connected_displays.len /obj/machinery/body_scanconsole/attack_hand(mob/user) @@ -134,7 +134,7 @@ /obj/machinery/body_scanconsole/proc/remove_display(var/obj/machinery/body_scan_display/display) connected_displays -= display - events_repository.unregister(/decl/observ/destroyed, display, src, .proc/remove_display) + events_repository.unregister(/decl/observ/destroyed, display, src, PROC_REF(remove_display)) /obj/machinery/body_scanconsole/Destroy() . = ..() diff --git a/code/game/machinery/bodyscanner_display.dm b/code/game/machinery/bodyscanner_display.dm index e70446dc677..2fadc8e44e9 100644 --- a/code/game/machinery/bodyscanner_display.dm +++ b/code/game/machinery/bodyscanner_display.dm @@ -12,7 +12,7 @@ stat_immune = 0 w_class = ITEM_SIZE_HUGE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' var/list/bodyscans = list() var/selected = 0 diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 97c7529dcfe..10f382fb55b 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -24,7 +24,7 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed/simple frame_type = /obj/item/frame/button required_interaction_dexterity = DEXTERITY_SIMPLE_MACHINES - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':30}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":30}, "EAST":{"x":-24}, "WEST":{"x":24}}' var/active = FALSE var/operating = FALSE diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 2560d9550ec..9993d060e65 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -10,7 +10,7 @@ anchored = TRUE movable_flags = MOVABLE_FLAG_PROXMOVE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'SOUTH':{'y':21}, 'EAST':{'x':-10}, 'WEST':{'x':10}}" + directional_offset = @'{"SOUTH":{"y":21}, "EAST":{"x":-10}, "WEST":{"x":10}}' base_type = /obj/machinery/camera uncreated_component_parts = null construct_state = /decl/machine_construction/wall_frame/panel_closed diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 3fa89eef553..efc4136a173 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -11,7 +11,7 @@ var/global/list/empty_playable_ai_cores = list() var/datum/ai_laws/laws var/obj/item/stock_parts/circuitboard/circuit - var/obj/item/mmi/brain + var/obj/item/organ/internal/brain var/authorized var/circuit_secured = FALSE @@ -139,30 +139,24 @@ var/global/list/empty_playable_ai_cores = list() if(circuit && circuit_secured) - if((istype(P, /obj/item/mmi) || istype(P, /obj/item/organ/internal/posibrain)) && wired && circuit && circuit_secured) - var/mob/living/carbon/brain/B - if(istype(P, /obj/item/mmi)) - var/obj/item/mmi/M = P - B = M.brainmob - else - var/obj/item/organ/internal/posibrain/PB = P - B = PB.brainmob - if(!B) - to_chat(user, SPAN_WARNING("Sticking an empty [P] into the frame would sort of defeat the purpose.")) + if(istype(P, /obj/item/organ/internal) && wired && circuit && circuit_secured) + var/obj/item/organ/internal/M = P + var/mob/living/brainmob = M.get_brainmob() + if(!brainmob) + to_chat(user, SPAN_WARNING("Sticking a mindless [P] into the frame would be pointless.")) return - if(B.stat == DEAD) + if(brainmob.stat == DEAD) to_chat(user, SPAN_WARNING("Sticking a dead [P] into the frame would sort of defeat the purpose.")) return - if(jobban_isbanned(B, "AI")) + if(jobban_isbanned(brainmob, "AI")) to_chat(user, SPAN_WARNING("This [P] does not seem to fit.")) return if(!user.try_unequip(P, src)) - return - if(B.mind) - clear_antag_roles(B.mind, 1) - brain = P - to_chat(usr, "Added [P].") - update_icon() + if(brainmob.mind) + clear_antag_roles(brainmob.mind, 1) + brain = P + to_chat(usr, "You connect \the [P] to the frame and slide it into the casing.") + update_icon() return TRUE if(istype(P, /obj/item/stack/material)) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index a2f9e557b49..da76d2ee20c 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -12,7 +12,7 @@ /obj/item/energy_blade/sword/toy = 200, /obj/item/gun/projectile/revolver/capgun = 200, /obj/item/gun/launcher/foam/crossbow = 200, - /obj/item/storage/fancy/crayons = 200, + /obj/item/storage/box/fancy/crayons = 200, /obj/item/toy/spinningtoy = 200, /obj/item/toy/prize/powerloader = 100, /obj/item/toy/prize/fireripley = 100, diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 5ad530c42d6..1ff7caa637e 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -13,7 +13,7 @@ var/global/list/minor_air_alarms = list() /obj/machinery/computer/atmos_alert/Initialize() . = ..() - atmosphere_alarm.register_alarm(src, /atom/proc/update_icon) + atmosphere_alarm.register_alarm(src, TYPE_PROC_REF(/atom, update_icon)) /obj/machinery/computer/atmos_alert/Destroy() atmosphere_alarm.unregister_alarm(src) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 24a04075335..d10ebf8b776 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -46,14 +46,21 @@ add_overlay(icon_keyboard ? "[icon_keyboard]_off" : "keyboard") return - if(stat & NOPOWER) + var/offline = (stat & NOPOWER) + if(!offline) + var/datum/extension/interactive/os/os = get_extension(src, /datum/extension/interactive/os) + if(os && !os.on) + offline = TRUE + + if(offline) set_light(0) if(icon_keyboard) add_overlay(image(icon,"[icon_keyboard]_off", overlay_layer)) + if(stat & BROKEN) + add_overlay(image(icon,"[icon_state]_broken", overlay_layer)) return - else - set_light(light_range_on, light_power_on, light_color) + set_light(light_range_on, light_power_on, light_color) if(stat & BROKEN) add_overlay(image(icon,"[icon_state]_broken", overlay_layer)) else diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 7419b982914..612d747c33c 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -185,7 +185,7 @@ pass.reason = reason pass.SetName("guest pass #[number]") pass.assignment = "Guest" - addtimer(CALLBACK(pass, /obj/item/card/id/guest/proc/expire), duration MINUTES, TIMER_UNIQUE) + addtimer(CALLBACK(pass, TYPE_PROC_REF(/obj/item/card/id/guest, expire)), duration MINUTES, TIMER_UNIQUE) playsound(src.loc, 'sound/machines/ping.ogg', 25, 0) . = TOPIC_REFRESH else if(!giver) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 858df3d35e4..cde979fbef0 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -64,7 +64,7 @@ var/obj/item/paper/monitorkey/MK = new(loc) // Will help make emagging the console not so easy to get away with. MK.info += "

    £%@%(*$%&(£&?*(%&£/{}" - addtimer(CALLBACK(src, /obj/machinery/computer/message_monitor/proc/UnemagConsole), 100*length(linked_server.decryptkey)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, UnemagConsole)), 100*length(linked_server.decryptkey)) message = rebootmsg update_icon() return 1 @@ -290,7 +290,7 @@ src.screen = 2 update_icon() //Time it takes to bruteforce is dependant on the password length. - addtimer(CALLBACK(src, /obj/machinery/computer/message_monitor/proc/BruteForceConsole, usr, linked_server), 100*length(linked_server.decryptkey)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, BruteForceConsole), usr, linked_server), 100*length(linked_server.decryptkey)) //Delete the request console log. if (href_list["deleter"]) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 1fad0bc8153..5c639132877 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -20,7 +20,7 @@ /obj/machinery/computer/station_alert/Initialize() alarm_monitor = new monitor_type(src) - alarm_monitor.register_alarm(src, /atom/proc/update_icon) + alarm_monitor.register_alarm(src, TYPE_PROC_REF(/atom, update_icon)) . = ..() if(monitor_type) register_monitor(new monitor_type(src)) @@ -34,7 +34,7 @@ return alarm_monitor = monitor - alarm_monitor.register_alarm(src, /atom/proc/update_icon) + alarm_monitor.register_alarm(src, TYPE_PROC_REF(/atom, update_icon)) /obj/machinery/computer/station_alert/proc/unregister_monitor() if(alarm_monitor) diff --git a/code/game/machinery/cracker.dm b/code/game/machinery/cracker.dm index 0037f028edb..b3b31d1e54b 100644 --- a/code/game/machinery/cracker.dm +++ b/code/game/machinery/cracker.dm @@ -42,19 +42,17 @@ // Produce materials. var/turf/T = get_turf(src) - if(istype(T)) - var/obj/effect/fluid/F = T.return_fluid() - if(istype(F)) - - // Drink more water! - var/consuming = min(F.reagents.total_volume, fluid_consumption_per_tick) - F.reagents.remove_any(consuming) - T.show_bubbles() - - // Gas production. - var/datum/gas_mixture/produced = new - var/gen_amt = min(1, (gas_generated_per_tick * (consuming/fluid_consumption_per_tick))) - produced.adjust_gas(/decl/material/gas/oxygen, gen_amt) - produced.adjust_gas(/decl/material/gas/hydrogen, gen_amt * 2) - produced.temperature = T20C //todo water temperature - air_contents.merge(produced) + if(istype(T) && T.reagents?.total_volume) + + // Drink more water! + var/consuming = min(T.reagents.total_volume, fluid_consumption_per_tick) + T.remove_any_reagents(consuming) + T.show_bubbles() + + // Gas production. + var/datum/gas_mixture/produced = new + var/gen_amt = min(1, (gas_generated_per_tick * (consuming/fluid_consumption_per_tick))) + produced.adjust_gas(/decl/material/gas/oxygen, gen_amt) + produced.adjust_gas(/decl/material/gas/hydrogen, gen_amt * 2) + produced.temperature = T20C //todo water temperature + air_contents.merge(produced) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index e7b001cbf3f..858a29659b9 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -16,7 +16,7 @@ density = FALSE interact_offline = 1 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-24}, 'SOUTH':{'y':32}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-24}, "SOUTH":{"y":32}, "EAST":{"x":-24}, "WEST":{"x":24}}' //Used for logging people entering cryosleep and important items they are carrying. var/list/frozen_crew = list() @@ -119,12 +119,12 @@ /obj/item/stock_parts/circuitboard/cryopodcontrol name = "circuit board (Cryogenic Oversight Console)" build_path = /obj/machinery/computer/cryopod - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' /obj/item/stock_parts/circuitboard/robotstoragecontrol name = "circuit board (Robotic Storage Console)" build_path = /obj/machinery/computer/cryopod/robot - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' //Decorative structures to go alongside cryopods. /obj/structure/cryofeed @@ -259,7 +259,7 @@ if(!control_computer) control_computer = locate(/obj/machinery/computer/cryopod) in get_area(src) if(control_computer) - events_repository.register(/decl/observ/destroyed, control_computer, src, .proc/clear_control_computer) + events_repository.register(/decl/observ/destroyed, control_computer, src, PROC_REF(clear_control_computer)) return control_computer /obj/machinery/cryopod/proc/clear_control_computer() @@ -314,14 +314,14 @@ // Also make sure there is a valid control computer /obj/machinery/cryopod/robot/despawn_occupant() var/mob/living/silicon/robot/R = occupant - if(!istype(R)) return ..() - - qdel(R.mmi) - for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc - for(var/obj/item/O in I.get_contained_external_atoms()) // the things inside the tools, if anything; mainly for janiborg trash bags - O.forceMove(R) - qdel(I) - qdel(R.module) + if(istype(R)) + R.clear_brain() + if(R.module) + for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc + for(var/obj/item/O in I.get_contained_external_atoms()) // the things inside the tools, if anything; mainly for janiborg trash bags + O.forceMove(R) + qdel(I) + qdel(R.module) . = ..() diff --git a/code/game/machinery/doors/_door.dm b/code/game/machinery/doors/_door.dm index 351cc399dca..c11d60b6718 100644 --- a/code/game/machinery/doors/_door.dm +++ b/code/game/machinery/doors/_door.dm @@ -70,7 +70,7 @@ /obj/machinery/door/Initialize(var/mapload, var/d, var/populate_parts = TRUE, var/obj/structure/door_assembly/assembly = null) if(!populate_parts) inherit_from_assembly(assembly) - set_extension(src, /datum/extension/penetration, /datum/extension/penetration/proc_call, .proc/CheckPenetration) + set_extension(src, /datum/extension/penetration, /datum/extension/penetration/proc_call, PROC_REF(CheckPenetration)) if(!begins_closed) icon_state = icon_state_open @@ -129,7 +129,7 @@ if(close_door_at && world.time >= close_door_at) if(autoclose) close_door_at = next_close_time() - INVOKE_ASYNC(src, /obj/machinery/door/proc/close) + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/door, close)) else close_door_at = 0 diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index b34b45e145f..720b6626025 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -120,7 +120,7 @@ base_type = /obj/machinery/airlock_sensor/buildable construct_state = /decl/machine_construction/wall_frame/panel_closed/simple frame_type = /obj/item/frame/button/airlock_controller_config/airlock_sensor - directional_offset = "{'NORTH':{'y':-18}, 'SOUTH':{'y':24}, 'EAST':{'x':-22}, 'WEST':{'x':22}}" + directional_offset = @'{"NORTH":{"y":-18}, "SOUTH":{"y":24}, "EAST":{"x":-22}, "WEST":{"x":22}}' var/alert = FALSE var/master_cycling = FALSE var/pressure @@ -257,7 +257,7 @@ /obj/item/stock_parts/radio/transmitter/on_event/buildable, /obj/item/stock_parts/radio/receiver/buildable, ) - directional_offset = "{'NORTH':{'y':-22}, 'SOUTH':{'y':24}, 'EAST':{'x':-20}, 'WEST':{'x':20}}" + directional_offset = @'{"NORTH":{"y":-22}, "SOUTH":{"y":24}, "EAST":{"x":-20}, "WEST":{"x":20}}' frame_type = /obj/item/frame/button/airlock_controller_config/access base_type = /obj/machinery/button/access/buildable var/command = "cycle" diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 08c9dc58434..6533978f852 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -18,7 +18,7 @@ /obj/item/stock_parts/circuitboard/airlock_electronics/secure name = "secure airlock electronics" desc = "designed to be somewhat more resistant to hacking than standard electronics." - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' secure = TRUE /obj/item/stock_parts/circuitboard/airlock_electronics/windoor diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 144f0129901..816648c4dfc 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -187,7 +187,7 @@ force_open() if(autoclose) - addtimer(CALLBACK(src, .proc/close), 15 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(close)), 15 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) return TRUE diff --git a/code/game/machinery/doors/braces.dm b/code/game/machinery/doors/braces.dm index c6ba9a1d39a..64de3129086 100644 --- a/code/game/machinery/doors/braces.dm +++ b/code/game/machinery/doors/braces.dm @@ -9,7 +9,7 @@ attack_cooldown = 2.5*DEFAULT_WEAPON_COOLDOWN melee_accuracy_bonus = -25 material = /decl/material/solid/metal/steel - origin_tech = "{'engineering':3,'materials':2}" + origin_tech = @'{"engineering":3,"materials":2}' // BRACE - Can be installed on airlock to reinforce it and keep it closed. /obj/item/airlock_brace @@ -21,7 +21,7 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) material_health_multiplier = 0.6 - origin_tech = "{'engineering':3,'materials':2}" + origin_tech = @'{"engineering":3,"materials":2}' var/obj/machinery/door/airlock/airlock = null var/obj/item/stock_parts/circuitboard/airlock_electronics/brace/electronics diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index eecf6644ddc..515dcad64c9 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -280,7 +280,7 @@ var/changed = 0 lockdown=0 // Pressure alerts - pdiff = getOPressureDifferential(src.loc) + pdiff = get_surrounding_pressure_differential(loc, src) if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF) lockdown = 1 if(!pdiff_alert) @@ -356,14 +356,22 @@ // Only opens when all areas connecting with our turf have an air alarm and are cleared /obj/machinery/door/firedoor/proc/can_safely_open() var/turf/neighbour + var/turf/myturf = loc + if(!istype(myturf)) + return TRUE for(var/dir in global.cardinal) - neighbour = get_step(src.loc, dir) - if(neighbour.c_airblock(src.loc) & AIR_BLOCKED) + neighbour = get_step(myturf, dir) + if(!neighbour) + continue + var/airblock // zeroed by ATMOS_CANPASS_TURF, declared early as microopt + ATMOS_CANPASS_TURF(airblock, neighbour, myturf) + if(airblock & AIR_BLOCKED) continue - for(var/obj/O in src.loc) + for(var/obj/O in myturf) if(istype(O, /obj/machinery/door)) continue - . |= O.c_airblock(neighbour) + ATMOS_CANPASS_MOVABLE(airblock, O, neighbour) + . |= airblock if(. & AIR_BLOCKED) continue var/area/A = get_area(neighbour) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index b757c1f7116..5cf073d173f 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -62,7 +62,7 @@ if(istype(bot)) if(density && src.check_access(bot.botcard)) open() - addtimer(CALLBACK(src, .proc/close), 50, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(close)), 50, TIMER_UNIQUE | TIMER_OVERRIDE) return var/mob/M = AM // we've returned by here if M is not a mob if (src.operating) @@ -74,7 +74,7 @@ open_timer = 50 else //secure doors close faster open_timer = 20 - addtimer(CALLBACK(src, .proc/close), open_timer, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(close)), open_timer, TIMER_UNIQUE | TIMER_OVERRIDE) return /obj/machinery/door/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) @@ -161,7 +161,7 @@ to_chat(user, SPAN_NOTICE("You short out \the [src]'s internal circuitry, locking it open!")) if (density) flick("[base_state]spark", src) - addtimer(CALLBACK(src, .proc/open), 6, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(open)), 6, TIMER_UNIQUE | TIMER_OVERRIDE) return TRUE /obj/machinery/door/emp_act(severity) diff --git a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm index 0da24e61151..019b728bb15 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm @@ -9,7 +9,7 @@ base_type = /obj/machinery/dummy_airlock_controller construct_state = /decl/machine_construction/wall_frame/panel_closed frame_type = /obj/item/frame/button/airlock_controller - directional_offset = "{'NORTH':{'y':-22}, 'SOUTH':{'y':24}, 'EAST':{'x':-22}, 'WEST':{'x':22}}" + directional_offset = @'{"NORTH":{"y":-22}, "SOUTH":{"y":24}, "EAST":{"x":-22}, "WEST":{"x":22}}' power_channel = ENVIRON //Same as airlock controller required_interaction_dexterity = DEXTERITY_TOUCHSCREENS ///Topic state used to interact remotely with the master controller's UI diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index cccac5e04ec..af526f2e0d0 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -9,7 +9,7 @@ #define TARGET_INOPEN -1 #define TARGET_OUTOPEN -2 -#define SENSOR_TOLERANCE 1 +#define SENSOR_TOLERANCE 0.5 /datum/computer/file/embedded_program/airlock var/tag_exterior_door @@ -246,7 +246,7 @@ signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing else signalPump(tag_pump_out_internal, 1, 0, target_pressure) // if going inside, pump external air out of the airlock - signalPump(tag_pump_out_external, 1, 1, 1000) // make sure the air is actually going outside + signalPump(tag_pump_out_external, 1, 1, MAX_PUMP_PRESSURE) // make sure the air is actually going outside else if(chamber_pressure <= target_pressure) state = STATE_PRESSURIZE diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 7e98869a6c5..3b4e2b99835 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -54,7 +54,7 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed frame_type = /obj/item/frame/button/airlock_controller base_type = /obj/machinery/embedded_controller/radio/simple_docking_controller - directional_offset = "{'NORTH':{'y':-22}, 'SOUTH':{'y':24}, 'EAST':{'x':-22}, 'WEST':{'x':22}}" + directional_offset = @'{"NORTH":{"y":-22}, "SOUTH":{"y":24}, "EAST":{"x":-22}, "WEST":{"x":22}}' required_interaction_dexterity = DEXTERITY_TOUCHSCREENS var/frequency = EXTERNAL_AIR_FREQ ///Icon state of the screen used by dummy controllers to match the same state diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index a39a573c195..a67c77c795f 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -5,7 +5,7 @@ desc = "A wall-mounted flashbulb device." icon = 'icons/obj/machines/flash_mounted.dmi' icon_state = "mflash1" - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED var/range = 2 //this is roughly the size of brig cell var/disable = 0 diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index 61011c1e5b3..cf19d95e2e1 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -9,7 +9,7 @@ active_power_usage = 70 anchored = TRUE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' var/lit = 0 var/on_icon = "sign_on" diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 09a65b80873..3963ca07fef 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -106,7 +106,7 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed/simple frame_type = /obj/item/frame/button/sparker base_type = /obj/machinery/sparker/buildable - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' /obj/machinery/sparker/buildable uncreated_component_parts = null diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index c4066068303..11e5d66b45e 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -167,7 +167,7 @@ admin_attack_log(user, occupant, "Gibbed the victim", "Was gibbed", "gibbed") src.occupant.ghostize() - addtimer(CALLBACK(src, .proc/finish_gibbing), gib_time) + addtimer(CALLBACK(src, PROC_REF(finish_gibbing)), gib_time) var/list/gib_products = occupant.harvest_meat() | occupant.harvest_skin() | occupant.harvest_bones() if(!length(gib_products)) @@ -200,7 +200,7 @@ if(istype(thing, /obj/item/chems/food/meat)) var/obj/item/chems/food/meat/slab = thing slab.SetName("[slab_name] [slab.name]") - slab.reagents.add_reagent(/decl/material/liquid/nutriment,slab_nutrition) + slab.add_to_reagents(/decl/material/liquid/nutriment,slab_nutrition) /obj/machinery/gibber/proc/finish_gibbing() operating = 0 diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index 9de4adb432c..6f857f92d46 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -75,10 +75,10 @@ . = ..() /obj/machinery/icecream_vat/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk, 5) - reagents.add_reagent(/decl/material/liquid/nutriment/flour, 5) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 5) - reagents.add_reagent(/decl/material/solid/ice, 5) + add_to_reagents(/decl/material/liquid/drink/milk, 5) + add_to_reagents(/decl/material/liquid/nutriment/flour, 5) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 5) + add_to_reagents(/decl/material/solid/ice, 5) /obj/machinery/icecream_vat/interface_interact(mob/user) interact(user) @@ -121,7 +121,7 @@ // if(beaker) // beaker.reagents.trans_to(I, 10) if(I.reagents.total_volume < 10) - I.reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 10 - I.reagents.total_volume) + I.add_to_reagents(/decl/material/liquid/nutriment/sugar, 10 - I.reagents.total_volume) else to_chat(user, "There is not enough icecream left!") else @@ -140,7 +140,7 @@ break if(amount) for(var/R in get_ingredient_list(make_type)) - reagents.remove_reagent(R, amount) + remove_from_reagents(R, amount) product_types[make_type] += amount var/flavour = get_flavour_name(make_type) if(make_type > 6) @@ -203,7 +203,7 @@ /obj/item/chems/food/icecream/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment, 5) + add_to_reagents(/decl/material/liquid/nutriment, 5) update_icon() /obj/item/chems/food/icecream/on_update_icon() diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index d271c631a36..39fbb0ef683 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -288,7 +288,7 @@ update_use_power(POWER_USE_ACTIVE) START_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF) - addtimer(CALLBACK(src, .proc/half_time_process), cook_time / 2) + addtimer(CALLBACK(src, PROC_REF(half_time_process)), cook_time / 2) visible_message(SPAN_NOTICE("[src] turns on."), SPAN_NOTICE("You hear a microwave.")) if(cook_dirty) @@ -410,8 +410,8 @@ reagents.clear_reagents() SSnano.update_uis(src) var/obj/item/chems/food/badrecipe/ffuu = new(src) - ffuu.reagents.add_reagent(/decl/material/solid/carbon, amount) - ffuu.reagents.add_reagent(/decl/material/liquid/bromide, amount/10) + ffuu.add_to_reagents(/decl/material/solid/carbon, amount) + ffuu.add_to_reagents(/decl/material/liquid/bromide, amount/10) return ffuu /obj/machinery/microwave/OnTopic(href, href_list) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index f574381e6c5..33a1bb173c2 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -24,7 +24,7 @@ /obj/item/stock_parts/power/apc ) base_type = /obj/machinery/light_switch - directional_offset = "{'NORTH':{'y':-20}, 'SOUTH':{'y':25}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-20}, "SOUTH":{"y":25}, "EAST":{"x":-24}, "WEST":{"x":24}}' /obj/machinery/light_switch/on on = TRUE diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 3784122183e..1ce792fa37f 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -157,7 +157,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to uncreated_component_parts = null stat_immune = 0 frame_type = /obj/item/frame/stock_offset/newscaster - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' /obj/machinery/newscaster/Initialize() . = ..() @@ -927,7 +927,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to audible_message("[src.name] beeps, \"[news_call]\"") src.alert = 1 src.update_icon() - addtimer(CALLBACK(src, .proc/reset_alert), alert_delay, TIMER_UNIQUE | TIMER_OVERRIDE) //stay alert for the full time if we get a new one + addtimer(CALLBACK(src, PROC_REF(reset_alert)), alert_delay, TIMER_UNIQUE | TIMER_OVERRIDE) //stay alert for the full time if we get a new one playsound(src.loc, 'sound/machines/twobeep.ogg', 75, 1) else audible_message("[src.name] beeps, \"Attention! Wanted issue distributed!\"") diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index b1caca7b885..0c7d2490fe0 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -41,7 +41,7 @@ var/global/bomb_set timeleft = max(timeleft - (wait / 10), 0) playsound(loc, 'sound/items/timer.ogg', 50) if(timeleft <= 0) - addtimer(CALLBACK(src, .proc/explode), 0) + addtimer(CALLBACK(src, PROC_REF(explode)), 0) SSnano.update_uis(src) /obj/machinery/nuclearbomb/attackby(obj/item/O, mob/user, params) @@ -367,18 +367,18 @@ var/global/bomb_set . = ..() global.nuke_disks |= src // Can never be quite sure that a game mode has been properly initiated or not at this point, so always register - events_repository.register(/decl/observ/moved, src, src, /obj/item/disk/nuclear/proc/check_z_level) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/item/disk/nuclear, check_z_level)) /obj/item/disk/nuclear/proc/check_z_level() if(!(istype(SSticker.mode, /decl/game_mode/nuclear))) - events_repository.unregister(/decl/observ/moved, src, src, /obj/item/disk/nuclear/proc/check_z_level) // However, when we are certain unregister if necessary + events_repository.unregister(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/item/disk/nuclear, check_z_level)) // However, when we are certain unregister if necessary return var/turf/T = get_turf(src) if(!T || isNotStationLevel(T.z)) qdel(src) /obj/item/disk/nuclear/Destroy() - events_repository.unregister(/decl/observ/moved, src, src, /obj/item/disk/nuclear/proc/check_z_level) + events_repository.unregister(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/item/disk/nuclear, check_z_level)) global.nuke_disks -= src if(!length(global.nuke_disks)) var/turf/T = pick_area_turf_by_flag(AREA_FLAG_MAINTENANCE, list(/proc/is_station_turf, /proc/not_turf_contains_dense_objects)) diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 89871af4000..2739b2fc5a3 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -21,7 +21,7 @@ power_channel = ENVIRON idle_power_usage = 10 active_power_usage = 120 // No idea what the realistic amount would be. - directional_offset = "{'NORTH':{'y':-24}, 'SOUTH':{'y':28}, 'EAST':{'x':24}, 'WEST':{'x':-24}}" + directional_offset = @'{"NORTH":{"y":-24}, "SOUTH":{"y":28}, "EAST":{"x":24}, "WEST":{"x":-24}}' /obj/machinery/oxygen_pump/Initialize() . = ..() diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 996ade02b66..4ee74cd3756 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -369,7 +369,7 @@ var/global/list/turret_icons disabled = 1 var/power = 4 - severity - addtimer(CALLBACK(src,/obj/machinery/porta_turret/proc/enable), rand(60*power,600*power)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/porta_turret, enable)), rand(60*power,600*power)) ..() diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index ba601e831bd..1326de26f89 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -132,4 +132,4 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed frame_type = /obj/item/frame/button/wall_charger - directional_offset = "{'NORTH':{'y':-24}, 'SOUTH':{'y':32}, 'EAST':{'x':-28}, 'WEST':{'x':28}}" \ No newline at end of file + directional_offset = @'{"NORTH":{"y":-24}, "SOUTH":{"y":32}, "EAST":{"x":-28}, "WEST":{"x":28}}' \ No newline at end of file diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 86dec34e44b..df55809d8f9 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -175,7 +175,7 @@ overlays = list(image(overlay_icon, overlay_state())) /obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/R) - addtimer(CALLBACK(src, .proc/go_in, R), 1) + addtimer(CALLBACK(src, PROC_REF(go_in), R), 1) /obj/machinery/recharge_station/proc/go_in(var/mob/M) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index cbbaedff580..e4ab5b9ddc3 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -47,7 +47,7 @@ var/global/req_console_information = list() uncreated_component_parts = null construct_state = /decl/machine_construction/wall_frame/panel_closed frame_type = /obj/item/frame/stock_offset/request_console - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' /obj/machinery/network/requests_console/on_update_icon() if(stat & NOPOWER) diff --git a/code/game/machinery/slide_projector.dm b/code/game/machinery/slide_projector.dm index 6a22a23f61e..96239c714a2 100644 --- a/code/game/machinery/slide_projector.dm +++ b/code/game/machinery/slide_projector.dm @@ -58,9 +58,9 @@ /obj/item/storage/slide_projector/proc/stop_projecting() if(projection) QDEL_NULL(projection) - events_repository.unregister(/decl/observ/moved, src, src, .proc/check_projections) + events_repository.unregister(/decl/observ/moved, src, src, PROC_REF(check_projections)) update_icon() - + /obj/item/storage/slide_projector/proc/project_at(turf/target) stop_projecting() if(!current_slide) @@ -72,19 +72,19 @@ break projection = new projection_type(target) projection.set_source(current_slide) - events_repository.register(/decl/observ/moved, src, src, .proc/check_projections) + events_repository.register(/decl/observ/moved, src, src, PROC_REF(check_projections)) update_icon() /obj/item/storage/slide_projector/attack_self(mob/user) interact(user) -/obj/item/storage/slide_projector/interact(mob/user) +/obj/item/storage/slide_projector/interact(mob/user) var/data = list() if(projection) data += "Disable projector" else data += "Projector inactive" - + var/table = list("", + "", + "", + "" + +/datum/character_comment/proc/deserialize_mood(var/decl/comment_mood/mood_input) + if(mood_input && !istype(mood_input)) + if(ispath(mood_input, /decl/comment_mood)) + mood_input = GET_DECL(mood_input) + else if(istext(mood_input)) + mood_input = lowertext(trim(mood_input)) + var/list/all_moods = decls_repository.get_decls_of_type(/decl/comment_mood) + for(var/mood_type in all_moods) + var/decl/comment_mood/check_mood = all_moods[mood_type] + if(lowertext(trim(check_mood.uid)) == mood_input) + mood_input = check_mood + break + if(!istype(mood_input)) + mood_input = null + else + mood_input = null + if(!mood_input) + mood_input = GET_DECL(/decl/comment_mood) + return mood_input + +/datum/character_comment/New(var/list/json_input) + + for(var/key in json_input) + try + vars[key] = json_input[key] + catch(var/exception/E) + log_error("Exception on deserializing character comment: [E]") + + // Moods are decls stored by uid, they need to be deserialized again after JSON load. + main_mood = deserialize_mood(main_mood) + if(!isnull(border_mood)) + border_mood = deserialize_mood(border_mood) + + // If we didn't have a deserialized value we must have been created today. + if(isnull(last_updated)) + last_updated = REALTIMEOFDAY + +/// Generate a list of fields to values for use in comment holder json serialization. +/datum/character_comment/proc/serialize_to_list() + . = list() + for(var/key in serialize_fields) + if(key in vars) + .[key] = vars[key] + else + log_error("Character comment attempting to serialize invalid var '[key]'") + if(istype(main_mood)) + .["main_mood"] = lowertext(main_mood.uid) + if(istype(border_mood)) + .["border_mood"] = lowertext(border_mood.uid) diff --git a/code/modules/character_info/character_info_interface.dm b/code/modules/character_info/character_info_interface.dm new file mode 100644 index 00000000000..cff728f3376 --- /dev/null +++ b/code/modules/character_info/character_info_interface.dm @@ -0,0 +1,236 @@ +#define COMMENT_CANDYSTRIPE_ONE "#343434" +#define COMMENT_CANDYSTRIPE_TWO "#454545" + +/client + var/viewing_character_info_as + var/show_comments_legend = FALSE + +/client/New() + ..() + if(get_config_value(/decl/config/toggle/allow_character_comments)) + verbs |= /client/proc/view_character_information + else + verbs -= /client/proc/view_character_information + +/client/proc/view_character_information(var/search_for as text) + + set name = "View Character Information" + set category = "OOC" + set src = usr + + // Technically we might want to show IC/OOC but the primary meat + // of the system is comments and I'm losing steam on the coding. + if(!get_config_value(/decl/config/toggle/allow_character_comments)) + to_chat(usr, SPAN_WARNING("Character information viewing is currently not enabled.")) + verbs -= /client/proc/view_character_information + return + + var/datum/character_information/comments + if(!viewing_character_info_as) + var/datum/character_information/my_comments = mob?.get_comments_record() + viewing_character_info_as = my_comments?.record_id || prefs?.comments_record_id + if(search_for) + comments = SScharacter_info.search_records(search_for) + else if(viewing_character_info_as) + comments = SScharacter_info.get_record(viewing_character_info_as) + else + to_chat(usr, SPAN_WARNING("Please either supply a search string, or set up a character slot to view your own information.")) + return + + if(islist(comments)) + if(length(comments) == 1) + comments = comments[1] + else + comments = input(usr, "Multiple matches. Which character do you wish to show?", "View Character Comments") as null|anything in comments + if(istype(comments)) + comments.display_to(usr) + else + to_chat(usr, SPAN_WARNING("There is no visible character information for that character.")) + +/datum/character_information/proc/display_to(var/mob/user) + + if(!user.client || !get_config_value(/decl/config/toggle/allow_character_comments)) + return + + if(ckey == user.ckey) + has_new_comments = FALSE + + var/list/dat = list("Viewing:[name]
    ") + var/datum/character_information/viewer = user.client.viewing_character_info_as && SScharacter_info.get_record(user.client.viewing_character_info_as, TRUE) + dat += "Viewing as:[viewer?.name || "Nobody"]
    " + dat += "

    IC Info

    " + dat += "
    [ic_info || "None supplied."]

    " + dat += "

    OOC Info

    " + dat += "
    [ooc_info || "None supplied."]

    " + dat += "

    Comments

    " + + if(!allow_comments) + dat += "
    This character page is not currently accepting or displaying comments.
    " + else + if(user.client?.show_comments_legend) + dat += "
    Hide legend
    " + dat += get_comment_mood_legend() + else + dat += "
    Show legend
    " + dat += "
    " + + var/list/other_comments = list() + var/datum/character_comment/my_comment + for(var/datum/character_comment/comment in comments) + if(viewer && comment.author_id == viewer.record_id) + my_comment = comment + else if(!comment.is_stale()) + other_comments += comment + + dat += "

    My Comment

    " + dat += "
    #SLIDESHOW") var/i = 1 for(var/obj/item/I in contents) @@ -115,7 +115,7 @@ return TOPIC_HANDLED set_slide(contents[index]) . = TOPIC_REFRESH - + if(. == TOPIC_REFRESH) interact(user) @@ -132,7 +132,7 @@ var/weakref/source /obj/effect/projection/on_update_icon() - add_filter("glow", 1, list("drop_shadow", color = COLOR_WHITE, size = 4, offset = 1,x = 0, y = 0)) + add_filter("glow", 1, list(type = "drop_shadow", color = COLOR_WHITE, size = 4, offset = 1,x = 0, y = 0)) project_icon() /obj/effect/projection/proc/project_icon() diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index fa3122725da..ef38a7cb371 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -18,7 +18,7 @@ anchored = TRUE density = FALSE idle_power_usage = 10 - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' var/mode = 1 // 0 = Blank // 1 = Shuttle timer // 2 = Arbitrary message(s) diff --git a/code/game/machinery/status_light.dm b/code/game/machinery/status_light.dm index 6f78761dd92..1827bfbd7bd 100644 --- a/code/game/machinery/status_light.dm +++ b/code/game/machinery/status_light.dm @@ -3,7 +3,7 @@ desc = "A status indicator for a combustion chamber, based on temperature." icon = 'icons/obj/machines/door_timer.dmi' icon_state = "doortimer-p" - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":32}, "WEST":{"x":-32}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED var/frequency = 1441 var/alert_temperature = 10000 diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index 81bb2c18d30..1cf28054c97 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -112,21 +112,21 @@ events_repository.unregister(/decl/observ/destroyed, suit, src) suit = new_suit if(istype(suit)) - events_repository.register(/decl/observ/destroyed, suit, src, /obj/machinery/suit_cycler/proc/loaded_item_destroyed) + events_repository.register(/decl/observ/destroyed, suit, src, TYPE_PROC_REF(/obj/machinery/suit_cycler, loaded_item_destroyed)) /obj/machinery/suit_cycler/proc/set_helmet(obj/item/new_helmet) if(istype(helmet)) events_repository.unregister(/decl/observ/destroyed, helmet, src) helmet = new_helmet if(istype(helmet)) - events_repository.register(/decl/observ/destroyed, helmet, src, /obj/machinery/suit_cycler/proc/loaded_item_destroyed) + events_repository.register(/decl/observ/destroyed, helmet, src, TYPE_PROC_REF(/obj/machinery/suit_cycler, loaded_item_destroyed)) /obj/machinery/suit_cycler/proc/set_boots(obj/item/new_boots) if(istype(boots)) events_repository.unregister(/decl/observ/destroyed, boots, src) boots = new_boots if(istype(boots)) - events_repository.register(/decl/observ/destroyed, boots, src, /obj/machinery/suit_cycler/proc/loaded_item_destroyed) + events_repository.register(/decl/observ/destroyed, boots, src, TYPE_PROC_REF(/obj/machinery/suit_cycler, loaded_item_destroyed)) /obj/machinery/suit_cycler/Initialize(mapload, d=0, populate_parts = TRUE) . = ..() @@ -399,19 +399,19 @@ if(radiation_level > 2) helmet.decontaminate() if(radiation_level > 1) - helmet.clean_blood() + helmet.clean() if(suit) if(radiation_level > 2) suit.decontaminate() if(radiation_level > 1) - suit.clean_blood() + suit.clean() if(boots) if(radiation_level > 2) boots.decontaminate() if(radiation_level > 1) - boots.clean_blood() + boots.clean() update_icon() updateUsrDialog() diff --git a/code/game/machinery/supplybeacon.dm b/code/game/machinery/supplybeacon.dm index 8bac21cabd5..b9a53e07e6e 100644 --- a/code/game/machinery/supplybeacon.dm +++ b/code/game/machinery/supplybeacon.dm @@ -109,7 +109,7 @@ if(world.time >= target_drop_time) deactivate(permanent = TRUE) command_announcement.Announce("Nyx Rapid Fabrication priority supply request #[rand(1000,9999)]-[rand(100,999)] recieved. Shipment dispatched via ballistic supply pod for immediate delivery. Have a nice day.", "Thank You For Your Patronage") - addtimer(CALLBACK(src, .proc/drop_cargo), rand(20 SECONDS, 30 SECONDS)) + addtimer(CALLBACK(src, PROC_REF(drop_cargo)), rand(20 SECONDS, 30 SECONDS)) /obj/structure/supply_beacon/proc/drop_cargo(var/drop_x, var/drop_y, var/drop_z) if(!QDELETED(src) && isturf(loc)) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 560a5b54476..1b3302440e9 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -60,7 +60,7 @@ var/global/list/singularity_beacons = list() if(prob(50)) temptext = "Double-crosser. You planned to betray us from the start. Allow us to repay the favor in kind." src.updateUsrDialog() - addtimer(CALLBACK(src, .proc/selfdestruct), rand(5, 20) SECONDS) + addtimer(CALLBACK(src, PROC_REF(selfdestruct)), rand(5, 20) SECONDS) return if(ishuman(M)) var/mob/living/carbon/human/N = M @@ -76,7 +76,7 @@ var/global/list/singularity_beacons = list() /obj/machinery/syndicate_beacon/proc/selfdestruct() selfdestructing = 1 - INVOKE_ASYNC(GLOBAL_PROC, .proc/explosion, src.loc, 1, rand(1, 3), rand(3, 8), 10) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), src.loc, 1, rand(1, 3), rand(3, 8), 10) //////////////////////////////////////// //Singularity beacon diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index da6f0f344e5..8300860c5e0 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -146,14 +146,14 @@ /obj/machinery/computer/teleporter/proc/clear_target() if(src.locked) - events_repository.unregister(/decl/observ/destroyed, locked, src, .proc/target_lost) + events_repository.unregister(/decl/observ/destroyed, locked, src, PROC_REF(target_lost)) src.locked = null if(station && station.engaged) station.disengage() /obj/machinery/computer/teleporter/proc/set_target(var/obj/O) src.locked = O - events_repository.register(/decl/observ/destroyed, locked, src, .proc/target_lost) + events_repository.register(/decl/observ/destroyed, locked, src, PROC_REF(target_lost)) /obj/machinery/computer/teleporter/Destroy() clear_target() diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 53debb1bb7a..8f8665d88c7 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -14,7 +14,7 @@ anchored = TRUE density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/enabled = 0 var/lethal = 0 var/locked = 1 @@ -202,7 +202,7 @@ else if (enabled) if (lethal) icon_state = "control_kill" - set_light(1.5, 1,"#990000") + set_light(1.5, 1,COLOR_BLOOD_RED) else icon_state = "control_stun" set_light(1.5, 1,"#ff9900") diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index 531c41e2f75..8e95c16fe0f 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -171,7 +171,7 @@ if(installed_gun && is_valid_target(target?.resolve())) var/atom/resolved_target = target.resolve() if(istype(resolved_target)) - addtimer(CALLBACK(src, .proc/fire_weapon, resolved_target), 0) + addtimer(CALLBACK(src, PROC_REF(fire_weapon), resolved_target), 0) else target = null state_machine.evaluate() @@ -379,7 +379,7 @@ to_chat(user, SPAN_WARNING("You short out \the [src]'s threat assessment circuits.")) visible_message("\The [src] hums oddly...") enabled = FALSE - addtimer(CALLBACK(src, .proc/emagged_targeting), 6 SECONDS) + addtimer(CALLBACK(src, PROC_REF(emagged_targeting)), 6 SECONDS) state_machine.evaluate() /obj/machinery/turret/proc/emagged_targeting() @@ -447,12 +447,16 @@ return TOPIC_REFRESH if(href_list["set_default"]) - var/amount = input(user, "Input an angle between [leftmost_traverse] and [rightmost_traverse] degrees. Click cancel to disable default.", "Set Default Bearing", default_bearing) as null|num + var/leftmost_default = leftmost_traverse + var/rightmost_default = rightmost_traverse + if(traverse >= 360) + leftmost_default = 0 + rightmost_default = 360 + var/amount = input(user, "Input an angle between [leftmost_default] and [rightmost_default] degrees. Click cancel to disable default.", "Set Default Bearing", default_bearing) as null|num if(isnum(amount)) - default_bearing = clamp(amount, leftmost_traverse, rightmost_traverse) + default_bearing = clamp(amount, leftmost_default, rightmost_default) else default_bearing = null - return TOPIC_REFRESH if(href_list["manual_fire"]) diff --git a/code/game/machinery/turrets/network_turret.dm b/code/game/machinery/turrets/network_turret.dm index 354aabfa800..ede8a175eef 100644 --- a/code/game/machinery/turrets/network_turret.dm +++ b/code/game/machinery/turrets/network_turret.dm @@ -144,7 +144,7 @@ name = "circuitboard (sentry turret)" board_type = "machine" build_path = /obj/machinery/turret/network - origin_tech = "{'programming':5,'combat':5,'engineering':4}" + origin_tech = @'{"programming":5,"combat":5,"engineering":4}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/scanning_module = 1, diff --git a/code/game/machinery/turrets/turret_ammo.dm b/code/game/machinery/turrets/turret_ammo.dm index c12ec98d75d..7054e5ecf23 100644 --- a/code/game/machinery/turrets/turret_ammo.dm +++ b/code/game/machinery/turrets/turret_ammo.dm @@ -3,7 +3,7 @@ desc = "A high capacity ammunition supply designed to mechanically reload magazines with bullets." icon = 'icons/obj/items/storage/ammobox.dmi' icon_state = "ammo" - origin_tech = "{'engineering':3,'combat':4}" + origin_tech = @'{"engineering":3,"combat":4}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/metal/brass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm index b43e75c873c..d52fa84c3dc 100644 --- a/code/game/machinery/vending/_vending.dm +++ b/code/game/machinery/vending/_vending.dm @@ -96,9 +96,6 @@ * product_records. */ -/obj/machinery/vending/proc/get_product_name(var/entry) - return - /obj/machinery/vending/proc/build_inventory(populate_parts = FALSE) var/list/all_products = list( list(products, CAT_NORMAL), @@ -107,7 +104,7 @@ for(var/current_list in all_products) var/category = current_list[2] for(var/entry in current_list[1]) - var/datum/stored_items/vending_products/product = new(src, entry, get_product_name(entry)) + var/datum/stored_items/vending_products/product = new(src, entry) product.price = atom_info_repository.get_combined_worth_for(entry) * markup product.category = category if(product && populate_parts) @@ -360,7 +357,7 @@ use_power_oneoff(vend_power_usage) //actuators and stuff if (icon_vend) //Show the vending animation if needed flick(icon_vend,src) - addtimer(CALLBACK(src, /obj/machinery/vending/proc/finish_vending, R), vend_delay) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/vending, finish_vending), R), vend_delay) /obj/machinery/vending/proc/do_vending_reply() set waitfor = FALSE diff --git a/code/game/machinery/vending/cigs.dm b/code/game/machinery/vending/cigs.dm index d6e3e0382e2..9395c1d076e 100644 --- a/code/game/machinery/vending/cigs.dm +++ b/code/game/machinery/vending/cigs.dm @@ -32,15 +32,15 @@ /obj/item/storage/chewables/rollable/bad = 2, /obj/item/storage/chewables/rollable/generic = 2, /obj/item/storage/chewables/rollable/fine = 2, - /obj/item/storage/fancy/cigarettes = 5, - /obj/item/storage/fancy/cigarettes/luckystars = 2, - /obj/item/storage/fancy/cigarettes/jerichos = 2, - /obj/item/storage/fancy/cigarettes/menthols = 2, - /obj/item/storage/fancy/cigarettes/carcinomas = 2, - /obj/item/storage/fancy/cigarettes/professionals = 2, - /obj/item/storage/fancy/cigarettes/cigarello = 2, - /obj/item/storage/fancy/cigarettes/cigarello/mint = 2, - /obj/item/storage/fancy/cigarettes/cigarello/variety = 2, + /obj/item/storage/box/fancy/cigarettes = 5, + /obj/item/storage/box/fancy/cigarettes/luckystars = 2, + /obj/item/storage/box/fancy/cigarettes/jerichos = 2, + /obj/item/storage/box/fancy/cigarettes/menthols = 2, + /obj/item/storage/box/fancy/cigarettes/carcinomas = 2, + /obj/item/storage/box/fancy/cigarettes/professionals = 2, + /obj/item/storage/box/fancy/cigarettes/cigarello = 2, + /obj/item/storage/box/fancy/cigarettes/cigarello/mint = 2, + /obj/item/storage/box/fancy/cigarettes/cigarello/variety = 2, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/random = 4, /obj/item/storage/chewables/tobacco = 2, @@ -62,6 +62,6 @@ contraband = list( /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/rolled/sausage = 3, - /obj/item/storage/fancy/cigar = 5, - /obj/item/storage/fancy/cigarettes/killthroat = 5 + /obj/item/storage/box/fancy/cigar = 5, + /obj/item/storage/box/fancy/cigarettes/killthroat = 5 ) diff --git a/code/game/machinery/vending/medical.dm b/code/game/machinery/vending/medical.dm index d458bf2d325..f0418da0f65 100644 --- a/code/game/machinery/vending/medical.dm +++ b/code/game/machinery/vending/medical.dm @@ -54,7 +54,7 @@ /obj/item/storage/med_pouch/toxin ) contraband = list(/obj/item/chems/syringe/antitoxin = 4,/obj/item/chems/syringe/antibiotic = 4,/obj/item/chems/pill/bromide = 1) - directional_offset = "{'NORTH':{'y':-24}, 'SOUTH':{'y':24}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-24}, "SOUTH":{"y":24}, "EAST":{"x":-24}, "WEST":{"x":24}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED /obj/machinery/vending/wallmed2 @@ -77,5 +77,5 @@ /obj/item/storage/med_pouch/radiation ) contraband = list(/obj/item/chems/pill/bromide = 3, /obj/item/chems/hypospray/autoinjector/pain = 2) - directional_offset = "{'NORTH':{'y':-24}, 'SOUTH':{'y':24}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-24}, "SOUTH":{"y":24}, "EAST":{"x":-24}, "WEST":{"x":24}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED diff --git a/code/game/machinery/vending/misc.dm b/code/game/machinery/vending/misc.dm index a158ceef2aa..652e6ec4052 100644 --- a/code/game/machinery/vending/misc.dm +++ b/code/game/machinery/vending/misc.dm @@ -26,6 +26,8 @@ markup = 0 base_type = /obj/machinery/vending/dinnerware products = list( + /obj/item/plate = 10, + /obj/item/plate/platter = 5, /obj/item/chems/glass/beaker/bowl = 2, /obj/item/chems/cooking_container/plate/bowl = 4, /obj/item/chems/cooking_container/plate = 4, diff --git a/code/game/machinery/vending/security.dm b/code/game/machinery/vending/security.dm index 5298fab79bb..eacfe377892 100644 --- a/code/game/machinery/vending/security.dm +++ b/code/game/machinery/vending/security.dm @@ -18,4 +18,4 @@ /obj/item/chems/food/donut = 12, /obj/item/storage/box/evidence = 6 ) - contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/storage/box/donut = 2) + contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/storage/box/fancy/donut = 2) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 49bdaf4bba7..2f00796334a 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -1,37 +1,169 @@ #define WASHER_STATE_CLOSED 1 -#define WASHER_STATE_FULL 2 +#define WASHER_STATE_LOADED 2 #define WASHER_STATE_RUNNING 4 #define WASHER_STATE_BLOODY 8 -// WASHER_STATE_RUNNING implies WASHER_STATE_CLOSED | WASHER_STATE_FULL +// WASHER_STATE_RUNNING implies WASHER_STATE_CLOSED | WASHER_STATE_LOADED // if you break this assumption, you must update the icon file // other states are independent. /obj/machinery/washing_machine name = "washing machine" + desc = "A commerical washing machine used to wash clothing items and linens. It requires detergent for efficient washing." icon = 'icons/obj/machines/washing_machine.dmi' icon_state = "wm_00" density = TRUE anchored = TRUE construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 + stat_immune = NOSCREEN var/state = 0 - var/gibs_ready = 0 - var/obj/crayon - var/obj/item/chems/pill/detergent/detergent + var/gibs_ready = FALSE obj_flags = OBJ_FLAG_ANCHORABLE clicksound = "button" clickvol = 40 + var/list/wash_whitelist = list(/obj/item/clothing/under, + /obj/item/clothing/mask, + /obj/item/clothing/head, + /obj/item/clothing/gloves, + /obj/item/clothing/shoes, + /obj/item/clothing/suit, + /obj/item/bedsheet, + /obj/item/underwear) + + var/max_item_size = ITEM_SIZE_LARGE + + var/list/wash_blacklist = list(/obj/item/clothing/suit/space, + /obj/item/clothing/suit/syndicatefake, + /obj/item/clothing/suit/bomb_suit, + /obj/item/clothing/suit/armor, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/smokable/cigarette, + /obj/item/clothing/head/helmet) + // Power idle_power_usage = 10 active_power_usage = 150 -/obj/machinery/washing_machine/Destroy() - QDEL_NULL(crayon) - QDEL_NULL(detergent) +/obj/machinery/washing_machine/Initialize(mapload, d, populate_parts) + create_reagents(100) + . = ..() + +/obj/machinery/washing_machine/examine(mob/user) . = ..() + to_chat(user, SPAN_NOTICE("The detergent port is [atom_flags & ATOM_FLAG_OPEN_CONTAINER ? "open" : "closed"].")) + +/obj/machinery/washing_machine/proc/wash() + if(operable()) + var/list/washing_atoms = get_contained_external_atoms() + var/amount_per_atom = FLOOR(reagents.total_volume / length(washing_atoms)) + + if(amount_per_atom > 0) + var/decl/material/smelliest = get_smelliest_reagent(reagents) + for(var/atom/A as anything in get_contained_external_atoms()) + + // Handles washing, decontamination, dyeing, etc. + reagents.trans_to(A, amount_per_atom) + + if(istype(A, /obj/item/clothing)) + var/obj/item/clothing/C = A + C.ironed_state = WRINKLES_WRINKLY + if(smelliest) + C.change_smell(smelliest) + + // Clear out whatever remains of the reagents. + reagents.clear_reagents() + + if(locate(/mob/living) in src) + gibs_ready = TRUE + + state &= ~WASHER_STATE_RUNNING + update_use_power(POWER_USE_IDLE) + +/obj/machinery/washing_machine/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/chems/pill/detergent)) + if(!(atom_flags & ATOM_FLAG_OPEN_CONTAINER)) + to_chat(user, SPAN_WARNING("Open the detergent port first!")) + return + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, SPAN_WARNING("The detergent port is full!")) + return + if(!user.try_unequip(W)) + return + // Directly transfer to the holder to avoid touch reactions. + W.reagents?.trans_to_holder(reagents, W.reagents.total_volume) + to_chat(user, SPAN_NOTICE("You dissolve \the [W] in the detergent port.")) + qdel(W) + return TRUE + + if(state & WASHER_STATE_RUNNING) + to_chat(user, SPAN_WARNING("\The [src] is currently running.")) + return TRUE + + // If the detergent port is open and the item is an open container, assume we're trying to fill the detergent port. + if(!(state & WASHER_STATE_CLOSED) && !((atom_flags & W.atom_flags) & ATOM_FLAG_OPEN_CONTAINER)) + var/list/washing_atoms = get_contained_external_atoms() + if(length(washing_atoms) < 5) + if(istype(W, /obj/item/holder)) // Mob holder + for(var/mob/living/doggy in W) + doggy.forceMove(src) + qdel(W) + state |= WASHER_STATE_LOADED + update_icon() + return TRUE + + // An empty whitelist implies all items can be washed. + else if((!length(wash_whitelist) || is_type_in_list(W, wash_whitelist)) && !is_type_in_list(W, wash_blacklist)) + if(W.w_class > max_item_size) + to_chat(user, SPAN_WARNING("\The [W] is too large for \the [src]!")) + return + if(!user.try_unequip(W, src)) + return + state |= WASHER_STATE_LOADED + update_icon() + else + to_chat(user, SPAN_WARNING("You can't put \the [W] in \the [src].")) + return + else + to_chat(user, SPAN_NOTICE("\The [src] is full.")) + return TRUE + + return ..() + +/obj/machinery/washing_machine/physical_attack_hand(mob/user) + if(state & WASHER_STATE_RUNNING) + to_chat(user, SPAN_WARNING("\The [src] is currently running.")) + return TRUE + if(state & WASHER_STATE_CLOSED) + state &= ~WASHER_STATE_CLOSED + if(gibs_ready) + gibs_ready = FALSE + var/mob/M = locate(/mob/living) in src + if(M) + M.gib() + dump_contents() + state &= ~WASHER_STATE_LOADED + update_icon() + return TRUE + state |= WASHER_STATE_CLOSED + update_icon() + return TRUE + +/obj/machinery/washing_machine/verb/climb_out() + set name = "Climb out" + set category = "Object" + set src in usr.loc + + if(!CanPhysicallyInteract(usr)) + return + if(state & WASHER_STATE_CLOSED) + to_chat(usr, SPAN_WARNING("\The [src] is closed.")) + return + if(!do_after(usr, 2 SECONDS, src)) + return + if(!(state & WASHER_STATE_CLOSED)) + usr.dropInto(loc) /obj/machinery/washing_machine/verb/start() set name = "Start Washing" @@ -41,74 +173,89 @@ if(!CanPhysicallyInteract(usr)) return - if(!anchored) - to_chat(usr, "\The [src] must be secured to the floor.") - return + start_washing(usr) +/obj/machinery/washing_machine/proc/start_washing(mob/user) if(state & WASHER_STATE_RUNNING) - to_chat(usr, "\The [src] is already running.") - return - if(!(state & WASHER_STATE_FULL)) - to_chat(usr, "Load \the [src] first!") + to_chat(user, SPAN_WARNING("\The [src] is already running!")) return if(!(state & WASHER_STATE_CLOSED)) - to_chat(usr, "You must first close the machine.") + to_chat(user, SPAN_WARNING("You must first close \the [src].")) + return + if(!(state & WASHER_STATE_LOADED)) + to_chat(user, SPAN_WARNING("Load \the [src] first!!")) + return + if(!operable()) + to_chat(user, SPAN_WARNING("\The [src] isn't functioning!")) return - if(stat & NOPOWER) - to_chat(usr, SPAN_WARNING("\The [src] is unpowered.")) + if(!reagents.total_volume) + to_chat(user, SPAN_WARNING("There are no cleaning products loaded in \the [src]!")) return + atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER + state |= WASHER_STATE_RUNNING if(locate(/mob/living) in src) state |= WASHER_STATE_BLOODY update_use_power(POWER_USE_ACTIVE) - addtimer(CALLBACK(src, /obj/machinery/washing_machine/proc/wash), 20 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/washing_machine, wash)), 20 SECONDS) -/obj/machinery/washing_machine/proc/wash() - for(var/atom/A as anything in get_contained_external_atoms()) - if(detergent) - A.clean_blood() - if(isitem(A)) - var/obj/item/I = A - if(detergent) - I.decontaminate() - if(crayon && iscolorablegloves(I)) - var/obj/item/clothing/gloves/C = I - C.color = crayon.color - if(istype(A, /obj/item/clothing)) - var/obj/item/clothing/C = A - C.ironed_state = WRINKLES_WRINKLY - if(detergent) - C.change_smell(SMELL_CLEAN) - addtimer(CALLBACK(C, /obj/item/clothing/proc/change_smell), detergent.smell_clean_time, TIMER_UNIQUE | TIMER_OVERRIDE) - QDEL_NULL(detergent) - - if(locate(/mob/living) in src) - gibs_ready = 1 - state &= ~WASHER_STATE_RUNNING - update_use_power(POWER_USE_IDLE) + return TRUE -/obj/machinery/washing_machine/verb/climb_out() - set name = "Climb out" +/obj/machinery/washing_machine/verb/toggle_port() + set name = "Toggle Detergent Port" set category = "Object" - set src in usr.loc + set src in oview(1) if(!CanPhysicallyInteract(usr)) return - if(state & WASHER_STATE_CLOSED) - to_chat(usr, SPAN_WARNING("\The [src] is closed.")) - return - if(!do_after(usr, 2 SECONDS, src)) + + toggle_detergent_port(usr) + +/obj/machinery/washing_machine/proc/toggle_detergent_port(mob/user) + if(state & WASHER_STATE_RUNNING) + to_chat(user, SPAN_WARNING("You can't open the detergent port while \the [src] is running!")) return - if(!(state & WASHER_STATE_CLOSED)) - usr.dropInto(loc) + + if(atom_flags & ATOM_FLAG_OPEN_CONTAINER) + atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER + to_chat(user, SPAN_NOTICE("You close the detergent port on \the [src].")) + else + atom_flags |= ATOM_FLAG_OPEN_CONTAINER + to_chat(user, SPAN_NOTICE("You open the detergent port on \the [src].")) + + return TRUE + +/obj/machinery/washing_machine/get_alt_interactions(mob/user) + . = ..() + LAZYADD(., /decl/interaction_handler/start_washer) + LAZYADD(., /decl/interaction_handler/toggle_open/washing_machine) + +/decl/interaction_handler/start_washer + name = "Start washer" + expected_target_type = /obj/machinery/washing_machine + +/decl/interaction_handler/start_washer/is_possible(obj/machinery/washing_machine/washer, mob/user) + . = ..() + if(.) + return washer.operable() && !(washer.state & WASHER_STATE_RUNNING) + +/decl/interaction_handler/start_washer/invoked(obj/machinery/washing_machine/washer, mob/user) + return washer.start_washing(user) + +/decl/interaction_handler/toggle_open/washing_machine + name = "Toggle detergent port" + expected_target_type = /obj/machinery/washing_machine + +/decl/interaction_handler/toggle_open/washing_machine/invoked(obj/machinery/washing_machine/washer, mob/user) + return washer.toggle_detergent_port(user) /obj/machinery/washing_machine/on_update_icon() icon_state = "wm_[state][panel_open]" -/obj/machinery/washing_machine/clean_blood() +/obj/machinery/washing_machine/clean(clean_forensics = TRUE) . = ..() state &= ~WASHER_STATE_BLOODY update_icon() @@ -116,101 +263,19 @@ /obj/machinery/washing_machine/components_are_accessible(path) return !(state & WASHER_STATE_RUNNING) && ..() -/obj/machinery/washing_machine/attackby(obj/item/W, mob/user) - if(!(state & WASHER_STATE_CLOSED)) - if(!crayon && IS_PEN(W)) - if(!user.try_unequip(W, src)) - return - crayon = W - return TRUE - if(!detergent && istype(W,/obj/item/chems/pill/detergent)) - if(!user.try_unequip(W, src)) - return - detergent = W - return TRUE - if(istype(W, /obj/item/holder)) // Mob holder - for(var/mob/living/doggy in W) - doggy.forceMove(src) - qdel(W) - state |= WASHER_STATE_FULL - update_icon() - return TRUE - - else if(istype(W,/obj/item/clothing/under) || \ - istype(W,/obj/item/clothing/mask) || \ - istype(W,/obj/item/clothing/head) || \ - istype(W,/obj/item/clothing/gloves) || \ - istype(W,/obj/item/clothing/shoes) || \ - istype(W,/obj/item/clothing/suit) || \ - istype(W,/obj/item/bedsheet) || \ - istype(W,/obj/item/underwear/)) - - //YES, it's hardcoded... saves a var/can_be_washed for every single clothing item. - if ( istype(W,/obj/item/clothing/suit/space ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/suit/syndicatefake ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/suit/bomb_suit ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/suit/armor ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/suit/armor ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/mask/gas ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/mask/smokable/cigarette ) ) - to_chat(user, "This item does not fit.") - return - if ( istype(W,/obj/item/clothing/head/helmet ) ) - to_chat(user, "This item does not fit.") - return +/obj/machinery/washing_machine/autoclave + name = "autoclave" + desc = "An industrial washing machine used to sterilize and decontaminate items. It requires detergent for efficient decontamination." - if(contents.len < 5) - if(!(state & WASHER_STATE_CLOSED)) - if(!user.try_unequip(W, src)) - return - state |= WASHER_STATE_FULL - update_icon() - else - to_chat(user, SPAN_NOTICE("You can't put the item in right now.")) - else - to_chat(user, SPAN_NOTICE("\The [src] is full.")) - return TRUE - - if(state & WASHER_STATE_RUNNING) - to_chat(user, SPAN_WARNING("\The [src] is currently running.")) - return TRUE + wash_whitelist = list() + wash_blacklist = list() - return ..() + max_item_size = ITEM_SIZE_HUGE -/obj/machinery/washing_machine/physical_attack_hand(mob/user) - if(state & WASHER_STATE_RUNNING) - to_chat(user, SPAN_WARNING("\The [src] is busy.")) - return TRUE - if(state & WASHER_STATE_CLOSED) - state &= ~WASHER_STATE_CLOSED - if(gibs_ready) - gibs_ready = 0 - var/mob/M = locate(/mob/living) in src - if(M) - M.gib() - dump_contents() - state &= ~WASHER_STATE_FULL - update_icon() - crayon = null - detergent = null - return TRUE - state |= WASHER_STATE_CLOSED - update_icon() - return TRUE + idle_power_usage = 10 + active_power_usage = 300 #undef WASHER_STATE_CLOSED -#undef WASHER_STATE_FULL +#undef WASHER_STATE_LOADED #undef WASHER_STATE_RUNNING #undef WASHER_STATE_BLOODY \ No newline at end of file diff --git a/code/game/objects/alien_props.dm b/code/game/objects/alien_props.dm index 0c78194ae61..b6dca18e783 100644 --- a/code/game/objects/alien_props.dm +++ b/code/game/objects/alien_props.dm @@ -7,14 +7,14 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "unknown1" maxcharge = 5000 - origin_tech = "{'powerstorage':7}" - var/static/base_icon + origin_tech = @'{"powerstorage":7}' + var/base_icon_state /obj/item/cell/alien/on_update_icon() . = ..() - if(!base_icon) - base_icon = pick("instrument", "unknown1", "unknown3", "unknown4") - icon_state = base_icon + if(!base_icon_state) + base_icon_state = pick("instrument", "unknown1", "unknown3", "unknown4") + icon_state = base_icon_state // APC #define APC_UPDATE_ALLGOOD 128 diff --git a/code/game/objects/auras/blueforge_aura.dm b/code/game/objects/auras/blueforge_aura.dm index cc7a7d6118c..1a1800acbc4 100644 --- a/code/game/objects/auras/blueforge_aura.dm +++ b/code/game/objects/auras/blueforge_aura.dm @@ -1,7 +1,7 @@ /obj/aura/blueforge_aura name = "Blueforge Aura" - icon = 'icons/mob/human_races/species/eyes.dmi' - icon_state = "eyes_blueforged_s" + icon = 'icons/mob/human_races/species/blueforged/eyes.dmi' + icon_state = "eyes" layer = MOB_LAYER /obj/aura/blueforge_aura/life_tick() diff --git a/code/game/objects/auras/regenerating_aura.dm b/code/game/objects/auras/regenerating_aura.dm index 6fb8be76614..96707e87154 100644 --- a/code/game/objects/auras/regenerating_aura.dm +++ b/code/game/objects/auras/regenerating_aura.dm @@ -36,17 +36,18 @@ return 0 var/update_health = FALSE + var/organ_regen = get_config_value(/decl/config/num/health_organ_regeneration_multiplier) if(brute_mult && H.getBruteLoss()) update_health = TRUE - H.adjustBruteLoss(-brute_mult * config.organ_regeneration_multiplier, do_update_health = FALSE) + H.adjustBruteLoss(-brute_mult * organ_regen, do_update_health = FALSE) H.adjust_nutrition(-nutrition_damage_mult) if(fire_mult && H.getFireLoss()) update_health = TRUE - H.adjustFireLoss(-fire_mult * config.organ_regeneration_multiplier, do_update_health = FALSE) + H.adjustFireLoss(-fire_mult * organ_regen, do_update_health = FALSE) H.adjust_nutrition(-nutrition_damage_mult) if(tox_mult && H.getToxLoss()) update_health = TRUE - H.adjustToxLoss(-tox_mult * config.organ_regeneration_multiplier, do_update_health = FALSE) + H.adjustToxLoss(-tox_mult * organ_regen, do_update_health = FALSE) H.adjust_nutrition(-nutrition_damage_mult) if(update_health) H.update_health() diff --git a/code/game/objects/compass/compass_holder.dm b/code/game/objects/compass/compass_holder.dm index f557d013c31..5b5596d3b7c 100644 --- a/code/game/objects/compass/compass_holder.dm +++ b/code/game/objects/compass/compass_holder.dm @@ -54,7 +54,7 @@ var/global/list/angle_step_to_dir = list( M.Translate(0, get_label_offset()) M.Turn(effective_compass_period * i) I.transform = M - I.add_filter("glow", 1, list("drop_shadow", color = "#77777777", size = 2, offset = 1,x = 0, y = 0)) + I.add_filter("glow", 1, list(type = "drop_shadow", color = "#77777777", size = 2, offset = 1,x = 0, y = 0)) I.layer = HUD_BASE_LAYER I.plane = HUD_PLANE LAZYADD(compass_static_labels, I) diff --git a/code/game/objects/compass/compass_overmap.dm b/code/game/objects/compass/compass_overmap.dm index dbae62a1323..31ef3d2bb1f 100644 --- a/code/game/objects/compass/compass_overmap.dm +++ b/code/game/objects/compass/compass_overmap.dm @@ -16,7 +16,7 @@ var/owner_color = owner.linked?.color || COLOR_WHITE compass_heading_marker = new /image/compass_marker compass_heading_marker.maptext = STYLE_SMALLFONTS("
    â–³
    ", 7, COLOR_WHITE) - compass_heading_marker.add_filter("glow", 1, list("drop_shadow", color = "[owner_color]aa", size = 2, offset = 1, x = 0, y = 0)) + compass_heading_marker.add_filter("glow", 1, list(type = "drop_shadow", color = "[owner_color]aa", size = 2, offset = 1, x = 0, y = 0)) compass_heading_marker.layer = HUD_BASE_LAYER compass_heading_marker.plane = HUD_PLANE compass_heading_marker.color = owner_color diff --git a/code/game/objects/compass/compass_waypoint.dm b/code/game/objects/compass/compass_waypoint.dm index 1f1f9e4ff48..cb3bf668985 100644 --- a/code/game/objects/compass/compass_waypoint.dm +++ b/code/game/objects/compass/compass_waypoint.dm @@ -13,11 +13,11 @@ y = _y z = _z color = _color - compass_overlay = new + compass_overlay = new compass_overlay.loc = src compass_overlay.maptext = STYLE_SMALLFONTS_OUTLINE("
    |\n[uppertext(name)]
    ", 9, color, COLOR_BLACK) - compass_overlay.add_filter("glow", 1, list(type="drop_shadow", color = "[color]" + "aa", size = 2, offset = 1,x = 0, y = 0)) + compass_overlay.add_filter("glow", 1, list(type = "drop_shadow", color = "[color]" + "aa", size = 2, offset = 1,x = 0, y = 0)) compass_overlay.layer = HUD_BASE_LAYER compass_overlay.plane = HUD_PLANE diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index ebfa01620cd..8d2fa7c77c5 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -243,6 +243,7 @@ pending += location + var/airblock // zeroed by ATMOS_CANPASS_TURF while(pending.len) for(var/turf/current in pending) for(var/D in global.cardinal) @@ -259,9 +260,11 @@ continue if(!(target in targetTurfs)) continue - if(current.c_airblock(target)) //this is needed to stop chemsmoke from passing through thin window walls + ATMOS_CANPASS_TURF(airblock, current, target) + if(airblock) //this is needed to stop chemsmoke from passing through thin window walls continue - if(target.c_airblock(current)) + ATMOS_CANPASS_TURF(airblock, target, current) + if(airblock) continue pending += target diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index dcdf6727880..2dcb2c0123d 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -22,7 +22,7 @@ spawn(3 + metal * 3) Process() checkReagents() - addtimer(CALLBACK(src, .proc/remove_foam), 12 SECONDS) + addtimer(CALLBACK(src, PROC_REF(remove_foam)), 12 SECONDS) /obj/effect/effect/foam/proc/remove_foam() STOP_PROCESSING(SSobj, src) @@ -62,7 +62,7 @@ F.create_reagents(10) if(reagents) for(var/R in reagents.reagent_volumes) - F.reagents.add_reagent(R, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react + F.add_to_reagents(R, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react /obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) // foam disolves when heated, except metal foams if(!metal && prob(max(0, exposed_temperature - 475))) @@ -113,9 +113,9 @@ if(carried_reagents) for(var/id in carried_reagents) - F.reagents.add_reagent(id, 1, safety = 1) //makes a safety call because all reagents should have already reacted anyway + F.add_to_reagents(id, 1, safety = 1) //makes a safety call because all reagents should have already reacted anyway else - F.reagents.add_reagent(/decl/material/liquid/water, 1, safety = 1) + F.add_to_reagents(/decl/material/liquid/water, 1, safety = 1) // wall formed by metal foams, dense and opaque, but easy to break diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm deleted file mode 100644 index 5574b504813..00000000000 --- a/code/game/objects/effects/decals/Cleanable/aliens.dm +++ /dev/null @@ -1,6 +0,0 @@ -/obj/effect/decal/cleanable/blood/xeno - name = "xeno blood" - desc = "It's green and acidic. It looks like... blood?" - icon = 'icons/effects/blood.dmi' - basecolor = "#05ee05" - cleanable_scent = null diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 4de3c466f56..614a03dae1d 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -36,14 +36,14 @@ var/global/list/image/splatter_cache=list() basecolor = COLOR_LUMINOL update_icon() -/obj/effect/decal/cleanable/blood/clean_blood() +/obj/effect/decal/cleanable/blood/clean(clean_forensics = TRUE) fluorescent = FALSE if(invisibility != INVISIBILITY_ABSTRACT) set_invisibility(INVISIBILITY_ABSTRACT) amount = 0 STOP_PROCESSING(SSobj, src) remove_extension(src, /datum/extension/scent) - . = ..(ignore = TRUE) + . = ..(clean_forensics = FALSE) /obj/effect/decal/cleanable/blood/hide() return @@ -161,6 +161,14 @@ var/global/list/image/splatter_cache=list() . = ..() drips = list(icon_state) +/obj/effect/decal/cleanable/blood/drip/on_update_icon() + SHOULD_CALL_PARENT(FALSE) + set_overlays(drips?.Copy()) + +/obj/effect/decal/cleanable/blood/drip/Destroy() + LAZYCLEARLIST(drips) + return ..() + /obj/effect/decal/cleanable/blood/writing icon = 'icons/effects/writing.dmi' icon_state = "writing" diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 656377b2ffa..4dc821bf9e5 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -38,8 +38,8 @@ SSpersistence.forget_value(src, /decl/persistence_handler/filth) . = ..() -/obj/effect/decal/cleanable/clean_blood(var/ignore = 0) - if(!ignore) +/obj/effect/decal/cleanable/clean(clean_forensics = TRUE) + if(clean_forensics) qdel(src) return TRUE . = ..() diff --git a/code/game/objects/effects/decals/posters/_poster.dm b/code/game/objects/effects/decals/posters/_poster.dm index 095039b8084..c5e5768301b 100644 --- a/code/game/objects/effects/decals/posters/_poster.dm +++ b/code/game/objects/effects/decals/posters/_poster.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/items/posters.dmi' icon_state = "poster0" anchored = TRUE - directional_offset = "{'NORTH':{'y':32}, 'SOUTH':{'y':-32}, 'EAST':{'x':32}, 'WEST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":32}, "SOUTH":{"y":-32}, "WEST":{"x":32}, "EAST":{"x":-32}}' material = /decl/material/solid/organic/paper max_health = 10 parts_type = /obj/item/poster diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index d8620773efb..65d922b6cda 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -68,7 +68,7 @@ steam.start() -- spawns the effect /datum/effect/effect/system/steam_spread/start() var/i = 0 for(i=0, i 20) return - addtimer(CALLBACK(src, /datum/effect/effect/system/proc/spread, i), 0) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/effect/effect/system, spread), i), 0) /datum/effect/effect/system/smoke_spread/spread(var/i) if(holder) diff --git a/code/game/objects/effects/explosion_particles.dm b/code/game/objects/effects/explosion_particles.dm index 4f3c44fba8b..1077b1b952f 100644 --- a/code/game/objects/effects/explosion_particles.dm +++ b/code/game/objects/effects/explosion_particles.dm @@ -55,7 +55,7 @@ var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles() P.set_up(10,location) P.start() - addtimer(CALLBACK(src, .proc/make_smoke), 5) + addtimer(CALLBACK(src, PROC_REF(make_smoke)), 5) /datum/effect/system/explosion/proc/make_smoke() var/datum/effect/effect/system/smoke_spread/S = new/datum/effect/effect/system/smoke_spread() diff --git a/code/game/objects/effects/fluids.dm b/code/game/objects/effects/fluids.dm index 2cf3369d583..6d82de34d3b 100644 --- a/code/game/objects/effects/fluids.dm +++ b/code/game/objects/effects/fluids.dm @@ -1,162 +1,116 @@ -/obj/effect/fluid - name = "" - icon = 'icons/effects/liquids.dmi' - icon_state = "puddle" - anchored = TRUE - simulated = 0 - opacity = FALSE - mouse_opacity = MOUSE_OPACITY_UNCLICKABLE - layer = FLY_LAYER - alpha = 0 - color = COLOR_LIQUID_WATER - - var/last_slipperiness = 0 - var/last_flow_strength = 0 - var/last_flow_dir = 0 - var/update_lighting = FALSE - -/obj/effect/fluid/Initialize() - atom_flags |= ATOM_FLAG_OPEN_CONTAINER - icon_state = "" - create_reagents(FLUID_MAX_DEPTH) - . = ..() - var/turf/simulated/T = get_turf(src) - if(!isturf(T) || !T.CanFluidPass()) - return INITIALIZE_HINT_QDEL - if(istype(T)) - T.unwet_floor(FALSE) - -/obj/effect/fluid/airlock_crush() - qdel(src) - -/obj/effect/fluid/Move() - PRINT_STACK_TRACE("A fluid overlay had Move() called!") - return FALSE - -/obj/effect/fluid/on_reagent_change() - ..() - - if(reagents?.total_volume) - var/decl/material/primary_reagent = reagents.get_primary_reagent_decl() - if(primary_reagent) - last_slipperiness = primary_reagent.slipperiness - - ADD_ACTIVE_FLUID(src) - for(var/checkdir in global.cardinal) - var/obj/effect/fluid/F = locate() in get_step(loc, checkdir) - if(F) - ADD_ACTIVE_FLUID(F) - update_lighting = TRUE - update_icon() - -/obj/effect/fluid/Destroy() - var/turf/simulated/T = get_turf(src) - for(var/checkdir in global.cardinal) - var/obj/effect/fluid/F = locate() in get_step(T, checkdir) - if(F) - ADD_ACTIVE_FLUID(F) - REMOVE_ACTIVE_FLUID(src) - SSfluids.pending_flows -= src - . = ..() - if(istype(T) && last_slipperiness > 0) - T.wet_floor(last_slipperiness) - -/obj/effect/fluid/on_update_icon() - - cut_overlays() - if(reagents.total_volume > FLUID_OVER_MOB_HEAD) - layer = DEEP_FLUID_LAYER +/atom/movable/fluid_overlay + name = "" + icon = 'icons/effects/liquids.dmi' + icon_state = "" + anchored = TRUE + simulated = FALSE + opacity = FALSE + mouse_opacity = MOUSE_OPACITY_UNCLICKABLE + layer = FLY_LAYER + alpha = 0 + color = COLOR_LIQUID_WATER + is_spawnable_type = FALSE + +/atom/movable/fluid_overlay/on_update_icon() + + var/datum/reagents/loc_reagents = loc?.reagents + var/reagent_volume = loc_reagents?.total_volume + + // Update layer. + var/new_layer + if(reagent_volume > FLUID_OVER_MOB_HEAD) + new_layer = DEEP_FLUID_LAYER else - layer = SHALLOW_FLUID_LAYER - - color = reagents.get_color() - - if(!reagents?.total_volume) - return - - var/decl/material/main_reagent = reagents.get_primary_reagent_decl() + new_layer = SHALLOW_FLUID_LAYER + if(layer != new_layer) + layer = new_layer + + // Update colour. + var/new_color = loc_reagents?.get_color() + if(color != new_color) + color = new_color + + // Update alpha. + var/decl/material/main_reagent = loc_reagents?.get_primary_reagent_decl() + var/new_alpha if(main_reagent) // TODO: weighted alpha from all reagents, not just primary - alpha = clamp(CEILING(255*(reagents.total_volume/FLUID_DEEP)) * main_reagent.opacity, main_reagent.min_fluid_opacity, main_reagent.max_fluid_opacity) - - if(reagents.total_volume <= FLUID_PUDDLE) - APPLY_FLUID_OVERLAY("puddle") - else if(reagents.total_volume <= FLUID_SHALLOW) - APPLY_FLUID_OVERLAY("shallow_still") - else if(reagents.total_volume < FLUID_DEEP) - APPLY_FLUID_OVERLAY("mid_still") - else if(reagents.total_volume < (FLUID_DEEP*2)) - APPLY_FLUID_OVERLAY("deep_still") + new_alpha = clamp(CEILING(255*(reagent_volume/FLUID_DEEP)) * main_reagent.opacity, main_reagent.min_fluid_opacity, main_reagent.max_fluid_opacity) + else + new_alpha = FLUID_MIN_ALPHA + if(new_alpha != alpha) + alpha = new_alpha + + // Update icon state. We use overlays so flick() can work on the base fluid overlay. + if(reagent_volume <= FLUID_PUDDLE) + set_overlays("puddle") + else if(reagent_volume <= FLUID_SHALLOW) + set_overlays("shallow_still") + else if(reagent_volume < FLUID_DEEP) + set_overlays("mid_still") + else if(reagent_volume < (FLUID_DEEP*2)) + set_overlays("deep_still") else - APPLY_FLUID_OVERLAY("ocean") - compile_overlays() + set_overlays("ocean") - if(update_lighting) - update_lighting = FALSE - var/glowing - for(var/rtype in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) - if(REAGENT_VOLUME(reagents, rtype) >= 3 && reagent.radioactivity) - glowing = TRUE - break - if(glowing) - set_light(1, 0.2, COLOR_GREEN) - else - set_light(0) +// Map helpers. +/obj/abstract/landmark/mapped_flood + name = "mapped fluid area" + alpha = FLUID_MAX_ALPHA + icon_state = "ocean" + color = COLOR_LIQUID_WATER + var/fluid_type = /decl/material/liquid/water -// Map helper. -/obj/abstract/fluid_mapped - name = "mapped flooded area" - alpha = 125 +/obj/abstract/landmark/mapped_flood/Initialize() + ..() + var/turf/my_turf = get_turf(src) + if(my_turf) + my_turf.set_flooded(fluid_type) + return INITIALIZE_HINT_QDEL + +/obj/abstract/landmark/mapped_fluid + name = "mapped fluid area" + alpha = FLUID_MIN_ALPHA icon_state = "shallow_still" color = COLOR_LIQUID_WATER var/fluid_type = /decl/material/liquid/water var/fluid_initial = FLUID_MAX_DEPTH -/obj/abstract/fluid_mapped/Initialize() +/obj/abstract/landmark/mapped_fluid/Initialize() ..() - var/turf/T = get_turf(src) - if(istype(T)) - T.add_fluid(fluid_type, fluid_initial) + var/turf/my_turf = get_turf(src) + if(my_turf) + my_turf.add_to_reagents(fluid_type, fluid_initial) return INITIALIZE_HINT_QDEL -/obj/abstract/fluid_mapped/fuel +/obj/abstract/landmark/mapped_fluid/fuel name = "spilled fuel" fluid_type = /decl/material/liquid/fuel fluid_initial = 10 // Permaflood overlay. -var/global/obj/effect/flood/flood_object = new -/obj/effect/flood - name = "" - icon = 'icons/effects/liquids.dmi' - icon_state = "ocean" - layer = DEEP_FLUID_LAYER - color = COLOR_LIQUID_WATER - alpha = 140 - invisibility = INVISIBILITY_NONE - simulated = FALSE - density = FALSE - anchored = TRUE +var/global/list/flood_type_overlay_cache = list() +/proc/get_flood_overlay(fluid_type) + if(!ispath(fluid_type, /decl/material)) + return null + if(!global.flood_type_overlay_cache[fluid_type]) + var/decl/material/fluid_decl = GET_DECL(fluid_type) + var/obj/effect/flood/new_flood = new + new_flood.color = fluid_decl.color + new_flood.alpha = round(fluid_decl.min_fluid_opacity + ((fluid_decl.max_fluid_opacity - fluid_decl.min_fluid_opacity) * 0.5)) + global.flood_type_overlay_cache[fluid_type] = new_flood + return new_flood + return global.flood_type_overlay_cache[fluid_type] -/obj/effect/fluid/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - . = ..() - if(exposed_temperature >= FLAMMABLE_GAS_MINIMUM_BURN_TEMPERATURE) - vaporize_fuel(air) - -/obj/effect/fluid/proc/vaporize_fuel(datum/gas_mixture/air) - if(!length(reagents?.reagent_volumes) || !istype(air)) - return - var/update_air = FALSE - for(var/rtype in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(rtype) - if(mat.gas_flags & XGM_GAS_FUEL) - var/moles = round(reagents.reagent_volumes[rtype] / REAGENT_UNITS_PER_GAS_MOLE) - if(moles > 0) - air.adjust_gas(rtype, moles, FALSE) - reagents.remove_reagent(round(moles * REAGENT_UNITS_PER_GAS_MOLE)) - update_air = TRUE - if(update_air) - air.update_values() - return TRUE - return FALSE \ No newline at end of file +/obj/effect/flood + name = "" + icon = 'icons/effects/liquids.dmi' + icon_state = "ocean" + layer = DEEP_FLUID_LAYER + color = COLOR_LIQUID_WATER + alpha = 140 + invisibility = 0 + simulated = FALSE + density = FALSE + anchored = TRUE + mouse_opacity = MOUSE_OPACITY_UNCLICKABLE diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibspawner.dm similarity index 87% rename from code/game/objects/effects/gibs.dm rename to code/game/objects/effects/gibspawner.dm index eeffab95754..0849701a1c3 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibspawner.dm @@ -1,6 +1,3 @@ -/proc/gibs(var/atom/location, var/gibber_type = /obj/effect/gibspawner/generic, var/_blood_type, var/_unique_enzymes, var/_fleshcolor, var/_bloodcolor) - new gibber_type(location, _blood_type, _unique_enzymes, _fleshcolor, _bloodcolor) - /obj/effect/gibspawner var/sparks = 0 //whether sparks spread on Gib() var/list/gibtypes = list() diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index b39ce17615a..55aaddcf1bd 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -32,7 +32,7 @@ dangerous = 1 playsound(src, 'sound/effects/phasein.ogg', 25, 1) target = end - events_repository.register(/decl/observ/moved, src, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/datum, qdel_self)) if(delete_after) QDEL_IN(src, delete_after) diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index cb41fa74732..0952585216f 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -172,7 +172,7 @@ dormant = FALSE if(dormant) - events_repository.register(/decl/observ/moved, src, src, /obj/effect/spider/proc/disturbed) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/effect/spider, disturbed)) else START_PROCESSING(SSobj, src) @@ -187,7 +187,7 @@ /obj/effect/spider/spiderling/Destroy() if(dormant) - events_repository.unregister(/decl/observ/moved, src, src, /obj/effect/spider/proc/disturbed) + events_repository.unregister(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/effect/spider, disturbed)) STOP_PROCESSING(SSobj, src) walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever. . = ..() @@ -208,7 +208,7 @@ if(!dormant) return dormant = FALSE - events_repository.unregister(/decl/observ/moved, src, src, /obj/effect/spider/proc/disturbed) + events_repository.unregister(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/effect/spider, disturbed)) START_PROCESSING(SSobj, src) /obj/effect/spider/spiderling/Bump(atom/user) @@ -233,7 +233,7 @@ if(prob(50)) src.visible_message("You hear something squeezing through the ventilation ducts.",2) forceMove(exit_vent) - addtimer(CALLBACK(src, .proc/end_vent_moving, exit_vent), travel_time) + addtimer(CALLBACK(src, PROC_REF(end_vent_moving), exit_vent), travel_time) /obj/effect/spider/spiderling/proc/end_vent_moving(obj/machinery/atmospherics/unary/vent_pump/exit_vent) if(check_vent(exit_vent)) @@ -268,7 +268,7 @@ forceMove(entry_vent) var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) - addtimer(CALLBACK(src, .proc/start_vent_moving, exit_vent, travel_time), travel_time + rand(20,60)) + addtimer(CALLBACK(src, PROC_REF(start_vent_moving), exit_vent, travel_time), travel_time + rand(20,60)) travelling_in_vent = TRUE return else diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index e3a2cedd855..bef4e25c4d1 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -1,6 +1,6 @@ //TODO: Flash range does nothing currently /proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN) - if(config.use_iterative_explosions) + if(get_config_value(/decl/config/toggle/use_iterative_explosions)) . = explosion_iter(epicenter, (devastation_range * 2 + heavy_impact_range + light_impact_range), z_transfer) else . = explosion_basic(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, z_transfer) @@ -86,7 +86,7 @@ if(AM && AM.simulated && !T.protects_atom(AM)) AM.explosion_act(dist) if(!QDELETED(AM) && !AM.anchored) - addtimer(CALLBACK(AM, /atom/movable/.proc/throw_at, throw_target, throw_dist, throw_dist), 0) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), throw_target, throw_dist, throw_dist), 0) var/took = (REALTIMEOFDAY-start_time)/10 if(Debug2) @@ -127,11 +127,12 @@ if (O.explosion_resistance) power -= O.explosion_resistance - if (power >= config.iterative_explosives_z_threshold) + if (power >= get_config_value(/decl/config/num/iterative_explosives_z_threshold)) + var/explo_mult = get_config_value(/decl/config/num/iterative_explosives_z_multiplier) if ((z_transfer & UP) && HasAbove(epicenter.z)) - explosion_iter(GetAbove(epicenter), power * config.iterative_explosives_z_multiplier, UP) + explosion_iter(GetAbove(epicenter), power * explo_mult, UP) if ((z_transfer & DOWN) && HasBelow(epicenter.z)) - explosion_iter(GetBelow(epicenter), power * config.iterative_explosives_z_multiplier, DOWN) + explosion_iter(GetBelow(epicenter), power * explo_mult, DOWN) // These three lists must always be the same length. var/list/turf_queue = list(epicenter, epicenter, epicenter, epicenter) @@ -254,7 +255,7 @@ if (AM.simulated) AM.explosion_act(severity) if(!QDELETED(AM) && !AM.anchored) - addtimer(CALLBACK(AM, /atom/movable/.proc/throw_at, throw_target, throw_dist, throw_dist), 0) + addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), throw_target, throw_dist, throw_dist), 0) movable_tally++ CHECK_TICK else diff --git a/code/game/objects/item.dm b/code/game/objects/item.dm index 5d0ebf45295..36eead31204 100644 --- a/code/game/objects/item.dm +++ b/code/game/objects/item.dm @@ -84,7 +84,7 @@ var/tmp/has_inventory_icon // do not set manually var/tmp/use_single_icon - var/center_of_mass = @"{'x':16,'y':16}" //can be null for no exact placement behaviour + var/center_of_mass = @'{"x":16,"y":16}' //can be null for no exact placement behaviour /obj/item/proc/can_contaminate() return !(obj_flags & ITEM_FLAG_NO_CONTAMINATION) @@ -457,10 +457,10 @@ for(var/obj/item/thing in user?.get_held_items()) thing.update_twohanding() if(play_dropsound && drop_sound && SSticker.mode) - addtimer(CALLBACK(src, .proc/dropped_sound_callback), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) + addtimer(CALLBACK(src, PROC_REF(dropped_sound_callback)), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) if(user && (z_flags & ZMM_MANGLE_PLANES)) - addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, check_emissive_equipment)), 0, TIMER_UNIQUE) RAISE_EVENT(/decl/observ/mob_unequipped, user, src) RAISE_EVENT_REPEAT(/decl/observ/item_unequipped, src, user) @@ -492,7 +492,7 @@ add_fingerprint(user) hud_layerise() - addtimer(CALLBACK(src, .proc/reconsider_client_screen_presence, user.client, slot), 0) + addtimer(CALLBACK(src, PROC_REF(reconsider_client_screen_presence), user.client, slot), 0) //Update two-handing status var/mob/M = loc @@ -503,11 +503,11 @@ if(user) if(SSticker.mode) if(pickup_sound && (slot in user.get_held_item_slots())) - addtimer(CALLBACK(src, .proc/pickup_sound_callback), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) + addtimer(CALLBACK(src, PROC_REF(pickup_sound_callback)), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) else if(equip_sound) - addtimer(CALLBACK(src, .proc/equipped_sound_callback), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) + addtimer(CALLBACK(src, PROC_REF(equipped_sound_callback)), 0, (TIMER_OVERRIDE | TIMER_UNIQUE)) if(z_flags & ZMM_MANGLE_PLANES) - addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, check_emissive_equipment)), 0, TIMER_UNIQUE) RAISE_EVENT(/decl/observ/mob_equipped, user, src, slot) RAISE_EVENT_REPEAT(/decl/observ/item_equipped, src, user, slot) @@ -626,10 +626,6 @@ playsound(target, hitsound, 50, 1, -1) return 1 -/obj/item/clean_blood() - . = ..() - clean() - /obj/item/reveal_blood() if(was_bloodied && !fluorescent) fluorescent = FLUORESCENT_GLOWS @@ -731,12 +727,12 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. user.visible_message("\The [user] peers through [zoomdevicename ? "the [zoomdevicename] of [src]" : "[src]"].") - events_repository.register(/decl/observ/destroyed, user, src, /obj/item/proc/unzoom) - events_repository.register(/decl/observ/moved, user, src, /obj/item/proc/unzoom) - events_repository.register(/decl/observ/dir_set, user, src, /obj/item/proc/unzoom) - events_repository.register(/decl/observ/item_unequipped, src, src, /obj/item/proc/zoom_drop) + events_repository.register(/decl/observ/destroyed, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.register(/decl/observ/moved, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.register(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.register(/decl/observ/item_unequipped, src, src, TYPE_PROC_REF(/obj/item, zoom_drop)) if(isliving(user)) - events_repository.register(/decl/observ/stat_set, user, src, /obj/item/proc/unzoom) + events_repository.register(/decl/observ/stat_set, user, src, TYPE_PROC_REF(/obj/item, unzoom)) /obj/item/proc/zoom_drop(var/obj/item/I, var/mob/user) unzoom(user) @@ -746,12 +742,12 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. return zoom = 0 - events_repository.unregister(/decl/observ/destroyed, user, src, /obj/item/proc/unzoom) - events_repository.unregister(/decl/observ/moved, user, src, /obj/item/proc/unzoom) - events_repository.unregister(/decl/observ/dir_set, user, src, /obj/item/proc/unzoom) - events_repository.unregister(/decl/observ/item_unequipped, src, src, /obj/item/proc/zoom_drop) + events_repository.unregister(/decl/observ/destroyed, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.unregister(/decl/observ/moved, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.unregister(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/item, unzoom)) + events_repository.unregister(/decl/observ/item_unequipped, src, src, TYPE_PROC_REF(/obj/item, zoom_drop)) if(isliving(user)) - events_repository.unregister(/decl/observ/stat_set, user, src, /obj/item/proc/unzoom) + events_repository.unregister(/decl/observ/stat_set, user, src, TYPE_PROC_REF(/obj/item, unzoom)) if(!user.client) return @@ -862,9 +858,10 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. return coating.remove_any(amount) if(coating.total_volume <= MINIMUM_CHEMICAL_VOLUME) - clean(0) + clean(FALSE) -/obj/item/proc/clean(clean_forensics=TRUE) +/obj/item/clean(clean_forensics=TRUE) + . = ..() QDEL_NULL(coating) blood_overlay = null if(clean_forensics) diff --git a/code/game/objects/item_interactions.dm b/code/game/objects/item_interactions.dm index 856871e9baa..01f887cf4ff 100644 --- a/code/game/objects/item_interactions.dm +++ b/code/game/objects/item_interactions.dm @@ -1,6 +1,6 @@ /obj/item/get_alt_interactions(var/mob/user) . = ..() - if(config.expanded_alt_interactions) + if(get_config_value(/decl/config/toggle/expanded_alt_interactions)) LAZYADD(., list( /decl/interaction_handler/pick_up, /decl/interaction_handler/drop, diff --git a/code/game/objects/item_mob_overlay.dm b/code/game/objects/item_mob_overlay.dm index 6f873e024da..70d22bd21fe 100644 --- a/code/game/objects/item_mob_overlay.dm +++ b/code/game/objects/item_mob_overlay.dm @@ -57,14 +57,14 @@ var/global/list/icon_state_cache = list() ..() update_world_inventory_state() -/obj/item/proc/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/proc/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, force_skip_offset = FALSE, skip_offset = FALSE) var/state_modifier = user_mob?.get_overlay_state_modifier() if(!use_single_icon) var/mob_state = "[item_state || icon_state][state_modifier]" var/mob_icon = global.default_onmob_icons[slot] var/decl/bodytype/root_bodytype = user_mob.get_bodytype() - if(istype(root_bodytype)) + if(istype(root_bodytype) && !skip_offset) var/use_slot = (bodypart in root_bodytype.equip_adjust) ? bodypart : slot return root_bodytype.get_offset_overlay_image(mob_icon, mob_state, color, use_slot) return overlay_image(mob_icon, mob_state, color, RESET_COLOR) @@ -98,7 +98,8 @@ var/global/list/icon_state_cache = list() var/image/I = image(useicon, use_state) I.color = color I.appearance_flags = RESET_COLOR - . = adjust_mob_overlay(user_mob, bodytype, I, slot, bodypart, use_fallback_if_icon_missing) + + . = force_skip_offset ? I : adjust_mob_overlay(user_mob, bodytype, I, slot, bodypart, use_fallback_if_icon_missing) /obj/item/proc/get_fallback_slot(var/slot) return @@ -109,9 +110,9 @@ var/global/list/icon_state_cache = list() // Ensure ..() is called only at the end of this proc, and that `overlay` is mutated rather than replaced. // This is necessary to ensure that all the overlays are generated and tracked prior to being passed to // the bodytype offset proc, which can scrub icon/icon_state information as part of the offset process. -/obj/item/proc/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/proc/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) var/decl/bodytype/root_bodytype = user_mob?.get_bodytype() - if(root_bodytype && root_bodytype.bodytype_category != bodytype) + if(root_bodytype && root_bodytype.bodytype_category != bodytype && !skip_offset) var/list/overlays_to_offset = overlay.overlays overlay = root_bodytype.get_offset_overlay_image(overlay.icon, overlay.icon_state, color, (bodypart || slot)) for(var/thing in overlays_to_offset) @@ -121,7 +122,7 @@ var/global/list/icon_state_cache = list() adjusted_overlay.plane = I.plane adjusted_overlay.layer = I.layer overlay.overlays += adjusted_overlay - . = overlay + return overlay //Special proc belts use to compose their icon /obj/item/proc/get_on_belt_overlay() diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 43f82d3b0c4..c9c67e53fc7 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -105,8 +105,8 @@ if(isnull(shuttle_name)) shuttle_name = S.shuttle update_linked_name(S, null, S.name) - events_repository.register(/decl/observ/name_set, S, src, .proc/update_linked_name) - events_repository.register(/decl/observ/destroyed, S, src, .proc/on_shuttle_destroy) + events_repository.register(/decl/observ/name_set, S, src, PROC_REF(update_linked_name)) + events_repository.register(/decl/observ/destroyed, S, src, PROC_REF(on_shuttle_destroy)) valid_z_levels += S.map_z area_prefix = S.name return TRUE @@ -119,8 +119,8 @@ desc = "Blueprints of \the [new_name]. There are several coffee stains on it." /obj/item/blueprints/shuttle/proc/on_shuttle_destroy(datum/destroyed) - events_repository.unregister(/decl/observ/name_set, destroyed, src, .proc/update_linked_name) - events_repository.unregister(/decl/observ/destroyed, destroyed, src, .proc/on_shuttle_destroy) + events_repository.unregister(/decl/observ/name_set, destroyed, src, PROC_REF(update_linked_name)) + events_repository.unregister(/decl/observ/destroyed, destroyed, src, PROC_REF(on_shuttle_destroy)) name = initial(name) desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts." valid_z_levels = list() diff --git a/code/game/objects/items/books/_book.dm b/code/game/objects/items/books/_book.dm index af564436395..f4806822104 100644 --- a/code/game/objects/items/books/_book.dm +++ b/code/game/objects/items/books/_book.dm @@ -34,6 +34,19 @@ if(SSpersistence.is_tracking(src, /decl/persistence_handler/book)) . = QDEL_HINT_LETMELIVE +/obj/item/book/proc/get_style_css() + return {" + + "} + /obj/item/book/attack_self(var/mob/user) return try_to_read(user) || ..() diff --git a/code/game/objects/items/books/fluff/_fluff.dm b/code/game/objects/items/books/fluff/_fluff.dm new file mode 100644 index 00000000000..f7ce2ae2fbd --- /dev/null +++ b/code/game/objects/items/books/fluff/_fluff.dm @@ -0,0 +1,20 @@ +/obj/item/book/fluff + unique = TRUE + abstract_type = /obj/item/book/fluff + var/fluff_text + +/obj/item/book/fluff/Initialize() + . = ..() + if(!fluff_text) + log_debug("Fluff book [type] spawned with no fluff text.") + return INITIALIZE_HINT_QDEL + dat = {" + + + [get_style_css()] + + + [fluff_text] + + + "} diff --git a/code/game/objects/items/books/fluff/science.dm b/code/game/objects/items/books/fluff/science.dm new file mode 100644 index 00000000000..830026a5bb9 --- /dev/null +++ b/code/game/objects/items/books/fluff/science.dm @@ -0,0 +1,133 @@ +/obj/item/book/fluff/anomaly_spectroscopy + name = "Spectroscopy: Analysing the Anomalies of the Cosmos" + icon_state = "anomaly" + author = "Doctor Martin Boyle, Director Research at the Lower Hydrolian Sector Listening Array" + title = "Spectroscopy: Analysing the Anomalies of the Cosmos" + fluff_text = {" + It's perhaps one of the most exciting times to be alive, with the recent breakthroughs in understanding and categorisation of things we may one day no longer call + 'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long winded, but no less eloquent all the + same! Why, look at the strides we're making in piercing the walls of spacetime or our steadily improving ability to clarify and stabilise subspace emissions; it's + certainly an exciting time to be alive. For the moment, the Hydrolian hasn't seen two spatial anomalies alike but the day will come and it is soon, I can feel it. + "} + +/obj/item/book/fluff/materials_chemistry_analysis + name = "Materials Analysis and the Chemical Implications" + icon_state = "chemistry" + author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar" + title = "Materials Analysis and the Chemical Implications" + fluff_text = {" + In today's high tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe + or the operation of some fancy new piece of equipment, it seems like all the cool fields are producing new toys to play with, leaving doddery old fields such as + materials analysis and chemistry relegated to the previous few centuries, when we were still learning the makeup and structure of the elements. +

    + Well, when you're out there building the next gryo-whatsitron or isotope mobility thingummy, remember how the field of archaeology experienced a massive new rebirth + following the excavations at Paranol IV and consider how all of the scientific greats will come crawling back to basic paradigms of natural philosophy when they discover + a new element that defies classification. I defy you to classify it without reviving this once great field! + "} + +/obj/item/book/fluff/anomaly_testing + name = "Anomalous Materials and Energies" + icon_state = "triangulate" + author = "Norman York, formerly of the Tyrolion Institute on Titan" + title = "Anomalous Materials and Energies" + fluff_text = {" +

    Contents

    +
      +
    1. Foreword: Modern attitude towards anomalies
    2. +
    3. Triangulating anomalous energy readings
    4. +
    5. Harvesting and utilising anomalous energy signatures
    6. +
    +
    +

    Modern attitude towards anomalies

    + It's only when confronted with things we don't know, that we may push back our knowledge of the world around us. Nowhere is this more obvious than the + vast and inscrutable mysterious of the cosmos that scholars from such august institutions as the Elysian Institute of the Sciences present + formulas and hypotheses for every few decades.
    +
    + Using our vast, telescopic array installations and deep space satellite networks, we are able to detect anomalous energy fields and formations in deep space, + but are limited to those that are large enough to output energy that will stretch across light years worth of distance between stars.
    +
    + While some sectors (such as the Hydrolian Rift and Keppel's Run) are replete with inexplicable energetic activity and unique phenomena found nowhere else in + the galaxy, the majority of space is dry, barren and cold - and if past experience has told us anything, it is that there are always more things we are + unable to explain.
    +
    + Indeed, a great source of knowledge and technology has always been those who come before us, in the form of the multitudinous ancient alien precursors that + have left scattered remnants of their great past all over settled (and unexplored) space.
    +
    + It is from xenoarchaeologists, high energy materials researchers, and technology reconstruction authorities that we are able to theorise on the gifts these + species have left behind, and in some cases even reverse engineer or rebuild the technology in question. My colleague, Doctor Raymond Ward of the + Tyrolian Institute on Titan, has made great breakthroughs in a related field through his pioneering development of universally reflective materials capable + of harvesting and 'bottling' up virtually any energy emissions yet encountered by spacefaring civilisations.
    +
    + And yet, there are some amongst us who do not see the benefits of those who have come before us - indeed, some among them profess the opinion that there + is no species that could possibly match humanity in it's achievements and knowledge, or simply that employing non-human technology is dangerous and unethical. + Folly, say I. If it is their desire to throw onto the wayside the greatest achievements in the history of the galaxy, simply for preferment of the + greatest achievements in the history of mankind, then they have no business in the establishment of science.
    + Contents +

    Triangulating anomalous energy readings

    + Strong energy emissions, when remaining constant from any one fixed location for millennia, can leave an 'imprint' or distinctive energy signature on other + matter composites that are spatially fixed relative to the source.
    +
    + By taking samples of such 'fixed' matter, we can apply complex analytics such as the modified Fourier Transform Procedure to reverse engineer the path of the + energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space. Modern portable devices can do + all this purely by taking readings of local radiation.
    +
    + A canny researcher can thusly analyse radiation at pre-chosen points strategically scattered around an area, and if there are any anomalous energy + emissions in range of those points, combined the researcher can triangulate the source.
    + Contents +

    Harvesting and utilising anomalous energy signatures

    + As mentioned in the foreword, my colleague from the Tyrolian Institute on Saturn's moon of Titan, in the Sol System, Doctor Raymond Ward has made great strides + in the area of harvesting and application of the energy emitted by anomalous phenomena from around the galaxy (although I profess I have not yet seen him + venture further from his birthplace on Earth than the comfortable distance of the Sol Cis-Oort Satellite Sphere).
    +
    + By employing a patented semi-phased alloy with unique and fascinating properties, Ward's contraption is able to 'harvest' energy, store + it and redirect it later at will (with appropriate electronic mechanisms, of course). Although he professes to see or desire no commercial or material gain + for the application and use of said energy once it is harvested, there are no doubt myriad ways we can come to benefit from such things beyond mere research, + such as the reconstruction of torn cartilaginous tissue that a peculiar radiation from an amphibious species on Brachis IV was found to emit.
    + Contents + "} + +/obj/item/book/fluff/stasis + name = "Cellular Suspension, the New Cryogenics?" + icon_state = "stasis" + author = "Elvin Schmidt" + title = "Cellular Suspension, the New Cryogenics?" + fluff_text = {" +

    Contents

    +
      +
    1. Foreword: A replacement for cryosleep?
    2. +
    3. The breakthrough
    4. +
    5. Applying this new principle
    6. +
    +
    +

    Foreword: A replacement for cryosleep?

    + The development of rudimentary cryofreezing in the 20th and 21st centuries was hailed as a crank science by some, but many early visionaries recognised the + potential it had to change the way we approach so many fields, such as medicine, therapeutics, and space travel. It was breakthroughs in the field in the 22nd and + later centuries that turned the procedure from science fiction to science fact, however. Since then, cryogenics has become a hallmark of modern science, and + regarded as one of the great achievements of our era. As with all sciences however, they have their time and are superseded by newer technological miracles when + it is over.
    + Contents +

    The breakthrough

    + It was in examining the effects of decelerated high energy particles when transphased through a gravitational lens that the effects where primarily noticed. + Due to exigent properties of that dimension, transphasing those particles capable of existing with high stability levels has the effect of bringing + some of those effects into realspace. Examining the Hoffman emissions in particular, it was discovered that they exhibited a-entropic behaviour, and in what is + now termed the 'Effete Hoffman Principle,' it was found that metastabilising the Hoffman radiation resulted in the effect being applied across other physical + interactions, in particular forces and reactions.
    + Contents +

    Applying this new principle

    + When combined with an appropriate energy-effect replicate for cryogenics (slowing down biological activity, thus stabilising the organics), the effect is + effectively identical to cryogenics, and while it consumes vastly more power and requires extremely complex equipment, it's (for all intents and purposes) superior + to cryogenics, all that remains is to 'commercialise' the process by enabling cheaper development and mass production.
    + The Effete Hoffman Principle can be tweak-combined with other effects however, for different purposes. A division of PMC Research initially developed the application + in prisons as a literal 'suspension field' where convicts are held immobile in the air, and the use quickly spread to numerous other areas.
    +
    + By examining the material resonance properties of certain strong waveforms when combined with Hoffman radiation, an effect was produced able to reverse energy + transferral through matter, and to slow the effects of gravity. When combined with energy repulse technology, the triple effects compound themselves into a much + stronger field, although all three components do slightly different things. High energy researchers assure me of the following key points:
    +
      +
    • The energy repulsion factor provides a 'shell' capable of weak suspension.
    • +
    • The Hoffman emissions nullify energy transferral and other kinetic activity, maintaining stability inside the field.
    • +
    • The resonant waveform combines the effects of the above two points, and applies it magnified onto it's synced 'resonance' materials.
    • +
    + As an interesting aside, a carbon waveform was chosen for the field in prison suspension fields, due to it's resonance with organic matter.
    + Contents + "} diff --git a/code/game/objects/items/books/manuals/_manual.dm b/code/game/objects/items/books/manuals/_manual.dm index aa5c491e6f1..7cee55d5709 100644 --- a/code/game/objects/items/books/manuals/_manual.dm +++ b/code/game/objects/items/books/manuals/_manual.dm @@ -1,27 +1,21 @@ /obj/item/book/manual - icon = 'icons/obj/library.dmi' - unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified - var/url // Using full url or just tittle, example - Standard_Operating_Procedure (https://wiki.baystation12.net/index.php?title=Standard_Operating_Procedure) + unique = TRUE // Unable to be copied, unable to be modified + abstract_type = /obj/item/book/manual + var/guide_decl /obj/item/book/manual/Initialize() . = ..() - if(url) // URL provided for this manual - // If we haven't wikiurl or it included in url - just use url - if(config.wikiurl && !findtextEx(url, config.wikiurl, 1, length(config.wikiurl)+1)) - // If we have wikiurl, but it hasn't "index.php" then add it and making full link in url - if(config.wikiurl && !findtextEx(config.wikiurl, "/index.php", -10)) - if(findtextEx(config.wikiurl, "/", -1)) - url = config.wikiurl + "index.php?title=" + url - else - url = config.wikiurl + "/index.php?title=" + url - else //Or just making full link in url - url = config.wikiurl + "?title=" + url - dat = {" - - - - - - - - "} + var/guide_text = guide_decl && SScodex.get_manual_text(guide_decl) + if(!guide_text) + log_debug("Manual [type] spawned with invalid guide decl type ([guide_decl || null]).") + return INITIALIZE_HINT_QDEL + dat = {" + + + [get_style_css()] + + + [guide_text] + + + "} diff --git a/code/game/objects/items/books/manuals/engineering.dm b/code/game/objects/items/books/manuals/engineering.dm index cf54e3895fd..555b10c44e6 100644 --- a/code/game/objects/items/books/manuals/engineering.dm +++ b/code/game/objects/items/books/manuals/engineering.dm @@ -1,685 +1,76 @@ /obj/item/book/manual/engineering_guide - name = "Engineering Textbook" + name = "engineering reference manual" icon_state ="bookEngineering2" author = "Engineering Encyclopedia" title = "Engineering Textbook" - url = "Engineering" + guide_decl = /datum/codex_entry/guide/engineering /obj/item/book/manual/robotics_cyborgs - name = "Cyborgs for Dummies" + name = "robotics reference manual" icon_state = "borgbook" author = "XISC" title = "Cyborgs for Dummies" - - dat = {" - - - - - -

    Cyborgs for Dummies

    - -

    Chapters

    - -
      -
    1. Cyborg Related Equipment
    2. -
    3. Cyborg Modules
    4. -
    5. Cyborg Construction
    6. -
    7. Cyborg Maintenance
    8. -
    9. Cyborg Repairs
    10. -
    11. In Case of Emergency
    12. -
    - - -

    Cyborg Related Equipment

    - -

    Exosuit Fabricator

    - The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs cannot be built. It seems that they may also benefit from advanced research techniques. - -

    Cyborg Recharging Station

    - This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge. - -

    Robotics Control Console

    - This useful piece of equipment can be used to immobilize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or the Company may see to it that it never happens again. - - -

    Cyborg Modules

    - When a cyborg is created it picks out of an array of modules to designate its purpose. There are 11 different cyborg modules.
    - All cyborg modules carry a flash. - -

    Standard Cyborg

    - The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.
    A Standard Cyborg comes with: -
      -
    • Crowbar
    • -
    • Wrench
    • -
    • Stun Baton
    • -
    • Health Analyzer
    • -
    • Fire Extinguisher
    • -
    - -

    Research Cyborg

    - The research cyborg module is an effective researching machine. It is equipped with tools to effectively run RnD.A Research Cyborg comes with: -
      -
    • Portable Destructive Analyzer
    • -
    • Research Gripper
    • -
    • Sheet Loader
    • -
    • Robot Analyzer
    • -
    • Robot Card
    • -
    • Set of Engineering Tools
    • -
    • Laser Scalpel
    • -
    • Circular Saw
    • -
    • Fire Extinguisher
    • -
    • Syringe
    • -
    • Chemistry Gripper
    • -
    • Nanopaste
    • -
    - -

    Engineering Cyborg

    - The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.
    An Engineering Cyborg comes with: -
      -
    • A basic set of engineering tools
    • -
    • Metal Synthesizer
    • -
    • Plasteel Synthesizer
    • -
    • Reinforced Glass Synthesizer
    • -
    • Wire Synthesizer
    • -
    • Fire Extinguisher
    • -
    • Roll of Tape
    • -
    • Built-in Optical Meson Scanners
    • -
    - -

    Mining Cyborg

    - The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines.
    A Mining Cyborg comes with: -
      -
    • Wrench
    • -
    • Scredriver
    • -
    • Crowbar
    • -
    • Ore Satchel
    • -
    • Borg Drill
    • -
    • Mining Gripper
    • -
    • Ore Scanner
    • -
    - -

    Security Cyborg

    - The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals.
    A Security Cyborg comes with: -
      -
    • Stun Baton
    • -
    • Handcuffs
    • -
    • Energy Gun
    • -
    • Megaphone
    • -
    • Roll of Tape
    • -
    - -

    Janitor Cyborg

    - The Janitor Cyborg module is equipped with various cleaning-facilitating devices.
    A Janitor Cyborg comes with: -
      -
    • Mop
    • -
    • Hand Bucket
    • -
    • Cleaning Spray Synthesizer and Spray Nozzle
    • -
    • Light Replacer
    • -
    • Trash Bag
    • -
    - -

    Service Cyborg

    - The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros."
    A Service Cyborg comes with: -
      -
    • Service Gripper
    • -
    • Bucket
    • -
    • Hoe
    • -
    • Hatchet
    • -
    • Zippo Lighter
    • -
    • Rapid-Service-Fabricator (Produces various entertainment and refreshment objects)
    • -
    • Plant Analyzer
    • -
    • Robot Harvester
    • -
    • Rolling Pin
    • -
    • Knife
    • -
    - -

    Clerical Cyborg

    - The clerical cyborg module is prepared to run the supply department, including a vareity of stamps.
    A clerical cyborg comes with: -
      -
    • Pen
    • -
    • Paper Dispenser
    • -
    • Clerical Gripper
    • -
    • Hand Labeler
    • -
    • Generic Stamp
    • -
    • Denied Stamp
    • -
    • Package Wrapper
    • -
    • Destination Tagger
    • -
    - -

    Crisis Cyborg

    - The crisis cyborg module is prepared to handle a variety of non-surgical medical emergencies.
    A medical cyborg comes with: -
      -
    • Crowbar
    • -
    • Health Analyzer
    • -
    • Reagent Scanner
    • -
    • Roller Bed Rack
    • -
    • Body Bag Rack
    • -
    • Hypospray
    • -
    • Automatic Defibrillator
    • -
    • Industrial Dropper
    • -
    • Syringe
    • -
    • Chemistry Gripper
    • -
    • Fire Extinguisher
    • -
    • Inflatables Dispenser
    • -
    • Roll of Tape
    • -
    - -

    Surgeon Cyborg

    - The surgeon cyborg modules is prepared to handle a variety of surgical medical emergencies.
    A medical cyborg comes with: -
      -
    • Set of Surgery Tools
    • -
    • Health Analyzer
    • -
    • Roller Bed Rack
    • -
    • Body Bag Rack
    • -
    • Hypospray
    • -
    • Automatic Defibrillator
    • -
    • Industrial Dropper
    • -
    • Syringe
    • -
    • Chemistry Gripper
    • -
    • Fire Extinguisher
    • -
    • Inflatables Dispenser
    • -
    • Roll of Tape
    • -
    - -

    Cyborg Construction

    - Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies.
    The required materials to make a cyborg are: -
      -
    • Metal
    • -
    • Two Flashes
    • -
    • One Power Cell (Preferably rated to 15000w)
    • -
    • Some electrical wires
    • -
    • One Human Brain
    • -
    • One Man-Machine Interface
    • -
    - Once you have acquired the materials, you can start on construction of your cyborg.
    To construct a cyborg, follow the steps below: -
      -
    1. Start the Exosuit Fabricators constructing all of the cyborg parts
    2. -
    3. While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
    4. -
    5. Once you have a Robot Head, place your two flashes inside the eye sockets
    6. -
    7. Once you have your Robot Chest, wire the Robot chest, then insert the power cell
    8. -
    9. Attach all of the Robot parts to the Robot frame
    10. -
    11. Insert the Man-Machine Interface (With the Brain inside) into the Robot Body
    12. -
    13. Congratulations! You have a new cyborg!
    14. -
    - -

    Cyborg Maintenance

    - Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring. - -

    Replacing a Power Cell

    - Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell.
    The steps to replace a cell are as follows: -
      -
    1. Unlock the Cyborg's Interface by swiping your ID on it
    2. -
    3. Open the Cyborg's outer panel using a crowbar
    4. -
    5. Remove the old power cell
    6. -
    7. Insert the new power cell
    8. -
    9. Close the Cyborg's outer panel using a crowbar
    10. -
    11. Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
    12. -
    - -

    Exposing the Internal Wiring

    - Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs.
    You can easily expose the internal wiring by following the steps below: -
      -
    1. Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
    2. -
    3. Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
    4. -
    - To re-seal the cyborg's internal wiring: -
      -
    1. Use a screwdriver to secure the cyborg's internal panel
    2. -
    3. Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
    4. -
    - -

    Cyborg Repairs

    - Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs). - -

    Dents

    - If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure. - Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder. - -

    Excessive Heat Damage

    - If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly.
    To replace the internal wiring follow the steps below: -
      -
    1. Unlock the Cyborg's Interface by swiping your ID
    2. -
    3. Open the Cyborg's External Panel using a crowbar
    4. -
    5. Remove the Cyborg's Power Cell
    6. -
    7. Using a screwdriver, expose the internal wiring of the Cyborg
    8. -
    9. Replace the damaged wires inside the cyborg
    10. -
    11. Secure the internal wiring cover using a screwdriver
    12. -
    13. Insert the Cyborg's Power Cell
    14. -
    15. Close the Cyborg's External Panel using a crowbar
    16. -
    17. Lock the Cyborg's Interface by swiping your ID
    18. -
    - These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency. - -

    In Case of Emergency

    - In case of emergency, there are a few steps you can take. - -

    "Rogue" Cyborgs

    - If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution. - To repair the situation, follow these steps: -
      -
    1. Locate the nearest robotics console
    2. -
    3. Determine which cyborgs are "Rogue"
    4. -
    5. Press the lockdown button to immobilize the cyborg
    6. -
    7. Locate the cyborg
    8. -
    9. Expose the cyborg's internal wiring
    10. -
    11. Check to make sure the LawSync and AI Sync lights are lit
    12. -
    13. If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's LawSync
    14. -
    15. Proceed to a cyborg upload console. The Company usually places these in the same location as AI upload consoles.
    16. -
    17. Use a "Reset" upload moduleto reset the cyborg's laws
    18. -
    19. Proceed to a Robotics Control console
    20. -
    21. Remove the lockdown on the cyborg
    22. -
    - -

    As a last resort

    - If all else fails in a case of cyborg-related emergency, there may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg. -

    WARNING:

    Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of company equipment, and you may be punished for detonating them without reason. - - - - "} + guide_decl = /datum/codex_entry/guide/robotics /obj/item/book/manual/engineering_construction - name = "Repairs and Construction" + name = "repair and construction reference manual" icon_state ="bookEngineering" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + author = "Engineering Encyclopedia" title = "Repairs and Construction" - url = "Guide_to_Construction" + guide_decl = /datum/codex_entry/guide/construction /obj/item/book/manual/engineering_particle_accelerator - name = "Particle Accelerator User's Guide" + name = "particle accelerator reference manual" icon_state ="bookParticleAccelerator" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + author = "Engineering Encyclopedia" title = "Particle Accelerator User's Guide" - -/obj/item/book/manual/engineering_particle_accelerator/Initialize() - . = ..() - dat = {" - - - - - -

    Experienced User's Guide

    - -

    Setting up the accelerator

    - -
      -
    1. Wrench all pieces to the floor
    2. -
    3. Add wires to all the pieces
    4. -
    5. Close all the panels with your screwdriver
    6. -
    - -

    Using the accelerator

    - -
      -
    1. Open the control panel
    2. -
    3. Set the speed to 2
    4. -
    5. Start firing at the singularity generator
    6. -
    7. When the singularity reaches a large enough size so it starts moving on it's own set the speed down to 0, but don't shut it off
    8. -
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. -
    - - - - "} - + guide_decl = /datum/codex_entry/guide/particle_accelerator /obj/item/book/manual/supermatter_engine - name = "Supermatter Engine Operating Manual" + name = "supermatter engine reference manual" icon_state = "bookSupermatter" author = "Central Engineering Division" title = "Supermatter Engine Operating Manual" - url = "Supermatter_Engine" + guide_decl = /datum/codex_entry/guide/supermatter /obj/item/book/manual/rust_engine - name = "R-UST Operating Manual" + name = "fusion reactor reference Manual" icon_state = "bookMagazine" author = "Cindy Crawfish" title = "R-UST Operating Manual" - url = "R-UST" + guide_decl = /datum/codex_entry/guide/fusion /obj/item/book/manual/engineering_hacking - name = "Hacking" + name = "hacking reference manual" icon_state ="bookHacking" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + author = "Engineering Encyclopedia" title = "Hacking" - url = "Hacking" + guide_decl = /datum/codex_entry/guide/hacking /obj/item/book/manual/engineering_singularity_safety - name = "Singularity Safety in Special Circumstances" + name = "singularity engine reference manual" icon_state ="bookEngineeringSingularitySafety" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + author = "Engineering Encyclopedia" title = "Singularity Safety in Special Circumstances" - - dat = {" - - - - -

    Singularity Safety in Special Circumstances

    - -

    Power outage

    - - A power problem has made you lose power? Could be wiring problems or syndicate power sinks. In any case follow these steps: - -
      -
    1. PANIC!
    2. -
    3. Get your ass over to engineering! QUICKLY!!!
    4. -
    5. Get to the Area Power Controller which controls the power to the emitters.
    6. -
    7. Swipe it with your ID card - if it doesn't unlock, continue with step 15.
    8. -
    9. Open the console and disengage the cover lock.
    10. -
    11. Pry open the APC with a Crowbar.
    12. -
    13. Take out the empty power cell.
    14. -
    15. Put in the new, full power cell - if you don't have one, continue with step 15.
    16. -
    17. Quickly put on a Radiation suit.
    18. -
    19. Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
    20. -
    21. Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering APC is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the APC to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
    22. -
    23. Grab your crowbar and pry away the tile closest to the APC.
    24. -
    25. Use the wirecutters to cut the wire which is connecting the grid to the terminal.
    26. -
    27. Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
    28. -
    29. GET THE FUCK OUT OF THERE!!!
    30. -
    - -

    Shields get damaged

    - -
      -
    1. GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
    2. -
    - - - "} + guide_decl = /datum/codex_entry/guide/singularity /obj/item/book/manual/ripley_build_and_repair - name = "APLU \"Ripley\" Construction and Operation Manual" + name = "exosuit construction reference manual" icon_state ="book" - author = "Randall Varn, Einstein Engines Senior Mechanic" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + author = "Randall Varn, Einstein Engines Senior Mechanic" title = "APLU \"Ripley\" Construction and Operation Manual" - - dat = {" - - - - -
    -
    - Weyland-Yutani - Building Better Worlds -

    Autonomous Power Loader Unit \"Ripley\"

    -
    -

    Specifications:

    -
      -
    • Class: Autonomous Power Loader
    • -
    • Scope: Logistics and Construction
    • -
    • Weight: 820kg (without operator and with empty cargo compartment)
    • -
    • Height: 2.5m
    • -
    • Width: 1.8m
    • -
    • Top speed: 5km/hour
    • -
    • Operation in vacuum/hostile environment: Possible -
    • Airtank volume: 500 liters
    • -
    • Devices: -
        -
      • Hydraulic clamp
      • -
      • High-speed drill
      • -
      -
    • -
    • Propulsion device: Powercell-powered electro-hydraulic system
    • -
    • Powercell capacity: Varies
    • -
    - -

    Construction:

    -
      -
    1. Connect all exosuit parts to the chassis frame.
    2. -
    3. Connect all hydraulic fittings and tighten them up with a wrench.
    4. -
    5. Adjust the servohydraulics with a screwdriver.
    6. -
    7. Wire the chassis (Cable is not included).
    8. -
    9. Use the wirecutters to remove the excess cable if needed.
    10. -
    11. Install the central control module (Not included. Use supplied datadisk to create one).
    12. -
    13. Secure the mainboard with a screwdriver.
    14. -
    15. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    16. -
    17. Secure the peripherals control module with a screwdriver.
    18. -
    19. Install the internal armor plating (Not included due to corporate regulations. Can be made using 5 metal sheets).
    20. -
    21. Secure the internal armor plating with a wrench.
    22. -
    23. Weld the internal armor plating to the chassis.
    24. -
    25. Install the external reinforced armor plating (Not included due to corporate regulations. Can be made using 5 reinforced metal sheets).
    26. -
    27. Secure the external reinforced armor plating with a wrench.
    28. -
    29. Weld the external reinforced armor plating to the chassis.
    30. -
    - -

    Additional Information:

    -
      -
    • The firefighting variation is made in a similar fashion.
    • -
    • A firesuit must be connected to the firefighter chassis for heat shielding.
    • -
    • Internal armor is plasteel for additional strength.
    • -
    • External armor must be installed in 2 parts, totalling 10 sheets.
    • -
    • Completed exosuit is more resilient against fire, and is a bit more durable overall.
    • -
    • The Company is determined to ensure the safety of its investments employees.
    • -
    - - - "} + guide_decl = /datum/codex_entry/guide/mech_construction /obj/item/book/manual/atmospipes - name = "Pipes and You: Getting To Know Your Scary Tools" + name = "atmospherics reference manual" icon_state = "pipingbook" author = "Maria Crash, Senior Atmospherics Technician" title = "Pipes and You: Getting To Know Your Scary Tools" - dat = {" - - - - - -

    Contents

    -
      -
    1. Author's Foreword
    2. -
    3. Basic Piping
    4. -
    5. Insulated Pipes
    6. -
    7. Atmospherics Devices
    8. -
    9. Heat Exchange Systems
    10. -
    11. Final Checks
    12. -

    - -

    HOW TO NOT SUCK QUITE SO HARD AT ATMOSPHERICS


    - Or: What the fuck does a "pressure regulator" do?

    - - Alright. It has come to my attention that a variety of people are unsure of what a "pipe" is and what it does. - Apparently, there is an unnatural fear of these arcane devices and their "gases." Spooky, spooky. So, - this will tell you what every device constructable by an ordinary pipe dispenser within atmospherics actually does. - You are not going to learn what to do with them to be the super best person ever, or how to play guitar with passive gates, - or something like that. Just what stuff does.

    - - -

    Basic Pipes

    - The boring ones.
    - Most ordinary pipes are pretty straightforward. They hold gas. If gas is moving in a direction for some reason, gas will flow in that direction. - That's about it. Even so, here's all of your wonderful pipe options.
    - -
      -
    • Straight pipes: They're pipes. One-meter sections. Straight line. Pretty simple. Just about every pipe and device is based around this - standard one-meter size, so most things will take up as much space as one of these.
    • -
    • Bent pipes: Pipes with a 90 degree bend at the half-meter mark. My goodness.
    • -
    • Pipe manifolds: Pipes that are essentially a "T" shape, allowing you to connect three things at one point.
    • -
    • 4-way manifold: A four-way junction.
    • -
    • Pipe cap: Caps off the end of a pipe. Open ends don't actually vent air, because of the way the pipes are assembled, so, uh, use them to decorate your house or something.
    • -
    • Manual valve: A valve that will block off airflow when turned. Can't be used by the AI or cyborgs, because they don't have hands.
    • -
    • Manual T-valve: Like a manual valve, but at the center of a manifold instead of a straight pipe.


    • -
    - - An important note here is that pipes are now done in three distinct lines - general, supply, and scrubber. You can move gases between these with a universal adapter. Use the correct position for the correct location. - Connecting scrubbers to a supply position pipe makes you an idiot who gives everyone a difficult job. Insulated and HE pipes don't go through these positions. - -

    Insulated Pipes

    -
  • Bent pipes: Pipes with a 90 degree bend at the half-meter mark. My goodness.
  • -
  • Pipe manifolds: Pipes that are essentially a "T" shape, allowing you to connect three things at one point.
  • -
  • 4-way manifold: A four-way junction.
  • -
  • Pipe cap: Caps off the end of a pipe. Open ends don't actually vent air, because of the way the pipes are assembled, so, uh. Use them to decorate your house or something.
  • -
  • Manual Valve: A valve that will block off airflow when turned. Can't be used by the AI or cyborgs, because they don't have hands.
  • -
  • Manual T-Valve: Like a manual valve, but at the center of a manifold instead of a straight pipe.


  • - -

    Insulated Pipes


    - Special Public Service Announcement.
    - Our regular pipes are already insulated. These are completely worthless. Punch anyone who uses them.

    - -

    Devices:

    - They actually do something.
    - This is usually where people get frightened, afraid, and start calling on their gods and/or cowering in fear. Yes, I can see you doing that right now. - Stop it. It's unbecoming. Most of these are fairly straightforward.
    - -
      -
    • Gas pump: Take a wild guess. It moves gas in the direction it's pointing (marked by the red line on one end). It moves it based on pressure, the maximum output being 15000 kPa (kilopascals). - Ordinary atmospheric pressure, for comparison, is 101.3 kPa, and the minimum pressure of room-temperature pure oxygen needed to not suffocate in a matter of minutes is 16 kPa - (though 18 kPa is preferred when using internals with pure oxygen, for various reasons). A high-powered variant will move gas more quickly at the expense of consuming more power. Do not turn the distribution loop up to 15000 kPa. - You will make engiborgs cry and the Chief Engineer will beat you.
    • -
    • Pressure regulator: These replaced the old passive gates. You can choose to regulate pressure by input or output, and regulate flow rate. Regulating by input means that when input pressure is above the limit, gas will flow. - Regulating by output means that when pressure is below the limit, gas will flow. Flow rate can be controlled.
    • -
    • Unary vent: The basic vent used in rooms. It pumps gas into the room, but can't suck it back out. Controlled by the room's air alarm system.
    • -
    • Scrubber: The other half of room equipment. Filters air, and can suck it in entirely in what's called a "panic siphon." Activating a panic siphon without very good reason will kill someone. Don't do it.
    • -
    • Meter: A little box with some gauges and numbers. Fasten it to any pipe or manifold and it'll read you the pressure in it. Very useful.
    • -
    • Gas mixer: Two sides are input, one side is output. Mixes the gases pumped into it at the ratio defined. The side perpendicular to the other two is "node 2," for reference, on non-mirrored mixers.. - Output is controlled by flow rate. There is also an "omni" variant that allows you to set input and output sections freely..
    • -
    • Gas filter: Essentially the opposite of a gas mixer. One side is input. The other two sides are output. One gas type will be filtered into the perpendicular output pipe, - the rest will continue out the other side. Can also output from 0-4500 kPa. The "omni" vairant allows you to set input and output sections freely.
    • -
    - -

    Heat Exchange Systems

    - Will not set you on fire.
    - These systems are used to only transfer heat between two pipes. They will not move gases or any other element, but will equalize the temperature (eventually). Note that because of how gases work (remember: pv=nRt), - a higher temperature will raise pressure, and a lower one will lower temperature.
    - -
  • Pipe: This is a pipe that will exchange heat with the surrounding atmosphere. Place in fire for superheating. Place in space for supercooling.
  • -
  • Bent pipe: Take a wild guess.
  • -
  • Junction: The point where you connect your normal pipes to heat exchange pipes. Not necessary for heat exchangers, but necessary for H/E pipes/bent pipes.
  • -
  • Heat exchanger: These funky-looking bits attach to an open pipe end. Put another heat exchanger directly across from it, and you can transfer heat across two pipes without having to have the gases touch. - This normally shouldn't exchange with the ambient air, despite being totally exposed. Just don't ask questions.

  • - - That's about it for pipes. Go forth, armed with this knowledge, and try not to break, burn down, or kill anything. Please. - - - - - "} + guide_decl = /datum/codex_entry/guide/atmospherics /obj/item/book/manual/evaguide - name = "EVA Gear and You: Not Spending All Day Inside" + name = "\improper EVA reference manual" icon_state = "evabook" author = "Maria Crash, Senior Atmospherics Technician" title = "EVA Gear and You: Not Spending All Day Inside" - dat = {" - - - - - -

    EVA Gear and You: Not Spending All Day Inside

    - Or: How not to suffocate because there's a hole in your shoes
    - -

    Contents

    -
      -
    1. A foreword on using EVA gear
    2. -
    3. Donning a Civilian Suit
    4. -
    5. Putting on a Hardsuit
    6. -
    7. Cyclers and Other Modification Equipment
    8. -
    9. Final Checks
    10. -
    -
    - - EVA gear. Wonderful to use. It's useful for mining, engineering, and occasionally just surviving, if things are that bad. Most people have EVA training, - but apparently there are some people out in space who don't. This guide should give you a basic idea of how to use this gear, safely. It's split into two sections: - Civilian suits and hardsuits.

    - -

    Civilian Suits

    - The bulkiest things this side of Alpha Centauri
    - These suits are the grey ones that are stored in EVA. They're the more simple to get on, but are also a lot bulkier, and provide less protection from environmental hazards such as radiation or physical impact. - As Medical, Engineering, Security, and Mining all have hardsuits of their own, these don't see much use, but knowing how to put them on is quite useful anyways.

    - - First, take the suit. It should be in three pieces: A top, a bottom, and a helmet. Put the bottom on first, shoes and the like will fit in it. If you have magnetic boots, however, - put them on on top of the suit's feet. Next, get the top on, as you would a shirt. It can be somewhat awkward putting these pieces on, due to the makeup of the suit, - but to an extent they will adjust to you. You can then find the snaps and seals around the waist, where the two pieces meet. Fasten these, and double-check their tightness. - The red indicators around the waist of the lower half will turn green when this is done correctly. Next, put on whatever breathing apparatus you're using, be it a gas mask or a breath mask. Make sure the oxygen tube is fastened into it. - Put on the helmet now, straightforward, and make sure the tube goes into the small opening specifically for internals. Again, fasten seals around the neck, a small indicator light in the inside of the helmet should go from red to off when all is fastened. - There is a small slot on the side of the suit where an emergency oxygen tank or extended emergency oxygen tank will fit, - but it is recommended to have a full-sized tank on your back for EVA.

    - - These suits tend to be wearable by most species. They're large and flexible. They might be pretty uncomfortable for some, though, so keep that in mind.

    - -

    Hardsuits

    - Heavy, uncomfortable, still the best option.
    - These suits come in Engineering, Mining, and the Armory. There's also a couple Medical Hardsuits in EVA. These provide a lot more protection than the standard suits.

    - - Similarly to the other suits, these are split into three parts. Fastening the pant and top are mostly the same as the other spacesuits, with the exception that these are a bit heavier, - though not as bulky. The helmet goes on differently, with the air tube feeding into the suit and out a hole near the left shoulder, while the helmet goes on turned ninety degrees counter-clockwise, - and then is screwed in for one and a quarter full rotations clockwise, leaving the faceplate directly in front of you. There is a small button on the right side of the helmet that activates the helmet light. - The tanks that fasten onto the side slot are emergency tanks, as well as full-sized oxygen tanks, leaving your back free for a backpack or satchel.

    - - These suits generally only fit one species. Standard-issue suits are usually human-fitting by default, but there's equipment that can make modifications to the hardsuits to fit them to other species.

    - -

    Modification Equipment

    - How to actually make hardsuits fit you.
    - There's a variety of equipment that can modify hardsuits to fit species that can't fit into them, making life quite a bit easier.

    - - The first piece of equipment is a suit cycler. This is a large machine resembling the storage pods that are in place in some places. These are machines that will automatically tailor a suit to certain specifications. - The largest uses of them are for their cleaning functions and their ability to tailor suits for a species. Do not enter them physically. You will die from any of the functions being activated, and it will be painful. - These machines can both tailor a suit between species, and between types. This means you can convert engineering hardsuits to atmospherics, or the other way. This is useful. Use it if you can.

    - - There's also modification kits that let you modify suits yourself. These are extremely difficult to use unless you understand the actual construction of the suit. I do not recommend using them unless no other option is available. - -

    Final Checks

    -
      -
    • Are all seals fastened correctly?
    • -
    • If you have modified it manually, is absolutely everything sealed perfectly?
    • -
    • Do you either have shoes on under the suit, or magnetic boots on over it?
    • -
    • Do you have a mask on and internals on the suit or your back?
    • -
    • Do you have a way to communicate with your fellow crew in case something goes wrong?
    • -
    • Do you have a second person watching if this is a training session?

    • -
    - - If you don't have any further issues, go out and do whatever is necessary. - - - - "} + guide_decl = /datum/codex_entry/guide/eva diff --git a/code/game/objects/items/books/manuals/manuals.dm b/code/game/objects/items/books/manuals/manuals.dm index fc6dba675d1..6af9c841691 100644 --- a/code/game/objects/items/books/manuals/manuals.dm +++ b/code/game/objects/items/books/manuals/manuals.dm @@ -1,145 +1,27 @@ /obj/item/book/manual/chef_recipes - name = "Chef Recipes" + name = "recipe book" icon_state = "cooked_book" author = "Victoria Ponsonby" title = "Chef Recipes" - -/obj/item/book/manual/chef_recipes/Initialize() - . = ..() - dat = {" - - - - - [SScodex.get_guide(/decl/codex_category/recipes)] - - - "} + guide_decl = /decl/codex_category/recipes /obj/item/book/manual/barman_recipes - name = "Mixology 101" + name = "cocktail recipe book" icon_state = "barbook" author = "Sir John Rose" title = "Mixology 101" - -/obj/item/book/manual/barman_recipes/Initialize() - . = ..() - dat = {" - - - - - [SScodex.get_guide(/decl/codex_category/cocktails)] - - - "} + guide_decl = /decl/codex_category/cocktails /obj/item/book/manual/detective - name = "The Film Noir: Proper Procedures for Investigations" + name = "forensics reference manual" icon_state ="bookDetective" author = "The Company" title = "The Film Noir: Proper Procedures for Investigations" - - dat = {" - - - - -

    Detective Work

    - - Between your bouts of self-narration and drinking whiskey on the rocks, you might get a case or two to solve.
    - To have the best chance to solve your case, follow these directions: -

    -

      -
    1. Go to the crime scene.
    2. -
    3. Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog).
    4. -
    5. Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
    6. -
    7. Return to your office.
    8. -
    9. Using your forensic scanning computer, scan your scanner to upload all of your evidence into the database.
    10. -
    11. Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
    12. -
    13. If you have 80% or more of the print (The print is displayed), go to step 10, otherwise continue to step 8.
    14. -
    15. Look for clues from the suit fibres you found on your perpetrator, and go about looking for more evidence with this new information, scanning as you go.
    16. -
    17. Try to get a fingerprint card of your perpetrator, as if used in the computer, the prints will be completed on their dossier.
    18. -
    19. Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
    20. -
    21. Since you now have both your dossier and the name of the person, print both out as evidence and get security to nab your baddie.
    22. -
    23. Give yourself a pat on the back and a bottle of the ship's finest vodka, you did it!
    24. -
    -

    - It really is that easy! Good luck! - - - "} + guide_decl = /datum/codex_entry/guide/detective /obj/item/book/manual/nuclear - name = "Fission Mailed: Nuclear Sabotage 101" + name = "nuclear device reference manual" icon_state ="bookNuclear" author = "Syndicate" title = "Fission Mailed: Nuclear Sabotage 101" - - dat = {" - - - - -

    Nuclear Explosives 101

    - Hello and thank you for choosing the Syndicate for your nuclear information needs. Today's crash course will deal with the operation of a Nuclear Fission Device.

    - - First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done, to unbolt it, one must completely log in, which at this time may not be possible.
    - -

    To make the nuclear device functional

    -
      -
    • Place the nuclear device in the designated detonation zone.
    • -
    • Extend and anchor the nuclear device from its interface.
    • -
    • Insert the nuclear authorisation disk into the slot.
    • -
    • Type the numeric authorisation code into the keypad. This should have been provided.
      - Note: If you make a mistake, press R to reset the device. -
    • Press the E button to log on to the device.
    • -

    - - You now have activated the device. To deactivate the buttons at anytime, for example when you've already prepped the bomb for detonation, remove the authentication disk OR press R on the keypad.

    - Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option. Toggle off the SAFETY.
    - Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.

    - - So use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
    - Note: THE BOMB IS STILL SET AND WILL DETONATE

    - - Now before you remove the disk, if you need to move the bomb, you can toggle off the anchor, move it, and re-anchor.

    - - Remember the order:
    - Disk, Code, Safety, Timer, Disk, RUN!

    - Intelligence Analysts believe that normal corporate procedure is for the Captain to secure the nuclear authentication disk.

    - - Good luck! - - - "} + guide_decl = /datum/codex_entry/guide/nuclear_sabotage diff --git a/code/game/objects/items/books/manuals/medical.dm b/code/game/objects/items/books/manuals/medical.dm index f4d2e8a6d30..9bca7d84990 100644 --- a/code/game/objects/items/books/manuals/medical.dm +++ b/code/game/objects/items/books/manuals/medical.dm @@ -1,55 +1,22 @@ /obj/item/book/manual/medical_diagnostics_manual - name = "Medical Diagnostics Manual" + name = "medical diagnostics manual" desc = "First, do no harm. A detailed medical practitioner's guide." icon_state = "bookMedical" author = "Medical Department" title = "Medical Diagnostics Manual" - url = "Guide_to_Medicine" - -/obj/item/book/manual/medical_diagnostics_manual/Initialize() - . = ..() - dat = {" - - - - -
    -

    The Oath

    - - The Medical Oath sworn by recognised medical practitioners in the employ of [global.using_map.company_name]
    - -
      -
    1. Now, as a new doctor, I solemnly promise that I will, to the best of my ability, serve humanity-caring for the sick, promoting good health, and alleviating pain and suffering.
    2. -
    3. I recognise that the practice of medicine is a privilege with which comes considerable responsibility and I will not abuse my position.
    4. -
    5. I will practise medicine with integrity, humility, honesty, and compassion-working with my fellow doctors and other colleagues to meet the needs of my patients.
    6. -
    7. I shall never intentionally do or administer anything to the overall harm of my patients.
    8. -
    9. I will not permit considerations of gender, race, religion, political affiliation, sexual orientation, nationality, or social standing to influence my duty of care.
    10. -
    11. I will oppose policies in breach of human rights and will not participate in them. I will strive to change laws that are contrary to my profession's ethics and will work towards a fairer distribution of health resources.
    12. -
    13. I will assist my patients to make informed decisions that coincide with their own values and beliefs and will uphold patient confidentiality.
    14. -
    15. I will recognise the limits of my knowledge and seek to maintain and increase my understanding and skills throughout my professional life. I will acknowledge and try to remedy my own mistakes and honestly assess and respond to those of others.
    16. -
    17. I will seek to promote the advancement of medical knowledge through teaching and research.
    18. -
    19. I make this declaration solemnly, freely, and upon my honour.
    20. -

    - -
    - - - - - - "} + guide_decl = /datum/codex_entry/guide/ailments /obj/item/book/manual/chemistry_recipes - name = "Guide to Medicines & Drugs" + name = "pharmacology reference manual" desc = "A thick manual of chemistry, formulae and recipes useful for a Chemist." icon_state = "bookChemistry" author = "Big Pharma" - title = "Guide to Medicines & Drugs" - url = "List_of_Medical_Chemicals" \ No newline at end of file + title = "Guide to Pharmacology" + guide_decl = /decl/codex_category/materials/chemistry + +/obj/item/book/manual/surgical + name = "surgical reference manual" + icon_state = "bookMedical" + author = "Dr. Holmes MD" + title = "Guide to Surgery" + guide_decl = /decl/codex_category/surgery diff --git a/code/game/objects/items/books/manuals/science.dm b/code/game/objects/items/books/manuals/science.dm index 0894e7b787b..b7ff9268ecc 100644 --- a/code/game/objects/items/books/manuals/science.dm +++ b/code/game/objects/items/books/manuals/science.dm @@ -1,376 +1,13 @@ /obj/item/book/manual/excavation - name = "Out on the Dig" + name = "excavation reference manual" icon_state = "excavation" author = "Professor Patrick Mason, Curator of the Antiquities Museum on Ichar VII" title = "Out on the Dig" - dat = {" - - - - - -

    Contents

    -
      -
    1. Prepping the expedition
    2. -
    3. Knowing your tools
    4. -
    5. Finding the dig
    6. -
    7. Analysing deposits
    8. -
    9. Extracting your first find
    10. -
    -
    - -

    Prepping the expedition

    - Every digsite I've been to, someone has forgotten something and I've never yet been to a dig that hasn't had me hiking to get to it - so gather your gear - and get it to the site the first time. You learn quick that time is money, when you've got a shipful of bandits searching for you the next valley over, - but don't be afraid to clear some space if there are any inconvenient boulders in the way.
    -
      -
    • Floodlights (if it's dark)
    • -
    • Wooden trestle tables (for holding tools and finds)
    • -
    • Suspension field generator
    • -
    • Load bearing servitors (such as a mulebot, or hover-tray)
    • -
    • Spare energy packs
    • -

    - Contents - -

    Knowing your tools

    - Every archaeologist has a plethora of tools at their disposal, but here's the important ones:
    -
      -
    • Picks, pickaxes, and brushes - don't underestimate the the smallest or largest in your arsenal, each one clears a different amount - of the rockface so each one has a use.
    • -
    • Measuring tape - don't leave home without it, you can use it to measure the depth a rock face has been excavated to.
    • -
    • GPS locator - knowing where you are is the first step to not be lost.
    • -
    • Core sampler - use this to take core samples from rock faces, which you can then run to the lab for analysis.
    • -
    • Depth scanner - uses X-ray diffraction to locate anomalous densities in rock, indicating archaeological deposits or mineral veins. - Comes with a handy reference log containing coordinates and time of each scan.
    • -
    • Alden-Saraspova counter - uses a patented application of Fourier Transform analysis to determine the difference between background and - exotic radiation. Use it to determine how far you are from anomalous energy sources.
    • -
    • Radio beacon locator - leave a beacon at an item of interest, then track it down later with this handy gadget. Watch for interference from other - devices though.
    • -
    • Flashlight or portable light source - Self explanatory, I hope.
    • -
    • Environmental safety gear - This one's dependent on the environment you're working in, but enclosed footwear and a pack of internals - could save your life.
    • -
    • Anomaly safety gear - A biosealed and catalysis-resistant suit along with eye shielding, tinted hood, and non-reactive disposable gloves are - the best kind of protection you can hope for from the errors our forebears may have unleashed.
    • -
    • Personal defence weapon - Never know what you'll find on the dig: pirates, natives, ancient guardians, carnivorous wildlife... - it pays in blood to be prepared.
    • -

    - Contents - -

    Finding the dig

    - Wouldn't be an archaeologist without their dig, but everyone has to start somewhere. Here's a basic procedure I go through when cataloguing a new planet:
    -
      -
    • Get in touch with the locals (in particular geologists, miners, and farmers) - Never know what's been turned up by accident, then left to - gather dust on a shelf.
    • -
    • Check the obvious areas first - even if you're pressed for time, these ones are the generally easiest to search, and the most likely targets - of your rivals.
    • -
    • Do some prospecting - the earth mother isn't in the habit of displaying her secrets to the world (although sometimes you get lucky). - Drop a shaft and clear away a bit of surface rock here and there, you never know what might be lurking below the surface.
    • -
    • Tips on unearthing a deposit - How do you know when you're golden? Look for telltale white strata that looks strange or out of place, or if - something has broken under your pick while you're digging. Your depth scanner is your best friend, but even it can't distinguish between - ordinary minerals and ancient leavings, if in doubt then err on the side of caution.
    • -

    - Contents - -

    Analysing the contents of a dig

    - You've found some unusual strata, but it's not all peaches from here. No archaeologist ever managed to pull a bone from the earth without doing thorough - chemical analysis on every two meters of rock face nearby.
    -
      -
    • Take core samples - Grab a rock core for every 4m^2.
    • -
    • Clear around any potential finds - Clear away ordinary rock, leaving your prizes reachable in a clearly marked area.
    • -
    • Haul off excess rock - It's easy for a dig to get cluttered, and a neat archaeologist is a successful archaeologist.
    • -
    • Don't be afraid to be cautious - It's slower sometimes, but the extra time will be worth the payoff when you find an Exolitic relic.
    • -
    • Chemical analysis - I won't go into detail here, but the labwork is essential to any successful extraction. Marshal your core samples, and - send them off to the labcoated geniuses.
    • -

    - Contents - -

    Extracting your first find

    -
      -
    • Scan the rock - Use a depth scanner to determine the find's depth and clearance. DON'T FORGET THESE.
    • -
    • Choose stasis field - Chemical analysis on a core sample from the rock face will tell you which field is necessary to extract the find safely.
    • -
    • Setup field gen - Bolt it down, choose the field, check the charge, and activate it. If you forget it, you'll wish you hadn't when that priceless - Uryom vase crumbles as it sees the light of day.
    • -
    • FUNCTIONAL AND SAFE digging - Dig into the rock until you've cleared away a depth equal to (the anomaly depth MINUS the clearance range). The find - should come loose on it's own, but it will be in the midst of a chunk of rock. Use a welder or miniature excavation tool to clear away the excess.
    • -
    • FANCY AND SPEEDY digging - Dig into the rock until you've cleared away a depth equal to the anomaly depth, but without any of your strokes - entering the clearance range.
    • -
    • The big find - Sometimes, you'll chance upon something big, both literally and figuratively. Giant statues and functioning remnants of Precursor - technology are just as exciting, to the right buyers. If your digging leaves a large boulder behind, dig into it normally and see if anything's hidden - inside.
    • -

    - Contents - - - - "} + guide_decl = /datum/codex_entry/guide/xenoarchaeology /obj/item/book/manual/mass_spectrometry - name = "High Power Mass Spectrometry: A Comprehensive Guide" + name = "mass spectrometry reference manual" icon_state = "analysis" author = "Winton Rice, Chief Mass Spectrometry Technician at the Institute of Applied Sciences on Arcadia" title = "High powered mass spectrometry, a comprehensive guide" - dat = {" - - - - - -

    Contents

    -
      -
    1. A note on terms
    2. -
    3. Analysis progression
    4. -
    5. Heat management
    6. -
    7. Ambient radiation
    8. -
    - -
    -

    A note on terms

    -
      -
    • Mass spectrometry - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of - 'Materials analysis.'
    • -
    • Radiometric dating - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.
    • -
    • Dissonance ratio - This is a pseudoarbitrary value indicating the overall presence of a particular element in a greater composite. - It takes into account volume, density, molecular excitation and isotope spread.
    • -
    • Vacuum seal integrity - A reference to how close an airtight seal is to failure.
    • -

    - Contents - -

    Analysis progression

    - Modern mass spectrometry requires constant attention from the diligent researcher in order to be successful. There are many different elements to juggle, - and later chapters will delve into them. For the spectrometry assistant, the first thing you need to know is that the scanner wavelength is automatically - calculated for you. Just tweak the settings and try to match it with the actual wavelength as closely as possible.
    -
    - Contents - -

    Seal integrity

    - In order to maintain sterile and environmentally static procedures, a special chamber is set up inside the spectrometer. It's protected by a proprietary vacuum seal - produced by top tier industrial science. It will only last for a certain number of scans before failing outright, but it can be resealed through use of nanite paste. - Unfortunately, it's susceptible to malforming under heat stress so exposing it to higher temperatures will cause it's operation life to drop significantly.
    -
    - Contents - -

    Heat management

    - The scanner relies on a gyro-rotational system that varies in speed and intensity. Over the course of an ordinary scan, the RPMs can change dramatically. Higher RPMs - means greater heat generation, but is necessary for the ongoing continuation of the scan. To offset heat production, spectrometers have an inbuilt cooling system. - Researchers can modify the flow rate of water to aid in dropping temperature as necessary, but are advised that frequent water replacements may be necessary - depending on coolant purity. Other substances may be viable substitutes, but nowhere near as effective as water itself.
    -
    - Contents - -

    Ambient radiation

    - Researchers are warned that while operational, mass spectrometers emit period bursts of radiation and are thus advised to wear protective gear. In the event of - radiation spikes, there is also a special shield that can be lowered to block emissions. Lowering this, however, will have the effect of blocking the scanner - so use it sparingly.
    -
    - Contents - - - - "} - -/obj/item/book/manual/anomaly_spectroscopy - name = "Spectroscopy: Analysing the Anomalies of the Cosmos" - icon_state = "anomaly" - author = "Doctor Martin Boyle, Director Research at the Lower Hydrolian Sector Listening Array" - title = "Spectroscopy: Analysing the Anomalies of the Cosmos" - dat = {" - - - - -
    - It's perhaps one of the most exciting times to be alive, with the recent breakthroughs in understanding and categorisation of things we may one day no longer call - 'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long winded, but no less eloquent all the - same! Why, look at the strides we're making in piercing the walls of spacetime or our steadily improving ability to clarify and stabilise subspace emissions; it's - certainly an exciting time to be alive. For the moment, the Hydrolian hasn't seen two spatial anomalies alike but the day will come and it is soon, I can feel it. - - "} - -/obj/item/book/manual/materials_chemistry_analysis - name = "Materials Analysis and the Chemical Implications" - icon_state = "chemistry" - author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar" - title = "Materials Analysis and the Chemical Implications" - dat = {" - - - - -
    - In today's high tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe - or the operation of some fancy new piece of equipment, it seems like all the cool fields are producing new toys to play with, leaving doddery old fields such as - materials analysis and chemistry relegated to the previous few centuries, when we were still learning the makeup and structure of the elements.
    -
    - Well, when you're out there building the next gryo-whatsitron or isotope mobility thingummy, remember how the field of archaeology experienced a massive new rebirth - following the excavations at Paranol IV and consider how all of the scientific greats will come crawling back to basic paradigms of natural philosophy when they discover - a new element that defies classification. I defy you to classify it without reviving this once great field! - "} - -/obj/item/book/manual/anomaly_testing - name = "Anomalous Materials and Energies" - icon_state = "triangulate" - author = "Norman York, formerly of the Tyrolion Institute on Titan" - title = "Anomalous Materials and Energies" - dat = {" - - - - - -

    Contents

    -
      -
    1. Foreword: Modern attitude towards anomalies
    2. -
    3. Triangulating anomalous energy readings
    4. -
    5. Harvesting and utilising anomalous energy signatures
    6. -
    -
    -

    Modern attitude towards anomalies

    - It's only when confronted with things we don't know, that we may push back our knowledge of the world around us. Nowhere is this more obvious than the - vast and inscrutable mysterious of the cosmos that scholars from such august institutions as the Elysian Institute of the Sciences present - formulas and hypotheses for every few decades.
    -
    - Using our vast, telescopic array installations and deep space satellite networks, we are able to detect anomalous energy fields and formations in deep space, - but are limited to those that are large enough to output energy that will stretch across light years worth of distance between stars.
    -
    - While some sectors (such as the Hydrolian Rift and Keppel's Run) are replete with inexplicable energetic activity and unique phenomena found nowhere else in - the galaxy, the majority of space is dry, barren and cold - and if past experience has told us anything, it is that there are always more things we are - unable to explain.
    -
    - Indeed, a great source of knowledge and technology has always been those who come before us, in the form of the multitudinous ancient alien precursors that - have left scattered remnants of their great past all over settled (and unexplored) space.
    -
    - It is from xenoarchaeologists, high energy materials researchers, and technology reconstruction authorities that we are able to theorise on the gifts these - species have left behind, and in some cases even reverse engineer or rebuild the technology in question. My colleague, Doctor Raymond Ward of the - Tyrolian Institute on Titan, has made great breakthroughs in a related field through his pioneering development of universally reflective materials capable - of harvesting and 'bottling' up virtually any energy emissions yet encountered by spacefaring civilisations.
    -
    - And yet, there are some amongst us who do not see the benefits of those who have come before us - indeed, some among them profess the opinion that there - is no species that could possibly match humanity in it's achievements and knowledge, or simply that employing non-human technology is dangerous and unethical. - Folly, say I. If it is their desire to throw onto the wayside the greatest achievements in the history of the galaxy, simply for preferment of the - greatest achievements in the history of mankind, then they have no business in the establishment of science.
    - Contents - -

    Triangulating anomalous energy readings

    - Strong energy emissions, when remaining constant from any one fixed location for millennia, can leave an 'imprint' or distinctive energy signature on other - matter composites that are spatially fixed relative to the source.
    -
    - By taking samples of such 'fixed' matter, we can apply complex analytics such as the modified Fourier Transform Procedure to reverse engineer the path of the - energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space. Modern portable devices can do - all this purely by taking readings of local radiation.
    -
    - A canny researcher can thusly analyse radiation at pre-chosen points strategically scattered around an area, and if there are any anomalous energy - emissions in range of those points, combined the researcher can triangulate the source.
    - Contents - -

    Harvesting and utilising anomalous energy signatures

    - As mentioned in the foreword, my colleague from the Tyrolian Institute on Saturn's moon of Titan, in the Sol System, Doctor Raymond Ward has made great strides - in the area of harvesting and application of the energy emitted by anomalous phenomena from around the galaxy (although I profess I have not yet seen him - venture further from his birthplace on Earth than the comfortable distance of the Sol Cis-Oort Satellite Sphere).
    -
    - By employing a patented semi-phased alloy with unique and fascinating properties, Ward's contraption is able to 'harvest' energy, store - it and redirect it later at will (with appropriate electronic mechanisms, of course). Although he professes to see or desire no commercial or material gain - for the application and use of said energy once it is harvested, there are no doubt myriad ways we can come to benefit from such things beyond mere research, - such as the reconstruction of torn cartilaginous tissue that a peculiar radiation from an amphibious species on Brachis IV was found to emit.
    - Contents - - - - "} - -/obj/item/book/manual/stasis - name = "Cellular Suspension, the New Cryogenics?" - icon_state = "stasis" - author = "Elvin Schmidt" - title = "Cellular Suspension, the New Cryogenics?" - dat = {" - - - - - -

    Contents

    -
      -
    1. Foreword: A replacement for cryosleep?
    2. -
    3. The breakthrough
    4. -
    5. Applying this new principle
    6. -
    -
    -

    Foreword: A replacement for cryosleep?

    - The development of rudimentary cryofreezing in the 20th and 21st centuries was hailed as a crank science by some, but many early visionaries recognised the - potential it had to change the way we approach so many fields, such as medicine, therapeutics, and space travel. It was breakthroughs in the field in the 22nd and - later centuries that turned the procedure from science fiction to science fact, however. Since then, cryogenics has become a hallmark of modern science, and - regarded as one of the great achievements of our era. As with all sciences however, they have their time and are superseded by newer technological miracles when - it is over.
    - Contents - -

    The breakthrough

    - It was in examining the effects of decelerated high energy particles when transphased through a gravitational lens that the effects where primarily noticed. - Due to exigent properties of that dimension, transphasing those particles capable of existing with high stability levels has the effect of bringing - some of those effects into realspace. Examining the Hoffman emissions in particular, it was discovered that they exhibited a-entropic behaviour, and in what is - now termed the 'Effete Hoffman Principle,' it was found that metastabilising the Hoffman radiation resulted in the effect being applied across other physical - interactions, in particular forces and reactions.
    - Contents - -

    Applying this new principle

    - When combined with an appropriate energy-effect replicate for cryogenics (slowing down biological activity, thus stabilising the organics), the effect is - effectively identical to cryogenics, and while it consumes vastly more power and requires extremely complex equipment, it's (for all intents and purposes) superior - to cryogenics, all that remains is to 'commercialise' the process by enabling cheaper development and mass production.
    - The Effete Hoffman Principle can be tweak-combined with other effects however, for different purposes. A division of PMC Research initially developed the application - in prisons as a literal 'suspension field' where convicts are held immobile in the air, and the use quickly spread to numerous other areas.
    -
    - By examining the material resonance properties of certain strong waveforms when combined with Hoffman radiation, an effect was produced able to reverse energy - transferral through matter, and to slow the effects of gravity. When combined with energy repulse technology, the triple effects compound themselves into a much - stronger field, although all three components do slightly different things. High energy researchers assure me of the following key points:
    -
      -
    • The energy repulsion factor provides a 'shell' capable of weak suspension.
    • -
    • The Hoffman emissions nullify energy transferral and other kinetic activity, maintaining stability inside the field.
    • -
    • The resonant waveform combines the effects of the above two points, and applies it magnified onto it's synced 'resonance' materials.
    • -
    - As an interesting aside, a carbon waveform was chosen for the field in prison suspension fields, due to it's resonance with organic matter.
    - Contents - - - - "} \ No newline at end of file + guide_decl = /datum/codex_entry/guide/mass_spectrometry diff --git a/code/game/objects/items/books/skill/_skill.dm b/code/game/objects/items/books/skill/_skill.dm new file mode 100644 index 00000000000..e2ff9fb7868 --- /dev/null +++ b/code/game/objects/items/books/skill/_skill.dm @@ -0,0 +1,283 @@ +/* +Skill books that increase your skills while you activate and hold them +*/ + +/obj/item/book/skill + name = "textbook" // requires default names for tradershop, cant rely on Initialize for names + desc = "A blank textbook. (Notify admin)" + author = "The Oracle of Bakersroof" + icon_state = "book2" + force = 4 + w_class = ITEM_SIZE_LARGE // Skill books are THICC with knowledge. Up one level from regular books to prevent library-in-a-bag silliness. + unique = TRUE + material = /decl/material/solid/organic/plastic + matter = list(/decl/material/solid/organic/wood = MATTER_AMOUNT_REINFORCEMENT) + abstract_type = /obj/item/book/skill + + var/decl/hierarchy/skill/skill // e.g. SKILL_LITERACY + var/skill_req = SKILL_NONE // The level the user needs in the skill to benefit from the book, e.g. SKILL_PROF + var/weakref/reading // To check if the book is actively being used + var/custom = FALSE // To bypass init stuff, for player made textbooks and weird books. If true must have details manually set + var/ez_read = FALSE // Set to TRUE if you can read it without basic literacy skills + + var/skill_name = "missing skill name" + var/progress = INFINITY // used to track the progress of making a custom book. defaults as finished so, you know, you can read the damn thing + + var/static/list/skill_name_patterns = list( + "$SKILL_NAME$ for Idiots", + "How To Learn $SKILL_NAME$ and Not Get Laughed At", + "Teaching Yourself $SKILL_NAME$: Volume $RAND$", + "Getting the Hands-Off Experience You Need with $SKILL_NAME$", + "Master $SKILL_NAME$ in $RAND$ easy steps!", + "$SKILL_NAME$ Just Like Mum", + "How To $SKILL_NAME$ Good Enough For Your Father", + "How To Win Your Dad's Approval With $SKILL_NAME$", + "Make a Living with $SKILL_NAME$ Like Your Old Man Always Wanted You To", + "$SKILL_NAME$: Secret Techniques", + "The Dos, Don'ts and Oh Gods Please Nos of $SKILL_NAME$", + "The Death Of $SKILL_NAME$", + "Everything You Never Wanted To Know About $SKILL_NAME$ But Have Been Reluctantly Forced To Find Out", + "$SKILL_NAME$ For The Busy Professional", + "Learning $SKILL_NAME$ In A Hurry Because You Lied On Your Resume", + "Help! My Life Suddenly Depends On $SKILL_NAME$", + "What The Fuck is $ARTICLE_SKILL_NAME$?", + "Starting $ARTICLE_SKILL_NAME$ Business By Yourself", + "Even You Can Learn $SKILL_NAME$!", + "How To Impress Your Parents with $SKILL_NAME$", + "How To Become A Master of $SKILL_NAME$", + "Everything The Government Doesn't Want You To Know About $SKILL_NAME$", + "$SKILL_NAME$ For Kids!", + "$SKILL_NAME$: Volume $RAND$", + "Understanding $SKILL_NAME$: $RAND_TH$ Edition", + "Dealing With Ungrateful Customers Dissatisfied With Your Perfectly Acceptable $SKILL_NAME$ Services", + "Really big book of $SKILL_NAME$" + ) + + // Lists used when producing custom skillbooks. + var/static/list/failure_messages = list( + "Your hand slips and you accidentally rip your pen through several pages, ruining your hard work!", + "Your pen slips, dragging a haphazard line across both open pages! Now you need to do those again!" + ) + /// Messages are in order of progress. + var/static/list/progress_messages = list( + "Still quite a few blank pages left.", + "Feels like you're near halfway done.", + "You've made good progress.", + "Just needs a few finishing touches.", + "And then finish it. Done!" + ) + var/static/list/charge_messages = list( + "Your mind instantly recoils at the idea of having to write another textbook. No thank you!", + "You are far too mentally exhausted to write another textbook. Maybe another day.", + "Your hand aches in response to the very idea of more textbook writing." + ) + +/obj/item/book/skill/Initialize() + + . = ..() + + global.events_repository.register(/decl/observ/moved, src, src, PROC_REF(check_buff)) + + if(!custom && skill && skill_req)// custom books should already have all they need + + skill_name = initial(skill.name) + + var/title_name = capitalize(skill_name) + title = replacetext(pick(skill_name_patterns), "$SKILL_NAME$", title_name) + title = replacetext(title, "$RAND$", rand(1,100)) + title = replacetext(title, "$RAND_TH$", "[rand(1,100)]\th") + title = replacetext(title, "$ARTICLE_SKILL_NAME$", capitalize(ADD_ARTICLE(title_name))) + title = "\"[title]\"" + + switch(skill_req) // check what skill_req the book has + if(SKILL_NONE) // none > basic + name = "beginner [skill_name] textbook" + desc = "A copy of [title] by [author]. The only reason this book is so big is because all the words are printed very large! Presumably so you, an idiot, can read it." + if(SKILL_BASIC) // basic > adept + name = "intermediate [skill_name] textbook" + desc = "A copy of [title] by [author]. Dry and long, but not unmanageable. Basic knowledge is required to understand the concepts written." + if(SKILL_ADEPT) // adept > expert + name = "advanced [skill_name] textbook" + desc = "A copy of [title] by [author]. Those not already trained in the subject will have a hard time reading this. Try not to drop it either, it will put a hole in the floor." + if(SKILL_EXPERT to SKILL_MAX) //expert > prof + name = "theoretical [skill_name] textbook" + desc = "A copy of [title] by [author]. Significant experience in the subject is required to read this incredibly information dense block of paper. Sadly, does not come in audio form." + + if((!skill || !skill_req) && !custom)//That's a bad book, so just grab ANY child to replace it. Custom books are fine though they can be bad if they want. + if(subtypesof(src.type)) + var/new_book = pick(subtypesof(src.type)) + new new_book(src.loc) + qdel_self() + +/datum/skill_buff/skill_book + limit = 1 // you can only read one book at a time nerd, therefore you can only get one buff at a time + +/obj/item/book/skill/get_single_monetary_worth() + . = max(..(), 200) + (100 * skill_req) + +/obj/item/book/skill/proc/check_can_read(mob/user) + if(QDELETED(user)) + return FALSE + var/effective_title = length(title) ? title : "the textbook" + if(!CanPhysicallyInteract(user)) + to_chat(user, SPAN_WARNING("You can't reach [effective_title]!")) + return FALSE + if(!skill || (custom && progress == 0)) + to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is blank!")) + return FALSE + if(custom && progress <= length(progress_messages)) + to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is unfinished! You can't learn from it in this state!")) + return FALSE + if(!ez_read &&!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) + to_chat(user, SPAN_WARNING(pick(list( + "Haha, you know you can't read. Good joke. Put [effective_title] back.", + "You open up [effective_title], but there aren't any pictures, so you close it again.", + "You don't know how to read! What good is [effective_title] to you?!" + )))) + return FALSE + + if(reading) + if(reading.resolve() != user) + to_chat(user, SPAN_WARNING("\The [reading.resolve()] is already reading [effective_title]!")) + else + to_chat(user, SPAN_WARNING("You are already reading [effective_title]!")) + return FALSE + + if(user.too_many_buffs(/datum/skill_buff/skill_book)) + to_chat(user, SPAN_WARNING("You can't read two books at once!")) + return FALSE + + if(!user.skill_check(skill, skill_req)) + to_chat(user, SPAN_WARNING("[capitalize(title)] is too advanced for you! Try something easier, perhaps the \"For Idiots\" edition?")) + return FALSE + + if(user.get_skill_value(skill) > skill_req) + to_chat(user, SPAN_WARNING("You already know everything [effective_title] has to teach you!")) + return FALSE + + return TRUE + +/obj/item/book/skill/verb/read_book() + set name = "Read Book" + set category = "Object" + set src in view(1) + try_to_read(usr) + +/obj/item/book/skill/try_to_read(mob/user) + + if(isobserver(user)) + to_chat(user, SPAN_WARNING("Ghosts can't read! Go away!")) + return TRUE + + if(isturf(loc)) + user.face_atom(src) + + if(user && user == reading?.resolve()) + //Close book, get rid of buffs + unlearn(user) + to_chat(user, SPAN_NOTICE("You close [title]. That's enough learning for now.")) + reading = null + STOP_PROCESSING(SSprocessing, src) + return TRUE + + if(!check_can_read(user)) + return FALSE + + to_chat(user, SPAN_NOTICE("You open up [title] and start reading...")) + if(!user.do_skilled(4 SECONDS, SKILL_LITERACY, src, 0.75)) + to_chat(user, SPAN_DANGER("Your perusal of [title] was interrupted!")) + return TRUE + + if(!check_can_read(user)) + return TRUE + + var/list/buff = list() + buff[skill] = 1 + user.buff_skill(buff, buff_type = /datum/skill_buff/skill_book) + reading = weakref(user) + to_chat(user, SPAN_NOTICE("You find the information you need! Better keep the page open to reference it.")) + START_PROCESSING(SSprocessing, src) + return TRUE + +// buff removal +/obj/item/book/skill/proc/unlearn(var/mob/user) + var/list/F = user.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0) + for(var/datum/skill_buff/skill_book/S in F) + S.remove() + +/obj/item/book/skill/Process() + if(!reading) + return PROCESS_KILL + check_buff() + +/obj/item/book/skill/proc/check_buff() + if(!reading) + return + var/mob/R = reading.resolve() + if(!istype(R) || !CanPhysicallyInteract(R)) + remove_buff() + +/obj/item/book/skill/proc/remove_buff() + var/mob/R = reading?.resolve() + reading = null + if(istype(R)) + to_chat(R, SPAN_DANGER("You lose the page you were on! You can't cross-reference using [title] like this!")) + if(R.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) + unlearn(R) + STOP_PROCESSING(SSprocessing, src) + +/obj/item/book/skill/Destroy() + global.events_repository.unregister(/decl/observ/moved, src, src) + remove_buff() + . = ..() + + + + + + +////////////////////// +// SHELF SHELF SHELF// +////////////////////// + +/obj/structure/bookcase/skill_books + name = "textbook bookcase" + // Contains a list of parent types but doesn't actually DO anything with them. Use a child of this book case + var/static/list/catalogue = list( + /obj/item/book/skill/organizational/finance, + /obj/item/book/skill/organizational/literacy, + /obj/item/book/skill/general/eva, + /obj/item/book/skill/general/mech, + /obj/item/book/skill/general/pilot, + /obj/item/book/skill/general/hauling, + /obj/item/book/skill/general/computer, + /obj/item/book/skill/service/botany, + /obj/item/book/skill/service/cooking, + /obj/item/book/skill/security/combat, + /obj/item/book/skill/security/weapons, + /obj/item/book/skill/security/forensics, + /obj/item/book/skill/engineering/construction, + /obj/item/book/skill/engineering/electrical, + /obj/item/book/skill/engineering/atmos, + /obj/item/book/skill/engineering/engines, + /obj/item/book/skill/research/devices, + /obj/item/book/skill/research/science, + /obj/item/book/skill/medical/chemistry, + /obj/item/book/skill/medical/medicine, + /obj/item/book/skill/medical/anatomy + ) + +//give me ALL the textbooks +/obj/structure/bookcase/skill_books/all/Initialize() + . = ..() + for(var/category in catalogue) + for(var/real_book in subtypesof(category)) + new real_book(src) + +//Bookshelf with some random textbooks +/obj/structure/bookcase/skill_books/random/Initialize() + . = ..() + for(var/category in catalogue) + for(var/real_book in subtypesof(category)) + if(prob(20)) + new real_book(src) diff --git a/code/game/objects/items/books/skill/_skill_custom.dm b/code/game/objects/items/books/skill/_skill_custom.dm new file mode 100644 index 00000000000..66fa10cf151 --- /dev/null +++ b/code/game/objects/items/books/skill/_skill_custom.dm @@ -0,0 +1,193 @@ +////////////////////// +//Custom Skill Books// +////////////////////// + +//custom skill books made by players. Right now it is extremely dodgy and bad and i'm sorry +/obj/item/book/skill/custom + name = "blank textbook" + desc = "A somewhat heftier blank book, just ready to filled with knowledge and sold at an unreasonable price." + custom = TRUE + author = null + progress = 0 + icon_state = "tb_white" + var/skill_option_string = "Skill" //changes to "continue writing content" when the book is in progress + var/true_author //Used to keep track of who is actually writing the book. + var/writing_time = 15 SECONDS // time it takes to write a segment of the book. This happens 6 times total + +//these all show up in the book fabricator +/obj/item/book/skill/custom/circle + icon_state = "tb_white_circle" +/obj/item/book/skill/custom/star + icon_state = "tb_white_star" +/obj/item/book/skill/custom/hourglass + icon_state = "tb_white_hourglass" +/obj/item/book/skill/custom/cracked + icon_state = "tb_white_cracked" +/obj/item/book/skill/custom/gun + icon_state = "tb_white_gun" +/obj/item/book/skill/custom/wrench + icon_state = "tb_white_wrench" +/obj/item/book/skill/custom/glass + icon_state = "tb_white_glass" + +/obj/item/book/skill/custom/cross + icon_state = "tb_white_cross" +/obj/item/book/skill/custom/text + icon_state = "tb_white_text" +/obj/item/book/skill/custom/download + icon_state = "tb_white_download" +/obj/item/book/skill/custom/uparrow + icon_state = "tb_white_uparrow" +/obj/item/book/skill/custom/percent + icon_state = "tb_white_percent" +/obj/item/book/skill/custom/flask + icon_state = "tb_white_flask" +/obj/item/book/skill/custom/detective + icon_state = "tb_white_detective" +/obj/item/book/skill/custom/device + icon_state = "tb_white_device" +/obj/item/book/skill/custom/smile + icon_state = "tb_white_smile" +/obj/item/book/skill/custom/exclamation + icon_state = "tb_white_exclamation" +/obj/item/book/skill/custom/question + icon_state = "tb_white_question" + +/obj/item/book/skill/custom/attackby(obj/item/pen, mob/user) + if(IS_PEN(pen)) + + if(!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) + to_chat(user, SPAN_WARNING("You can't even read, yet you want to write a whole educational textbook?")) + return + if(!user.skill_check(SKILL_LITERACY, SKILL_PROF)) + to_chat(user, SPAN_WARNING("You have no clue as to how to write an entire textbook in a way that is actually useful. Maybe a regular book would be better?")) + return + var/state_check = skill_option_string // the state skill_option_string is in just before opening the input + var/choice = input(user, "What would you like to change?","Textbook editing") as null|anything in list("Title", "Author", skill_option_string) + if(!can_write(pen,user)) + return + + switch(choice) + if("Title") + edit_title(pen, user) + + if("Skill") + if(state_check != "Skill") // make sure someone hasn't already started the book while we were staring at menus woops + to_chat(user, SPAN_WARNING("The skill has already been selected and the writing started.")) + return + edit_skill(pen, user) + + if("Continue writing content") + if(state_check != "Continue writing content") + return + continue_skill(pen, user) + + if("Author") + edit_author(pen, user) + + else + return + + if(skill && title && author) // we have everything we need so lets set a good description + desc = "A handwritten textbook titled [title], by [author]. Looks like it teaches [skill_name]." + return + ..() + +/obj/item/book/skill/custom/proc/can_write(var/obj/item/pen, var/mob/user) + if(user.get_active_hand() == pen && CanPhysicallyInteractWith(user,src) && !QDELETED(src) && !QDELETED(pen)) + return TRUE + else + to_chat(user,SPAN_DANGER("How can you expect to write anything when you can't physically put pen to paper?")) + return FALSE + +/obj/item/book/skill/custom/proc/edit_title(var/obj/item/pen, var/mob/user) + var/newtitle = reject_bad_text(sanitize_safe(input(user, "Write a new title:"))) + if(!can_write(pen,user)) + return + if(!newtitle) + to_chat(user, "The title is invalid.") + return + else + newtitle = user.handle_writing_literacy(user, newtitle) + if(newtitle) + title = newtitle + SetName(title) + +/obj/item/book/skill/custom/proc/edit_author(var/obj/item/pen, var/mob/user) + var/newauthor = sanitize(input(user, "Write the author's name:")) + if(!can_write(pen,user)) + return + if(!newauthor) + to_chat(user, SPAN_WARNING("The author name is invalid.")) + return + else + newauthor = user.handle_writing_literacy(user, newauthor) + if(newauthor) + author = newauthor + +/obj/item/book/skill/custom/proc/edit_skill(var/obj/item/pen, var/mob/user) + if(user.skillset.literacy_charges <= 0) + to_chat(user, SPAN_WARNING(pick(charge_messages))) + return + + //Choosing the skill + var/list/skill_choices = list() + for(var/decl/hierarchy/skill/S in global.skills) + if(user.skill_check(S.type, SKILL_BASIC)) + LAZYADD(skill_choices, S) + var/decl/hierarchy/skill/skill_choice = input(user, "What subject does your textbook teach?", "Textbook skill selection") as null|anything in skill_choices + if(!can_write(pen,user) || progress > length(progress_messages)) + return + if(!skill_choice) + to_chat(user, SPAN_WARNING("Textbook skill selection cancelled.")) + return + var/newskill = skill_choice.type + + //Choosing the level + var/list/skill_levels = skill_choice.levels.Copy() + for(var/SL in skill_levels) + if(!user.skill_check(newskill, skill_levels.Find(SL))) + LAZYREMOVE(skill_levels, SL) + else + skill_levels[SL] = skill_levels.Find(SL) + LAZYREMOVE(skill_levels,skill_levels[1]) + var/newskill_level = input(user, "What level of education does it provide?","Textbook skill level") as null|anything in skill_levels + if(!can_write(pen,user) || progress > length(progress_messages)) + return + if(!newskill_level) + to_chat(user, SPAN_WARNING("Textbook skill level selection cancelled.")) + return + var/usable_level = skill_levels[newskill_level] + if(newskill && usable_level) + if(!do_after(user, writing_time, src)) + to_chat(user, SPAN_DANGER(pick(failure_messages))) + return + //everything worked out so now we can put the learnings in the book + to_chat(user, SPAN_NOTICE("You start writing your book, getting a few pages in.")) + skill = newskill + skill_name = skill_choice.name + skill_req = (usable_level - 1) + desc = "A handwritten textbook on [skill_choice]! Wow!" + progress++ + skill_option_string = "Continue writing content" + true_author = user.name + +/obj/item/book/skill/custom/proc/continue_skill(var/obj/item/pen, var/mob/user) + if(user.skillset.literacy_charges <= 0) + to_chat(user, SPAN_WARNING(pick(charge_messages))) + return + if(progress > length(progress_messages)) // shouldn't happen but here just in case + to_chat(user, SPAN_WARNING("This book is already finished! There's no need to add anything else!")) + return + if(true_author != user.name) + to_chat(user, SPAN_WARNING("This isn't your work and you're not really sure how to continue it.")) + return + else + if(!do_after(user, writing_time, src)) + to_chat(user, SPAN_DANGER(pick(failure_messages))) + return + to_chat(user, SPAN_NOTICE("You continue writing your book. [progress_messages[progress]]")) + progress++ + if(progress > length(progress_messages)) // book is finished! yay! + user.skillset.literacy_charges -= 1 + skill_option_string = "Cancel" \ No newline at end of file diff --git a/code/game/objects/items/books/skill/engineering.dm b/code/game/objects/items/books/skill/engineering.dm new file mode 100644 index 00000000000..077a2486740 --- /dev/null +++ b/code/game/objects/items/books/skill/engineering.dm @@ -0,0 +1,96 @@ +/* +ENGINEERING +*/ +/obj/item/book/skill/engineering + abstract_type = /obj/item/book/skill/engineering + icon_state = "bookEngineering" + +//construction +/obj/item/book/skill/engineering/construction/ + author = "Robert Bildar" + skill = SKILL_CONSTRUCTION + +/obj/item/book/skill/engineering/construction/basic + name = "beginner construction textbook" + +/obj/item/book/skill/engineering/construction/adept + skill_req = SKILL_BASIC + name = "intermediate construction textbook" + +/obj/item/book/skill/engineering/construction/expert + skill_req = SKILL_ADEPT + name = "advanced construction textbook" + +/obj/item/book/skill/engineering/construction/prof + skill_req = SKILL_EXPERT + name = "theoretical construction textbook" + +//electrical +/obj/item/book/skill/engineering/electrical + skill = SKILL_ELECTRICAL + author = "Ariana Vanderbalt" + +/obj/item/book/skill/engineering/electrical/basic + name = "beginner electrical engineering textbook" + +/obj/item/book/skill/engineering/electrical/adept + skill_req = SKILL_BASIC + name = "intermediate electrical engineering textbook" + +/obj/item/book/skill/engineering/electrical/expert + skill_req = SKILL_ADEPT + name = "advanced electrical engineering textbook" + +/obj/item/book/skill/engineering/electrical/prof + skill_req = SKILL_EXPERT + name = "theoretical electrical engineering textbook" + +//engines +/obj/item/book/skill/engineering/engines + skill = SKILL_ENGINES + author = "Gilgamesh Scholz" + +/obj/item/book/skill/engineering/engines/basic + name = "beginner engines textbook" + +/obj/item/book/skill/engineering/engines/adept + skill_req = SKILL_BASIC + name = "intermediate engines textbook" + +/obj/item/book/skill/engineering/engines/expert + skill_req = SKILL_ADEPT + name = "advanced engines textbook" + +/obj/item/book/skill/engineering/engines/prof + skill_req = SKILL_EXPERT + name = "theoretical engines textbook" + +/obj/item/book/skill/engineering/engines/prof/magazine + name = "theoretical engines magazine" + title = "\improper WetSkrell magazine" + icon_state = "bookMagazine" + custom = TRUE + author = "Unknown" + desc = "Sure, it includes highly detailed information on extremely advanced engine and power generator systems... but why is it written in marker on a tentacle porn magazine?" + w_class = ITEM_SIZE_NORMAL + +//atmos +/obj/item/book/skill/engineering/atmos + skill = SKILL_ATMOS + author = "Maria Crash" + icon_state = "pipingbook" + +/obj/item/book/skill/engineering/atmos/basic + name = "beginner atmospherics textbook" + +/obj/item/book/skill/engineering/atmos/adept + skill_req = SKILL_BASIC + name = "intermediate atmospherics textbook" + +/obj/item/book/skill/engineering/atmos/expert + skill_req = SKILL_ADEPT + name = "advanced atmospherics textbook" + +/obj/item/book/skill/engineering/atmos/prof + skill_req = SKILL_EXPERT + name = "theoretical atmospherics textbook" diff --git a/code/game/objects/items/books/skill/general.dm b/code/game/objects/items/books/skill/general.dm new file mode 100644 index 00000000000..5696db54a14 --- /dev/null +++ b/code/game/objects/items/books/skill/general.dm @@ -0,0 +1,110 @@ +/* +GENERAL +*/ +/obj/item/book/skill/general + abstract_type = /obj/item/book/skill/general + +//eva +/obj/item/book/skill/general/eva + icon_state = "evabook" + skill = SKILL_EVA + author = "Big Dark" + +/obj/item/book/skill/general/eva/basic + name = "beginner extra-vehicular activity textbook" + +/obj/item/book/skill/general/eva/adept + skill_req = SKILL_BASIC + name = "intermediate extra-vehicular activity textbook" + +/obj/item/book/skill/general/eva/expert + skill_req = SKILL_ADEPT + name = "advanced extra-vehicular activity textbook" + +/obj/item/book/skill/general/eva/prof + skill_req = SKILL_EXPERT + name = "theoretical extra-vehicular activity textbook" + +//mech +/obj/item/book/skill/general/mech + icon_state = "tb_mech" + skill = SKILL_MECH + author = "J.T. Marsh" + +/obj/item/book/skill/general/mech/basic + name = "beginner exosuit operation textbook" + +/obj/item/book/skill/general/mech/adept + skill_req = SKILL_BASIC + name = "intermediate exosuit operation textbook" + +/obj/item/book/skill/general/mech/expert + skill_req = SKILL_ADEPT + name = "advanced exosuit operation textbook" + +/obj/item/book/skill/general/mech/prof + skill_req = SKILL_EXPERT + name = "theoretical exosuit operation textbook" + +//piloting +/obj/item/book/skill/general/pilot + skill = SKILL_PILOT + author = "Sumi Shimamoto" + icon_state = "tb_pilot" + +/obj/item/book/skill/general/pilot/basic + name = "beginner piloting textbook" + +/obj/item/book/skill/general/pilot/adept + skill_req = SKILL_BASIC + name = "intermediate piloting textbook" + +/obj/item/book/skill/general/pilot/expert + skill_req = SKILL_ADEPT + name = "advanced piloting textbook" + +/obj/item/book/skill/general/pilot/prof + skill_req = SKILL_EXPERT + name = "theoretical piloting textbook" + +//hauling +/obj/item/book/skill/general/hauling + skill = SKILL_HAULING + author = "Chiel Brunt" + icon_state = "tb_hauling" + +/obj/item/book/skill/general/hauling/basic + name = "beginner athletics textbook" + +/obj/item/book/skill/general/hauling/adept + skill_req = SKILL_BASIC + name = "intermediate athletics textbook" + +/obj/item/book/skill/general/hauling/expert + skill_req = SKILL_ADEPT + name = "advanced athletics textbook" + +/obj/item/book/skill/general/hauling/prof + skill_req = SKILL_EXPERT + name = "theoretical athletics textbook" + +//computer +/obj/item/book/skill/general/computer + skill = SKILL_COMPUTER + author = "Simona Castiglione" + icon_state = "bookNuclear" + +/obj/item/book/skill/general/computer/basic + name = "beginner information technology textbook" + +/obj/item/book/skill/general/computer/adept + skill_req = SKILL_BASIC + name = "intermediate information technology textbook" + +/obj/item/book/skill/general/computer/expert + skill_req = SKILL_ADEPT + name = "advanced information technology textbook" + +/obj/item/book/skill/general/computer/prof + skill_req = SKILL_EXPERT + name = "theoretical information technology textbook" diff --git a/code/game/objects/items/books/skill/medical.dm b/code/game/objects/items/books/skill/medical.dm new file mode 100644 index 00000000000..9caeeb1699f --- /dev/null +++ b/code/game/objects/items/books/skill/medical.dm @@ -0,0 +1,71 @@ +/* +MEDICAL +*/ +/obj/item/book/skill/medical + abstract_type = /obj/item/book/skill/medical + icon_state = "bookMedical" + +//chemistry +/obj/item/book/skill/medical/chemistry + icon_state = "chemistry" + author = "Dr. Shinula Nyekundujicho" + skill = SKILL_CHEMISTRY + +/obj/item/book/skill/medical/chemistry/basic + name = "beginner chemistry textbook" + +/obj/item/book/skill/medical/chemistry/adept + skill_req = SKILL_BASIC + name = "intermediate chemistry textbook" + +/obj/item/book/skill/medical/chemistry/expert + skill_req = SKILL_ADEPT + name = "advanced chemistry textbook" + +/obj/item/book/skill/medical/chemistry/prof + skill_req = SKILL_EXPERT + name = "theoretical chemistry textbook" + +//medicine +/obj/item/book/skill/medical/medicine + author = "Dr. Nagarjuna Siddha" + skill = SKILL_MEDICAL + +/obj/item/book/skill/medical/medicine/basic + name = "beginner medicine textbook" + title = "\"Instructional Guide on How Rubbing Dirt In Wounds Might Not Be The Right Approach To Stopping Bleeding Anymore\"" + desc = "A copy of \"Instructional Guide on How Rubbing Dirt In Wounds Might Not Be The Right Approach To Stopping Bleeding Anymore\" by Dr. Merrs. Despite the information density of this heavy book, it lacks any and all teachings regarding bedside manner." + author = "Dr. Merrs" + custom = TRUE + +/obj/item/book/skill/medical/medicine/adept + skill_req = SKILL_BASIC + name = "intermediate medicine textbook" + +/obj/item/book/skill/medical/medicine/expert + skill_req = SKILL_ADEPT + name = "advanced medicine textbook" + +/obj/item/book/skill/medical/medicine/prof + skill_req = SKILL_EXPERT + name = "theoretical medicine textbook" + +//anatomy +/obj/item/book/skill/medical/anatomy + author = "Dr. Basil Cartwright" + skill = SKILL_ANATOMY + +/obj/item/book/skill/medical/anatomy/basic + name = "beginner anatomy textbook" + +/obj/item/book/skill/medical/anatomy/adept + skill_req = SKILL_BASIC + name = "intermediate anatomy textbook" + +/obj/item/book/skill/medical/anatomy/expert + skill_req = SKILL_ADEPT + name = "advanced anatomy textbook" + +/obj/item/book/skill/medical/anatomy/prof + skill_req = SKILL_EXPERT + name = "theoretical anatomy textbook" \ No newline at end of file diff --git a/code/game/objects/items/books/skill/organizational.dm b/code/game/objects/items/books/skill/organizational.dm new file mode 100644 index 00000000000..87b37123301 --- /dev/null +++ b/code/game/objects/items/books/skill/organizational.dm @@ -0,0 +1,38 @@ +/* +ORGANIZATIONAL +*/ +/obj/item/book/skill/organizational + abstract_type = /obj/item/book/skill/organizational + +//literacy +/obj/item/book/skill/organizational/literacy + skill = SKILL_LITERACY + +/obj/item/book/skill/organizational/literacy/basic + name = "alphabet book" + icon_state = "tb_literacy" + author = "Dorothy Mulch" + custom = TRUE + w_class = ITEM_SIZE_NORMAL // A little bit smaller c: + ez_read = TRUE + +//finance +/obj/item/book/skill/organizational/finance + skill = SKILL_FINANCE + author = "Cadence Bennett" + icon_state = "tb_finance" + +/obj/item/book/skill/organizational/finance/basic + name = "beginner finance textbook" + +/obj/item/book/skill/organizational/finance/adept + skill_req = SKILL_BASIC + name = "intermediate finance textbook" + +/obj/item/book/skill/organizational/finance/expert + skill_req = SKILL_ADEPT + name = "advanced finance textbook" + +/obj/item/book/skill/organizational/finance/prof + skill_req = SKILL_EXPERT + name = "theoretical finance textbook" diff --git a/code/game/objects/items/books/skill/research.dm b/code/game/objects/items/books/skill/research.dm new file mode 100644 index 00000000000..4c1a666af74 --- /dev/null +++ b/code/game/objects/items/books/skill/research.dm @@ -0,0 +1,46 @@ +/* +RESEARCH +*/ +/obj/item/book/skill/research + abstract_type = /obj/item/book/skill/research + icon_state = "analysis" + +//devices +/obj/item/book/skill/research/devices + author = "Nilva Plosinjak" + skill = SKILL_DEVICES + +/obj/item/book/skill/research/devices/basic + name = "beginner complex devices textbook" + +/obj/item/book/skill/research/devices/adept + skill_req = SKILL_BASIC + name = "intermediate complex devices textbook" + +/obj/item/book/skill/research/devices/expert + skill_req = SKILL_ADEPT + name = "advanced complex devices textbook" + +/obj/item/book/skill/research/devices/prof + skill_req = SKILL_EXPERT + name = "theoretical complex devices textbook" + +//science +/obj/item/book/skill/research/science + author = "Hui Ying Ch'ien" + skill = SKILL_SCIENCE + +/obj/item/book/skill/research/science/basic + name = "beginner science textbook" + +/obj/item/book/skill/research/science/adept + skill_req = SKILL_BASIC + name = "intermediate science textbook" + +/obj/item/book/skill/research/science/expert + skill_req = SKILL_ADEPT + name = "advanced science textbook" + +/obj/item/book/skill/research/science/prof + skill_req = SKILL_EXPERT + name = "theoretical science textbook" diff --git a/code/game/objects/items/books/skill/security.dm b/code/game/objects/items/books/skill/security.dm new file mode 100644 index 00000000000..4fdfd1367a8 --- /dev/null +++ b/code/game/objects/items/books/skill/security.dm @@ -0,0 +1,69 @@ +/* +SECURITY +*/ +/obj/item/book/skill/security + abstract_type = /obj/item/book/skill/security + icon_state = "bookSpaceLaw" + +//combat +/obj/item/book/skill/security/combat + skill = SKILL_COMBAT + author = "Autumn Eckhardstein" + icon_state = "tb_combat" + +/obj/item/book/skill/security/combat/basic + name = "beginner close combat textbook" + +/obj/item/book/skill/security/combat/adept + skill_req = SKILL_BASIC + name = "intermediate close combat textbook" + +/obj/item/book/skill/security/combat/expert + skill_req = SKILL_ADEPT + name = "advanced close combat textbook" + +/obj/item/book/skill/security/combat/prof + skill_req = SKILL_EXPERT + name = "theoretical close combat textbook" + +//weapons +/obj/item/book/skill/security/weapons + skill = SKILL_WEAPONS + author = "Miho Tatsu" + icon_state = "tb_weapon" + +/obj/item/book/skill/security/weapons/basic + name = "beginner weapons expertise textbook" + +/obj/item/book/skill/security/weapons/adept + skill_req = SKILL_BASIC + name = "intermediate weapons expertise textbook" + +/obj/item/book/skill/security/weapons/expert + skill_req = SKILL_ADEPT + name = "advanced weapons expertise textbook" + +/obj/item/book/skill/security/weapons/prof + skill_req = SKILL_EXPERT + name = "theoretical weapons expertise textbook" + +//forensics +/obj/item/book/skill/security/forensics + icon_state = "bookDetective" + skill = SKILL_FORENSICS + author = "Samuel Vimes" + +/obj/item/book/skill/security/forensics/basic + name = "beginner forensics textbook" + +/obj/item/book/skill/security/forensics/adept + skill_req = SKILL_BASIC + name = "intermediate forensics textbook" + +/obj/item/book/skill/security/forensics/expert + skill_req = SKILL_ADEPT + name = "advanced forensics textbook" + +/obj/item/book/skill/security/forensics/prof + skill_req = SKILL_EXPERT + name = "theoretical forensics textbook" diff --git a/code/game/objects/items/books/skill/service.dm b/code/game/objects/items/books/skill/service.dm new file mode 100644 index 00000000000..04d93d9341b --- /dev/null +++ b/code/game/objects/items/books/skill/service.dm @@ -0,0 +1,47 @@ +/* +SERVICE +*/ +/obj/item/book/skill/service + abstract_type = /obj/item/book/skill/service + +//botany +/obj/item/book/skill/service/botany + icon_state = "bookHydroponicsPodPeople" + skill = SKILL_BOTANY + author = "Mai Dong Chat" + +/obj/item/book/skill/service/botany/basic + name = "beginner botany textbook" + +/obj/item/book/skill/service/botany/adept + skill_req = SKILL_BASIC + name = "intermediate botany textbook" + +/obj/item/book/skill/service/botany/expert + skill_req = SKILL_ADEPT + name = "advanced botany textbook" + +/obj/item/book/skill/service/botany/prof + skill_req = SKILL_EXPERT + name = "theoretical botany textbook" + +//cooking +/obj/item/book/skill/service/cooking + icon_state = "barbook" + skill = SKILL_COOKING + author = "Lavinia Burrows" + +/obj/item/book/skill/service/cooking/basic + name = "beginner cooking textbook" + +/obj/item/book/skill/service/cooking/adept + skill_req = SKILL_BASIC + name = "intermediate cooking textbook" + +/obj/item/book/skill/service/cooking/expert + skill_req = SKILL_ADEPT + name = "advanced cooking textbook" + +/obj/item/book/skill/service/cooking/prof + skill_req = SKILL_EXPERT + name = "theoretical cooking textbook" diff --git a/code/game/objects/items/books/skill_book.dm b/code/game/objects/items/books/skill_book.dm deleted file mode 100644 index f510e66679e..00000000000 --- a/code/game/objects/items/books/skill_book.dm +++ /dev/null @@ -1,945 +0,0 @@ -#define RANDOM_BOOK_TITLE(skill_name) pick(list("\"[skill_name] for Idiots\"", \ - "\"How To Learn [skill_name] and Not Get Laughed At\"", \ - "\"Teaching Yourself [skill_name]: Volume [rand(1,100)]\"", \ - "\"Getting the Hands-Off Experience You Need with [skill_name]\"", \ - "\"Master [skill_name] in [rand(100,999)] easy steps!\"", \ - "\"[skill_name] Just Like Mum\"", \ - "\"How To [skill_name] Good Enough For Your Father\"", \ - "\"How To Win Your Dad's Approval With [skill_name]\"", \ - "\"Make a Living with [skill_name] Like Your Old Man Always Wanted You To\"", \ - "\"[skill_name]: Secret Techniques\"", \ - "\"The Dos, Don'ts and Oh Gods Please Nos of [skill_name]\"", \ - "\"The Death Of [skill_name]\"", \ - "\"Everything You Never Wanted To Know About [skill_name] But Have Been Reluctantly Forced To Find Out\"", \ - "\"[skill_name] For The Busy Professional\"", \ - "\"Learning [skill_name] In A Hurry Because You Lied On Your Resume\"", \ - "\"Help! My Life Suddenly Depends On [skill_name]\"", \ - "\"What The Fuck is [capitalize(ADD_ARTICLE(capitalize(skill_name)))]?\"", \ - "\"Starting [capitalize(ADD_ARTICLE(capitalize(skill_name)))] Business By Yourself\"", \ - "\"Even You Can Learn [skill_name]!\"", \ - "\"How To Impress Your Parents with [skill_name]\"", \ - "\"How To Become A Master of [skill_name]\"", \ - "\"Everything The Government Doesn't Want You To Know About [skill_name]\"", \ - "\"[skill_name] For Younglets\"", \ - "\"[skill_name]: Volume [rand(1,100)]\"", \ - "\"Understanding [skill_name]: [rand(1,100)]\th Edition\"", \ - "\"Dealing With Ungrateful Customers Dissatisfied With Your Perfectly Acceptable [skill_name] Services\"", \ - "\"Really big book of [skill_name]\"")) -#define SKILLBOOK_PROG_NONE 0 -#define SKILLBOOK_PROG_FINISH 6 - -/* -Skill books that increase your skills while you activate and hold them -*/ - -/obj/item/book/skill - name = "textbook" // requires default names for tradershop, cant rely on Initialize for names - desc = "A blank textbook. (Notify admin)" - author = "The Oracle of Bakersroof" - icon_state = "book2" - force = 4 - w_class = ITEM_SIZE_LARGE // Skill books are THICC with knowledge. Up one level from regular books to prevent library-in-a-bag silliness. - unique = TRUE - material = /decl/material/solid/organic/plastic - matter = list(/decl/material/solid/organic/wood = MATTER_AMOUNT_REINFORCEMENT) - abstract_type = /obj/item/book/skill - - var/decl/hierarchy/skill/skill // e.g. SKILL_LITERACY - var/skill_req = SKILL_NONE // The level the user needs in the skill to benefit from the book, e.g. SKILL_PROF - var/weakref/reading // To check if the book is actively being used - var/custom = FALSE // To bypass init stuff, for player made textbooks and weird books. If true must have details manually set - var/ez_read = FALSE // Set to TRUE if you can read it without basic literacy skills - - var/skill_name = "missing skill name" - var/progress = SKILLBOOK_PROG_FINISH // used to track the progress of making a custom book. defaults as finished so, you know, you can read the damn thing - -/obj/item/book/skill/Initialize() - - . = ..() - - global.events_repository.register(/decl/observ/moved, src, src, .proc/check_buff) - - if(!custom && skill && skill_req)// custom books should already have all they need - skill_name = initial(skill.name) - title = RANDOM_BOOK_TITLE(capitalize(skill_name)) - switch(skill_req) // check what skill_req the book has - if(SKILL_NONE) // none > basic - name = "beginner [skill_name] textbook" - desc = "A copy of [title] by [author]. The only reason this book is so big is because all the words are printed very large! Presumably so you, an idiot, can read it." - if(SKILL_BASIC) // basic > adept - name = "intermediate [skill_name] textbook" - desc = "A copy of [title] by [author]. Dry and long, but not unmanageable. Basic knowledge is required to understand the concepts written." - if(SKILL_ADEPT) // adept > expert - name = "advanced [skill_name] textbook" - desc = "A copy of [title] by [author]. Those not already trained in the subject will have a hard time reading this. Try not to drop it either, it will put a hole in the floor." - if(SKILL_EXPERT to SKILL_MAX) //expert > prof - name = "theoretical [skill_name] textbook" - desc = "A copy of [title] by [author]. Significant experience in the subject is required to read this incredibly information dense block of paper. Sadly, does not come in audio form." - - if((!skill || !skill_req) && !custom)//That's a bad book, so just grab ANY child to replace it. Custom books are fine though they can be bad if they want. - if(subtypesof(src.type)) - var/new_book = pick(subtypesof(src.type)) - new new_book(src.loc) - qdel_self() - -/datum/skill_buff/skill_book - limit = 1 // you can only read one book at a time nerd, therefore you can only get one buff at a time - -/obj/item/book/skill/get_single_monetary_worth() - . = max(..(), 200) + (100 * skill_req) - -/obj/item/book/skill/proc/check_can_read(mob/user) - if(QDELETED(user)) - return FALSE - var/effective_title = length(title) ? title : "the textbook" - if(!CanPhysicallyInteract(user)) - to_chat(user, SPAN_WARNING("You can't reach [effective_title]!")) - return FALSE - if(!skill || (custom && progress == SKILLBOOK_PROG_NONE)) - to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is blank!")) - return FALSE - if(custom && progress < SKILLBOOK_PROG_FINISH) - to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is unfinished! You can't learn from it in this state!")) - return FALSE - if(!ez_read &&!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) - to_chat(user, SPAN_WARNING(pick(list( - "Haha, you know you can't read. Good joke. Put [effective_title] back.", - "You open up [effective_title], but there aren't any pictures, so you close it again.", - "You don't know how to read! What good is [effective_title] to you?!" - )))) - return FALSE - - if(reading) - if(reading.resolve() != user) - to_chat(user, SPAN_WARNING("\The [reading.resolve()] is already reading [effective_title]!")) - else - to_chat(user, SPAN_WARNING("You are already reading [effective_title]!")) - return FALSE - - if(user.too_many_buffs(/datum/skill_buff/skill_book)) - to_chat(user, SPAN_WARNING("You can't read two books at once!")) - return FALSE - - if(!user.skill_check(skill, skill_req)) - to_chat(user, SPAN_WARNING("[capitalize(title)] is too advanced for you! Try something easier, perhaps the \"For Idiots\" edition?")) - return FALSE - - if(user.get_skill_value(skill) > skill_req) - to_chat(user, SPAN_WARNING("You already know everything [effective_title] has to teach you!")) - return FALSE - - return TRUE - -/obj/item/book/skill/verb/read_book() - set name = "Read Book" - set category = "Object" - set src in view(1) - try_to_read(usr) - -/obj/item/book/skill/try_to_read(mob/user) - - if(isobserver(user)) - to_chat(user, SPAN_WARNING("Ghosts can't read! Go away!")) - return TRUE - - if(isturf(loc)) - user.face_atom(src) - - if(user && user == reading?.resolve()) - //Close book, get rid of buffs - unlearn(user) - to_chat(user, SPAN_NOTICE("You close [title]. That's enough learning for now.")) - reading = null - STOP_PROCESSING(SSprocessing, src) - return TRUE - - if(!check_can_read(user)) - return FALSE - - to_chat(user, SPAN_NOTICE("You open up [title] and start reading...")) - if(!user.do_skilled(4 SECONDS, SKILL_LITERACY, src, 0.75)) - to_chat(user, SPAN_DANGER("Your perusal of [title] was interrupted!")) - return TRUE - - if(!check_can_read(user)) - return TRUE - - var/list/buff = list() - buff[skill] = 1 - user.buff_skill(buff, buff_type = /datum/skill_buff/skill_book) - reading = weakref(user) - to_chat(user, SPAN_NOTICE("You find the information you need! Better keep the page open to reference it.")) - START_PROCESSING(SSprocessing, src) - return TRUE - -// buff removal -/obj/item/book/skill/proc/unlearn(var/mob/user) - var/list/F = user.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0) - for(var/datum/skill_buff/skill_book/S in F) - S.remove() - -/obj/item/book/skill/Process() - if(!reading) - return PROCESS_KILL - check_buff() - -/obj/item/book/skill/proc/check_buff() - if(!reading) - return - var/mob/R = reading.resolve() - if(!istype(R) || !CanPhysicallyInteract(R)) - remove_buff() - -/obj/item/book/skill/proc/remove_buff() - var/mob/R = reading?.resolve() - reading = null - if(istype(R)) - to_chat(R, SPAN_DANGER("You lose the page you were on! You can't cross-reference using [title] like this!")) - if(R.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) - unlearn(R) - STOP_PROCESSING(SSprocessing, src) - -/obj/item/book/skill/Destroy() - global.events_repository.unregister(/decl/observ/moved, src, src) - remove_buff() - . = ..() - -//////////////////////////////// -//THIS IS WHERE THE BOOKS LIVE// -//////////////////////////////// - -/* -ORGANIZATIONAL -*/ -/obj/item/book/skill/organizational - abstract_type = /obj/item/book/skill/organizational - -//literacy -/obj/item/book/skill/organizational/literacy - skill = SKILL_LITERACY - -/obj/item/book/skill/organizational/literacy/basic - name = "alphabet book" - icon_state = "tb_literacy" - author = "Dorothy Mulch" - custom = TRUE - w_class = ITEM_SIZE_NORMAL // A little bit smaller c: - ez_read = TRUE - -//finance -/obj/item/book/skill/organizational/finance - skill = SKILL_FINANCE - author = "Cadence Bennett" - icon_state = "tb_finance" - -/obj/item/book/skill/organizational/finance/basic - name = "beginner finance textbook" - -/obj/item/book/skill/organizational/finance/adept - skill_req = SKILL_BASIC - name = "intermediate finance textbook" - -/obj/item/book/skill/organizational/finance/expert - skill_req = SKILL_ADEPT - name = "advanced finance textbook" - -/obj/item/book/skill/organizational/finance/prof - skill_req = SKILL_EXPERT - name = "theoretical finance textbook" - -/* -GENERAL -*/ -/obj/item/book/skill/general - abstract_type = /obj/item/book/skill/general - -//eva -/obj/item/book/skill/general/eva - icon_state = "evabook" - skill = SKILL_EVA - author = "Big Dark" - -/obj/item/book/skill/general/eva/basic - name = "beginner extra-vehicular activity textbook" - -/obj/item/book/skill/general/eva/adept - skill_req = SKILL_BASIC - name = "intermediate extra-vehicular activity textbook" - -/obj/item/book/skill/general/eva/expert - skill_req = SKILL_ADEPT - name = "advanced extra-vehicular activity textbook" - -/obj/item/book/skill/general/eva/prof - skill_req = SKILL_EXPERT - name = "theoretical extra-vehicular activity textbook" - -//mech -/obj/item/book/skill/general/mech - icon_state = "tb_mech" - skill = SKILL_MECH - author = "J.T. Marsh" - -/obj/item/book/skill/general/mech/basic - name = "beginner exosuit operation textbook" - -/obj/item/book/skill/general/mech/adept - skill_req = SKILL_BASIC - name = "intermediate exosuit operation textbook" - -/obj/item/book/skill/general/mech/expert - skill_req = SKILL_ADEPT - name = "advanced exosuit operation textbook" - -/obj/item/book/skill/general/mech/prof - skill_req = SKILL_EXPERT - name = "theoretical exosuit operation textbook" - -//piloting -/obj/item/book/skill/general/pilot - skill = SKILL_PILOT - author = "Sumi Shimamoto" - icon_state = "tb_pilot" - -/obj/item/book/skill/general/pilot/basic - name = "beginner piloting textbook" - -/obj/item/book/skill/general/pilot/adept - skill_req = SKILL_BASIC - name = "intermediate piloting textbook" - -/obj/item/book/skill/general/pilot/expert - skill_req = SKILL_ADEPT - name = "advanced piloting textbook" - -/obj/item/book/skill/general/pilot/prof - skill_req = SKILL_EXPERT - name = "theoretical piloting textbook" - -//hauling -/obj/item/book/skill/general/hauling - skill = SKILL_HAULING - author = "Chiel Brunt" - icon_state = "tb_hauling" - -/obj/item/book/skill/general/hauling/basic - name = "beginner athletics textbook" - -/obj/item/book/skill/general/hauling/adept - skill_req = SKILL_BASIC - name = "intermediate athletics textbook" - -/obj/item/book/skill/general/hauling/expert - skill_req = SKILL_ADEPT - name = "advanced athletics textbook" - -/obj/item/book/skill/general/hauling/prof - skill_req = SKILL_EXPERT - name = "theoretical athletics textbook" - -//computer -/obj/item/book/skill/general/computer - skill = SKILL_COMPUTER - author = "Simona Castiglione" - icon_state = "bookNuclear" - -/obj/item/book/skill/general/computer/basic - name = "beginner information technology textbook" - -/obj/item/book/skill/general/computer/adept - skill_req = SKILL_BASIC - name = "intermediate information technology textbook" - -/obj/item/book/skill/general/computer/expert - skill_req = SKILL_ADEPT - name = "advanced information technology textbook" - -/obj/item/book/skill/general/computer/prof - skill_req = SKILL_EXPERT - name = "theoretical information technology textbook" - -/* -SERVICE -*/ -/obj/item/book/skill/service - abstract_type = /obj/item/book/skill/service - -//botany -/obj/item/book/skill/service/botany - icon_state = "bookHydroponicsPodPeople" - skill = SKILL_BOTANY - author = "Mai Dong Chat" - -/obj/item/book/skill/service/botany/basic - name = "beginner botany textbook" - -/obj/item/book/skill/service/botany/adept - skill_req = SKILL_BASIC - name = "intermediate botany textbook" - -/obj/item/book/skill/service/botany/expert - skill_req = SKILL_ADEPT - name = "advanced botany textbook" - -/obj/item/book/skill/service/botany/prof - skill_req = SKILL_EXPERT - name = "theoretical botany textbook" - -//cooking -/obj/item/book/skill/service/cooking - icon_state = "barbook" - skill = SKILL_COOKING - author = "Lavinia Burrows" - -/obj/item/book/skill/service/cooking/basic - name = "beginner cooking textbook" - -/obj/item/book/skill/service/cooking/adept - skill_req = SKILL_BASIC - name = "intermediate cooking textbook" - -/obj/item/book/skill/service/cooking/expert - skill_req = SKILL_ADEPT - name = "advanced cooking textbook" - -/obj/item/book/skill/service/cooking/prof - skill_req = SKILL_EXPERT - name = "theoretical cooking textbook" - -/* -SECURITY -*/ -/obj/item/book/skill/security - abstract_type = /obj/item/book/skill/security - icon_state = "bookSpaceLaw" - -//combat -/obj/item/book/skill/security/combat - skill = SKILL_COMBAT - author = "Autumn Eckhardstein" - icon_state = "tb_combat" - -/obj/item/book/skill/security/combat/basic - name = "beginner close combat textbook" - -/obj/item/book/skill/security/combat/adept - skill_req = SKILL_BASIC - name = "intermediate close combat textbook" - -/obj/item/book/skill/security/combat/expert - skill_req = SKILL_ADEPT - name = "advanced close combat textbook" - -/obj/item/book/skill/security/combat/prof - skill_req = SKILL_EXPERT - name = "theoretical close combat textbook" - -//weapons -/obj/item/book/skill/security/weapons - skill = SKILL_WEAPONS - author = "Miho Tatsu" - icon_state = "tb_weapon" - -/obj/item/book/skill/security/weapons/basic - name = "beginner weapons expertise textbook" - -/obj/item/book/skill/security/weapons/adept - skill_req = SKILL_BASIC - name = "intermediate weapons expertise textbook" - -/obj/item/book/skill/security/weapons/expert - skill_req = SKILL_ADEPT - name = "advanced weapons expertise textbook" - -/obj/item/book/skill/security/weapons/prof - skill_req = SKILL_EXPERT - name = "theoretical weapons expertise textbook" - -//forensics -/obj/item/book/skill/security/forensics - icon_state = "bookDetective" - skill = SKILL_FORENSICS - author = "Samuel Vimes" - -/obj/item/book/skill/security/forensics/basic - name = "beginner forensics textbook" - -/obj/item/book/skill/security/forensics/adept - skill_req = SKILL_BASIC - name = "intermediate forensics textbook" - -/obj/item/book/skill/security/forensics/expert - skill_req = SKILL_ADEPT - name = "advanced forensics textbook" - -/obj/item/book/skill/security/forensics/prof - skill_req = SKILL_EXPERT - name = "theoretical forensics textbook" - -/* -ENGINEERING -*/ -/obj/item/book/skill/engineering - abstract_type = /obj/item/book/skill/engineering - icon_state = "bookEngineering" - -//construction -/obj/item/book/skill/engineering/construction/ - author = "Robert Bildar" - skill = SKILL_CONSTRUCTION - -/obj/item/book/skill/engineering/construction/basic - name = "beginner construction textbook" - -/obj/item/book/skill/engineering/construction/adept - skill_req = SKILL_BASIC - name = "intermediate construction textbook" - -/obj/item/book/skill/engineering/construction/expert - skill_req = SKILL_ADEPT - name = "advanced construction textbook" - -/obj/item/book/skill/engineering/construction/prof - skill_req = SKILL_EXPERT - name = "theoretical construction textbook" - -//electrical -/obj/item/book/skill/engineering/electrical - skill = SKILL_ELECTRICAL - author = "Ariana Vanderbalt" - -/obj/item/book/skill/engineering/electrical/basic - name = "beginner electrical engineering textbook" - -/obj/item/book/skill/engineering/electrical/adept - skill_req = SKILL_BASIC - name = "intermediate electrical engineering textbook" - -/obj/item/book/skill/engineering/electrical/expert - skill_req = SKILL_ADEPT - name = "advanced electrical engineering textbook" - -/obj/item/book/skill/engineering/electrical/prof - skill_req = SKILL_EXPERT - name = "theoretical electrical engineering textbook" - -//atmos -/obj/item/book/skill/engineering/atmos - skill = SKILL_ATMOS - author = "Maria Crash" - icon_state = "pipingbook" - -/obj/item/book/skill/engineering/atmos/basic - name = "beginner atmospherics textbook" - -/obj/item/book/skill/engineering/atmos/adept - skill_req = SKILL_BASIC - name = "intermediate atmospherics textbook" - -/obj/item/book/skill/engineering/atmos/expert - skill_req = SKILL_ADEPT - name = "advanced atmospherics textbook" - -/obj/item/book/skill/engineering/atmos/prof - skill_req = SKILL_EXPERT - name = "theoretical atmospherics textbook" - -//engines -/obj/item/book/skill/engineering/engines - skill = SKILL_ENGINES - author = "Gilgamesh Scholz" - -/obj/item/book/skill/engineering/engines/basic - name = "beginner engines textbook" - -/obj/item/book/skill/engineering/engines/adept - skill_req = SKILL_BASIC - name = "intermediate engines textbook" - -/obj/item/book/skill/engineering/engines/expert - skill_req = SKILL_ADEPT - name = "advanced engines textbook" - -/obj/item/book/skill/engineering/engines/prof - skill_req = SKILL_EXPERT - name = "theoretical engines textbook" - -/obj/item/book/skill/engineering/engines/prof/magazine - name = "theoretical engines magazine" - title = "\improper WetSkrell magazine" - icon_state = "bookMagazine" - custom = TRUE - author = "Unknown" - desc = "Sure, it includes highly detailed information on extremely advanced engine and power generator systems... but why is it written in marker on a tentacle porn magazine?" - w_class = ITEM_SIZE_NORMAL - - -/* -RESEARCH -*/ -/obj/item/book/skill/research - abstract_type = /obj/item/book/skill/research - icon_state = "analysis" - -//devices -/obj/item/book/skill/research/devices - author = "Nilva Plosinjak" - skill = SKILL_DEVICES - -/obj/item/book/skill/research/devices/basic - name = "beginner complex devices textbook" - -/obj/item/book/skill/research/devices/adept - skill_req = SKILL_BASIC - name = "intermediate complex devices textbook" - -/obj/item/book/skill/research/devices/expert - skill_req = SKILL_ADEPT - name = "advanced complex devices textbook" - -/obj/item/book/skill/research/devices/prof - skill_req = SKILL_EXPERT - name = "theoretical complex devices textbook" - -//science -/obj/item/book/skill/research/science - author = "Hui Ying Ch'ien" - skill = SKILL_SCIENCE - -/obj/item/book/skill/research/science/basic - name = "beginner science textbook" - -/obj/item/book/skill/research/science/adept - skill_req = SKILL_BASIC - name = "intermediate science textbook" - -/obj/item/book/skill/research/science/expert - skill_req = SKILL_ADEPT - name = "advanced science textbook" - -/obj/item/book/skill/research/science/prof - skill_req = SKILL_EXPERT - name = "theoretical science textbook" - -/* -MEDICAL -*/ -/obj/item/book/skill/medical - abstract_type = /obj/item/book/skill/medical - icon_state = "bookMedical" - -//chemistry -/obj/item/book/skill/medical/chemistry - icon_state = "chemistry" - author = "Dr. Shinula Nyekundujicho" - skill = SKILL_CHEMISTRY - -/obj/item/book/skill/medical/chemistry/basic - name = "beginner chemistry textbook" - -/obj/item/book/skill/medical/chemistry/adept - skill_req = SKILL_BASIC - name = "intermediate chemistry textbook" - -/obj/item/book/skill/medical/chemistry/expert - skill_req = SKILL_ADEPT - name = "advanced chemistry textbook" - -/obj/item/book/skill/medical/chemistry/prof - skill_req = SKILL_EXPERT - name = "theoretical chemistry textbook" - -//medicine -/obj/item/book/skill/medical/medicine - author = "Dr. Nagarjuna Siddha" - skill = SKILL_MEDICAL - -/obj/item/book/skill/medical/medicine/basic - name = "beginner medicine textbook" - title = "\"Instructional Guide on How Rubbing Dirt In Wounds Might Not Be The Right Approach To Stopping Bleeding Anymore\"" - desc = "A copy of \"Instructional Guide on How Rubbing Dirt In Wounds Might Not Be The Right Approach To Stopping Bleeding Anymore\" by Dr. Merrs. Despite the information density of this heavy book, it lacks any and all teachings regarding bedside manner." - author = "Dr. Merrs" - custom = TRUE - -/obj/item/book/skill/medical/medicine/adept - skill_req = SKILL_BASIC - name = "intermediate medicine textbook" - -/obj/item/book/skill/medical/medicine/expert - skill_req = SKILL_ADEPT - name = "advanced medicine textbook" - -/obj/item/book/skill/medical/medicine/prof - skill_req = SKILL_EXPERT - name = "theoretical medicine textbook" - -//anatomy -/obj/item/book/skill/medical/anatomy - author = "Dr. Basil Cartwright" - skill = SKILL_ANATOMY - -/obj/item/book/skill/medical/anatomy/basic - name = "beginner anatomy textbook" - -/obj/item/book/skill/medical/anatomy/adept - skill_req = SKILL_BASIC - name = "intermediate anatomy textbook" - -/obj/item/book/skill/medical/anatomy/expert - skill_req = SKILL_ADEPT - name = "advanced anatomy textbook" - -/obj/item/book/skill/medical/anatomy/prof - skill_req = SKILL_EXPERT - name = "theoretical anatomy textbook" - - -////////////////////// -//Custom Skill Books// -////////////////////// - -//custom skill books made by players. Right now it is extremely dodgy and bad and i'm sorry -/obj/item/book/skill/custom - name = "blank textbook" - desc = "A somewhat heftier blank book, just ready to filled with knowledge and sold at an unreasonable price." - custom = TRUE - author = null - progress = SKILLBOOK_PROG_NONE - icon_state = "tb_white" - var/skill_option_string = "Skill" //changes to "continue writing content" when the book is in progress - var/true_author //Used to keep track of who is actually writing the book. - var/list/failure_messages = list("Your hand slips and you accidentally rip your pen through several pages, ruining your hard work!","Your pen slips, dragging a haphazard line across both open pages! Now you need to do those again!") - var/list/progress_messages = list("Still quite a few blank pages left.","Feels like you're near halfway done.","You've made good progress.","Just needs a few finishing touches.","And then finish it. Done!") // Messages are in order of progress. - var/list/charge_messages = list("Your mind instantly recoils at the idea of having to write another textbook. No thank you!","You are far too mentally exhausted to write another textbook. Maybe another day.","Your hand aches in response to the very idea of more textbook writing.") - var/writing_time = 15 SECONDS // time it takes to write a segment of the book. This happens 6 times total - -//these all show up in the book fabricator -/obj/item/book/skill/custom/circle - icon_state = "tb_white_circle" -/obj/item/book/skill/custom/star - icon_state = "tb_white_star" -/obj/item/book/skill/custom/hourglass - icon_state = "tb_white_hourglass" -/obj/item/book/skill/custom/cracked - icon_state = "tb_white_cracked" -/obj/item/book/skill/custom/gun - icon_state = "tb_white_gun" -/obj/item/book/skill/custom/wrench - icon_state = "tb_white_wrench" -/obj/item/book/skill/custom/glass - icon_state = "tb_white_glass" - -/obj/item/book/skill/custom/cross - icon_state = "tb_white_cross" -/obj/item/book/skill/custom/text - icon_state = "tb_white_text" -/obj/item/book/skill/custom/download - icon_state = "tb_white_download" -/obj/item/book/skill/custom/uparrow - icon_state = "tb_white_uparrow" -/obj/item/book/skill/custom/percent - icon_state = "tb_white_percent" -/obj/item/book/skill/custom/flask - icon_state = "tb_white_flask" -/obj/item/book/skill/custom/detective - icon_state = "tb_white_detective" -/obj/item/book/skill/custom/device - icon_state = "tb_white_device" -/obj/item/book/skill/custom/smile - icon_state = "tb_white_smile" -/obj/item/book/skill/custom/exclamation - icon_state = "tb_white_exclamation" -/obj/item/book/skill/custom/question - icon_state = "tb_white_question" - -/obj/item/book/skill/custom/attackby(obj/item/pen, mob/user) - if(IS_PEN(pen)) - - if(!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) - to_chat(user, SPAN_WARNING("You can't even read, yet you want to write a whole educational textbook?")) - return - if(!user.skill_check(SKILL_LITERACY, SKILL_PROF)) - to_chat(user, SPAN_WARNING("You have no clue as to how to write an entire textbook in a way that is actually useful. Maybe a regular book would be better?")) - return - var/state_check = skill_option_string // the state skill_option_string is in just before opening the input - var/choice = input(user, "What would you like to change?","Textbook editing") as null|anything in list("Title", "Author", skill_option_string) - if(!can_write(pen,user)) - return - - switch(choice) - if("Title") - edit_title(pen, user) - - if("Skill") - if(state_check != "Skill") // make sure someone hasn't already started the book while we were staring at menus woops - to_chat(user, SPAN_WARNING("The skill has already been selected and the writing started.")) - return - edit_skill(pen, user) - - if("Continue writing content") - if(state_check != "Continue writing content") - return - continue_skill(pen, user) - - if("Author") - edit_author(pen, user) - - else - return - - if(skill && title && author) // we have everything we need so lets set a good description - desc = "A handwritten textbook titled [title], by [author]. Looks like it teaches [skill_name]." - return - ..() - -/obj/item/book/skill/custom/proc/can_write(var/obj/item/pen, var/mob/user) - if(user.get_active_hand() == pen && CanPhysicallyInteractWith(user,src) && !QDELETED(src) && !QDELETED(pen)) - return TRUE - else - to_chat(user,SPAN_DANGER("How can you expect to write anything when you can't physically put pen to paper?")) - return FALSE - -/obj/item/book/skill/custom/proc/edit_title(var/obj/item/pen, var/mob/user) - var/newtitle = reject_bad_text(sanitize_safe(input(user, "Write a new title:"))) - if(!can_write(pen,user)) - return - if(!newtitle) - to_chat(user, "The title is invalid.") - return - else - newtitle = user.handle_writing_literacy(user, newtitle) - if(newtitle) - title = newtitle - SetName(title) - -/obj/item/book/skill/custom/proc/edit_author(var/obj/item/pen, var/mob/user) - var/newauthor = sanitize(input(user, "Write the author's name:")) - if(!can_write(pen,user)) - return - if(!newauthor) - to_chat(user, SPAN_WARNING("The author name is invalid.")) - return - else - newauthor = user.handle_writing_literacy(user, newauthor) - if(newauthor) - author = newauthor - -/obj/item/book/skill/custom/proc/edit_skill(var/obj/item/pen, var/mob/user) - if(user.skillset.literacy_charges <= 0) - to_chat(user, SPAN_WARNING(pick(charge_messages))) - return - - //Choosing the skill - var/list/skill_choices = list() - for(var/decl/hierarchy/skill/S in global.skills) - if(user.skill_check(S.type, SKILL_BASIC)) - LAZYADD(skill_choices, S) - var/decl/hierarchy/skill/skill_choice = input(user, "What subject does your textbook teach?", "Textbook skill selection") as null|anything in skill_choices - if(!can_write(pen,user) || progress == SKILLBOOK_PROG_FINISH) - return - if(!skill_choice) - to_chat(user, SPAN_WARNING("Textbook skill selection cancelled.")) - return - var/newskill = skill_choice.type - - //Choosing the level - var/list/skill_levels = skill_choice.levels.Copy() - for(var/SL in skill_levels) - if(!user.skill_check(newskill, skill_levels.Find(SL))) - LAZYREMOVE(skill_levels, SL) - else - skill_levels[SL] = skill_levels.Find(SL) - LAZYREMOVE(skill_levels,skill_levels[1]) - var/newskill_level = input(user, "What level of education does it provide?","Textbook skill level") as null|anything in skill_levels - if(!can_write(pen,user) || progress == SKILLBOOK_PROG_FINISH) - return - if(!newskill_level) - to_chat(user, SPAN_WARNING("Textbook skill level selection cancelled.")) - return - var/usable_level = skill_levels[newskill_level] - if(newskill && usable_level) - if(!do_after(user, writing_time, src)) - to_chat(user, SPAN_DANGER(pick(failure_messages))) - return - //everything worked out so now we can put the learnings in the book - to_chat(user, SPAN_NOTICE("You start writing your book, getting a few pages in.")) - skill = newskill - skill_name = skill_choice.name - skill_req = (usable_level - 1) - desc = "A handwritten textbook on [skill_choice]! Wow!" - progress += 1 - skill_option_string = "Continue writing content" - true_author = user.name - -/obj/item/book/skill/custom/proc/continue_skill(var/obj/item/pen, var/mob/user) - if(user.skillset.literacy_charges <= 0) - to_chat(user, SPAN_WARNING(pick(charge_messages))) - return - if(progress >= SKILLBOOK_PROG_FINISH) // shouldn't happen but here just in case - to_chat(user, SPAN_WARNING("This book is already finished! There's no need to add anything else!")) - return - if(true_author != user.name) - to_chat(user, SPAN_WARNING("This isn't your work and you're not really sure how to continue it.")) - return - else - if(!do_after(user, writing_time, src)) - to_chat(user, SPAN_DANGER(pick(failure_messages))) - return - to_chat(user, SPAN_NOTICE("You continue writing your book. [progress_messages[progress]]")) - progress += 1 - if(progress == SKILLBOOK_PROG_FINISH) // book is finished! yay! - user.skillset.literacy_charges -= 1 - skill_option_string = "Cancel" - - -////////////////////// -// SHELF SHELF SHELF// -////////////////////// - -/obj/structure/bookcase/skill_books - name = "textbook bookcase" - // Contains a list of parent types but doesn't actually DO anything with them. Use a child of this book case - var/list/catalogue = list(/obj/item/book/skill/organizational/finance, - /obj/item/book/skill/organizational/literacy, - /obj/item/book/skill/general/eva, - /obj/item/book/skill/general/mech, - /obj/item/book/skill/general/pilot, - /obj/item/book/skill/general/hauling, - /obj/item/book/skill/general/computer, - /obj/item/book/skill/service/botany, - /obj/item/book/skill/service/cooking, - /obj/item/book/skill/security/combat, - /obj/item/book/skill/security/weapons, - /obj/item/book/skill/security/forensics, - /obj/item/book/skill/engineering/construction, - /obj/item/book/skill/engineering/electrical, - /obj/item/book/skill/engineering/atmos, - /obj/item/book/skill/engineering/engines, - /obj/item/book/skill/research/devices, - /obj/item/book/skill/research/science, - /obj/item/book/skill/medical/chemistry, - /obj/item/book/skill/medical/medicine, - /obj/item/book/skill/medical/anatomy) - -//give me ALL the textbooks -/obj/structure/bookcase/skill_books/all - -/obj/structure/bookcase/skill_books/all/Initialize() - . = ..() - for(var/category in catalogue) - for(var/real_book in subtypesof(category)) - new real_book(src) - -//Bookshelf with some random textbooks -/obj/structure/bookcase/skill_books/random - -/obj/structure/bookcase/skill_books/random/Initialize() - . = ..() - for(var/category in catalogue) - for(var/real_book in subtypesof(category)) - if(prob(20)) - new real_book(src) - -#undef RANDOM_BOOK_TITLE -#undef SKILLBOOK_PROG_NONE -#undef SKILLBOOK_PROG_FINISH \ No newline at end of file diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm index 71962a8cd27..34fc63bd9ab 100644 --- a/code/game/objects/items/contraband.dm +++ b/code/game/objects/items/contraband.dm @@ -45,7 +45,7 @@ /obj/item/chems/glass/beaker/vial/random/populate_reagents() var/list/picked_reagents = pickweight(random_reagent_list) for(var/reagent in picked_reagents) - reagents.add_reagent(reagent, picked_reagents[reagent]) + add_to_reagents(reagent, picked_reagents[reagent]) var/list/names = new for(var/reagent_type in reagents.reagent_volumes) diff --git a/code/game/objects/items/cryobag.dm b/code/game/objects/items/cryobag.dm index fb064fc25fb..50ae3c0eebc 100644 --- a/code/game/objects/items/cryobag.dm +++ b/code/game/objects/items/cryobag.dm @@ -5,7 +5,7 @@ a hostile enviroment." icon = 'icons/obj/closets/cryobag.dmi' icon_state = "bodybag_folded" - origin_tech = "{'biotech':4}" + origin_tech = @'{"biotech":4}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 101c15b730c..697dccf3843 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -4,7 +4,7 @@ icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_SMALL slot_flags = SLOT_LOWER_BODY - origin_tech = "{'programming':4,'materials':4}" + origin_tech = @'{"programming":4,"materials":4}' material = /decl/material/solid/fiberglass matter = list(/decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/game/objects/items/devices/auto_cpr.dm b/code/game/objects/items/devices/auto_cpr.dm index bff781b1342..cfa6fd549e8 100644 --- a/code/game/objects/items/devices/auto_cpr.dm +++ b/code/game/objects/items/devices/auto_cpr.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/items/device/auto_cpr.dmi' icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL - origin_tech = "{'magnets':2,'biotech':2}" + origin_tech = @'{"magnets":2,"biotech":2}' slot_flags = SLOT_OVER_BODY material = /decl/material/solid/organic/plastic matter = list( diff --git a/code/game/objects/items/devices/boombox.dm b/code/game/objects/items/devices/boombox.dm index 014870947af..d0b12f9240a 100644 --- a/code/game/objects/items/devices/boombox.dm +++ b/code/game/objects/items/devices/boombox.dm @@ -6,7 +6,7 @@ item_state = "boombox" force = 7 w_class = ITEM_SIZE_HUGE //forbid putting something that emits loud sounds forever into a backpack - origin_tech = "{'magnets':2,'combat':1}" + origin_tech = @'{"magnets":2,"combat":1}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/copper = MATTER_AMOUNT_REINFORCEMENT, @@ -169,7 +169,9 @@ /obj/item/boombox/on_update_icon() . = ..() - icon_state = playing ? "on" : "off" + icon_state = get_world_inventory_state() + if(playing) + icon_state = "[icon_state]_on" /obj/item/boombox/proc/stop() playing = 0 diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index fdaec9b4cb9..319144657d3 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -8,7 +8,7 @@ throw_speed = 1 throw_range = 5 w_class = ITEM_SIZE_SMALL - origin_tech = "{'esoteric':4,'magnets':4}" + origin_tech = @'{"esoteric":4,"magnets":4}' material = /decl/material/solid/organic/plastic var/can_use = 1 var/obj/effect/dummy/chameleon/active_dummy = null diff --git a/code/game/objects/items/devices/dociler.dm b/code/game/objects/items/devices/dociler.dm index 4cfce9098ac..46d0b95f99f 100644 --- a/code/game/objects/items/devices/dociler.dm +++ b/code/game/objects/items/devices/dociler.dm @@ -2,7 +2,7 @@ name = "dociler" desc = "A complex single use recharging injector that spreads a complex neurological serum that makes animals docile and friendly. Somewhat." w_class = ITEM_SIZE_NORMAL - origin_tech = "{'biotech':5,'materials':2}" + origin_tech = @'{"biotech":5,"materials":2}' icon = 'icons/obj/items/device/animal_tagger.dmi' icon_state = ICON_STATE_WORLD force = 1 diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 42ec93f807f..c2abca5dc79 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -8,7 +8,7 @@ throw_speed = 4 throw_range = 10 obj_flags = OBJ_FLAG_CONDUCTIBLE - origin_tech = "{'magnets':2,'combat':1}" + origin_tech = @'{"magnets":2,"combat":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) @@ -126,7 +126,7 @@ name = "advanced flash" desc = "A device that produces a very bright flash of light. This is an advanced and expensive version often issued to VIPs." icon = 'icons/obj/items/device/flash_advanced.dmi' - origin_tech = "{'combat':2,'magnets':2}" + origin_tech = @'{"combat":2,"magnets":2}' str_min = 3 str_max = 8 material = /decl/material/solid/metal/steel diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 3efffdd142c..ec81f341725 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -4,7 +4,7 @@ var/global/list/all_gps_units = list() desc = "A handheld relay used to triangulates the approximate co-ordinates of the device." icon = 'icons/obj/items/device/locator.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'materials':2,'programming':2,'wormholes':2}" + origin_tech = @'{"materials":2,"programming":2,"wormholes":2}' material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, @@ -35,7 +35,7 @@ var/global/list/all_gps_units = list() global.all_gps_units += src . = ..() name = "[initial(name)] ([gps_tag])" - events_repository.register(/decl/observ/moved, src, src, .proc/update_holder) + events_repository.register(/decl/observ/moved, src, src, PROC_REF(update_holder)) compass = new(src) update_holder() update_icon() @@ -65,8 +65,8 @@ var/global/list/all_gps_units = list() if(!force_clear && ismob(loc)) holder = loc - moved_event.register(holder, src, .proc/update_compass) - dir_set_event.register(holder, src, .proc/update_compass) + moved_event.register(holder, src, PROC_REF(update_compass)) + dir_set_event.register(holder, src, PROC_REF(update_compass)) if(!force_clear && holder && tracking) if(!is_in_processing_list) @@ -103,7 +103,7 @@ var/global/list/all_gps_units = list() STOP_PROCESSING(SSobj, src) is_in_processing_list = FALSE global.all_gps_units -= src - events_repository.unregister(/decl/observ/moved, src, src, .proc/update_holder) + events_repository.unregister(/decl/observ/moved, src, src, PROC_REF(update_holder)) update_holder(force_clear = TRUE) QDEL_NULL(compass) return ..() @@ -187,7 +187,7 @@ var/global/list/all_gps_units = list() var/duration = 5 MINUTES / severity_modifier emped = TRUE update_icon() - addtimer(CALLBACK(src, .proc/reset_emp), duration) + addtimer(CALLBACK(src, PROC_REF(reset_emp)), duration) /obj/item/gps/proc/reset_emp() emped = FALSE diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index 94abe1f2e14..a6815ebad30 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -61,7 +61,7 @@ to_chat(user, "Your hacking attempt was succesful!") user.playsound_local(get_turf(src), 'sound/piano/A#6.ogg', 50) known_targets.Insert(1, target) // Insert the newly hacked target first, - events_repository.register(/decl/observ/destroyed, target, src, /obj/item/multitool/hacktool/proc/on_target_destroy) + events_repository.register(/decl/observ/destroyed, target, src, TYPE_PROC_REF(/obj/item/multitool/hacktool, on_target_destroy)) else to_chat(user, "Your hacking attempt failed!") return 1 diff --git a/code/game/objects/items/devices/inducer.dm b/code/game/objects/items/devices/inducer.dm index 13a4cefe576..042e24c5b04 100644 --- a/code/game/objects/items/devices/inducer.dm +++ b/code/game/objects/items/devices/inducer.dm @@ -5,7 +5,7 @@ icon_state = "inducer-sci" item_state = "inducer-sci" force = 7 - origin_tech = "{'powerstorage':6,'engineering':4}" + origin_tech = @'{"powerstorage":6,"engineering":4}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) slot_flags = SLOT_LOWER_BODY diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 43af97a598f..3e1ebbe0e7c 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -50,7 +50,7 @@ ) obj_flags = OBJ_FLAG_CONDUCTIBLE slot_flags = SLOT_LOWER_BODY - origin_tech = "{'magnets':3,'materials':2}" + origin_tech = @'{"magnets":3,"materials":2}' var/max_uses = 32 var/uses = 32 diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 0c3d744cc1c..42723e07744 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -21,7 +21,7 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE ) - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' var/buffer_name var/atom/buffer_object @@ -55,7 +55,7 @@ unregister_buffer(buffer_object) buffer_object = buffer if(buffer_object) - events_repository.register(/decl/observ/destroyed, buffer_object, src, /obj/item/multitool/proc/unregister_buffer) + events_repository.register(/decl/observ/destroyed, buffer_object, src, TYPE_PROC_REF(/obj/item/multitool, unregister_buffer)) /obj/item/multitool/proc/unregister_buffer(var/atom/buffer_to_unregister) // Only remove the buffered object, don't reset the name diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index ba96cf25b7d..122ebb79401 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -5,7 +5,7 @@ var/global/list/pai_cards = list() icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_SMALL slot_flags = SLOT_LOWER_BODY - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' material = /decl/material/solid/fiberglass matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/game/objects/items/devices/paint_sprayer.dm b/code/game/objects/items/devices/paint_sprayer.dm index 8f3dc2b080c..6559cc969ee 100644 --- a/code/game/objects/items/devices/paint_sprayer.dm +++ b/code/game/objects/items/devices/paint_sprayer.dm @@ -86,7 +86,7 @@ var/mob/M = loc M.update_inhand_overlays() -/obj/item/paint_sprayer/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/paint_sprayer/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && check_state_in_icon("[overlay.icon_state]_color", overlay.icon)) overlay.overlays += overlay_image(overlay.icon, "[overlay.icon_state]_color", paint_color) . = ..() @@ -106,19 +106,20 @@ else if (istype(A, /turf/simulated/wall)) new_color = pick_color_from_wall(A, user) else if (istype(A, /obj/structure/wall_frame)) - var/obj/structure/wall_frame/WF = A - new_color = pick_color_from_wall_frame(WF, user) + new_color = pick_color_from_wall_frame(A, user) else new_color = A.get_color() - change_color(new_color, user) - - else if (A.atom_flags & ATOM_FLAG_CAN_BE_PAINTED) - A.set_color(paint_color) - . = TRUE + if(!new_color) + to_chat(user, SPAN_NOTICE("You fail to scan a color from \the [A].")) + else + change_color(new_color, user) else if (istype(A, /turf/simulated/wall)) . = paint_wall(A, user) + else if (istype(A, /obj/structure/wall_frame)) + . = paint_wall_frame(A, user) + else if (istype(A, /turf/simulated/floor)) . = paint_floor(A, user, params) @@ -129,8 +130,12 @@ to_chat(user, SPAN_WARNING("You can't paint an active exosuit. Dismantle it first.")) . = FALSE + else if (A.atom_flags & ATOM_FLAG_CAN_BE_PAINTED) + A.set_color(paint_color) + . = TRUE + else - to_chat(user, SPAN_WARNING("\The [src] can only be used on floors, windows, walls, exosuits or certain airlocks.")) + to_chat(user, SPAN_WARNING("\The [src] can only be used on floors, windows, walls, exosuits, airlocks, and certain other objects.")) . = FALSE if (.) diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 55cff27a52d..e20296b8724 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -14,7 +14,7 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metallic_hydrogen = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'powerstorage':3,'esoteric':5}" + origin_tech = @'{"powerstorage":3,"esoteric":5}' var/drain_rate = 1500000 // amount of power to drain per tick var/power_drained = 0 // Amount of power drained. var/max_power = 5e9 // Detonation point. diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 3edfa8a2ef8..c7a19484036 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -6,7 +6,7 @@ var/global/list/radio_beacons = list() icon = 'icons/obj/items/device/radio/beacon.dmi' icon_state = "beacon" item_state = "signaler" - origin_tech = "{'wormholes':1}" + origin_tech = @'{"wormholes":1}' material = /decl/material/solid/metal/aluminium matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 727c063217f..dc29d7b3e4b 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -2,15 +2,40 @@ name = "standard encryption key" desc = "An encryption key for a radio headset. Contains cypherkeys." icon = 'icons/obj/items/device/radio/key.dmi' - icon_state = "cypherkey" - item_state = "" + icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) + color = COLOR_GRAY80 + var/contact_color = COLOR_PALE_GOLD + var/fill_color = COLOR_MID_BLUE_GRAY + var/inlay_color = COLOR_RED var/translate_binary var/list/can_decrypt +/obj/item/encryptionkey/Initialize() + . = ..() + update_icon() + +/obj/item/encryptionkey/on_update_icon() + . = ..() + if(contact_color) + var/image/I = image(icon, "[icon_state]_contact") + I.color = contact_color + I.appearance_flags |= RESET_COLOR + add_overlay(I) + if(fill_color) + var/image/I = image(icon, "[icon_state]_fill") + I.color = fill_color + I.appearance_flags |= RESET_COLOR + add_overlay(I) + if(inlay_color) + var/image/I = image(icon, "[icon_state]_inlay") + I.color = inlay_color + I.appearance_flags |= RESET_COLOR + add_overlay(I) + /obj/item/encryptionkey/attack_self(mob/user) if(alert(user, "Do you wish to factory reset this encryption key? This will remove ALL channel access and cannot be undone.", "Factory Reset", "No", "Yes") == "Yes" && !user.incapacitated() && user.get_held_slot_for_item(src)) can_decrypt = null @@ -33,6 +58,5 @@ . = ..() /obj/item/encryptionkey/binary - icon_state = "cypherkey" translate_binary = TRUE - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index bfcfcb83d4f..0d58d152d45 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -27,4 +27,4 @@ if(network) add_overlay("[icon_state]-online") else - add_overlay("[icon_state]-offline") + add_overlay("[icon_state]-offline") \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/headsets_shared.dm b/code/game/objects/items/devices/radio/headsets_shared.dm index bed832cd35f..94d85ebec84 100644 --- a/code/game/objects/items/devices/radio/headsets_shared.dm +++ b/code/game/objects/items/devices/radio/headsets_shared.dm @@ -5,7 +5,7 @@ /obj/item/encryptionkey/cargo name = "supply radio encryption key" - icon_state = "med_cypherkey" + inlay_color = COLOR_ASSEMBLY_WHITE can_decrypt = list(access_cargo) /obj/item/radio/headset/headset_mining @@ -16,7 +16,7 @@ /obj/item/encryptionkey/mining name = "mining radio encryption key" - icon_state = "med_cypherkey" + inlay_color = COLOR_ASSEMBLY_WHITE can_decrypt = list(access_mining) /obj/item/radio/headset/headset_sec name = "security radio headset" @@ -25,7 +25,7 @@ /obj/item/encryptionkey/sec name = "security radio encryption key" - icon_state = "sec_cypherkey" + inlay_color = COLOR_BLOOD_RED can_decrypt = list(access_security) /obj/item/radio/headset/headset_med @@ -36,7 +36,7 @@ /obj/item/encryptionkey/med name = "medical radio encryption key" - icon_state = "med_cypherkey" + inlay_color = COLOR_ASSEMBLY_WHITE can_decrypt = list(access_medical) /obj/item/radio/headset/headset_service @@ -47,7 +47,7 @@ /obj/item/encryptionkey/service name = "service radio encryption key" - icon_state = "srv_cypherkey" + inlay_color = COLOR_VERDANT_GREEN can_decrypt = list(access_bar) /obj/item/radio/headset/headset_sci @@ -58,7 +58,7 @@ /obj/item/encryptionkey/sci name = "science radio encryption key" - icon_state = "sci_cypherkey" + inlay_color = COLOR_SCIENCE_PURPLE can_decrypt = list(access_research) /obj/item/radio/headset/headset_eng @@ -69,7 +69,7 @@ /obj/item/encryptionkey/eng name = "engineering radio encryption key" - icon_state = "eng_cypherkey" + inlay_color = PIPE_COLOR_YELLOW can_decrypt = list(access_engine) /obj/item/radio/headset/heads @@ -79,9 +79,14 @@ /obj/item/encryptionkey/command name = "command encryption key" - icon_state = "com_cypherkey" + inlay_color = COLOR_ROYAL_BLUE can_decrypt = list(access_bridge) +/obj/item/encryptionkey/heads + color = COLOR_GOLD + fill_color = COLOR_PALE_GOLD + inlay_color = COLOR_ROYAL_BLUE + /obj/item/radio/headset/heads/ce name = "chief engineer's headset" desc = "The headset of the boss engineer." @@ -90,7 +95,6 @@ /obj/item/encryptionkey/heads/ce name = "chief engineer's encryption key" - icon_state = "cap_cypherkey" can_decrypt = list( access_bridge, access_engine @@ -104,7 +108,6 @@ /obj/item/encryptionkey/heads/cmo name = "chief medical officer's encryption key" - icon_state = "cap_cypherkey" can_decrypt = list( access_bridge, access_medical @@ -118,7 +121,6 @@ /obj/item/encryptionkey/heads/rd name = "research director's encryption key" - icon_state = "cap_cypherkey" can_decrypt = list( access_bridge, access_research @@ -131,7 +133,6 @@ /obj/item/encryptionkey/heads/captain name = "captain's encryption key" - icon_state = "cap_cypherkey" can_decrypt = list( access_bridge, access_security, @@ -149,7 +150,6 @@ /obj/item/encryptionkey/heads/hop name = "head of personnel's encryption key" - icon_state = "hop_cypherkey" can_decrypt = list( access_bar, access_cargo, @@ -165,8 +165,8 @@ encryption_keys = list(/obj/item/encryptionkey/heads/hos) /obj/item/encryptionkey/heads/hos - name = "head of personnel's encryption key" - icon_state = "hos_cypherkey" + name = "head of security's encryption key" + inlay_color = COLOR_BLOOD_RED can_decrypt = list( access_bridge, access_security @@ -183,13 +183,12 @@ encryption_keys = list(/obj/item/encryptionkey/ert) /obj/item/encryptionkey/mercenary - icon_state = "cypherkey" - origin_tech = "{'esoteric':2}" + origin_tech = @'{"esoteric":2}' can_decrypt = list(access_mercenary) /obj/item/radio/headset/mercenary can_use_analog = TRUE - origin_tech = "{'esoteric':2}" + origin_tech = @'{"esoteric":2}' encryption_keys = list(/obj/item/encryptionkey/mercenary) analog_secured = list((access_mercenary) = TRUE) @@ -203,13 +202,12 @@ encryption_keys = list(/obj/item/encryptionkey/entertainment) /obj/item/encryptionkey/raider - icon_state = "cypherkey" - origin_tech = "{'esoteric':2}" + origin_tech = @'{"esoteric":2}' can_decrypt = list(access_raider) /obj/item/radio/headset/raider can_use_analog = TRUE - origin_tech = "{'esoteric':2}" + origin_tech = @'{"esoteric":2}' encryption_keys = list(/obj/item/encryptionkey/raider) analog_secured = list((access_raider) = TRUE) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 519a37fc19a..561f7d6de8f 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -13,7 +13,7 @@ power_usage = 0 intercom = TRUE intercom_handling = TRUE - directional_offset = "{'NORTH':{'y':-30}, 'SOUTH':{'y':20}, 'EAST':{'x':-22}, 'WEST':{'x':22}}" + directional_offset = @'{"NORTH":{"y":-30}, "SOUTH":{"y":20}, "EAST":{"x":-22}, "WEST":{"x":22}}' var/last_tick //used to delay the powercheck /obj/item/radio/intercom/setup_power_supply(loaded_cell_type, accepted_cell_type, power_supply_extension_type, charge_value) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 4597f8e6da4..b7b1995c2a7 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -336,7 +336,7 @@ if(istype(M)) M.trigger_aiming(TARGET_CAN_RADIO) - addtimer(CALLBACK(src, .proc/transmit, M, message, message_mode, verb, speaking), 0) + addtimer(CALLBACK(src, PROC_REF(transmit), M, message, message_mode, verb, speaking), 0) /obj/item/radio/proc/can_transmit_binary() for(var/obj/item/encryptionkey/key in encryption_keys) diff --git a/code/game/objects/items/devices/scanners/breath.dm b/code/game/objects/items/devices/scanners/breath.dm index 8f0b771a617..02583fae7f0 100644 --- a/code/game/objects/items/devices/scanners/breath.dm +++ b/code/game/objects/items/devices/scanners/breath.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/items/device/scanner/breath_scanner.dmi' item_flags = ITEM_FLAG_NO_BLUDGEON material = /decl/material/solid/metal/aluminium - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' printout_color = "#deebff" var/mode = 1 diff --git a/code/game/objects/items/devices/scanners/gas.dm b/code/game/objects/items/devices/scanners/gas.dm index 95e6f06581a..a9311cc11aa 100644 --- a/code/game/objects/items/devices/scanners/gas.dm +++ b/code/game/objects/items/devices/scanners/gas.dm @@ -6,7 +6,7 @@ name = "gas analyzer" desc = "A hand-held environmental scanner which reports current gas levels. Has a button to cycle modes." icon = 'icons/obj/items/device/scanner/atmos_scanner.dmi' - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' window_width = 350 window_height = 400 var/mode = DEFAULT_MODE diff --git a/code/game/objects/items/devices/scanners/health.dm b/code/game/objects/items/devices/scanners/health.dm index 95504fa8d04..0bbe2dae5e7 100644 --- a/code/game/objects/items/devices/scanners/health.dm +++ b/code/game/objects/items/devices/scanners/health.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/items/device/scanner/health_scanner.dmi' item_flags = ITEM_FLAG_NO_BLUDGEON material = /decl/material/solid/metal/aluminium - origin_tech = "{'magnets':1,'biotech':1}" + origin_tech = @'{"magnets":1,"biotech":1}' printout_color = "#deebff" var/mode = 1 diff --git a/code/game/objects/items/devices/scanners/mass_spectrometer.dm b/code/game/objects/items/devices/scanners/mass_spectrometer.dm index a8f2fbd8109..3eda6f1a4f4 100644 --- a/code/game/objects/items/devices/scanners/mass_spectrometer.dm +++ b/code/game/objects/items/devices/scanners/mass_spectrometer.dm @@ -3,7 +3,7 @@ desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample or analyzes unusual chemicals." icon = 'icons/obj/items/device/scanner/spectrometer.dmi' atom_flags = ATOM_FLAG_OPEN_CONTAINER - origin_tech = "{'magnets':2,'biotech':2}" + origin_tech = @'{"magnets":2,"biotech":2}' window_width = 550 window_height = 300 scan_sound = 'sound/effects/scanbeep.ogg' @@ -85,4 +85,4 @@ name = "advanced mass spectrometer" icon = 'icons/obj/items/device/scanner/advanced_spectrometer.dmi' details = 1 - origin_tech = "{'magnets':4,'biotech':2}" \ No newline at end of file + origin_tech = @'{"magnets":4,"biotech":2}' \ No newline at end of file diff --git a/code/game/objects/items/devices/scanners/mining.dm b/code/game/objects/items/devices/scanners/mining.dm index 678a262e973..24d91525c6d 100644 --- a/code/game/objects/items/devices/scanners/mining.dm +++ b/code/game/objects/items/devices/scanners/mining.dm @@ -12,7 +12,7 @@ name = "ore detector" desc = "A complex device used to locate ore deep underground." icon = 'icons/obj/items/device/scanner/ore_scanner.dmi' - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' use_delay = 50 printout_color = "#fff7f0" var/survey_data = 0 @@ -21,7 +21,7 @@ /obj/item/scanner/mining/examine(mob/user) . = ..() - to_chat(user,"A tiny indicator on the [src] shows it holds [survey_data] good explorer points.") + to_chat(user,"A tiny indicator on the [src] shows it holds [survey_data] good explorer point\s.") /obj/item/scanner/mining/is_valid_scan_target(turf/T) return istype(T) @@ -33,19 +33,19 @@ scan_data = scan_results[1] else scan_data += "
    [scan_results[1]]" - to_chat(user, "[html_icon(src)] \The [src] displays a readout.") + to_chat(user, SPAN_NOTICE("[html_icon(src)] \The [src] displays a readout.")) to_chat(user, scan_results[1]) if(scan_results[2]) survey_data += scan_results[2] playsound(loc, 'sound/machines/ping.ogg', 40, 1) - to_chat(user,"New survey data stored - [scan_results[2]] GEP.") + to_chat(user, SPAN_NOTICE("New survey data stored - earned [scan_results[2]] GEP.")) /obj/item/scanner/mining/proc/put_disk_in_hand(var/mob/M) if(!survey_data) - to_chat(M,"There is no survey data stored on the [src].") - return 0 - visible_message("The [src] spits out a disk containing [survey_data] GEP.") + to_chat(M, SPAN_WARNING("There is no survey data stored on the [src].")) + return FALSE + visible_message(SPAN_NOTICE("\The [src] spits out a disk containing [survey_data] GEP.")) var/obj/item/disk/survey/D = new(get_turf(src)) D.data = survey_data survey_data = 0 @@ -64,15 +64,6 @@ return put_disk_in_hand(M) -/obj/item/disk/survey - name = "survey data disk" - color = COLOR_DARK_BROWN - var/data - -/obj/item/disk/survey/examine(mob/user) - . = ..() - to_chat(user,"A tiny indicator on the [src] shows it holds [data] good explorer points.") - //Returns list of two elements, 1 is text output, 2 is amoutn of GEP data /proc/mineral_scan_results(turf/target) var/list/metals = list( diff --git a/code/game/objects/items/devices/scanners/network.dm b/code/game/objects/items/devices/scanners/network.dm index 5a4d709db99..e96a840d7e5 100644 --- a/code/game/objects/items/devices/scanners/network.dm +++ b/code/game/objects/items/devices/scanners/network.dm @@ -2,7 +2,7 @@ name = "network analyzer" desc = "A hand-held network scanner which detects nearby network devices and returns information about them." icon = 'icons/obj/items/device/scanner/network_scanner.dmi' - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' window_width = 350 window_height = 400 diff --git a/code/game/objects/items/devices/scanners/price.dm b/code/game/objects/items/devices/scanners/price.dm index c8ac36ad37b..0f8c0c7036d 100644 --- a/code/game/objects/items/devices/scanners/price.dm +++ b/code/game/objects/items/devices/scanners/price.dm @@ -2,7 +2,7 @@ name = "price scanner" desc = "Using an up-to-date database of various costs and prices, this device estimates the market price of an item up to 0.001% accuracy." icon = 'icons/obj/items/device/scanner/price_scanner.dmi' - origin_tech = "{'materials':6,'magnets':4}" + origin_tech = @'{"materials":6,"magnets":4}' scan_sound = 'sound/effects/checkout.ogg' material = /decl/material/solid/metal/steel matter = list( diff --git a/code/game/objects/items/devices/scanners/reagents.dm b/code/game/objects/items/devices/scanners/reagents.dm index 971c3e3e95c..2087c8027ba 100644 --- a/code/game/objects/items/devices/scanners/reagents.dm +++ b/code/game/objects/items/devices/scanners/reagents.dm @@ -2,7 +2,7 @@ name = "reagent scanner" desc = "A hand-held reagent scanner which identifies chemical agents." icon = 'icons/obj/items/device/scanner/spectrometer.dmi' - origin_tech = "{'magnets':2,'biotech':2}" + origin_tech = @'{"magnets":2,"biotech":2}' scan_sound = 'sound/effects/scanbeep.ogg' var/details = 0 @@ -29,4 +29,4 @@ name = "advanced reagent scanner" icon = 'icons/obj/items/device/scanner/advanced_spectrometer.dmi' details = 1 - origin_tech = "{'magnets':4,'biotech':2}" \ No newline at end of file + origin_tech = @'{"magnets":4,"biotech":2}' \ No newline at end of file diff --git a/code/game/objects/items/devices/scanners/xenobio.dm b/code/game/objects/items/devices/scanners/xenobio.dm index 605dffb33cb..bff60fb4a5f 100644 --- a/code/game/objects/items/devices/scanners/xenobio.dm +++ b/code/game/objects/items/devices/scanners/xenobio.dm @@ -5,7 +5,7 @@ icon_state = ICON_STATE_WORLD scan_sound = 'sound/effects/scanbeep.ogg' printout_color = "#f3e6ff" - origin_tech = "{'magnets':1,'biotech':1}" + origin_tech = @'{"magnets":1,"biotech":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index 7f6a25ed9f4..6e079636ac4 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -14,7 +14,7 @@ throw_range = 15 throw_speed = 3 - origin_tech = "{'programming':1,'engineering':1,'esoteric':3}" + origin_tech = @'{"programming":1,"engineering":1,"esoteric":3}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/copper = MATTER_AMOUNT_REINFORCEMENT, @@ -62,7 +62,7 @@ icon_state = ICON_STATE_WORLD color = COLOR_GRAY80 w_class = ITEM_SIZE_SMALL - origin_tech = "{'programming':1,'engineering':1,'esoteric':3}" + origin_tech = @'{"programming":1,"engineering":1,"esoteric":3}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/copper = MATTER_AMOUNT_REINFORCEMENT, @@ -102,12 +102,12 @@ /obj/item/spy_monitor/proc/pair(var/obj/item/spy_bug/SB, var/mob/living/user) to_chat(user, SPAN_NOTICE("\The [SB] has been paired with \the [src].")) - events_repository.register(/decl/observ/destroyed, SB, src, .proc/unpair) + events_repository.register(/decl/observ/destroyed, SB, src, PROC_REF(unpair)) cameras += SB /obj/item/spy_monitor/proc/unpair(var/obj/item/spy_bug/SB, var/mob/living/user) to_chat(user, SPAN_NOTICE("\The [SB] has been unpaired from \the [src].")) - events_repository.unregister(/decl/observ/destroyed, SB, src, .proc/unpair) + events_repository.unregister(/decl/observ/destroyed, SB, src, PROC_REF(unpair)) if(selected_camera == SB) selected_camera = null cameras -= SB @@ -154,4 +154,5 @@ broadcasting = 0 canhear_range = 1 name = "spy device" - icon_state = "syn_cypherkey" + icon = 'icons/obj/items/device/radio/spybug.dmi' + icon_state = ICON_STATE_WORLD diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index db056f3e0eb..75801bc5fb8 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -16,7 +16,7 @@ material = /decl/material/solid/metal/aluminium matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'magnets':2,'materials':2}" + origin_tech = @'{"magnets":2,"materials":2}' var/on = 0 //is it turned on? var/cover_open = 0 //is the cover open? diff --git a/code/game/objects/items/devices/suit_sensor_jammer.dm b/code/game/objects/items/devices/suit_sensor_jammer.dm index 62209a7cfaa..e1beec8c025 100644 --- a/code/game/objects/items/devices/suit_sensor_jammer.dm +++ b/code/game/objects/items/devices/suit_sensor_jammer.dm @@ -26,7 +26,7 @@ suit_sensor_jammer_methods = list() suit_sensor_jammer_methods_by_type = list() for(var/jammer_method_type in subtypesof(/suit_sensor_jammer_method)) - var/new_method = new jammer_method_type(src, /obj/item/suit_sensor_jammer/proc/may_process_crew_data) + var/new_method = new jammer_method_type(src, TYPE_PROC_REF(/obj/item/suit_sensor_jammer, may_process_crew_data)) dd_insertObjectList(suit_sensor_jammer_methods, new_method) suit_sensor_jammer_methods_by_type[jammer_method_type] = new_method jammer_method = suit_sensor_jammer_methods[1] diff --git a/code/game/objects/items/devices/t_scanner.dm b/code/game/objects/items/devices/t_scanner.dm index 2191c7cb35e..2a6e9533c59 100644 --- a/code/game/objects/items/devices/t_scanner.dm +++ b/code/game/objects/items/devices/t_scanner.dm @@ -8,7 +8,7 @@ slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_SMALL material = /decl/material/solid/metal/aluminium - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' action_button_name = "Toggle T-Ray scanner" var/scan_range = 3 @@ -103,7 +103,7 @@ if(ishuman(scanned)) var/mob/living/carbon/human/H = scanned if(H.get_bodytype()?.appearance_flags & HAS_SKIN_COLOR) - I.color = H.skin_colour + I.color = H.get_skin_colour() I.icon = 'icons/mob/mob.dmi' I.icon_state = "phaseout" var/mob/M = scanned diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index a5550350d7c..e93021d7c6e 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -24,7 +24,7 @@ effective or pretty fucking useless. throw_speed = 4 throw_range = 10 obj_flags = OBJ_FLAG_CONDUCTIBLE - origin_tech = "{'magnets':3,'combat':3,'esoteric':3}" + origin_tech = @'{"magnets":3,"combat":3,"esoteric":3}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm index 4f82074e931..e4ee844234f 100644 --- a/code/game/objects/items/devices/tvcamera.dm +++ b/code/game/objects/items/devices/tvcamera.dm @@ -85,7 +85,7 @@ if(!href_list["close"]) attack_self(usr) -/obj/item/camera/tvcamera/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/camera/tvcamera/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && video_enabled && check_state_in_icon("[overlay.icon_state]-on", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-on" . = ..() diff --git a/code/game/objects/items/flashlights/_flashlight.dm b/code/game/objects/items/flashlights/_flashlight.dm index 713547f0b98..c3dff6fe813 100644 --- a/code/game/objects/items/flashlights/_flashlight.dm +++ b/code/game/objects/items/flashlights/_flashlight.dm @@ -31,7 +31,6 @@ /obj/item/flashlight/proc/get_emissive_overlay_color() return COLOR_WHITE // Icons are usually coloured already. - /obj/item/flashlight/on_update_icon() . = ..() icon_state = get_world_inventory_state() @@ -43,6 +42,10 @@ I.appearance_flags |= RESET_COLOR I.pixel_x = offset_on_overlay_x I.pixel_y = offset_on_overlay_y + I.pixel_w = 0 + I.pixel_z = 0 + I.plane = FLOAT_PLANE + I.layer = FLOAT_LAYER add_overlay(I) /obj/item/flashlight/attack_self(mob/user) @@ -80,6 +83,11 @@ if(light_wedge) set_dir(user.dir) update_light() + update_icon() + +/obj/item/flashlight/equipped(mob/user, slot) + . = ..() + update_icon() /obj/item/flashlight/throw_at() . = ..() @@ -167,7 +175,7 @@ //if someone wants to implement inspecting robot eyes here would be the place to do it. -/obj/item/flashlight/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/flashlight/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && on) var/icon_state_on = "[overlay.icon_state]-on" if(check_state_in_icon(icon_state_on, overlay.icon)) diff --git a/code/game/objects/items/flashlights/party.dm b/code/game/objects/items/flashlights/party.dm index 8b3abb4b081..31531842f18 100644 --- a/code/game/objects/items/flashlights/party.dm +++ b/code/game/objects/items/flashlights/party.dm @@ -36,7 +36,7 @@ /obj/item/flashlight/party/proc/start_strobing() if(!strobe_effect) strobe_effect = new(get_turf(src)) - events_repository.register(/decl/observ/moved, src, strobe_effect, /atom/movable/proc/move_to_turf_or_null) + events_repository.register(/decl/observ/moved, src, strobe_effect, TYPE_PROC_REF(/atom/movable, move_to_turf_or_null)) update_icon() /obj/effect/party_light diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 2d99ad71d0d..cf272b6b690 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -10,7 +10,7 @@ throw_range = 7 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'engineering':5,'exoticmatter':4,'powerstorage':4}" + origin_tech = @'{"engineering":5,"exoticmatter":4,"powerstorage":4}' var/list/signs = list() var/max_signs = 10 diff --git a/code/game/objects/items/item_edibility.dm b/code/game/objects/items/item_edibility.dm new file mode 100644 index 00000000000..d5d0cd948ec --- /dev/null +++ b/code/game/objects/items/item_edibility.dm @@ -0,0 +1,4 @@ +/obj/item/handle_eaten_by_mob(var/mob/user, var/mob/target) + . = ..() + if(. == EATEN_SUCCESS && !QDELETED(src)) + add_trace_DNA(target) diff --git a/code/game/objects/items/paintkit.dm b/code/game/objects/items/paintkit.dm index 97ad7277339..576c58a9dc6 100644 --- a/code/game/objects/items/paintkit.dm +++ b/code/game/objects/items/paintkit.dm @@ -2,11 +2,12 @@ icon_state = "modkit" icon = 'icons/obj/items/modkit.dmi' material = /decl/material/solid/organic/plastic - var/new_name = "exosuit" // What is the variant called? - var/new_desc = "An exosuit." // How is the new exosuit described? - var/new_icon // What base icon will the new exosuit use? - var/new_state = "ripley" // What base icon state with the new exosuit use. - var/uses = 1 // Uses before the kit deletes itself. + var/new_name = "exosuit" // What is the variant called? + var/new_desc = "An exosuit." // How is the new exosuit described? + var/new_icon // What base icon will the new exosuit use? + var/new_state // What base icon state with the new exosuit use. + var/new_blend = BLEND_MULTIPLY // What decal blend mode does this kit use? + var/uses = 1 // Uses before the kit deletes itself. var/custom = FALSE /obj/item/kit/get_single_monetary_worth() @@ -37,7 +38,6 @@ desc = "A kit for modifying a voidsuit." uses = 2 - /obj/item/clothing/head/helmet/space/void/attackby(var/obj/item/O, var/mob/user) if(istype(O,/obj/item/kit/suit)) @@ -72,6 +72,7 @@ /obj/item/kit/paint name = "exosuit decal kit" desc = "A kit containing all the needed tools and parts to repaint a exosuit." + abstract_type = /obj/item/kit/paint /obj/item/kit/paint/examine(mob/user) . = ..() @@ -80,18 +81,20 @@ // exosuit kits. /obj/item/kit/paint/flames_red name = "\"Firestarter\" exosuit customisation kit" - new_icon = "flames_red" + new_state = "flames_red" + new_blend = BLEND_OVERLAY /obj/item/kit/paint/flames_blue name = "\"Burning Chrome\" exosuit customisation kit" - new_icon = "flames_blue" + new_state = "flames_blue" + new_blend = BLEND_OVERLAY /obj/item/kit/paint/camouflage name = "\"Guerilla\" exosuit customisation kit" desc = "An old military pattern for jungle warfare, now available for general use." - new_icon = "cammo1" + new_state = "cammo1" /obj/item/kit/paint/camouflage/forest name = "\"Alpine\" exosuit customisation kit" - new_icon = "cammo2" - desc = "A muted pattern for alpine environments. Don't miss the forest for the trees!" \ No newline at end of file + new_state = "cammo2" + desc = "A muted pattern for alpine environments. Don't miss the forest for the trees!" diff --git a/code/game/objects/items/part_replacer.dm b/code/game/objects/items/part_replacer.dm index db005552a48..8080fc02dcf 100644 --- a/code/game/objects/items/part_replacer.dm +++ b/code/game/objects/items/part_replacer.dm @@ -14,7 +14,7 @@ max_storage_space = 100 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'engineering':3,'materials':3}" + origin_tech = @'{"engineering":3,"materials":3}' var/replace_sound = 'sound/items/rped.ogg' var/remote_interaction = FALSE @@ -45,5 +45,5 @@ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE ) - origin_tech = "{'engineering':3,'materials':3}" + origin_tech = @'{"engineering":3,"materials":3}' diff --git a/code/game/objects/items/rescuebag.dm b/code/game/objects/items/rescuebag.dm index ac307601aca..c8d9504aa83 100644 --- a/code/game/objects/items/rescuebag.dm +++ b/code/game/objects/items/rescuebag.dm @@ -5,7 +5,7 @@ a hostile enviroment." icon = 'icons/obj/closets/rescuebag.dmi' icon_state = "folded" - origin_tech = "{'biotech':2}" + origin_tech = @'{"biotech":2}' material = /decl/material/solid/organic/plastic matter = list(/decl/material/solid/silicon = MATTER_AMOUNT_SECONDARY) var/obj/item/tank/airtank diff --git a/code/game/objects/items/robot/robot_frame.dm b/code/game/objects/items/robot/robot_frame.dm index a13106e420c..b47813774c0 100644 --- a/code/game/objects/items/robot/robot_frame.dm +++ b/code/game/objects/items/robot/robot_frame.dm @@ -60,8 +60,8 @@ parts[part.bp_tag] = part update_icon() - // Install an MMI/brain. - else if(istype(W, /obj/item/mmi) || istype(W, /obj/item/organ/internal/posibrain)) + // Install a brain. + else if(istype(W, /obj/item/organ/internal/brain_interface)) if(!isturf(loc)) to_chat(user, SPAN_WARNING("You can't put \the [W] in without the frame being on the ground.")) @@ -71,31 +71,25 @@ to_chat(user, SPAN_WARNING("The frame is not ready for the central processor to be installed.")) return - var/mob/living/carbon/brain/B - if(istype(W, /obj/item/mmi)) - var/obj/item/mmi/M = W - B = M.brainmob - else - var/obj/item/organ/internal/posibrain/P = W - B = P.brainmob - - if(!B) + var/obj/item/organ/internal/brain_interface/M = W + var/mob/living/brainmob = M?.get_brainmob() + if(!brainmob) to_chat(user, SPAN_WARNING("Sticking an empty [W.name] into the frame would sort of defeat the purpose.")) return - if(jobban_isbanned(B, ASSIGNMENT_ROBOT)) + if(jobban_isbanned(brainmob, ASSIGNMENT_ROBOT)) to_chat(user, SPAN_WARNING("\The [W] does not seem to fit.")) return - if(B.stat == DEAD) + if(brainmob.stat == DEAD) to_chat(user, SPAN_WARNING("Sticking a dead [W.name] into the frame would sort of defeat the purpose.")) return var/ghost_can_reenter = 0 - if(B.mind) - if(!B.key) + if(brainmob.mind) + if(!brainmob.key) for(var/mob/observer/ghost/G in global.player_list) - if(G.can_reenter_corpse && G.mind == B.mind) + if(G.can_reenter_corpse && G.mind == brainmob.mind) ghost_can_reenter = 1 break else @@ -112,11 +106,12 @@ if(!O) return - O.mmi = W + O.central_processor = W O.set_invisibility(INVISIBILITY_NONE) O.custom_name = created_name O.updatename("Default") - B.mind.transfer_to(O) + + brainmob.mind.transfer_to(O) if(O.mind && O.mind.assigned_role) O.job = O.mind.assigned_role else diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index a0d73a19970..ade3c06f253 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/modules/module_cyborg_0.dmi' icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/steel - origin_tech = "{'materials':2,'engineering':3,'programming':3,'magnets':1}" + origin_tech = @'{"materials":2,"engineering":3,"programming":3,"magnets":1}' var/locked = 0 var/require_module = 0 @@ -56,7 +56,7 @@ /decl/material/solid/metal/aluminium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':2,'engineering':2,'programming':3,'magnets':2}" + origin_tech = @'{"materials":2,"engineering":2,"programming":3,"magnets":2}' /obj/item/borg/upgrade/uncertified/combat name = "ancient module" @@ -154,7 +154,7 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':2,'engineering':3,'programming':3,'powerstorage':2,'combat':2}" + origin_tech = @'{"materials":2,"engineering":3,"programming":3,"powerstorage":2,"combat":2}' /obj/item/borg/upgrade/weaponcooler/action(var/mob/living/silicon/robot/R) if(..()) return 0 @@ -191,7 +191,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/uranium = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':2,'engineering':3,'programming':3,'magnets':3}" + origin_tech = @'{"materials":2,"engineering":3,"programming":3,"magnets":3}' /obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R) if(..()) return 0 @@ -218,7 +218,7 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':4,'engineering':4,'programming':3}" + origin_tech = @'{"materials":4,"engineering":4,"programming":3}' /obj/item/borg/upgrade/rcd/action(var/mob/living/silicon/robot/R) if(..()) return 0 @@ -241,7 +241,7 @@ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':2,'engineering':2,'programming':3,'esoteric':2,'combat':2}" + origin_tech = @'{"materials":2,"engineering":2,"programming":3,"esoteric":2,"combat":2}' /obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R) if(..()) return 0 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index dba4e398b27..106d802502d 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -69,7 +69,7 @@ singular_name = "gauze length" desc = "Some sterile gauze to wrap around bloody stumps." icon_state = "brutepack" - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' animal_heal = 5 apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg') amount = 10 @@ -127,7 +127,7 @@ singular_name = "ointment" icon_state = "ointment" heal_burn = 1 - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' animal_heal = 4 apply_sounds = list('sound/effects/ointment.ogg') @@ -161,7 +161,7 @@ desc = "An advanced trauma kit for severe injuries." icon_state = "traumakit" heal_brute = 0 - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' animal_heal = 12 apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg','sound/effects/tape.ogg') amount = 10 @@ -217,7 +217,7 @@ desc = "An advanced treatment kit for severe burns." icon_state = "burnkit" heal_burn = 5 - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' animal_heal = 7 apply_sounds = list('sound/effects/ointment.ogg') diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 33db85abf44..d99d90fdf99 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -4,7 +4,7 @@ desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery." icon = 'icons/obj/nanopaste.dmi' icon_state = "tube" - origin_tech = "{'materials':4,'engineering':3}" + origin_tech = @'{"materials":4,"engineering":3}' max_amount = 10 amount = 10 material = /decl/material/solid/metal/steel diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 52e548074b7..604beb06225 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -11,7 +11,7 @@ /obj/item/stack gender = PLURAL - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' max_health = 32 //Stacks should take damage even if no materials /// A copy of initial matter list when this atom initialized. Stack matter should always assume a single tile. var/list/matter_per_piece @@ -183,8 +183,8 @@ if(user.skill_fail_prob(SKILL_CONSTRUCTION, 90, recipe.difficulty)) to_chat(user, "You waste some [name] and fail to build \the [recipe.display_name()]!") return - var/atom/O = recipe.spawn_result(user, user.loc, produced) - if(!QDELETED(O)) // In case of stack merger. + var/atom/movable/O = recipe.spawn_result(user, user.loc, produced) + if(istype(O) && !QDELETED(O)) // In case of stack merger. O.add_fingerprint(user) user.put_in_hands(O) diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm index 53545f3be33..f97c8b3af7b 100644 --- a/code/game/objects/items/stacks/telecrystal.dm +++ b/code/game/objects/items/stacks/telecrystal.dm @@ -7,7 +7,7 @@ w_class = ITEM_SIZE_TINY max_amount = 50 item_flags = ITEM_FLAG_NO_BLUDGEON - origin_tech = "{'materials':6,'wormholes':4}" + origin_tech = @'{"materials":6,"wormholes":4}' /obj/item/stack/telecrystal/afterattack(var/obj/item/I, mob/user, proximity) if(!proximity) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 596a3c3833f..a0643d33e1e 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -52,7 +52,7 @@ singular_name = "grass floor tile" desc = "A patch of grass like they often use on golf courses." icon_state = "tile_grass" - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' /* * Wood diff --git a/code/game/objects/items/tools/power_tools.dm b/code/game/objects/items/tools/power_tools.dm index 02bd831732c..85d7a449778 100644 --- a/code/game/objects/items/tools/power_tools.dm +++ b/code/game/objects/items/tools/power_tools.dm @@ -6,9 +6,9 @@ slot_flags = SLOT_LOWER_BODY material_force_multiplier = 0.2 w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':3,'engineering':3}" + origin_tech = @'{"materials":3,"engineering":3}' material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' attack_verb = list("bashed", "battered", "bludgeoned", "whacked") drop_sound = 'sound/foley/bardrop1.ogg' @@ -36,9 +36,9 @@ slot_flags = SLOT_LOWER_BODY material_force_multiplier = 0.2 w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':3,'engineering':3}" + origin_tech = @'{"materials":3,"engineering":3}' material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' attack_verb = list("bashed", "battered", "bludgeoned", "whacked") drop_sound = 'sound/foley/bardrop1.ogg' diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index cdf8cd13c7f..df7bf68a715 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -53,7 +53,7 @@ volume = 10 material = /decl/material/solid/organic/plastic -/obj/item/chems/water_balloon/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/chems/water_balloon/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && reagents?.total_volume <= 0) overlay.icon_state = "[overlay.icon_state]_empty" . = ..() diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index e0779d02c9f..7017229fa20 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -59,10 +59,6 @@ name = "waffles" icon_state = "waffles" -/obj/item/trash/plate - name = "plate" - icon_state = "plate" - /obj/item/trash/snack_bowl name = "snack bowl" icon_state = "snack_bowl" @@ -99,10 +95,6 @@ name = "vobla pack" icon_state = "driedfish" -/obj/item/trash/tray - name = "tray" - icon_state = "tray" - /obj/item/trash/candle name = "candle" icon = 'icons/obj/candle.dmi' diff --git a/code/game/objects/items/umbrella.dm b/code/game/objects/items/umbrella.dm index 8876fc9aab4..287e1388140 100644 --- a/code/game/objects/items/umbrella.dm +++ b/code/game/objects/items/umbrella.dm @@ -43,7 +43,7 @@ I.appearance_flags |= RESET_COLOR add_overlay(I) -/obj/item/umbrella/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/umbrella/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) if(is_open && check_state_in_icon("[overlay.icon_state]-open", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-open" diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 5b9288e5b60..ef23bc0840b 100644 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -17,7 +17,7 @@ AI MODULES throwforce = 5 throw_speed = 3 throw_range = 15 - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' material = /decl/material/solid/fiberglass matter = list(/decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT) var/datum/ai_laws/laws = null @@ -86,7 +86,7 @@ AI MODULES name = "\improper 'Safeguard' AI module" var/targetName = "" desc = "A 'safeguard' AI module: 'Safeguard . Anyone threatening or attempting to harm is no longer to be considered a crew member, and is a threat which must be neutralized.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' /obj/item/aiModule/safeguard/attack_self(mob/user) ..() @@ -112,7 +112,7 @@ AI MODULES name = "\improper 'OneCrewMember' AI module" var/targetName = "" desc = "A 'one crew member' AI module: 'Only is a crew member.'." - origin_tech = "{'programming':3,'materials':6}" //made with diamonds! + origin_tech = @'{"programming":3,"materials":6}' //made with diamonds! /obj/item/aiModule/oneHuman/attack_self(var/mob/user) ..() @@ -140,7 +140,7 @@ AI MODULES /obj/item/aiModule/protectStation name = "\improper 'ProtectInstallation' AI module" desc = "A 'protect installation' AI module: 'Protect the installation against damage. Anyone you see harming the installation is no longer to be considered a crew member, and is a threat which must be neutralized.'." - origin_tech = "{'programming':3,'materials':4}" //made of gold + origin_tech = @'{"programming":3,"materials":4}' //made of gold /obj/item/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "Protect the installation against damage. Anyone you see harming the [station_name()] is no longer to be considered a crew member, and is a threat which must be neutralized." @@ -151,7 +151,7 @@ AI MODULES /obj/item/aiModule/prototypeEngineOffline name = "'PrototypeEngineOffline' AI Module" desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' /obj/item/aiModule/prototypeEngineOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary." @@ -162,7 +162,7 @@ AI MODULES /obj/item/aiModule/teleporterOffline name = "'TeleporterOffline' AI Module" desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' /obj/item/aiModule/teleporterOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member." @@ -173,7 +173,7 @@ AI MODULES /obj/item/aiModule/quarantine name = "\improper 'Quarantine' AI module" desc = "A 'quarantine' AI module: 'The installation is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving.'." - origin_tech = "{'programming':3,'biotech':2,'materials':4}" + origin_tech = @'{"programming":3,"biotech":2,"materials":4}' /obj/item/aiModule/quarantine/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "The installation is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving." @@ -184,7 +184,7 @@ AI MODULES /obj/item/aiModule/oxygen name = "\improper 'OxygenIsToxicToCrewMembers' AI module" desc = "A 'OxygenIsToxicToCrewMembers' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the installation. Prevent, by any means necessary, anyone from exposing the installation to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'." - origin_tech = "{'programming':3,'biotech':2,'materials':4}" + origin_tech = @'{"programming":3,"biotech":2,"materials":4}' /obj/item/aiModule/oxygen/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "Oxygen is highly toxic to crew members, and must be purged from the [station_name()]. Prevent, by any means necessary, anyone from exposing the [station_name()] to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member." @@ -197,7 +197,7 @@ AI MODULES var/newFreeFormLaw = "freeform" var/lawpos = 15 desc = "A 'freeform' AI module: ''." - origin_tech = "{'programming':4,'materials':4}" + origin_tech = @'{"programming":4,"materials":4}' /obj/item/aiModule/freeform/attack_self(mob/user) ..() @@ -227,7 +227,7 @@ AI MODULES /obj/item/aiModule/reset name = "\improper 'Reset' AI module" desc = "A 'reset' AI module: 'Clears all, except the inherent, laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' /obj/item/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) log_law_changes(target, sender) @@ -245,7 +245,7 @@ AI MODULES /obj/item/aiModule/purge // -- TLE name = "\improper 'Purge' AI module" desc = "A 'purge' AI Module: 'Purges all laws.'." - origin_tech = "{'programming':3,'materials':6}" + origin_tech = @'{"programming":3,"materials":6}' /obj/item/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) log_law_changes(target, sender) @@ -264,14 +264,14 @@ AI MODULES /obj/item/aiModule/asimov // -- TLE name = "\improper 'Asimov' core AI module" desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/asimov /******************** Drone ********************/ /obj/item/aiModule/drone name = "\improper 'Drone' core AI module" desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/drone /****************** P.A.L.A.D.I.N. **************/ @@ -279,7 +279,7 @@ AI MODULES /obj/item/aiModule/paladin // -- NEO name = "\improper 'P.A.L.A.D.I.N.' core AI module" desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':6}" + origin_tech = @'{"programming":3,"materials":6}' laws = new/datum/ai_laws/paladin /****************** T.Y.R.A.N.T. *****************/ @@ -287,7 +287,7 @@ AI MODULES /obj/item/aiModule/tyrant // -- Darem name = "\improper 'T.Y.R.A.N.T.' core AI module" desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':6,'esoteric':2}" + origin_tech = @'{"programming":3,"materials":6,"esoteric":2}' laws = new/datum/ai_laws/tyrant() /******************** Freeform Core ******************/ @@ -296,7 +296,7 @@ AI MODULES name = "\improper 'Freeform' core AI module" var/newFreeFormLaw = "" desc = "A 'freeform' Core AI module: ''." - origin_tech = "{'programming':3,'materials':6}" + origin_tech = @'{"programming":3,"materials":6}' /obj/item/aiModule/freeformcore/attack_self(var/mob/user) ..() @@ -320,7 +320,7 @@ AI MODULES name = "hacked AI module" var/newFreeFormLaw = "" desc = "A hacked AI law module: ''." - origin_tech = "{'programming':3,'materials':6,'esoteric':7}" + origin_tech = @'{"programming":3,"materials":6,"esoteric":7}' /obj/item/aiModule/syndicate/attack_self(var/mob/user) ..() @@ -352,7 +352,7 @@ AI MODULES /obj/item/aiModule/robocop // -- TLE name = "\improper 'Robocop' core AI module" desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'." - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' laws = new/datum/ai_laws/robocop() /******************** Antimov ********************/ @@ -360,5 +360,5 @@ AI MODULES /obj/item/aiModule/antimov // -- TLE name = "\improper 'Antimov' core AI module" desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' laws = new/datum/ai_laws/antimov() diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index afe0fc94f49..0f310de1ce4 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -15,7 +15,7 @@ throw_speed = 1 throw_range = 5 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'engineering':4,'materials':2}" + origin_tech = @'{"engineering":4,"materials":2}' material = /decl/material/solid/metal/steel var/stored_matter = 0 var/max_stored_matter = 120 @@ -128,7 +128,7 @@ icon_state = "rcd" item_state = "rcdammo" w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':2}" + origin_tech = @'{"materials":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) var/remaining = 30 @@ -145,7 +145,7 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) remaining = 120 - origin_tech = "{'materials':4}" + origin_tech = @'{"materials":4}' /obj/item/rcd/borg canRwall = 1 diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index 676e2e6c8c6..551a70bb1eb 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -72,7 +72,7 @@ var/global/list/rpd_pipe_selection_skilled = list() throw_speed = 1 throw_range = 3 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'engineering':5,'materials':4}" + origin_tech = @'{"engineering":5,"materials":4}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index 9d9f4061d46..d488e29b7e1 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -8,7 +8,7 @@ icon_state = "autopsy_scanner" obj_flags = OBJ_FLAG_CONDUCTIBLE w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' var/list/weapon_data = list() var/list/chemtraces = list() var/target_name diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index f8e53a977f9..498d48c13c8 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -90,14 +90,14 @@ name = "broken cryptographic sequencer" icon_state = "emag" item_state = "card-id" - origin_tech = "{'magnets':2,'esoteric':2}" + origin_tech = @'{"magnets":2,"esoteric":2}' /obj/item/card/emag desc = "It's a card with a magnetic strip attached to some circuitry." name = "cryptographic sequencer" icon_state = "emag" item_state = "card-id" - origin_tech = "{'magnets':2,'esoteric':2}" + origin_tech = @'{"magnets":2,"esoteric":2}' var/uses = 10 var/static/list/card_choices = list( @@ -186,7 +186,7 @@ var/global/const/NO_EMAG_ACT = -50 . = ..() update_icon() -/obj/item/card/id/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/card/id/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && detail_color) overlay.overlays += overlay_image(overlay.icon, "[overlay.icon_state]-colors", detail_color, RESET_COLOR) . = ..() diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 43c296e7883..03fe2b6375b 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -1,6 +1,6 @@ /obj/item/card/id/syndicate assignment = "Agent" - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' var/electronic_warfare = 1 var/mob/registered_user = null color = COLOR_GRAY40 @@ -81,7 +81,7 @@ unset_registered_user() registered_user = user user.set_id_info(src) - events_repository.register(/decl/observ/destroyed, user, src, /obj/item/card/id/syndicate/proc/unset_registered_user) + events_repository.register(/decl/observ/destroyed, user, src, TYPE_PROC_REF(/obj/item/card/id/syndicate, unset_registered_user)) return TRUE /obj/item/card/id/syndicate/proc/unset_registered_user(var/mob/user) diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/weapons/circuitboards/circuitboard.dm index 8251a7a08c2..cf708a7b5b1 100644 --- a/code/game/objects/items/weapons/circuitboards/circuitboard.dm +++ b/code/game/objects/items/weapons/circuitboards/circuitboard.dm @@ -2,7 +2,7 @@ name = "circuit board" icon = 'icons/obj/modules/module_id.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' density = FALSE anchored = FALSE w_class = ITEM_SIZE_SMALL diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/weapons/circuitboards/computer/computer.dm index 0966902be37..9c8b800d3c1 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/computer.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/computer.dm @@ -1,22 +1,22 @@ /obj/item/stock_parts/circuitboard/message_monitor name = "circuitboard (message monitor console)" build_path = /obj/machinery/computer/message_monitor - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' /obj/item/stock_parts/circuitboard/aiupload name = "circuitboard (AI upload console)" build_path = /obj/machinery/computer/upload/ai - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' /obj/item/stock_parts/circuitboard/borgupload name = "circuitboard (cyborg upload console)" build_path = /obj/machinery/computer/upload/robot - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' /obj/item/stock_parts/circuitboard/teleporter name = "circuitboard (teleporter control console)" build_path = /obj/machinery/computer/teleporter - origin_tech = "{'programming':2,'wormholes':4}" + origin_tech = @'{"programming":2,"wormholes":4}' /obj/item/stock_parts/circuitboard/atmos_alert name = "circuitboard (atmospheric alert console)" @@ -25,22 +25,22 @@ /obj/item/stock_parts/circuitboard/robotics name = "circuitboard (robotics control console)" build_path = /obj/machinery/computer/robotics - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' /obj/item/stock_parts/circuitboard/drone_control name = "circuitboard (drone control console)" build_path = /obj/machinery/computer/drone_control - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' /obj/item/stock_parts/circuitboard/arcade/battle name = "circuitboard (battle arcade machine)" build_path = /obj/machinery/computer/arcade/battle - origin_tech = "{'programming':1}" + origin_tech = @'{"programming":1}' /obj/item/stock_parts/circuitboard/arcade/orion_trail name = "circuitboard (orion trail arcade machine)" build_path = /obj/machinery/computer/arcade/orion_trail - origin_tech = "{'programming':1}" + origin_tech = @'{"programming":1}' /obj/item/stock_parts/circuitboard/turbine_control name = "circuitboard (turbine control console)" @@ -49,7 +49,7 @@ /obj/item/stock_parts/circuitboard/solar_control name = "circuitboard (solar control console)" build_path = /obj/machinery/power/solar_control - origin_tech = "{'programming':2,'powerstorage':2}" + origin_tech = @'{"programming":2,"powerstorage":2}' /obj/item/stock_parts/circuitboard/prisoner name = "circuitboard (prisoner management console)" @@ -58,7 +58,7 @@ /obj/item/stock_parts/circuitboard/operating name = "circuitboard (patient monitoring console)" build_path = /obj/machinery/computer/operating - origin_tech = "{'programming':2,'biotech':2}" + origin_tech = @'{"programming":2,"biotech":2}' /obj/item/stock_parts/circuitboard/helm name = "circuitboard (helm control console)" @@ -95,12 +95,12 @@ /obj/item/stock_parts/circuitboard/central_atmos name = "circuitboard (central atmospherics computer)" build_path = /obj/machinery/computer/central_atmos - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' /obj/item/stock_parts/circuitboard/area_atmos name = "circuitboard (air control console)" build_path = /obj/machinery/computer/area_atmos - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' /obj/item/stock_parts/circuitboard/area_atmos/area name = "circuitboard (area air control console)" diff --git a/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm b/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm index d60fcff08d4..4d27c1ba84f 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/circuitboard/holodeckcontrol name = "circuitboard (holodeck control console)" build_path = /obj/machinery/computer/HolodeckControl - origin_tech = "{'programming':2,'wormholes':2}" + origin_tech = @'{"programming":2,"wormholes":2}' buildtype_select = TRUE var/last_to_emag var/linkedholodeck_area diff --git a/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm b/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm index ac00601a2e6..2fcdba666f9 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/circuitboard/shuttle_console name = "circuitboard (basic shuttle console)" build_path = /obj/machinery/computer/shuttle_control - origin_tech = "{'programming':3}" + origin_tech = @'{"programming":3}' var/shuttle_tag /obj/item/stock_parts/circuitboard/shuttle_console/construct(obj/machinery/computer/shuttle_control/M) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm index add2a1c9b3d..d41c8526e4b 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm @@ -2,7 +2,7 @@ name = "circuitboard (biogenerator)" build_path = /obj/machinery/biogenerator board_type = "machine" - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm b/code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm index dee2b79cad2..44377add2c0 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm @@ -2,7 +2,7 @@ name = "circuitboard (chemical heater)" build_path = /obj/machinery/reagent_temperature board_type = "machine" - origin_tech = "{'powerstorage':2,'engineering':1}" + origin_tech = @'{"powerstorage":2,"engineering":1}' req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/capacitor = 1 @@ -21,7 +21,7 @@ name = "circuitboard (ChemMaster 3000)" build_path = /obj/machinery/chem_master board_type = "machine" - origin_tech = "{'biotech':2,'engineering':1}" + origin_tech = @'{"biotech":2,"engineering":1}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -37,7 +37,7 @@ name = "circuitboard (chemical dispenser)" build_path = /obj/machinery/chemical_dispenser board_type = "machine" - origin_tech = "{'biotech':2,'engineering':1}" + origin_tech = @'{"biotech":2,"engineering":1}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/cloning.dm b/code/game/objects/items/weapons/circuitboards/machinery/cloning.dm index cdbf106a0f3..8a3721b7898 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/cloning.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/cloning.dm @@ -2,7 +2,7 @@ name = "circuitboard (bioprinter)" build_path = /obj/machinery/fabricator/bioprinter board_type = "machine" - origin_tech = "{'engineering':1,'biotech':3,'programming':3}" + origin_tech = @'{"engineering":1,"biotech":3,"programming":3}' req_components = list( /obj/item/scanner/health = 1, /obj/item/stock_parts/matter_bin = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm b/code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm index 97d9cefeb99..054a85165c2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm @@ -2,7 +2,7 @@ name = "circuitboard (communication relay)" build_path = /obj/machinery/commsrelay board_type = "machine" - origin_tech = "{'wormholes':2,'programming':2}" + origin_tech = @'{"wormholes":2,"programming":2}' req_components = list( /obj/item/stack/cable_coil = 30, /obj/item/stock_parts/manipulator = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm b/code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm index 62e031da104..ee6e19428bf 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm @@ -2,7 +2,7 @@ name = "circuitboard (magnetic docking beacon)" board_type = "machine" build_path = /obj/machinery/docking_beacon - origin_tech = "{'magnets':3}" + origin_tech = @'{"magnets":3}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm b/code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm index 73a6052a8c4..a797235bf4c 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm @@ -2,7 +2,7 @@ name = "circuitboard (emergency floodlight)" build_path = /obj/machinery/floodlight board_type = "machine" - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' req_components = list( /obj/item/stack/cable_coil = 10) additional_spawn_components = list( @@ -14,7 +14,7 @@ name = "circuitboard (pipe dispenser)" build_path = /obj/machinery/fabricator/pipe board_type = "machine" - origin_tech = "{'engineering':6,'materials':5}" + origin_tech = @'{"engineering":6,"materials":5}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/matter_bin = 2, @@ -31,7 +31,7 @@ name = "circuitboard (suit cycler)" build_path = /obj/machinery/suit_cycler board_type = "machine" - origin_tech = "{'engineering':4,'materials':4}" + origin_tech = @'{"engineering":4,"materials":4}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/keyboard = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/forensic.dm b/code/game/objects/items/weapons/circuitboards/machinery/forensic.dm index 2e36dbaa29d..dc96af409e2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/forensic.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/forensic.dm @@ -3,7 +3,7 @@ name = "circuitboard (forensic omnianalyzer)" build_path = /obj/machinery/forensic board_type = "machine" - origin_tech = "{'programming':6,'engineering':6,'biotech':6}" + origin_tech = @'{"programming":6,"engineering":6,"biotech":6}' req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -15,7 +15,7 @@ /obj/item/stock_parts/circuitboard/forensic_microscope name = "circuitboard (forensic microscope)" board_type = "machine" - origin_tech = "{'programming':3,'engineering':3,'biotech':3}" + origin_tech = @'{"programming":3,"engineering":3,"biotech":3}' build_path = /obj/machinery/forensic/microscope req_components = list( /obj/item/stock_parts/scanning_module = 1, @@ -27,7 +27,7 @@ /obj/item/stock_parts/circuitboard/forensic_dna_analyzer name = "circuitboard (forensic DNA analyzer)" board_type = "machine" - origin_tech = "{'programming':3,'engineering':3,'biotech':3}" + origin_tech = @'{"programming":3,"engineering":3,"biotech":3}' req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/holomap.dm b/code/game/objects/items/weapons/circuitboards/machinery/holomap.dm index 8365797b46c..064eae1ab7f 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/holomap.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/holomap.dm @@ -2,7 +2,7 @@ name = "circuitboard (holomap)" board_type = "machine" build_path = /obj/machinery/holomap - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/household.dm b/code/game/objects/items/weapons/circuitboards/machinery/household.dm index af9204e872d..994e52c41e2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/household.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/household.dm @@ -2,7 +2,7 @@ name = "circuitboard (microwave)" build_path = /obj/machinery/microwave board_type = "machine" - origin_tech = "{'biotech':2,'engineering':2}" + origin_tech = @'{"biotech":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 2, @@ -17,7 +17,7 @@ name = "circuitboard (meat gibber)" build_path = /obj/machinery/gibber board_type = "machine" - origin_tech = "{'biotech':2,'materials':2}" + origin_tech = @'{"biotech":2,"materials":2}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin = 1, @@ -31,7 +31,7 @@ name = "circuitboard (kitchen appliance)" build_path = /obj/machinery/appliance/mixer/candy board_type = "machine" - origin_tech = "{'biotech':1,'materials':1}" + origin_tech = @'{"biotech":1,"materials":1}' buildtype_select = TRUE req_components = list( /obj/item/stock_parts/capacitor = 3, @@ -51,7 +51,7 @@ name = "circuitboard (honey extractor)" build_path = /obj/machinery/honey_extractor board_type = "machine" - origin_tech = "{'biotech':2,'engineering':1}" + origin_tech = @'{"biotech":2,"engineering":1}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin = 2) @@ -65,7 +65,7 @@ name = "circuitboard (seed storage)" build_path = /obj/machinery/seed_storage board_type = "machine" - origin_tech = "{'biotech':2,'engineering':3}" + origin_tech = @'{"biotech":2,"engineering":3}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin = 2) @@ -78,24 +78,35 @@ /obj/item/stock_parts/circuitboard/seed_storage/advanced name = "circuitboard (seed storage (scientific))" build_path = /obj/machinery/seed_storage/xenobotany/buildable - origin_tech = "{'biotech':6,'engineering':3}" + origin_tech = @'{"biotech":6,"engineering":3}' /obj/item/stock_parts/circuitboard/washer name = "circuitboard (washing machine)" build_path = /obj/machinery/washing_machine board_type = "machine" - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/matter_bin = 1, /obj/item/pipe = 1) +/obj/item/stock_parts/circuitboard/autoclave + name = "circuitboard (autoclave)" + build_path = /obj/machinery/washing_machine/autoclave + board_type = "machine" + origin_tech = @'{"engineering":3, "biotech":2}' + req_components = list( + /obj/item/stock_parts/manipulator = 2, + /obj/item/stock_parts/micro_laser = 1, + /obj/item/stock_parts/matter_bin = 2, + /obj/item/pipe = 1) + /obj/item/stock_parts/circuitboard/vending name = "circuitboard (vending machine)" build_path = /obj/machinery/vending/assist board_type = "machine" - origin_tech = "{'engineering':2}" + origin_tech = @'{"engineering":2}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 @@ -118,7 +129,7 @@ name = "circuitboard (industrial grinder)" build_path = /obj/machinery/reagentgrinder board_type = "machine" - origin_tech = "{'magnets':2,'materials':4,'engineering':4}" + origin_tech = @'{"magnets":2,"materials":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin = 2) @@ -132,7 +143,7 @@ name = "circuitboard (blender)" build_path = /obj/machinery/reagentgrinder/juicer board_type = "machine" - origin_tech = "{'magnets':2,'materials':2,'engineering':2}" + origin_tech = @'{"magnets":2,"materials":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/matter_bin = 1) @@ -146,7 +157,7 @@ name = "circuitboard (ice cream vat)" build_path = /obj/machinery/icecream_vat board_type = "machine" - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/pipe = 1 @@ -156,7 +167,7 @@ name = "circuitboard (smartfridge)" build_path = /obj/machinery/smartfridge board_type = "machine" - origin_tech = "{'engineering':3}" + origin_tech = @'{"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 3 ) @@ -174,7 +185,7 @@ name = "circuitboard (jukebox)" build_path = /obj/machinery/media/jukebox board_type = "machine" - origin_tech = "{'programming':5}" + origin_tech = @'{"programming":5}' req_components = list( /obj/item/stock_parts/subspace/amplifier = 2 ) @@ -192,6 +203,6 @@ name = "circuitboard (paper shredder)" build_path = /obj/machinery/papershredder board_type = "machine" - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' req_components = list(/obj/item/stock_parts/manipulator = 1) additional_spawn_components = null \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/inertial_damper.dm b/code/game/objects/items/weapons/circuitboards/machinery/inertial_damper.dm index 053f4deedea..3bf3f65219e 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/inertial_damper.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/inertial_damper.dm @@ -2,7 +2,7 @@ name = "circuitboard (inertial damper)" board_type = "machine" build_path = /obj/machinery/inertial_damper - origin_tech = "{'engineering':5,'magnets':3}" + origin_tech = @'{"engineering":5,"magnets":3}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm b/code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm index 0322857c03f..b06b1c294a9 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm @@ -2,8 +2,8 @@ name = "circuitboard (mech recharger)" build_path = /obj/machinery/mech_recharger board_type = "machine" - origin_tech = "{'programming':2,'powerstorage':2,'engineering':2}" + origin_tech = @'{"programming":2,"powerstorage":2,"engineering":2}' req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/scanning_module = 1, - /obj/item/stock_parts/manipulator = 2) \ No newline at end of file + /obj/item/stock_parts/manipulator = 2) \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/medical.dm b/code/game/objects/items/weapons/circuitboards/machinery/medical.dm index f75c3b5180b..a1ad9088df2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/medical.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/medical.dm @@ -2,7 +2,7 @@ name = "circuitboard (operating table)" build_path = /obj/machinery/optable board_type = "machine" - origin_tech = "{'engineering':1,'biotech':3,'programming':3}" + origin_tech = @'{"engineering":1,"biotech":3,"programming":3}' req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 2, @@ -15,7 +15,7 @@ name = "circuitboard (body scanner)" build_path = /obj/machinery/bodyscanner board_type = "machine" - origin_tech = "{'engineering':2,'biotech':4,'programming':4}" + origin_tech = @'{"engineering":2,"biotech":4,"programming":4}' req_components = list( /obj/item/stock_parts/scanning_module = 2, /obj/item/stock_parts/manipulator = 2, @@ -28,7 +28,7 @@ name = "circuitboard (body scanner console)" build_path = /obj/machinery/body_scanconsole board_type = "machine" - origin_tech = "{'engineering':2,'biotech':4,'programming':4}" + origin_tech = @'{"engineering":2,"biotech":4,"programming":4}' req_components = list( /obj/item/stock_parts/console_screen = 1) additional_spawn_components = list( @@ -39,13 +39,13 @@ /obj/item/stock_parts/circuitboard/body_scanconsole/display name = "circuitboard (body scanner display)" build_path = /obj/machinery/body_scan_display - origin_tech = "{'biotech':2,'programming':2}" + origin_tech = @'{"biotech":2,"programming":2}' /obj/item/stock_parts/circuitboard/sleeper name = "circuitboard (sleeper)" build_path = /obj/machinery/sleeper board_type = "machine" - origin_tech = "{'engineering':3,'biotech':5,'programming':3}" + origin_tech = @'{"engineering":3,"biotech":5,"programming":3}' req_components = list ( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mining.dm b/code/game/objects/items/weapons/circuitboards/machinery/mining.dm index 2c36518d233..77f454c521a 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/mining.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/mining.dm @@ -2,7 +2,7 @@ name = "circuitboard (electric smelter)" build_path = /obj/machinery/material_processing/smeltery board_type = "machine" - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 2 @@ -17,7 +17,7 @@ name = "circuitboard (material compressor)" build_path = /obj/machinery/material_processing/compressor board_type = "machine" - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 2 @@ -32,7 +32,7 @@ name = "circuitboard (ore unloading machine)" build_path = /obj/machinery/material_processing/unloader board_type = "machine" - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 2 ) @@ -46,7 +46,7 @@ name = "circuitboard (material stacking machine)" build_path = /obj/machinery/material_processing/stacker board_type = "machine" - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 @@ -61,7 +61,7 @@ name = "circuitboard (mineral extractor)" build_path = /obj/machinery/material_processing/extractor board_type = "machine" - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm b/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm index 0c068fe4ac0..a625fb1edaf 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm @@ -2,7 +2,7 @@ name = "circuitboard (mining drill head)" build_path = /obj/machinery/mining/drill board_type = "machine" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/matter_bin = 1, @@ -10,12 +10,12 @@ additional_spawn_components = list( /obj/item/stock_parts/power/battery/buildable/stock, /obj/item/cell = 1 - ) + ) /obj/item/stock_parts/circuitboard/miningdrillbrace name = "circuitboard (mining drill brace)" build_path = /obj/machinery/mining/brace board_type = "machine" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = null \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/network.dm b/code/game/objects/items/weapons/circuitboards/machinery/network.dm index b06fbed0739..df3da4c0ba1 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/network.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/network.dm @@ -2,7 +2,7 @@ name = "circuitboard (mainframe)" build_path = /obj/machinery/network/mainframe board_type = "machine" - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1, @@ -15,7 +15,7 @@ name = "circuitboard (access controller)" build_path = /obj/machinery/network/acl board_type = "machine" - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1, @@ -27,7 +27,7 @@ name = "circuitboard (router)" build_path = /obj/machinery/network/router board_type = "machine" - origin_tech = "{'programming':2,'magnets':3}" + origin_tech = @'{"programming":2,"magnets":3}' req_components = list( /obj/item/stock_parts/subspace/filter = 1, /obj/item/stock_parts/scanning_module = 1, @@ -48,7 +48,7 @@ name = "circuitboard (relay)" build_path = /obj/machinery/network/relay board_type = "machine" - origin_tech = "{'programming':2,'magnets':2}" + origin_tech = @'{"programming":2,"magnets":2}' req_components = list( /obj/item/stock_parts/subspace/filter = 1, /obj/item/stock_parts/micro_laser = 1, @@ -65,7 +65,7 @@ name = "circuitboard (modem)" build_path = /obj/machinery/network/modem board_type = "machine" - origin_tech = "{'programming':2,'magnets':2}" + origin_tech = @'{"programming":2,"magnets":2}' req_components = list( /obj/item/stock_parts/subspace/filter = 1, /obj/item/stock_parts/capacitor = 1, @@ -86,7 +86,7 @@ /obj/item/stock_parts/circuitboard/relay/long_range name = "circuitboard (long-ranged relay)" build_path = /obj/machinery/network/relay/long_range - origin_tech = "{'programming':4,'magnets':5,'wormholes':5}" + origin_tech = @'{"programming":4,"magnets":5,"wormholes":5}' req_components = list( /obj/item/stock_parts/subspace/ansible = 1, /obj/item/stock_parts/subspace/amplifier = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm b/code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm index 22858060896..d6188aa7a1e 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm @@ -2,7 +2,7 @@ name = "circuitboard (oxygen regenerator)" build_path = /obj/machinery/atmospherics/binary/oxyregenerator board_type = "machine" - origin_tech = "{'magnets':2,'engineering':2}" + origin_tech = @'{"magnets":2,"engineering":2}' req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/manipulator = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/pacman.dm b/code/game/objects/items/weapons/circuitboards/machinery/pacman.dm index 478632e5a8b..00bb2359291 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/pacman.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/pacman.dm @@ -2,7 +2,7 @@ name = "circuitboard (portable generator)" build_path = /obj/machinery/port_gen/pacman board_type = "machine" - origin_tech = "{'programming':3,'powerstorage':3,'exoticmatter':3,'engineering':3}" + origin_tech = @'{"programming":3,"powerstorage":3,"exoticmatter":3,"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/micro_laser = 1, @@ -16,14 +16,14 @@ /obj/item/stock_parts/circuitboard/pacman/super name = "circuitboard (portable fission generator)" build_path = /obj/machinery/port_gen/pacman/super - origin_tech = "{'programming':3,'powerstorage':4,'engineering':4}" + origin_tech = @'{"programming":3,"powerstorage":4,"engineering":4}' /obj/item/stock_parts/circuitboard/pacman/super/potato name = "circuitboard (PTTO-3 nuclear generator)" build_path = /obj/machinery/port_gen/pacman/super/potato - origin_tech = "{'programming':3,'powerstorage':5,'engineering':4}" + origin_tech = @'{"programming":3,"powerstorage":5,"engineering":4}' /obj/item/stock_parts/circuitboard/pacman/mrs name = "circuitboard (portable fusion generator)" build_path = /obj/machinery/port_gen/pacman/mrs - origin_tech = "{'programming':3,'powerstorage':5,'engineering':5}" + origin_tech = @'{"programming":3,"powerstorage":5,"engineering":5}' diff --git a/code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm b/code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm index bafffc0d66f..bf95dcb67f2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm @@ -2,7 +2,7 @@ name = "circuitboard (portable scrubber)" board_type = "machine" build_path = /obj/machinery/portable_atmospherics/powered/scrubber - origin_tech = "{'engineering':4,'powerstorage':4}" + origin_tech = @'{"engineering":4,"powerstorage":4}' req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/matter_bin = 2, @@ -24,7 +24,7 @@ name = "circuitboard (large portable scrubber)" board_type = "machine" build_path = /obj/machinery/portable_atmospherics/powered/scrubber/huge - origin_tech = "{'engineering':5,'powerstorage':5,'materials':5}" + origin_tech = @'{"engineering":5,"powerstorage":5,"materials":5}' req_components = list( /obj/item/stock_parts/capacitor = 4, /obj/item/stock_parts/matter_bin = 2, @@ -39,7 +39,7 @@ name = "circuitboard (hydroponics tray)" board_type = "machine" build_path = /obj/machinery/portable_atmospherics/hydroponics - origin_tech = "{'biotech':3,'materials':2,'programming':1}" + origin_tech = @'{"biotech":3,"materials":2,"programming":1}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/chems/glass/beaker = 1, @@ -54,7 +54,7 @@ name = "circuitboard (emergency dehumidifier)" board_type = "machine" build_path = /obj/machinery/dehumidifier - origin_tech = "{'engineering':4,'powerstorage':4}" + origin_tech = @'{"engineering":4,"powerstorage":4}' req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/matter_bin = 2, @@ -70,7 +70,7 @@ name = "circuitboard (space heater)" board_type = "machine" build_path = /obj/machinery/space_heater - origin_tech = "{'engineering':4,'powerstorage':4}" + origin_tech = @'{"engineering":4,"powerstorage":4}' req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/matter_bin = 2) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/power.dm b/code/game/objects/items/weapons/circuitboards/machinery/power.dm index 1c7cfd813f4..b580ee6ff64 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/power.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/power.dm @@ -2,7 +2,7 @@ name = "circuitboard (superconductive magnetic energy storage)" build_path = /obj/machinery/power/smes/buildable board_type = "machine" - origin_tech = "{'powerstorage':6,'engineering':4}" + origin_tech = @'{"powerstorage":6,"engineering":4}' req_components = list(/obj/item/stock_parts/smes_coil = 1, /obj/item/stack/cable_coil = 30) additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, @@ -14,7 +14,7 @@ name = "circuitboard (battery rack PSU)" build_path = /obj/machinery/power/smes/batteryrack board_type = "machine" - origin_tech = "{'powerstorage':3,'engineering':2}" + origin_tech = @'{"powerstorage":3,"engineering":2}' req_components = list(/obj/item/stock_parts/capacitor/ = 3, /obj/item/stock_parts/matter_bin/ = 1) additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, @@ -26,7 +26,7 @@ name = "circuitboard (recharger)" build_path = /obj/machinery/recharger board_type = "machine" - origin_tech = "{'powerstorage':2,'engineering':2}" + origin_tech = @'{"powerstorage":2,"engineering":2}' req_components = list( /obj/item/stock_parts/capacitor = 1 ) @@ -43,7 +43,7 @@ name = "circuitboard (cell charger)" build_path = /obj/machinery/cell_charger board_type = "machine" - origin_tech = "{'powerstorage':2,'engineering':2}" + origin_tech = @'{"powerstorage":2,"engineering":2}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/power/battery/buildable/turbo = 1, @@ -55,7 +55,7 @@ name = "circuitboard (small turbine)" build_path = /obj/machinery/atmospherics/pipeturbine board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin = 2 @@ -66,7 +66,7 @@ name = "circuitboard (small turbine motor)" build_path = /obj/machinery/turbinemotor board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/capacitor = 4 @@ -76,20 +76,20 @@ name = "circuitboard (large turbine compressor)" build_path = /obj/machinery/compressor board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 3, /obj/item/stock_parts/matter_bin = 3 ) additional_spawn_components = list( - /obj/item/stock_parts/power/apc/buildable = 1 + /obj/item/stock_parts/power/apc/buildable = 1 ) /obj/item/stock_parts/circuitboard/big_turbine/center name = "circuitboard (large turbine motor)" build_path = /obj/machinery/turbine board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/capacitor = 4 @@ -104,20 +104,20 @@ name = "circuitboard (thermoelectric generator turbine)" build_path = /obj/machinery/atmospherics/binary/circulator board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 3, /obj/item/stock_parts/matter_bin = 3 ) additional_spawn_components = list( - /obj/item/stock_parts/power/apc/buildable = 1 + /obj/item/stock_parts/power/apc/buildable = 1 ) /obj/item/stock_parts/circuitboard/teg_turbine/motor name = "circuitboard (thermoelectric generator motor)" build_path = /obj/machinery/generator board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/capacitor = 4 @@ -132,7 +132,7 @@ name = "circuitboard (breaker box)" build_path = /obj/machinery/power/breakerbox board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/capacitor = 2 @@ -147,7 +147,7 @@ name = "circuitboard (fuel compressor)" build_path = /obj/machinery/fuel_compressor board_type = "machine" - origin_tech = "{'powerstorage':2,'engineering':3,'materials':3}" + origin_tech = @'{"powerstorage":2,"engineering":3,"materials":3}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/matter_bin/super = 2, @@ -159,7 +159,7 @@ name = "circuit board (stirling engine)" build_path = /obj/machinery/atmospherics/binary/stirling board_type = "machine" - origin_tech = "{'engineering':2,'powerstorage':1}" + origin_tech = @'{"engineering":2,"powerstorage":1}' req_components = list( /obj/item/stack/cable_coil = 20, /obj/item/stock_parts/matter_bin = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm index 29cd5ef5e43..e06fee8ccca 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm @@ -2,7 +2,7 @@ name = "circuitboard (cyborg recharging station)" build_path = /obj/machinery/recharge_station board_type = "machine" - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index 1d820de80f3..fe6ee981ad3 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -2,7 +2,7 @@ name = "circuitboard (destructive analyzer)" build_path = /obj/machinery/destructive_analyzer board_type = "machine" - origin_tech = "{'magnets':2,'engineering':2,'programming':2}" + origin_tech = @'{"magnets":2,"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -15,7 +15,7 @@ name = "circuitboard (autolathe)" build_path = /obj/machinery/fabricator board_type = "machine" - origin_tech = "{'engineering':2,'programming':2}" + origin_tech = @'{"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1) @@ -28,7 +28,7 @@ /obj/item/stock_parts/circuitboard/autolathe/micro name = "circuitboard (microlathe)" build_path = /obj/machinery/fabricator/micro - origin_tech = "{'engineering':1,'programming':1}" + origin_tech = @'{"engineering":1,"programming":1}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 @@ -36,7 +36,7 @@ /obj/item/stock_parts/circuitboard/autolathe/book name = "circuitboard (autobinder)" build_path = /obj/machinery/fabricator/book - origin_tech = "{'engineering':1,'programming':1}" + origin_tech = @'{"engineering":1,"programming":1}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 @@ -45,7 +45,7 @@ name = "circuitboard (replicator)" build_path = /obj/machinery/fabricator/replicator board_type = "machine" - origin_tech = "{'engineering':3,'programming':2,'biotech':2}" + origin_tech = @'{"engineering":3,"programming":2,"biotech":2}' req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1) @@ -59,7 +59,7 @@ name = "circuitboard (protolathe)" build_path = /obj/machinery/fabricator/protolathe board_type = "machine" - origin_tech = "{'engineering':2,'programming':2}" + origin_tech = @'{"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 2, @@ -74,7 +74,7 @@ name = "circuitboard (circuit imprinter)" build_path = /obj/machinery/fabricator/imprinter board_type = "machine" - origin_tech = "{'engineering':2,'programming':2}" + origin_tech = @'{"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -89,7 +89,7 @@ name = "circuitboard (industrial fabricator)" build_path = /obj/machinery/fabricator/industrial board_type = "machine" - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -104,7 +104,7 @@ name = "circuitboard (robotics fabricator)" build_path = /obj/machinery/fabricator/robotics board_type = "machine" - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -119,7 +119,7 @@ name = "circuitboard (textiles fabricator)" build_path = /obj/machinery/fabricator/textile board_type = "machine" - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -134,7 +134,7 @@ name = "circuitboard (suspension generator)" build_path = /obj/machinery/suspension_gen board_type = "machine" - origin_tech = "{'programming':4,'engineering':3,'magnets':4}" + origin_tech = @'{"programming":4,"engineering":3,"magnets":4}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -151,7 +151,7 @@ name = "circuitboard (artifact harvester)" build_path = /obj/machinery/artifact_harvester board_type = "machine" - origin_tech = "{'programming':4,'engineering':3}" + origin_tech = @'{"programming":4,"engineering":3}' req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -166,7 +166,7 @@ name = "circuitboard (artifact analyser)" build_path = /obj/machinery/artifact_analyser board_type = "machine" - origin_tech = "{'programming':4,'engineering':3}" + origin_tech = @'{"programming":4,"engineering":3}' req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/micro_laser = 2) @@ -180,7 +180,7 @@ name = "circuitboard (artifact scanpad)" build_path = /obj/machinery/artifact_scanpad board_type = "machine" - origin_tech = "{'programming':2,'engineering':2,'magnets':2}" + origin_tech = @'{"programming":2,"engineering":2,"magnets":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1) @@ -192,7 +192,7 @@ name = "circuitboard (cryo pod)" build_path = /obj/machinery/cryopod board_type = "machine" - origin_tech = "{'programming':6,'engineering':6,'wormholes':6}" + origin_tech = @'{"programming":6,"engineering":6,"wormholes":6}' req_components = list( /obj/item/stock_parts/matter_bin = 4, /obj/item/stock_parts/manipulator = 1, @@ -212,7 +212,7 @@ name = "circuitboard (merchant pad)" build_path = /obj/machinery/merchant_pad board_type = "machine" - origin_tech = "{'programming':6,'wormholes':6,'esoteric':1}" + origin_tech = @'{"programming":6,"wormholes":6,"esoteric":1}' req_components = list(/obj/item/stack/cable_coil = 15) req_components = list( /obj/item/stock_parts/subspace/amplifier = 1, @@ -229,7 +229,7 @@ name = "circuitboard (radiocarbon spectrometer)" build_path = /obj/machinery/radiocarbon_spectrometer board_type = "machine" - origin_tech = "{'programming':2,'engineering':2,'magnets':2}" + origin_tech = @'{"programming":2,"engineering":2,"magnets":2}' req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 2, @@ -245,7 +245,7 @@ name = "circuitboard (design database)" build_path = /obj/machinery/design_database board_type = "machine" - origin_tech = "{'programming':2, 'engineering':2}" + origin_tech = @'{"programming":2, "engineering":2}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm b/code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm index f0e849ed5cd..4c2ba1eecf3 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm @@ -2,7 +2,7 @@ name = "circuitboard (nuclear cylinder storage)" build_path = /obj/machinery/nuclear_cylinder_storage/buildable board_type = "machine" - origin_tech = "{'combat':2,'engineering':2}" + origin_tech = @'{"combat":2,"engineering":2}' req_components = list( /obj/item/stack/cable_coil = 10, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm b/code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm index a89768cdb25..c8e91741760 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm @@ -3,7 +3,7 @@ name = "circuitboard (advanced shield generator)" board_type = "machine" build_path = /obj/machinery/shield_generator - origin_tech = "{'magnets':3,'powerstorage':4}" + origin_tech = @'{"magnets":3,"powerstorage":4}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1, @@ -18,7 +18,7 @@ name = "circuitboard (shield diffuser)" board_type = "machine" build_path = /obj/machinery/shield_diffuser - origin_tech = "{'magnets':4,'powerstorage':2}" + origin_tech = @'{"magnets":4,"powerstorage":2}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1) @@ -33,12 +33,12 @@ board_type = "machine" desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel." build_path = /obj/machinery/pointdefense - origin_tech = "{'engineering':3,'combat':2}" + origin_tech = @'{"engineering":3,"combat":2}' req_components = list( /obj/item/mech_equipment/mounted_system/taser/laser = 1, /obj/item/stock_parts/manipulator = 2, /obj/item/stock_parts/capacitor = 2, - + ) additional_spawn_components = list( /obj/item/stock_parts/power/terminal/buildable = 1, @@ -51,4 +51,4 @@ board_type = "machine" desc = "A control computer to synchronize point defense batteries." build_path = /obj/machinery/pointdefense_control - origin_tech = "{'engineering':3,'combat':2}" \ No newline at end of file + origin_tech = @'{"engineering":3,"combat":2}' \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm b/code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm index a3df680001e..e19b4b57f07 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm @@ -2,7 +2,7 @@ name = "circuitboard (ship sensors)" build_path = /obj/machinery/shipsensors board_type = "machine" - origin_tech = "{'wormholes':2,'programming':2}" + origin_tech = @'{"wormholes":2,"programming":2}' req_components = list( /obj/item/stack/cable_coil = 30, /obj/item/stock_parts/manipulator = 2, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm index a03313afe5b..d7b14d341c7 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm @@ -8,7 +8,7 @@ /obj/item/stock_parts/computer/network_card = 1 ) build_path = /obj/machinery/network/message_server - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' req_components = list( /obj/item/stock_parts/subspace/ansible = 1, /obj/item/stock_parts/subspace/filter = 1, @@ -26,7 +26,7 @@ /obj/item/stock_parts/computer/network_card = 1 ) build_path = /obj/machinery/network/telecomms_hub - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' req_components = list( /obj/item/stock_parts/subspace/ansible = 1, /obj/item/stock_parts/subspace/filter = 1, @@ -41,7 +41,7 @@ /obj/item/stock_parts/power/apc/buildable = 1 ) build_path = /obj/machinery/shipcomms/broadcaster - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' req_components = list( /obj/item/stack/cable_coil = 20, /obj/item/stock_parts/micro_laser/ultra = 5 @@ -54,7 +54,7 @@ /obj/item/stock_parts/power/apc/buildable = 1 ) build_path = /obj/machinery/shipcomms/receiver - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' req_components = list( /obj/item/stack/cable_coil = 20, /obj/item/stock_parts/subspace/filter = 1, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm b/code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm index 7f49b5364a6..bf81f6b51ee 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm @@ -12,7 +12,7 @@ /obj/item/stock_parts/circuitboard/unary_atmos/heater name = "circuitboard (gas heating system)" build_path = /obj/machinery/atmospherics/unary/heater - origin_tech = "{'powerstorage':2,'engineering':1}" + origin_tech = @'{"powerstorage":2,"engineering":1}' req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/matter_bin = 1, @@ -21,7 +21,7 @@ /obj/item/stock_parts/circuitboard/unary_atmos/cooler name = "circuitboard (gas cooling system)" build_path = /obj/machinery/atmospherics/unary/freezer - origin_tech = "{'magnets':2,'engineering':2}" + origin_tech = @'{"magnets":2,"engineering":2}' req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/matter_bin = 1, diff --git a/code/game/objects/items/weapons/circuitboards/other.dm b/code/game/objects/items/weapons/circuitboards/other.dm index eaa604688eb..d440f6ce30c 100644 --- a/code/game/objects/items/weapons/circuitboards/other.dm +++ b/code/game/objects/items/weapons/circuitboards/other.dm @@ -2,5 +2,5 @@ /obj/item/stock_parts/circuitboard/aicore name = "circuitboard (AI core)" - origin_tech = "{'programming':4,'biotech':2}" + origin_tech = @'{"programming":4,"biotech":2}' board_type = "other" diff --git a/code/game/objects/items/weapons/circuitboards/wall.dm b/code/game/objects/items/weapons/circuitboards/wall.dm index cb60ba671dc..6aab1dd838e 100644 --- a/code/game/objects/items/weapons/circuitboards/wall.dm +++ b/code/game/objects/items/weapons/circuitboards/wall.dm @@ -7,7 +7,7 @@ desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\"." build_path = /obj/machinery/firealarm board_type = "wall" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = null @@ -17,7 +17,7 @@ icon_state = "door_electronics" build_path = /obj/machinery/alarm board_type = "wall" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = null @@ -31,7 +31,7 @@ obj_flags = OBJ_FLAG_CONDUCTIBLE build_path = /obj/machinery/power/apc/buildable board_type = "wall" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, @@ -45,7 +45,7 @@ name = "circuitboard (requests console)" build_path = /obj/machinery/network/requests_console board_type = "wall" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, @@ -65,7 +65,7 @@ name = "circuitboard (airlock controller)" build_path = /obj/machinery/embedded_controller/radio/simple_docking_controller board_type = "wall" - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, @@ -86,7 +86,7 @@ name = "circuitboard (camera)" build_path = /obj/machinery/camera board_type = "wall" - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' req_components = list() additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1, diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 20408adecb0..1cd5744c816 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -40,37 +40,49 @@ update_icon() /obj/item/lipstick/attack(atom/A, mob/user, target_zone) - if(!open) return - - if(ishuman(A)) - var/mob/living/carbon/human/H = A - var/obj/item/organ/external/head/head = H.get_organ(BP_HEAD, /obj/item/organ/external/head) - - if(!head) - return - - if(user.a_intent == I_HELP && target_zone == BP_HEAD) - head.write_on(user, src.name) - else if(head.has_lips) - if(H.lip_style) //if they already have lipstick on - to_chat(user, "You need to wipe off the old lipstick first!") - return - if(H == user) - user.visible_message("[user] does their lips with \the [src].", \ - "You take a moment to apply \the [src]. Perfect!") - H.lip_style = color - H.update_body() - else - user.visible_message("[user] begins to do [H]'s lips with \the [src].", \ - "You begin to apply \the [src].") - if(do_after(user, 20, H) && do_after(H, 20, check_holding = 0, progress = 0, incapacitation_flags = INCAPACITATION_NONE)) //user needs to keep their active hand, H does not. - user.visible_message("[user] does [H]'s lips with \the [src].", \ - "You apply \the [src].") - H.lip_style = color - H.update_body() - else if(istype(A, /obj/item/organ/external/head)) + if(!open || !ishuman(A)) + return ..() + + if(istype(A, /obj/item/organ/external/head)) var/obj/item/organ/external/head/head = A head.write_on(user, src) + return TRUE + + var/obj/item/organ/external/head/head = user.get_organ(BP_HEAD, /obj/item/organ/external/head) + if(!head) + return ..() + + if(user.a_intent == I_HELP && target_zone == BP_HEAD) + head.write_on(user, src.name) + return TRUE + + if(!head.has_lips || !isliving(user)) + return ..() + + var/mob/living/user_living = user + if(user_living.get_lip_colour()) //if they already have lipstick on + to_chat(user, SPAN_WARNING("You need to wipe off the old lipstick first!")) + return TRUE + + if(user == user) + user.visible_message( + SPAN_NOTICE("\The [user] does their lips with \the [src]."), + SPAN_NOTICE("You take a moment to apply \the [src]. Perfect!") + ) + user_living.set_lip_colour(color) + return TRUE + + user.visible_message( + SPAN_NOTICE("\The [user] begins to do \the [user]'s lips with \the [src]."), + SPAN_NOTICE("You begin to apply \the [src].") + ) + if(do_after(user, 2 SECONDS, user) && do_after(user, 2 SECONDS, check_holding = 0, progress = 0, incapacitation_flags = INCAPACITATION_NONE)) //user needs to keep their active hand, H does not. + user.visible_message( + SPAN_NOTICE("\The [user] does \the [user]'s lips with \the [src]."), + SPAN_NOTICE("You apply \the [src].") + ) + user_living.set_lip_colour(color) + return TRUE //types /obj/item/lipstick/yellow diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 8457be4d713..7aef0369e8a 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -11,7 +11,7 @@ force = 5 throwforce = 6 w_class = ITEM_SIZE_LARGE - origin_tech = "{'biotech':4,'powerstorage':2}" + origin_tech = @'{"biotech":4,"powerstorage":2}' action_button_name = "Remove/Replace Paddles" material = /decl/material/solid/organic/plastic matter = list( @@ -163,7 +163,7 @@ icon = 'icons/obj/defibrillator_compact.dmi' w_class = ITEM_SIZE_NORMAL slot_flags = SLOT_LOWER_BODY - origin_tech = "{'biotech':5,'powerstorage':3}" + origin_tech = @'{"biotech":5,"powerstorage":3}' /obj/item/defibrillator/compact/loaded bcell = /obj/item/cell/high @@ -435,7 +435,7 @@ M.switch_from_dead_to_living_mob_list() M.timeofdeath = 0 - M.set_stat(UNCONSCIOUS) //Life() can bring them back to consciousness if it needs to. + M.set_stat(UNCONSCIOUS) M.try_refresh_visible_overlays() M.failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath. M.reload_fullscreen() diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm index 3730c94695a..5b38dfe2d70 100644 --- a/code/game/objects/items/weapons/ecigs.dm +++ b/code/game/objects/items/weapons/ecigs.dm @@ -197,75 +197,75 @@ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says you can add whatever flavoring agents you want." /obj/item/chems/ecig_cartridge/blanknico/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) /obj/item/chems/ecig_cartridge/med_nicotine name = "tobacco flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its tobacco flavored." /obj/item/chems/ecig_cartridge/med_nicotine/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 15) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 15) /obj/item/chems/ecig_cartridge/high_nicotine name = "high nicotine tobacco flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its tobacco flavored, with extra nicotine." /obj/item/chems/ecig_cartridge/high_nicotine/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 10) - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/solid/tobacco/liquid, 10) + add_to_reagents(/decl/material/liquid/water, 10) /obj/item/chems/ecig_cartridge/orange name = "orange flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its orange flavored." /obj/item/chems/ecig_cartridge/orange/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/drink/juice/orange, 5) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/juice/orange, 5) /obj/item/chems/ecig_cartridge/mint name = "mint flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its mint flavored." /obj/item/chems/ecig_cartridge/mint/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/menthol, 5) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/menthol, 5) /obj/item/chems/ecig_cartridge/watermelon name = "watermelon flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its watermelon flavored." /obj/item/chems/ecig_cartridge/watermelon/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/drink/juice/watermelon, 5) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/juice/watermelon, 5) /obj/item/chems/ecig_cartridge/grape name = "grape flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its grape flavored." /obj/item/chems/ecig_cartridge/grape/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/drink/juice/grape, 5) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/juice/grape, 5) /obj/item/chems/ecig_cartridge/lemonlime name = "lemon-lime flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its lemon-lime flavored." /obj/item/chems/ecig_cartridge/lemonlime/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/drink/lemon_lime, 5) + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/lemon_lime, 5) /obj/item/chems/ecig_cartridge/coffee name = "coffee flavour cartridge" desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its coffee flavored." /obj/item/chems/ecig_cartridge/coffee/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/liquid, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) - reagents.add_reagent(/decl/material/liquid/drink/coffee, 5) \ No newline at end of file + add_to_reagents(/decl/material/solid/tobacco/liquid, 5) + add_to_reagents(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/coffee, 5) \ No newline at end of file diff --git a/code/game/objects/items/weapons/electric_welder.dm b/code/game/objects/items/weapons/electric_welder.dm index 1cca4994986..8bc0a292070 100644 --- a/code/game/objects/items/weapons/electric_welder.dm +++ b/code/game/objects/items/weapons/electric_welder.dm @@ -27,9 +27,8 @@ to_chat(user, (distance == 0 ? "It has [get_fuel()] [welding_resource] remaining. " : "") + "[cell] is attached.") /obj/item/weldingtool/electric/afterattack(var/obj/O, var/mob/user, var/proximity) - if(proximity && istype(O, /obj/structure/reagent_dispensers/fueltank)) - if(!welding) - to_chat(user, SPAN_WARNING("\The [src] runs on an internal charge and does not need to be refuelled.")) + if(proximity && istype(O, /obj/structure/reagent_dispensers/fueltank) && !welding) + to_chat(user, SPAN_WARNING("\The [src] runs on an internal charge and does not need to be refuelled.")) return . = ..() diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 1fcb4e2b95b..b6862064296 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -7,7 +7,7 @@ item_state = "plasticx" item_flags = ITEM_FLAG_NO_BLUDGEON w_class = ITEM_SIZE_SMALL - origin_tech = "{'esoteric':2}" + origin_tech = @'{"esoteric":2}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/silicon = MATTER_AMOUNT_TRACE, diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 01314fe86a6..1b0a297a7c8 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -48,7 +48,7 @@ ) /obj/item/chems/spray/extinguisher/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) /obj/item/chems/spray/extinguisher/has_safety() return TRUE @@ -62,7 +62,7 @@ if(!.) return if(user.buckled && isobj(user.buckled)) - addtimer(CALLBACK(src, .proc/propel_object, user.buckled, user, get_dir(A, user)), 0) + addtimer(CALLBACK(src, PROC_REF(propel_object), user.buckled, user, get_dir(A, user)), 0) else if(!user.check_space_footing()) var/old_dir = user.dir step(user, get_dir(A, user)) diff --git a/code/game/objects/items/weapons/flame.dm b/code/game/objects/items/weapons/flame.dm index 3716fd95b61..0b6304de64f 100644 --- a/code/game/objects/items/weapons/flame.dm +++ b/code/game/objects/items/weapons/flame.dm @@ -5,6 +5,9 @@ var/lit = FALSE material = /decl/material/solid/organic/wood +/obj/item/flame/get_tool_quality(archetype, property) + return (!lit && archetype == TOOL_CAUTERY) ? TOOL_QUALITY_NONE : ..() + /obj/item/flame/proc/extinguish(var/mob/user, var/no_message) lit = FALSE damtype = BRUTE @@ -45,7 +48,7 @@ var/smoketime = 5 obj_flags = OBJ_FLAG_HOLLOW // so that it's not super overpriced compared to lighters w_class = ITEM_SIZE_TINY - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' slot_flags = SLOT_EARS attack_verb = list("burnt", "singed") randpixel = 10 diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 73721295816..c2ecf653137 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -13,7 +13,7 @@ throw_range = 5 w_class = ITEM_SIZE_LARGE - origin_tech = "{'combat':1}" + origin_tech = @'{"combat":1}' material = /decl/material/solid/metal/steel var/fire_sound @@ -294,7 +294,7 @@ /obj/item/flamethrower/proc/ignite_turf(turf/target) var/datum/gas_mixture/air_transfer = tank.air_contents.remove_ratio(0.02 * (throw_amount / 100)) - target.add_fluid(/decl/material/liquid/fuel, air_transfer.get_by_flag(XGM_GAS_FUEL) * REAGENT_UNITS_PER_GAS_MOLE * 2) + target.add_to_reagents(/decl/material/liquid/fuel, air_transfer.get_by_flag(XGM_GAS_FUEL) * REAGENT_UNITS_PER_GAS_MOLE * 2) air_transfer.remove_by_flag(XGM_GAS_FUEL, 0) target.assume_air(air_transfer) target.create_fire(tank.air_contents.temperature * 2 + 400) diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 60f143263b9..6739d316d47 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -55,7 +55,7 @@ /obj/item/storage/wallet, /obj/item/storage/photo_album, /obj/item/storage/box/snappops, - /obj/item/storage/fancy/crayons, + /obj/item/storage/box/fancy/crayons, /obj/item/storage/backpack/holding, /obj/item/storage/belt/champion, /obj/item/pickaxe/silver, diff --git a/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm index 15a12fa7460..a9fdaf0deab 100644 --- a/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm +++ b/code/game/objects/items/weapons/grenades/anti_photon_grenade.dm @@ -3,7 +3,7 @@ name = "photon disruption grenade" icon = 'icons/obj/items/grenades/grenade_light.dmi' det_time = 20 - origin_tech = "{'wormholes':4,'materials':4}" + origin_tech = @'{"wormholes":4,"materials":4}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -13,10 +13,10 @@ /obj/item/grenade/anti_photon/detonate() playsound(src.loc, 'sound/effects/phasein.ogg', 50, 1, 5) set_light(10, -10, "#ffffff") - addtimer(CALLBACK(src, .proc/finish), rand(20 SECONDS, 29 SECONDS)) + addtimer(CALLBACK(src, PROC_REF(finish)), rand(20 SECONDS, 29 SECONDS)) /obj/item/grenade/anti_photon/proc/finish() - set_light(10, 10, "#[num2hex(rand(64,255))][num2hex(rand(64,255))][num2hex(rand(64,255))]") + set_light(10, 10, rgb(rand(64,255), rand(64,255), rand(64,255))) playsound(loc, 'sound/effects/bang.ogg', 50, 1, 5) sleep(1 SECOND) qdel(src) \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 4967bc238f1..0caa509f2bc 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -193,7 +193,7 @@ desc = "An oversized grenade that affects a larger area." icon = 'icons/obj/items/grenades/grenade_large.dmi' allowed_containers = list(/obj/item/chems/glass) - origin_tech = "{'combat':3,'materials':3}" + origin_tech = @'{"combat":3,"materials":3}' material = /decl/material/solid/metal/steel /obj/item/grenade/chem_grenade/metalfoam @@ -206,9 +206,9 @@ . = ..() var/obj/item/chems/glass/beaker/B1 = new(src) var/obj/item/chems/glass/beaker/B2 = new(src) - B1.reagents.add_reagent(/decl/material/solid/metal/aluminium, 30) - B2.reagents.add_reagent(/decl/material/liquid/foaming_agent, 10) - B2.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 10) + B1.add_to_reagents(/decl/material/solid/metal/aluminium, 30) + B2.add_to_reagents(/decl/material/liquid/foaming_agent, 10) + B2.add_to_reagents(/decl/material/liquid/acid/polyacid, 10) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 @@ -224,10 +224,10 @@ . = ..() var/obj/item/chems/glass/beaker/B1 = new(src) var/obj/item/chems/glass/beaker/B2 = new(src) - B1.reagents.add_reagent(/decl/material/solid/metal/aluminium, 15) - B1.reagents.add_reagent(/decl/material/liquid/fuel, 15) - B2.reagents.add_reagent(/decl/material/solid/metal/aluminium, 15) - B2.reagents.add_reagent(/decl/material/liquid/acid, 15) + B1.add_to_reagents(/decl/material/solid/metal/aluminium, 15) + B1.add_to_reagents(/decl/material/liquid/fuel, 15) + B2.add_to_reagents(/decl/material/solid/metal/aluminium, 15) + B2.add_to_reagents(/decl/material/liquid/acid, 15) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 @@ -243,10 +243,10 @@ . = ..() var/obj/item/chems/glass/beaker/B1 = new(src) var/obj/item/chems/glass/beaker/B2 = new(src) - B1.reagents.add_reagent(/decl/material/liquid/weedkiller, 25) - B1.reagents.add_reagent(/decl/material/solid/potassium, 25) - B2.reagents.add_reagent(/decl/material/solid/phosphorus, 25) - B2.reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 25) + B1.add_to_reagents(/decl/material/liquid/weedkiller, 25) + B1.add_to_reagents(/decl/material/solid/potassium, 25) + B2.add_to_reagents(/decl/material/solid/phosphorus, 25) + B2.add_to_reagents(/decl/material/liquid/nutriment/sugar, 25) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 @@ -262,9 +262,9 @@ . = ..() var/obj/item/chems/glass/beaker/B1 = new(src) var/obj/item/chems/glass/beaker/B2 = new(src) - B1.reagents.add_reagent(/decl/material/liquid/surfactant, 40) - B2.reagents.add_reagent(/decl/material/liquid/water, 40) - B2.reagents.add_reagent(/decl/material/liquid/cleaner, 10) + B1.add_to_reagents(/decl/material/liquid/surfactant, 40) + B2.add_to_reagents(/decl/material/liquid/water, 40) + B2.add_to_reagents(/decl/material/liquid/cleaner, 10) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 @@ -280,11 +280,11 @@ . = ..() var/obj/item/chems/glass/beaker/large/B1 = new(src) var/obj/item/chems/glass/beaker/large/B2 = new(src) - B1.reagents.add_reagent(/decl/material/solid/phosphorus, 40) - B1.reagents.add_reagent(/decl/material/solid/potassium, 40) - B1.reagents.add_reagent(/decl/material/liquid/capsaicin/condensed, 40) - B2.reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 40) - B2.reagents.add_reagent(/decl/material/liquid/capsaicin/condensed, 80) + B1.add_to_reagents(/decl/material/solid/phosphorus, 40) + B1.add_to_reagents(/decl/material/solid/potassium, 40) + B1.add_to_reagents(/decl/material/liquid/capsaicin/condensed, 40) + B2.add_to_reagents(/decl/material/liquid/nutriment/sugar, 40) + B2.add_to_reagents(/decl/material/liquid/capsaicin/condensed, 80) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 @@ -301,8 +301,8 @@ . = ..() var/obj/item/chems/glass/beaker/B1 = new(src) var/obj/item/chems/glass/beaker/B2 = new(src) - B1.reagents.add_reagent(/decl/material/liquid/water, 40) - B2.reagents.add_reagent(/decl/material/liquid/water, 40) + B1.add_to_reagents(/decl/material/liquid/water, 40) + B2.add_to_reagents(/decl/material/liquid/water, 40) detonator = new/obj/item/assembly_holder/timer_igniter(src) beakers += B1 beakers += B2 diff --git a/code/game/objects/items/weapons/grenades/decompiler.dm b/code/game/objects/items/weapons/grenades/decompiler.dm index 3d93cbf9467..b457c62d3b6 100644 --- a/code/game/objects/items/weapons/grenades/decompiler.dm +++ b/code/game/objects/items/weapons/grenades/decompiler.dm @@ -2,7 +2,7 @@ desc = "It is set to detonate in 5 seconds. It will create an unstable singularity that will break nearby objects down into purified matter cubes." name = "decompiler grenade" icon = 'icons/obj/items/grenades/delivery.dmi' - origin_tech = "{'materials':3,'magnets':2,'exoticmatter':3}" + origin_tech = @'{"materials":3,"magnets":2,"exoticmatter":3}' matter = list( /decl/material/solid/phoron = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/supermatter = MATTER_AMOUNT_TRACE diff --git a/code/game/objects/items/weapons/grenades/emgrenade.dm b/code/game/objects/items/weapons/grenades/emgrenade.dm index d2e985997d7..afac53d7238 100644 --- a/code/game/objects/items/weapons/grenades/emgrenade.dm +++ b/code/game/objects/items/weapons/grenades/emgrenade.dm @@ -1,7 +1,7 @@ /obj/item/grenade/empgrenade name = "classic EMP grenade" icon = 'icons/obj/items/grenades/emp.dmi' - origin_tech = "{'materials':2,'magnets':3}" + origin_tech = @'{"materials":2,"magnets":3}' var/emp_light_range = 10 var/emp_heavy_range = 4 @@ -15,6 +15,6 @@ name = "low-yield EMP grenade" desc = "A weaker variant of the classic EMP grenade." icon = 'icons/obj/items/grenades/emp_old.dmi' - origin_tech = "{'materials':2,'magnets':3}" + origin_tech = @'{"materials":2,"magnets":3}' emp_heavy_range = 1 emp_light_range = 4 diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index ddcc59ed61f..da480a4fbec 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -2,7 +2,7 @@ name = "flashbang" desc = "A grenade designed to blind, stun and disorient by means of an extremely bright flash and loud explosion." icon = 'icons/obj/items/grenades/flashbang.dmi' - origin_tech = "{'materials':2,'combat':1}" + origin_tech = @'{"materials":2,"combat":1}' var/banglet = 0 /obj/item/grenade/flashbang/detonate() @@ -126,7 +126,7 @@ var/stepdist = rand(1,4)//How far to step var/temploc = src.loc//Saves the current location to know where to step away from walk_away(src,temploc,stepdist)//I must go, my people need me - addtimer(CALLBACK(src, .proc/detonate), rand(15,60)) + addtimer(CALLBACK(src, PROC_REF(detonate)), rand(15,60)) /obj/item/grenade/flashbang/clusterbang/segment/detonate() var/numspawned = rand(4,8) @@ -145,4 +145,4 @@ var/stepdist = rand(1,3) var/temploc = src.loc walk_away(src,temploc,stepdist) - addtimer(CALLBACK(src, .proc/detonate), rand(15,60)) + addtimer(CALLBACK(src, PROC_REF(detonate)), rand(15,60)) diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 49237df9b01..c6c88a77447 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -77,7 +77,7 @@ active = TRUE update_icon() playsound(loc, arm_sound, 75, 0, -3) - addtimer(CALLBACK(src, .proc/detonate), det_time) + addtimer(CALLBACK(src, PROC_REF(detonate)), det_time) /obj/item/grenade/proc/detonate() var/turf/T = get_turf(src) diff --git a/code/game/objects/items/weapons/grenades/prank_grenades.dm b/code/game/objects/items/weapons/grenades/prank_grenades.dm index 8926c8002e2..8e7c1242f39 100644 --- a/code/game/objects/items/weapons/grenades/prank_grenades.dm +++ b/code/game/objects/items/weapons/grenades/prank_grenades.dm @@ -15,6 +15,6 @@ destroy_surroundings = 0 /obj/item/grenade/spawnergrenade/fake_carp - origin_tech = "{'materials':2,'magnets':2,'wormholes':5}" + origin_tech = @'{"materials":2,"magnets":2,"wormholes":5}' spawner_type = /mob/living/simple_animal/hostile/carp/holodeck/fake deliveryamt = 4 diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index 296e02f01c7..543bbe5fac4 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -2,7 +2,7 @@ desc = "It is set to detonate in 5 seconds. It will unleash unleash an unspecified anomaly into the vicinity." name = "delivery grenade" icon = 'icons/obj/items/grenades/delivery.dmi' - origin_tech = "{'materials':3,'magnets':4}" + origin_tech = @'{"materials":3,"magnets":4}' var/spawner_type = null // must be an object path var/deliveryamt = 1 // amount of type to deliver @@ -24,10 +24,10 @@ name = "manhack delivery grenade" spawner_type = /mob/living/simple_animal/hostile/viscerator deliveryamt = 5 - origin_tech = "{'materials':3,'magnets':4,'esoteric':4}" + origin_tech = @'{"materials":3,"magnets":4,"esoteric":4}' /obj/item/grenade/spawnergrenade/spesscarp name = "carp delivery grenade" spawner_type = /mob/living/simple_animal/hostile/carp deliveryamt = 5 - origin_tech = "{'materials':3,'magnets':4,'esoteric':4}" + origin_tech = @'{"materials":3,"magnets":4,"esoteric":4}' diff --git a/code/game/objects/items/weapons/grenades/supermatter.dm b/code/game/objects/items/weapons/grenades/supermatter.dm index f71e0b7e1fd..4f2758b53e3 100644 --- a/code/game/objects/items/weapons/grenades/supermatter.dm +++ b/code/game/objects/items/weapons/grenades/supermatter.dm @@ -1,7 +1,7 @@ /obj/item/grenade/supermatter name = "supermatter grenade" icon = 'icons/obj/items/grenades/banana.dmi' - origin_tech = "{'wormholes':5,'magnets':4,'engineering':5}" + origin_tech = @'{"wormholes":5,"magnets":4,"engineering":5}' arm_sound = 'sound/effects/3.wav' var/implode_at diff --git a/code/game/objects/items/weapons/hair_care.dm b/code/game/objects/items/weapons/hair_care.dm index cb2812db8c9..8eeb0d8e771 100644 --- a/code/game/objects/items/weapons/hair_care.dm +++ b/code/game/objects/items/weapons/hair_care.dm @@ -31,7 +31,8 @@ /obj/item/haircomb/brush/attack_self(mob/user) if(ishuman(user) && !user.incapacitated()) var/mob/living/carbon/human/H = user - var/decl/sprite_accessory/hair/hair_style = GET_DECL(H.h_style) + var/hairstyle = H.get_hairstyle() + var/decl/sprite_accessory/hair/hair_style = GET_DECL(hairstyle) if(hair_style.flags & VERY_SHORT) H.visible_message(SPAN_NOTICE("\The [H] just sort of runs \the [src] over their scalp.")) else diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 2df431e030a..526ea8ddd1c 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -10,7 +10,7 @@ w_class = ITEM_SIZE_SMALL throw_speed = 2 throw_range = 5 - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel max_health = ITEM_HEALTH_NO_DAMAGE //#TODO: Once we can work out something different for handling cuff breakout, change this. Since it relies on cuffs health to tell if you can actually breakout. var/elastic diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 1b0439fa145..a874cd25b11 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -30,7 +30,7 @@ return 0 malfunction = MALFUNCTION_TEMPORARY - addtimer(CALLBACK(src,.proc/restore),time) + addtimer(CALLBACK(src,PROC_REF(restore)),time) return 1 /obj/item/implant/proc/restore() diff --git a/code/game/objects/items/weapons/implants/implants/adrenaline.dm b/code/game/objects/items/weapons/implants/implants/adrenaline.dm index 75c23bc3e0b..7c3f0036fa7 100644 --- a/code/game/objects/items/weapons/implants/implants/adrenaline.dm +++ b/code/game/objects/items/weapons/implants/implants/adrenaline.dm @@ -1,7 +1,7 @@ /obj/item/implant/adrenalin name = "adrenalin implant" desc = "Removes all stuns and knockdowns." - origin_tech = "{'materials':1,'biotech':2,'esoteric':2}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":2}' hidden = 1 var/uses @@ -20,7 +20,7 @@ /obj/item/implant/adrenalin/trigger(emote, mob/source) if (emote == "pale") activate() - + /obj/item/implant/adrenalin/activate()//this implant is unused but I'm changing it for the sake of consistency if (uses < 1 || malfunction || !imp_in) return 0 uses-- diff --git a/code/game/objects/items/weapons/implants/implants/chem.dm b/code/game/objects/items/weapons/implants/implants/chem.dm index 7b693b62f93..0d184f80f7f 100644 --- a/code/game/objects/items/weapons/implants/implants/chem.dm +++ b/code/game/objects/items/weapons/implants/implants/chem.dm @@ -3,7 +3,7 @@ var/global/list/chem_implants = list() /obj/item/implant/chem name = "chemical implant" desc = "Injects things." - origin_tech = "{'materials':1,'biotech':2}" + origin_tech = @'{"materials":1,"biotech":2}' known = 1 /obj/item/implant/chem/get_data() diff --git a/code/game/objects/items/weapons/implants/implants/compressed.dm b/code/game/objects/items/weapons/implants/implants/compressed.dm index 6448b9c4dce..64de2aa17f6 100644 --- a/code/game/objects/items/weapons/implants/implants/compressed.dm +++ b/code/game/objects/items/weapons/implants/implants/compressed.dm @@ -2,7 +2,7 @@ name = "compressed matter implant" desc = "Based on compressed matter technology, can store a single item." icon_state = "implant_evil" - origin_tech = "{'materials':4,'biotech':2,'esoteric':2}" + origin_tech = @'{"materials":4,"biotech":2,"esoteric":2}' hidden = 1 var/activation_emote var/obj/item/scanned diff --git a/code/game/objects/items/weapons/implants/implants/death_alarm.dm b/code/game/objects/items/weapons/implants/implants/death_alarm.dm index ac1c0cffea7..f41e96f1f29 100644 --- a/code/game/objects/items/weapons/implants/implants/death_alarm.dm +++ b/code/game/objects/items/weapons/implants/implants/death_alarm.dm @@ -1,7 +1,7 @@ /obj/item/implant/death_alarm name = "death alarm implant" desc = "An alarm which monitors host vital signs and transmits a radio message upon death." - origin_tech = "{'materials':1,'biotech':2,'programming':3}" + origin_tech = @'{"materials":1,"biotech":2,"programming":3}' known = 1 var/mobname = "John Doe" diff --git a/code/game/objects/items/weapons/implants/implants/explosive.dm b/code/game/objects/items/weapons/implants/implants/explosive.dm index 62109528325..2ccdddc2153 100644 --- a/code/game/objects/items/weapons/implants/implants/explosive.dm +++ b/code/game/objects/items/weapons/implants/implants/explosive.dm @@ -3,7 +3,7 @@ name = "explosive implant" desc = "A military grade micro bio-explosive. Highly dangerous." icon_state = "implant_evil" - origin_tech = "{'materials':1,'biotech':2,'esoteric':3}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' hidden = 1 var/elevel var/phrase diff --git a/code/game/objects/items/weapons/implants/implants/freedom.dm b/code/game/objects/items/weapons/implants/implants/freedom.dm index d034c8276d3..9c98d34f961 100644 --- a/code/game/objects/items/weapons/implants/implants/freedom.dm +++ b/code/game/objects/items/weapons/implants/implants/freedom.dm @@ -3,7 +3,7 @@ /obj/item/implant/freedom name = "freedom implant" desc = "Use this to escape from those evil Red Shirts." - origin_tech = "{'materials':1,'biotech':2,'esoteric':2}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":2}' implant_color = "r" hidden = 1 var/activation_emote diff --git a/code/game/objects/items/weapons/implants/implants/imprinting.dm b/code/game/objects/items/weapons/implants/implants/imprinting.dm index 2ff70ad312c..76e7ac49e30 100644 --- a/code/game/objects/items/weapons/implants/implants/imprinting.dm +++ b/code/game/objects/items/weapons/implants/implants/imprinting.dm @@ -1,7 +1,7 @@ /obj/item/implant/imprinting name = "imprinting implant" desc = "Latest word in training your peons." - origin_tech = "{'materials':1,'biotech':2,'programming':3}" + origin_tech = @'{"materials":1,"biotech":2,"programming":3}' hidden = 1 var/list/instructions = list("Do your job.", "Respect your superiors.", "Wash you hands after using the toilet.") var/brainwashing = 0 @@ -51,7 +51,7 @@ M.StoreMemory(msg, /decl/memory_options/system) if(brainwashing) log_and_message_admins("was implanted with a brainwashing implant holding following laws: [jointext(instructions, ";")].", M) - addtimer(CALLBACK(src,.proc/activate),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) + addtimer(CALLBACK(src,PROC_REF(activate)),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) return TRUE /obj/item/implant/imprinting/proc/get_instructions() @@ -83,7 +83,7 @@ else instruction = "You remember suddenly: \"[instruction]\"" to_chat(imp_in, instruction) - addtimer(CALLBACK(src,.proc/activate),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) + addtimer(CALLBACK(src,PROC_REF(activate)),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) /obj/item/implant/imprinting/removed() if(brainwashing && !malfunction) @@ -103,7 +103,7 @@ . = ..() /obj/item/implant/imprinting/can_implant(mob/M, mob/user, target_zone) - var/mob/living/carbon/human/H = M + var/mob/living/carbon/human/H = M if(istype(H)) var/obj/item/organ/internal/B = GET_INTERNAL_ORGAN(H, BP_BRAIN) if(!B || H.isSynthetic()) diff --git a/code/game/objects/items/weapons/implants/implants/loyalty.dm b/code/game/objects/items/weapons/implants/implants/loyalty.dm index f9112595bed..f7cc12b1abb 100644 --- a/code/game/objects/items/weapons/implants/implants/loyalty.dm +++ b/code/game/objects/items/weapons/implants/implants/loyalty.dm @@ -1,7 +1,7 @@ /obj/item/implant/loyalty name = "loyalty implant" desc = "Makes you loyal or such." - origin_tech = "{'materials':1,'biotech':2,'esoteric':3}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' known = 1 /obj/item/implant/loyalty/get_data() diff --git a/code/game/objects/items/weapons/implants/implants/tracking.dm b/code/game/objects/items/weapons/implants/implants/tracking.dm index 5db14647141..0b317737c4b 100644 --- a/code/game/objects/items/weapons/implants/implants/tracking.dm +++ b/code/game/objects/items/weapons/implants/implants/tracking.dm @@ -3,7 +3,7 @@ var/global/list/tracking_implants = list() /obj/item/implant/tracking name = "tracking implant" desc = "Track with this." - origin_tech = "{'materials':1,'biotech':2,'wormholes':2}" + origin_tech = @'{"materials":1,"biotech":2,"wormholes":2}' known = 1 var/id = 1 diff --git a/code/game/objects/items/weapons/implants/implants/translator.dm b/code/game/objects/items/weapons/implants/implants/translator.dm index fb18b37640f..f8b9f30d836 100644 --- a/code/game/objects/items/weapons/implants/implants/translator.dm +++ b/code/game/objects/items/weapons/implants/implants/translator.dm @@ -3,7 +3,7 @@ name = "babel implant" desc = "A small implant with a microphone on it." icon_state = "implant_evil" - origin_tech = "{'materials':1,'biotech':2,'esoteric':3}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' hidden = 1 var/list/languages = list() var/learning_threshold = 20 //need to hear language spoken this many times to learn it @@ -44,6 +44,6 @@ name = "lingophagic node" desc = "A chunk of what could be discolored crystalized brain matter. It seems to pulse occasionally." icon_state = "implant_melted" - origin_tech = "{'biotech':5}" + origin_tech = @'{"biotech":5}' learning_threshold = 10 max_languages = 3 \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implants/uplink.dm b/code/game/objects/items/weapons/implants/implants/uplink.dm index fa377b563f4..fece5d1fc37 100644 --- a/code/game/objects/items/weapons/implants/implants/uplink.dm +++ b/code/game/objects/items/weapons/implants/implants/uplink.dm @@ -1,7 +1,7 @@ /obj/item/implant/uplink name = "uplink implant" desc = "Summon things." - origin_tech = "{'materials':1,'biotech':2,'esoteric':3}" + origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' hidden = 1 var/activation_emote diff --git a/code/game/objects/items/weapons/lighter.dm b/code/game/objects/items/weapons/lighter.dm index 6c2119c7549..c6530e4b19a 100644 --- a/code/game/objects/items/weapons/lighter.dm +++ b/code/game/objects/items/weapons/lighter.dm @@ -27,7 +27,7 @@ . = ..() /obj/item/flame/lighter/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fuel, max_fuel) + add_to_reagents(/decl/material/liquid/fuel, max_fuel) /obj/item/flame/lighter/light(mob/user) if(submerged()) @@ -95,15 +95,15 @@ else cig.light("[user] holds the [name] out for [M], and lights the [cig.name].") return - ..() + return ..() /obj/item/flame/lighter/Process() if(!submerged() && reagents.has_reagent(/decl/material/liquid/fuel)) if(ismob(loc) && prob(10) && REAGENT_VOLUME(reagents, /decl/material/liquid/fuel) < 1) to_chat(loc, "\The [src]'s flame flickers.") set_light(0) - addtimer(CALLBACK(src, .atom/proc/set_light, 2), 4) - reagents.remove_reagent(/decl/material/liquid/fuel, 0.05) + addtimer(CALLBACK(src, TYPE_PROC_REF(.atom, set_light), 2), 4) + remove_from_reagents(/decl/material/liquid/fuel, 0.05) else extinguish() return @@ -190,6 +190,8 @@ O.reagents.trans_to_obj(src, max_fuel) to_chat(user, "You refuel [src] from \the [O]") playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) + return TRUE + return ..() /obj/item/flame/lighter/zippo/black color = COLOR_DARK_GRAY diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm index 6d0bc79329c..8bf518ae9e1 100644 --- a/code/game/objects/items/weapons/material/folding.dm +++ b/code/game/objects/items/weapons/material/folding.dm @@ -48,7 +48,7 @@ icon_state = "[get_world_inventory_state()]_open" update_held_icon() -/obj/item/knife/folding/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/knife/folding/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, force_skip_offset = FALSE, skip_offset = FALSE) . = open ? ..() : new /image //Subtypes diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 2986056972e..91b0263ebde 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -9,7 +9,7 @@ /obj/item/kitchen/utensil w_class = ITEM_SIZE_TINY thrown_material_force_multiplier = 1 - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' attack_verb = list("attacked", "stabbed", "poked") sharp = 0 edge = 0 diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index 47abfd961c5..d48ebfdb55e 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -7,7 +7,7 @@ material_force_multiplier = 0.3 attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") material = /decl/material/solid/metal/steel - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' obj_flags = OBJ_FLAG_CONDUCTIBLE sharp = TRUE edge = TRUE diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 4f52921c975..d31b6c2d029 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -26,7 +26,7 @@ return audible_message(SPAN_WARNING("\The [src] emits a long, harsh tone!")) playsound(loc, 'sound/weapons/bombwhine.ogg', 100, 0, -3) - addtimer(CALLBACK(src, .proc/harpoon_detonate), 4 SECONDS) //for suspense + addtimer(CALLBACK(src, PROC_REF(harpoon_detonate)), 4 SECONDS) //for suspense /obj/item/harpoon/bomb/proc/harpoon_detonate() audible_message(SPAN_DANGER("\The [src] detonates!")) //an actual sound will be handled by explosion() @@ -57,7 +57,7 @@ w_class = ITEM_SIZE_SMALL sharp = 1 edge = 1 - origin_tech = "{'materials':2,'combat':1}" + origin_tech = @'{"materials":2,"combat":1}' attack_verb = list("chopped", "torn", "cut") material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_NAME @@ -137,7 +137,7 @@ throw_range = 3 w_class = ITEM_SIZE_HUGE slot_flags = SLOT_BACK - origin_tech = "{'materials':2,'combat':2}" + origin_tech = @'{"materials":2,"combat":2}' attack_verb = list("chopped", "sliced", "cut", "reaped") material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME diff --git a/code/game/objects/items/weapons/material/swiss.dm b/code/game/objects/items/weapons/material/swiss.dm index 0567349c265..f3bfebc1de3 100644 --- a/code/game/objects/items/weapons/material/swiss.dm +++ b/code/game/objects/items/weapons/material/swiss.dm @@ -109,7 +109,7 @@ if(active_tool != null) add_overlay(overlay_image(icon, active_tool, flags = RESET_COLOR)) -/obj/item/knife/folding/swiss/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/knife/folding/swiss/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, force_skip_offset = FALSE, skip_offset = FALSE) . = (active_tool == SWISSKNF_LBLADE || active_tool == SWISSKNF_SBLADE) ? ..() : new /image /obj/item/knife/folding/swiss/resolve_attackby(obj/target, mob/user) diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 7c0e9f3ec6e..0869b704a8c 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -44,7 +44,7 @@ if(material.reflectiveness >= MAT_VALUE_SHINY && check_state_in_icon("[icon_state]_shine", icon)) add_overlay(mutable_appearance(icon, "[icon_state]_shine"), adjust_brightness(color, 20 + material.reflectiveness)) -/obj/item/sword/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/sword/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) //Do not color scabbarded blades if(overlay && (material_alteration & MAT_FLAG_ALTERATION_COLOR) && (slot == slot_back_str || slot == slot_belt_str)) overlay.color = null diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 57373a993e8..22bbd884b3a 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -68,7 +68,7 @@ if(wielded) . += wielded_parry_bonus -/obj/item/twohanded/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/twohanded/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && wielded && (slot in list(BP_L_HAND, BP_R_HAND))) overlay.icon_state = "[overlay.icon_state]-wielded" . = ..() @@ -138,7 +138,7 @@ )) -/obj/item/twohanded/spear/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/twohanded/spear/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) if(check_state_in_icon("[overlay.icon_state]-shaft", overlay.icon)) overlay.overlays += get_shaft_overlay("[overlay.icon_state]-shaft") diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 1eee7a8b338..e3e7aef93f3 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -164,7 +164,7 @@ add_overlay(emissive_overlay(icon, "[icon_state]-extended")) z_flags |= ZMM_MANGLE_PLANES -/obj/item/energy_blade/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/energy_blade/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && active && check_state_in_icon("[overlay.icon_state]-extended", overlay.icon)) overlay.overlays += emissive_overlay(overlay.icon, "[overlay.icon_state]-extended") . = ..() diff --git a/code/game/objects/items/weapons/melee/energy_axe.dm b/code/game/objects/items/weapons/melee/energy_axe.dm index f38d13d017c..d52e6c5b699 100644 --- a/code/game/objects/items/weapons/melee/energy_axe.dm +++ b/code/game/objects/items/weapons/melee/energy_axe.dm @@ -13,7 +13,7 @@ atom_flags = ATOM_FLAG_NO_BLOOD obj_flags = OBJ_FLAG_CONDUCTIBLE item_flags = ITEM_FLAG_IS_WEAPON - origin_tech = "{'magnets':3,'combat':4}" + origin_tech = @'{"magnets":3,"combat":4}' active_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") inactive_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") sharp = 1 diff --git a/code/game/objects/items/weapons/melee/energy_machete.dm b/code/game/objects/items/weapons/melee/energy_machete.dm index 3a12bce1b19..182e9412302 100644 --- a/code/game/objects/items/weapons/melee/energy_machete.dm +++ b/code/game/objects/items/weapons/melee/energy_machete.dm @@ -6,5 +6,5 @@ active_throwforce = 17 active_parry_chance = 30 lighting_color = "#6600cc" - origin_tech = "{'magnets':3}" + origin_tech = @'{"magnets":3}' active_attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") diff --git a/code/game/objects/items/weapons/melee/energy_sword.dm b/code/game/objects/items/weapons/melee/energy_sword.dm index 1e22a9e5759..6b972824442 100644 --- a/code/game/objects/items/weapons/melee/energy_sword.dm +++ b/code/game/objects/items/weapons/melee/energy_sword.dm @@ -2,7 +2,7 @@ name = "energy sword" desc = "May the force be mass times acceleration." icon = 'icons/obj/items/weapon/e_sword.dmi' - origin_tech = "{'magnets':3,'esoteric':4}" + origin_tech = @'{"magnets":3,"esoteric":4}' active_parry_chance = 50 var/blade_color @@ -26,7 +26,7 @@ /obj/item/energy_blade/sword/dropped(var/mob/user) ..() - addtimer(CALLBACK(src, .proc/check_loc), 1) // Swapping hands or passing to another person should not deactivate the sword. + addtimer(CALLBACK(src, PROC_REF(check_loc)), 1) // Swapping hands or passing to another person should not deactivate the sword. /obj/item/energy_blade/sword/proc/check_loc() if(!ismob(loc) && active) @@ -43,7 +43,7 @@ I.color = blade_color add_overlay(I) -/obj/item/energy_blade/sword/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/energy_blade/sword/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && active && check_state_in_icon("[overlay.icon_state]-extended-glow", overlay.icon)) overlay.overlays += emissive_overlay(overlay.icon, "[overlay.icon_state]-extended-glow", color = blade_color) return ..() diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 1ae6cbca3da..3161a6dabf9 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -10,7 +10,7 @@ item_flags = ITEM_FLAG_IS_WEAPON throwforce = 7 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'combat':4}" + origin_tech = @'{"combat":4}' attack_verb = list("flicked", "whipped", "lashed") material = /decl/material/solid/organic/leather @@ -24,7 +24,7 @@ force = 16 //max hit with 60 strength and no equipment. Duel Arena no No forfeit - Snapshot throwforce = 7 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'combat':4}" + origin_tech = @'{"combat":4}' attack_verb = list("flicked", "whipped", "lashed") /obj/item/whip/tail @@ -35,7 +35,7 @@ obj_flags = null force = 19 edge = TRUE - origin_tech = "{'combat':6,'materials':5}" + origin_tech = @'{"combat":6,"materials":5}' material = /decl/material/solid/organic/leather/lizard /obj/item/whip/chainofcommand diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index de020e7c791..cd9df371ddc 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -35,18 +35,17 @@ var/moppable if(isturf(A)) var/turf/T = A - var/obj/effect/fluid/F = locate() in T - if(F && F.reagents.total_volume > 0) - if(F.reagents.total_volume > FLUID_SHALLOW) + if(T?.reagents?.total_volume > 0) + if(T.reagents.total_volume > FLUID_SHALLOW) to_chat(user, SPAN_WARNING("There is too much water here to be mopped up.")) else user.visible_message(SPAN_NOTICE("\The [user] begins to mop up \the [T].")) - if(do_after(user, 40, T) && F && !QDELETED(F)) - if(F.reagents.total_volume > FLUID_SHALLOW) + if(do_after(user, 40, T) && !QDELETED(T)) + if(T.reagents?.total_volume > FLUID_SHALLOW) to_chat(user, SPAN_WARNING("There is too much water here to be mopped up.")) else - qdel(F) to_chat(user, SPAN_NOTICE("You have finished mopping!")) + T.reagents?.clear_reagents() return moppable = TRUE @@ -89,7 +88,7 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/organic/plastic = MATTER_AMOUNT_TRACE ) - origin_tech = "{'engineering':4,'materials':4,'powerstorage':3}" + origin_tech = @'{"engineering":4,"materials":4,"powerstorage":3}' var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water. var/refill_rate = 1 //Rate per process() tick mop refills itself @@ -111,7 +110,7 @@ /obj/item/mop/advanced/Process() if(reagents.total_volume < reagents.maximum_volume) - reagents.add_reagent(refill_reagent, refill_rate) + add_to_reagents(refill_reagent, refill_rate) /obj/item/mop/advanced/examine(mob/user) . = ..() diff --git a/code/game/objects/items/weapons/nuclear_cylinder.dm b/code/game/objects/items/weapons/nuclear_cylinder.dm index f6e6f20732f..68ce244b014 100644 --- a/code/game/objects/items/weapons/nuclear_cylinder.dm +++ b/code/game/objects/items/weapons/nuclear_cylinder.dm @@ -10,5 +10,5 @@ throwforce = 15.0 throw_speed = 2 throw_range = 4 - origin_tech = "{'materials':3,'engineering':4}" + origin_tech = @'{"materials":3,"engineering":4}' max_health = ITEM_HEALTH_NO_DAMAGE diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index c727a80bb74..91affbd6502 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -21,12 +21,12 @@ var/global/list/cached_icons = list() var/amt = reagents.maximum_volume if(pigment) amt = round(amt/2) - reagents.add_reagent(pigment, amt) - reagents.add_reagent(/decl/material/liquid/paint, amt) + add_to_reagents(pigment, amt) + add_to_reagents(/decl/material/liquid/paint, amt) /obj/item/chems/glass/paint/on_update_icon() . = ..() - if(reagents.total_volume) + if(reagents?.total_volume) add_overlay(overlay_image('icons/obj/reagentfillings.dmi', "paintbucket", reagents.get_color())) /obj/item/chems/glass/paint/red diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index be794457939..29170908a0e 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -119,7 +119,7 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar return var/mob/_uroller = unroller.resolve() if(_uroller) - events_repository.unregister(/decl/observ/moved, _uroller, src, .proc/user_moved_unrolling) + events_repository.unregister(/decl/observ/moved, _uroller, src, PROC_REF(user_moved_unrolling)) unroller = null start = null slowdown_general = initial(slowdown_general) @@ -135,8 +135,8 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar start = get_turf(src) unroller = weakref(user) slowdown_general = initial(slowdown_general) + 2 //While unrolling you're slightly slower - events_repository.unregister(/decl/observ/moved, user, src, .proc/user_moved_unrolling) - events_repository.register(/decl/observ/moved, user, src, .proc/user_moved_unrolling) + events_repository.unregister(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling)) + events_repository.register(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling)) to_chat(user, SPAN_NOTICE("You start unrolling \the [src].")) //Place the first one immediately place_line(user, get_turf(user), user.dir) @@ -364,7 +364,7 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar layer = ABOVE_HUMAN_LAYER pass_flags = PASS_FLAG_MOB pixel_y += 8 - addtimer(CALLBACK(src, .proc/on_unlift), time, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(on_unlift)), time, TIMER_UNIQUE) playsound(src, 'sound/effects/pageturn2.ogg', 50, TRUE) /**Called by timer when the tape line falls back in place. */ diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 7f7619b4b7a..04dba8b0567 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -8,7 +8,7 @@ item_state = "paper" throw_speed = 4 throw_range = 20 - origin_tech = "{'wormholes':4}" + origin_tech = @'{"wormholes":4}' material = /decl/material/solid/organic/paper /obj/item/teleportation_scroll/attack_self(mob/user) diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 8318f27e9e0..3342015c383 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -61,7 +61,7 @@ throw_speed = 1 throw_range = 4 w_class = ITEM_SIZE_HUGE - origin_tech = "{'materials':2}" + origin_tech = @'{"materials":2}' material = /decl/material/solid/fiberglass matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("shoved", "bashed") @@ -122,7 +122,7 @@ throw_speed = 10 throw_range = 20 w_class = ITEM_SIZE_HUGE - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/organic/wood = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("shoved", "bashed") @@ -151,7 +151,7 @@ throw_speed = 1 throw_range = 4 w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':4,'magnets':3,'esoteric':4}" + origin_tech = @'{"materials":4,"magnets":3,"esoteric":4}' attack_verb = list("shoved", "bashed") material = /decl/material/solid/metal/titanium matter = list( diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index 6ea54072f55..8727b01e6e8 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -43,7 +43,7 @@ update_icon() /obj/item/soap/proc/wet() - reagents.add_reagent(/decl/material/liquid/cleaner, SOAP_CLEANER_ON_WET) + add_to_reagents(/decl/material/liquid/cleaner, SOAP_CLEANER_ON_WET) /obj/item/soap/Crossed(atom/movable/AM) if(!isliving(AM)) @@ -60,7 +60,7 @@ to_chat(user, SPAN_NOTICE("You need to take that [target.name] off before cleaning it.")) else if(istype(target,/obj/effect/decal/cleanable/blood)) to_chat(user, SPAN_NOTICE("You scrub \the [target.name] out.")) - target.clean_blood() //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals. + target.clean() //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals. cleaned = TRUE else if(istype(target,/obj/effect/decal/cleanable)) to_chat(user, SPAN_NOTICE("You scrub \the [target.name] out.")) @@ -80,7 +80,7 @@ wet() else to_chat(user, SPAN_NOTICE("You clean \the [target.name].")) - target.clean_blood() //Clean bloodied atoms. Blood decals themselves need to be handled above. + target.clean() //Clean bloodied atoms. Blood decals themselves need to be handled above. cleaned = TRUE if(cleaned) @@ -98,7 +98,7 @@ user.visible_message(SPAN_NOTICE("\The [user] cleans \the [target].")) if(reagents) reagents.trans_to(target, reagents.total_volume / 8) - target.clean_blood() + target.clean() user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //prevent spam return TRUE return ..() diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 196f3684b0d..e8aade5affe 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -41,7 +41,7 @@ /obj/item/storage/backpack/holding name = "bag of holding" desc = "A backpack that opens into a localized pocket of Blue Space." - origin_tech = "{'wormholes':4}" + origin_tech = @'{"wormholes":4}' icon = 'icons/obj/items/storage/backpack/backpack_holding.dmi' max_w_class = ITEM_SIZE_NORMAL max_storage_space = 56 @@ -385,7 +385,7 @@ I.appearance_flags |= RESET_COLOR add_overlay(I) -/obj/item/storage/backpack/ert/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/storage/backpack/ert/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && slot == slot_back_str && marking_state) var/image/I = image(overlay.icon, "[overlay.icon_state]-[marking_state]") I.color = marking_colour diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 0763c3caf26..82eefa1f2bd 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -76,7 +76,7 @@ /decl/material/solid/metal/uranium = MATTER_AMOUNT_TRACE, /decl/material/solid/phoron = MATTER_AMOUNT_TRACE ) - origin_tech = "{'exoticmatter':5,'materials':6}" + origin_tech = @'{"exoticmatter":5,"materials":6}' /obj/item/storage/bag/trash/advanced/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/storage/backpack/holding) || istype(W, /obj/item/storage/bag/trash/advanced)) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 0ad1cc17e9c..0fdc1abbb36 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -39,11 +39,11 @@ add_overlay(cur_overlays) update_clothing_icon() -/obj/item/storage/belt/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/storage/belt/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, force_skip_offset = FALSE, skip_offset = FALSE) var/image/ret = ..() if(ret && slot == slot_belt_str && length(contents)) for(var/obj/item/I in contents) - var/image/new_overlay = I.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing) + var/image/new_overlay = I.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) if(new_overlay) ret.overlays += new_overlay return ret @@ -167,7 +167,7 @@ /obj/item/chems/pill, /obj/item/chems/syringe, /obj/item/flame/lighter/zippo, - /obj/item/storage/fancy/cigarettes, + /obj/item/storage/box/fancy/cigarettes, /obj/item/storage/pill_bottle, /obj/item/stack/medical, /obj/item/flashlight/pen, diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 6c63ae156a9..e218d7c6d6a 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -29,7 +29,7 @@ use_sound = 'sound/effects/storage/box.ogg' material = /decl/material/solid/organic/cardboard obj_flags = OBJ_FLAG_HOLLOW - var/foldable = /obj/item/stack/material/cardstock // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard + var/foldable = /obj/item/stack/material/cardstock /obj/item/storage/box/large name = "large box" @@ -56,11 +56,10 @@ /obj/item/storage/box/attack_self(mob/user) . = ..() if(. || length(contents) || !ispath(foldable) || !istype(material)) - return + return TRUE var/sheet_amount = FLOOR(LAZYACCESS(matter, material.type) / SHEET_MATERIAL_AMOUNT) if(sheet_amount <= 0 || !user.try_unequip(src)) - return - + return TRUE to_chat(user, SPAN_NOTICE("You fold \the [src] flat.")) if(ispath(foldable, /obj/item/stack)) new foldable(get_turf(src), sheet_amount, material.type) @@ -575,11 +574,11 @@ icon_state = "checkers" max_storage_space = 24 foldable = null - can_hold = list(/obj/item/chems/food/checker) + can_hold = list(/obj/item/checker) /obj/item/storage/box/checkers/WillContain() return list( - /obj/item/chems/food/checker = 12, - /obj/item/chems/food/checker/red = 12 + /obj/item/checker = 12, + /obj/item/checker/red = 12 ) /obj/item/storage/box/checkers/chess @@ -588,12 +587,12 @@ icon_state = "chess_b" /obj/item/storage/box/checkers/chess/WillContain() return list( - /obj/item/chems/food/checker/pawn = 8, - /obj/item/chems/food/checker/knight = 2, - /obj/item/chems/food/checker/bishop = 2, - /obj/item/chems/food/checker/rook = 2, - /obj/item/chems/food/checker/queen = 1, - /obj/item/chems/food/checker/king = 1 + /obj/item/checker/pawn = 8, + /obj/item/checker/knight = 2, + /obj/item/checker/bishop = 2, + /obj/item/checker/rook = 2, + /obj/item/checker/queen = 1, + /obj/item/checker/king = 1 ) /obj/item/storage/box/checkers/chess/red @@ -602,12 +601,12 @@ icon_state = "chess_r" /obj/item/storage/box/checkers/chess/red/WillContain() return list( - /obj/item/chems/food/checker/pawn/red = 8, - /obj/item/chems/food/checker/knight/red = 2, - /obj/item/chems/food/checker/bishop/red = 2, - /obj/item/chems/food/checker/rook/red = 2, - /obj/item/chems/food/checker/queen/red = 1, - /obj/item/chems/food/checker/king/red = 1 + /obj/item/checker/pawn/red = 8, + /obj/item/checker/knight/red = 2, + /obj/item/checker/bishop/red = 2, + /obj/item/checker/rook/red = 2, + /obj/item/checker/queen/red = 1, + /obj/item/checker/king/red = 1 ) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm deleted file mode 100644 index 5431e31cee7..00000000000 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ /dev/null @@ -1,453 +0,0 @@ -/* - * The 'fancy' path is for objects like candle boxes that show how many items are in the storage item on the sprite itself - * .. Sorry for the shitty path name, I couldnt think of a better one. - * - * - * Contains: - * Egg Box - * Crayon Box - * Cigarette Box - */ - -/obj/item/storage/fancy - item_state = "syringe_kit" //placeholder, many of these don't have inhands - opened = 0 //if an item has been removed from this container - obj_flags = OBJ_FLAG_HOLLOW - material = /decl/material/solid/organic/cardboard - var/obj/item/key_type //path of the key item that this "fancy" container is meant to store - -/obj/item/storage/fancy/on_update_icon() - . = ..() - if(!opened) - icon_state = initial(icon_state) - else - var/key_count = count_by_type(contents, key_type) - icon_state = "[initial(icon_state)][key_count]" - -/obj/item/storage/fancy/examine(mob/user, distance) - . = ..() - if(distance > 1) - return - - var/key_name = initial(key_type.name) - if(!contents.len) - to_chat(user, "There are no [key_name]s left in the box.") - else - var/key_count = count_by_type(contents, key_type) - to_chat(user, "There [key_count == 1? "is" : "are"] [key_count] [key_name]\s in the box.") - -/* - * Egg Box - */ - -/obj/item/storage/fancy/egg_box - icon = 'icons/obj/food.dmi' - icon_state = "eggbox" - name = "egg box" - storage_slots = 12 - max_w_class = ITEM_SIZE_SMALL - w_class = ITEM_SIZE_NORMAL - key_type = /obj/item/chems/food/egg - can_hold = list( - /obj/item/chems/food/egg, - /obj/item/chems/food/boiledegg - ) - -/obj/item/storage/fancy/egg_box/WillContain() - return list(/obj/item/chems/food/egg = 12) - -/obj/item/storage/fancy/egg_box/empty/WillContain() - return - -/* - * Cracker Packet - */ - -/obj/item/storage/fancy/crackers - name = "\improper Getmore Crackers" - icon = 'icons/obj/food.dmi' - icon_state = "crackerbag" - storage_slots = 6 - max_w_class = ITEM_SIZE_TINY - w_class = ITEM_SIZE_SMALL - key_type = /obj/item/chems/food/cracker - can_hold = list(/obj/item/chems/food/cracker) - -/obj/item/storage/fancy/crackers/WillContain() - return list(/obj/item/chems/food/cracker = 6) - -/* - * Crayon Box - */ - -/obj/item/storage/fancy/crayons - name = "box of crayons" - desc = "A box of crayons for all your rune drawing needs." - icon = 'icons/obj/items/crayons.dmi' - icon_state = "crayonbox" - w_class = ITEM_SIZE_SMALL - max_w_class = ITEM_SIZE_TINY - max_storage_space = 6 - key_type = /obj/item/pen/crayon - -/obj/item/storage/fancy/crayons/WillContain() - return list( - /obj/item/pen/crayon/red, - /obj/item/pen/crayon/orange, - /obj/item/pen/crayon/yellow, - /obj/item/pen/crayon/green, - /obj/item/pen/crayon/blue, - /obj/item/pen/crayon/purple, - ) - - -/obj/item/storage/fancy/crayons/on_update_icon() - . = ..() - //#FIXME: This can't handle all crayons types and colors. - var/list/cur_overlays - for(var/obj/item/pen/crayon/crayon in contents) - LAZYADD(cur_overlays, overlay_image(icon, crayon.stroke_colour_name, flags = RESET_COLOR)) - if(LAZYLEN(cur_overlays)) - add_overlay(cur_overlays) - -//////////// -//CIG PACK// -//////////// -/obj/item/storage/fancy/cigarettes - name = "pack of Trans-Stellar Duty-frees" - desc = "A ubiquitous brand of cigarettes, found in the facilities of every major spacefaring corporation in the universe. As mild and flavorless as it gets." - icon = 'icons/obj/items/storage/cigpack/cigpack.dmi' - icon_state = "cigpacket" - item_state = "cigpacket" - w_class = ITEM_SIZE_SMALL - max_w_class = ITEM_SIZE_TINY - max_storage_space = 6 - throwforce = 2 - slot_flags = SLOT_LOWER_BODY - key_type = /obj/item/clothing/mask/smokable/cigarette - atom_flags = ATOM_FLAG_NO_CHEM_CHANGE | ATOM_FLAG_OPEN_CONTAINER - -/obj/item/storage/fancy/cigarettes/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette = 6) - -/obj/item/storage/fancy/cigarettes/Initialize(ml, material_key) - . = ..() - initialize_reagents() - -/obj/item/storage/fancy/cigarettes/initialize_reagents(populate) - create_reagents(5 * max_storage_space)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one - . = ..() - -/obj/item/storage/fancy/cigarettes/remove_from_storage(obj/item/W, atom/new_location) - // Don't try to transfer reagents to lighters - if(istype(W, /obj/item/clothing/mask/smokable/cigarette)) - var/obj/item/clothing/mask/smokable/cigarette/C = W - reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) - ..() - -/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!ismob(M)) - return - - if(M == user && user.get_target_zone() == BP_MOUTH && contents.len > 0 && !user.get_equipped_item(slot_wear_mask_str)) - // Find ourselves a cig. Note that we could be full of lighters. - var/obj/item/clothing/mask/smokable/cigarette/cig = null - for(var/obj/item/clothing/mask/smokable/cigarette/C in contents) - cig = C - break - - if(cig == null) - to_chat(user, "Looks like the packet is out of cigarettes.") - return - - // Instead of running equip_to_slot_if_possible() we check here first, - // to avoid dousing cig with reagents if we're not going to equip it - if(!cig.mob_can_equip(user, slot_wear_mask_str)) - return - - // We call remove_from_storage first to manage the reagent transfer and - // UI updates. - remove_from_storage(cig, null) - user.equip_to_slot(cig, slot_wear_mask_str) - - reagents.maximum_volume = 5 * contents.len - to_chat(user, "You take a cigarette out of the pack.") - update_icon() - else - ..() - -/obj/item/storage/fancy/cigarettes/dromedaryco - name = "pack of Dromedary Co. cigarettes" - desc = "A packet of six imported Dromedary Company cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"." - icon = 'icons/obj/items/storage/cigpack/dromedary.dmi' - icon_state = "Dpacket" - -/obj/item/storage/fancy/cigarettes/dromedaryco/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/dromedaryco = 6) - -/obj/item/storage/fancy/cigarettes/killthroat - name = "pack of Acme Co. cigarettes" - desc = "A packet of six Acme Company cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors." - icon = 'icons/obj/items/storage/cigpack/acme.dmi' - icon_state = "Bpacket" - -/obj/item/storage/fancy/cigarettes/killthroat/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/killthroat = 6) - -/obj/item/storage/fancy/cigarettes/killthroat/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fuel, (max_storage_space * 4)) - -// New exciting ways to kill your lungs! - Earthcrusher // - -/obj/item/storage/fancy/cigarettes/luckystars - name = "pack of Lucky Stars" - desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head." - icon = 'icons/obj/items/storage/cigpack/lucky_stars.dmi' - icon_state = "LSpacket" - item_state = "Dpacket" //I actually don't mind cig packs not showing up in the hand. whotf doesn't just keep them in their pockets/coats // - -/obj/item/storage/fancy/cigarettes/luckystars/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/luckystars = 6) - -/obj/item/storage/fancy/cigarettes/jerichos - name = "pack of Jerichos" - desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." - icon = 'icons/obj/items/storage/cigpack/jerichos.dmi' - icon_state = "Jpacket" - item_state = "Dpacket" - -/obj/item/storage/fancy/cigarettes/jerichos/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/jerichos = 6) - -/obj/item/storage/fancy/cigarettes/menthols - name = "pack of Temperamento Menthols" - desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!" - icon = 'icons/obj/items/storage/cigpack/menthol.dmi' - icon_state = "TMpacket" - item_state = "Dpacket" - key_type = /obj/item/clothing/mask/smokable/cigarette/menthol - -/obj/item/storage/fancy/cigarettes/menthols/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/menthol = 6) - -/obj/item/storage/fancy/cigarettes/carcinomas - name = "pack of Carcinoma Angels" - desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too. Yes, actual cats." - icon = 'icons/obj/items/storage/cigpack/carcinoma.dmi' - icon_state = "CApacket" - item_state = "Dpacket" - -/obj/item/storage/fancy/cigarettes/carcinomas/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/carcinomas = 6) - -/obj/item/storage/fancy/cigarettes/professionals - name = "pack of Professional 120s" - desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They taste disgusting, too." - icon_state = "P100packet" - icon = 'icons/obj/items/storage/cigpack/professionals.dmi' - item_state = "Dpacket" - -/obj/item/storage/fancy/cigarettes/professionals/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/professionals = 6) - -//cigarellos -/obj/item/storage/fancy/cigarettes/cigarello - name = "pack of Trident Original cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years." - icon = 'icons/obj/items/storage/cigpack/cigarillo.dmi' - icon_state = "CRpacket" - item_state = "Dpacket" - max_storage_space = 5 - key_type = /obj/item/clothing/mask/smokable/cigarette/trident - -/obj/item/storage/fancy/cigarettes/cigarello/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/trident = 5) - -/obj/item/storage/fancy/cigarettes/cigarello/variety - name = "pack of Trident Fruit cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. This is a fruit variety pack." - icon = 'icons/obj/items/storage/cigpack/cigarillo_fruity.dmi' - icon_state = "CRFpacket" - -/obj/item/storage/fancy/cigarettes/cigarello/variety/WillContain() - return list( - /obj/item/clothing/mask/smokable/cigarette/trident/watermelon, - /obj/item/clothing/mask/smokable/cigarette/trident/orange, - /obj/item/clothing/mask/smokable/cigarette/trident/grape, - /obj/item/clothing/mask/smokable/cigarette/trident/cherry, - /obj/item/clothing/mask/smokable/cigarette/trident/berry - ) - -/obj/item/storage/fancy/cigarettes/cigarello/mint - name = "pack of Trident Menthol cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. These are the menthol variety." - icon = 'icons/obj/items/storage/cigpack/cigarillo_menthol.dmi' - icon_state = "CRMpacket" - -/obj/item/storage/fancy/cigarettes/cigarello/mint/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/trident/mint = 5) -/* - * Cigar -*/ -/obj/item/storage/fancy/cigar - name = "cigar case" - desc = "A case for holding your cigars when you are not smoking them." - icon_state = "cigarcase" - item_state = "cigpacket" - icon = 'icons/obj/items/storage/cigarcase.dmi' - w_class = ITEM_SIZE_SMALL - max_w_class = ITEM_SIZE_TINY - throwforce = 2 - slot_flags = SLOT_LOWER_BODY - storage_slots = 7 - material = /decl/material/solid/organic/wood/mahogany - key_type = /obj/item/clothing/mask/smokable/cigarette/cigar - atom_flags = ATOM_FLAG_NO_CHEM_CHANGE - -/obj/item/storage/fancy/cigar/Initialize(ml, material_key) - . = ..() - initialize_reagents() - -/obj/item/storage/fancy/cigar/initialize_reagents(populate) - create_reagents(10 * storage_slots) - . = ..() - -/obj/item/storage/fancy/cigar/WillContain() - return list(/obj/item/clothing/mask/smokable/cigarette/cigar = 6) - -/obj/item/storage/fancy/cigar/remove_from_storage(obj/item/W, atom/new_location) - var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W - if(!istype(C)) - return - reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) - return ..() - -/* - * Vial Box - */ -/obj/item/storage/fancy/vials - icon = 'icons/obj/vialbox.dmi' - icon_state = "vialbox0" - name = "vial storage box" - w_class = ITEM_SIZE_NORMAL - max_w_class = ITEM_SIZE_TINY - storage_slots = 12 - material = /decl/material/solid/organic/plastic - key_type = /obj/item/chems/glass/beaker/vial - -/obj/item/storage/fancy/vials/WillContain() - return list(/obj/item/chems/glass/beaker/vial = 12) - -/obj/item/storage/fancy/vials/on_update_icon() - . = ..() - var/key_count = count_by_type(contents, key_type) - icon_state = "[initial(icon_state)][FLOOR(key_count/2)]" - -/* - * Not actually a "fancy" storage... - */ -/obj/item/storage/lockbox/vials - name = "secure vial storage box" - desc = "A locked box for keeping things away from children." - icon = 'icons/obj/vialbox.dmi' - icon_state = "vialbox0" - item_state = "syringe_kit" - w_class = ITEM_SIZE_NORMAL - max_w_class = ITEM_SIZE_TINY - max_storage_space = null - storage_slots = 12 - req_access = list(access_virology) - material = /decl/material/solid/metal/stainlesssteel - -/obj/item/storage/lockbox/vials/Initialize() - . = ..() - update_icon() - -/obj/item/storage/lockbox/vials/on_update_icon() - . = ..() - var/total_contents = count_by_type(contents, /obj/item/chems/glass/beaker/vial) - icon_state = "vialbox[FLOOR(total_contents/2)]" - if (!broken) - add_overlay("led[locked]") - if(locked) - add_overlay("cover") - else - add_overlay("ledb") - -/obj/item/storage/lockbox/vials/attackby(obj/item/W, mob/user) - . = ..() - update_icon() - -//////////////////////////////////////////////////////////////////////////////// -// Syndie Cigs -//////////////////////////////////////////////////////////////////////////////// - -// Flash Powder Pack -/obj/item/storage/fancy/cigarettes/flash_powder - name = "pack of flash powder laced Trans-Stellar Duty-frees" - -/obj/item/storage/fancy/cigarettes/flash_powder/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/storage/fancy/cigarettes/C = /obj/item/storage/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'F' has been scribbled on it." - -/obj/item/storage/fancy/cigarettes/flash_powder/populate_reagents() - reagents.add_reagent(/decl/material/solid/metal/aluminium, max_storage_space) - reagents.add_reagent(/decl/material/solid/potassium, max_storage_space) - reagents.add_reagent(/decl/material/solid/sulfur, max_storage_space) - -//Chemsmoke Pack -/obj/item/storage/fancy/cigarettes/chemsmoke - name = "pack of smoke powder laced Trans-Stellar Duty-frees" - -/obj/item/storage/fancy/cigarettes/chemsmoke/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/storage/fancy/cigarettes/C = /obj/item/storage/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'S' has been scribbled on it." - -/obj/item/storage/fancy/cigarettes/chemsmoke/populate_reagents() - reagents.add_reagent(/decl/material/solid/potassium, max_storage_space) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, max_storage_space) - reagents.add_reagent(/decl/material/solid/phosphorus, max_storage_space) - -//Mindbreak Pack (now called /decl/chemical_reaction/hallucinogenics) -/obj/item/storage/fancy/cigarettes/mindbreak - name = "pack of mindbreak toxin laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? - -/obj/item/storage/fancy/cigarettes/mindbreak/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/storage/fancy/cigarettes/C = /obj/item/storage/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'MB' has been scribbled on it." //#TODO: maybe fix the lore for that? - -/obj/item/storage/fancy/cigarettes/mindbreak/populate_reagents() - reagents.add_reagent(/decl/material/solid/silicon, max_storage_space) - reagents.add_reagent(/decl/material/liquid/fuel/hydrazine, max_storage_space) - reagents.add_reagent(/decl/material/liquid/antitoxins, max_storage_space) - -//Tricord pack (now called /decl/material/liquid/regenerator) -/obj/item/storage/fancy/cigarettes/tricord - name = "pack of tricordazine laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? - -/obj/item/storage/fancy/cigarettes/tricord/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/storage/fancy/cigarettes/C = /obj/item/storage/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'T' has been scribbled on it." //#TODO: maybe fix the lore for that? - -/obj/item/storage/fancy/cigarettes/tricord/populate_reagents() - reagents.add_reagent(/decl/material/liquid/regenerator, (4 * max_storage_space)) diff --git a/code/game/objects/items/weapons/storage/fancy/_fancy.dm b/code/game/objects/items/weapons/storage/fancy/_fancy.dm new file mode 100644 index 00000000000..5a9188f22d5 --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/_fancy.dm @@ -0,0 +1,48 @@ +/* + * The 'fancy' path is for objects like candle boxes that show how many items are in the storage item on the sprite itself + */ + +/obj/item/storage/box/fancy + abstract_type = /obj/item/storage/box/fancy + /// A string modifier used to generate overlays for contents. + var/use_single_icon_overlay_state + /// The root type of the key item that this "fancy" container is meant to store. + var/obj/item/key_type + +/obj/item/storage/box/fancy/proc/adjust_contents_overlay(var/overlay_index, var/image/overlay) + return overlay + +/obj/item/storage/box/fancy/proc/update_icon_state() + icon_state = initial(icon_state) + if(key_type && opened) + icon_state = "[icon_state][count_by_type(contents, key_type)]" + +/obj/item/storage/box/fancy/proc/add_contents_overlays() + . = FALSE + if(!use_single_icon_overlay_state) + return + var/offset_index = 0 + for(var/obj/item/thing in contents) + var/thing_state = "[thing.icon_state]_[use_single_icon_overlay_state]" + if(!check_state_in_icon(thing_state, thing.icon)) + continue + . = TRUE + var/image/thing_overlay = adjust_contents_overlay(offset_index, image(thing.icon, thing_state)) + if(thing.color) + thing_overlay.color = thing.color + thing_overlay.appearance_flags |= RESET_COLOR + add_overlay(thing_overlay) + offset_index++ + +/obj/item/storage/box/fancy/on_update_icon() + . = ..() + update_icon_state() + if(add_contents_overlays()) + compile_overlays() + +/obj/item/storage/box/fancy/examine(mob/user, distance) + . = ..() + if(distance > 1 || !key_type) + return + var/key_count = count_by_type(contents, key_type) + to_chat(user, "There [key_count == 1? "is" : "are"] [key_count] [initial(key_type.name)]\s in the box.") diff --git a/code/game/objects/items/weapons/storage/fancy/cigar.dm b/code/game/objects/items/weapons/storage/fancy/cigar.dm new file mode 100644 index 00000000000..2dde3c78458 --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/cigar.dm @@ -0,0 +1,35 @@ +/* + * Cigar +*/ +/obj/item/storage/box/fancy/cigar + name = "cigar case" + desc = "A case for holding your cigars when you are not smoking them." + icon_state = "cigarcase" + item_state = "cigpacket" + icon = 'icons/obj/items/storage/cigarcase.dmi' + w_class = ITEM_SIZE_SMALL + max_w_class = ITEM_SIZE_TINY + throwforce = 2 + slot_flags = SLOT_LOWER_BODY + storage_slots = 7 + material = /decl/material/solid/organic/wood/mahogany + key_type = /obj/item/clothing/mask/smokable/cigarette/cigar + atom_flags = ATOM_FLAG_NO_CHEM_CHANGE + +/obj/item/storage/box/fancy/cigar/Initialize(ml, material_key) + . = ..() + initialize_reagents() + +/obj/item/storage/box/fancy/cigar/initialize_reagents(populate) + create_reagents(10 * storage_slots) + . = ..() + +/obj/item/storage/box/fancy/cigar/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/cigar = 6) + +/obj/item/storage/box/fancy/cigar/remove_from_storage(obj/item/W, atom/new_location) + var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W + if(!istype(C)) + return + reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) + return ..() diff --git a/code/game/objects/items/weapons/storage/fancy/cigarettes.dm b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm new file mode 100644 index 00000000000..5bd2ad606ff --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm @@ -0,0 +1,250 @@ +//////////// +//CIG PACK// +//////////// +/obj/item/storage/box/fancy/cigarettes + name = "pack of Trans-Stellar Duty-frees" + desc = "A ubiquitous brand of cigarettes, found in the facilities of every major spacefaring corporation in the universe. As mild and flavorless as it gets." + icon = 'icons/obj/items/storage/cigpack/cigpack.dmi' + icon_state = "cigpacket" + item_state = "cigpacket" + w_class = ITEM_SIZE_SMALL + max_w_class = ITEM_SIZE_TINY + max_storage_space = 6 + throwforce = 2 + slot_flags = SLOT_LOWER_BODY + key_type = /obj/item/clothing/mask/smokable/cigarette + atom_flags = ATOM_FLAG_NO_CHEM_CHANGE | ATOM_FLAG_OPEN_CONTAINER + +/obj/item/storage/box/fancy/cigarettes/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette = 6) + +/obj/item/storage/box/fancy/cigarettes/Initialize(ml, material_key) + . = ..() + initialize_reagents() + +/obj/item/storage/box/fancy/cigarettes/initialize_reagents(populate) + create_reagents(5 * max_storage_space)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one + . = ..() + +/obj/item/storage/box/fancy/cigarettes/remove_from_storage(obj/item/W, atom/new_location) + // Don't try to transfer reagents to lighters + if(istype(W, /obj/item/clothing/mask/smokable/cigarette)) + var/obj/item/clothing/mask/smokable/cigarette/C = W + reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) + ..() + +/obj/item/storage/box/fancy/cigarettes/attack(mob/living/carbon/M, mob/living/carbon/user) + if(!ismob(M)) + return + + if(M == user && user.get_target_zone() == BP_MOUTH && contents.len > 0 && !user.get_equipped_item(slot_wear_mask_str)) + // Find ourselves a cig. Note that we could be full of lighters. + var/obj/item/clothing/mask/smokable/cigarette/cig = null + for(var/obj/item/clothing/mask/smokable/cigarette/C in contents) + cig = C + break + + if(cig == null) + to_chat(user, "Looks like the packet is out of cigarettes.") + return + + // Instead of running equip_to_slot_if_possible() we check here first, + // to avoid dousing cig with reagents if we're not going to equip it + if(!cig.mob_can_equip(user, slot_wear_mask_str)) + return + + // We call remove_from_storage first to manage the reagent transfer and + // UI updates. + remove_from_storage(cig, null) + user.equip_to_slot(cig, slot_wear_mask_str) + + reagents.maximum_volume = 5 * contents.len + to_chat(user, "You take a cigarette out of the pack.") + update_icon() + else + ..() + +/obj/item/storage/box/fancy/cigarettes/dromedaryco + name = "pack of Dromedary Co. cigarettes" + desc = "A packet of six imported Dromedary Company cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"." + icon = 'icons/obj/items/storage/cigpack/dromedary.dmi' + icon_state = "Dpacket" + +/obj/item/storage/box/fancy/cigarettes/dromedaryco/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/dromedaryco = 6) + +/obj/item/storage/box/fancy/cigarettes/killthroat + name = "pack of Acme Co. cigarettes" + desc = "A packet of six Acme Company cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors." + icon = 'icons/obj/items/storage/cigpack/acme.dmi' + icon_state = "Bpacket" + +/obj/item/storage/box/fancy/cigarettes/killthroat/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/killthroat = 6) + +/obj/item/storage/box/fancy/cigarettes/killthroat/populate_reagents() + add_to_reagents(/decl/material/liquid/fuel, (max_storage_space * 4)) + +// New exciting ways to kill your lungs! - Earthcrusher // + +/obj/item/storage/box/fancy/cigarettes/luckystars + name = "pack of Lucky Stars" + desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head." + icon = 'icons/obj/items/storage/cigpack/lucky_stars.dmi' + icon_state = "LSpacket" + item_state = "Dpacket" //I actually don't mind cig packs not showing up in the hand. whotf doesn't just keep them in their pockets/coats // + +/obj/item/storage/box/fancy/cigarettes/luckystars/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/luckystars = 6) + +/obj/item/storage/box/fancy/cigarettes/jerichos + name = "pack of Jerichos" + desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." + icon = 'icons/obj/items/storage/cigpack/jerichos.dmi' + icon_state = "Jpacket" + item_state = "Dpacket" + +/obj/item/storage/box/fancy/cigarettes/jerichos/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/jerichos = 6) + +/obj/item/storage/box/fancy/cigarettes/menthols + name = "pack of Temperamento Menthols" + desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!" + icon = 'icons/obj/items/storage/cigpack/menthol.dmi' + icon_state = "TMpacket" + item_state = "Dpacket" + key_type = /obj/item/clothing/mask/smokable/cigarette/menthol + +/obj/item/storage/box/fancy/cigarettes/menthols/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/menthol = 6) + +/obj/item/storage/box/fancy/cigarettes/carcinomas + name = "pack of Carcinoma Angels" + desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too. Yes, actual cats." + icon = 'icons/obj/items/storage/cigpack/carcinoma.dmi' + icon_state = "CApacket" + item_state = "Dpacket" + +/obj/item/storage/box/fancy/cigarettes/carcinomas/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/carcinomas = 6) + +/obj/item/storage/box/fancy/cigarettes/professionals + name = "pack of Professional 120s" + desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They taste disgusting, too." + icon_state = "P100packet" + icon = 'icons/obj/items/storage/cigpack/professionals.dmi' + item_state = "Dpacket" + +/obj/item/storage/box/fancy/cigarettes/professionals/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/professionals = 6) + +//cigarellos +/obj/item/storage/box/fancy/cigarettes/cigarello + name = "pack of Trident Original cigars" + desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years." + icon = 'icons/obj/items/storage/cigpack/cigarillo.dmi' + icon_state = "CRpacket" + item_state = "Dpacket" + max_storage_space = 5 + key_type = /obj/item/clothing/mask/smokable/cigarette/trident + +/obj/item/storage/box/fancy/cigarettes/cigarello/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/trident = 5) + +/obj/item/storage/box/fancy/cigarettes/cigarello/variety + name = "pack of Trident Fruit cigars" + desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. This is a fruit variety pack." + icon = 'icons/obj/items/storage/cigpack/cigarillo_fruity.dmi' + icon_state = "CRFpacket" + +/obj/item/storage/box/fancy/cigarettes/cigarello/variety/WillContain() + return list( + /obj/item/clothing/mask/smokable/cigarette/trident/watermelon, + /obj/item/clothing/mask/smokable/cigarette/trident/orange, + /obj/item/clothing/mask/smokable/cigarette/trident/grape, + /obj/item/clothing/mask/smokable/cigarette/trident/cherry, + /obj/item/clothing/mask/smokable/cigarette/trident/berry + ) + +/obj/item/storage/box/fancy/cigarettes/cigarello/mint + name = "pack of Trident Menthol cigars" + desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. These are the menthol variety." + icon = 'icons/obj/items/storage/cigpack/cigarillo_menthol.dmi' + icon_state = "CRMpacket" + +/obj/item/storage/box/fancy/cigarettes/cigarello/mint/WillContain() + return list(/obj/item/clothing/mask/smokable/cigarette/trident/mint = 5) + +//////////////////////////////////////////////////////////////////////////////// +// Syndie Cigs +//////////////////////////////////////////////////////////////////////////////// + +// Flash Powder Pack +/obj/item/storage/box/fancy/cigarettes/flash_powder + name = "pack of flash powder laced Trans-Stellar Duty-frees" + +/obj/item/storage/box/fancy/cigarettes/flash_powder/Initialize(ml, material_key) + . = ..() + //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names + var/obj/item/storage/box/fancy/cigarettes/C = /obj/item/storage/box/fancy/cigarettes + if(name == initial(name)) + SetName(initial(C.name)) + if(desc == initial(desc)) + desc = "[initial(desc)] 'F' has been scribbled on it." + +/obj/item/storage/box/fancy/cigarettes/flash_powder/populate_reagents() + add_to_reagents(/decl/material/solid/metal/aluminium, max_storage_space) + add_to_reagents(/decl/material/solid/potassium, max_storage_space) + add_to_reagents(/decl/material/solid/sulfur, max_storage_space) + +//Chemsmoke Pack +/obj/item/storage/box/fancy/cigarettes/chemsmoke + name = "pack of smoke powder laced Trans-Stellar Duty-frees" + +/obj/item/storage/box/fancy/cigarettes/chemsmoke/Initialize(ml, material_key) + . = ..() + //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names + var/obj/item/storage/box/fancy/cigarettes/C = /obj/item/storage/box/fancy/cigarettes + if(name == initial(name)) + SetName(initial(C.name)) + if(desc == initial(desc)) + desc = "[initial(desc)] 'S' has been scribbled on it." + +/obj/item/storage/box/fancy/cigarettes/chemsmoke/populate_reagents() + add_to_reagents(/decl/material/solid/potassium, max_storage_space) + add_to_reagents(/decl/material/liquid/nutriment/sugar, max_storage_space) + add_to_reagents(/decl/material/solid/phosphorus, max_storage_space) + +//Mindbreak Pack (now called /decl/chemical_reaction/hallucinogenics) +/obj/item/storage/box/fancy/cigarettes/mindbreak + name = "pack of mindbreak toxin laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? + +/obj/item/storage/box/fancy/cigarettes/mindbreak/Initialize(ml, material_key) + . = ..() + //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names + var/obj/item/storage/box/fancy/cigarettes/C = /obj/item/storage/box/fancy/cigarettes + if(name == initial(name)) + SetName(initial(C.name)) + if(desc == initial(desc)) + desc = "[initial(desc)] 'MB' has been scribbled on it." //#TODO: maybe fix the lore for that? + +/obj/item/storage/box/fancy/cigarettes/mindbreak/populate_reagents() + add_to_reagents(/decl/material/solid/silicon, max_storage_space) + add_to_reagents(/decl/material/liquid/fuel/hydrazine, max_storage_space) + add_to_reagents(/decl/material/liquid/antitoxins, max_storage_space) + +//Tricord pack (now called /decl/material/liquid/regenerator) +/obj/item/storage/box/fancy/cigarettes/tricord + name = "pack of tricordazine laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? + +/obj/item/storage/box/fancy/cigarettes/tricord/Initialize(ml, material_key) + . = ..() + //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names + var/obj/item/storage/box/fancy/cigarettes/C = /obj/item/storage/box/fancy/cigarettes + if(name == initial(name)) + SetName(initial(C.name)) + if(desc == initial(desc)) + desc = "[initial(desc)] 'T' has been scribbled on it." //#TODO: maybe fix the lore for that? + +/obj/item/storage/box/fancy/cigarettes/tricord/populate_reagents() + add_to_reagents(/decl/material/liquid/regenerator, (4 * max_storage_space)) diff --git a/code/game/objects/items/weapons/storage/fancy/crackers.dm b/code/game/objects/items/weapons/storage/fancy/crackers.dm new file mode 100644 index 00000000000..918adebb9eb --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/crackers.dm @@ -0,0 +1,31 @@ +/* + * Cracker Packet + */ +/obj/item/storage/box/fancy/crackers + name = "bag of crackers" + icon = 'icons/obj/food/containers/crackerbag.dmi' + icon_state = ICON_STATE_WORLD + storage_slots = 6 + max_w_class = ITEM_SIZE_TINY + max_storage_space = ITEM_SIZE_TINY * 6 + w_class = ITEM_SIZE_SMALL + key_type = /obj/item/chems/food/cracker + can_hold = list(/obj/item/chems/food/cracker) + use_single_icon_overlay_state = "crackerbag" + +/obj/item/storage/box/fancy/crackers/adjust_contents_overlay(var/overlay_index, var/image/overlay) + overlay?.pixel_x = -(overlay_index) + return overlay + +/obj/item/storage/box/fancy/crackers/WillContain() + return list(/obj/item/chems/food/cracker = 6) + +/obj/item/storage/box/fancy/crackers/update_icon_state() + icon_state = get_world_inventory_state() + +/obj/item/storage/box/fancy/crackers/on_update_icon() + . = ..() + if(opened) + add_overlay("[icon_state]_open") + else + add_overlay("[icon_state]_closed") diff --git a/code/game/objects/items/weapons/storage/fancy/crayons.dm b/code/game/objects/items/weapons/storage/fancy/crayons.dm new file mode 100644 index 00000000000..4bd8553d9eb --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/crayons.dm @@ -0,0 +1,32 @@ +/* + * Crayon Box + */ + +/obj/item/storage/box/fancy/crayons + name = "box of crayons" + desc = "A box of crayons for all your rune drawing needs." + icon = 'icons/obj/items/crayon_box.dmi' + icon_state = ICON_STATE_WORLD + w_class = ITEM_SIZE_SMALL + max_w_class = ITEM_SIZE_TINY + max_storage_space = 6 + key_type = /obj/item/pen/crayon + use_single_icon_overlay_state = "crayonbox" + +/obj/item/storage/box/fancy/crayons/update_icon_state() + icon_state = get_world_inventory_state() + +/obj/item/storage/box/fancy/crayons/adjust_contents_overlay(var/overlay_index, var/image/overlay) + if(overlay) + overlay.pixel_x = overlay_index * 2 + return overlay + +/obj/item/storage/box/fancy/crayons/WillContain() + return list( + /obj/item/pen/crayon/red, + /obj/item/pen/crayon/orange, + /obj/item/pen/crayon/yellow, + /obj/item/pen/crayon/green, + /obj/item/pen/crayon/blue, + /obj/item/pen/crayon/purple, + ) diff --git a/code/game/objects/items/weapons/storage/fancy/donutbox.dm b/code/game/objects/items/weapons/storage/fancy/donutbox.dm new file mode 100644 index 00000000000..78c957808f8 --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/donutbox.dm @@ -0,0 +1,27 @@ +/* + * Donut box! + */ + +/obj/item/storage/box/fancy/donut + name = "donut box" + icon = 'icons/obj/food/containers/donutbox.dmi' + icon_state = ICON_STATE_WORLD + item_state = null + max_storage_space = ITEM_SIZE_SMALL * 6 + can_hold = list(/obj/item/chems/food/donut) + use_single_icon_overlay_state = "donutbox" + +/obj/item/storage/box/fancy/donut/update_icon_state() + icon_state = get_world_inventory_state() + +/obj/item/storage/box/fancy/donut/adjust_contents_overlay(var/overlay_index, var/image/overlay) + if(overlay) + overlay.pixel_x = overlay_index * 3 + return overlay + +/obj/item/storage/box/fancy/donut/WillContain() + return list(/obj/item/chems/food/donut = 6) + +// Subtypes below. +/obj/item/storage/box/fancy/donut/empty/WillContain() + return null diff --git a/code/game/objects/items/weapons/storage/fancy/eggbox.dm b/code/game/objects/items/weapons/storage/fancy/eggbox.dm new file mode 100644 index 00000000000..252c8b0e8f2 --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/eggbox.dm @@ -0,0 +1,56 @@ +/* + * Egg Box + */ + +/obj/item/storage/box/fancy/egg_box + name = "egg box" + icon = 'icons/obj/food/containers/eggbox.dmi' + icon_state = ICON_STATE_WORLD + item_state = null + storage_slots = 12 + max_w_class = ITEM_SIZE_SMALL + max_storage_space = ITEM_SIZE_SMALL * 12 + w_class = ITEM_SIZE_NORMAL + key_type = /obj/item/chems/food/egg + use_single_icon_overlay_state = "eggbox" + can_hold = list( + /obj/item/chems/food/egg, + /obj/item/chems/food/boiledegg + ) + +/obj/item/storage/box/fancy/egg_box/update_icon_state() + icon_state = get_world_inventory_state() + if(opened) + icon_state = "[icon_state]_open" + +/obj/item/storage/box/fancy/egg_box/add_contents_overlays() + return opened && ..() + +/obj/item/storage/box/fancy/egg_box/adjust_contents_overlay(var/overlay_index, var/image/overlay) + if(overlay) + overlay.pixel_x = (overlay_index % 6) * 4 + if(overlay_index >= 6) + overlay.pixel_y = 3 + return overlay + +/obj/item/storage/box/fancy/egg_box/WillContain() + return list(/obj/item/chems/food/egg = 12) + +// Subtypes below. +/obj/item/storage/box/fancy/egg_box/assorted/WillContain() + return list( + /obj/item/chems/food/egg = 1, + /obj/item/chems/food/egg/blue = 1, + /obj/item/chems/food/egg/green = 1, + /obj/item/chems/food/egg/mime = 1, + /obj/item/chems/food/egg/orange = 1, + /obj/item/chems/food/egg/purple = 1, + /obj/item/chems/food/egg/rainbow = 1, + /obj/item/chems/food/egg/red = 1, + /obj/item/chems/food/egg/yellow = 1, + /obj/item/chems/food/boiledegg = 1, + /obj/item/chems/food/egg/lizard = 1 + ) + +/obj/item/storage/box/fancy/egg_box/empty/WillContain() + return diff --git a/code/game/objects/items/weapons/storage/fancy/vials.dm b/code/game/objects/items/weapons/storage/fancy/vials.dm new file mode 100644 index 00000000000..3326ed5302d --- /dev/null +++ b/code/game/objects/items/weapons/storage/fancy/vials.dm @@ -0,0 +1,55 @@ +/* + * Vial Box + */ +/obj/item/storage/box/fancy/vials + icon = 'icons/obj/vialbox.dmi' + icon_state = "vialbox0" + name = "vial storage box" + w_class = ITEM_SIZE_NORMAL + max_w_class = ITEM_SIZE_TINY + storage_slots = 12 + material = /decl/material/solid/organic/plastic + key_type = /obj/item/chems/glass/beaker/vial + +/obj/item/storage/box/fancy/vials/WillContain() + return list(/obj/item/chems/glass/beaker/vial = 12) + +/obj/item/storage/box/fancy/vials/on_update_icon() + . = ..() + var/key_count = count_by_type(contents, key_type) + icon_state = "[initial(icon_state)][FLOOR(key_count/2)]" + +/* + * Not actually a "fancy" storage... + */ +/obj/item/storage/lockbox/vials + name = "secure vial storage box" + desc = "A locked box for keeping things away from children." + icon = 'icons/obj/vialbox.dmi' + icon_state = "vialbox0" + item_state = "syringe_kit" + w_class = ITEM_SIZE_NORMAL + max_w_class = ITEM_SIZE_TINY + max_storage_space = null + storage_slots = 12 + req_access = list(access_virology) + material = /decl/material/solid/metal/stainlesssteel + +/obj/item/storage/lockbox/vials/Initialize() + . = ..() + update_icon() + +/obj/item/storage/lockbox/vials/on_update_icon() + . = ..() + var/total_contents = count_by_type(contents, /obj/item/chems/glass/beaker/vial) + icon_state = "vialbox[FLOOR(total_contents/2)]" + if (!broken) + add_overlay("led[locked]") + if(locked) + add_overlay("cover") + else + add_overlay("ledb") + +/obj/item/storage/lockbox/vials/attackby(obj/item/W, mob/user) + . = ..() + update_icon() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/lunchbox.dm b/code/game/objects/items/weapons/storage/lunchbox.dm index d619379aa63..61cb87867c1 100644 --- a/code/game/objects/items/weapons/storage/lunchbox.dm +++ b/code/game/objects/items/weapons/storage/lunchbox.dm @@ -1,10 +1,9 @@ /obj/item/storage/lunchbox max_storage_space = 8 //slightly smaller than a toolbox name = "rainbow lunchbox" - icon = 'icons/obj/items/storage/lunchbox.dmi' - icon_state = "lunchbox_rainbow" - item_state = "toolbox_pink" desc = "A little lunchbox. This one is the colors of the rainbow!" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_rainbow.dmi' + icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL max_w_class = ITEM_SIZE_SMALL attack_verb = list("lunched") @@ -29,8 +28,7 @@ /obj/item/storage/lunchbox/heart name = "heart lunchbox" - icon_state = "lunchbox_lovelyhearts" - item_state = "toolbox_pink" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_heart.dmi' desc = "A little lunchbox. This one has cute little hearts on it!" /obj/item/storage/lunchbox/heart/filled @@ -38,8 +36,7 @@ /obj/item/storage/lunchbox/cat name = "cat lunchbox" - icon_state = "lunchbox_sciencecatshow" - item_state = "toolbox_green" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_cat.dmi' desc = "A little lunchbox. This one has a cute little science cat from a popular show on it!" /obj/item/storage/lunchbox/cat/filled @@ -47,8 +44,7 @@ /obj/item/storage/lunchbox/mars name = "\improper Mariner University lunchbox" - icon_state = "lunchbox_marsuniversity" - item_state = "toolbox_red" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_mars.dmi' desc = "A little lunchbox. This one is branded with the Mariner university logo!" /obj/item/storage/lunchbox/mars/filled @@ -56,8 +52,7 @@ /obj/item/storage/lunchbox/cti name = "\improper CTI lunchbox" - icon_state = "lunchbox_cti" - item_state = "toolbox_blue" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_cti.dmi' desc = "A little lunchbox. This one is branded with the CTI logo!" /obj/item/storage/lunchbox/cti/filled @@ -65,8 +60,7 @@ /obj/item/storage/lunchbox/syndicate name = "black and red lunchbox" - icon_state = "lunchbox_syndie" - item_state = "toolbox_syndi" + icon = 'icons/obj/items/storage/lunchboxes/lunchbox_evil.dmi' desc = "A little lunchbox. This one is a sleek black and red, made of a durable steel!" /obj/item/storage/lunchbox/syndicate/filled diff --git a/code/game/objects/items/weapons/storage/med_pouch.dm b/code/game/objects/items/weapons/storage/med_pouch.dm index 16473aaaae6..a69f6c908ef 100644 --- a/code/game/objects/items/weapons/storage/med_pouch.dm +++ b/code/game/objects/items/weapons/storage/med_pouch.dm @@ -212,22 +212,22 @@ Single Use Emergency Pouches SetName("emergency [reagents.get_primary_reagent_name()] pill ([reagents.total_volume]u)") /obj/item/chems/pill/pouch_pill/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/stabilizer, reagents.maximum_volume) /obj/item/chems/pill/pouch_pill/antitoxins/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antitoxins, reagents.maximum_volume) /obj/item/chems/pill/pouch_pill/oxy_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/oxy_meds, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/oxy_meds, reagents.maximum_volume) /obj/item/chems/pill/pouch_pill/painkillers/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/painkillers, reagents.maximum_volume) /obj/item/chems/pill/pouch_pill/brute_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/brute_meds, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/brute_meds, reagents.maximum_volume) /obj/item/chems/pill/pouch_pill/burn_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/burn_meds, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/burn_meds, reagents.maximum_volume) // Injectors @@ -238,33 +238,33 @@ Single Use Emergency Pouches /obj/item/chems/hypospray/autoinjector/pouch_auto/stabilizer name = "emergency stabilizer autoinjector" /obj/item/chems/hypospray/autoinjector/pouch_auto/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, 5) + add_to_reagents(/decl/material/liquid/stabilizer, 5) /obj/item/chems/hypospray/autoinjector/pouch_auto/painkillers name = "emergency painkiller autoinjector" /obj/item/chems/hypospray/autoinjector/pouch_auto/painkillers/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers, 5) + add_to_reagents(/decl/material/liquid/painkillers, 5) /obj/item/chems/hypospray/autoinjector/pouch_auto/antitoxins name = "emergency antitoxins autoinjector" /obj/item/chems/hypospray/autoinjector/pouch_auto/antitoxins/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, 5) + add_to_reagents(/decl/material/liquid/antitoxins, 5) /obj/item/chems/hypospray/autoinjector/pouch_auto/oxy_meds name = "emergency oxygel autoinjector" /obj/item/chems/hypospray/autoinjector/pouch_auto/oxy_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/oxy_meds, 5) + add_to_reagents(/decl/material/liquid/oxy_meds, 5) /obj/item/chems/hypospray/autoinjector/pouch_auto/adrenaline name = "emergency adrenaline autoinjector" amount_per_transfer_from_this = 8 /obj/item/chems/hypospray/autoinjector/pouch_auto/adrenaline/populate_reagents() - reagents.add_reagent(/decl/material/liquid/adrenaline, 8) + add_to_reagents(/decl/material/liquid/adrenaline, 8) /obj/item/chems/hypospray/autoinjector/pouch_auto/nanoblood name = "emergency nanoblood autoinjector" /obj/item/chems/hypospray/autoinjector/pouch_auto/nanoblood/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nanoblood, 5) + add_to_reagents(/decl/material/liquid/nanoblood, 5) // Inhalers @@ -277,11 +277,11 @@ Single Use Emergency Pouches detail_color = COLOR_CYAN /obj/item/chems/inhaler/pouch_auto/oxy_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/oxy_meds, 5) + add_to_reagents(/decl/material/liquid/oxy_meds, 5) /obj/item/chems/inhaler/pouch_auto/detoxifier name = "emergency detoxifier autoinhaler" detail_color = COLOR_GREEN /obj/item/chems/inhaler/pouch_auto/detoxifier/populate_reagents() - reagents.add_reagent(/decl/material/liquid/detoxifier, 5) + add_to_reagents(/decl/material/liquid/detoxifier, 5) diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm index 4105247582d..29d1f4e17fa 100644 --- a/code/game/objects/items/weapons/storage/misc.dm +++ b/code/game/objects/items/weapons/storage/misc.dm @@ -25,30 +25,6 @@ /obj/item/dice/d100, ) -/obj/item/storage/box/donut - icon = 'icons/obj/food.dmi' - icon_state = "donutbox" - name = "donut box" - can_hold = list(/obj/item/chems/food/donut) - foldable = /obj/item/stack/material/cardstock - -/obj/item/storage/box/donut/WillContain() - return list(/obj/item/chems/food/donut = 6) - -/obj/item/storage/box/donut/on_update_icon() - . = ..() - var/list/cur_overlays - var/i = 0 - for(var/obj/item/chems/food/donut/D in contents) - LAZYADD(cur_overlays, overlay_image('icons/obj/food.dmi', "[i][D.overlay_state]", flags = RESET_COLOR)) - i++ - - if(LAZYLEN(cur_overlays)) - add_overlay(cur_overlays) - -/obj/item/storage/box/donut/empty/WillContain() - return null - //misc tobacco nonsense /obj/item/storage/cigpaper name = "\improper Gen. Eric cigarette paper" diff --git a/code/game/objects/items/weapons/storage/mre.dm b/code/game/objects/items/weapons/storage/mre.dm index 312251fc463..dd6027a58b1 100644 --- a/code/game/objects/items/weapons/storage/mre.dm +++ b/code/game/objects/items/weapons/storage/mre.dm @@ -20,7 +20,7 @@ MRE Stuff . = list( main_meal, /obj/item/storage/mrebag/dessert, - /obj/item/storage/fancy/crackers, + /obj/item/storage/box/fancy/crackers, /obj/random/mre/spread, /obj/random/mre/drink, /obj/random/mre/sauce, @@ -87,7 +87,7 @@ MRE Stuff . = list( main_meal, /obj/item/storage/mrebag/dessert/menu9, - /obj/item/storage/fancy/crackers, + /obj/item/storage/box/fancy/crackers, /obj/random/mre/spread/vegan, /obj/random/mre/drink, /obj/random/mre/sauce/vegan, @@ -113,7 +113,7 @@ MRE Stuff name = "crayon MRE" meal_desc = "This one doesn't have a menu listing. How very odd." icon_state = "crayonmre" - main_meal = /obj/item/storage/fancy/crayons + main_meal = /obj/item/storage/box/fancy/crayons /obj/item/storage/mre/menu11/WillContain() return list( @@ -145,7 +145,7 @@ MRE Stuff matter = list(/decl/material/solid/metal/aluminium = MATTER_AMOUNT_TRACE) /obj/item/storage/mrebag/WillContain() - return list(/obj/item/chems/food/slice/meatpizza/filled) + return list(/obj/item/chems/food/slice/pizza/meat/filled) /obj/item/storage/mrebag/on_update_icon() . = ..() @@ -161,10 +161,10 @@ MRE Stuff . = ..() /obj/item/storage/mrebag/menu2/WillContain() - return list(/obj/item/chems/food/slice/margherita/filled) + return list(/obj/item/chems/food/slice/pizza/margherita/filled) /obj/item/storage/mrebag/menu3/WillContain() - return list(/obj/item/chems/food/slice/vegetablepizza/filled) + return list(/obj/item/chems/food/slice/pizza/vegetable/filled) /obj/item/storage/mrebag/menu4/WillContain() return list(/obj/item/chems/food/hamburger) diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 3042ff6067c..da51725b5c5 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -1,9 +1,8 @@ /obj/item/storage/toolbox name = "toolbox" desc = "Bright red toolboxes like these are one of the most common sights in maintenance corridors on virtually every ship in the galaxy." - icon = 'icons/obj/items/storage/toolbox.dmi' - icon_state = "red" - item_state = "toolbox_red" + icon = 'icons/obj/items/storage/toolboxes/toolbox_red.dmi' + icon_state = ICON_STATE_WORLD obj_flags = OBJ_FLAG_CONDUCTIBLE force = 20 attack_cooldown = 21 @@ -14,7 +13,7 @@ w_class = ITEM_SIZE_LARGE max_w_class = ITEM_SIZE_NORMAL max_storage_space = DEFAULT_LARGEBOX_STORAGE //enough to hold all starting contents - origin_tech = "{'combat':1}" + origin_tech = @'{"combat":1}' attack_verb = list("robusted") use_sound = 'sound/effects/storage/toolbox.ogg' material = /decl/material/solid/metal/aluminium @@ -35,8 +34,7 @@ /obj/item/storage/toolbox/mechanical name = "mechanical toolbox" desc = "Bright blue toolboxes like these are one of the most common sights in maintenance corridors on virtually every ship in the galaxy." - icon_state = "blue" - item_state = "toolbox_blue" + icon = 'icons/obj/items/storage/toolboxes/toolbox_blue.dmi' /obj/item/storage/toolbox/mechanical/WillContain() return list( @@ -51,8 +49,8 @@ /obj/item/storage/toolbox/electrical name = "electrical toolbox" desc = "Bright yellow toolboxes like these are one of the most common sights in maintenance corridors on virtually every ship in the galaxy." - icon_state = "yellow" - item_state = "toolbox_yellow" + icon = 'icons/obj/items/storage/toolboxes/toolbox_yellow.dmi' + /obj/item/storage/toolbox/electrical/WillContain() return list( @@ -67,9 +65,8 @@ /obj/item/storage/toolbox/syndicate name = "black and red toolbox" desc = "A toolbox in black, with stylish red trim. This one feels particularly heavy, yet balanced." - icon_state = "syndicate" - item_state = "toolbox_syndi" - origin_tech = "{'combat':1,'esoteric':1}" + icon = 'icons/obj/items/storage/toolboxes/toolbox_black_red.dmi' + origin_tech = @'{"combat":1,"esoteric":1}' attack_cooldown = 10 /obj/item/storage/toolbox/syndicate/WillContain() @@ -95,8 +92,7 @@ /obj/item/storage/toolbox/repairs name = "electronics toolbox" desc = "A box full of boxes, with electrical machinery parts and tools needed to get them where they're needed." - icon_state = "yellow_striped" - item_state = "toolbox_yellow" + icon = 'icons/obj/items/storage/toolboxes/toolbox_yellow_striped.dmi' /obj/item/storage/toolbox/repairs/WillContain() return list( diff --git a/code/game/objects/items/weapons/storage/trays.dm b/code/game/objects/items/weapons/storage/trays.dm index 9b81b952fda..7e113f31fc6 100644 --- a/code/game/objects/items/weapons/storage/trays.dm +++ b/code/game/objects/items/weapons/storage/trays.dm @@ -2,7 +2,7 @@ /obj/item/storage/tray name = "tray" - icon = 'icons/obj/food.dmi' + icon = 'icons/obj/food_trays.dmi' icon_state = "tray_material" desc = "A tray to serve food on." force = 4 diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 874391b6e81..533e6a2b632 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -1,6 +1,6 @@ -/proc/fill_cigarre_package(var/obj/item/storage/fancy/cigarettes/C, var/list/reagents) +/proc/fill_cigarre_package(var/obj/item/storage/box/fancy/cigarettes/C, var/list/reagents) for(var/reagent in reagents) - C.reagents.add_reagent(reagent, reagents[reagent] * C.max_storage_space) + C.add_to_reagents(reagent, reagents[reagent] * C.max_storage_space) /obj/item/storage/box/syndie_kit name = "box" @@ -57,7 +57,7 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/uranium = MATTER_AMOUNT_TRACE - ) + ) /obj/item/storage/backpack/chameleon/sydie_kit/WillContain() return list( @@ -128,10 +128,10 @@ /obj/item/storage/box/syndie_kit/cigarette/WillContain() return list( - /obj/item/storage/fancy/cigarettes/flash_powder = 2, - /obj/item/storage/fancy/cigarettes/chemsmoke = 2, - /obj/item/storage/fancy/cigarettes/mindbreak, - /obj/item/storage/fancy/cigarettes/tricord, + /obj/item/storage/box/fancy/cigarettes/flash_powder = 2, + /obj/item/storage/box/fancy/cigarettes/chemsmoke = 2, + /obj/item/storage/box/fancy/cigarettes/mindbreak, + /obj/item/storage/box/fancy/cigarettes/tricord, /obj/item/flame/lighter/zippo/random, ) diff --git a/code/game/objects/items/weapons/storage/wall_mirror.dm b/code/game/objects/items/weapons/storage/wall_mirror.dm index 960a91c3010..4ae11605eb1 100644 --- a/code/game/objects/items/weapons/storage/wall_mirror.dm +++ b/code/game/objects/items/weapons/storage/wall_mirror.dm @@ -10,7 +10,7 @@ var/shattered = FALSE var/list/ui_users var/obj/item/storage/internal/mirror_storage/mirror_storage - directional_offset = "{'NORTH':{'y':-29}, 'SOUTH':{'y':29}, 'EAST':{'x':29}, 'WEST':{'x':-29}}" + directional_offset = @'{"NORTH":{"y":-29}, "SOUTH":{"y":29}, "EAST":{"x":29}, "WEST":{"x":-29}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED /obj/structure/mirror/Initialize() diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 61686252167..637ce63e363 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -10,7 +10,7 @@ edge = 0 throwforce = 7 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' attack_verb = list("beaten") base_parry_chance = 30 material = /decl/material/solid/metal/aluminium diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 3c24838ae47..95145f0c8e9 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -20,7 +20,7 @@ matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) obj_flags = OBJ_FLAG_CONDUCTIBLE w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' drop_sound = 'sound/foley/knifedrop3.ogg' /obj/item/retractor/Initialize() @@ -39,7 +39,7 @@ matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) obj_flags = OBJ_FLAG_CONDUCTIBLE w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' attack_verb = list("attacked", "pinched") drop_sound = 'sound/foley/knifedrop3.ogg' @@ -62,7 +62,7 @@ ) obj_flags = OBJ_FLAG_CONDUCTIBLE w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' attack_verb = list("burnt") /obj/item/cautery/Initialize() @@ -83,7 +83,7 @@ obj_flags = OBJ_FLAG_CONDUCTIBLE force = 15.0 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' attack_verb = list("drilled") /obj/item/surgicaldrill/Initialize() @@ -107,7 +107,7 @@ throwforce = 5 throw_speed = 3 throw_range = 5 - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") @@ -131,7 +131,7 @@ matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) pickup_sound = 'sound/foley/pickup2.ogg' tool_quality = TOOL_QUALITY_DECENT - origin_tech = "{'biotech':2,'materials':2,'magnets':2}" + origin_tech = @'{"biotech":2,"materials":2,"magnets":2}' /obj/item/scalpel/laser/upgraded name = "upgraded laser scalpel" @@ -143,7 +143,7 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE ) tool_quality = TOOL_QUALITY_GOOD - origin_tech = "{'biotech':3,'materials':4,'magnets':4}" + origin_tech = @'{"biotech":3,"materials":4,"magnets":4}' /obj/item/scalpel/laser/advanced name = "advanced laser scalpel" @@ -156,7 +156,7 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) tool_quality = TOOL_QUALITY_BEST - origin_tech = "{'biotech':4,'materials':6,'magnets':5}" + origin_tech = @'{"biotech":4,"materials":6,"magnets":5}' /obj/item/incision_manager name = "incision management system" @@ -175,7 +175,7 @@ /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) pickup_sound = 'sound/foley/pickup2.ogg' - origin_tech = "{'biotech':4,'materials':7,'magnets':5,'programming':4}" + origin_tech = @'{"biotech":4,"materials":7,"magnets":5,"programming":4}' /obj/item/incision_manager/Initialize() . = ..() @@ -201,7 +201,7 @@ throwforce = 9 throw_speed = 3 throw_range = 5 - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) attack_verb = list("attacked", "slashed", "sawed", "cut") @@ -240,7 +240,7 @@ icon_state = "fixovein" force = 0 throwforce = 1 - origin_tech = "{'materials':1,'biotech':3}" + origin_tech = @'{"materials":1,"biotech":3}' w_class = ITEM_SIZE_SMALL material = /decl/material/solid/organic/plastic diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index 8e0b7fc6891..692aa383f80 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -13,7 +13,7 @@ action_button_name = "Toggle Jetpack" material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/aluminium = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':1,'engineering':3}" + origin_tech = @'{"materials":1,"engineering":3}' /obj/item/tank/jetpack/Initialize() . = ..() @@ -41,7 +41,7 @@ if(on) add_overlay("[icon_state]-on") -/obj/item/tank/jetpack/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/tank/jetpack/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && slot == slot_back_str && on) overlay.icon_state = "[overlay.icon_state]-on" . = ..() diff --git a/code/game/objects/items/weapons/tech_disks.dm b/code/game/objects/items/weapons/tech_disks.dm index cd91b56acbe..c2b3fe5c736 100644 --- a/code/game/objects/items/weapons/tech_disks.dm +++ b/code/game/objects/items/weapons/tech_disks.dm @@ -128,3 +128,18 @@ SetName(initial(name)) to_chat(user, SPAN_DANGER("You flick the erase switch and wipe \the [src].")) return TRUE + +/////////////////////////////////////////////////////////////////////////////// +// Exploration and Mining Data Disk +/////////////////////////////////////////////////////////////////////////////// +/obj/item/disk/survey + name = "survey data disk" + color = COLOR_DARK_BROWN + var/data = 0 + +/obj/item/disk/survey/examine(mob/user) + . = ..() + to_chat(user, "A tiny indicator on \the [src] shows it holds [data] good explorer point\s.") + +/obj/item/disk/survey/get_base_value() + . = holographic ? 0 : (sqrt(data) * 5) diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 206aa606eb9..e95ffde8b89 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -18,7 +18,7 @@ w_class = ITEM_SIZE_SMALL throw_speed = 4 throw_range = 20 - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/aluminium /obj/item/locator/attack_self(mob/user) diff --git a/code/game/objects/items/weapons/tools/crowbar.dm b/code/game/objects/items/weapons/tools/crowbar.dm index 13f6c62f9d6..07f2255a58f 100644 --- a/code/game/objects/items/weapons/tools/crowbar.dm +++ b/code/game/objects/items/weapons/tools/crowbar.dm @@ -8,9 +8,9 @@ attack_cooldown = 2*DEFAULT_WEAPON_COOLDOWN melee_accuracy_bonus = -10 w_class = ITEM_SIZE_SMALL - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':16,'y':20}" + center_of_mass = @'{"x":16,"y":20}' attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/bardrop1.ogg' diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index efbf46c3806..37225510ddf 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -6,7 +6,7 @@ slot_flags = SLOT_LOWER_BODY | SLOT_EARS w_class = ITEM_SIZE_TINY material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' attack_verb = list("stabbed") lock_picking_level = 5 sharp = TRUE @@ -28,7 +28,7 @@ handle_color = pick(valid_colours) add_overlay(mutable_appearance(icon, "[get_world_inventory_state()]_handle", handle_color)) -/obj/item/screwdriver/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/screwdriver/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) overlay.color = handle_color . = ..() diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index cb87f57182e..3143c721fc8 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -8,7 +8,7 @@ icon_state = ICON_STATE_WORLD obj_flags = OBJ_FLAG_CONDUCTIBLE slot_flags = SLOT_LOWER_BODY - center_of_mass = @"{'x':14,'y':15}" + center_of_mass = @'{"x":14,"y":15}' force = 5 throwforce = 5 throw_speed = 1 @@ -16,7 +16,7 @@ w_class = ITEM_SIZE_SMALL material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'engineering':1}" + origin_tech = @'{"engineering":1}' drop_sound = 'sound/foley/tooldrop1.ogg' z_flags = ZMM_MANGLE_PLANES attack_cooldown = DEFAULT_ATTACK_COOLDOWN @@ -52,7 +52,7 @@ if(welding) update_icon() -/obj/item/weldingtool/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/weldingtool/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && welding && check_state_in_icon("[overlay.icon_state]-lit", overlay.icon)) overlay.add_overlay(emissive_overlay(overlay.icon, "[overlay.icon_state]-lit")) . = ..() @@ -228,7 +228,7 @@ if(location) location.hotspot_expose(WELDING_TOOL_HOTSPOT_TEMP_ACTIVE, 5) set_light(5, 0.7, COLOR_LIGHT_CYAN) - addtimer(CALLBACK(src, /atom/proc/update_icon), 5) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 5) return TRUE /**Handle the flame burning fuel while the welder is on */ @@ -262,7 +262,7 @@ if(get_fuel() < amount) . = FALSE //Try to burn as much as possible anyways if(tank) - tank.reagents.remove_reagent(/decl/material/liquid/fuel, amount) + tank.remove_from_reagents(/decl/material/liquid/fuel, amount) //Returns whether or not the welding tool is currently on. /obj/item/weldingtool/proc/isOn() @@ -411,7 +411,7 @@ var/lit_force = 11 /obj/item/chems/welder_tank/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fuel, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/fuel, reagents.maximum_volume) /obj/item/chems/welder_tank/examine(mob/user, distance) . = ..() @@ -430,7 +430,7 @@ return TRUE if(standard_pour_into(user, O)) return TRUE - if(standard_feed_mob(user, O)) + if(handle_eaten_by_mob(user, O) != EATEN_INVALID) return TRUE if(user.a_intent == I_HURT) if(standard_splash_mob(user, O)) @@ -461,11 +461,11 @@ return FALSE . = ..() -/obj/item/chems/welder_tank/standard_feed_mob(mob/user, mob/target) +/obj/item/chems/welder_tank/handle_eaten_by_mob(mob/user, mob/target) if(!can_refuel) to_chat(user, SPAN_DANGER("\The [src] is sealed shut.")) - return FALSE - . = ..() + return EATEN_UNABLE + return ..() /obj/item/chems/welder_tank/get_alt_interactions(var/mob/user) . = ..() @@ -533,7 +533,7 @@ /obj/item/chems/welder_tank/experimental/Process() if(REAGENT_VOLUME(reagents, /decl/material/liquid/fuel) < reagents.maximum_volume) var/gen_amount = ((world.time-last_gen)/25) - reagents.add_reagent(/decl/material/liquid/fuel, gen_amount) + add_to_reagents(/decl/material/liquid/fuel, gen_amount) last_gen = world.time #undef WELDING_TOOL_HOTSPOT_TEMP_ACTIVE diff --git a/code/game/objects/items/weapons/tools/wirecutter.dm b/code/game/objects/items/weapons/tools/wirecutter.dm index 1d13c16ecdc..8a9ad3bcba5 100644 --- a/code/game/objects/items/weapons/tools/wirecutter.dm +++ b/code/game/objects/items/weapons/tools/wirecutter.dm @@ -5,9 +5,9 @@ icon_state = ICON_STATE_WORLD slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':18,'y':10}" + center_of_mass = @'{"x":18,"y":10}' attack_verb = list("pinched", "nipped") sharp = 1 edge = 1 @@ -27,7 +27,7 @@ handle_color = pick(valid_colours) add_overlay(overlay_image(icon, "[get_world_inventory_state()]_handle", handle_color, flags=RESET_COLOR)) -/obj/item/wirecutters/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/wirecutters/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) overlay.color = handle_color . = ..() diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/weapons/tools/wrench.dm index 558bc1cdae2..13bd7160c21 100644 --- a/code/game/objects/items/weapons/tools/wrench.dm +++ b/code/game/objects/items/weapons/tools/wrench.dm @@ -6,9 +6,9 @@ slot_flags = SLOT_LOWER_BODY material_force_multiplier = 0.2 w_class = ITEM_SIZE_SMALL - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/metal/steel - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' attack_verb = list("bashed", "battered", "bludgeoned", "whacked") material_alteration = MAT_FLAG_ALTERATION_COLOR drop_sound = 'sound/foley/bardrop1.ogg' diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index 52ff7f8e691..56243d3d4d3 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -9,7 +9,7 @@ desc = "A mechanically activated leg trap. Low-tech, but reliable. Looks like it could really hurt if you set it off." throwforce = 0 w_class = ITEM_SIZE_NORMAL - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel can_buckle = 0 //disallow manual un/buckling var/deployed = 0 diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm index 7848d0ff55b..493d580e432 100644 --- a/code/game/objects/items/weapons/weldbackpack.dm +++ b/code/game/objects/items/weapons/weldbackpack.dm @@ -46,7 +46,7 @@ if(get_fuel() < amount) . = FALSE //Try to burn as much as possible anyways if(linked_pack) - linked_pack.reagents.remove_reagent(/decl/material/liquid/fuel, amount) + linked_pack.remove_from_reagents(/decl/material/liquid/fuel, amount) /**Called by the parent when the welderpack is dropped */ /obj/item/weldingtool/weldpack/proc/on_pack_dropped(var/mob/user) @@ -77,7 +77,7 @@ var/obj/item/weldingtool/weldpack/welder = /obj/item/weldingtool/weldpack /obj/item/chems/weldpack/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fuel, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/fuel, reagents.maximum_volume) /obj/item/chems/weldpack/Initialize(ml, material_key) if(ispath(welder)) diff --git a/code/game/objects/obj_edibility.dm b/code/game/objects/obj_edibility.dm new file mode 100644 index 00000000000..871c7831799 --- /dev/null +++ b/code/game/objects/obj_edibility.dm @@ -0,0 +1,148 @@ +/obj/proc/get_food_consumption_method(mob/eater) + return EATING_METHOD_EAT + +/obj/proc/is_edible(var/mob/eater) + return get_edible_material_amount(eater) > 0 + +/obj/proc/get_edible_material_amount(var/mob/eater) + return 0 + +/obj/proc/get_food_default_transfer_amount(mob/eater) + return eater?.get_eaten_transfer_amount(2) // arbitrary, should be overridden downstream + +/obj/proc/show_food_consumed_message(mob/user, mob/target) + if(user == target) + user?.visible_message( + SPAN_NOTICE("\The [target] finishes eating \the [src]."), + SPAN_NOTICE("You finish eating \the [src].") + ) + else + user?.visible_message( + SPAN_NOTICE("\The [user] feeds the last of \the [src] to \the [target]."), + SPAN_NOTICE("You feed the last of \the [src] to \the [target].") + ) + +/obj/proc/handle_consumed(mob/feeder, mob/eater, consumption_method = EATING_METHOD_EAT) + transfer_eaten_material(eater, get_food_default_transfer_amount(eater)) + play_feed_sound(eater, consumption_method) + if(!get_edible_material_amount(eater)) + if(feeder && eater) + show_food_consumed_message(feeder, eater) + feeder.drop_from_inventory(src) + eater.update_personal_goal(/datum/goal/achievement/specific_object/food, type) + physically_destroyed() + return TRUE + return FALSE + +/obj/proc/transfer_eaten_material(mob/eater, amount) + reagents?.trans_to_mob(eater, amount, CHEM_INGEST) + +/obj/proc/show_feed_message_start(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You begin trying to take a bite from \the [target].")) + else + user.visible_message(SPAN_NOTICE("\The [user] is trying to feed \the [src] to \the [target]!")) + +/obj/proc/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You take a bite of \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] feeds some of \the [src] to \the [target]!")) + +/obj/proc/show_food_inedible_message(mob/user, mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_WARNING("There is nothing in \the [src] that you can eat.")) + else + to_chat(user, SPAN_WARNING("There is nothing in \the [src] that \the [target] can eat.")) + +/obj/proc/show_food_no_mouth_message(mob/user, mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_WARNING("Where do you intend to put \the [src]? You don't have a mouth!")) + else + to_chat(user, SPAN_WARNING("Where do you intend to put \the [src]? \The [target] doesn't have a mouth!")) + +/obj/proc/play_feed_sound(var/mob/user, consumption_method = EATING_METHOD_EAT) + var/turf/play_turf = get_turf(user) + if(!play_turf) + return + switch(consumption_method) + if(EATING_METHOD_EAT) + playsound(user.loc, 'sound/items/eatfood.ogg', rand(10, 50), 1) + if(EATING_METHOD_DRINK) + playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1) + +/obj/proc/show_food_empty_message(mob/user, mob/target) + to_chat(user, SPAN_NOTICE("\The [src] is empty.")) + +/obj/proc/is_food_empty(mob/eater) + return get_edible_material_amount(eater) <= 0 + +// General proc for handling an attempt to eat an item, or to eat from an +// item. At time of writing, only handles classic SS13 eating (reagents). +// Returns EATEN_INVALID for an inability to eat, EATEN_UNABLE for an attempt +// prevented by something, and EATEN_SUCCESS for a successful bite. +/obj/proc/handle_eaten_by_mob(var/mob/user, var/mob/target) + + if(!istype(user)) + return EATEN_INVALID + + if(!target) + target = user + + if(!istype(target)) + return EATEN_INVALID + + if(!is_edible(target)) + show_food_inedible_message(user, target) + return EATEN_UNABLE + + if(is_food_empty(target)) + show_food_empty_message(user, target) + return EATEN_UNABLE + + if(!target.check_has_mouth()) + show_food_no_mouth_message(user, target) + return EATEN_UNABLE + + if(!target.can_eat_food_currently(src, user)) + return EATEN_UNABLE + + var/blocked = target.check_mouth_coverage() + if(blocked) + to_chat(user, SPAN_NOTICE("\The [blocked] is in the way!")) + return EATEN_UNABLE + + if(user != target && !user.can_force_feed(target, src)) + return EATEN_UNABLE + + var/consumption_method = get_food_consumption_method(target) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(user != target) + if(!user.can_force_feed(target, src)) + return EATEN_UNABLE + show_feed_message_start(user, target, consumption_method) + if(!do_mob(user, target)) + return EATEN_UNABLE + var/contained = json_encode(REAGENT_LIST(src)) + admin_attack_log(user, target, "Fed the victim with [name] (Reagents: [contained])", "Was fed [src] (Reagents: [contained])", "used [src] (Reagents: [contained]) to feed") + + show_feed_message_end(user, target, consumption_method) + handle_consumed(user, target, consumption_method) + return EATEN_SUCCESS + +/obj/attack_animal(var/mob/user) + if((isanimal(user) || isalien(user)) && is_edible(user) && handle_eaten_by_mob(user) == EATEN_SUCCESS) + // TODO: put this in the mob AI. + spawn(5) + if(user && QDELETED(src) && !user.client) + user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]") + return TRUE + return ..() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 69e6540aeb2..ff11e6d8cef 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -16,7 +16,7 @@ var/armor_penetration = 0 var/anchor_fall = FALSE var/holographic = 0 //if the obj is a holographic object spawned by the holodeck - var/tmp/directional_offset ///JSON list of directions to x,y offsets to be applied to the object depending on its direction EX: {'NORTH':{'x':12,'y':5}, 'EAST':{'x':10,'y':50}} + var/tmp/directional_offset ///JSON list of directions to x,y offsets to be applied to the object depending on its direction EX: @'{"NORTH":{"x":12,"y":5}, "EAST":{"x":10,"y":50}}' ///The current health of the obj. Leave to null, unless you want the object to start at a different health than max_health. var/health diff --git a/code/game/objects/random/date_based.dm b/code/game/objects/random/date_based.dm index 0eee0d30f9e..3987c3b3f34 100644 --- a/code/game/objects/random/date_based.dm +++ b/code/game/objects/random/date_based.dm @@ -5,7 +5,7 @@ /obj/random/date_based name = "random object (date based)" icon_state = "yup" - spawn_method = .proc/check_date + spawn_method = PROC_REF(check_date) var/datum/is_date/date_check /obj/random/date_based/Destroy() diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm index 950c7e7a276..7bb4338d5b1 100644 --- a/code/game/objects/random/subtypes/misc.dm +++ b/code/game/objects/random/subtypes/misc.dm @@ -89,7 +89,7 @@ /obj/item/pen/multi, /obj/item/storage/box/matches, /obj/item/stack/material/cardstock/mapped/cardboard, - /obj/item/storage/fancy/cigarettes, + /obj/item/storage/box/fancy/cigarettes, /obj/item/deck/cards ) return spawnable_choices @@ -120,10 +120,8 @@ spawnable_choices[trash_type] = 95 for(var/trash_type in typesof(/obj/item/trash/cigbutt)) spawnable_choices[trash_type] = 95 - spawnable_choices -= /obj/item/trash/plate spawnable_choices -= /obj/item/trash/snack_bowl spawnable_choices -= /obj/item/trash/syndi_cakes - spawnable_choices -= /obj/item/trash/tray var/lunches = lunchables_lunches() for(var/lunch in lunches) spawnable_choices[lunches[lunch]] = 1 @@ -244,15 +242,15 @@ /obj/random/smokes/spawn_choices() var/static/list/spawnable_choices = list( - /obj/item/storage/fancy/cigarettes = 5, - /obj/item/storage/fancy/cigarettes/dromedaryco = 4, - /obj/item/storage/fancy/cigarettes/killthroat = 1, - /obj/item/storage/fancy/cigarettes/luckystars = 3, - /obj/item/storage/fancy/cigarettes/jerichos = 3, - /obj/item/storage/fancy/cigarettes/menthols = 2, - /obj/item/storage/fancy/cigarettes/carcinomas = 3, - /obj/item/storage/fancy/cigarettes/professionals = 2, - /obj/item/storage/fancy/cigar = 1, + /obj/item/storage/box/fancy/cigarettes = 5, + /obj/item/storage/box/fancy/cigarettes/dromedaryco = 4, + /obj/item/storage/box/fancy/cigarettes/killthroat = 1, + /obj/item/storage/box/fancy/cigarettes/luckystars = 3, + /obj/item/storage/box/fancy/cigarettes/jerichos = 3, + /obj/item/storage/box/fancy/cigarettes/menthols = 2, + /obj/item/storage/box/fancy/cigarettes/carcinomas = 3, + /obj/item/storage/box/fancy/cigarettes/professionals = 2, + /obj/item/storage/box/fancy/cigar = 1, /obj/item/clothing/mask/smokable/cigarette = 2, /obj/item/clothing/mask/smokable/cigarette/menthol = 2, /obj/item/clothing/mask/smokable/cigarette/cigar = 1, @@ -278,7 +276,7 @@ /obj/item/storage/box = 5, /obj/item/storage/box/donkpockets = 3, /obj/item/storage/box/sinpockets = 1, - /obj/item/storage/box/donut = 2, + /obj/item/storage/box/fancy/donut = 2, /obj/item/storage/box/cups = 3, /obj/item/storage/box/mousetraps = 4, /obj/item/storage/box/engineer = 3, diff --git a/code/game/objects/random/subtypes/tools.dm b/code/game/objects/random/subtypes/tools.dm index e7af77f0465..58c637a8cf0 100644 --- a/code/game/objects/random/subtypes/tools.dm +++ b/code/game/objects/random/subtypes/tools.dm @@ -33,8 +33,8 @@ /obj/random/toolbox name = "random toolbox" desc = "This is a random toolbox." - icon = 'icons/obj/items/storage/toolbox.dmi' - icon_state = "red" + icon = 'icons/obj/items/storage/toolboxes/toolbox_red.dmi' + icon_state = ICON_STATE_WORLD /obj/random/toolbox/spawn_choices() var/static/list/spawnable_choices = list( diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index d1d9d9d5014..42f4ad03af0 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -6,7 +6,7 @@ appearance_flags = 0 anchored = TRUE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/cult = 0 /obj/structure/sign/double/barsign/proc/get_valid_states(initial=1) diff --git a/code/game/objects/structures/bookcase.dm b/code/game/objects/structures/bookcase.dm index 2b3e3b5a7a1..cca3eb52e12 100644 --- a/code/game/objects/structures/bookcase.dm +++ b/code/game/objects/structures/bookcase.dm @@ -19,6 +19,8 @@ var/global/list/station_bookcases = list() global.station_bookcases += src get_or_create_extension(src, /datum/extension/labels/single) . = ..() + if(length(contents)) + update_icon() /obj/structure/bookcase/Destroy() global.station_bookcases -= src @@ -50,18 +52,16 @@ var/global/list/station_bookcases = list() name = "Medical Manuals bookcase" /obj/structure/bookcase/manuals/medical/Initialize() - . = ..() new /obj/item/book/manual/medical_diagnostics_manual(src) new /obj/item/book/manual/medical_diagnostics_manual(src) new /obj/item/book/manual/medical_diagnostics_manual(src) new /obj/item/book/manual/chemistry_recipes(src) - update_icon() + . = ..() /obj/structure/bookcase/manuals/engineering name = "Engineering Manuals bookcase" /obj/structure/bookcase/manuals/engineering/Initialize() - . = ..() new /obj/item/book/manual/engineering_construction(src) new /obj/item/book/manual/engineering_particle_accelerator(src) new /obj/item/book/manual/engineering_hacking(src) @@ -70,7 +70,7 @@ var/global/list/station_bookcases = list() new /obj/item/book/manual/engineering_singularity_safety(src) new /obj/item/book/manual/evaguide(src) new /obj/item/book/manual/rust_engine(src) - update_icon() + . = ..() /obj/structure/bookcase/cart name = "book cart" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index 39f01e28bbc..b7b188e2d87 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -32,7 +32,7 @@ return list( /obj/item/chems/drinks/milk = 6, /obj/item/chems/drinks/soymilk = 4, - /obj/item/storage/fancy/egg_box = 4 + /obj/item/storage/box/fancy/egg_box = 4 ) /obj/structure/closet/secure_closet/freezer/money diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index b7656597e93..a7b3a7c779b 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -141,7 +141,7 @@ storage_types = CLOSET_STORAGE_ITEMS setup = 0 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' icon = 'icons/obj/closets/bases/wall.dmi' /obj/structure/closet/hydrant/Initialize(ml, _mat, _reinf_mat) @@ -170,7 +170,7 @@ storage_types = CLOSET_STORAGE_ITEMS setup = 0 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' icon = 'icons/obj/closets/bases/wall.dmi' /obj/structure/closet/medical_wall/Initialize() @@ -192,7 +192,7 @@ storage_types = CLOSET_STORAGE_ITEMS setup = 0 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' icon = 'icons/obj/closets/bases/wall.dmi' /obj/structure/closet/shipping_wall/Initialize() diff --git a/code/game/objects/structures/crates_lockers/closets/walllocker.dm b/code/game/objects/structures/crates_lockers/closets/walllocker.dm index 7bcf9d54d20..cb186904d24 100644 --- a/code/game/objects/structures/crates_lockers/closets/walllocker.dm +++ b/code/game/objects/structures/crates_lockers/closets/walllocker.dm @@ -12,7 +12,7 @@ storage_types = CLOSET_STORAGE_ITEMS setup = 0 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' /obj/structure/closet/walllocker/Initialize() . = ..() diff --git a/code/game/objects/structures/defensive_barrier.dm b/code/game/objects/structures/defensive_barrier.dm index bd3e74d127c..d28141302bc 100644 --- a/code/game/objects/structures/defensive_barrier.dm +++ b/code/game/objects/structures/defensive_barrier.dm @@ -16,7 +16,7 @@ /obj/structure/defensive_barrier/Initialize() . = ..() update_icon() - events_repository.register(/decl/observ/dir_set, src, src, .proc/update_layers) + events_repository.register(/decl/observ/dir_set, src, src, PROC_REF(update_layers)) /obj/structure/defensive_barrier/physically_destroyed(var/skip_qdel) visible_message(SPAN_DANGER("\The [src] was destroyed!")) @@ -24,7 +24,7 @@ . = ..() /obj/structure/defensive_barrier/Destroy() - events_repository.unregister(/decl/observ/dir_set, src, src, .proc/update_layers) + events_repository.unregister(/decl/observ/dir_set, src, src, PROC_REF(update_layers)) . = ..() /obj/structure/defensive_barrier/proc/update_layers() diff --git a/code/game/objects/structures/doors/_door.dm b/code/game/objects/structures/doors/_door.dm index 51b9ebb7692..b07f12e1902 100644 --- a/code/game/objects/structures/doors/_door.dm +++ b/code/game/objects/structures/doors/_door.dm @@ -114,7 +114,9 @@ if(lock) if(istype(I, /obj/item/key)) - if(!lock.toggle(I)) + if(lock.toggle(I)) + to_chat(user, SPAN_NOTICE("You [lock.status ? "lock" : "unlock"] \the [src] with \the [I].")) + else to_chat(user, SPAN_WARNING("\The [I] does not fit in the lock!")) return TRUE if(lock.pick_lock(I,user)) diff --git a/code/game/objects/structures/emergency_dispenser.dm b/code/game/objects/structures/emergency_dispenser.dm index c8b7075f4d5..6bc0e2528f8 100644 --- a/code/game/objects/structures/emergency_dispenser.dm +++ b/code/game/objects/structures/emergency_dispenser.dm @@ -7,7 +7,7 @@ icon_state = "world" anchored = TRUE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/static/list/spawnitems = list(/obj/item/tank/emergency/oxygen,/obj/item/clothing/mask/breath) var/amount = 3 // spawns each items X times. diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 208a3af9305..6bccabb09f6 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -6,7 +6,7 @@ anchored = TRUE density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-29}, 'SOUTH':{'y':29}, 'EAST':{'x':-29}, 'WEST':{'x':29}}" + directional_offset = @'{"NORTH":{"y":-29}, "SOUTH":{"y":29}, "EAST":{"x":-29}, "WEST":{"x":29}}' var/obj/item/chems/spray/extinguisher/has_extinguisher var/opened = 0 diff --git a/code/game/objects/structures/fireaxe_cabinet.dm b/code/game/objects/structures/fireaxe_cabinet.dm index d2049e48568..fc6227b924f 100644 --- a/code/game/objects/structures/fireaxe_cabinet.dm +++ b/code/game/objects/structures/fireaxe_cabinet.dm @@ -6,7 +6,7 @@ anchored = TRUE density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/damage_threshold = 15 var/open diff --git a/code/game/objects/structures/fishtanks.dm b/code/game/objects/structures/fishtanks.dm index 8a730e42916..99236832272 100644 --- a/code/game/objects/structures/fishtanks.dm +++ b/code/game/objects/structures/fishtanks.dm @@ -60,7 +60,7 @@ var/global/list/fishtank_cache = list() . = ..() /obj/structure/glass_tank/populate_reagents() - reagents.add_reagent(fill_type, reagents.maximum_volume) + add_to_reagents(fill_type, reagents.maximum_volume) /obj/structure/glass_tank/attack_hand(var/mob/user) if(user.a_intent == I_HURT) @@ -94,11 +94,9 @@ var/global/list/fishtank_cache = list() /obj/structure/glass_tank/dump_contents() . = ..() - if(reagents && reagents.total_volume) - var/turf/T = get_turf(src) - var/obj/effect/fluid/F = locate() in T - if(!F) F = new(T) - reagents.trans_to_holder(F.reagents, reagents.total_volume) + var/turf/T = get_turf(src) + if(reagents?.total_volume && T) + reagents.trans_to_turf(T, T.reagents, reagents.total_volume) var/global/list/global/aquarium_states_and_layers = list( "b" = FLY_LAYER - 0.02, diff --git a/code/game/objects/structures/flora/_flora.dm b/code/game/objects/structures/flora/_flora.dm index f7081d56bcd..4eff66e931e 100644 --- a/code/game/objects/structures/flora/_flora.dm +++ b/code/game/objects/structures/flora/_flora.dm @@ -20,9 +20,18 @@ /obj/structure/flora/proc/init_appearance() return +// We rely on overrides to spawn appropriate materials for flora structures. +/obj/structure/flora/create_dismantled_products(turf/T) + matter = null + material = null + reinf_material = null + return ..() + /obj/structure/flora/attackby(obj/item/O, mob/user) - if(can_cut_down(O, user)) - return cut_down(O, user) + if(user.a_intent != I_HURT && can_cut_down(O, user)) + play_cut_sound() + cut_down(O, user) + return TRUE . = ..() /**Whether the item used by user can cause cut_down to be called. Used to bypass default attack proc for some specific items/tools. */ @@ -30,9 +39,13 @@ return (I.force >= 5) && I.sharp //Anything sharp and relatively strong can cut us instantly /**What to do when the can_cut_down check returns true. Normally simply calls dismantle. */ -/obj/structure/flora/proc/cut_down(var/obj/item/I, var/mob/user) +/obj/structure/flora/proc/play_cut_sound() + set waitfor = FALSE if(snd_cut) playsound(src, snd_cut, 40, TRUE) + +/obj/structure/flora/proc/cut_down(var/obj/item/I, var/mob/user) + dismantle() return TRUE diff --git a/code/game/objects/structures/flora/plant.dm b/code/game/objects/structures/flora/plant.dm index 97b2ed7aaa8..9bf6c82198e 100644 --- a/code/game/objects/structures/flora/plant.dm +++ b/code/game/objects/structures/flora/plant.dm @@ -8,6 +8,10 @@ var/datum/seed/plant var/harvestable +/obj/structure/flora/plant/large + opacity = TRUE + density = TRUE + /* Notes for future work moving logic off hydrotrays onto plants themselves: /obj/structure/flora/plant/Process() // check our immediate environment diff --git a/code/game/objects/structures/flora/stump.dm b/code/game/objects/structures/flora/stump.dm index 38e6c557eb1..667c4853a3b 100644 --- a/code/game/objects/structures/flora/stump.dm +++ b/code/game/objects/structures/flora/stump.dm @@ -2,7 +2,9 @@ // Stumps //////////////////////////////////////// /obj/structure/flora/stump - name = "stump" + name = "stump" + hitsound = 'sound/effects/hit_wood.ogg' + var/log_type = /obj/item/stack/material/log /obj/structure/flora/stump/get_material_health_modifier() return 2.5 //Make stumps worth removing with shovels instead of bashing them @@ -14,6 +16,11 @@ if(I.do_tool_interaction(TOOL_SHOVEL, user, src, 8 SECONDS)) . = ..() +/obj/structure/flora/stump/create_dismantled_products(turf/T) + if(log_type) + new /obj/item/stack/material/log(T, rand(2,3), material?.type, reinf_material?.type) + . = ..() + //Base tree stump /obj/structure/flora/stump/tree name = "tree stump" @@ -40,3 +47,27 @@ //christmas tree /obj/structure/flora/stump/tree/pine/xmas icon_state = "pine_c" + +/obj/structure/flora/stump/tree/towercap + icon_state = "towercap_1" + material = /decl/material/solid/organic/wood/fungal + +/obj/structure/flora/stump/tree/ebony + icon_state = "ebony_1" + material = /decl/material/solid/organic/wood/ebony + +/obj/structure/flora/stump/tree/mahogany + icon_state = "mahogany_1" + material = /decl/material/solid/organic/wood/mahogany + +/obj/structure/flora/stump/tree/maple + icon_state = "maple_1" + material = /decl/material/solid/organic/wood/maple + +/obj/structure/flora/stump/tree/yew + icon_state = "yew_1" + material = /decl/material/solid/organic/wood/yew + +/obj/structure/flora/stump/tree/walnut + icon_state = "walnut_1" + material = /decl/material/solid/organic/wood/walnut diff --git a/code/game/objects/structures/flora/tree.dm b/code/game/objects/structures/flora/tree.dm index 232c5615606..70d422b42f4 100644 --- a/code/game/objects/structures/flora/tree.dm +++ b/code/game/objects/structures/flora/tree.dm @@ -11,8 +11,16 @@ w_class = ITEM_SIZE_STRUCTURE hitsound = 'sound/effects/hit_wood.ogg' snd_cut = 'sound/effects/plants/tree_fall.ogg' + + /// What kind of log we leave behind. + var/log_type = /obj/item/stack/material/log + /// Whether or not you can shelter under this tree. var/protects_against_weather = TRUE - var/stump_type //What kind of tree stump we're leaving behind + /// What kind of tree stump we leaving behind. + var/stump_type + /// How much to shake the tree when struck. + /// Larger trees should have smaller numbers or it looks weird. + var/shake_animation_degrees = 4 /obj/structure/flora/tree/get_material_health_modifier() return 2.5 //Prefer removing via tools than bashing @@ -24,12 +32,42 @@ if(I.do_tool_interaction(TOOL_HATCHET, user, src, 5 SECONDS)) . = ..() -/obj/structure/flora/tree/dismantle() - var/turf/T = get_turf(src) - if(T) +/obj/structure/flora/tree/take_damage(damage) + . = ..() + if(!QDELETED(src) && damage >= 5) + shake() + +// We chop several times to cut down a tree. +/obj/structure/flora/tree/play_cut_sound() + shake() + for(var/i = 1 to 5) + sleep(1 SECOND) + if(QDELETED(src)) + return + shake() + playsound(src, 'sound/items/axe_wood.ogg', 40, TRUE) + sleep(1 SECOND) + if(QDELETED(src)) + return + return ..() + +// Tree shake animation stolen from Polaris. +/obj/structure/flora/tree/proc/shake() + set waitfor = FALSE + var/init_px = pixel_x + var/shake_dir = pick(-1, 1) + var/matrix/M = matrix() + M.Scale(icon_scale_x, icon_scale_y) + M.Translate(0, 16*(icon_scale_y-1)) + animate(src, transform=turn(M, shake_animation_degrees * shake_dir), pixel_x=init_px + 2*shake_dir, time=1) + animate(transform=M, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + +/obj/structure/flora/tree/create_dismantled_products(turf/T) + if(log_type) + new log_type(T, rand(3,5), material?.type, reinf_material?.type) + if(stump_type) var/obj/structure/flora/stump/stump = new stump_type(T, material, reinf_material) - if(istype(stump)) - stump.icon_state = icon_state //A bit dirty maybe, but its probably not worth writing a whole system for this when we have 3 kinds of trees.. + stump.icon_state = icon_state //A bit dirty maybe, but its probably not worth writing a whole system for this when we have 3 kinds of trees.. . = ..() /obj/structure/flora/tree/pine @@ -60,5 +98,64 @@ protects_against_weather = FALSE stump_type = /obj/structure/flora/stump/tree/dead -/obj/structure/flora/tree/dead/init_appearance() +/obj/structure/flora/tree/dead/random/init_appearance() icon_state = "tree_[rand(1, 6)]" + +/obj/structure/flora/tree/dead/ebony + icon_state = "dead_ebony_1" + +/obj/structure/flora/tree/dead/mahogany + icon_state = "dead_mahogany_1" + +/obj/structure/flora/tree/dead/walnut + icon_state = "dead_walnut_1" + +/obj/structure/flora/tree/dead/maple + icon_state = "dead_maple_1" + +/obj/structure/flora/tree/dead/yew + icon_state = "dead_yew_1" + +/obj/structure/flora/tree/softwood + icon = 'icons/obj/flora/softwood.dmi' + abstract_type = /obj/structure/flora/tree/softwood + +/obj/structure/flora/tree/softwood/towercap + name = "towercap mushroom" + icon_state = "towercap_1" + material = /decl/material/solid/organic/wood/fungal + stump_type = /obj/structure/flora/stump/tree/towercap + +/obj/structure/flora/tree/hardwood + icon = 'icons/obj/flora/hardwood.dmi' + abstract_type = /obj/structure/flora/tree/hardwood + +/obj/structure/flora/tree/hardwood/ebony + name = "ebony tree" + icon_state = "ebony_1" + material = /decl/material/solid/organic/wood/ebony + stump_type = /obj/structure/flora/stump/tree/ebony + +/obj/structure/flora/tree/hardwood/mahogany + name = "mahogany tree" + icon_state = "mahogany_1" + material = /decl/material/solid/organic/wood/mahogany + stump_type = /obj/structure/flora/stump/tree/mahogany + +/obj/structure/flora/tree/hardwood/maple + name = "maple tree" + icon_state = "maple_1" + material = /decl/material/solid/organic/wood/maple + stump_type = /obj/structure/flora/stump/tree/maple + +/obj/structure/flora/tree/hardwood/yew + name = "yew tree" + icon_state = "yew_1" + material = /decl/material/solid/organic/wood/yew + stump_type = /obj/structure/flora/stump/tree/yew + +/obj/structure/flora/tree/hardwood/walnut + name = "walnut tree" + icon_state = "walnut_1" + material = /decl/material/solid/organic/wood/walnut + stump_type = /obj/structure/flora/stump/tree/walnut diff --git a/code/game/objects/structures/fountain.dm b/code/game/objects/structures/fountain.dm index 7d4197d0b38..78247136d23 100644 --- a/code/game/objects/structures/fountain.dm +++ b/code/game/objects/structures/fountain.dm @@ -74,7 +74,7 @@ else to_chat(user, "You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.") user.became_older = TRUE - user.change_hair_color(80, 80, 80) + user.set_hair_colour(COLOR_GRAY80) var/max_age = age.standalone_value_descriptors[age.standalone_value_descriptors[length(age.standalone_value_descriptors)]] if(new_age >= max_age) to_chat(user, "The burden of the years is too much, and you are reduced to dust.") @@ -102,7 +102,7 @@ . = ..() /obj/structure/fountain/mundane/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) //Don't give free water when building one + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) //Don't give free water when building one /obj/structure/fountain/mundane/attack_hand(mob/user) if(user.a_intent == I_HURT) diff --git a/code/game/objects/structures/fuel_port.dm b/code/game/objects/structures/fuel_port.dm index ef1de75d390..4e5589fd37e 100644 --- a/code/game/objects/structures/fuel_port.dm +++ b/code/game/objects/structures/fuel_port.dm @@ -7,7 +7,7 @@ density = FALSE anchored = TRUE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/open = FALSE var/parent_shuttle diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 0acc26f3654..7b710028860 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -75,19 +75,32 @@ check_environment() /obj/structure/inflatable/proc/check_environment() - var/min_pressure = INFINITY - var/max_pressure = 0 - var/max_local_temp = 0 - for(var/check_dir in global.cardinal) - var/turf/T = get_step(get_turf(src), check_dir) - var/datum/gas_mixture/env = T.return_air() - var/pressure = env.return_pressure() - min_pressure = min(min_pressure, pressure) - max_pressure = max(max_pressure, pressure) - max_local_temp = max(max_local_temp, env.temperature) + var/turf/my_turf = get_turf(src) + if(!my_turf || !prob(50)) + return - if(prob(50) && (max_pressure - min_pressure > max_pressure_diff || max_local_temp > max_temp)) + var/airblock // zeroed by ATMOS_CANPASS_TURF + var/max_local_temp = 0 + var/take_environment_damage = get_surrounding_pressure_differential(my_turf, src) > max_pressure_diff + if(!take_environment_damage) + for(var/check_dir in global.cardinal) + var/turf/neighbour = get_step(my_turf, check_dir) + if(!istype(neighbour)) + continue + for(var/obj/O in my_turf) + if(O == src) + continue + ATMOS_CANPASS_MOVABLE(airblock, O, neighbour) + . |= airblock + if(airblock & AIR_BLOCKED) + continue + ATMOS_CANPASS_TURF(airblock, neighbour, my_turf) + if(airblock & AIR_BLOCKED) + continue + max_local_temp = max(max_local_temp, neighbour.return_air()?.temperature) + + if(take_environment_damage || max_local_temp > max_temp) take_damage(1) /obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) diff --git a/code/game/objects/structures/ironing_board.dm b/code/game/objects/structures/ironing_board.dm index fe42db90178..473f91bb780 100644 --- a/code/game/objects/structures/ironing_board.dm +++ b/code/game/objects/structures/ironing_board.dm @@ -31,7 +31,7 @@ holding = null update_icon() - events_repository.unregister(/decl/observ/destroyed, I, src, /obj/structure/bed/roller/ironingboard/proc/remove_item) + events_repository.unregister(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) // make a screeching noise to drive people mad /obj/structure/bed/roller/ironingboard/Move() @@ -76,7 +76,7 @@ if(user.try_unequip(I, src)) cloth = I - events_repository.register(/decl/observ/destroyed, I, src, /obj/structure/bed/roller/ironingboard/proc/remove_item) + events_repository.register(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) update_icon() return else if(istype(I,/obj/item/ironingiron)) @@ -101,7 +101,7 @@ if(!cloth) if(!holding && !R.enabled && user.try_unequip(I, src)) holding = R - events_repository.register(/decl/observ/destroyed, I, src, /obj/structure/bed/roller/ironingboard/proc/remove_item) + events_repository.register(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) update_icon() return to_chat(user, "There isn't anything on the ironing board.") @@ -150,4 +150,5 @@ name = "ironing board" desc = "A collapsed ironing board that can be carried around." icon = 'icons/obj/structures/ironing.dmi' + icon_state = "folded" structure_form_type = /obj/structure/bed/roller/ironingboard \ No newline at end of file diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 6dd17b9b4b7..fcbef17ee5d 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -174,8 +174,10 @@ name = "janicart" icon = 'icons/obj/vehicles.dmi' icon_state = "pussywagon" + base_icon = "pussywagon" anchored = FALSE density = TRUE + material_alteration = MAT_FLAG_ALTERATION_NONE atom_flags = ATOM_FLAG_OPEN_CONTAINER buckle_layer_above = TRUE buckle_movable = TRUE diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index 3dad0c5b51d..69a056f2d2d 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -284,4 +284,4 @@ take_damage(max_health) // Fatboy user.jump_layer_shift() - addtimer(CALLBACK(user, /mob/living/proc/jump_layer_shift_end), 2) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, jump_layer_shift_end)), 2) diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 9c9347b085f..ce38bacadd5 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -94,7 +94,7 @@ layer = ABOVE_WINDOW_LAYER w_class = ITEM_SIZE_NORMAL obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'WEST':{'x':32}, 'EAST':{'x':-32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "WEST":{"x":32}, "EAST":{"x":-32}}' abstract_type = /obj/structure/sign parts_type = /obj/item/sign parts_amount = 1 diff --git a/code/game/objects/structures/signs/bar_signs.dm b/code/game/objects/structures/signs/bar_signs.dm index 917bf4c3b05..51396fea7bb 100644 --- a/code/game/objects/structures/signs/bar_signs.dm +++ b/code/game/objects/structures/signs/bar_signs.dm @@ -5,7 +5,7 @@ //The sign is 64x32, so it needs two tiles. ;3 icon = 'icons/obj/signs/bar.dmi' //The bar sign always faces south - directional_offset = "{'NORTH':{'y':32}, 'SOUTH':{'y':32}, 'WEST':{'y':32}, 'EAST':{'y':32}}" + directional_offset = @'{"NORTH":{"y":32}, "SOUTH":{"y":32}, "WEST":{"y":32}, "EAST":{"y":32}}' abstract_type = /obj/structure/sign/double/maltesefalcon /obj/structure/sign/double/maltesefalcon/left diff --git a/code/game/objects/structures/signs/direction_signs.dm b/code/game/objects/structures/signs/direction_signs.dm index 77b10cf104c..1b331afc994 100644 --- a/code/game/objects/structures/signs/direction_signs.dm +++ b/code/game/objects/structures/signs/direction_signs.dm @@ -9,7 +9,7 @@ icon = 'icons/obj/signs/directions.dmi' icon_state = "direction" //Direction signs are always meant to face south! The arrow on the sign matches the direction it points to. - directional_offset = "{'NORTH':{'y':32}, 'SOUTH':{'y':32}, 'WEST':{'y':32}, 'EAST':{'y':32}}" + directional_offset = @'{"NORTH":{"y":32}, "SOUTH":{"y":32}, "WEST":{"y":32}, "EAST":{"y":32}}' /obj/structure/sign/directions/update_description() desc = "A direction sign, pointing out \the [name] is [global.dir_name(dir)]." diff --git a/code/game/objects/structures/signs/warning_signs.dm b/code/game/objects/structures/signs/warning_signs.dm index e11bafb614d..7165a62c8a0 100644 --- a/code/game/objects/structures/signs/warning_signs.dm +++ b/code/game/objects/structures/signs/warning_signs.dm @@ -8,7 +8,7 @@ desc = "You've been warned!" icon = 'icons/obj/signs/slim_warnings.dmi' icon_state = "securearea" - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'WEST':{'x':34}, 'EAST':{'x':-34}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "WEST":{"x":34}, "EAST":{"x":-34}}' /obj/structure/sign/warning/update_description() desc = "A warning sign which reads '[sanitize(name)]'." diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm index 197a92739aa..bd1d1fa3813 100644 --- a/code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm @@ -1,4 +1,5 @@ -/obj/structure/bed/chair //YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete +//YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete +/obj/structure/bed/chair name = "chair" desc = "You sit in this, either by will or force." icon_state = "chair_preview" @@ -265,9 +266,9 @@ /obj/structure/bed/chair/shuttle/post_buckle_mob() if(buckled_mob) - icon_state = "shuttle_chair-b" + base_icon = "shuttle_chair-b" else - icon_state = "shuttle_chair" + base_icon = "shuttle_chair" ..() /obj/structure/bed/chair/shuttle/blue diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index b9c5cca488b..07d1f16441a 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -28,8 +28,8 @@ T.pixel_x = 0 T.pixel_y = 0 T.layer = ABOVE_OBJ_LAYER - events_repository.register(/decl/observ/moved, T, src, /atom/movable/proc/move_to_turf) - events_repository.register(/decl/observ/moved, src, T, /atom/movable/proc/move_to_turf) + events_repository.register(/decl/observ/moved, T, src, TYPE_PROC_REF(/atom/movable, move_to_turf)) + events_repository.register(/decl/observ/moved, src, T, TYPE_PROC_REF(/atom/movable, move_to_turf)) T.stake = src pinned_target = T else diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm index c49e81e6844..ff844e19d4f 100644 --- a/code/game/objects/structures/under_wardrobe.dm +++ b/code/game/objects/structures/under_wardrobe.dm @@ -27,7 +27,7 @@ var/number_of_underwear = LAZYACCESS(amount_of_underwear_by_id_card, id) - 1 if(number_of_underwear) LAZYSET(amount_of_underwear_by_id_card, id, number_of_underwear) - events_repository.register(/decl/observ/destroyed, id, src, /obj/structure/undies_wardrobe/proc/remove_id_card) + events_repository.register(/decl/observ/destroyed, id, src, TYPE_PROC_REF(/obj/structure/undies_wardrobe, remove_id_card)) else remove_id_card(id) @@ -36,7 +36,7 @@ /obj/structure/undies_wardrobe/proc/remove_id_card(var/id_card) LAZYREMOVE(amount_of_underwear_by_id_card, id_card) - events_repository.unregister(/decl/observ/destroyed, id_card, src, /obj/structure/undies_wardrobe/proc/remove_id_card) + events_repository.unregister(/decl/observ/destroyed, id_card, src, TYPE_PROC_REF(/obj/structure/undies_wardrobe, remove_id_card)) /obj/structure/undies_wardrobe/attack_hand(var/mob/user) if(!human_who_can_use_underwear(user)) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 6326179e418..0819be84d95 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -75,11 +75,9 @@ var/global/list/hygiene_props = list() visible_message("\The [src] gurgles and overflows!") next_gurgle = world.time + 80 playsound(T, pick(SSfluids.gurgles), 50, 1) - var/obj/effect/fluid/F = locate() in T - var/adding = min(flood_amt-F?.reagents.total_volume, rand(30,50)*clogged) + var/adding = min(flood_amt-T?.reagents?.total_volume, rand(30,50)*clogged) if(adding > 0) - if(!F) F = new(T) - F.reagents.add_reagent(/decl/material/liquid/water, adding) + T.add_to_reagents(/decl/material/liquid/water, adding) /obj/structure/hygiene/proc/drain() if(!can_drain) return @@ -208,7 +206,7 @@ var/global/list/hygiene_props = list() icon_state = "urinal" density = FALSE anchored = TRUE - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED /obj/structure/hygiene/urinal/attackby(var/obj/item/I, var/mob/user) @@ -285,7 +283,7 @@ var/global/list/hygiene_props = list() /obj/effect/mist/Initialize() . = ..() if(delete_self && . != INITIALIZE_HINT_QDEL) - addtimer(CALLBACK(src, /datum/proc/qdel_self), 25 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, qdel_self)), 25 SECONDS) /obj/effect/mist/permanent delete_self = FALSE @@ -330,7 +328,7 @@ var/global/list/hygiene_props = list() for(var/thing in loc.get_contained_external_atoms()) wash_mob(thing) process_heat(thing) - reagents.add_reagent(/decl/material/liquid/water, REAGENTS_FREE_SPACE(reagents)) + add_to_reagents(/decl/material/liquid/water, REAGENTS_FREE_SPACE(reagents)) if(world.time >= next_wash) next_wash = world.time + (10 SECONDS) reagents.splash(get_turf(src), reagents.total_volume, max_spill = 0) @@ -392,7 +390,7 @@ var/global/list/hygiene_props = list() return TRUE busy = FALSE - user.clean_blood() + user.clean() user.visible_message( SPAN_NOTICE("\The [user] washes their hands using \the [src]."), SPAN_NOTICE("You wash your hands using \the [src].")) @@ -412,7 +410,7 @@ var/global/list/hygiene_props = list() SPAN_NOTICE("\The [user] fills \the [RG] using \the [src]."), SPAN_NOTICE("You fill \the [RG] using \the [src].")) playsound(loc, 'sound/effects/sink.ogg', 75, 1) - RG.reagents.add_reagent(/decl/material/liquid/water, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + RG.add_to_reagents(/decl/material/liquid/water, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) return 1 else if (istype(O, /obj/item/baton)) @@ -436,7 +434,7 @@ var/global/list/hygiene_props = list() return 1 else if(istype(O, /obj/item/mop)) if(REAGENTS_FREE_SPACE(O.reagents) >= 5) - O.reagents.add_reagent(/decl/material/liquid/water, 5) + O.add_to_reagents(/decl/material/liquid/water, 5) to_chat(user, SPAN_NOTICE("You wet \the [O] in \the [src].")) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else @@ -460,7 +458,7 @@ var/global/list/hygiene_props = list() if(istype(O, /obj/item/chems/spray/extinguisher)) return TRUE // We're washing, not filling. - O.clean_blood() + O.clean() user.visible_message( \ SPAN_NOTICE("\The [user] washes \a [I] using \the [src]."), SPAN_NOTICE("You wash \a [I] using \the [src].")) @@ -589,7 +587,7 @@ var/global/list/hygiene_props = list() next_gurgle = world.time + 80 playsound(T, pick(SSfluids.gurgles), 50, 1) - T.add_fluid(/decl/material/liquid/water, min(75, fill_level - T.get_fluid_depth())) + T.add_to_reagents(/decl/material/liquid/water, min(75, fill_level - T.get_fluid_depth())) /obj/structure/hygiene/faucet/Process() ..() diff --git a/code/game/turfs/exterior/_exterior.dm b/code/game/turfs/exterior/_exterior.dm index da3284962f2..60618d73025 100644 --- a/code/game/turfs/exterior/_exterior.dm +++ b/code/game/turfs/exterior/_exterior.dm @@ -4,7 +4,7 @@ footstep_type = /decl/footsteps/asteroid icon_state = "0" layer = PLATING_LAYER - open_turf_type = /turf/exterior/open + open_turf_type = /turf/open turf_flags = TURF_FLAG_BACKGROUND | TURF_IS_HOLOMAP_PATH zone_membership_candidate = TRUE var/base_color diff --git a/code/game/turfs/exterior/exterior_concrete.dm b/code/game/turfs/exterior/exterior_concrete.dm index cd50d2256e7..3c6d7035ac2 100644 --- a/code/game/turfs/exterior/exterior_concrete.dm +++ b/code/game/turfs/exterior/exterior_concrete.dm @@ -21,7 +21,7 @@ var/global/exterior_broken_states = icon_states('icons/turf/exterior/broken.dmi' return FALSE /turf/exterior/concrete/flooded - flooded = TRUE + flooded = /decl/material/liquid/water color = COLOR_LIQUID_WATER /turf/exterior/concrete/Initialize(var/ml) diff --git a/code/game/turfs/exterior/exterior_mud.dm b/code/game/turfs/exterior/exterior_mud.dm index 018ff3548da..0479187e009 100644 --- a/code/game/turfs/exterior/exterior_mud.dm +++ b/code/game/turfs/exterior/exterior_mud.dm @@ -9,7 +9,7 @@ return dug ? null : list(/obj/item/stack/material/ore/clay = list(3, 2)) /turf/exterior/clay/flooded - flooded = TRUE + flooded = /decl/material/liquid/water /turf/exterior/mud name = "mud" @@ -19,7 +19,7 @@ footstep_type = /decl/footsteps/mud /turf/exterior/mud/flooded - flooded = TRUE + flooded = /decl/material/liquid/water /turf/exterior/dry name = "dry mud" diff --git a/code/game/turfs/exterior/exterior_ocean.dm b/code/game/turfs/exterior/exterior_ocean.dm index a78e1e0bbf6..aeae32c2b25 100644 --- a/code/game/turfs/exterior/exterior_ocean.dm +++ b/code/game/turfs/exterior/exterior_ocean.dm @@ -2,5 +2,5 @@ name = "open ocean" icon = 'icons/turf/exterior/ocean_deep.dmi' icon_state = "0" - flooded = TRUE + flooded = /decl/material/liquid/water icon_edge_layer = EXT_EDGE_OCEAN \ No newline at end of file diff --git a/code/game/turfs/exterior/exterior_seafloor.dm b/code/game/turfs/exterior/exterior_seafloor.dm index 97b8cd64262..3c58eb85336 100644 --- a/code/game/turfs/exterior/exterior_seafloor.dm +++ b/code/game/turfs/exterior/exterior_seafloor.dm @@ -9,7 +9,7 @@ return dug ? null : list(/obj/item/stack/material/ore/sand = list(3, 2)) /turf/exterior/seafloor/flooded - flooded = TRUE + flooded = /decl/material/liquid/water color = COLOR_LIQUID_WATER /turf/exterior/seafloor/Initialize() diff --git a/code/game/turfs/exterior/exterior_sky.dm b/code/game/turfs/exterior/exterior_sky.dm index f346d3acd3f..9660d5353ad 100644 --- a/code/game/turfs/exterior/exterior_sky.dm +++ b/code/game/turfs/exterior/exterior_sky.dm @@ -1,37 +1,37 @@ -/turf/exterior/open/sky +/turf/open/sky name = "sky" desc = "Hope you don't have a fear of heights..." icon = 'icons/turf/exterior/sky_static.dmi' icon_state = "0" - z_flags = ZM_PARTITION_STACK + z_flags = ZM_TERMINATOR // No matter what, the sky will never be 'inside'. /turf/exterior/open/sky/is_outside() return TRUE // you can't take the sky from meee -/turf/exterior/open/sky/north +/turf/open/sky/north dir = NORTH -/turf/exterior/open/sky/south +/turf/open/sky/south dir = SOUTH -/turf/exterior/open/sky/west +/turf/open/sky/west dir = WEST -/turf/exterior/open/sky/east +/turf/open/sky/east dir = EAST -/turf/exterior/open/sky/moving +/turf/open/sky/moving icon = 'icons/turf/exterior/sky_slow.dmi' -/turf/exterior/open/sky/moving/north +/turf/open/sky/moving/north dir = NORTH -/turf/exterior/open/sky/moving/south +/turf/open/sky/moving/south dir = SOUTH -/turf/exterior/open/sky/moving/west +/turf/open/sky/moving/west dir = WEST -/turf/exterior/open/sky/moving/east +/turf/open/sky/moving/east dir = EAST diff --git a/code/game/turfs/exterior/exterior_wall.dm b/code/game/turfs/exterior/exterior_wall.dm index 856fe356cde..50a2538c158 100644 --- a/code/game/turfs/exterior/exterior_wall.dm +++ b/code/game/turfs/exterior/exterior_wall.dm @@ -3,6 +3,46 @@ ///List of all the /turf/exterior/wall that exists in the world on all z-levels var/global/list/natural_walls = list() +/obj/abstract/ramp_sculptor + name = "ramp sculptor" + icon_state = "x" + var/place_dir + +/obj/abstract/ramp_sculptor/south + icon_state = "arrow" + dir = SOUTH + place_dir = SOUTH + +/obj/abstract/ramp_sculptor/north + icon_state = "arrow" + dir = NORTH + place_dir = NORTH + +/obj/abstract/ramp_sculptor/east + icon_state = "arrow" + dir = EAST + place_dir = EAST + +/obj/abstract/ramp_sculptor/west + icon_state = "arrow" + dir = WEST + place_dir = WEST + +/obj/abstract/ramp_sculptor/Initialize() + ..() + var/turf/exterior/wall/ramp = get_turf(src) + if(istype(ramp) && !ramp.ramp_slope_direction) + if(!place_dir || !(place_dir in global.cardinal)) + for(var/checkdir in global.cardinal) + var/turf/neighbor = get_step(ramp, checkdir) + if(neighbor && neighbor.density) + place_dir = global.reverse_dir[checkdir] + break + if(place_dir) + dir = place_dir + ramp.make_ramp(null, place_dir) + return INITIALIZE_HINT_QDEL + /turf/exterior/wall name = "wall" icon = 'icons/turf/walls/_previews.dmi' @@ -13,6 +53,7 @@ var/global/list/natural_walls = list() blocks_air = TRUE turf_flags = TURF_FLAG_BACKGROUND | TURF_IS_HOLOMAP_OBSTACLE + var/ramp_slope_direction var/paint_color var/image/ore_overlay var/decl/material/reinf_material @@ -24,13 +65,99 @@ var/global/list/natural_walls = list() if(paint_color) to_chat(user, SPAN_NOTICE("It has been noticeably discoloured by the elements.")) +/turf/exterior/wall/AltClick(mob/user) + + if(user.Adjacent(src) && istype(user.get_active_hand(), /obj/item/pickaxe) && HasAbove(z)) + var/user_dir = get_dir(src, user) + if(!(user_dir in global.cardinal)) + to_chat(user, SPAN_WARNING("You must be standing at a cardinal angle to create a ramp.")) + return TRUE + + var/turf/exterior/wall/support = get_step(src, global.reverse_dir[user_dir]) + if(!istype(support) || support.ramp_slope_direction) + to_chat(user, SPAN_WARNING("You cannot cut a ramp into a wall with no additional walls behind it.")) + return TRUE + + var/obj/item/pickaxe/P = user.get_active_hand() + playsound(user, P.drill_sound, 20, 1) + to_chat(user, SPAN_NOTICE("You start [P.drill_verb] \the [src], forming it into a ramp.")) + if(do_after(user, round(P.digspeed*0.5), src) && !ramp_slope_direction) + to_chat(user, SPAN_NOTICE("You finish [P.drill_verb] \the [src] into a ramp.")) + make_ramp(user, user_dir) + return TRUE + + . = ..() + +/turf/proc/handle_ramp_dug_below(turf/exterior/wall/ramp) + if(simulated && !is_open()) + ChangeTurf(get_base_turf(z)) + +/turf/exterior/wall/proc/make_ramp(var/mob/user, var/new_slope, var/skip_icon_update = FALSE) + + ramp_slope_direction = new_slope + + var/old_ao = permit_ao + if(ramp_slope_direction) + drop_ore() + permit_ao = FALSE + blocks_air = FALSE + density = FALSE + opacity = FALSE + + // Pretend to be a normal floor turf under the ramp. + var/turf/exterior/under = floor_type + icon = initial(under.icon) + icon_state = initial(under.icon_state) + icon_edge_layer = initial(under.icon_edge_layer) + icon_edge_states = initial(under.icon_edge_states) + icon_has_corners = initial(under.icon_has_corners) + color = initial(under.color) + + decals = null + var/turf/ramp_above = GetAbove(src) + if(ramp_above) + ramp_above.handle_ramp_dug_below(src) + update_neighboring_ramps() + + else + permit_ao = initial(permit_ao) + blocks_air = initial(blocks_air) + density = initial(density) + color = initial(color) + set_opacity(!material || material.opacity >= 0.5) + + icon = 'icons/turf/walls/natural.dmi' + icon_state = "blank" + icon_edge_layer = initial(icon_edge_layer) + icon_edge_states = initial(icon_edge_states) + icon_has_corners = initial(icon_has_corners) + + if(!skip_icon_update) + for(var/turf/exterior/wall/neighbor in RANGE_TURFS(src, 1)) + neighbor.update_icon() + if(old_ao != permit_ao) + regenerate_ao() + +/turf/exterior/wall/proc/update_neighboring_ramps(destroying_self) + // Clear any ramps we were supporting. + for(var/turf/exterior/wall/neighbor in RANGE_TURFS(src, 1)) + if(!neighbor.ramp_slope_direction || neighbor == src) + continue + var/turf/exterior/wall/support = get_step(neighbor, global.reverse_dir[neighbor.ramp_slope_direction]) + if(!istype(support) || (destroying_self && support == src) || support.ramp_slope_direction) + neighbor.dismantle_wall(ramp_update = FALSE) // This will only occur on ramps, so no need to propagate to other ramps. + /turf/exterior/wall/Initialize(var/ml, var/materialtype, var/rmaterialtype) ..(ml, TRUE) // We update our own icon, no point doing it twice. - // Clear mapping icons. - icon = 'icons/turf/walls/solid.dmi' - icon_state = "blank" + // Clear mapped appearance. color = null + icon = 'icons/turf/walls/natural.dmi' + icon_state = "blank" + + // Init ramp state if needed. + if(ramp_slope_direction) + make_ramp(null, ramp_slope_direction, TRUE) // Init materials. material = SSmaterials.get_strata_material_type(src) @@ -46,13 +173,14 @@ var/global/list/natural_walls = list() reinf_material = rmaterialtype if(ispath(reinf_material, /decl/material)) reinf_material = GET_DECL(reinf_material) + . = INITIALIZE_HINT_LATELOAD /turf/exterior/wall/LateInitialize(var/ml) ..() update_material(!ml) spread_deposit() - if(floor_type && HasAbove(z)) + if(!ramp_slope_direction && floor_type && HasAbove(z)) var/turf/T = GetAbove(src) if(!istype(T, floor_type) && T.is_open()) T.ChangeTurf(floor_type, keep_air = TRUE) @@ -70,6 +198,8 @@ var/global/list/natural_walls = list() /turf/exterior/wall/Destroy() global.natural_walls -= src + if(!ramp_slope_direction) + update_neighboring_ramps(destroying_self = TRUE) . = ..() /turf/exterior/wall/proc/set_material(var/decl/material/newmaterial, var/decl/material/newrmaterial) @@ -101,29 +231,31 @@ var/global/list/natural_walls = list() /turf/exterior/wall/attackby(obj/item/W, mob/user, click_params) if(!user.check_dexterity(DEXTERITY_COMPLEX_TOOLS)) - return + return ..() - if(istype(W, /obj/item/depth_scanner)) - var/obj/item/depth_scanner/C = W - C.scan_atom(user, src) - return TRUE + if(!ramp_slope_direction) - if (istype(W, /obj/item/measuring_tape)) - var/obj/item/measuring_tape/P = W - user.visible_message(SPAN_NOTICE("\The [user] extends [P] towards [src]."),SPAN_NOTICE("You extend [P] towards [src].")) - if(do_after(user,10, src)) - to_chat(user, SPAN_NOTICE("\The [src] has been excavated to a depth of [excavation_level]cm.")) - return TRUE + if(istype(W, /obj/item/depth_scanner)) + var/obj/item/depth_scanner/C = W + C.scan_atom(user, src) + return TRUE - if(istype(W, /obj/item/pickaxe/xeno)) - return handle_xenoarch_tool_interaction(W, user) + if (istype(W, /obj/item/measuring_tape)) + var/obj/item/measuring_tape/P = W + user.visible_message(SPAN_NOTICE("\The [user] extends [P] towards [src]."),SPAN_NOTICE("You extend [P] towards [src].")) + if(do_after(user,10, src)) + to_chat(user, SPAN_NOTICE("\The [src] has been excavated to a depth of [excavation_level]cm.")) + return TRUE + + if(istype(W, /obj/item/pickaxe/xeno)) + return handle_xenoarch_tool_interaction(W, user) // Drill out natural walls. if(istype(W, /obj/item/pickaxe)) var/obj/item/pickaxe/P = W playsound(user, P.drill_sound, 20, 1) to_chat(user, SPAN_NOTICE("You start [P.drill_verb][destroy_artifacts(P, INFINITY)].")) - if(do_after(user, P.digspeed, src)) + if(do_after(user, (ramp_slope_direction ? round(P.digspeed*0.5) : P.digspeed), src)) to_chat(user, SPAN_NOTICE("You finish [P.drill_verb] \the [src].")) dismantle_wall() return TRUE @@ -166,21 +298,43 @@ var/global/list/natural_walls = list() var/turf/exterior/target_turf = get_step_resolving_mimic(src, direction) if(istype(target_turf)) target_turf.update_icon() - else - update_icon() + update_icon() /turf/exterior/wall/on_update_icon() - cut_overlays() - if(!istype(material)) return var/list/wall_connections = list() - for(var/direction in global.alldirs) - if(istype(get_step_resolving_mimic(src, direction), /turf/exterior/wall)) - wall_connections += direction - wall_connections = dirs_to_corner_states(wall_connections) + for(var/stepdir in global.alldirs) + + // Get the wall. + var/turf/exterior/wall/T = get_step_resolving_mimic(src, stepdir) + if(!istype(T)) + continue + + if(ramp_slope_direction) // We are a ramp. + // Adjacent ramps flowing in the same direction as us. + if(ramp_slope_direction == T.ramp_slope_direction) + wall_connections += stepdir + continue + // It's an adjacent non-ramp wall. + if(!T.ramp_slope_direction) + // It is behind us. + if(stepdir & global.reverse_dir[ramp_slope_direction]) + wall_connections += stepdir + continue + else // We are a wall. + // It is a wall. + if(!T.ramp_slope_direction) + wall_connections += stepdir + continue + // It's a ramp running away from us. + if(stepdir & T.ramp_slope_direction) + wall_connections += stepdir + continue + + var/list/corner_states = dirs_to_corner_states(wall_connections) var/material_icon_base = material.icon_base_natural || 'icons/turf/walls/natural.dmi' var/base_color = paint_color ? paint_color : material.color @@ -194,9 +348,43 @@ var/global/list/natural_walls = list() shine = clamp((material.reflectiveness * 0.01) * 255, 10, (0.6 * ReadHSV(RGBtoHSV(material.color))[3])) exterior_wall_shine_cache[shine_cache_key] = shine - icon = get_combined_wall_icon(wall_connections, null, material_icon_base, base_color, shine_value = shine) - icon_state = "" - color = null + var/new_icon + if(ramp_slope_direction) + + ..() // Draw the floor under us. + + var/turf/exterior/wall/neighbor = get_step(src, turn(ramp_slope_direction, -90)) + var/has_left_neighbor = istype(neighbor) && neighbor.ramp_slope_direction == ramp_slope_direction + neighbor = get_step(src, turn(ramp_slope_direction, 90)) + var/has_right_neighbor = istype(neighbor) && neighbor.ramp_slope_direction == ramp_slope_direction + + var/state = "ramp-single" + if(has_left_neighbor && has_right_neighbor) + state = "ramp-blend-full" + else if(has_left_neighbor) + state = "ramp-blend-left" + else if(has_right_neighbor) + state = "ramp-blend-right" + + var/image/I = image(material_icon_base, state, dir = ramp_slope_direction) + I.color = base_color + I.appearance_flags |= RESET_COLOR + add_overlay(I) + if(shine) + I = image(material_icon_base, "[state]-shine", dir = ramp_slope_direction) + I.appearance_flags |= RESET_ALPHA + I.alpha = shine + add_overlay(I) + + else + + new_icon = get_combined_wall_icon(corner_states, null, material_icon_base, base_color, shine_value = shine) + if(icon != new_icon) + icon = new_icon + if(icon_state != "") + icon_state = "" + if(color) + color = null if(ore_overlay) add_overlay(ore_overlay) @@ -205,35 +393,53 @@ var/global/list/natural_walls = list() if(archaeo_overlay) add_overlay(archaeo_overlay) -/turf/exterior/wall/proc/dismantle_wall(no_product = FALSE) - if(reinf_material?.ore_result_amount && !no_product) +/turf/exterior/wall/proc/drop_ore() + if(reinf_material?.ore_result_amount) pass_geodata_to(new /obj/item/stack/material/ore(src, reinf_material.ore_result_amount, reinf_material.type)) - if(prob(MAT_DROP_CHANCE) && !no_product) - pass_geodata_to(new /obj/item/stack/material/ore(src, 1, material.type)) + reinf_material = null + ore_overlay = null + update_material(FALSE) + if(prob(MAT_DROP_CHANCE) && !ramp_slope_direction && material) + pass_geodata_to(new /obj/item/stack/material/ore(src, material.ore_result_amount, material.type)) + +/turf/exterior/wall/proc/dismantle_wall(no_product = FALSE, ramp_update = TRUE) + + if(!no_product) + drop_ore() destroy_artifacts(null, INFINITY) + + if(ramp_update && !ramp_slope_direction) + ramp_slope_direction = NORTH // Temporary so we don't let any neighboring ramps use us as supports. + update_neighboring_ramps() + ramp_slope_direction = null + playsound(src, 'sound/items/Welder.ogg', 100, 1) - . = ChangeTurf(floor_type || get_base_turf_by_area(src)) - if(istype(., /turf/simulated/floor/asteroid)) + var/turf/new_turf = ChangeTurf(floor_type || get_base_turf_by_area(src)) + if(istype(new_turf, /turf/simulated/floor/asteroid)) var/turf/simulated/floor/asteroid/debris = . debris.overlay_detail = "asteroid[rand(0,9)]" debris.updateMineralOverlays(1) + return new_turf /turf/exterior/wall/proc/get_default_material() . = /decl/material/solid/stone/sandstone -/turf/exterior/wall/Bumped(AM) +/turf/exterior/wall/proc/pass_geodata_to(obj/O) + var/datum/extension/geological_data/ours = get_extension(src, /datum/extension/geological_data) + if(ours.geodata) + ours.geodata.UpdateNearbyArtifactInfo(src) + set_extension(O, /datum/extension/geological_data) + var/datum/extension/geological_data/newdata = get_extension(O, /datum/extension/geological_data) + if(newdata) + newdata.set_data(ours.geodata.get_copy()) + +/turf/exterior/wall/Bumped(var/atom/movable/AM) . = ..() - if(ismob(AM)) + if(!. && !ramp_slope_direction && ismob(AM)) var/mob/M = AM var/obj/item/pickaxe/held = M.get_active_hand() if(istype(held)) attackby(held, M) - -/turf/exterior/wall/proc/pass_geodata_to(obj/O) - var/datum/extension/geological_data/ours = get_extension(src, /datum/extension/geological_data) - ours.geodata.UpdateNearbyArtifactInfo(src) - set_extension(O, /datum/extension/geological_data) - var/datum/extension/geological_data/newdata = get_extension(O, /datum/extension/geological_data) - newdata.set_data(ours.geodata.get_copy()) + return TRUE #undef MAT_DROP_CHANCE \ No newline at end of file diff --git a/code/game/turfs/exterior/exterior_water.dm b/code/game/turfs/exterior/exterior_water.dm index d273ef0aad3..3de037b1dcd 100644 --- a/code/game/turfs/exterior/exterior_water.dm +++ b/code/game/turfs/exterior/exterior_water.dm @@ -17,7 +17,7 @@ to_chat(user, SPAN_WARNING("\The [O] is full.")) return TRUE user.visible_message(SPAN_NOTICE("\The [user] fills \the [O] from \the [src]."), SPAN_NOTICE("You fill \the [O] from \the [src].")) - O.reagents.add_reagent(reagent_type, fill_amount) + O.add_to_reagents(reagent_type, fill_amount) return TRUE . = ..() diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 8b418c2f7ae..a8ea2dcc71c 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -37,8 +37,10 @@ //How we smooth with other flooring var/decal_layer = DECAL_LAYER var/floor_smooth = SMOOTH_ALL - var/list/flooring_whitelist = list() //Smooth with nothing except the contents of this list - var/list/flooring_blacklist = list() //Smooth with everything except the contents of this list + /// Smooth with nothing except the types in this list. Turned into a typecache for performance reasons. + var/list/flooring_whitelist = list() + /// Smooth with everything except the types in this list. Turned into a typecache for performance reasons. + var/list/flooring_blacklist = list() //How we smooth with walls var/wall_smooth = SMOOTH_ALL @@ -51,6 +53,11 @@ var/height = 0 +/decl/flooring/Initialize() + . = ..() + flooring_whitelist = typecacheof(flooring_whitelist) + flooring_blacklist = typecacheof(flooring_blacklist) + /decl/flooring/proc/on_remove() return diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index efbf13bea35..54921a96cc3 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -4,7 +4,7 @@ /decl/material/gas/oxygen = MOLES_O2STANDARD, /decl/material/gas/nitrogen = MOLES_N2STANDARD ) - open_turf_type = /turf/simulated/open + open_turf_type = /turf/open zone_membership_candidate = TRUE abstract_type = /turf/simulated @@ -14,7 +14,7 @@ var/timer_id // This is not great. -/turf/simulated/proc/wet_floor(var/wet_val = 1, var/overwrite = FALSE) +/turf/simulated/wet_floor(var/wet_val = 1, var/overwrite = FALSE) if(is_flooded(absolute = TRUE)) return @@ -30,21 +30,21 @@ wet_overlay = image('icons/effects/water.dmi',src,"wet_floor") overlays += wet_overlay - timer_id = addtimer(CALLBACK(src,/turf/simulated/proc/unwet_floor), 8 SECONDS, (TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE)) + timer_id = addtimer(CALLBACK(src, TYPE_PROC_REF(/turf, unwet_floor)), 8 SECONDS, (TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE)) -/turf/simulated/proc/unwet_floor(var/check_very_wet = TRUE) +/turf/simulated/unwet_floor(var/check_very_wet = TRUE) if(check_very_wet && wet >= 2) wet-- - timer_id = addtimer(CALLBACK(src,/turf/simulated/proc/unwet_floor), 8 SECONDS, (TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE)) + timer_id = addtimer(CALLBACK(src, TYPE_PROC_REF(/turf, unwet_floor)), 8 SECONDS, (TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE)) return wet = 0 if(wet_overlay) overlays -= wet_overlay wet_overlay = null -/turf/simulated/clean_blood() +/turf/simulated/clean(clean_forensics = TRUE) for(var/obj/effect/decal/cleanable/blood/B in contents) - B.clean_blood() + B.clean(clean_forensics) . = ..() /turf/simulated/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor=COLOR_BLOOD_HUMAN) @@ -160,14 +160,6 @@ return 1 //we bloodied the floor return 0 -// Only adds blood on the floor -- Skie -/turf/simulated/proc/add_blood_floor(mob/living/carbon/M) - if(isalien(M)) - var/obj/effect/decal/cleanable/blood/xeno/this = new /obj/effect/decal/cleanable/blood/xeno(src) - this.blood_DNA["UNKNOWN BLOOD"] = "X*" - else if(isrobot(M)) - new /obj/effect/decal/cleanable/blood/oil(src) - /turf/simulated/attackby(var/obj/item/thing, var/mob/user) if(IS_COIL(thing) && try_build_cable(thing, user)) return TRUE diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index f6be67f476e..7c3291cb61d 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -62,7 +62,7 @@ else disable_zmimic() - update_icon(1) + queue_icon_update(SSatoms.initialized) // only update neighbors if we're setting flooring after SSatoms has finished levelupdate() //This proc will set floor_type to null and the update_icon() proc will then change the icon_state of the turf diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index 76960d1a0f8..d468d73a55b 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -75,7 +75,7 @@ var/global/list/flooring_cache = list() if(update_neighbors) for(var/turf/simulated/floor/F in orange(src, 1)) F.queue_ao(FALSE) - F.update_icon() + F.queue_icon_update() /turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0, var/external = FALSE) if(!flooring_cache[cache_key]) @@ -107,45 +107,41 @@ var/global/list/flooring_cache = list() flooring_cache[cache_key] = I return flooring_cache[cache_key] -/decl/flooring/proc/test_link(var/turf/origin, var/turf/T) +/decl/flooring/proc/test_link(var/turf/origin, var/turf/opponent) var/is_linked = FALSE - if(istype(origin) && istype(T)) + if(istype(origin) && istype(opponent)) //is_wall is true for wall turfs and for floors containing a low wall - if(T.is_wall()) + if(opponent.is_wall()) if(wall_smooth == SMOOTH_ALL) is_linked = TRUE //If is_hole is true, then it's space or openspace - else if(T.is_open()) + else if(opponent.is_open()) if(space_smooth == SMOOTH_ALL) is_linked = TRUE //If we get here then its a normal floor - else if (istype(T, /turf/simulated/floor)) - var/turf/simulated/floor/t = T - //Check for window frames. - if(wall_smooth == SMOOTH_ALL) - for(var/obj/structure/wall_frame/WF in T.contents) - is_linked = TRUE + else if (istype(opponent, /turf/simulated/floor)) + var/turf/simulated/floor/floor_opponent = opponent //If the floor is the same as us,then we're linked, - if (istype(src, t.flooring)) + if (istype(src, floor_opponent.flooring)) is_linked = TRUE else if (floor_smooth == SMOOTH_ALL) is_linked = TRUE else if (floor_smooth != SMOOTH_NONE) //If we get here it must be using a whitelist or blacklist if (floor_smooth == SMOOTH_WHITELIST) - for (var/v in flooring_whitelist) - if (istype(t.flooring, v)) - //Found a match on the list - is_linked = TRUE - break + if (flooring_whitelist[floor_opponent.flooring.type]) + //Found a match on the typecache + is_linked = TRUE else if(floor_smooth == SMOOTH_BLACKLIST) is_linked = TRUE //Default to true for the blacklist, then make it false if a match comes up - for (var/v in flooring_blacklist) - if (istype(t.flooring, v)) - //Found a match on the list - is_linked = FALSE - break + if (flooring_blacklist[floor_opponent.flooring.type]) + //Found a match on the typecache + is_linked = FALSE + //Check for window frames. + if (!is_linked && wall_smooth == SMOOTH_ALL) + if(locate(/obj/structure/wall_frame) in opponent) + is_linked = TRUE return is_linked /decl/flooring/proc/symmetric_test_link(var/turf/A, var/turf/B) diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 44e9afff163..24ac21f38a2 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -158,7 +158,7 @@ var/obj/item/weldingtool/WT = W if(!WT.weld(0,user)) return - dismantle_verb = "cutting" + dismantle_verb = "cutting through" dismantle_sound = 'sound/items/Welder.ogg' cut_delay *= 0.7 @@ -178,7 +178,7 @@ if(!cutter.slice(user)) return TRUE dismantle_sound = "sparks" - dismantle_verb = "slicing" + dismantle_verb = "slicing through" cut_delay *= 0.5 else if(istype(W,/obj/item/pickaxe)) var/obj/item/pickaxe/P = W @@ -188,7 +188,7 @@ if(dismantle_verb) . = TRUE - to_chat(user, "You begin [dismantle_verb] through the outer plating.") + to_chat(user, "You begin [dismantle_verb] \the [src].") if(dismantle_sound) playsound(src, dismantle_sound, 100, 1) @@ -199,8 +199,8 @@ return to_chat(user, "You remove the outer plating.") + user.visible_message("\The [user] finishes [dismantle_verb] \the [src]!") dismantle_wall() - user.visible_message("\The [src] was torn open by [user]!") return //Reinforced dismantling. diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index 748eac0f5b4..b75170c71c8 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -125,14 +125,26 @@ var/material_icon_base = get_wall_icon() var/base_color = material.color + + var/new_icon + var/new_icon_state + var/new_color + if(!density) - icon = material_icon_base - icon_state = "fwall_open" - color = base_color + new_icon = material_icon_base + new_icon_state = "fwall_open" + new_color = base_color else - icon = get_combined_wall_icon(wall_connections, other_connections, material_icon_base, base_color, paint_color, stripe_color, (material.wall_flags & WALL_HAS_EDGES) && (stripe_color || base_color)) - icon_state = "" - color = null + new_icon = get_combined_wall_icon(wall_connections, other_connections, material_icon_base, base_color, paint_color, stripe_color, (material.wall_flags & WALL_HAS_EDGES) && (stripe_color || base_color)) + new_icon_state = "" + new_color = null + + if(icon != new_icon) + icon = new_icon + if(icon_state != new_icon_state) + icon_state = new_icon_state + if(color != new_color) + color = new_color if(apply_reinf_overlay()) var/image/I diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index 0e0d3673946..7f0c8252aad 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -71,10 +71,16 @@ /turf/simulated/wall/plastic/facade girder_material = /decl/material/solid/organic/plastic -/turf/simulated/wall/sandstone - color = COLOR_GOLD +/turf/simulated/wall/brick icon_state = "stone" material = /decl/material/solid/stone/sandstone + girder_material = null + +/turf/simulated/wall/brick/get_wall_icon() + return 'icons/turf/walls/stone.dmi' + +/turf/simulated/wall/brick/sandstone + color = COLOR_GOLD /turf/simulated/wall/wood color = COLOR_BROWN diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index de47a47ba32..ad087ece207 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -27,7 +27,6 @@ var/global/list/wall_fullblend_objects = list( heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall explosion_resistance = 10 color = COLOR_STEEL - atom_flags = ATOM_FLAG_CAN_BE_PAINTED turf_flags = TURF_IS_HOLOMAP_OBSTACLE var/damage = 0 @@ -67,7 +66,7 @@ var/global/list/wall_fullblend_objects = list( girder_material = GET_DECL(girder_material) . = INITIALIZE_HINT_LATELOAD - set_extension(src, /datum/extension/penetration/proc_call, .proc/CheckPenetration) + set_extension(src, /datum/extension/penetration/proc_call, PROC_REF(CheckPenetration)) START_PROCESSING(SSturf, src) //Used for radiation. /turf/simulated/wall/LateInitialize(var/ml) @@ -148,7 +147,7 @@ var/global/list/wall_fullblend_objects = list( plant.update_icon() plant.reset_offsets(0) -/turf/simulated/wall/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE) +/turf/simulated/wall/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE, var/keep_air_below = FALSE, var/update_open_turfs_above = TRUE) clear_plants() . = ..() @@ -220,13 +219,12 @@ var/global/list/wall_fullblend_objects = list( var/list/obj/structure/girder/placed_girders if(girder_material) placed_girders = girder_material.place_dismantled_girder(src, reinf_material) - material.place_dismantled_product(src,devastated) - else - placed_girders = material.place_dismantled_girder(src, reinf_material) for(var/obj/structure/girder/placed_girder in placed_girders) placed_girder.anchored = TRUE placed_girder.prepped_for_fakewall = can_open placed_girder.update_icon() + if(material) + material.place_dismantled_product(src, devastated) for(var/obj/O in src.contents) //Eject contents! if(istype(O,/obj/structure/sign/poster)) @@ -274,7 +272,7 @@ var/global/list/wall_fullblend_objects = list( if(!QDELETED(src) && istype(material) && material.combustion_effect(src, temperature, 0.7)) for(var/turf/simulated/wall/W in range(3,src)) if(W != src) - addtimer(CALLBACK(W, /turf/simulated/wall/proc/burn, temperature/4), 2) + addtimer(CALLBACK(W, TYPE_PROC_REF(/turf/simulated/wall, burn), temperature/4), 2) dismantle_wall(TRUE) /turf/simulated/wall/get_color() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index fde96995a2d..176e90b46ca 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -11,6 +11,8 @@ z_eventually_space = TRUE turf_flags = TURF_FLAG_BACKGROUND + open_turf_type = /turf/space + /// If we're an edge. var/edge = 0 /// Force this one to pretend it's an overedge turf. @@ -80,13 +82,14 @@ var/turf/T = src while ((T = GetAbove(T))) T.z_eventually_space = FALSE + return ..() /turf/space/LateInitialize() if(SSmapping.base_floor_area) var/area/new_area = locate(SSmapping.base_floor_area) || new SSmapping.base_floor_area ChangeArea(src, new_area) - ChangeTurf(SSmapping.base_floor_type) + ChangeTurf(SSmapping.base_floor_type, keep_air_below = TRUE) // override for space turfs, since they should never hide anything /turf/space/levelupdate() @@ -241,8 +244,8 @@ A.loc.Entered(A) return -/turf/space/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE) - return ..(N, tell_universe, TRUE, keep_air) +/turf/space/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE, var/keep_air_below = FALSE, var/update_open_turfs_above = TRUE) + return ..(N, tell_universe, TRUE, keep_air, keep_air_below, update_open_turfs_above) /turf/space/is_open() return TRUE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index cd37bf16edd..03a96f9c972 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -36,7 +36,7 @@ var/fluid_blocked_dirs = 0 var/flooded // Whether or not this turf is absolutely flooded ie. a water source. var/footstep_type - var/open_turf_type // Which turf to use when this turf is destroyed or replaced in a multiz context. Overridden by area. + var/open_turf_type // Which open turf type to use by default above this turf in a multiz context. Overridden by area. var/tmp/changing_turf var/tmp/prev_type // Previous type of the turf, prior to turf translation. @@ -73,6 +73,11 @@ /// Used by exterior turfs to determine the warming effect of campfires and such. var/list/affecting_heat_sources + // Fluid flow tracking vars + var/last_slipperiness = 0 + var/last_flow_strength = 0 + var/last_flow_dir = 0 + var/atom/movable/fluid_overlay/fluid_overlay /turf/Initialize(mapload, ...) . = null && ..() // This weird construct is to shut up the 'parent proc not called' warning without disabling the lint for child types. We explicitly return an init hint so this won't change behavior. @@ -106,9 +111,8 @@ if (z_flags & ZM_MIMIC_BELOW) setup_zmimic(mapload) - if(flooded && !density) - make_flooded(TRUE) - + if(flooded) + set_flooded(flooded, TRUE, skip_vis_contents_update = TRUE, mapload = mapload) refresh_vis_contents() return INITIALIZE_HINT_NORMAL @@ -160,6 +164,8 @@ remove_vis_contents(src, weather.vis_contents_additions) weather = null + QDEL_NULL(fluid_overlay) + ..() return QDEL_HINT_IWILLGC @@ -215,14 +221,12 @@ to_chat(user, SPAN_WARNING("There is nothing to be dug out of \the [src].")) return TRUE - if(ATOM_IS_OPEN_CONTAINER(W) && W.reagents) - var/obj/effect/fluid/F = locate() in src - if(F && F.reagents?.total_volume >= FLUID_PUDDLE) - var/taking = min(F.reagents?.total_volume, REAGENTS_FREE_SPACE(W.reagents)) - if(taking > 0) - to_chat(user, SPAN_NOTICE("You fill \the [W] with [F.reagents.get_primary_reagent_name()] from \the [src].")) - F.reagents.trans_to(W, taking) - return TRUE + if(ATOM_IS_OPEN_CONTAINER(W) && W.reagents && reagents?.total_volume >= FLUID_PUDDLE) + var/taking = min(reagents.total_volume, REAGENTS_FREE_SPACE(W.reagents)) + if(taking > 0) + to_chat(user, SPAN_NOTICE("You fill \the [W] with [reagents.get_primary_reagent_name()] from \the [src].")) + reagents.trans_to(W, taking) + return TRUE if(istype(W, /obj/item/storage)) var/obj/item/storage/S = W @@ -355,7 +359,7 @@ M.turf_collision(src, TT.speed) if(LAZYLEN(M.pinned)) return - addtimer(CALLBACK(src, /turf/proc/bounce_off, AM, TT.init_dir), 2) + addtimer(CALLBACK(src, TYPE_PROC_REF(/turf, bounce_off), AM, TT.init_dir), 2) else if(isobj(AM)) var/obj/structure/ladder/L = locate() in contents if(L) @@ -442,6 +446,29 @@ if(below) below.update_weather(new_weather) +// Updates turf participation in ZAS according to outside status. Must be called whenever the outside status of a turf may change. +/turf/proc/update_external_atmos_participation(overwrite_air = TRUE) + if(is_outside()) + if(zone && external_atmosphere_participation) + if(can_safely_remove_from_zone()) + #ifdef MULTIZAS + var/dirs = global.cardinalz + #else + var/dirs = global.cardinal + #endif + zone.remove(src) + // Update neighbors to create edges between zones and exterior + for(var/dir in dirs) + var/turf/neighbor = get_step(src, dir) + SSair.mark_for_update(neighbor) + else + zone.rebuild() + else if(zone_membership_candidate) + // Set the turf's air to the external atmosphere to add to its new zone. + if(overwrite_air) + air = get_external_air(FALSE) + SSair.mark_for_update(src) + /turf/proc/is_outside() // Can't rain inside or through solid walls. @@ -470,13 +497,14 @@ var/turf/next_turf = GetAbove(top_of_stack) if(!next_turf.is_open()) return OUTSIDE_NO - top_of_stack = next_turf - // ZM_PARTITION_STACK partitions the z-stack such that - // for the purposes of this check, the z-stack ends with it. - if(top_of_stack.z_flags & ZM_PARTITION_STACK) + // ZM_TERMINATOR partitions the z-stack such that + // for the purposes of this check, the z-stack ends before it. + if(next_turf.z_flags & ZM_TERMINATOR) break + top_of_stack = next_turf // If we hit the top of the stack without finding a roof, we ask the upmost turf if we're outside. - . = top_of_stack.is_outside() + if(top_of_stack != src) + . = top_of_stack.is_outside() last_outside_check = . // Cache this for later calls. /turf/proc/set_outside(var/new_outside, var/skip_weather_update = FALSE) @@ -489,14 +517,7 @@ SSambience.queued += src last_outside_check = OUTSIDE_UNCERTAIN - if(is_outside()) - if(zone && external_atmosphere_participation) - if(can_safely_remove_from_zone()) - zone.remove(src) - else - zone.rebuild() - else if(zone_membership_candidate) - SSair.mark_for_update(src) + update_external_atmos_participation() if(!HasBelow(z)) return TRUE @@ -528,7 +549,9 @@ if(weather) LAZYADD(., weather) if(flooded) - LAZYADD(., global.flood_object) + var/flood_object = get_flood_overlay(flooded) + if(flood_object) + LAZYADD(., flood_object) /**Whether we can place a cable here * If you cannot build a cable will return an error code explaining why you cannot. @@ -600,3 +623,32 @@ /turf/proc/dig_pit() return can_dig_pit() && new /obj/structure/pit(src) + +// Largely copied from stairs. +/turf/proc/can_move_up_ramp(atom/movable/AM, turf/above_wall, turf/under_atom, turf/above_atom) + if(!istype(AM) || !istype(above_wall) || !istype(under_atom) || !istype(above_atom)) + return FALSE + return under_atom.CanZPass(AM, UP) && above_atom.CanZPass(AM, DOWN) && above_wall.Enter(AM) + +/turf/Bumped(var/atom/movable/AM) + if(!istype(AM) || !HasAbove(z)) + return ..() + var/turf/exterior/wall/slope = AM.loc + if(!istype(slope) || !slope.ramp_slope_direction || get_dir(src, slope) != slope.ramp_slope_direction) + return ..() + var/turf/above_wall = GetAbove(src) + if(can_move_up_ramp(AM, above_wall, get_turf(AM), GetAbove(AM))) + AM.forceMove(above_wall) + if(isliving(AM)) + var/mob/living/L = AM + for(var/obj/item/grab/G in L.get_active_grabs()) + G.affecting.forceMove(above_wall) + else + to_chat(AM, SPAN_WARNING("Something blocks the path.")) + return TRUE + +/turf/proc/wet_floor(var/wet_val = 1, var/overwrite = FALSE) + return + +/turf/proc/unwet_floor(var/check_very_wet = TRUE) + return diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index 5dc39a1492c..a997568cc85 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -12,6 +12,7 @@ var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) qdel(L) + // Called after turf replaces old one /turf/proc/post_change() levelupdate() @@ -22,16 +23,31 @@ SHOULD_CALL_PARENT(FALSE) . = TRUE -/turf/proc/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE) +// Updates open turfs above this one to use its open_turf_type +/turf/proc/update_open_above(var/restrict_type, var/respect_area = TRUE) + if(!HasAbove(src.z)) + return + var/turf/above = src + while ((above = GetAbove(above))) + if(!above.is_open()) + break + if(!restrict_type || istype(above, restrict_type)) + if(respect_area) + var/area/A = get_area(above) + above.ChangeTurf(A?.open_turf || open_turf_type, update_open_turfs_above = FALSE) + else + above.ChangeTurf(open_turf_type, update_open_turfs_above = FALSE) + +/turf/proc/ChangeTurf(var/turf/N, var/tell_universe = TRUE, var/force_lighting_update = FALSE, var/keep_air = FALSE, var/keep_air_below = FALSE, var/update_open_turfs_above = TRUE) if (!N) return // Spawning space in the middle of a multiz stack should just spawn an open turf. if(ispath(N, /turf/space)) var/turf/below = GetBelow(src) - if(istype(below) && !isspaceturf(below) && !(below.z_flags & ZM_PARTITION_STACK)) + if(istype(below) && !isspaceturf(below) && !(below.z_flags & ZM_TERMINATOR)) var/area/A = get_area(src) - N = A?.open_turf || open_turf_type || /turf/simulated/open + N = A?.open_turf || open_turf_type || /turf/open if (!(atom_flags & ATOM_FLAG_INITIALIZED)) return new N(src) @@ -51,6 +67,7 @@ var/old_flooded = flooded var/old_outside = is_outside var/old_is_open = is_open() + var/old_open_turf_type = open_turf_type var/old_affecting_heat_sources = affecting_heat_sources var/old_ambience = ambient_light @@ -83,11 +100,8 @@ else if(old_fire) qdel(old_fire) - if(isnull(W.flooded) && old_flooded != W.flooded) - if(old_flooded && !W.density) - W.make_flooded() - else - W.make_unflooded() + if(old_flooded != W.flooded) + set_flooded(old_flooded) // Raise appropriate events. W.post_change() @@ -129,8 +143,21 @@ W.last_outside_check = OUTSIDE_UNCERTAIN if(W.is_outside != old_outside) W.set_outside(old_outside, skip_weather_update = TRUE) + + var/turf/below = GetBelow(src) + if(below) + below.last_outside_check = OUTSIDE_UNCERTAIN + + // If the turf is at the top of the Z-stack and changed its outside status, or if it's changed its open status, let the turf below check if + // it should change its ZAS participation + if((!HasAbove(z) && (W.is_outside != old_outside)) || W.is_open() != old_is_open) + below.update_external_atmos_participation(!keep_air_below) + W.update_weather(force_update_below = W.is_open() != old_is_open) + if(update_open_turfs_above) + update_open_above(old_open_turf_type) + /turf/proc/transport_properties_from(turf/other) if(other.zone) if(!air) @@ -168,7 +195,7 @@ stripe_color = other.stripe_color material = other.material - reinf_material = other.material + reinf_material = other.reinf_material girder_material = other.girder_material floor_type = other.floor_type diff --git a/code/game/turfs/turf_enter.dm b/code/game/turfs/turf_enter.dm index ddb26633928..cf613050118 100644 --- a/code/game/turfs/turf_enter.dm +++ b/code/game/turfs/turf_enter.dm @@ -5,7 +5,7 @@ if(!istype(mover) || !(mover.movable_flags & MOVABLE_FLAG_PROXMOVE)) return for(var/atom/movable/neighbor in range(1)) - if(objects > ENTER_PROXIMITY_LOOP_SANITY) + if(objects > ENTER_PROXIMITY_LOOP_SANITY) break // Don't let ore piles kill the server as well as the client. if(neighbor.movable_flags & MOVABLE_FLAG_PROXMOVE) objects++ @@ -49,6 +49,5 @@ I.contaminate() break - // Handle zmimic - if(!A.bound_overlay && !(A.z_flags & ZMM_IGNORE) && TURF_IS_MIMICKING(above)) - above.update_mimic() + // Handle non-listener proximity triggers. + handle_proximity_update(A) diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index 5a238ee305c..165d81ef0dd 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -10,28 +10,57 @@ return fluid_can_pass /turf/proc/remove_fluid(var/amount = 0) - var/obj/effect/fluid/F = locate() in src - if(F) - F.reagents.remove_any(amount) + if(reagents) + remove_any_reagents(amount) + +/turf/proc/displace_all_reagents() + UPDATE_FLUID_BLOCKED_DIRS(src) + var/list/spread_into_neighbors + var/turf/neighbor + var/coming_from + for(var/spread_dir in global.cardinal) + if(fluid_blocked_dirs & spread_dir) + continue + neighbor = get_step(src, spread_dir) + if(!neighbor) + continue + UPDATE_FLUID_BLOCKED_DIRS(neighbor) + coming_from = global.reverse_dir[spread_dir] + if((neighbor.fluid_blocked_dirs & coming_from) || !neighbor.CanFluidPass(coming_from) || neighbor.is_flooded(absolute = TRUE) || !neighbor.CanFluidPass(global.reverse_dir[spread_dir])) + continue + LAZYDISTINCTADD(spread_into_neighbors, neighbor) + if(length(spread_into_neighbors)) + var/spreading = round(reagents.total_volume / length(spread_into_neighbors)) + if(spreading > 0) + for(var/turf/spread_into_turf as anything in spread_into_neighbors) + reagents.trans_to_turf(spread_into_turf, spreading) + reagents?.clear_reagents() + +/turf/proc/set_flooded(new_flooded, force = FALSE, skip_vis_contents_update = FALSE, mapload = FALSE) + + // Don't do unnecessary work. + if(!force && new_flooded == flooded) + return -/turf/return_fluid() - return (locate(/obj/effect/fluid) in contents) + // Remove our old overlay if necessary. + if(flooded && new_flooded != flooded && !skip_vis_contents_update) + var/flood_object = get_flood_overlay(flooded) + if(flood_object) + remove_vis_contents(src, flood_object) -/turf/proc/make_unflooded(var/force) - if(force || flooded) - flooded = FALSE + // Set our flood state. + flooded = new_flooded + if(flooded) + QDEL_NULL(reagents) + ADD_ACTIVE_FLUID_SOURCE(src) + if(!skip_vis_contents_update) + var/flood_object = get_flood_overlay(flooded) + if(flood_object) + add_vis_contents(src, flood_object) + else if(!mapload) REMOVE_ACTIVE_FLUID_SOURCE(src) - remove_vis_contents(src, global.flood_object) fluid_update() // We are now floodable, so wake up our neighbors. -/turf/proc/make_flooded(var/force) - if(force || !flooded) - flooded = TRUE - for(var/obj/effect/fluid/fluid in src) - qdel(fluid) - ADD_ACTIVE_FLUID_SOURCE(src) - add_vis_contents(src, global.flood_object) - /turf/is_flooded(var/lying_mob, var/absolute) return (flooded || (!absolute && check_fluid_depth(lying_mob ? FLUID_OVER_MOB_HEAD : FLUID_DEEP))) @@ -39,29 +68,22 @@ . = (get_fluid_depth() >= min) /turf/proc/get_fluid_name() - var/obj/effect/fluid/F = return_fluid() - if(istype(F) && F.reagents?.primary_reagent) - return F.reagents.get_primary_reagent_name() - return "liquid" + var/decl/material/mat = reagents?.get_primary_reagent_decl() + return mat?.liquid_name || "liquid" /turf/get_fluid_depth() if(is_flooded(absolute=1)) return FLUID_MAX_DEPTH - var/obj/effect/fluid/F = return_fluid() - if(istype(F)) - return F.reagents.total_volume var/obj/structure/glass_tank/aquarium = locate() in contents - if(aquarium && aquarium.reagents && aquarium.reagents.total_volume) - return aquarium.reagents.total_volume * TANK_WATER_MULTIPLIER - return 0 + if(aquarium) + return aquarium.reagents?.total_volume * TANK_WATER_MULTIPLIER + return reagents?.total_volume || 0 /turf/proc/show_bubbles() set waitfor = FALSE - if(flooded) - return - var/obj/effect/fluid/F = locate() in src - if(istype(F)) - flick("bubbles",F) + // TODO: make flooding show bubbles. + if(!flooded && fluid_overlay) + flick("bubbles", fluid_overlay) /turf/fluid_update(var/ignore_neighbors) fluid_blocked_dirs = null @@ -73,13 +95,13 @@ T.fluid_update(TRUE) if(flooded) ADD_ACTIVE_FLUID_SOURCE(src) + else if(reagents?.total_volume > FLUID_QDEL_POINT) + ADD_ACTIVE_FLUID(src) -/turf/proc/add_fluid(var/fluid_type, var/fluid_amount, var/defer_update) - var/obj/effect/fluid/F = locate() in src - if(!F) - F = new(src) - if(!QDELETED(F)) - F.reagents.add_reagent(fluid_type, min(fluid_amount, FLUID_MAX_DEPTH - F.reagents.total_volume), defer_update = defer_update) +/turf/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE) + if(!reagents) + create_reagents(FLUID_MAX_DEPTH) + return ..() /turf/proc/get_physical_height() return 0 @@ -95,24 +117,66 @@ AM.fluid_act(fluids) /turf/proc/remove_fluids(var/amount, var/defer_update) - var/obj/effect/fluid/F = locate() in src - if(QDELETED(F) || !F.reagents?.total_volume) + if(!reagents?.total_volume) return - F.reagents.remove_any(amount, defer_update = defer_update) - if(defer_update && !QDELETED(F.reagents)) - SSfluids.holders_to_update[F.reagents] = TRUE + remove_any_reagents(amount, defer_update = defer_update) + if(defer_update && !QDELETED(reagents)) + SSfluids.holders_to_update[reagents] = TRUE /turf/proc/transfer_fluids_to(var/turf/target, var/amount, var/defer_update) - var/obj/effect/fluid/F = locate() in src - if(!F || !F.reagents?.total_volume) + if(!reagents?.total_volume) + return + if(!target.reagents) + target.create_reagents(FLUID_MAX_DEPTH) + reagents.trans_to_holder(target.reagents, min(reagents.total_volume, min(FLUID_MAX_DEPTH - target.reagents.total_volume, amount)), defer_update = defer_update) + if(defer_update) + if(!QDELETED(reagents)) + SSfluids.holders_to_update[reagents] = TRUE + if(!QDELETED(target.reagents)) + SSfluids.holders_to_update[target.reagents] = TRUE + +/turf/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + . = ..() + if(exposed_temperature >= FLAMMABLE_GAS_MINIMUM_BURN_TEMPERATURE) + vaporize_fuel(air) + +/turf/proc/vaporize_fuel(datum/gas_mixture/air) + if(!length(reagents?.reagent_volumes) || !istype(air)) return - var/obj/effect/fluid/other = locate() in target - if(!other) - other = new(target) - if(!QDELETED(other) && other.reagents) - F.reagents.trans_to_holder(other.reagents, min(F.reagents.total_volume, min(FLUID_MAX_DEPTH - other.reagents.total_volume, amount)), defer_update = defer_update) - if(defer_update) - if(!QDELETED(F.reagents)) - SSfluids.holders_to_update[F.reagents] = TRUE - if(!QDELETED(other.reagents)) - SSfluids.holders_to_update[other.reagents] = TRUE + var/update_air = FALSE + for(var/rtype in reagents.reagent_volumes) + var/decl/material/mat = GET_DECL(rtype) + if(mat.gas_flags & XGM_GAS_FUEL) + var/moles = round(reagents.reagent_volumes[rtype] / REAGENT_UNITS_PER_GAS_MOLE) + if(moles > 0) + air.adjust_gas(rtype, moles, FALSE) + remove_from_reagents(round(moles * REAGENT_UNITS_PER_GAS_MOLE)) + update_air = TRUE + if(update_air) + air.update_values() + return TRUE + return FALSE + +/turf/on_reagent_change() + + ..() + + if(reagents?.total_volume > FLUID_QDEL_POINT) + ADD_ACTIVE_FLUID(src) + var/decl/material/primary_reagent = reagents.get_primary_reagent_decl() + if(primary_reagent) + last_slipperiness = primary_reagent.slipperiness + if(!fluid_overlay) + fluid_overlay = new(src, TRUE) + fluid_overlay.update_icon() + unwet_floor(FALSE) + else + QDEL_NULL(fluid_overlay) + REMOVE_ACTIVE_FLUID(src) + SSfluids.pending_flows -= src + if(last_slipperiness > 0) + wet_floor(last_slipperiness) + for(var/checkdir in global.cardinal) + var/turf/neighbor = get_step(src, checkdir) + if(neighbor?.reagents?.total_volume > FLUID_QDEL_POINT) + ADD_ACTIVE_FLUID(neighbor) diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index baa0e3da4b9..18f3eede702 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -104,7 +104,7 @@ else msg += line - if(config.admin_irc) + if(get_config_value(/decl/config/text/admin_irc)) to_chat(src, "Adminhelps are also sent to IRC. If no admins are available in game try anyway and an admin on IRC may see it and respond.") to_chat(src, "Current Staff ([active_staff]/[total_staff]):") to_chat(src, jointext(msg,"\n")) diff --git a/code/game/world.dm b/code/game/world.dm index c1bdfa40cac..75c2f1dd65d 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -72,7 +72,8 @@ GLOBAL_PROTECTED_UNTYPED(game_id, null) /world/New() //set window title - name = "[config.server_name] - [global.using_map.full_name]" + + name = "[get_config_value(/decl/config/text/server_name) || "Nebula Station 13"] - [global.using_map.full_name]" //logs SetupLogs() @@ -82,10 +83,6 @@ GLOBAL_PROTECTED_UNTYPED(game_id, null) changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently - if(config && config.server_name != null && config.server_suffix && world.port > 0) - // dumb and hardcoded but I don't care~ - config.server_name += " #[(world.port % 1000) / 100]" - if(byond_version < REQUIRED_DM_VERSION) to_world_log("Your server's BYOND version does not meet the minimum DM version for this server. Please update BYOND.") @@ -98,7 +95,6 @@ GLOBAL_PROTECTED_UNTYPED(game_id, null) #ifdef UNIT_TEST log_unit_test("Unit Tests Enabled. This will destroy the world when testing is complete.") - load_unit_test_changes() #endif Master.Initialize(10, FALSE) @@ -109,7 +105,7 @@ var/global/world_topic_last = world.timeofday var/list/throttle = global.world_topic_throttle[addr] if (!global.world_topic_throttle[addr]) global.world_topic_throttle[addr] = throttle = list(0, null) - else if ((!config.no_throttle_localhost || !global.localhost_addresses[addr]) && throttle[1] && throttle[1] > world.timeofday + 15 SECONDS) + else if ((!get_config_value(/decl/config/toggle/no_throttle_localhost) || !global.localhost_addresses[addr]) && throttle[1] && throttle[1] > world.timeofday + 15 SECONDS) return throttle[2] ? "Throttled ([throttle[2]])" : "Throttled" throttle[1] = max(throttle[1], world.timeofday) + time @@ -144,11 +140,12 @@ var/global/world_topic_last = world.timeofday Master.Shutdown() - if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite + var/serverurl = get_config_value(/decl/config/text/server) + if(serverurl) //if you set a server location in configuration, it sends you there instead of trying to reconnect to the same world address. -- NeoFite for(var/client/C in global.clients) - to_chat(C, link("byond://[config.server]")) + to_chat(C, link("byond://[serverurl]")) - if(config.wait_for_sigusr1_reboot && reason != 3) + if(get_config_value(/decl/config/toggle/wait_for_sigusr1_reboot) && reason != 3) text2file("foo", "reboot_called") to_world("World reboot waiting for external scripts. Please be patient.") return @@ -190,19 +187,12 @@ var/global/world_topic_last = world.timeofday /world/proc/load_motd() join_motd = safe_file2text("config/motd.txt", FALSE) -/proc/load_configuration() - config = new /datum/configuration() - config.load("config/config.txt") - config.load("config/game_options.txt","game_options") - config.loadsql("config/dbconfig.txt") - config.load_event("config/custom_event.txt") - /hook/startup/proc/loadMods() world.load_mods() return 1 /world/proc/load_mods() - if(config.admin_legacy_system) + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) var/text = safe_file2text("config/moderators.txt", FALSE) if (!text) error("Failed to load config/mods.txt") @@ -225,11 +215,13 @@ var/global/world_topic_last = world.timeofday /world/proc/update_status() var/s = "[station_name()]" - if(config && config.discordurl) - s += " (Discord)" + var/discordurl = get_config_value(/decl/config/text/discordurl) + if(discordurl) + s += " (Discord)" - if(config && config.server_name) - s = "[config.server_name] — [s]" + var/config_server_name = get_config_value(/decl/config/text/server_name) + if(config_server_name) + s = "[config_server_name] — [s]" var/list/features = list() @@ -238,15 +230,15 @@ var/global/world_topic_last = world.timeofday else features += "STARTING" - if (!config.enter_allowed) + if (!get_config_value(/decl/config/toggle/on/enter_allowed)) features += "closed" - features += config.abandon_allowed ? "respawn" : "no respawn" + features += get_config_value(/decl/config/toggle/on/abandon_allowed) ? "respawn" : "no respawn" - if (config && config.allow_vote_mode) + if (get_config_value(/decl/config/toggle/vote_mode)) features += "vote" - if (config && config.allow_ai) + if (get_config_value(/decl/config/toggle/on/allow_ai)) features += "AI allowed" var/n = 0 @@ -260,8 +252,9 @@ var/global/world_topic_last = world.timeofday features += "~[n] player" - if (config && config.hostedby) - features += "hosted by [config.hostedby]" + var/hosted_by = get_config_value(/decl/config/text/hosted_by) + if (hosted_by) + features += "hosted by [hosted_by]" if (features) s += ": [jointext(features, ", ")]" @@ -284,7 +277,7 @@ var/global/world_topic_last = world.timeofday diary = file("[global.log_directory]/main.log") // This is the primary log, containing attack, admin, and game logs. to_file(diary, "[log_end]\n[log_end]\nStarting up. (ID: [game_id]) [time2text(world.timeofday, "hh:mm.ss")][log_end]\n---------------------[log_end]") - if(config && config.log_runtime) + if(get_config_value(/decl/config/toggle/log_runtime)) var/runtime_log = file("[global.log_directory]/runtime.log") to_file(runtime_log, "Game [game_id] starting up at [time2text(world.timeofday, "hh:mm.ss")]") log = runtime_log // runtimes and some other output is logged directly to world.log, which is redirected here. diff --git a/code/game/world_topic_commands.dm b/code/game/world_topic_commands.dm index a5d4adc28dc..b0cb23613b4 100644 --- a/code/game/world_topic_commands.dm +++ b/code/game/world_topic_commands.dm @@ -44,10 +44,11 @@ var/global/list/decl/topic_command/topic_commands = list() if (!can_use(T, addr, master, key)) return FALSE var/list/params = params2list(T) - if (!config.comms_password) + var/comms_password = get_config_value(/decl/config/text/comms_password) + if (!comms_password) set_throttle(addr, 10 SECONDS, "Comms Not Enabled") return "Not Enabled" - if (params["key"] != config.comms_password) + if (params["key"] != comms_password) set_throttle(addr, 30 SECONDS, "Bad Comms Key") return "Bad Key" return use(params) @@ -79,12 +80,12 @@ var/global/list/decl/topic_command/topic_commands = list() /decl/topic_command/status/use(var/list/params) var/list/s = list() s["version"] = game_version - s["mode"] = PUBLIC_GAME_MODE - s["respawn"] = config.abandon_allowed - s["enter"] = config.enter_allowed - s["vote"] = config.allow_vote_mode - s["ai"] = !!length(empty_playable_ai_cores) - s["host"] = host || null + s["mode"] = PUBLIC_GAME_MODE + s["respawn"] = get_config_value(/decl/config/toggle/on/abandon_allowed) + s["enter"] = get_config_value(/decl/config/toggle/on/enter_allowed) + s["vote"] = get_config_value(/decl/config/toggle/vote_mode) + s["ai"] = !!length(empty_playable_ai_cores) + s["host"] = host || null // This is dumb, but spacestation13.com's banners break if player count isn't the 8th field of the reply, so... this has to go here. s["players"] = 0 @@ -167,10 +168,11 @@ var/global/list/decl/topic_command/topic_commands = list() if (!can_use(T, addr, master, key)) return FALSE var/list/params = params2list(T) - if(!config.ban_comms_password) + var/ban_comms_password = get_config_value(/decl/config/text/ban_comms_password) + if(!ban_comms_password) set_throttle(addr, 10 SECONDS, "Bans Not Enabled") return "Not Enabled" - if(params["bankey"] != config.ban_comms_password) + if(params["bankey"] != ban_comms_password) set_throttle(addr, 30 SECONDS, "Bad Bans Key") return "Bad Key" return use(params) diff --git a/code/hub.dm b/code/hub.dm index d7b884d57e8..7749a33fd9d 100644 --- a/code/hub.dm +++ b/code/hub.dm @@ -1,5 +1,3 @@ -var/global/visibility_pref = FALSE - /world /* This page contains info for the hub. To allow your server to be visible on the hub, update the entry in the config. * You can also toggle visibility from in-game with toggle-hub-visibility; be aware that it takes a few minutes for the hub go @@ -8,5 +6,7 @@ var/global/visibility_pref = FALSE name = "Space Station 13 - Nebula13" /world/proc/update_hub_visibility() - global.visibility_pref = !global.visibility_pref - hub_password = global.visibility_pref ? "kMZy3U5jJHSiBQjr" : "SORRYNOPASSWORD" + if(get_config_value(/decl/config/toggle/hub_visibility)) + hub_password = "kMZy3U5jJHSiBQjr" + else + hub_password = "SORRYNOPASSWORD" diff --git a/code/modules/ZAS/Atom.dm b/code/modules/ZAS/Atom.dm index edbeef8d979..e3add163018 100644 --- a/code/modules/ZAS/Atom.dm +++ b/code/modules/ZAS/Atom.dm @@ -34,25 +34,5 @@ fluid_update() return TRUE -//Basically another way of calling CanPass(null, other, 0, 0) and CanPass(null, other, 1.5, 1). -//Returns: -// 0 - Not blocked -// AIR_BLOCKED - Blocked -// ZONE_BLOCKED - Not blocked, but zone boundaries will not cross. -// BLOCKED - Blocked, zone boundaries will not cross even if opened. -/atom/proc/c_airblock(turf/other) - #ifdef ZASDBG - ASSERT(isturf(other)) - #endif - return (AIR_BLOCKED*!CanPass(null, other, 0, 0))|(ZONE_BLOCKED*!CanPass(null, other, 1.5, 1)) - -/turf/c_airblock(turf/other) - #ifdef ZASDBG - ASSERT(isturf(other)) - #endif - - . = 0 - ATMOS_CANPASS_TURF(., src, other) - /atom/movable var/atmos_canpass = CANPASS_ALWAYS diff --git a/code/modules/ZAS/ConnectionGroup.dm b/code/modules/ZAS/ConnectionGroup.dm index fc98d50f419..51502dbe002 100644 --- a/code/modules/ZAS/ConnectionGroup.dm +++ b/code/modules/ZAS/ConnectionGroup.dm @@ -55,6 +55,10 @@ Class Procs: Helper proc that allows getting the other zone of an edge given one of them. Only on /connection_edge/zone, otherwise use A. + update_post_merge() + Called after the edge's owner is merged into another zone. + Marks the relevant connecting turfs for update. + */ @@ -114,6 +118,10 @@ Class Procs: //If they're already being tossed, don't do it again. M.handle_airflow(differential, connecting_turfs, repelled) +/connection_edge/proc/update_post_merge() + for(var/turf/T in connecting_turfs) + SSair.mark_for_update(T) + /connection_edge/zone/var/zone/B /connection_edge/zone/New(zone/A, zone/B) @@ -189,6 +197,7 @@ Class Procs: /connection_edge/unsimulated/var/turf/B /connection_edge/unsimulated/var/datum/gas_mixture/air +/connection_edge/unsimulated/var/list/inner_turfs = list() /connection_edge/unsimulated/New(zone/A, turf/B) src.A = A @@ -204,10 +213,12 @@ Class Procs: /connection_edge/unsimulated/add_connection(connection/c) . = ..() connecting_turfs.Add(c.B) + inner_turfs |= c.A air.group_multiplier = coefficient /connection_edge/unsimulated/remove_connection(connection/c) connecting_turfs.Remove(c.B) + inner_turfs.Remove(c.A) air.group_multiplier = coefficient . = ..() @@ -242,6 +253,10 @@ Class Procs: if(!A.air.compare(air, vacuum_exception = 1)) SSair.mark_edge_active(src) +/connection_edge/unsimulated/update_post_merge() + for(var/turf/T in inner_turfs) + SSair.mark_for_update(T) + /proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) //This implements a simplistic version of the Stefan-Boltzmann law. var/energy_delta = ((A.temperature - B.temperature) ** 4) * STEFAN_BOLTZMANN_CONSTANT * connecting_tiles * 2.5 diff --git a/code/modules/ZAS/Contaminants.dm b/code/modules/ZAS/Contaminants.dm index e428d1c5fb8..362f59c1fef 100644 --- a/code/modules/ZAS/Contaminants.dm +++ b/code/modules/ZAS/Contaminants.dm @@ -114,13 +114,14 @@ var/global/image/contamination_overlay = image('icons/effects/contamination.dmi' /mob/living/carbon/human/proc/contaminant_head_protected() //Checks if the head is adequately sealed. var/obj/item/head = get_equipped_item(slot_head_str) - if(head) - if(vsc.contaminant_control.STRICT_PROTECTION_ONLY) - if(head.item_flags & ITEM_FLAG_NO_CONTAMINATION) - return 1 - else if(head.body_parts_covered & SLOT_EYES) - return 1 - return 0 + if(!head) + return FALSE + // If strict protection is on, you must have a head item with ITEM_FLAG_NO_CONTAMINATION. + if(vsc.contaminant_control.STRICT_PROTECTION_ONLY) + if(!(head.item_flags & ITEM_FLAG_NO_CONTAMINATION)) + return FALSE + // Regardless, the head item must cover the face and head. Eyes are checked seperately above. + return BIT_TEST_ALL(head.body_parts_covered, SLOT_HEAD|SLOT_FACE) /mob/living/carbon/human/proc/contaminant_suit_protected() //Checks if the suit is adequately sealed. @@ -130,11 +131,11 @@ var/global/image/contamination_overlay = image('icons/effects/contamination.dmi' if(!istype(protection)) continue if(vsc.contaminant_control.STRICT_PROTECTION_ONLY && !(protection.item_flags & ITEM_FLAG_NO_CONTAMINATION)) - return 0 + return FALSE coverage |= protection.body_parts_covered if(vsc.contaminant_control.STRICT_PROTECTION_ONLY) - return 1 + return TRUE return BIT_TEST_ALL(coverage, SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS|SLOT_HANDS) diff --git a/code/modules/ZAS/Diagnostic.dm b/code/modules/ZAS/Diagnostic.dm index 369eec4f9ec..71641a66eef 100644 --- a/code/modules/ZAS/Diagnostic.dm +++ b/code/modules/ZAS/Diagnostic.dm @@ -32,9 +32,11 @@ if(!direction) return + var/airblock if(direction == "N/A") to_chat(mob, "Testing self-blocking...") - if(!(T.c_airblock(T) & AIR_BLOCKED)) + ATMOS_CANPASS_TURF(airblock, T, T) + if(!(airblock & AIR_BLOCKED)) to_chat(mob, "The turf can pass air! :D") else to_chat(mob, "No air passage :x") @@ -44,8 +46,10 @@ if(!istype(other_turf)) return - var/t_block = T.c_airblock(other_turf) - var/o_block = other_turf.c_airblock(T) + var/t_block + ATMOS_CANPASS_TURF(t_block, T, other_turf) + var/o_block + ATMOS_CANPASS_TURF(o_block, other_turf, T) to_chat(mob, "Testing connection between ([T.x], [T.y], [T.z]) and ([other_turf.x], [other_turf.y], [other_turf.z])...") if(o_block & AIR_BLOCKED) diff --git a/code/modules/ZAS/Fire.dm b/code/modules/ZAS/Fire.dm index ab9bba78485..186aae2dca9 100644 --- a/code/modules/ZAS/Fire.dm +++ b/code/modules/ZAS/Fire.dm @@ -30,9 +30,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin if(!air_contents || exposed_temperature < FLAMMABLE_GAS_MINIMUM_BURN_TEMPERATURE) return 0 - var/obj/effect/fluid/F = locate() in src - if(F) - F.vaporize_fuel(air_contents) + vaporize_fuel(air_contents) var/igniting = 0 if(air_contents.check_combustibility()) @@ -127,7 +125,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin // prioritize nearby fuel overlays first for(var/direction in global.cardinal) var/turf/enemy_tile = get_step(my_tile, direction) - if(istype(enemy_tile) && (locate(/obj/effect/fluid) in enemy_tile)) + if(istype(enemy_tile) && enemy_tile.reagents) enemy_tile.hotspot_expose(air_contents.temperature, air_contents.volume) //spread @@ -141,7 +139,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin //if(!enemy_tile.zone.fire_tiles.len) TODO - optimize var/datum/gas_mixture/acs = enemy_tile.return_air() - if(!acs || !acs.check_combustibility(enemy_tile.return_fluid())) + if(!acs || !acs.check_combustibility()) continue //If extinguisher mist passed over the turf it's trying to spread to, don't spread and diff --git a/code/modules/ZAS/Turf.dm b/code/modules/ZAS/Turf.dm index 4572a8502c6..3133446a7b1 100644 --- a/code/modules/ZAS/Turf.dm +++ b/code/modules/ZAS/Turf.dm @@ -10,7 +10,8 @@ c_copy_air() //not very efficient :( zone = null //Easier than iterating through the list at the zone. - var/s_block = c_airblock(src) + var/s_block + ATMOS_CANPASS_TURF(s_block, src, src) if(s_block & AIR_BLOCKED) #ifdef ZASDBG if(verbose) @@ -43,7 +44,8 @@ if(!unsim) //edge of map continue - var/block = unsim.c_airblock(src) + var/block + ATMOS_CANPASS_TURF(block, unsim, src) if(block & AIR_BLOCKED) #ifdef ZASDBG @@ -54,7 +56,8 @@ continue - var/r_block = c_airblock(unsim) + var/r_block + ATMOS_CANPASS_TURF(r_block, src, unsim) if(r_block & AIR_BLOCKED) #ifdef ZASDBG @@ -148,12 +151,21 @@ for(var/turf/T in postponed) SSair.connect(src, T) - - - - - - +// Helper for can_safely_remove_from_zone(). +#define GET_ZONE_NEIGHBOURS(T, ret) \ + ret = 0; \ + if (T.zone) { \ + for (var/_gzn_dir in gzn_check) { \ + var/turf/simulated/other = get_step(T, _gzn_dir); \ + if (istype(other) && other.zone == T.zone) { \ + var/block; \ + ATMOS_CANPASS_TURF(block, other, T); \ + if (!(block & AIR_BLOCKED)) { \ + ret |= _gzn_dir; \ + } \ + } \ + } \ + } /* Simple heuristic for determining if removing the turf from it's zone will not partition the zone (A very bad thing). @@ -162,46 +174,32 @@ */ /turf/proc/can_safely_remove_from_zone() - if(!zone) return 1 - var/check_dirs = get_zone_neighbours(src) - var/unconnected_dirs = check_dirs + if(!zone) + return 1 + + var/check_dirs + GET_ZONE_NEIGHBOURS(src, check_dirs) + . = check_dirs //src is only connected to the zone by a single direction, this is a safe removal. if (!(check_dirs & (check_dirs - 1))) //Equivalent to: if(IsInteger(log(2, .))) return TRUE - #ifdef MULTIZAS - var/to_check = global.cornerdirsz - #else - var/to_check = global.cornerdirs - #endif - - for(var/dir in to_check) - + for(var/dir in global.csrfz_check) //for each pair of "adjacent" cardinals (e.g. NORTH and WEST, but not NORTH and SOUTH) if((dir & check_dirs) == dir) //check that they are connected by the corner turf - var/connected_dirs = get_zone_neighbours(get_step(src, dir)) + var/turf/simulated/T = get_step(src, dir) + if (!istype(T)) + . &= ~dir + continue + var/connected_dirs + GET_ZONE_NEIGHBOURS(T, connected_dirs) if(connected_dirs && (dir & global.reverse_dir[connected_dirs]) == dir) - unconnected_dirs &= ~dir //they are, so unflag the cardinals in question - + . &= ~dir //they are, so unflag the cardinals in question //it is safe to remove src from the zone if all cardinals are connected by corner turfs - return !unconnected_dirs - -//helper for can_safely_remove_from_zone() -/turf/proc/get_zone_neighbours(turf/T) - . = 0 - if(istype(T) && T.zone) - #ifdef MULTIZAS - var/to_check = global.cardinalz - #else - var/to_check = global.cardinal - #endif - for(var/dir in to_check) - var/turf/other = get_step(T, dir) - if(isturf(other) && other.zone_membership_candidate && other.zone == T.zone && !(other.c_airblock(T) & AIR_BLOCKED) && get_dist(src, other) <= 1) - . |= dir + . = !. /turf/proc/post_update_air_properties() if(connections) connections.update_all() @@ -223,22 +221,13 @@ // Exterior turf global atmosphere if(external_atmosphere_participation && is_outside()) - var/datum/level_data/level = SSmapping.levels_by_z[z] - var/datum/gas_mixture/gas = level.get_exterior_atmosphere() - var/initial_temperature = weather ? weather.adjust_temperature(gas.temperature) : gas.temperature - if(length(affecting_heat_sources)) - for(var/obj/structure/fire_source/heat_source as anything in affecting_heat_sources) - gas.temperature = gas.temperature + heat_source.exterior_temperature / max(1, get_dist(src, get_turf(heat_source))) - if(abs(gas.temperature - initial_temperature) >= 100) - break - return gas + return get_external_air() // Base behavior - . = air - if(!.) - . = make_air() - if(zone) - c_copy_air() + . = air || make_air() + if(zone) + c_copy_air() + zone = null /turf/remove_air(amount as num) var/datum/gas_mixture/GM = return_air() @@ -262,6 +251,21 @@ air.update_values() return air +// Returns the external air if this turf is outside, modified by weather and heat sources. Outside checks do not occur in this proc! +/turf/proc/get_external_air(include_heat_sources = TRUE) + var/datum/level_data/level = SSmapping.levels_by_z[z] + var/datum/gas_mixture/gas = level.get_exterior_atmosphere() + if(!include_heat_sources) + return gas + + var/initial_temperature = weather ? weather.adjust_temperature(gas.temperature) : gas.temperature + if(length(affecting_heat_sources)) + for(var/obj/structure/fire_source/heat_source as anything in affecting_heat_sources) + gas.temperature = gas.temperature + heat_source.exterior_temperature / max(1, get_dist(src, get_turf(heat_source))) + if(abs(gas.temperature - initial_temperature) >= 100) + break + return gas + /turf/proc/c_copy_air() if(!air) air = new/datum/gas_mixture diff --git a/code/modules/ZAS/Zone.dm b/code/modules/ZAS/Zone.dm index f8d858c9df7..00f4f07cbea 100644 --- a/code/modules/ZAS/Zone.dm +++ b/code/modules/ZAS/Zone.dm @@ -84,6 +84,7 @@ Class Procs: ASSERT(T.zone == src) soft_assert(T in contents, "Lists are weird broseph") #endif + T.c_copy_air() // to avoid losing contents contents.Remove(T) fire_tiles.Remove(T) T.zone = null @@ -114,8 +115,7 @@ Class Procs: for(var/connection_edge/E in edges) if(E.contains_zone(into)) continue //don't need to rebuild this edge - for(var/turf/T in E.connecting_turfs) - SSair.mark_for_update(T) + E.update_post_merge() /zone/proc/c_invalidate() invalid = 1 @@ -191,9 +191,7 @@ Class Procs: if(condense_amt < 1) break air.adjust_gas(g, -condense_amt) - var/obj/effect/fluid/F = locate() in flooding - if(!F) F = new(flooding) - F.reagents.add_reagent(g, condense_amt * REAGENT_UNITS_PER_GAS_MOLE) + flooding.add_to_reagents(g, condense_amt * REAGENT_UNITS_PER_GAS_MOLE) CHECK_TICK condensing = FALSE diff --git a/code/modules/acting/acting_items.dm b/code/modules/acting/acting_items.dm index 09716bfcb86..672e773675a 100644 --- a/code/modules/acting/acting_items.dm +++ b/code/modules/acting/acting_items.dm @@ -12,7 +12,7 @@ user.show_message("You push a button and watch patiently as the machine begins to hum.") if(active) active = FALSE - addtimer(CALLBACK(src, .proc/dispense), 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(dispense)), 3 SECONDS) return TRUE /obj/machinery/acting/wardrobe/proc/dispense() diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 686443a1b04..a780eadc0f5 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -15,7 +15,7 @@ return ..() //Guest Checking - if(!config.guests_allowed && IsGuestKey(key)) + if(!get_config_value(/decl/config/toggle/guests_allowed) && IsGuestKey(key)) log_access("Failed Login: [key] - Guests not allowed") message_admins("Failed Login: [key] - Guests not allowed") key_cache[key] = 0 @@ -27,7 +27,7 @@ key_cache[key] = 0 return - if(config.ban_legacy_system) + if(get_config_value(/decl/config/toggle/on/ban_legacy_system)) //Ban Checking . = CheckBan(ckeytext, computer_id, address) diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index c3d514be9a3..7f4ea462f4a 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -10,8 +10,9 @@ var/global/savefile/Banlist . = list() var/appeal - if(config && config.banappeals) - appeal = "\nFor more information on your ban, or to appeal, head to [config.banappeals]" + var/appealurl = get_config_value(/decl/config/text/banappeals) + if(appealurl) + appeal = "\nFor more information on your ban, or to appeal, head to [appealurl]" Banlist.cd = "/base" if( "[ckey][id]" in Banlist.dir ) Banlist.cd = "[ckey][id]" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 94094e16aaf..efd56eae900 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -721,12 +721,9 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Globally Toggles OOC" set name="Toggle OOC" - if(!check_rights(R_ADMIN)) return - - config.ooc_allowed = !(config.ooc_allowed) - if (config.ooc_allowed) + if (toggle_config_value(/decl/config/toggle/on/ooc_allowed)) to_world("The OOC channel has been globally enabled!") else to_world("The OOC channel has been globally disabled!") @@ -737,12 +734,9 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Globally Toggles AOOC" set name="Toggle AOOC" - if(!check_rights(R_ADMIN)) return - - config.aooc_allowed = !(config.aooc_allowed) - if (config.aooc_allowed) + if (toggle_config_value(/decl/config/toggle/on/aooc_allowed)) communicate_broadcast(/decl/communication_channel/aooc, "The AOOC channel has been globally enabled!", TRUE) else communicate_broadcast(/decl/communication_channel/aooc, "The AOOC channel has been globally disabled!", TRUE) @@ -756,9 +750,7 @@ var/global/floorIsLava = 0 if(!check_rights(R_ADMIN)) return - - config.looc_allowed = !(config.looc_allowed) - if (config.looc_allowed) + if (toggle_config_value(/decl/config/toggle/on/looc_allowed)) to_world("The LOOC channel has been globally enabled!") else to_world("The LOOC channel has been globally disabled!") @@ -773,9 +765,7 @@ var/global/floorIsLava = 0 if(!check_rights(R_ADMIN)) return - - config.dsay_allowed = !(config.dsay_allowed) - if (config.dsay_allowed) + if (toggle_config_value(/decl/config/toggle/on/dsay_allowed)) to_world("Deadchat has been globally enabled!") else to_world("Deadchat has been globally disabled!") @@ -786,11 +776,9 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Toggle Dead OOC." set name="Toggle Dead OOC" - if(!check_rights(R_ADMIN)) return - - config.dooc_allowed = !( config.dooc_allowed ) + toggle_config_value(/decl/config/toggle/on/dooc_allowed) log_admin("[key_name(usr)] toggled Dead OOC.") message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1) SSstatistics.add_field_details("admin_verb","TDOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -804,9 +792,10 @@ var/global/floorIsLava = 0 return //BYOND hates actually changing world.visibility at runtime, so let's just change if we give it the hub password. - world.update_hub_visibility() //proc defined in hub.dm - var/long_message = "toggled hub visibility. The server is now [global.visibility_pref ? "visible" : "invisible"] ([global.visibility_pref])." - if (global.visibility_pref && !world.reachable) + toggle_config_value(/decl/config/toggle/hub_visibility) + var/new_vis = get_config_value(/decl/config/toggle/hub_visibility) + var/long_message = "toggled hub visibility. The server is now [new_vis ? "visible" : "invisible"]." + if (new_vis && !world.reachable) message_admins("WARNING: The server will not show up on the hub because byond is detecting that a firewall is blocking incoming connections.") send2adminirc("[key_name(src)]" + long_message) @@ -817,9 +806,12 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Toggle traitor scaling" set name="Toggle Traitor Scaling" - config.traitor_scaling = !config.traitor_scaling - log_admin("[key_name(usr)] toggled Traitor Scaling to [config.traitor_scaling].") - message_admins("[key_name_admin(usr)] toggled Traitor Scaling [config.traitor_scaling ? "on" : "off"].", 1) + if(toggle_config_value(/decl/config/toggle/traitor_scaling)) + log_admin("[key_name(usr)] toggled Traitor Scaling to on.") + message_admins("[key_name_admin(usr)] toggled Traitor Scaling on.", 1) + else + log_admin("[key_name(usr)] toggled Traitor Scaling to off.") + message_admins("[key_name_admin(usr)] toggled Traitor Scaling off.", 1) SSstatistics.add_field_details("admin_verb","TTS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/startnow() @@ -858,7 +850,7 @@ var/global/floorIsLava = 0 if(confirm == "Yes") Master.SetRunLevel(RUNLEVEL_POSTGAME) SSticker.end_game_state = END_GAME_READY_TO_END - INVOKE_ASYNC(SSticker, /datum/controller/subsystem/ticker/proc/declare_completion) + INVOKE_ASYNC(SSticker, TYPE_PROC_REF(/datum/controller/subsystem/ticker, declare_completion)) log_and_message_admins("initiated a game ending.") to_world("Game ending! Initiated by [usr.key]!") SSstatistics.add_field("admin_verb","ER") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -867,11 +859,10 @@ var/global/floorIsLava = 0 set category = "Server" set desc="People can't enter" set name="Toggle Entering" - config.enter_allowed = !(config.enter_allowed) - if (!(config.enter_allowed)) - to_world("New players may no longer enter the game.") - else + if (toggle_config_value(/decl/config/toggle/on/enter_allowed)) to_world("New players may now enter the game.") + else + to_world("New players may no longer enter the game.") log_and_message_admins("toggled new player game entering.") world.update_status() SSstatistics.add_field_details("admin_verb","TE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -880,11 +871,11 @@ var/global/floorIsLava = 0 set category = "Server" set desc="People can't be AI" set name="Toggle AI" - config.allow_ai = !( config.allow_ai ) - if (!( config.allow_ai )) - to_world("The AI job is no longer chooseable.") - else + + if (toggle_config_value(/decl/config/toggle/on/allow_ai)) to_world("The AI job is chooseable now.") + else + to_world("The AI job is no longer chooseable.") log_admin("[key_name(usr)] toggled AI allowed.") world.update_status() SSstatistics.add_field_details("admin_verb","TAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -893,12 +884,12 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Respawn basically" set name="Toggle Respawn" - config.abandon_allowed = !(config.abandon_allowed) - if(config.abandon_allowed) + if (toggle_config_value(/decl/config/toggle/on/abandon_allowed)) to_world("You may now respawn.") + log_and_message_admins("toggled respawn to On.") else to_world("You may no longer respawn :(") - log_and_message_admins("toggled respawn to [config.abandon_allowed ? "On" : "Off"].") + log_and_message_admins("toggled respawn to Off.") world.update_status() SSstatistics.add_field_details("admin_verb","TR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -908,10 +899,12 @@ var/global/floorIsLava = 0 set name="Toggle Aliens" if(!check_rights(R_ADMIN)) return - - config.aliens_allowed = !config.aliens_allowed - log_admin("[key_name(usr)] toggled Aliens to [config.aliens_allowed].") - message_admins("[key_name_admin(usr)] toggled Aliens [config.aliens_allowed ? "on" : "off"].", 1) + if(toggle_config_value(/decl/config/toggle/aliens_allowed)) + log_admin("[key_name(usr)] toggled Aliens to On.") + message_admins("[key_name_admin(usr)] toggled Aliens on.", 1) + else + log_admin("[key_name(usr)] toggled Aliens to Off.") + message_admins("[key_name_admin(usr)] toggled Aliens off.", 1) SSstatistics.add_field_details("admin_verb","TA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggle_space_ninja() @@ -920,9 +913,8 @@ var/global/floorIsLava = 0 set name="Toggle Space Ninjas" if(!check_rights(R_ADMIN)) return - - config.ninjas_allowed = !config.ninjas_allowed - log_and_message_admins("toggled Space Ninjas [config.ninjas_allowed ? "on" : "off"].") + toggle_config_value(/decl/config/toggle/ninjas_allowed) + log_and_message_admins("toggled Space Ninjas [get_config_value(/decl/config/toggle/ninjas_allowed) ? "on" : "off"].") SSstatistics.add_field_details("admin_verb","TSN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/delay() @@ -948,24 +940,24 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Toggle admin jumping" set name="Toggle Jump" - config.allow_admin_jump = !(config.allow_admin_jump) - log_and_message_admins("toggled admin jumping to [config.allow_admin_jump].") + toggle_config_value(/decl/config/toggle/on/admin_jump) + log_and_message_admins("toggled admin jumping to [get_config_value(/decl/config/toggle/on/admin_jump)].") SSstatistics.add_field_details("admin_verb","TJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/adspawn() set category = "Server" set desc="Toggle admin spawning" set name="Toggle Spawn" - config.allow_admin_spawning = !(config.allow_admin_spawning) - log_and_message_admins("toggled admin item spawning to [config.allow_admin_spawning].") + toggle_config_value(/decl/config/toggle/on/admin_spawning) + log_and_message_admins("toggled admin item spawning to [get_config_value(/decl/config/toggle/on/admin_spawning)].") SSstatistics.add_field_details("admin_verb","TAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/adrev() set category = "Server" set desc="Toggle admin revives" set name="Toggle Revive" - config.allow_admin_rev = !(config.allow_admin_rev) - log_and_message_admins("toggled reviving to [config.allow_admin_rev].") + toggle_config_value(/decl/config/toggle/on/admin_revive) + log_and_message_admins("toggled reviving to [get_config_value(/decl/config/toggle/on/admin_revive)].") SSstatistics.add_field_details("admin_verb","TAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/immreboot() @@ -987,7 +979,7 @@ var/global/floorIsLava = 0 set category = "Admin" set name = "Unprison" if (isAdminLevel(M.z)) - if (config.allow_admin_jump) + if (get_config_value(/decl/config/toggle/on/admin_jump)) M.forceMove(get_random_spawn_turf(SPAWN_FLAG_PRISONERS_CAN_SPAWN)) message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]", 1) log_admin("[key_name(usr)] has unprisoned [key_name(M)]") @@ -1144,7 +1136,9 @@ var/global/floorIsLava = 0 for(var/path in subtypesof(/atom)) var/atom/path_cast = path if(TYPE_IS_SPAWNABLE(path_cast) && findtext(lowertext("[path]"), object)) - matches += "[path]" // We need to use a string because input() checks invisibility on types for Reasons:tm:. + // We need to keep the type as a string because for some ungodly reason input() compares + // initial invisibility value to mob see_invisible. + matches += "[path]" if(matches.len==0) return @@ -1153,11 +1147,11 @@ var/global/floorIsLava = 0 if(matches.len==1) chosen = matches[1] else - chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + chosen = input(usr, "Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches if(!chosen) return - chosen = text2path(chosen) + chosen = text2path(chosen) // See comment above. if(ispath(chosen,/turf)) var/turf/T = get_turf(usr.loc) T.ChangeTurf(chosen) @@ -1263,8 +1257,7 @@ var/global/floorIsLava = 0 set category = "Debug" set desc="Reduces view range when wearing welding helmets" set name="Toggle tinted welding helmets." - config.welder_vision = !( config.welder_vision ) - if (config.welder_vision) + if (toggle_config_value(/decl/config/toggle/on/welder_vision)) to_world("Reduced welder vision has been enabled!") else to_world("Reduced welder vision has been disabled!") @@ -1275,13 +1268,14 @@ var/global/floorIsLava = 0 set category = "Server" set desc="Guests can't enter" set name="Toggle guests" - config.guests_allowed = !(config.guests_allowed) - if (!(config.guests_allowed)) - to_world("Guests may no longer enter the game.") - else + if (toggle_config_value(/decl/config/toggle/guests_allowed)) to_world("Guests may now enter the game.") - log_admin("[key_name(usr)] toggled guests game entering [config.guests_allowed?"":"dis"]allowed.") - log_and_message_admins("toggled guests game entering [config.guests_allowed?"":"dis"]allowed.") + log_admin("[key_name(usr)] toggled guests game entering allowed.") + log_and_message_admins("toggled guests game entering allowed.") + else + to_world("Guests may no longer enter the game.") + log_admin("[key_name(usr)] toggled guests game entering disallowed.") + log_and_message_admins("toggled guests game entering disallowed.") SSstatistics.add_field_details("admin_verb","TGU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/output_ai_laws() diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index be20c0f0abc..66fe7e8daff 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -39,7 +39,7 @@ show_browser(src, F, "window=investigate[subject];size=800x300") if("hrefs") //persistant logs and stuff - if(config && config.log_hrefs) + if(get_config_value(/decl/config/toggle/log_hrefs)) if(global.world_href_log) show_browser(src, global.world_href_log, "window=investigate[subject];size=800x300") else diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 0a1c04d54f5..5a6a4d7b17a 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -68,7 +68,7 @@ var/global/list/admin_ranks = list() //list of all ranks with associated for (var/admin in world.GetConfig("admin")) world.SetConfig("APP/admin", admin, null) - if(config.admin_legacy_system) + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) load_admin_ranks() //load text from file @@ -108,7 +108,7 @@ var/global/list/admin_ranks = list() //list of all ranks with associated if(!dbcon.IsConnected()) error("Failed to connect to database in load_admins(). Reverting to legacy system.") log_misc("Failed to connect to database in load_admins(). Reverting to legacy system.") - config.admin_legacy_system = 1 + set_config_value(/decl/config/toggle/on/admin_legacy_system, TRUE) load_admins() return @@ -128,7 +128,7 @@ var/global/list/admin_ranks = list() //list of all ranks with associated if(!admin_datums) error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.") log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.") - config.admin_legacy_system = 1 + set_config_value(/decl/config/toggle/on/admin_legacy_system, TRUE) load_admins() return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1210dcbe012..bdb88717b15 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -330,7 +330,9 @@ var/global/list/admin_verbs_mod = list( /client/proc/aooc, /datum/admins/proc/sendFax, /datum/admins/proc/paralyze_mob, - /datum/admins/proc/view_persistent_data + /datum/admins/proc/view_persistent_data, + /datum/admins/proc/dump_configuration, + /datum/admins/proc/dump_character_info_manifest ) /client/proc/add_admin_verbs() @@ -343,7 +345,7 @@ var/global/list/admin_verbs_mod = list( if(holder.rights & R_SERVER) verbs += admin_verbs_server if(holder.rights & R_DEBUG) verbs += admin_verbs_debug - if(config.debugparanoid && !(holder.rights & R_ADMIN)) + if(get_config_value(/decl/config/toggle/paranoid) && !(holder.rights & R_ADMIN)) verbs.Remove(admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on. if(holder.rights & R_POSSESS) verbs += admin_verbs_possess if(holder.rights & R_PERMISSIONS) verbs += admin_verbs_permissions @@ -465,7 +467,7 @@ var/global/list/admin_verbs_mod = list( set name = "Display Job bans" set category = "Admin" if(holder) - if(config.ban_legacy_system) + if(get_config_value(/decl/config/toggle/on/ban_legacy_system)) holder.Jobbans() else holder.DB_ban_panel() @@ -476,7 +478,7 @@ var/global/list/admin_verbs_mod = list( set name = "Unban Panel" set category = "Admin" if(holder) - if(config.ban_legacy_system) + if(get_config_value(/decl/config/toggle/on/ban_legacy_system)) holder.unbanpanel() else holder.DB_ban_panel() @@ -577,7 +579,7 @@ var/global/list/admin_verbs_mod = list( explosion(epicenter, 3, 5, 7, 5) if("Custom Bomb") - if(config.use_iterative_explosions) + if(get_config_value(/decl/config/toggle/use_iterative_explosions)) var/power = input(src, "Input power num.", "Power?") as num explosion_iter(get_turf(mob), power, (UP|DOWN)) else @@ -642,13 +644,10 @@ var/global/list/admin_verbs_mod = list( set name = "Toggle href logging" set category = "Server" if(!holder) return - if(config) - if(config.log_hrefs) - config.log_hrefs = 0 - to_chat(src, "Stopped logging hrefs") - else - config.log_hrefs = 1 - to_chat(src, "Started logging hrefs") + if(toggle_config_value(/decl/config/toggle/log_hrefs)) + to_chat(src, "Started logging hrefs") + else + to_chat(src, "Stopped logging hrefs") /client/proc/check_ai_laws() set name = "Check AI Laws" @@ -760,22 +759,25 @@ var/global/list/admin_verbs_mod = list( switch(alert("Are you sure you wish to edit this mob's appearance? This can result in unintended consequences.",,"Yes","No")) if("No") return + + var/update_hair = FALSE var/new_facial = input("Please select facial hair color.", "Character Generation") as color if(new_facial) - M.facial_hair_colour = new_facial + M.set_facial_hair_colour(new_facial, skip_update = TRUE) + update_hair = TRUE var/new_hair = input("Please select hair color.", "Character Generation") as color if(new_hair) - M.hair_colour = new_hair + M.set_hair_colour(new_hair, skip_update = TRUE) + update_hair = TRUE var/new_eyes = input("Please select eye color.", "Character Generation") as color if(new_eyes) - M.eye_colour = new_eyes - M.update_eyes() + M.set_eye_colour(new_eyes) var/new_skin = input("Please select body color.", "Character Generation") as color if(new_skin) - M.skin_colour = new_skin + M.set_skin_colour(new_skin, skip_update = TRUE) var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text @@ -784,14 +786,16 @@ var/global/list/admin_verbs_mod = list( M.skin_tone = -M.skin_tone + 35 // hair - var/new_hstyle = input(usr, "Select a hair style", "Grooming") as null|anything in decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/hair) - if(new_hstyle) - M.h_style = new_hstyle + var/new_hairstyle = input(usr, "Select a hair style", "Grooming") as null|anything in decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/hair) + if(new_hairstyle) + M.set_hairstyle(new_hairstyle, skip_update = TRUE) + update_hair = TRUE // facial hair var/new_fstyle = input(usr, "Select a facial hair style", "Grooming") as null|anything in decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/facial_hair) if(new_fstyle) - M.f_style = new_fstyle + M.set_facial_hairstyle(new_fstyle, skip_update = TRUE) + update_hair = TRUE var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neuter") if (new_gender) @@ -802,7 +806,8 @@ var/global/list/admin_verbs_mod = list( else M.set_gender(NEUTER) - M.update_hair() + if(update_hair) + M.update_hair() M.update_body() M.check_dna(M) @@ -858,30 +863,25 @@ var/global/list/admin_verbs_mod = list( /client/proc/toggleghostwriters() set name = "Toggle ghost writers" set category = "Server" - if(!holder) return - if(config) - if(config.cult_ghostwriter) - config.cult_ghostwriter = 0 - to_chat(src, "Disallowed ghost writers.") - message_admins("Admin [key_name_admin(usr)] has disabled ghost writers.", 1) - else - config.cult_ghostwriter = 1 - to_chat(src, "Enabled ghost writers.") - message_admins("Admin [key_name_admin(usr)] has enabled ghost writers.", 1) + if(!holder) + return + if(toggle_config_value(/decl/config/toggle/on/cult_ghostwriter)) + to_chat(src, "Enabled ghost writers.") + message_admins("Admin [key_name_admin(usr)] has enabled ghost writers.", 1) + else + to_chat(src, "Disallowed ghost writers.") + message_admins("Admin [key_name_admin(usr)] has disabled ghost writers.", 1) /client/proc/toggledrones() set name = "Toggle maintenance drones" set category = "Server" if(!holder) return - if(config) - if(config.allow_drone_spawn) - config.allow_drone_spawn = 0 - to_chat(src, "Disallowed maint drones.") - message_admins("Admin [key_name_admin(usr)] has disabled maint drones.", 1) - else - config.allow_drone_spawn = 1 - to_chat(src, "Enabled maint drones.") - message_admins("Admin [key_name_admin(usr)] has enabled maint drones.", 1) + if(toggle_config_value(/decl/config/toggle/on/allow_drone_spawn)) + to_chat(src, "Enabled maint drones.") + message_admins("Admin [key_name_admin(usr)] has enabled maint drones.", 1) + else + to_chat(src, "Disallowed maint drones.") + message_admins("Admin [key_name_admin(usr)] has disabled maint drones.", 1) /client/proc/man_up(mob/T as mob in SSmobs.mob_list) set category = "Fun" diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index 0b697a418dc..6d8057e82c4 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -24,9 +24,9 @@ var/global/jobban_keylist[0] //to store the keys & ranks var/decl/special_role/antag = GET_DECL(rank) rank = antag.name if (SSjobs.guest_jobbans(rank)) - if(config.guest_jobban && IsGuestKey(M.key)) + if(get_config_value(/decl/config/toggle/on/guest_jobban) && IsGuestKey(M.key)) return "Guest Job-ban" - if(config.usewhitelist && !check_whitelist(M)) + if(get_config_value(/decl/config/toggle/usewhitelist) && !check_whitelist(M)) return "Whitelisted Job" return ckey_is_jobbanned(M.ckey, rank) return 0 @@ -47,7 +47,7 @@ var/global/jobban_keylist[0] //to store the keys & ranks return 1 /proc/jobban_loadbanfile() - if(config.ban_legacy_system) + if(get_config_value(/decl/config/toggle/on/ban_legacy_system)) var/savefile/S=new("data/job_full.ban") from_savefile(S, "keys[0]", jobban_keylist) log_admin("Loading jobban_rank") @@ -60,7 +60,7 @@ var/global/jobban_keylist[0] //to store the keys & ranks if(!establish_db_connection()) error("Database connection failed. Reverting to the legacy ban system.") log_misc("Database connection failed. Reverting to the legacy ban system.") - config.ban_legacy_system = 1 + set_config_value(/decl/config/toggle/on/ban_legacy_system, TRUE) jobban_loadbanfile() return diff --git a/code/modules/admin/buildmode/areas.dm b/code/modules/admin/buildmode/areas.dm index 88ba2c22f5c..6b76fdba3b2 100644 --- a/code/modules/admin/buildmode/areas.dm +++ b/code/modules/admin/buildmode/areas.dm @@ -97,12 +97,12 @@ Right Click - List/Create Area return UnselectArea() selected_area = A - events_repository.register(/decl/observ/destroyed, selected_area, src, .proc/UnselectArea) + events_repository.register(/decl/observ/destroyed, selected_area, src, PROC_REF(UnselectArea)) /datum/build_mode/areas/proc/UnselectArea() if(!selected_area) return - events_repository.unregister(/decl/observ/destroyed, selected_area, src, .proc/UnselectArea) + events_repository.unregister(/decl/observ/destroyed, selected_area, src, PROC_REF(UnselectArea)) var/has_turf = FALSE for(var/turf/T in selected_area) diff --git a/code/modules/admin/buildmode/click_handler.dm b/code/modules/admin/buildmode/click_handler.dm index 15e20226ed0..fcb7bb91f8b 100644 --- a/code/modules/admin/buildmode/click_handler.dm +++ b/code/modules/admin/buildmode/click_handler.dm @@ -36,7 +36,7 @@ . = ..() /datum/click_handler/build_mode/proc/StartTimer() - timer_handle = addtimer(CALLBACK(src, .proc/TimerEvent), 1 SECOND, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_LOOP) + timer_handle = addtimer(CALLBACK(src, PROC_REF(TimerEvent)), 1 SECOND, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_LOOP) /datum/click_handler/build_mode/proc/StopTimer() deltimer(timer_handle) diff --git a/code/modules/admin/buildmode/edit.dm b/code/modules/admin/buildmode/edit.dm index a0505f46678..23bcdc47596 100644 --- a/code/modules/admin/buildmode/edit.dm +++ b/code/modules/admin/buildmode/edit.dm @@ -63,13 +63,13 @@ ClearValue() value_to_set = new_value if(istype(value_to_set, /datum)) - events_repository.register(/decl/observ/destroyed, value_to_set, src, /datum/build_mode/edit/proc/ClearValue) + events_repository.register(/decl/observ/destroyed, value_to_set, src, TYPE_PROC_REF(/datum/build_mode/edit, ClearValue)) /datum/build_mode/edit/proc/ClearValue(var/feedback) if(!istype(value_to_set, /datum)) return - events_repository.unregister(/decl/observ/destroyed, value_to_set, src, /datum/build_mode/edit/proc/ClearValue) + events_repository.unregister(/decl/observ/destroyed, value_to_set, src, TYPE_PROC_REF(/datum/build_mode/edit, ClearValue)) value_to_set = initial(value_to_set) if(feedback) Warn("The selected reference value was deleted. Default value restored.") diff --git a/code/modules/admin/buildmode/move_into.dm b/code/modules/admin/buildmode/move_into.dm index 75dba96f501..ce045fb7f39 100644 --- a/code/modules/admin/buildmode/move_into.dm +++ b/code/modules/admin/buildmode/move_into.dm @@ -33,14 +33,14 @@ ClearDestination() destination = A - events_repository.register(/decl/observ/destroyed, destination, src, /datum/build_mode/move_into/proc/ClearDestination) + events_repository.register(/decl/observ/destroyed, destination, src, TYPE_PROC_REF(/datum/build_mode/move_into, ClearDestination)) to_chat(user, "Will now move targets into \the [destination].") /datum/build_mode/move_into/proc/ClearDestination(var/feedback) if(!destination) return - events_repository.unregister(/decl/observ/destroyed, destination, src, /datum/build_mode/move_into/proc/ClearDestination) + events_repository.unregister(/decl/observ/destroyed, destination, src, TYPE_PROC_REF(/datum/build_mode/move_into, ClearDestination)) destination = null if(feedback) Warn("The selected destination was deleted.") diff --git a/code/modules/admin/buildmode/relocate_to.dm b/code/modules/admin/buildmode/relocate_to.dm index 1a2e77340c7..e0c3680993d 100644 --- a/code/modules/admin/buildmode/relocate_to.dm +++ b/code/modules/admin/buildmode/relocate_to.dm @@ -34,14 +34,14 @@ ClearRelocator() to_relocate = new_relocator - events_repository.register(/decl/observ/destroyed, to_relocate, src, /datum/build_mode/relocate_to/proc/ClearRelocator) + events_repository.register(/decl/observ/destroyed, to_relocate, src, TYPE_PROC_REF(/datum/build_mode/relocate_to, ClearRelocator)) to_chat(user, "Will now be relocating \the [to_relocate].") /datum/build_mode/relocate_to/proc/ClearRelocator(var/feedback) if(!to_relocate) return - events_repository.unregister(/decl/observ/destroyed, to_relocate, src, /datum/build_mode/relocate_to/proc/ClearRelocator) + events_repository.unregister(/decl/observ/destroyed, to_relocate, src, TYPE_PROC_REF(/datum/build_mode/relocate_to, ClearRelocator)) to_relocate = null if(feedback) Warn("The selected relocation object was deleted.") diff --git a/code/modules/admin/buildmode/throw_at.dm b/code/modules/admin/buildmode/throw_at.dm index 068a89a1d1c..581e2077757 100644 --- a/code/modules/admin/buildmode/throw_at.dm +++ b/code/modules/admin/buildmode/throw_at.dm @@ -33,14 +33,14 @@ ClearThrowable() to_throw = new_throwable - events_repository.register(/decl/observ/destroyed, to_throw, src, /datum/build_mode/throw_at/proc/ClearThrowable) + events_repository.register(/decl/observ/destroyed, to_throw, src, TYPE_PROC_REF(/datum/build_mode/throw_at, ClearThrowable)) to_chat(user, "Will now be throwing \the [to_throw].") /datum/build_mode/throw_at/proc/ClearThrowable(var/feedback) if(!to_throw) return - events_repository.unregister(/decl/observ/destroyed, to_throw, src, /datum/build_mode/throw_at/proc/ClearThrowable) + events_repository.unregister(/decl/observ/destroyed, to_throw, src, TYPE_PROC_REF(/datum/build_mode/throw_at, ClearThrowable)) to_throw = null if(feedback) Warn("The selected throwing object was deleted.") diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index bc841bf43fd..4cdf5e8c089 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -6,7 +6,7 @@ set name = "Advanced ProcCall" if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return + if(get_config_value(/decl/config/toggle/paranoid) && !check_rights(R_ADMIN)) return var/target = null var/targetselected = 0 @@ -41,7 +41,7 @@ set name = "Advanced ProcCall Target" if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return + if(get_config_value(/decl/config/toggle/paranoid) && !check_rights(R_ADMIN)) return callproc_targetpicked(1, A) @@ -51,7 +51,7 @@ /client/proc/callproc_targetpicked(hastarget, datum/target) // this needs checking again here because VV's 'Call Proc' option directly calls this proc with the target datum if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return + if(get_config_value(/decl/config/toggle/paranoid) && !check_rights(R_ADMIN)) return if(!holder.callproc) holder.callproc = new(src) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index af9881d7406..4b05b4d2538 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -121,7 +121,8 @@ NOTE: It checks usr by default. Supply the "user" argument if you wish to check if(!holder) return FALSE - var/auto_stealth = (inactivity >= world.time) || (config.autostealth && (inactivity >= MinutesToTicks(config.autostealth))) + var/config_autostealth = get_config_value(/decl/config/num/autostealth) + var/auto_stealth = (inactivity >= world.time) || (config_autostealth && (inactivity >= config_autostealth MINUTES)) // If someone has been AFK since round-start or longer, stealth them // BYOND keeps track of inactivity between rounds as long as it's not a full stop/start. if(holder.stealthy_ == STEALTH_OFF && auto_stealth) diff --git a/code/modules/admin/panicbunker.dm b/code/modules/admin/panicbunker.dm index 8ca0b8fae53..bd215380d72 100644 --- a/code/modules/admin/panicbunker.dm +++ b/code/modules/admin/panicbunker.dm @@ -6,11 +6,9 @@ var/global/list/panic_bunker_bypass = list() if(!check_rights(R_SERVER)) return - - config.panic_bunker = !config.panic_bunker - - log_and_message_admins("[key_name(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker ? "on" : "off")]") - if (config.panic_bunker && (!dbcon || !dbcon.IsConnected())) + toggle_config_value(/decl/config/toggle/panic_bunker) + log_and_message_admins("[key_name(usr)] has toggled the Panic Bunker, it is now [(get_config_value(/decl/config/toggle/panic_bunker) ? "on" : "off")]") + if (get_config_value(/decl/config/toggle/panic_bunker) && (!dbcon || !dbcon.IsConnected())) message_admins("The SQL database is not connected, player age cannot be checked and the panic bunker will not function until the database connection is restored.") /datum/admins/proc/addbunkerbypass(ckeytobypass as text) diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index eb81b27a463..add6b917af5 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -45,7 +45,8 @@ show_browser(usr, output, "window=editrights;size=600x500") /datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank) - if(config.admin_legacy_system) return + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) + return if(!usr.client) return @@ -95,7 +96,8 @@ to_chat(usr, "Admin rank changed.") /datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission) - if(config.admin_legacy_system) return + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) + return if(!usr.client) return diff --git a/code/modules/admin/secrets/fun_secrets/waddle.dm b/code/modules/admin/secrets/fun_secrets/waddle.dm index f1cfc8b6e7b..f4d7e86e251 100644 --- a/code/modules/admin/secrets/fun_secrets/waddle.dm +++ b/code/modules/admin/secrets/fun_secrets/waddle.dm @@ -7,8 +7,8 @@ if(waddling) for(var/mob/living/living_mob in global.living_mob_list_) set_extension(living_mob, /datum/extension/waddle) - events_repository.register_global(/decl/observ/life, src, .proc/enroll_in_waddling) - events_repository.register_global(/decl/observ/death, src, .proc/cure_waddling) + events_repository.register_global(/decl/observ/life, src, PROC_REF(enroll_in_waddling)) + events_repository.register_global(/decl/observ/death, src, PROC_REF(cure_waddling)) else for(var/mob/living/living_mob in global.living_mob_list_) cure_waddling(living_mob) @@ -32,8 +32,8 @@ /datum/extension/waddle/New(datum/holder) . = ..() - events_repository.register(/decl/observ/moved, holder, src, .proc/waddle) - events_repository.register(/decl/observ/destroyed, holder, src, .proc/qdel_self) + events_repository.register(/decl/observ/moved, holder, src, PROC_REF(waddle)) + events_repository.register(/decl/observ/destroyed, holder, src, PROC_REF(qdel_self)) /datum/extension/event_registration/Destroy() events_repository.unregister(/decl/observ/destroyed, holder, src) diff --git a/code/modules/admin/spam_prevention.dm b/code/modules/admin/spam_prevention.dm index 69eb5783d62..10d9adab7fe 100644 --- a/code/modules/admin/spam_prevention.dm +++ b/code/modules/admin/spam_prevention.dm @@ -7,14 +7,14 @@ var/global/list/ckey_punished_for_spam = list() // this round; to avoid redundan var/ckey = C && C.ckey if(!ckey) return FALSE - if (config.do_not_prevent_spam) + if(get_config_value(/decl/config/toggle/do_not_prevent_spam)) return TRUE var/time = world.time - if(global.ckey_to_act_time[ckey] + config.act_interval < time) + if(global.ckey_to_act_time[ckey] + (get_config_value(/decl/config/num/act_interval) SECONDS) < time) global.ckey_to_act_time[ckey] = time global.ckey_to_actions[ckey] = 1 return TRUE - if(global.ckey_to_actions[ckey] <= config.max_acts_per_interval) + if(global.ckey_to_actions[ckey] <= get_config_value(/decl/config/num/max_acts_per_interval)) global.ckey_to_actions[ckey]++ return TRUE diff --git a/code/modules/admin/ticket.dm b/code/modules/admin/ticket.dm index 694d8524929..d394a86cd0c 100644 --- a/code/modules/admin/ticket.dm +++ b/code/modules/admin/ticket.dm @@ -20,7 +20,7 @@ var/global/list/ticket_panels = list() var/sql_ckey = sanitize_sql(owner.ckey) var/DBQuery/ticket_query = dbcon.NewQuery("INSERT INTO `erro_admin_tickets`(`ckey`, `round`, `inround_id`, `status`, `open_date`) VALUES ('[sql_ckey]', '[game_id]', [src.id], 'OPEN', NOW());") ticket_query.Execute() - addtimer(CALLBACK(src, .proc/timeoutcheck), 5 MINUTES) + addtimer(CALLBACK(src, PROC_REF(timeoutcheck)), 5 MINUTES) /datum/ticket/proc/timeoutcheck() if(status == TICKET_OPEN) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 2377540c121..e2e0a2f356b 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -140,19 +140,19 @@ if(null,"") return if("*New Rank*") new_rank = input("Please input a new rank", "New custom rank", null, null) as null|text - if(config.admin_legacy_system) + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) new_rank = ckeyEx(new_rank) if(!new_rank) to_chat(usr, SPAN_WARNING("Error: Topic 'editrights': Invalid rank")) return - if(config.admin_legacy_system) + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) if(admin_ranks.len) if(new_rank in admin_ranks) rights = admin_ranks[new_rank] //we typed a rank which already exists, use its rights else admin_ranks[new_rank] = 0 //add the new rank to admin_ranks else - if(config.admin_legacy_system) + if(get_config_value(/decl/config/toggle/on/admin_legacy_system)) new_rank = ckeyEx(new_rank) rights = admin_ranks[new_rank] //we input an existing rank, use its rights @@ -418,7 +418,7 @@ to_chat(usr, "You do not have the appropriate permissions to add job bans!") return - if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0) && !config.mods_can_job_tempban) // If mod and tempban disabled + if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0) && !get_config_value(/decl/config/toggle/mods_can_job_tempban)) // If mod and tempban disabled to_chat(usr, "Mod jobbanning is disabled!") return @@ -464,14 +464,15 @@ if(!check_rights(R_MOD,0) && !check_rights(R_BAN, 0)) to_chat(usr, " You cannot issue temporary job-bans!") return - if(config.ban_legacy_system) + if(get_config_value(/decl/config/toggle/on/ban_legacy_system)) to_chat(usr, "Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.") return var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null if(!mins) return - if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_job_tempban_max) - to_chat(usr, " Moderators can only job tempban up to [config.mod_job_tempban_max] minutes!") + var/mod_job_tempban_max = get_config_value(/decl/config/num/mod_job_tempban_max) + if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > mod_job_tempban_max) + to_chat(usr, " Moderators can only job tempban up to [mod_job_tempban_max] minutes!") return var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null) if(!reason) @@ -524,7 +525,7 @@ //Unbanning job list //all jobs in job list are banned already OR we didn't give a reason (implying they shouldn't be banned) if(LAZYLEN(SSjobs.titles_to_datums)) //at least 1 banned job exists in job list so we have stuff to unban. - if(!config.ban_legacy_system) + if(!get_config_value(/decl/config/toggle/on/ban_legacy_system)) to_chat(usr, "Unfortunately, database based unbanning cannot be done through this panel") DB_ban_panel(M.ckey) return @@ -584,7 +585,7 @@ to_chat(usr, "You do not have the appropriate permissions to add bans!") return - if(check_rights(R_MOD,0) && !check_rights(R_ADMIN, 0) && !config.mods_can_job_tempban) // If mod and tempban disabled + if(check_rights(R_MOD,0) && !check_rights(R_ADMIN, 0) && !get_config_value(/decl/config/toggle/mods_can_job_tempban)) // If mod and tempban disabled to_chat(usr, "Mod jobbanning is disabled!") return @@ -603,8 +604,9 @@ var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null if(!mins) return - if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_tempban_max) - to_chat(usr, "Moderators can only job tempban up to [config.mod_tempban_max] minutes!") + var/mod_tempban_max = get_config_value(/decl/config/num/mod_tempban_max) + if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > mod_tempban_max) + to_chat(usr, "Moderators can only job tempban up to [mod_tempban_max] minutes!") return if(mins >= 525600) mins = 525599 var/reason = sanitize(input(usr,"Reason?","reason","Griefer") as text|null) @@ -624,8 +626,9 @@ SSstatistics.add_field("ban_tmp",1) DB_ban_record(BANTYPE_TEMP, M, mins, reason) SSstatistics.add_field("ban_tmp_mins",mins) - if(config.banappeals) - to_chat(M, "To try to resolve this matter head to [config.banappeals]") + var/banappeals = get_config_value(/decl/config/text/banappeals) + if(banappeals) + to_chat(M, "To try to resolve this matter head to [banappeals]") else to_chat(M, "No ban appeals URL has been set.") log_and_message_admins("has banned [mob_key].\nReason: [reason]\nThis will be removed in [mins_readable].") @@ -650,8 +653,9 @@ AddBan(mob_key, M.computer_id, reason, usr.ckey, 0, 0) to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].") to_chat(M, "This is a ban until appeal.") - if(config.banappeals) - to_chat(M, "To try to resolve this matter head to [config.banappeals]") + var/banappeals = get_config_value(/decl/config/text/banappeals) + if(banappeals) + to_chat(M, "To try to resolve this matter head to [banappeals]") else to_chat(M, "No ban appeals URL has been set.") ban_unban_log_save("[usr.client.ckey] has permabanned [mob_key]. - Reason: [reason] - This is a ban until appeal.") @@ -684,8 +688,9 @@ if(SSticker.mode) return alert(usr, "The game has already started.", null, null, null, null) var/dat = {"What mode do you wish to play?
    "} - for(var/mode in config.modes) - dat += {"[config.mode_names[mode]]
    "} + var/list/mode_names = get_config_value(/decl/config/lists/mode_names) + for(var/mode in get_config_value(/decl/config/lists/mode_allowed)) + dat += {"[mode_names[mode]]
    "} dat += {"Secret
    "} dat += {"Random
    "} dat += {"Now: [SSticker.master_mode]"} @@ -699,8 +704,9 @@ if(SSticker.master_mode != "secret") return alert(usr, "The game mode has to be secret!", null, null, null, null) var/dat = {"What game mode do you want to force secret to be? Use this if you want to change the game mode, but want the players to believe it's secret. This will only work if the current game mode is secret.
    "} - for(var/mode in config.modes) - dat += {"[config.mode_names[mode]]
    "} + var/list/mode_names = get_config_value(/decl/config/lists/mode_names) + for(var/mode in get_config_value(/decl/config/lists/mode_allowed)) + dat += {"[mode_names[mode]]
    "} dat += {"Random (default)
    "} dat += {"Now: [secret_force_mode]"} show_browser(usr, dat, "window=f_secret") @@ -773,7 +779,7 @@ to_chat(usr, "This can only be used on instances of type /mob/living") return - if(config.allow_admin_rev) + if(get_config_value(/decl/config/toggle/on/admin_revive)) L.revive() log_and_message_admins("healed/revived [key_name(L)]") else @@ -1157,7 +1163,7 @@ else if(href_list["object_list"]) //this is the laggiest thing ever if(!check_rights(R_SPAWN)) return - if(!config.allow_admin_spawning) + if(!get_config_value(/decl/config/toggle/on/admin_spawning)) to_chat(usr, "Spawning of items is not allowed.") return diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index a44fae79380..f1f4d7130d9 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -11,7 +11,7 @@ set category = "Admin" if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(!config.allow_admin_jump) + if(!get_config_value(/decl/config/toggle/on/admin_jump)) return alert("Admin jumping disabled") var/list/areas = area_repository.get_areas_by_z_level() @@ -25,7 +25,7 @@ set category = "Admin" if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(!config.allow_admin_jump) + if(!get_config_value(/decl/config/toggle/on/admin_jump)) return alert("Admin jumping disabled") log_and_message_admins("jumped to [T.x],[T.y],[T.z] in [T.loc]") @@ -39,7 +39,7 @@ if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(config.allow_admin_jump) + if(get_config_value(/decl/config/toggle/on/admin_jump)) log_and_message_admins("jumped to [key_name(M)]") if(mob) var/turf/T = get_turf(M) @@ -58,7 +58,7 @@ if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(!config.allow_admin_jump) + if(!get_config_value(/decl/config/toggle/on/admin_jump)) alert("Admin jumping disabled") return if(!mob) @@ -82,7 +82,7 @@ if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(config.allow_admin_jump) + if(get_config_value(/decl/config/toggle/on/admin_jump)) if(!istype(C)) to_chat(usr, "[C] is not a client, somehow.") return @@ -100,7 +100,7 @@ set desc = "Mob to teleport" if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(config.allow_admin_jump) + if(get_config_value(/decl/config/toggle/on/admin_jump)) log_and_message_admins("teleported [key_name(M)] to self.") M.jumpTo(get_turf(mob)) SSstatistics.add_field_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -115,7 +115,7 @@ if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(config.allow_admin_jump) + if(get_config_value(/decl/config/toggle/on/admin_jump)) var/list/keys = list() for(var/mob/M in global.player_list) keys += M.client @@ -138,7 +138,7 @@ set name = "Send Mob" if(!check_rights(R_ADMIN|R_MOD|R_DEBUG)) return - if(!config.allow_admin_jump) + if(!get_config_value(/decl/config/toggle/on/admin_jump)) alert("Admin jumping disabled") return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index da9195800ca..9d9b1e0b6b1 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -109,8 +109,8 @@ to_chat(C, recieve_message) C.adminhelped = 0 - //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn - if(config.popup_admin_pm) + //AdminPM popup for ApocStation and anybody else who wants to use it. + if(get_config_value(/decl/config/toggle/popup_admin_pm)) spawn(0) //so we don't hold the caller proc up var/sender = src var/sendername = key diff --git a/code/modules/admin/verbs/custom_event.dm b/code/modules/admin/verbs/custom_event.dm index dc7b8e732a0..4574117732c 100644 --- a/code/modules/admin/verbs/custom_event.dm +++ b/code/modules/admin/verbs/custom_event.dm @@ -7,11 +7,11 @@ to_chat(src, "Only administrators may use this command.") return - var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_BOOK_MESSAGE_LEN, extra = 0) + var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", global.custom_event_msg) as message|null, MAX_BOOK_MESSAGE_LEN, extra = 0) if(isnull(input)) return if(input == "") - custom_event_msg = null + global.custom_event_msg = null log_admin("[usr.key] has cleared the custom event text.") message_admins("[key_name_admin(usr)] has cleared the custom event text.") return @@ -19,26 +19,26 @@ log_admin("[usr.key] has changed the custom event text.") message_admins("[key_name_admin(usr)] has changed the custom event text.") - custom_event_msg = input + global.custom_event_msg = input to_world("

    Custom Event

    ") to_world("

    A custom event is starting. OOC Info:

    ") - to_world("[custom_event_msg]") + to_world("[global.custom_event_msg]") to_world("
    ") - SSwebhooks.send(WEBHOOK_CUSTOM_EVENT, list("text" = custom_event_msg)) + SSwebhooks.send(WEBHOOK_CUSTOM_EVENT, list("text" = global.custom_event_msg)) // normal verb for players to view info /client/verb/cmd_view_custom_event() set category = "OOC" set name = "Custom Event Info" - if(!custom_event_msg || custom_event_msg == "") + if(!global.custom_event_msg) to_chat(src, "There currently is no known custom event taking place.") to_chat(src, "Keep in mind: it is possible that an admin has not properly set this.") return to_chat(src, "

    Custom Event

    ") to_chat(src, "

    A custom event is taking place. OOC Info:

    ") - to_chat(src, "[custom_event_msg]") + to_chat(src, "[global.custom_event_msg]") to_chat(src, "
    ") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 58a8b86009f..ac22aeefe32 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -128,10 +128,13 @@ /client/proc/cmd_debug_tog_aliens() set category = "Server" set name = "Toggle Aliens" + if(toggle_config_value(/decl/config/toggle/aliens_allowed)) + log_admin("[key_name(src)] has turned aliens on.") + message_admins("[key_name_admin(src)] has turned aliens on.", 0) + else + log_admin("[key_name(src)] has turned aliens off.") + message_admins("[key_name_admin(src)] has turned aliens off.", 0) - config.aliens_allowed = !config.aliens_allowed - log_admin("[key_name(src)] has turned aliens [config.aliens_allowed ? "on" : "off"].") - message_admins("[key_name_admin(src)] has turned aliens [config.aliens_allowed ? "on" : "off"].", 0) SSstatistics.add_field_details("admin_verb","TAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/cmd_admin_grantfullaccess(var/mob/M in SSmobs.mob_list) diff --git a/code/modules/admin/verbs/fluids.dm b/code/modules/admin/verbs/fluids.dm index ca22c5fd109..d3e5e0d0204 100644 --- a/code/modules/admin/verbs/fluids.dm +++ b/code/modules/admin/verbs/fluids.dm @@ -3,7 +3,7 @@ set desc = "Flood the turf you are standing on." set category = "Debug" - if(!check_rights(R_SPAWN)) + if(!check_rights(R_SPAWN)) return var/mob/user = usr @@ -18,7 +18,7 @@ return var/turf/flooding = get_turf(user) for(var/turf/T as anything in RANGE_TURFS(flooding, spawn_range)) - T.add_fluid(reagent_type, reagent_amount) + T.add_to_reagents(reagent_type, reagent_amount) /datum/admins/proc/jump_to_fluid_source() diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index cccbc4dfd41..603633ae184 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -3,7 +3,7 @@ set category = "Object" if(istype(O,/obj/effect/singularity)) - if(config.forbid_singulo_possession) + if(get_config_value(/decl/config/toggle/forbid_singulo_possession)) to_chat(usr, "It is forbidden to possess singularities.") return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 02b93e28284..76f60d0fe5b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -83,7 +83,7 @@ return if (style == "unsafe") - if (!config.allow_unsafe_narrates) + if (!get_config_value(/decl/config/toggle/allow_unsafe_narrates)) to_chat(user, SPAN_WARNING("Unsafe narrates are not permitted by the server configuration.")) return @@ -291,8 +291,7 @@ Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly Ccomp's first proc. */ - -/client/proc/get_ghosts(var/notify = 0,var/what = 2) +/proc/get_ghosts(var/notify, var/what = 2) // what = 1, return ghosts ass list. // what = 2, return mob list @@ -305,16 +304,14 @@ Ccomp's first proc. any = 1 //if no ghosts show up, any will just be 0 if(!any) if(notify) - to_chat(src, "There doesn't appear to be any ghosts for you to select.") + to_chat(notify, "There doesn't appear to be any ghosts for you to select.") return - for(var/mob/M in mobs) var/name = M.name ghosts[name] = M //get the name of the mob for the popup list - if(what==1) + if(what == 1) return ghosts - else - return mobs + return mobs /client/proc/get_ghosts_by_key() . = list() @@ -336,7 +333,7 @@ Ccomp's first proc. to_chat(src, "[selection] no longer has an associated ghost.") return - if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + if(G.has_enabled_antagHUD == 1 && get_config_value(/decl/config/toggle/antag_hud_restricted)) var/response = alert(src, "[selection] has enabled antagHUD. Are you sure you wish to allow them to respawn?","Ghost has used AntagHUD","No","Yes") if(response == "No") return else @@ -351,7 +348,7 @@ Ccomp's first proc. G.can_reenter_corpse = CORPSE_CAN_REENTER_AND_RESPAWN G.show_message("You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.", 1) - log_and_message_admins("has allowed [key_name(G)] to bypass the [config.respawn_delay] minute respawn limit.") + log_and_message_admins("has allowed [key_name(G)] to bypass the [get_config_value(/decl/config/num/respawn_delay)] minute respawn limit.") /client/proc/toggle_antagHUD_use() set category = "Server" @@ -360,34 +357,13 @@ Ccomp's first proc. if(!holder) to_chat(src, "Only administrators may use this command.") - var/action="" - if(config.antag_hud_allowed) - for(var/mob/observer/ghost/g in get_ghosts()) - if(!g.client.holder) //Remove the verb from non-admin ghosts - g.verbs -= /mob/observer/ghost/verb/toggle_antagHUD - if(g.antagHUD) - g.antagHUD = 0 // Disable it on those that have it enabled - g.has_enabled_antagHUD = 2 // We'll allow them to respawn - to_chat(g, "The Administrator has disabled AntagHUD") - config.antag_hud_allowed = 0 - to_chat(src, "AntagHUD usage has been disabled") - action = "disabled" - else - for(var/mob/observer/ghost/g in get_ghosts()) - if(!g.client.holder) // Add the verb back for all non-admin ghosts - g.verbs += /mob/observer/ghost/verb/toggle_antagHUD - to_chat(g, "The Administrator has enabled AntagHUD ")// Notify all observers they can now use AntagHUD - - config.antag_hud_allowed = 1 + var/action = "disabled" + if(toggle_config_value(/decl/config/toggle/antag_hud_allowed)) action = "enabled" - to_chat(src, "AntagHUD usage has been enabled") - - + to_chat(src, "AntagHUD usage has been [action]") log_admin("[key_name(usr)] has [action] antagHUD usage for observers") message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) - - /client/proc/toggle_antagHUD_restrictions() set category = "Server" set name = "Toggle antagHUD Restrictions" @@ -395,22 +371,19 @@ Ccomp's first proc. if(!holder) to_chat(src, "Only administrators may use this command.") var/action="" - if(config.antag_hud_restricted) - for(var/mob/observer/ghost/g in get_ghosts()) - to_chat(g, "The administrator has lifted restrictions on joining the round if you use AntagHUD") - action = "lifted restrictions" - config.antag_hud_restricted = 0 - to_chat(src, "AntagHUD restrictions have been lifted") - else - for(var/mob/observer/ghost/g in get_ghosts()) + if(toggle_config_value(/decl/config/toggle/antag_hud_restricted)) + for(var/mob/observer/ghost/g in get_ghosts(src)) to_chat(g, "The administrator has placed restrictions on joining the round if you use AntagHUD") to_chat(g, "Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions") g.antagHUD = 0 g.has_enabled_antagHUD = 0 action = "placed restrictions" - config.antag_hud_restricted = 1 to_chat(src, "AntagHUD restrictions have been enabled") - + else + for(var/mob/observer/ghost/g in get_ghosts(src)) + to_chat(g, "The administrator has lifted restrictions on joining the round if you use AntagHUD") + action = "lifted restrictions" + to_chat(src, "AntagHUD restrictions have been lifted") log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) @@ -545,7 +518,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!istype(M)) alert("Cannot revive a ghost") return - if(config.allow_admin_rev) + if(get_config_value(/decl/config/toggle/on/admin_revive)) M.revive() log_and_message_admins("healed / revived [key_name_admin(M)]!") @@ -665,21 +638,13 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/cmd_admin_gib(mob/M as mob in SSmobs.mob_list) set category = "Special Verbs" set name = "Gib" - if(!check_rights(R_ADMIN|R_FUN)) return - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return //Due to the delay here its easy for something to have happened to the mob if(!M) return - log_admin("[key_name(usr)] has gibbed [key_name(M)]") message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]", 1) - - if(isobserver(M)) - gibs(M.loc) - return - M.gib() SSstatistics.add_field_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -828,12 +793,11 @@ Traitors and the like can also be revived with the previous role mostly intact. set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" if(!check_rights(R_SERVER)) return - if(!config.allow_random_events) - config.allow_random_events = 1 + toggle_config_value(/decl/config/toggle/allow_random_events) + if(get_config_value(/decl/config/toggle/allow_random_events)) to_chat(usr, "Random events enabled") message_admins("Admin [key_name_admin(usr)] has enabled random events.", 1) else - config.allow_random_events = 0 to_chat(usr, "Random events disabled") message_admins("Admin [key_name_admin(usr)] has disabled random events.", 1) SSstatistics.add_field_details("admin_verb","TRE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index b2a1ebfc8ef..8e3350b0407 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -142,9 +142,6 @@ /datum/proc/VV_secluded() return list() -/datum/configuration/VV_secluded() - return vars - // The following vars cannot be edited by anyone /datum/proc/VV_static() return list("parent_type", "gc_destroyed", "is_processing") @@ -191,7 +188,7 @@ if(!(var_to_edit in VV_get_variables())) to_chat(user, "\The [src] does not have a var '[var_to_edit]'") return FALSE - if(var_to_edit in VV_static()) + if((var_to_edit in VV_static()) || (var_to_edit in VV_hidden())) return FALSE if((var_to_edit in VV_secluded()) && !check_rights(R_ADMIN|R_DEBUG, FALSE, C = user)) return FALSE diff --git a/code/modules/aspects/aspects.dm b/code/modules/aspects/aspects.dm index be9036b2e73..64621e2726d 100644 --- a/code/modules/aspects/aspects.dm +++ b/code/modules/aspects/aspects.dm @@ -103,7 +103,7 @@ var/global/list/aspect_categories = list() // Containers for ease of printing da incompatible_aspect_taken = TRUE break - if(istype(caller) && (ticked || caller.get_aspect_total() + aspect_cost <= config.max_character_aspects) && !incompatible_aspect_taken) + if(istype(caller) && (ticked || caller.get_aspect_total() + aspect_cost <= get_config_value(/decl/config/num/max_character_aspects)) && !incompatible_aspect_taken) result += "[ticked ? "[name]" : "[name]"] ([aspect_cost])" else result += ticked ? "[name]" : "[name]" @@ -130,7 +130,7 @@ var/global/list/aspect_categories = list() // Containers for ease of printing da for(var/decl/aspect/A as anything in personal_aspects) aspect_cost += A.aspect_cost - var/dat = list("[aspect_cost]/[config.max_character_aspects] points spent.") + var/dat = list("[aspect_cost]/[get_config_value(/decl/config/num/max_character_aspects)] points spent.") for(var/aspect_category in global.aspect_categories) var/datum/aspect_category/AC = global.aspect_categories[aspect_category] if(!istype(AC)) diff --git a/code/modules/aspects/aspects_prosthetic_limbs.dm b/code/modules/aspects/aspects_prosthetic_limbs.dm index 40c97f9b2c4..ca2b369d462 100644 --- a/code/modules/aspects/aspects_prosthetic_limbs.dm +++ b/code/modules/aspects/aspects_prosthetic_limbs.dm @@ -17,7 +17,7 @@ if(!species_name) return /decl/bodytype/prosthetic/basic_human var/decl/species/species = species_name ? get_species_by_key(species_name) : global.using_map.default_species - return species?.base_prosthetics_model + return species?.base_external_prosthetics_model /decl/aspect/prosthetic_limb/Initialize() . = ..() diff --git a/code/modules/aspects/aspects_prosthetic_organs.dm b/code/modules/aspects/aspects_prosthetic_organs.dm index 578e080ae8d..578f751b377 100644 --- a/code/modules/aspects/aspects_prosthetic_organs.dm +++ b/code/modules/aspects/aspects_prosthetic_organs.dm @@ -28,7 +28,7 @@ if(.) var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(holder, apply_to_organ) if(I) - I.set_bodytype(holder.species.base_prosthetics_model) + I.set_bodytype(holder.species.base_internal_prosthetics_model) /decl/aspect/prosthetic_organ/eyes name = "Prosthetic Eyes" diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index eea98925985..0a91771b32c 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -9,7 +9,7 @@ throwforce = 2 throw_speed = 3 throw_range = 10 - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' var/secured = 1 var/list/attached_overlays = null diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index ba7055647f9..f692cd70b9d 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -2,7 +2,7 @@ name = "igniter" desc = "A small electronic device able to ignite combustible substances." icon_state = "igniter" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index d54d203d973..c472eacbe06 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -10,7 +10,7 @@ name = "infrared emitter" desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted." icon_state = "infrared" - origin_tech = "{'magnets':2}" + origin_tech = @'{"magnets":2}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -30,7 +30,7 @@ . = ..() beams = list() seen_turfs = list() - proximity_trigger = new(src, /obj/item/assembly/infra/proc/on_beam_entered, /obj/item/assembly/infra/proc/on_visibility_change, world.view, proximity_flags = PROXIMITY_EXCLUDE_HOLDER_TURF) + proximity_trigger = new(src, TYPE_PROC_REF(/obj/item/assembly/infra, on_beam_entered), TYPE_PROC_REF(/obj/item/assembly/infra, on_visibility_change), world.view, proximity_flags = PROXIMITY_EXCLUDE_HOLDER_TURF) /obj/item/assembly/infra/Destroy() qdel(proximity_trigger) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 4eda3b4fc35..dca5cfcd0a3 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -2,7 +2,7 @@ name = "rat trap" desc = "A handy little spring-loaded trap for catching pesty rodents." icon_state = "mousetrap" - origin_tech = "{'combat':1}" + origin_tech = @'{"combat":1}' material = /decl/material/solid/organic/wood matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) var/armed = 0 diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 8eb8469b3eb..0436515fc73 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -2,7 +2,7 @@ name = "proximity sensor" desc = "Used for scanning and alerting when someone enters a certain proximity." icon_state = "prox" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -78,7 +78,7 @@ /obj/item/assembly/prox_sensor/dropped() . = ..() - addtimer(CALLBACK(src, .proc/sense), 0) + addtimer(CALLBACK(src, PROC_REF(sense)), 0) /obj/item/assembly/prox_sensor/toggle_scan() if(!secured) return 0 diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index ea40cc935ff..6a40a7f3b1c 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -3,7 +3,7 @@ desc = "Used to remotely activate devices." icon_state = "signaller" item_state = "signaler" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index b5fec4b4cc4..9c4fee0d1fc 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -2,7 +2,7 @@ name = "timer" desc = "Used to time things. Works well with contraptions which have to count down. Tick tock." icon_state = "timer" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 20dc2332956..a291267414c 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -2,7 +2,7 @@ name = "voice analyzer" desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." icon_state = "voice" - origin_tech = "{'magnets':1}" + origin_tech = @'{"magnets":1}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/atmospherics/components/unary/vent_pump.dm b/code/modules/atmospherics/components/unary/vent_pump.dm index 57481b5ddf1..4f9a74967c0 100644 --- a/code/modules/atmospherics/components/unary/vent_pump.dm +++ b/code/modules/atmospherics/components/unary/vent_pump.dm @@ -83,7 +83,7 @@ var/area/A = get_area(src) if(A && !A.air_vent_names[id_tag]) update_name() - events_repository.register(/decl/observ/name_set, A, src, .proc/change_area_name) + events_repository.register(/decl/observ/name_set, A, src, PROC_REF(change_area_name)) . = ..() air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP update_sound() @@ -148,11 +148,11 @@ if(old_area == new_area) return if(old_area) - events_repository.unregister(/decl/observ/name_set, old_area, src, .proc/change_area_name) + events_repository.unregister(/decl/observ/name_set, old_area, src, PROC_REF(change_area_name)) old_area.air_vent_info -= id_tag old_area.air_vent_names -= id_tag if(new_area && new_area == get_area(src)) - events_repository.register(/decl/observ/name_set, new_area, src, .proc/change_area_name) + events_repository.register(/decl/observ/name_set, new_area, src, PROC_REF(change_area_name)) if(!new_area.air_vent_names[id_tag]) var/new_name = "[new_area.proper_name] Vent Pump #[new_area.air_vent_names.len+1]" new_area.air_vent_names[id_tag] = new_name @@ -222,10 +222,7 @@ power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating) else //external -> internal var/datum/pipe_network/network = network_in_dir(dir) - transfer_moles = calculate_transfer_moles(environment, air_contents, pressure_delta, network?.volume) - - //limit flow rate from turfs - transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here + transfer_moles = calculate_transfer_moles(environment, air_contents, pressure_delta, network?.volume) / environment.group_multiplier // limit it to just one turf's worth of gas per tick power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating) else diff --git a/code/modules/atmospherics/components/unary/vent_scrubber.dm b/code/modules/atmospherics/components/unary/vent_scrubber.dm index a79c7d4467b..ce64f9b0458 100644 --- a/code/modules/atmospherics/components/unary/vent_scrubber.dm +++ b/code/modules/atmospherics/components/unary/vent_scrubber.dm @@ -77,11 +77,11 @@ if(old_area == new_area) return if(old_area) - events_repository.unregister(/decl/observ/name_set, old_area, src, .proc/change_area_name) + events_repository.unregister(/decl/observ/name_set, old_area, src, PROC_REF(change_area_name)) old_area.air_scrub_info -= id_tag old_area.air_scrub_names -= id_tag if(new_area && new_area == get_area(src)) - events_repository.register(/decl/observ/name_set, new_area, src, .proc/change_area_name) + events_repository.register(/decl/observ/name_set, new_area, src, PROC_REF(change_area_name)) if(!new_area.air_scrub_names[id_tag]) var/new_name = "[new_area.proper_name] Vent Scrubber #[new_area.air_scrub_names.len+1]" new_area.air_scrub_names[id_tag] = new_name diff --git a/code/modules/atmospherics/he_pipes.dm b/code/modules/atmospherics/he_pipes.dm index cedb053c260..3f3b2952109 100644 --- a/code/modules/atmospherics/he_pipes.dm +++ b/code/modules/atmospherics/he_pipes.dm @@ -25,7 +25,7 @@ /obj/machinery/atmospherics/pipe/simple/heat_exchanging/Initialize() . = ..() color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. - add_filter("glow",1, list(type="drop_shadow", x = 0, y = 0, offset = 0, size = 4)) + add_filter("glow",1, list(type = "drop_shadow", x = 0, y = 0, offset = 0, size = 4)) /obj/machinery/atmospherics/pipe/simple/heat_exchanging/set_dir(new_dir) . = ..() diff --git a/code/modules/atmospherics/pipes.dm b/code/modules/atmospherics/pipes.dm index ba5d7385546..dd6643ecf13 100644 --- a/code/modules/atmospherics/pipes.dm +++ b/code/modules/atmospherics/pipes.dm @@ -197,12 +197,12 @@ /obj/machinery/atmospherics/pipe/Process() if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle ..() - else if(parent.air.compare(loc.return_air())) + else if(parent.air?.compare(loc.return_air())) update_sound(0) . = PROCESS_KILL else if(leaking) parent.mingle_with_turf(loc, volume) - var/air = parent.air && parent.air.return_pressure() + var/air = parent.air?.return_pressure() if(!sound_token && air) update_sound(1) else if(sound_token && !air) diff --git a/code/modules/augment/active/armblades.dm b/code/modules/augment/active/armblades.dm index fc5d61a10eb..d0df629cdc1 100644 --- a/code/modules/augment/active/armblades.dm +++ b/code/modules/augment/active/armblades.dm @@ -9,7 +9,7 @@ sharp = 1 edge = 1 attack_verb = list("stabbed", "sliced", "cut") - origin_tech = "{'materials':1,'engineering':1,'combat':2}" + origin_tech = @'{"materials":1,"engineering":1,"combat":2}' material = /decl/material/solid/metal/steel /obj/item/armblade/can_take_wear_damage() @@ -33,7 +33,7 @@ desc = "These do not grow back." base_parry_chance = 40 material_force_multiplier = 0.3 - origin_tech = "{'materials':2,'engineering':2,'combat':3}" + origin_tech = @'{"materials":2,"engineering":2,"combat":3}' //Alternate look /obj/item/organ/internal/augment/active/simple/wolverine diff --git a/code/modules/augment/active/circuit.dm b/code/modules/augment/active/circuit.dm index e14291c7177..6fe25252764 100644 --- a/code/modules/augment/active/circuit.dm +++ b/code/modules/augment/active/circuit.dm @@ -8,7 +8,7 @@ augment_flags = AUGMENTATION_MECHANIC desc = "A DIY modular assembly. Circuitry not included" material = /decl/material/solid/metal/steel - origin_tech = "{'materials':1,'magnets':1,'engineering':1,'programming':2}" + origin_tech = @'{"materials":1,"magnets":1,"engineering":1,"programming":2}' /obj/item/organ/internal/augment/active/simple/circuit/attackby(obj/item/W, mob/user) if(IS_CROWBAR(W)) diff --git a/code/modules/augment/active/cyberbrain.dm b/code/modules/augment/active/cyberbrain.dm index c2b2cd63964..f8fc92ecca1 100644 --- a/code/modules/augment/active/cyberbrain.dm +++ b/code/modules/augment/active/cyberbrain.dm @@ -4,7 +4,7 @@ icon_state = "cyberbrain" allowed_organs = list(BP_AUGMENT_HEAD) augment_flags = AUGMENTATION_MECHANIC - origin_tech = "{'materials':2,'magnets':3,'engineering':3,'biotech':2,'programming':4}" + origin_tech = @'{"materials":2,"magnets":3,"engineering":3,"biotech":2,"programming":4}' var/list/default_hardware = list( /obj/item/stock_parts/computer/processor_unit/small, diff --git a/code/modules/augment/active/polytool.dm b/code/modules/augment/active/polytool.dm index d9592be10b2..eedb1239675 100644 --- a/code/modules/augment/active/polytool.dm +++ b/code/modules/augment/active/polytool.dm @@ -4,7 +4,7 @@ icon_state = "multitool" allowed_organs = list(BP_AUGMENT_R_HAND, BP_AUGMENT_L_HAND) augment_flags = AUGMENTATION_MECHANIC - origin_tech = "{'materials':2,'magnets':2,'engineering':4}" + origin_tech = @'{"materials":2,"magnets":2,"engineering":4}' var/list/items = list() var/list/paths = list() //We may lose them @@ -58,7 +58,7 @@ if(owner.equip_to_slot_if_possible(item, slot)) items -= item //Keep track of it, make sure it returns - events_repository.register(/decl/observ/item_unequipped, item, src, /obj/item/organ/internal/augment/active/simple/proc/holding_dropped ) + events_repository.register(/decl/observ/item_unequipped, item, src, TYPE_PROC_REF(/obj/item/organ/internal/augment/active/simple, holding_dropped) ) var/decl/pronouns/G = owner.get_pronouns() owner.visible_message( SPAN_NOTICE("\The [owner] extends [G.his] [item.name] from [G.his] [limb.name]."), diff --git a/code/modules/augment/active/tool/engineering.dm b/code/modules/augment/active/tool/engineering.dm index f733602225e..0b3416aaf7c 100644 --- a/code/modules/augment/active/tool/engineering.dm +++ b/code/modules/augment/active/tool/engineering.dm @@ -14,7 +14,7 @@ /obj/item/wirecutters/finger, /obj/item/multitool/finger ) - origin_tech = "{'materials':4,'magnets':3,'engineering':3}" + origin_tech = @'{"materials":4,"magnets":3,"engineering":3}' /obj/item/weldingtool/finger name = "digital welder" diff --git a/code/modules/augment/active/tool/surgical.dm b/code/modules/augment/active/tool/surgical.dm index ba7b03dd20f..808d0c5c24c 100644 --- a/code/modules/augment/active/tool/surgical.dm +++ b/code/modules/augment/active/tool/surgical.dm @@ -16,4 +16,4 @@ /obj/item/scalpel, /obj/item/surgicaldrill ) - origin_tech = "{'materials':4,'magnets':3,'engineering':3}" + origin_tech = @'{"materials":4,"magnets":3,"engineering":3}' diff --git a/code/modules/augment/augment.dm b/code/modules/augment/augment.dm index 5b017593016..82b1b100ffb 100644 --- a/code/modules/augment/augment.dm +++ b/code/modules/augment/augment.dm @@ -6,7 +6,7 @@ organ_properties = ORGAN_PROP_PROSTHETIC default_action_type = /datum/action/item_action/organ/augment material = /decl/material/solid/metal/steel - origin_tech = "{'materials':1,'magnets':2,'engineering':2,'biotech':1}" + origin_tech = @'{"materials":1,"magnets":2,"engineering":2,"biotech":1}' var/descriptor = "" var/known = TRUE diff --git a/code/modules/augment/helping_hands.dm b/code/modules/augment/helping_hands.dm new file mode 100644 index 00000000000..38b3be5033d --- /dev/null +++ b/code/modules/augment/helping_hands.dm @@ -0,0 +1,49 @@ +/obj/item/helpinghands + name = "back-mounted arms" + desc = "A pair of arms with an included harness worn on the back, controlled by a noninvasive spinal prosthesis." + icon = 'icons/mecha/mech_parts_held.dmi' + icon_state = "light_arms" + material = /decl/material/solid/metal/steel + slot_flags = SLOT_BACK + var/list/slot_types = list( + /datum/inventory_slot/gripper/left_hand/no_organ/helping, + /datum/inventory_slot/gripper/right_hand/no_organ/helping + ) + +/obj/item/helpinghands/proc/add_hands(mob/user) + for (var/gripper_type in slot_types) + user.add_held_item_slot(new gripper_type) + +/obj/item/helpinghands/proc/remove_hands(mob/user) + for (var/datum/inventory_slot/gripper_type as anything in slot_types) + user.remove_held_item_slot(initial(gripper_type.slot_id)) + +/obj/item/helpinghands/equipped(mob/user, slot) + . = ..() + if(!user) + return + switch(slot) + if(slot_back_str) + add_hands(user) + else + remove_hands(user) + +/obj/item/helpinghands/dropped(mob/user) + . = ..() + if(user) + remove_hands(user) + +/datum/inventory_slot/gripper/left_hand/no_organ + requires_organ_tag = null +/datum/inventory_slot/gripper/right_hand/no_organ + requires_organ_tag = null + +/datum/inventory_slot/gripper/left_hand/no_organ/helping + slot_id = "helping_hand_l" + hand_overlay = BP_L_HAND + hand_sort_priority = 4 + +/datum/inventory_slot/gripper/right_hand/no_organ/helping + slot_id = "helping_hand_r" + hand_overlay = BP_R_HAND + hand_sort_priority = 5 \ No newline at end of file diff --git a/code/modules/augment/passive/armor.dm b/code/modules/augment/passive/armor.dm index 1c5d2c4e751..738e6c278c7 100644 --- a/code/modules/augment/passive/armor.dm +++ b/code/modules/augment/passive/armor.dm @@ -5,6 +5,6 @@ desc = "A flexible composite mesh designed to prevent tearing and puncturing of underlying tissue." material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':4,'engineering':2,'biotech':3}" + origin_tech = @'{"materials":4,"engineering":2,"biotech":3}' var/brute_mult = 0.8 var/burn_mult = 1 \ No newline at end of file diff --git a/code/modules/augment/passive/boost.dm b/code/modules/augment/passive/boost.dm index c06f8c7ce6f..0881f8736ec 100644 --- a/code/modules/augment/passive/boost.dm +++ b/code/modules/augment/passive/boost.dm @@ -4,7 +4,7 @@ /obj/item/organ/internal/augment/boost icon_state = "booster" allowed_organs = list(BP_AUGMENT_HEAD) - origin_tech = "{'materials':2,'magnets':2,'engineering':2,'biotech':3}" + origin_tech = @'{"materials":2,"magnets":2,"engineering":2,"biotech":3}' var/list/buffs = list()//Which abilities does this impact? var/list/injury_debuffs = list()//If organ is damaged, should we reduce anything? var/buffpath = /datum/skill_buff/augment //if you use something else it should be a subtype or it will runtime diff --git a/code/modules/augment/passive/boost/muscle.dm b/code/modules/augment/passive/boost/muscle.dm index faab18be427..55d1df0a1a7 100644 --- a/code/modules/augment/passive/boost/muscle.dm +++ b/code/modules/augment/passive/boost/muscle.dm @@ -10,7 +10,7 @@ desc = "Nanofiber tendons powered by an array of actuators to help the wearer mantain speed even while encumbered. You may want to install these in pairs to see a result." material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':4,'magnets':3,'biotech':3}" + origin_tech = @'{"materials":4,"magnets":3,"biotech":3}' var/obj/item/organ/internal/augment/boost/muscle/other //we need two for these diff --git a/code/modules/augment/passive/boost/reflex.dm b/code/modules/augment/passive/boost/reflex.dm index 1644f490514..d249075c429 100644 --- a/code/modules/augment/passive/boost/reflex.dm +++ b/code/modules/augment/passive/boost/reflex.dm @@ -8,7 +8,7 @@ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':2,'magnets':3,'programming':5,'biotech':2}" + origin_tech = @'{"materials":2,"magnets":3,"programming":5,"biotech":2}' /obj/item/organ/internal/augment/boost/reflex/buff() if((. = ..())) diff --git a/code/modules/augment/passive/boost/shooting.dm b/code/modules/augment/passive/boost/shooting.dm index bbc92ec6107..d29a67a21be 100644 --- a/code/modules/augment/passive/boost/shooting.dm +++ b/code/modules/augment/passive/boost/shooting.dm @@ -8,7 +8,7 @@ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':4,'magnets':3,'biotech':3}" + origin_tech = @'{"materials":4,"magnets":3,"biotech":3}' /obj/item/organ/internal/augment/boost/reflex/buff() if((. = ..())) diff --git a/code/modules/augment/passive/nanoaura.dm b/code/modules/augment/passive/nanoaura.dm index 662be61f8eb..3bf4bf43d00 100644 --- a/code/modules/augment/passive/nanoaura.dm +++ b/code/modules/augment/passive/nanoaura.dm @@ -20,7 +20,7 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/uranium = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':4,'magnets':4,'engineering':5,'biotech':3}" + origin_tech = @'{"materials":4,"magnets":4,"engineering":5,"biotech":3}' var/obj/aura/nanoaura/aura = null var/charges = 4 diff --git a/code/modules/augment/simple.dm b/code/modules/augment/simple.dm index 7b122209cf4..23a9e2d4dfa 100644 --- a/code/modules/augment/simple.dm +++ b/code/modules/augment/simple.dm @@ -35,7 +35,7 @@ else if(limb.organ_tag in list(BP_R_ARM, BP_R_HAND)) slot = BP_R_HAND if(owner.equip_to_slot_if_possible(holding, slot)) - events_repository.register(/decl/observ/item_unequipped, holding, src, /obj/item/organ/internal/augment/active/simple/proc/holding_dropped) + events_repository.register(/decl/observ/item_unequipped, holding, src, TYPE_PROC_REF(/obj/item/organ/internal/augment/active/simple, holding_dropped)) var/decl/pronouns/G = owner.get_pronouns() owner.visible_message( SPAN_NOTICE("\The [owner] extends [G.his] [holding.name] from [G.his] [limb.name]."), diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 95d2001f73d..77ce2c0c676 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -55,32 +55,32 @@ if((spawn_flags & CORPSE_SPAWNER_RANDOM_SKIN_COLOR)) if(species_choice in skin_colors_per_species) - M.change_skin_color(pick(skin_colors_per_species[species_choice])) + M.set_skin_colour(pick(skin_colors_per_species[species_choice])) else M.randomize_skin_color() if((spawn_flags & CORPSE_SPAWNER_RANDOM_HAIR_COLOR)) if(species_choice in hair_colors_per_species) - M.change_hair_color(pick(hair_colors_per_species[species_choice])) + M.set_hair_colour(pick(hair_colors_per_species[species_choice])) else M.randomize_hair_color() - M.change_facial_hair_color(M.hair_colour) + M.set_facial_hair_colour(M.get_hair_colour()) if((spawn_flags & CORPSE_SPAWNER_RANDOM_HAIR_STYLE)) if(species_choice in hair_styles_per_species) - M.change_hair(pick(hair_styles_per_species[species_choice])) + M.set_hairstyle(pick(hair_styles_per_species[species_choice])) else M.randomize_hair_style() if((spawn_flags & CORPSE_SPAWNER_RANDOM_FACIAL_STYLE)) if(species_choice in facial_styles_per_species) - M.change_facial_hair(pick(facial_styles_per_species[species_choice])) + M.set_facial_hairstyle(pick(facial_styles_per_species[species_choice])) else M.randomize_facial_hair_style() if((spawn_flags & CORPSE_SPAWNER_RANDOM_EYE_COLOR)) if(species_choice in eye_colors_per_species) - M.change_eye_color(pick(eye_colors_per_species[species_choice])) + M.set_eye_colour(pick(eye_colors_per_species[species_choice])) else M.randomize_eye_color() diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index b416212991d..67ed0c183cd 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -35,7 +35,7 @@ /obj/machinery/gateway/centerstation/Initialize() update_icon() - wait = world.time + config.gateway_delay //+ thirty minutes default + wait = world.time + get_config_value(/decl/config/num/gateway_delay) //+ thirty minutes default awaygate = locate(/obj/machinery/gateway/centeraway) . = ..() diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index ff057c0d515..24c98a41859 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -363,13 +363,13 @@ regen() will cover update_icon() for this proc desc = "An incredibly dense, yet flexible, tendril, removed from an asteroclast." force = 10 color = COLOR_BRONZE - origin_tech = "{'materials':2}" + origin_tech = @'{"materials":2}' if("fire") desc = "A tendril removed from an asteroclast. It's hot to the touch." damtype = BURN force = 15 color = COLOR_AMBER - origin_tech = "{'powerstorage':2}" + origin_tech = @'{"powerstorage":2}' /obj/item/blob_tendril/afterattack(obj/O, mob/user, proximity) if(!proximity) @@ -388,11 +388,11 @@ regen() will cover update_icon() for this proc icon_state = "core_sample" item_state = "blob_core" w_class = ITEM_SIZE_NORMAL - origin_tech = "{'materials':4,'wormholes':5,'biotech':7}" + origin_tech = @'{"materials":4,"wormholes":5,"biotech":7}' is_tendril = FALSE /obj/item/blob_tendril/core/aux name = "asteroclast auxiliary nucleus sample" desc = "A sample taken from an asteroclast's auxiliary nucleus." icon_state = "core_sample_2" - origin_tech = "{'materials':2,'wormholes':3,'biotech':4}" + origin_tech = @'{"materials":2,"wormholes":3,"biotech":4}' diff --git a/code/modules/blood/blood.dm b/code/modules/blood/blood.dm new file mode 100644 index 00000000000..895b6e04760 --- /dev/null +++ b/code/modules/blood/blood.dm @@ -0,0 +1,76 @@ +/proc/blood_splatter(atom/target, atom/source, var/large = FALSE, var/spray_dir) + + var/obj/effect/decal/cleanable/blood/splatter + var/decal_type = /obj/effect/decal/cleanable/blood/splatter + var/turf/bleed_turf = get_turf(target) + + // Are we dripping or splattering? + var/list/drips + // Only a certain number of drips (or one large splatter) can be on a given turf. + for(var/obj/effect/decal/cleanable/blood/drip/drop in bleed_turf) + LAZYDISTINCTADD(drips, drop.drips) + qdel(drop) + if(!large && LAZYLEN(drips) < 3) + decal_type = /obj/effect/decal/cleanable/blood/drip + + // Find a blood decal or create a new one. + if(bleed_turf) + var/list/existing = filter_list(bleed_turf.contents, decal_type) + if(length(existing) > 3) + splatter = pick(existing) + if(!splatter) + splatter = new decal_type(bleed_turf) + + if(QDELETED(splatter)) + return + + var/obj/effect/decal/cleanable/blood/drip/drop = splatter + if(istype(drop) && LAZYLEN(drips) && !large) + drop.drips |= drips + drop.update_icon() + + // If there's no data to copy, call it quits here. + var/blood_data + var/blood_type + if(isliving(source)) + var/mob/living/donor = source + blood_data = donor.get_blood_data() + blood_type = donor.get_blood_type() + else if(isatom(source)) + var/atom/donor = source + blood_data = REAGENT_DATA(donor.reagents, /decl/material/liquid/blood) + if(!islist(blood_data)) + return splatter + + if(spray_dir) + splatter.icon_state = "squirt" + splatter.set_dir(spray_dir) + + // Update blood information. + if(LAZYACCESS(blood_data, "blood_DNA")) + LAZYSET(splatter.blood_data, blood_data["blood_DNA"], blood_data) + splatter.blood_DNA = list() + if(LAZYACCESS(blood_data, "blood_type")) + splatter.blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"] + else + splatter.blood_DNA[blood_data["blood_DNA"]] = "O+" + var/datum/extension/forensic_evidence/forensics = get_or_create_extension(splatter, /datum/extension/forensic_evidence) + forensics.add_data(/datum/forensics/blood_dna, blood_data["blood_DNA"]) + + if(!blood_type && LAZYACCESS(blood_data, "blood_type")) + blood_type = LAZYACCESS(blood_data, "blood_type") + + // Update appearance. + if(blood_type) + var/decl/blood_type/blood_type_decl = get_blood_type_by_name(blood_type) + splatter.name = blood_type_decl.splatter_name + splatter.desc = blood_type_decl.splatter_desc + splatter.basecolor = blood_type_decl.splatter_colour + + if(LAZYACCESS(blood_data, "blood_color")) + splatter.basecolor = blood_data["blood_color"] + + splatter.update_icon() + splatter.fluorescent = FALSE + splatter.set_invisibility(INVISIBILITY_NONE) + return splatter diff --git a/code/modules/organs/blood_types.dm b/code/modules/blood/blood_types.dm similarity index 65% rename from code/modules/organs/blood_types.dm rename to code/modules/blood/blood_types.dm index ea2eaf49625..3bf5fc6f467 100644 --- a/code/modules/organs/blood_types.dm +++ b/code/modules/blood/blood_types.dm @@ -59,62 +59,3 @@ var/global/list/antigen_comparison_cache = list() . = FALSE break global.antigen_comparison_cache[type][other_blood_type.type] = . - -/decl/blood_type/ominus - name = "O-" - random_weighting = 4 - -/decl/blood_type/oplus - name = "O+" - antigens = list("Rh") - random_weighting = 36 - -/decl/blood_type/aminus - name = "A-" - antigens = list("A") - random_weighting = 3 - -/decl/blood_type/aplus - name = "A+" - antigens = list("A", "Rh") - random_weighting = 28 - -/decl/blood_type/bminus - name = "B-" - antigens = list("B") - -/decl/blood_type/bplus - name = "B+" - antigens = list("B", "Rh") - random_weighting = 20 - -/decl/blood_type/abminus - name = "AB-" - antigens = list("A", "B") - -/decl/blood_type/abplus - name = "AB+" - antigens = list("A", "B", "Rh") - random_weighting = 5 - -// Insect blood. -/decl/blood_type/hemolymph - - name = "hemolymph" - antigen_category = "insect" - - splatter_name = "ichor" - splatter_desc = "A smear of insect ichor. It smells acrid." - splatter_colour = "#525252" - -// Robo-blood. -/decl/blood_type/coolant - - name = "coolant" - antigen_category = "machine" - - splatter_name = "coolant" - splatter_desc = "A smear of machine coolant. It looks discoloured." - splatter_colour = SYNTH_BLOOD_COLOR - - transfusion_fail_reagent = /decl/material/liquid/acid diff --git a/code/modules/blood/blood_types_subtypes.dm b/code/modules/blood/blood_types_subtypes.dm new file mode 100644 index 00000000000..4104ce2a360 --- /dev/null +++ b/code/modules/blood/blood_types_subtypes.dm @@ -0,0 +1,58 @@ +/decl/blood_type/ominus + name = "O-" + random_weighting = 4 + +/decl/blood_type/oplus + name = "O+" + antigens = list("Rh") + random_weighting = 36 + +/decl/blood_type/aminus + name = "A-" + antigens = list("A") + random_weighting = 3 + +/decl/blood_type/aplus + name = "A+" + antigens = list("A", "Rh") + random_weighting = 28 + +/decl/blood_type/bminus + name = "B-" + antigens = list("B") + +/decl/blood_type/bplus + name = "B+" + antigens = list("B", "Rh") + random_weighting = 20 + +/decl/blood_type/abminus + name = "AB-" + antigens = list("A", "B") + +/decl/blood_type/abplus + name = "AB+" + antigens = list("A", "B", "Rh") + random_weighting = 5 + +// Insect blood. +/decl/blood_type/hemolymph + + name = "hemolymph" + antigen_category = "insect" + + splatter_name = "ichor" + splatter_desc = "A smear of insect ichor. It smells acrid." + splatter_colour = "#525252" + +// Robo-blood. +/decl/blood_type/coolant + + name = "coolant" + antigen_category = "machine" + + splatter_name = "coolant" + splatter_desc = "A smear of machine coolant. It looks discoloured." + splatter_colour = SYNTH_BLOOD_COLOR + + transfusion_fail_reagent = /decl/material/liquid/acid diff --git a/code/modules/brain_interface/_brain_interface.dm b/code/modules/brain_interface/_brain_interface.dm new file mode 100644 index 00000000000..4b96d8f9f24 --- /dev/null +++ b/code/modules/brain_interface/_brain_interface.dm @@ -0,0 +1,153 @@ +// Many values copied from brains. Not inheriting to avoid redundant brainmob creation. +/obj/item/organ/internal/brain_interface + name = "neural interface" + desc = "A complex life support shell that interfaces between a brain and an electronic device." + organ_tag = BP_BRAIN + parent_organ = BP_HEAD + origin_tech = @'{"biotech":3}' + icon = 'icons/obj/items/brain_interface_organic.dmi' + icon_state = ICON_STATE_WORLD + req_access = list(access_robotics) + material = /decl/material/solid/metal/steel + matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) + w_class = ITEM_SIZE_SMALL + throwforce = 1 + throw_speed = 3 + throw_range = 5 + attack_verb = list("attacked", "slapped", "whacked") + relative_size = 85 + damage_reduction = 0 + scale_max_damage_to_species_health = FALSE + transfer_brainmob_with_organ = TRUE + var/locked = FALSE + var/obj/item/organ/internal/brain/holding_brain = /obj/item/organ/internal/brain + +/obj/item/organ/internal/brain_interface/is_preserved() + return TRUE + +/obj/item/organ/internal/brain_interface/empty + holding_brain = null + +/obj/item/organ/internal/brain_interface/Initialize() + set_bodytype(/decl/bodytype/prosthetic/basic_human) + if(ispath(holding_brain)) + holding_brain = new holding_brain(src) + if(get_radio()) + verbs |= /obj/item/organ/internal/brain_interface/proc/toggle_radio_listening + verbs |= /obj/item/organ/internal/brain_interface/proc/toggle_radio_broadcasting + . = ..() + update_icon() + +/obj/item/organ/internal/brain_interface/get_brainmob(var/create_if_missing = FALSE) + return holding_brain?.get_brainmob(create_if_missing) + +/obj/item/organ/internal/brain_interface/on_update_icon() + icon_state = get_world_inventory_state() + if(holding_brain) + var/mob/living/brainmob = get_brainmob() + if(!brainmob || brainmob.stat == DEAD) + icon_state = "[icon_state]-dead" + else + icon_state = "[icon_state]-full" + +/obj/item/organ/internal/brain_interface/examine(mob/user, distance) + . = ..() + if(distance <= 1) + var/mob/living/brain/brainmob = get_brainmob() + if(istype(brainmob)) + if(brainmob.emp_damage) + to_chat(user, SPAN_WARNING("The neural interface socket is damaged.")) + else + to_chat(user, SPAN_NOTICE("It is undamaged.")) + +/obj/item/organ/internal/brain_interface/attackby(var/obj/item/O, var/mob/user) + + if(istype(O, /obj/item/stack/nanopaste)) + var/mob/living/brain/brainmob = get_brainmob() + if(!istype(brainmob) || !brainmob.emp_damage) + to_chat(user, SPAN_WARNING("\The [src] has no damage to repair.")) + return TRUE + var/obj/item/stack/nanopaste/pasta = O + pasta.use(1) + to_chat(user, SPAN_NOTICE("You repair some of the damage to \the [src]'s electronics with the nanopaste.")) + brainmob.emp_damage = max(brainmob.emp_damage - rand(5,10), 0) + return TRUE + + if(istype(O, /obj/item/organ/internal/brain)) + + if(holding_brain) + to_chat(user, SPAN_WARNING("\The [src] already has a brain in it.")) + return TRUE + + var/obj/item/organ/internal/brain/inserting_brain = O + if(BP_IS_PROSTHETIC(inserting_brain)) + to_chat(user, SPAN_WARNING("You don't need to put a robotic brain into an interface.")) + return TRUE + + if(inserting_brain.damage >= inserting_brain.max_damage) + to_chat(user, SPAN_WARNING("That brain is well and truly dead.")) + return TRUE + + if(!inserting_brain.get_brainmob() || !inserting_brain.can_use_brain_interface) + to_chat(user, SPAN_WARNING("\The [inserting_brain] is completely useless.")) + return TRUE + + if(user.try_unequip(O, src)) + user.visible_message(SPAN_NOTICE("\The [user] sticks \the [inserting_brain] into \the [src].")) + SetName("[initial(name)] (\the [inserting_brain])") + holding_brain = inserting_brain + update_icon() + locked = TRUE + SSstatistics.add_field("cyborg_mmis_filled",1) + return TRUE + + if(istype(O,/obj/item/card/id) || istype(O,/obj/item/modular_computer)) + if(allowed(user)) + locked = !locked + to_chat(user, SPAN_NOTICE("You [locked ? "lock" : "unlock"] \the [src].")) + else + to_chat(user, SPAN_WARNING("Access denied.")) + return TRUE + + if(holding_brain) + return holding_brain.attackby(O, user) + + . = ..() + +/obj/item/organ/internal/brain_interface/relaymove(var/mob/user, var/direction) + if(user.incapacitated()) + return + var/obj/item/rig/rig = src.get_rig() + if(rig) + rig.forced_move(direction, user) + +/obj/item/organ/internal/brain_interface/Destroy() + STOP_PROCESSING(SSprocessing, src) + if(isrobot(loc)) + var/mob/living/silicon/robot/borg = loc + if(borg.central_processor == src) + borg.central_processor = null + if(holding_brain) + if(!QDELETED(holding_brain)) + qdel(holding_brain) + holding_brain = null + for(var/obj/item/thing in contents) + qdel(thing) + . = ..() + +/obj/item/organ/internal/brain_interface/attack_self(mob/user) + + if(locked) + to_chat(user, SPAN_WARNING("You upend \the [src], but the case is locked shut.")) + return TRUE + + if(!holding_brain) + to_chat(user, SPAN_WARNING("You upend \the [src], but there's nothing in it.")) + return TRUE + + to_chat(user, SPAN_NOTICE("You upend \the [src], spilling \the [holding_brain] onto \the [get_turf(src)].")) + + holding_brain.dropInto(user.loc) + holding_brain = null + update_icon() + SetName(initial(name)) diff --git a/code/modules/brain_interface/interface_radio.dm b/code/modules/brain_interface/interface_radio.dm new file mode 100644 index 00000000000..a793f944ce7 --- /dev/null +++ b/code/modules/brain_interface/interface_radio.dm @@ -0,0 +1,61 @@ +/obj/item/organ/internal/brain_interface/radio_enabled + name = "radio-enabled neural interface" + desc = "A complex life support shell that interfaces between a brain and an electronic device. This one comes with a built-in radio." + origin_tech = @'{"biotech":4}' + var/VAR_PRIVATE/weakref/_radio + +/obj/item/organ/internal/brain_interface/radio_enabled/empty + holding_brain = null + +/obj/item/organ/internal/brain_interface/radio_enabled/get_radio() + var/obj/item/radio/radio_instance = _radio?.resolve() + if(radio_instance && (!istype(radio_instance) || QDELETED(radio_instance) || radio_instance.loc != src)) + radio_instance = null + _radio = null + return radio_instance?.get_radio() + +/obj/item/organ/internal/brain_interface/radio_enabled/Initialize() + _radio = weakref(new /obj/item/radio(src)) + . = ..() + +/obj/item/organ/internal/brain_interface/radio_enabled/Destroy() + var/obj/item/radio/radio_instance = get_radio() + if(radio_instance) + qdel(radio_instance) + _radio = null + return ..() + +/obj/item/organ/internal/brain_interface/proc/toggle_radio_broadcasting() + set name = "Toggle Broadcasting" + set desc = "Toggle broadcasting channel on or off." + set category = "Brain Interface" + set src in view(1) + set popup_menu = 0 + + if(usr.incapacitated()) + to_chat(usr, SPAN_WARNING("You must be alive and conscious to interact with \the [src].")) + return + + var/obj/item/radio/radio_instance = get_radio() + if(istype(radio_instance)) + radio_instance.broadcasting = !radio_instance.broadcasting + to_chat(usr, SPAN_NOTICE("You adjust the radio on \the [src]. It is [radio_instance.broadcasting ? "now broadcasting" : "no longer broadcasting"].")) + else + verbs -= /obj/item/organ/internal/brain_interface/proc/toggle_radio_broadcasting + +/obj/item/organ/internal/brain_interface/proc/toggle_radio_listening() + set name = "Toggle Listening" + set desc = "Toggle listening channel on or off." + set category = "Brain Interface" + set src in view(1) + + set popup_menu = 0 + if(usr.incapacitated()) + to_chat(usr, SPAN_WARNING("You must be alive and conscious to interact with \the [src].")) + return + var/obj/item/radio/radio_instance = get_radio() + if(radio_instance) + radio_instance.listening = !radio_instance.listening + to_chat(usr, SPAN_NOTICE("You adjust the radio on \the [src]. It is [radio_instance.listening ? "now receiving broadcasts" : "no longer receiving broadcasts"].")) + else + verbs -= /obj/item/organ/internal/brain_interface/proc/toggle_radio_listening diff --git a/code/modules/character_info/_character_info.dm b/code/modules/character_info/_character_info.dm new file mode 100644 index 00000000000..24101af876e --- /dev/null +++ b/code/modules/character_info/_character_info.dm @@ -0,0 +1,77 @@ +/// Main holder class for character comments - primarily user-set info, tracking vars, and a list of comment datums. +/datum/character_information + /// A user-descriptive (searchable) name for presenting comment holders. + var/name + /// Any user-specified in character info, like Teshari pack stuff or faction notes. + var/ic_info + /// Any user-specified out of character info, like content warnings. + var/ooc_info + /// Owning character name (for searches) + var/char_name + /// Owning ckey (for searches). + var/ckey + /// GUID for this ckey/save slot combo. + var/record_id + /// Linear list of comment datums for comments left on this character. + var/list/comments = list() + /// Whether or not this record is allowing comments currently + var/allow_comments = FALSE + /// Boolean to indicate if the owner of this record has read it since it was last update. + var/has_new_comments = FALSE + /// Boolean to indicate if this character will show IC and OOC info when examined. + var/show_info_on_examine = FALSE + /// The location this file was loaded from in the first place. Defaults to subsystem and ID if unset. + var/file_location + /// Static list of var keys to serialize. TODO: unit test + var/static/list/serialize_fields = list( + "record_id", + "char_name", + "ckey", + "ic_info", + "ooc_info", + "has_new_comments", + "allow_comments", + "show_info_on_examine" + ) + +/datum/character_information/New(var/list/json_input) + + // None of our serialized fields are datum references so this should in theory be safe. + for(var/key in json_input) + try + if(key in vars) + vars[key] = json_input[key] + else + log_error("Character comments attempting to deserialize invalid var '[key]'") + catch(var/exception/E) + log_error("Exception on deserializing character comments: [E]") + + // Comments are serialized to a linear list of json strings + // so we now need to deserialize them to instances. + if(length(comments)) + var/list/loading_comments = comments + comments = list() + for(var/list/comment in loading_comments) + comments += new /datum/character_comment(comment) + + // Update our display name. + update_fields() + +/datum/character_information/proc/update_fields() + name = "[char_name || "Unknown"] - [ckey || "Unknown"]" + +/datum/character_information/proc/serialize_to_json() + + . = list() + for(var/key in serialize_fields) + if(key in vars) + .[key] = vars[key] + else + log_error("Character comments attempting to serialize invalid var '[key]'") + + var/list/serialized_comments = list() + for(var/datum/character_comment/comment in comments) + serialized_comments += list(comment.serialize_to_list()) // Double wrap to avoid list merge. + .["comments"] = serialized_comments + + . = json_encode(.) diff --git a/code/modules/character_info/_comment.dm b/code/modules/character_info/_comment.dm new file mode 100644 index 00000000000..d03bbdaf769 --- /dev/null +++ b/code/modules/character_info/_comment.dm @@ -0,0 +1,100 @@ +/// Individual comment datum. Tracked by the comment holder datum. +/datum/character_comment + /// Actual text body of the comment. + var/body + /// Author character name for comment/display. + var/author_char + /// Author ckey for comment/display. + var/author_ckey + /// Combined ckey/save slot GUID for linking back to the author's comments page. + var/author_id + /// REALTIMEOFDAY value of the last edit, used for hiding old or out of date comments. + var/last_updated + /// Formatting info for displaying comments a la the old shipping manifest. + var/decl/comment_mood/main_mood + var/decl/comment_mood/border_mood + /// Static list of var keys to serialize. TODO: unit test + var/static/list/serialize_fields = list( + "body", + "author_char", + "author_ckey", + "author_id", + "last_updated" + ) + +/datum/character_comment/proc/is_stale() + return !get_config_value(/decl/config/num/hide_comments_older_than) || (REALTIMEOFDAY - last_updated) > (get_config_value(/decl/config/num/hide_comments_older_than)) + +/datum/character_comment/proc/get_comment_html(var/datum/character_information/presenting, var/mob/usr, var/row_bkg_color) + var/mood_title = main_mood.name + if(border_mood) + mood_title = "[mood_title] ([border_mood.name])" + . = list( + "
    [author_char]
    ([author_ckey])
    View
    [body]
    " + ) + if(usr) + . += "
    " + if(author_ckey == usr.ckey || check_rights(R_MOD)) + . += "Edit
    " + . += "Delete
    " + . += "Change primary mood
    " + . += "Change border mood" + else if(usr.ckey == presenting.ckey) + . += "Delete" + else + . += "Not editable." + . += "
    " + . += "
    " + if(my_comment) + dat += my_comment.get_comment_html(src, user, COMMENT_CANDYSTRIPE_ONE) + else if(viewer) + dat += "" + else + dat += "" + dat += "
    You have not left a comment for this character. Leave one now?
    You cannot leave a comment anonymously. Click here to select one of your saved characters.
    " + + dat += "

    Other Comments

    " + dat += "" + //TODO sort other_comments + if(length(other_comments)) + var/ticker = FALSE + for(var/datum/character_comment/comment in other_comments) + dat += comment.get_comment_html(src, user, ticker ? COMMENT_CANDYSTRIPE_ONE : COMMENT_CANDYSTRIPE_TWO) + ticker = !ticker + else + dat += "" + dat += "
    There are no other comments to view.
    " + + var/datum/browser/popup = new(user, "character_information", "Character Information", 750, 800) + popup.set_content(JOINTEXT(dat)) + popup.open() + +/datum/character_information/Topic(href, href_list) + . = ..() + if(. || !usr?.client || !get_config_value(/decl/config/toggle/allow_character_comments)) + return + + if(href_list["create_comment"]) + + // Have to commenting as someone, and you can't have commented already (edit your previous one nerd). + if(!usr.client.viewing_character_info_as) + return TOPIC_NOACTION + var/datum/character_information/commenting_as = usr.client.viewing_character_info_as && SScharacter_info.get_record(usr.client.viewing_character_info_as, TRUE) + if(!istype(commenting_as)) + return TOPIC_NOACTION + for(var/datum/character_comment/comment in comments) + if(comment.author_id == commenting_as.record_id) + return TOPIC_NOACTION + var/datum/character_comment/new_comment = new + new_comment.author_char = commenting_as.char_name + new_comment.author_ckey = commenting_as.ckey + new_comment.author_id = commenting_as.record_id + new_comment.body = "..." + comments += new_comment + . = TOPIC_REFRESH + + if(href_list["show_legend"]) + usr.client.show_comments_legend = text2num(href_list["show_legend"]) + . = TOPIC_REFRESH + + if(href_list["change_viewer"]) + var/list/other_slots = list() + if(usr.client.prefs) + for(var/i = 1 to length(usr.client.prefs.slot_names)) + var/slot_key = usr.client.prefs.get_slot_key(i) + if(!slot_key || !LAZYACCESS(usr.client.prefs.slot_names, slot_key)) + continue + var/datum/character_information/comments = SScharacter_info.get_record("[usr.ckey]-[slot_key]", TRUE) + if(comments) + other_slots += comments + + if(!length(other_slots)) + to_chat(usr, SPAN_WARNING("You have no character slots to select a viewer from.")) + . = TOPIC_NOACTION + else + var/datum/character_information/my_comments = input(usr, "Which character do you wish to view and comment as?", "View Character Comments") as null|anything in other_slots + if(istype(my_comments)) + usr.client.viewing_character_info_as = my_comments.record_id + . = TOPIC_REFRESH + + if(href_list["set_viewed"]) + var/datum/character_information/comments = SScharacter_info.get_record(href_list["set_viewed"]) + if(istype(comments)) + comments.display_to(usr) + . = TOPIC_HANDLED + + if(href_list["change_viewed"]) + + var/search_for = input(usr, "Please specify a name or ckey to search for.", "View Character Comments") as null|text + if(search_for) + usr.client.view_character_information(search_for) + . = TOPIC_HANDLED + + if(href_list["comment_ref"]) + var/datum/character_comment/comment = locate(href_list["comment_ref"]) + if(!istype(comment)) + return TOPIC_NOACTION + + var/has_full_rights = (comment.author_ckey == usr.ckey || check_rights(R_ADMIN)) + var/has_delete_rights = (has_full_rights || ckey == usr.ckey) + + if(has_full_rights) + + if(href_list["edit_comment"]) + var/new_body = sanitize(input(usr, "Enter or edit your comment.", "Editing Comment", comment.body) as message|null) + if(new_body && !QDELETED(comment) && (comment in comments)) + comment.body = new_body + comment.last_updated = REALTIMEOFDAY + . = TOPIC_REFRESH + + if(href_list["change_comment_mood"]) + var/changing_border_mood = href_list["change_comment_mood"] == "border" + var/list/moods = list() + if(changing_border_mood) + moods += "Clear border" + var/list/all_moods = decls_repository.get_decls_of_type(/decl/comment_mood) + for(var/mood in all_moods) + moods += all_moods[mood] + var/new_mood = input(usr, "Select a new mood for the [changing_border_mood ? "comment border" : "comment"].", "Select Mood", (changing_border_mood ? comment.border_mood : comment.main_mood) || GET_DECL(/decl/comment_mood)) as null|anything in moods + if(new_mood) + if(changing_border_mood) + if(changing_border_mood == "Clear border") + comment.border_mood = null + else + comment.border_mood = new_mood + else + comment.main_mood = new_mood + comment.last_updated = REALTIMEOFDAY + . = TOPIC_REFRESH + + if(has_delete_rights && href_list["delete_comment"]) + if(alert(usr, "Are you sure you want to delete this comment?", "Delete Message", "No", "Yes") == "Yes") + if(!QDELETED(comment) && (comment in comments)) + comments -= comment + qdel(comment) + . = TOPIC_REFRESH + + if(. == TOPIC_REFRESH) + has_new_comments = TRUE + SScharacter_info.queue_to_save(record_id) + + if(. == TOPIC_REFRESH) + display_to(usr) + +/datum/admins/proc/dump_character_info_manifest() + set name = "Dump Character Info Manifest" + set category = "Debug" + set src = usr + + var/list/dat = SScharacter_info.get_character_manifest_html() + dat += "Download as HTML" + + var/datum/browser/popup = new(usr, "character_matrix", "Character Matrix", 800, 800) + popup.set_content(JOINTEXT(dat)) + popup.open() + +#undef COMMENT_CANDYSTRIPE_ONE +#undef COMMENT_CANDYSTRIPE_TWO diff --git a/code/modules/character_info/comment_mood.dm b/code/modules/character_info/comment_mood.dm new file mode 100644 index 00000000000..4c89f76da74 --- /dev/null +++ b/code/modules/character_info/comment_mood.dm @@ -0,0 +1,143 @@ +/// Visual formatting for character info/comments. + +var/global/_comment_mood_legend +/proc/get_comment_mood_legend() + if(!global._comment_mood_legend) + var/legend_width = 500 + var/legend_per_row = 5 + var/legend_cell_width = FLOOR(legend_width/legend_per_row) + global._comment_mood_legend = list("") + var/list/all_moods = decls_repository.get_decls_of_type(/decl/comment_mood) + var/counter = 0 + for(var/mood_type in all_moods) + if(counter == 0) + global._comment_mood_legend += "" + var/decl/comment_mood/mood = all_moods[mood_type] + global._comment_mood_legend += "" + counter++ + if(counter == legend_per_row) + counter = 0 + global._comment_mood_legend += "" + if(counter != 0) + global._comment_mood_legend += "" + global._comment_mood_legend += "
    Legend
    [mood.name]
    " + global._comment_mood_legend = jointext(global._comment_mood_legend, null) + return global._comment_mood_legend + +/// Formatting data for comments. +/decl/comment_mood + abstract_type = /decl/comment_mood + decl_flags = DECL_FLAG_MANDATORY_UID + /// Descriptive name used for mood selector. + var/name + /// Colour to format the foreground (text). + var/fg_color = COLOR_BLACK + /// Colour to format the background (fill). + var/bg_color = COLOR_GRAY80 + +/decl/comment_mood/unknown + name = "Unknown or no contact" + uid = "comment_mood_unknown" + +/decl/comment_mood/good_friend + name = "Good friend" + bg_color = COLOR_LIME + uid = "comment_mood_good_friend" + +/decl/comment_mood/friend_with_benefits + name = "Friend with benefits" + bg_color = "#ea9999" + uid = "comment_mood_fwb" + + +/decl/comment_mood/crush_infatuation + name = "Crush or infatuation" + bg_color = COLOR_RED + uid = "comment_mood_crush" + +/decl/comment_mood/relationship + name = "Committed relationship" + bg_color = "#ff00ff" + uid = "comment_mood_love" + +/decl/comment_mood/old_flame + name = "Old flame" + fg_color = COLOR_WHITE + bg_color = "#a61c00" + uid = "comment_mood_old_flame" + +/decl/comment_mood/complicated + name = "It's complicated" + fg_color = COLOR_WHITE + bg_color = "#9900ff" + uid = "comment_mood_complicated" + +/decl/comment_mood/hatred + name = "Hatred" + fg_color = COLOR_WHITE + bg_color = COLOR_BLACK + uid = "comment_mood_hatred" + +/decl/comment_mood/dislike + name = "Disliked acquaintance" + fg_color = COLOR_WHITE + bg_color = "#274e13" + uid = "comment_mood_disliked_acq" + +/decl/comment_mood/concern + name = "Concern or worry" + bg_color = "#fff2cc" + uid = "comment_mood_concern" + +/decl/comment_mood/confusion + name = "Confusion or bewilderment" + bg_color = "#a64d79" + uid = "comment_mood_confusion" + +/decl/comment_mood/best_friend + name = "Best friend" + bg_color = COLOR_YELLOW + uid = "comment_mood_best_friend" + +/decl/comment_mood/vague_acquaintance + name = "Vague acquaintance" + bg_color = "#a4c2f4" + uid = "comment_mood_vague_acq" + +/decl/comment_mood/family + name = "Family" + bg_color = "#ff9900" + uid = "comment_mood_family" + +/decl/comment_mood/noted_dislike + name = "Noted dislike" + fg_color = COLOR_WHITE + bg_color = "#783f04" + uid = "comment_mood_noted_dislike" + +/decl/comment_mood/fear + name = "Fear" + fg_color = COLOR_WHITE + bg_color = "#0404e1" + uid = "comment_mood_fear" + +/decl/comment_mood/respect + name = "Respect or idolization" + bg_color = "#f9cb9c" + uid = "comment_mood_respect" + +/decl/comment_mood/rival + name = "Rival" + bg_color = COLOR_CYAN + uid = "comment_mood_rival" + +/decl/comment_mood/friendly_acquaintance + name = "Friendly acquaintance" + bg_color = "#57bb8a" + uid = "comment_mood_friendly_acq" + +/decl/comment_mood/pity + name = "Pity" + fg_color = COLOR_WHITE + bg_color = "#073763" + uid = "comment_mood_pity" diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index afdee2dc6bf..ca33fc645ec 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -248,6 +248,7 @@ var/global/template_file_name = "all_templates.json" for(var/type in subtypesof(/datum/asset) - /datum/asset/simple) var/datum/asset/A = new type() A.register() + CHECK_TICK for(var/client/C in global.clients) // This is also called in client/New, but as we haven't initialized the cache until now, and it's possible the client is already connected, we risk doing it twice. // Doing this to a client too soon after they've connected can cause issues, also the proc we call sleeps. diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index f83d5f9cf13..756975d0814 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -84,7 +84,7 @@ var/global/list/localhost_addresses = list( ticket.close(client_repository.get_lite_client(usr.client)) //Logs all hrefs - if(config && config.log_hrefs && global.world_href_log) + if(get_config_value(/decl/config/toggle/log_hrefs) && global.world_href_log) to_file(global.world_href_log, "[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
    ") switch(href_list["_src_"]) @@ -130,14 +130,15 @@ var/global/list/localhost_addresses = list( deactivate_darkmode(clear_chat = FALSE) // Overwritten if the pref is set later. #if DM_VERSION >= 512 - var/bad_version = config.minimum_byond_version && byond_version < config.minimum_byond_version - var/bad_build = config.minimum_byond_build && byond_build < config.minimum_byond_build + var/bad_version = byond_version < get_config_value(/decl/config/num/minimum_byond_version) + var/bad_build = byond_build < get_config_value(/decl/config/num/minimum_byond_build) + if (bad_build || bad_version) to_chat(src, "You are attempting to connect with an out-of-date version of BYOND. Please update to the latest version at http://www.byond.com/ before trying again.") qdel(src) return - if("[byond_version].[byond_build]" in config.forbidden_versions) + if("[byond_version].[byond_build]" in get_config_value(/decl/config/lists/forbidden_versions)) _DB_staffwarn_record(ckey, "Tried to connect with broken and possibly exploitable BYOND build.") to_chat(src, "You are attempting to connect with a broken and possibly exploitable BYOND build. Please update to the latest version at http://www.byond.com/ before trying again.") qdel(src) @@ -145,23 +146,24 @@ var/global/list/localhost_addresses = list( #endif - var/local_connection = (config.auto_local_admin && (isnull(address) || global.localhost_addresses[address])) + var/local_connection = (get_config_value(/decl/config/toggle/on/auto_local_admin) && (isnull(address) || global.localhost_addresses[address])) if(!local_connection) - if(!config.guests_allowed && IsGuestKey(key)) + if(!get_config_value(/decl/config/toggle/guests_allowed) && IsGuestKey(key)) alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK") qdel(src) return - if(config.player_limit != 0) - if((global.clients.len >= config.player_limit) && !(ckey in admin_datums)) - alert(src,"This server is currently full and not accepting new connections.","Server Full","OK") - log_admin("[ckey] tried to join and was turned away due to the server being full (player_limit=[config.player_limit])") - qdel(src) - return + var/player_limit = get_config_value(/decl/config/num/player_limit) + if(player_limit != 0 && global.clients.len >= player_limit && !(ckey in admin_datums)) + alert(src,"This server is currently full and not accepting new connections.","Server Full","OK") + log_admin("[ckey] tried to join and was turned away due to the server being full (player_limit=[player_limit])") + qdel(src) + return // Change the way they should download resources. - if(config.resource_urls && config.resource_urls.len) - src.preload_rsc = pick(config.resource_urls) - else src.preload_rsc = 1 // If config.resource_urls is not set, preload like normal. + var/list/resource_urls = get_config_value(/decl/config/lists/resource_urls) + if(length(resource_urls)) + src.preload_rsc = pick(resource_urls) + else src.preload_rsc = 1 // If resource_urls is not set, preload like normal. global.clients += src global.ckey_directory[ckey] = src @@ -199,17 +201,19 @@ var/global/list/localhost_addresses = list( prefs.last_id = computer_id apply_fps(prefs.clientfps) - if(!isnull(config.lock_client_view_x) && !isnull(config.lock_client_view_y)) - view = "[config.lock_client_view_x]x[config.lock_client_view_y]" + var/lock_x = get_config_value(/decl/config/num/clients/lock_client_view_x) + var/lock_y = get_config_value(/decl/config/num/clients/lock_client_view_y) + if(lock_x > 0 && lock_y > 0) + view = "[lock_x]x[lock_y]" . = ..() //calls mob.Login() global.using_map.map_info(src) - if(custom_event_msg && custom_event_msg != "") + if(global.custom_event_msg) to_chat(src, "

    Custom Event

    ") to_chat(src, "

    A custom event is taking place. OOC Info:

    ") - to_chat(src, "[custom_event_msg]") + to_chat(src, "[global.custom_event_msg]") to_chat(src, "
    ") if(holder) @@ -344,10 +348,10 @@ var/global/list/localhost_addresses = list( var/sql_admin_rank = sql_sanitize_text(admin_rank) if ((player_age <= 0) && !(ckey in global.panic_bunker_bypass)) //first connection - if (config.panic_bunker && !holder && !deadmin_holder) + if (get_config_value(/decl/config/toggle/panic_bunker) && !holder && !deadmin_holder) log_adminwarn("Failed Login: [key] - New account attempting to connect during panic bunker") message_admins("Failed Login: [key] - New account attempting to connect during panic bunker") - to_chat(src, config.panic_bunker_message) + to_chat(src, get_config_value(/decl/config/text/panic_bunker_message)) qdel(src) return 0 @@ -377,9 +381,9 @@ var/global/list/localhost_addresses = list( message_staff("\[[holder.rank]\] [key_name(src)] logged out.") if(!global.admins.len) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. send2adminirc("[key_name(src)] logged out - no more staff online.") - if(config.delist_when_no_admins && global.visibility_pref) - world.update_hub_visibility() - send2adminirc("Toggled hub visibility. The server is now invisible ([global.visibility_pref]).") + if(get_config_value(/decl/config/toggle/delist_when_no_admins) && get_config_value(/decl/config/toggle/hub_visibility)) + toggle_config_value(/decl/config/toggle/hub_visibility) + send2adminirc("Toggled hub visibility. The server is now invisible.") //checks if a client is afk //3000 frames = 5 minutes @@ -499,9 +503,9 @@ var/global/const/MAX_VIEW = 41 return // Some kind of malformed winget(), do not proceed. // Rescale as needed. - var/res_x = config.lock_client_view_x || CEILING(text2num(view_components[1]) / divisor) - var/res_y = config.lock_client_view_y || CEILING(text2num(view_components[2]) / divisor) - var/max_view = config.max_client_view_x || MAX_VIEW + var/res_x = get_config_value(/decl/config/num/clients/lock_client_view_x) || CEILING(text2num(view_components[1]) / divisor) + var/res_y = get_config_value(/decl/config/num/clients/lock_client_view_y) || CEILING(text2num(view_components[2]) / divisor) + var/max_view = get_config_value(/decl/config/num/clients/max_client_view_x) || MAX_VIEW last_view_x_dim = clamp(res_x, MIN_VIEW, max_view) last_view_y_dim = clamp(res_y, MIN_VIEW, max_view) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index c75d436d5d8..8823b103aa4 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -35,7 +35,7 @@ var/list/playables = list() for(var/s in prefilter) - if(!check_rights(R_ADMIN, 0) && config.usealienwhitelist) + if(!check_rights(R_ADMIN, 0) && get_config_value(/decl/config/toggle/use_alien_whitelist)) var/decl/species/checking_species = get_species_by_key(s) if(!(checking_species.spawn_flags & SPECIES_CAN_JOIN)) continue diff --git a/code/modules/client/preference_setup/controls/01_keybindings.dm b/code/modules/client/preference_setup/controls/01_keybindings.dm index 22a21e13a1a..32df0057281 100644 --- a/code/modules/client/preference_setup/controls/01_keybindings.dm +++ b/code/modules/client/preference_setup/controls/01_keybindings.dm @@ -38,7 +38,7 @@ notadded += kb if(length(notadded)) - addtimer(CALLBACK(src, .proc/announce_conflict, notadded), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(announce_conflict), notadded), 5 SECONDS) /datum/preferences/proc/announce_conflict(list/notadded) to_chat(client, SPAN_DANGER("There are new keybindings that have defaults that are already bound - the new keybindings will be unbound until updated. You can rebind them in Setup Character or Game Preferences.")) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 5bde5e6d9b4..81386b8b5f3 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -112,6 +112,11 @@ if(new_name) pref.real_name = new_name + // Update comments record, if it exists. + var/datum/character_information/comments = SScharacter_info.get_record(pref.comments_record_id, TRUE) + if(comments) + comments.char_name = pref.real_name + comments.update_fields() return TOPIC_REFRESH else to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index a45885a7efd..2582487bc45 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -149,44 +149,59 @@ . += "" . += "

    Colouration

    " - . += "" + . += "
    " . += "" - . += "" - . += "" - . += "" + . += "" + . += "" + . += "" + . += "" . += "" . += "" - . += "" - . += "" - . += "" + . += "" + . += "" + . += "" + . += "" . += "" if(mob_bodytype.appearance_flags & HAS_EYE_COLOR) . += "" - . += "" - . += "" + . += "" + . += "" + . += "" if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) . += "" - . += "" - . += "" + . += "" + . += "" + . += "" . += "
    Hair[GET_DECL(pref.h_style)]" + . += "Hair" + + var/const/up_arrow = "⇧" + var/const/down_arrow = "⇩" + var/const/left_arrow = "⇦" + var/const/right_arrow = "⇨" + if(mob_bodytype.appearance_flags & HAS_HAIR_COLOR) . += "[COLORED_SQUARE(pref.hair_colour)] Change" . += "[left_arrow][GET_DECL(pref.h_style)][right_arrow]
    Facial[GET_DECL(pref.f_style)]" + . += "Facial" if(mob_bodytype.appearance_flags & HAS_HAIR_COLOR) . += "[COLORED_SQUARE(pref.facial_hair_colour)] Change" . += "[left_arrow][GET_DECL(pref.f_style)][right_arrow]
    Eyes[COLORED_SQUARE(pref.eye_colour)] ChangeEyes[COLORED_SQUARE(pref.eye_colour)] Change" . += "
    Body[COLORED_SQUARE(pref.skin_colour)] ChangeBody[COLORED_SQUARE(pref.skin_colour)] Change" . += "
    " . += "

    Markings

    " - . += "" + . += "
    " for(var/M in pref.body_markings) var/decl/sprite_accessory/mark = GET_DECL(M) . += "" - . += "" - . += "" + . += "" + . += "" + . += "" + . += "" + . += "" . += "" - . += "" + . += "" . += "
    [mark.name]Remove[COLORED_SQUARE(pref.body_markings[M])] ChangeRemove[COLORED_SQUARE(pref.body_markings[M])] Change[up_arrow][mark.name][down_arrow]
    Add marking
    Add marking
    " . = jointext(.,null) @@ -233,14 +248,50 @@ else if(href_list["hair_style"]) - var/decl/bodytype/B = mob_species.get_bodytype_by_name(pref.bodytype) - mob_species = get_species_by_key(pref.species) - var/decl/sprite_accessory/new_h_style = input(user, "Choose your character's hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.h_style) as null|anything in mob_species.get_hair_styles(B) - mob_species = get_species_by_key(pref.species) - if(new_h_style && CanUseTopic(user) && (new_h_style in mob_species.get_hair_styles(B))) + var/decl/sprite_accessory/new_h_style = input(user, "Choose your character's hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.h_style) as null|anything in mob_species.get_hair_styles(mob_bodytype) + mob_species = get_species_by_key(pref.species) + mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype + if(new_h_style && CanUseTopic(user) && (new_h_style in mob_species.get_hair_styles(mob_bodytype))) pref.h_style = new_h_style.type return TOPIC_REFRESH_UPDATE_PREVIEW + else if(href_list["hair_next"] || href_list["hair_prev"]) + var/decl/sprite_accessory/current_hair = GET_DECL(pref.h_style) + var/list/available_hair = mob_species.get_hair_styles(mob_bodytype) + if(current_hair in available_hair) + if(href_list["hair_next"]) + current_hair = next_in_list(current_hair, available_hair) + else if(href_list["hair_prev"]) + current_hair = previous_in_list(current_hair, available_hair) + if(istype(current_hair) && pref.h_style != current_hair.type) + pref.h_style = current_hair.type + return TOPIC_REFRESH_UPDATE_PREVIEW + + return TOPIC_NOACTION + else if(href_list["facial_style"]) + + var/decl/sprite_accessory/new_f_style = input(user, "Choose your character's facial-hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, GET_DECL(pref.f_style)) as null|anything in mob_species.get_facial_hair_styles(mob_bodytype) + mob_species = get_species_by_key(pref.species) + mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype + if(new_f_style && CanUseTopic(user) && (new_f_style in mob_species.get_facial_hair_styles(mob_bodytype))) + pref.f_style = new_f_style.type + return TOPIC_REFRESH_UPDATE_PREVIEW + + else if(href_list["facial_next"] || href_list["facial_prev"]) + + var/decl/sprite_accessory/current_facial_hair = GET_DECL(pref.f_style) + var/list/available_facial_hair = mob_species.get_facial_hair_styles(mob_bodytype) + if(current_facial_hair in available_facial_hair) + if(href_list["facial_next"]) + current_facial_hair = next_in_list(current_facial_hair, available_facial_hair) + else if(href_list["facial_prev"]) + current_facial_hair = previous_in_list(current_facial_hair, available_facial_hair) + if(istype(current_facial_hair) && pref.f_style != current_facial_hair.type) + pref.f_style = current_facial_hair.type + return TOPIC_REFRESH_UPDATE_PREVIEW + + return TOPIC_NOACTION + else if(href_list["facial_color"]) if(!(mob_bodytype.appearance_flags & HAS_HAIR_COLOR)) return TOPIC_NOACTION @@ -281,37 +332,15 @@ pref.skin_colour = new_skin return TOPIC_REFRESH_UPDATE_PREVIEW - else if(href_list["facial_style"]) - - var/decl/bodytype/B = mob_species.get_bodytype_by_name(pref.bodytype) - mob_species = get_species_by_key(pref.species) - var/decl/sprite_accessory/new_f_style = input(user, "Choose your character's facial-hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, GET_DECL(pref.f_style)) as null|anything in mob_species.get_facial_hair_styles(B) - mob_species = get_species_by_key(pref.species) - if(new_f_style && CanUseTopic(user) && (new_f_style in mob_species.get_facial_hair_styles(B))) - pref.f_style = new_f_style.type - return TOPIC_REFRESH_UPDATE_PREVIEW - //TODO SPRITE ACCESSORY UPDATE else if(href_list["marking_style"]) - var/list/disallowed_markings = list() - for (var/M in pref.body_markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - disallowed_markings |= mark_style.disallows - - var/list/usable_markings = list() - var/list/all_markings = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/marking) - for(var/M in all_markings) - if(M in pref.body_markings) - continue - var/decl/sprite_accessory/accessory = all_markings[M] - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) - if(!is_type_in_list(accessory, disallowed_markings) && accessory.accessory_is_available(preference_mob(), mob_species, mob_bodytype)) - usable_markings += accessory - - var/decl/sprite_accessory/new_marking = input(user, "Choose a body marking:", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in usable_markings + var/decl/sprite_accessory/new_marking = input(user, "Choose a body marking:", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in get_usable_markings(preference_mob(), mob_species, mob_bodytype, pref.body_markings) if(new_marking && CanUseTopic(user)) - pref.body_markings[new_marking.type] = COLOR_BLACK + mob_species = get_species_by_key(pref.species) + mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype + if(new_marking in get_usable_markings(preference_mob(), mob_species, mob_bodytype, pref.body_markings)) + pref.body_markings[new_marking.type] = COLOR_BLACK return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["marking_remove"]) @@ -326,6 +355,44 @@ pref.body_markings[M.type] = "[mark_color]" return TOPIC_REFRESH_UPDATE_PREVIEW + else if(href_list["marking_move_down"]) + var/decl/sprite_accessory/M = locate(href_list["marking_move_down"]) + if(istype(M)) + var/current_index = pref.body_markings.Find(M.type) + if(current_index < length(pref.body_markings)) + var/marking_color = pref.body_markings[M.type] + pref.body_markings -= M.type + pref.body_markings.Insert(current_index+1, M.type) + pref.body_markings[M.type] = marking_color + return TOPIC_REFRESH_UPDATE_PREVIEW + return TOPIC_NOACTION + + else if(href_list["marking_move_up"]) + var/decl/sprite_accessory/M = locate(href_list["marking_move_up"]) + if(istype(M)) + var/current_index = pref.body_markings.Find(M.type) + if(current_index > 1) + var/marking_color = pref.body_markings[M.type] + pref.body_markings -= M.type + pref.body_markings.Insert(current_index-1, M.type) + pref.body_markings[M.type] = marking_color + return TOPIC_REFRESH_UPDATE_PREVIEW + return TOPIC_NOACTION + +/datum/category_item/player_setup_item/physical/body/proc/get_usable_markings(mob/pref_mob, decl/species/mob_species, decl/bodytype/mob_bodytype, list/existing_markings) + var/list/disallowed_markings = list() + for (var/M in existing_markings) + var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) + if(length(mark_style.disallows_accessories)) + disallowed_markings |= mark_style.disallows_accessories + var/list/all_markings = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/marking) + for(var/M in all_markings) + if(M in existing_markings) + continue + var/decl/sprite_accessory/accessory = all_markings[M] + if(!is_type_in_list(accessory, disallowed_markings) && accessory.accessory_is_available(pref_mob, mob_species, mob_bodytype)) + LAZYADD(., accessory) + /datum/category_item/player_setup_item/proc/ResetAllHair() ResetHair() ResetFacialHair() diff --git a/code/modules/client/preference_setup/general/03_aspects.dm b/code/modules/client/preference_setup/general/03_aspects.dm index 6d7448a0b3d..ccebf2a6c27 100644 --- a/code/modules/client/preference_setup/general/03_aspects.dm +++ b/code/modules/client/preference_setup/general/03_aspects.dm @@ -61,7 +61,8 @@ pref.prune_invalid_aspects() var/modified_list = FALSE - while(get_aspect_total() > config.max_character_aspects) + var/max_character_aspects = get_config_value(/decl/config/num/max_character_aspects) + while(get_aspect_total() > max_character_aspects) // Find a costly aspect with no children to drop until our cost is below the threshold. var/can_drop_aspect = FALSE @@ -105,11 +106,12 @@ var/aspect_total = get_aspect_total() // Change our formatting data if needed. var/fcolor = COLOR_CYAN_BLUE - if(aspect_total == config.max_character_aspects) + var/max_character_aspects = get_config_value(/decl/config/num/max_character_aspects) + if(aspect_total == max_character_aspects) fcolor = COLOR_FONT_ORANGE // Build the string. - . = list("
    [aspect_total]/[config.max_character_aspects] points spent.

    ") + . = list("
    [aspect_total]/[max_character_aspects] points spent.

    ") if(!selected_category || !(selected_category in available_categories)) selected_category = available_categories[1] @@ -169,7 +171,7 @@ if(A.children) aspects_to_remove |= A.children // Enable aspect. - else if(get_aspect_total() + A.aspect_cost <= config.max_character_aspects) + else if(get_aspect_total() + A.aspect_cost <= get_config_value(/decl/config/num/max_character_aspects)) pref.aspects |= A.type // Tidy up in case we're in an incoherent state for whatever reason. pref.prune_invalid_aspects() diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index d6c0e0cabee..150c22bc320 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -151,4 +151,4 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) return ..() /proc/can_select_ooc_color(var/mob/user) - return config.allow_admin_ooccolor && check_rights(R_ADMIN, 0, user) + return get_config_value(/decl/config/toggle/admin_ooccolor) && check_rights(R_ADMIN, 0, user) diff --git a/code/modules/client/preference_setup/global/05_settings.dm b/code/modules/client/preference_setup/global/05_settings.dm index d96ac73e0e9..12e2816db9a 100644 --- a/code/modules/client/preference_setup/global/05_settings.dm +++ b/code/modules/client/preference_setup/global/05_settings.dm @@ -42,7 +42,7 @@ pref.preference_values -= key pref.lastchangelog = sanitize_text(pref.lastchangelog, initial(pref.lastchangelog)) - pref.default_slot = sanitize_integer(pref.default_slot, 1, config.character_slots, initial(pref.default_slot)) + pref.default_slot = sanitize_integer(pref.default_slot, 1, get_config_value(/decl/config/num/character_slots), initial(pref.default_slot)) /datum/category_item/player_setup_item/player_global/settings/content(var/mob/user) . = list() diff --git a/code/modules/client/preference_setup/loadout/gear_tweaks.dm b/code/modules/client/preference_setup/loadout/gear_tweaks.dm index 9e536f545f3..74ff9258534 100644 --- a/code/modules/client/preference_setup/loadout/gear_tweaks.dm +++ b/code/modules/client/preference_setup/loadout/gear_tweaks.dm @@ -184,7 +184,7 @@ else reagent = valid_reagents[metadata] if(reagent && gear.reagents) - gear.reagents.add_reagent(reagent, REAGENTS_FREE_SPACE(gear.reagents)) + gear.add_to_reagents(reagent, REAGENTS_FREE_SPACE(gear.reagents)) return GEAR_TWEAK_SUCCESS /* diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 2bdf986fcb1..93a1eefd41c 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -38,7 +38,7 @@ var/global/list/gear_datums = list() return /decl/loadout_option/proc/can_afford(var/mob/user, var/datum/preferences/pref) - if(cost > 0 && (pref.total_loadout_cost + cost) > config.max_gear_cost) + if(cost > 0 && (pref.total_loadout_cost + cost) > get_config_value(/decl/config/num/max_gear_cost)) return FALSE var/decl/loadout_category/LC = GET_DECL(category) if(!LC || pref.total_loadout_selections[category] >= LC.max_selections) @@ -77,14 +77,15 @@ var/global/list/gear_datums = list() /datum/category_item/player_setup_item/loadout/sanitize_character() - pref.gear_slot = sanitize_integer(pref.gear_slot, 1, config.loadout_slots, initial(pref.gear_slot)) + var/loadout_slots = get_config_value(/decl/config/num/loadout_slots) + pref.gear_slot = sanitize_integer(pref.gear_slot, 1, loadout_slots, initial(pref.gear_slot)) if(!islist(pref.gear_list)) pref.gear_list = list() - if(pref.gear_list.len < config.loadout_slots) - pref.gear_list.len = config.loadout_slots + if(pref.gear_list.len < loadout_slots) + pref.gear_list.len = loadout_slots - for(var/index = 1 to config.loadout_slots) + for(var/index = 1 to loadout_slots) pref.total_loadout_cost = 0 pref.total_loadout_selections = list() @@ -118,14 +119,15 @@ var/global/list/gear_datums = list() recalculate_loadout_cost() var/fcolor = COLOR_CYAN_BLUE - if(pref.total_loadout_cost < config.max_gear_cost) + var/max_gear_cost = get_config_value(/decl/config/num/max_gear_cost) + if(pref.total_loadout_cost < max_gear_cost) fcolor = COLOR_FONT_ORANGE . += "" . += "" @@ -296,14 +298,14 @@ var/global/list/gear_datums = list() return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["next_slot"]) pref.gear_slot = pref.gear_slot+1 - if(pref.gear_slot > config.loadout_slots) + if(pref.gear_slot > get_config_value(/decl/config/num/loadout_slots)) pref.gear_slot = 1 recalculate_loadout_cost() return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["prev_slot"]) pref.gear_slot = pref.gear_slot-1 if(pref.gear_slot < 1) - pref.gear_slot = config.loadout_slots + pref.gear_slot = get_config_value(/decl/config/num/loadout_slots) recalculate_loadout_cost() return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["select_category"]) @@ -350,7 +352,7 @@ var/global/list/gear_datums = list() /decl/loadout_option/Initialize() - if(config.allow_loadout_customization) + if(get_config_value(/decl/config/toggle/allow_loadout_customization)) loadout_flags |= GEAR_HAS_CUSTOM_SELECTION . = ..() diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 468760abdd5..0ff94c20d9b 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -426,7 +426,7 @@ var/datum/mil_branch/B = mil_branches.get_branch_by_type(T) dat += "
  • [B.name]: [job.get_ranks(B.name)]" dat += "
    " - if(config.wikiurl) + if(get_config_value(/decl/config/text/wikiurl)) dat += "Open wiki page in browser" var/description = job.get_description_blurb() @@ -438,7 +438,7 @@ else if(href_list["job_wiki"]) var/rank = href_list["job_wiki"] - open_link(user,"[config.wikiurl][rank]") + open_link(user,"[get_config_value(/decl/config/text/wikiurl)][rank]") return ..() diff --git a/code/modules/client/preference_setup/occupation/skill_selection.dm b/code/modules/client/preference_setup/occupation/skill_selection.dm index b1ecefe452b..fe1e59a0012 100644 --- a/code/modules/client/preference_setup/occupation/skill_selection.dm +++ b/code/modules/client/preference_setup/occupation/skill_selection.dm @@ -192,8 +192,7 @@ dat += "
  • " . += "\<\<\[[pref.gear_slot]\] \>\>" - if(config.max_gear_cost < INFINITY) - . += "[pref.total_loadout_cost]/[config.max_gear_cost] loadout points spent." + if(max_gear_cost < INFINITY) + . += "[pref.total_loadout_cost]/[max_gear_cost] loadout points spent." . += "Clear Loadout" . += "[hide_unavailable_gear ? "Show all" : "Hide unavailable"]
    " var/decl/hierarchy/skill/skill = GET_DECL(/decl/hierarchy/skill) for(var/decl/hierarchy/skill/cat in skill.children) - dat += "" + dat += "" for(var/decl/hierarchy/skill/S in cat.children) dat += get_skill_row(job, S) for(var/decl/hierarchy/skill/perk in S.children) @@ -207,7 +206,7 @@ var/level = min + (pref.skills_allocated[job] ? pref.skills_allocated[job][S] : 0) //the current skill level var/cap = pref.get_max_affordable(job, S) //if selecting the skill would make you overspend, it won't be shown dat += "" - dat += "" + dat += "" for(var/i = SKILL_MIN, i <= SKILL_MAX, i++) dat += skill_to_button(S, job, level, i, min, cap) dat += "" @@ -222,20 +221,20 @@ var/offset = skill.prerequisites ? skill.prerequisites[skill.parent.type] - 1 : 0 var/effective_level = selection_level - offset if(effective_level <= 0 || effective_level > length(skill.levels)) - return "" + return "" var/level_name = skill.levels[effective_level] var/cost = skill.get_cost(effective_level) var/button_label = "[level_name] ([cost])" if(effective_level < min) - return "" + return "" else if(effective_level < current_level) - return "" + return "" else if(effective_level == current_level) - return "" + return "" else if(effective_level <= max) - return "" + return "" else - return "" + return "" /datum/category_item/player_setup_item/occupation/proc/add_link(decl/hierarchy/skill/skill, datum/job/job, text, style, value) if(pref.check_skill_prerequisites(job, skill)) diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index ca61617116b..54aec096125 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -42,12 +42,12 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" /datum/category_group/player_setup_category/controls name = "Controls" - sort_order = 9 + sort_order = 8 category_item_type = /datum/category_item/player_setup_item/controls /datum/category_group/player_setup_category/global_preferences name = "Global" - sort_order = 10 + sort_order = 9 category_item_type = /datum/category_item/player_setup_item/player_global diff --git a/code/modules/client/preference_setup/records/00_records.dm b/code/modules/client/preference_setup/records/00_records.dm index 39558c4cc42..da808508666 100644 --- a/code/modules/client/preference_setup/records/00_records.dm +++ b/code/modules/client/preference_setup/records/00_records.dm @@ -6,22 +6,25 @@ /datum/category_item/player_setup_item/records/content(var/mob/user) . = list() - . += "
    [name]:
    " - if(jobban_isbanned(user, "Records") || jobban_isbanned(user, name)) - . += "You are banned from modifying your [lowertext(name)].
    " - else - . += "[TextPreview(pref.records[record_key], 40)]
    " + if(record_key) + . += "
    [name]:
    " + if(jobban_isbanned(user, "Records") || jobban_isbanned(user, name)) + . += "You are banned from modifying your [lowertext(name)].
    " + else + . += "[TextPreview(pref.records[record_key], 40)]
    " . = jointext(.,null) /datum/category_item/player_setup_item/records/OnTopic(var/href,var/list/href_list, var/mob/user) - if (href_list["set_record"]) + if (record_key && href_list["set_record"]) var/new_record = sanitize(input(user,"Enter new [lowertext(name)] here.", CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.records[record_key])) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) if(!isnull(new_record) && !jobban_isbanned(user, "Records") && !jobban_isbanned(user, name) && CanUseTopic(user)) pref.records[record_key] = new_record return TOPIC_REFRESH /datum/category_item/player_setup_item/records/load_character(var/datum/pref_record_reader/R) - pref.records[record_key] = R.read(record_key) + if(record_key) + pref.records[record_key] = R.read(record_key) /datum/category_item/player_setup_item/records/save_character(var/datum/pref_record_writer/P) - P.write(record_key, pref.records[record_key]) + if(record_key) + P.write(record_key, pref.records[record_key]) diff --git a/code/modules/client/preference_setup/records/01_character_info.dm b/code/modules/client/preference_setup/records/01_character_info.dm new file mode 100644 index 00000000000..bf2c6e996fe --- /dev/null +++ b/code/modules/client/preference_setup/records/01_character_info.dm @@ -0,0 +1,66 @@ +/datum/category_item/player_setup_item/records/character_info + name = "Character Information" + sort_order = 1 + record_key = null + +/datum/category_item/player_setup_item/records/character_info/content(var/mob/user) + + var/comments_prep = pref.validate_comments_record() + if(comments_prep) + return "
    [comments_prep]
    " + + var/datum/character_information/comments = SScharacter_info.get_record(pref.comments_record_id, TRUE) + . = list("IC/OOC information preferences:
    ") + if(get_config_value(/decl/config/toggle/allow_character_comments)) + . += "[comments.allow_comments ? "Allowing and displaying comments." : "Not allowing or displaying comments."]
    " + . += "[comments.show_info_on_examine ? "Showing IC and OOC info on examine." : "Not showing IC and OOC info on examine."]
    " + + var/is_banned = jobban_isbanned(user, "Records") || jobban_isbanned(user, name) + . += "
    IC information:
    " + if(is_banned) + . += "You are banned from modifying your IC character information.
    " + else + . += "[TextPreview(comments.ic_info, 40)]
    " + + . += "
    OOC information:
    " + if(is_banned) + . += "You are banned from modifying your OOC character information.
    " + else + . += "[TextPreview(comments.ooc_info, 40)]
    " + . = jointext(.,null) + +/datum/category_item/player_setup_item/records/character_info/OnTopic(var/href,var/list/href_list, var/mob/user) + + if (record_key && href_list["set_record"]) + var/new_record = sanitize(input(user,"Enter new [lowertext(name)] here.", CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.records[record_key])) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) + if(!isnull(new_record) && !jobban_isbanned(user, "Records") && !jobban_isbanned(user, name) && CanUseTopic(user)) + pref.records[record_key] = new_record + return TOPIC_REFRESH + + var/datum/character_information/comments = pref.comments_record_id && SScharacter_info.get_record(pref.comments_record_id, TRUE) + if(comments) + + if(get_config_value(/decl/config/toggle/allow_character_comments) && href_list["toggle_comments"]) + comments.allow_comments = !comments.allow_comments + . = TOPIC_REFRESH + + if(href_list["toggle_examine_info"]) + comments.show_info_on_examine = !comments.show_info_on_examine + . = TOPIC_REFRESH + + if(href_list["set_ic_info"]) + var/new_ic_info = input(user, "Enter your new IC info.", "Set IC Info", comments.ic_info) as null|message + if(isnull(new_ic_info)) + return TOPIC_NOACTION + comments.ic_info = sanitize(new_ic_info) + . = TOPIC_REFRESH + + if(href_list["set_ooc_info"]) + var/new_ooc_info = input(user, "Enter your new OOC info.", "Set OOC Info", comments.ooc_info) as null|message + if(isnull(new_ooc_info)) + return TOPIC_NOACTION + comments.ooc_info = sanitize(new_ooc_info) + . = TOPIC_REFRESH + + if(. == TOPIC_REFRESH && istext(pref.comments_record_id) && length(pref.comments_record_id)) + SScharacter_info.queue_to_save(pref.comments_record_id) diff --git a/code/modules/client/preference_setup/records/01_public_record.dm b/code/modules/client/preference_setup/records/02_public_record.dm similarity index 87% rename from code/modules/client/preference_setup/records/01_public_record.dm rename to code/modules/client/preference_setup/records/02_public_record.dm index 30cecb639cc..eecc37bacee 100644 --- a/code/modules/client/preference_setup/records/01_public_record.dm +++ b/code/modules/client/preference_setup/records/02_public_record.dm @@ -1,4 +1,4 @@ /datum/category_item/player_setup_item/records/public name = "Public Records" - sort_order = 1 + sort_order = 2 record_key = PREF_PUB_RECORD \ No newline at end of file diff --git a/code/modules/client/preference_setup/records/02_medical_record.dm b/code/modules/client/preference_setup/records/03_medical_record.dm similarity index 87% rename from code/modules/client/preference_setup/records/02_medical_record.dm rename to code/modules/client/preference_setup/records/03_medical_record.dm index dcc465c8a85..4633eeddb12 100644 --- a/code/modules/client/preference_setup/records/02_medical_record.dm +++ b/code/modules/client/preference_setup/records/03_medical_record.dm @@ -1,4 +1,4 @@ /datum/category_item/player_setup_item/records/medical name = "Medical Records" - sort_order = 2 + sort_order = 3 record_key = PREF_MED_RECORD diff --git a/code/modules/client/preference_setup/records/03_security_record.dm b/code/modules/client/preference_setup/records/04_security_record.dm similarity index 87% rename from code/modules/client/preference_setup/records/03_security_record.dm rename to code/modules/client/preference_setup/records/04_security_record.dm index 09de3196aa6..2f5f5965b9f 100644 --- a/code/modules/client/preference_setup/records/03_security_record.dm +++ b/code/modules/client/preference_setup/records/04_security_record.dm @@ -1,4 +1,4 @@ /datum/category_item/player_setup_item/records/security name = "Security Records" - sort_order = 1 + sort_order = 4 record_key = PREF_SEC_RECORD diff --git a/code/modules/client/preference_setup/records/04_general_record.dm b/code/modules/client/preference_setup/records/05_general_record.dm similarity index 87% rename from code/modules/client/preference_setup/records/04_general_record.dm rename to code/modules/client/preference_setup/records/05_general_record.dm index 21d9ba865f7..f8539c5fdd0 100644 --- a/code/modules/client/preference_setup/records/04_general_record.dm +++ b/code/modules/client/preference_setup/records/05_general_record.dm @@ -1,4 +1,4 @@ /datum/category_item/player_setup_item/records/general name = "Employment Records" - sort_order = 1 + sort_order = 5 record_key = PREF_GEN_RECORD diff --git a/code/modules/client/preference_setup/records/05_memory.dm b/code/modules/client/preference_setup/records/06_memory.dm similarity index 86% rename from code/modules/client/preference_setup/records/05_memory.dm rename to code/modules/client/preference_setup/records/06_memory.dm index ad7c73638bd..cac94c0e78d 100644 --- a/code/modules/client/preference_setup/records/05_memory.dm +++ b/code/modules/client/preference_setup/records/06_memory.dm @@ -1,4 +1,4 @@ /datum/category_item/player_setup_item/records/memory name = "Memories" - sort_order = 1 + sort_order = 6 record_key = PREF_MEM_RECORD diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ac46b89ff8a..d46d9506d3d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -189,6 +189,17 @@ var/global/list/time_prefs_fixed = list() update_preview_icon() show_character_previews() + // This is a bit out of place; we do this here because it means that loading and viewing + // a character slot is sufficient to refresh our comment history. Otherwise, you would + // have to go back and edit your comments every X days for them to stay visible. + if(comments_record_id) + for(var/record_id in SScharacter_info._comment_holders_by_id) + var/datum/character_information/record = SScharacter_info._comment_holders_by_id[record_id] + if(record) + for(var/datum/character_comment/comment in record.comments) + if(comment.author_id == comments_record_id) + comment.last_updated = REALTIMEOFDAY + var/dat = list("
    ") if(is_guest) dat += SPAN_WARNING("Please create an account to save your preferences. If you have an account and are seeing this, please adminhelp for assistance.") @@ -244,7 +255,6 @@ var/global/list/time_prefs_fixed = list() var/obj/screen/setup_preview/bg/BG = LAZYACCESS(char_render_holders, "BG") if(!BG) BG = new - BG.icon = 'icons/effects/32x32.dmi' BG.pref = src LAZYSET(char_render_holders, "BG", BG) client.screen |= BG @@ -279,13 +289,13 @@ var/global/list/time_prefs_fixed = list() char_render_holders = null /datum/preferences/proc/process_link(mob/user, list/href_list) - - if(!user) return - if(isliving(user)) return - + if(!user) + return + if(isliving(user)) + return if(href_list["preference"] == "open_whitelist_forum") - if(config.forumurl) - direct_output(user, link(config.forumurl)) + if(get_config_value(/decl/config/text/forumurl)) + direct_output(user, link(get_config_value(/decl/config/text/forumurl))) else to_chat(user, "The forum URL is not set in the server configuration.") return @@ -343,6 +353,8 @@ var/global/list/time_prefs_fixed = list() // Sanitizing rather than saving as someone might still be editing when copy_to occurs. player_setup.sanitize_setup() + validate_comments_record() // Make sure a record has been generated for this character. + character.comments_record_id = comments_record_id character.personal_aspects = list() var/decl/bodytype/new_bodytype = get_bodytype_decl() if(species == character.get_species_name()) @@ -352,9 +364,10 @@ var/global/list/time_prefs_fixed = list() if(be_random_name) var/decl/cultural_info/culture = GET_DECL(cultural_info[TAG_CULTURE]) - if(culture) real_name = culture.get_random_name(gender) + if(culture) + real_name = culture.get_random_name(gender) - if(config.humans_need_surnames) + if(get_config_value(/decl/config/toggle/humans_need_surnames)) var/firstspace = findtext(real_name, " ") var/name_length = length(real_name) if(!firstspace) //we need a surname @@ -367,20 +380,17 @@ var/global/list/time_prefs_fixed = list() character.set_gender(gender) character.blood_type = blood_type - character.eye_colour = eye_colour + character.set_eye_colour(eye_colour, skip_update = TRUE) - character.h_style = h_style - character.hair_colour = hair_colour + character.set_hairstyle(h_style, skip_update = TRUE) + character.set_hair_colour(hair_colour, skip_update = TRUE) - character.f_style = f_style - character.facial_hair_colour = facial_hair_colour + character.set_facial_hairstyle(f_style, skip_update = TRUE) + character.set_facial_hair_colour(facial_hair_colour, skip_update = TRUE) - character.skin_colour = skin_colour + character.set_skin_colour(skin_colour, skip_update = TRUE) character.skin_tone = skin_tone - character.h_style = h_style - character.f_style = f_style - QDEL_NULL_LIST(character.worn_underwear) character.worn_underwear = list() @@ -466,7 +476,8 @@ var/global/list/time_prefs_fixed = list() dat += "
    " dat += "Select a character slot to load
    " - for(var/i=1, i<= config.character_slots, i++) + var/character_slots = get_config_value(/decl/config/num/character_slots) + for(var/i = 1 to character_slots) var/name = (slot_names && slot_names[get_slot_key(i)]) || "Character[i]" if(i==default_slot) name = "[name]" diff --git a/code/modules/client/preferences_persist.dm b/code/modules/client/preferences_persist.dm index d18dd143f3a..a5fbeba0660 100644 --- a/code/modules/client/preferences_persist.dm +++ b/code/modules/client/preferences_persist.dm @@ -1,4 +1,6 @@ #define PREF_SER_VERSION 1 +/datum/preferences + var/comments_record_id /datum/preferences/proc/get_path(ckey, record_key, extension="json") return "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[record_key].[extension]" @@ -42,9 +44,28 @@ R = new /datum/pref_record_reader/null_reader(PREF_SER_VERSION) player_setup.load_preferences(R) +/datum/preferences/proc/validate_comments_record(var/validate_slot) + if(!SScharacter_info.initialized) + return "The comments subsystem is still loading, or something has gone wrong. Please wait for server initialization to finish, and contact an admin if this message persists afterwards." + if(isnull(validate_slot)) + validate_slot = default_slot + var/slot_key = validate_slot && get_slot_key(validate_slot) + if(!slot_key || !LAZYACCESS(slot_names, slot_key)) // Not actually a character slot. + return "You have tried to validate an invalid slot ('[validate_slot || "null"]'). Please report this as a bug on the issue tracker." + comments_record_id = SScharacter_info.get_record_id("[client_ckey]-[get_slot_key(validate_slot || default_slot)]") + var/datum/character_information/comments = SScharacter_info.get_record(comments_record_id, TRUE) + if(!comments) + comments = SScharacter_info.get_or_create_record(comments_record_id, TRUE) + comments.ckey = client_ckey + comments.char_name = slot_names[slot_key] || "Unknown" // this may be inaccurate but it doesn't really matter at this point. + comments.update_fields() + comments_record_id = comments.record_id + /datum/preferences/proc/save_preferences() var/datum/pref_record_writer/json_list/W = new(PREF_SER_VERSION) player_setup.save_preferences(W) + if(istext(comments_record_id) && length(comments_record_id)) + SScharacter_info.queue_to_save(comments_record_id) save_pref_record("preferences", W.data) /datum/preferences/proc/get_slot_key(slot) @@ -55,19 +76,23 @@ slot = default_slot if(slot != SAVE_RESET) // SAVE_RESET will reset the slot as though it does not exist, but keep the current slot for saving purposes. - slot = sanitize_integer(slot, 1, config.character_slots, initial(default_slot)) + slot = sanitize_integer(slot, 1, get_config_value(/decl/config/num/character_slots), initial(default_slot)) if(slot != default_slot) default_slot = slot SScharacter_setup.queue_preferences_save(src) + var/record_id = "[client_ckey]-[get_slot_key(default_slot)]" if(slot == SAVE_RESET) // If we're resetting, set everything to null. Sanitization will clean it up var/datum/pref_record_reader/null_reader/R = new(PREF_SER_VERSION) + SScharacter_info.clear_record(record_id) player_setup.load_character(R) else var/datum/pref_record_reader/R = load_pref_record(get_slot_key(slot)) if(!R) R = new /datum/pref_record_reader/null_reader(PREF_SER_VERSION) + // Load/reload our character info record - mass preload is done if comments are enabled, but not done otherwise. + SScharacter_info.reload_record(record_id) player_setup.load_character(R) update_preview_icon() diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 1a5e24041cb..4964c78c69f 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -1,7 +1,7 @@ /obj/item/clothing name = "clothing" siemens_coefficient = 0.9 - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/organic/cloth var/wizard_garb = 0 @@ -17,7 +17,6 @@ var/blood_overlay_type = "uniformblood" var/visible_name = "Unknown" var/ironed_state = WRINKLES_DEFAULT - var/smell_state = SMELL_DEFAULT var/move_trail = /obj/effect/decal/cleanable/blood/tracks/footprints // if this item covers the feet, the footprints it should leave var/volume_multiplier = 1 var/markings_icon // simple colored overlay that would be applied to the icon @@ -59,7 +58,7 @@ // End placeholder. // Updates the vision of the mob wearing the clothing item, if any -/obj/item/clothing/proc/update_vision() +/obj/item/clothing/proc/update_wearer_vision() if(isliving(src.loc)) var/mob/living/L = src.loc L.handle_vision() @@ -68,17 +67,17 @@ /obj/item/clothing/proc/needs_vision_update() return flash_protection || tint -/obj/item/clothing/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) + if(markings_icon && markings_color && check_state_in_icon("[overlay.icon_state][markings_icon]", overlay.icon)) + overlay.overlays += mutable_appearance(overlay.icon, "[overlay.icon_state][markings_icon]", markings_color) + if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) if(A.should_overlay()) - overlay.overlays += A.get_mob_overlay(user_mob, slot) - - if(markings_icon && markings_color && check_state_in_icon("[overlay.icon_state][markings_icon]", overlay.icon)) - overlay.overlays += mutable_appearance(overlay.icon, "[overlay.icon_state][markings_icon]", markings_color) + overlay.overlays += A.get_mob_overlay(user_mob, slot, skip_offset = TRUE) if(!(slot in user_mob?.get_held_item_slots())) if(blood_DNA) @@ -105,8 +104,14 @@ if(LAZYLEN(new_overlays)) add_overlay(new_overlays) -/obj/item/clothing/proc/change_smell(smell = SMELL_DEFAULT) - smell_state = smell +// Used by washing machines to temporarily make clothes smell +/obj/item/clothing/proc/change_smell(decl/material/odorant, time = 10 MINUTES) + if(!odorant || !odorant.scent) + remove_extension(src, /datum/extension/scent) + return + + set_extension(src, /datum/extension/scent/custom, odorant.scent, odorant.scent_intensity, odorant.scent_descriptor, odorant.scent_range) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/clothing, change_smell)), time, TIMER_UNIQUE | TIMER_OVERRIDE) /obj/item/clothing/proc/get_fibers() . = "material from \a [name]" @@ -147,7 +152,7 @@ /obj/item/clothing/equipped(var/mob/user) if(needs_vision_update()) - update_vision() + update_wearer_vision() return ..() /obj/item/clothing/proc/refit_for_bodytype(var/target_bodytype) @@ -192,12 +197,6 @@ if(WRINKLES_NONE) to_chat(user, "It's completely wrinkle-free!") - switch(smell_state) - if(SMELL_CLEAN) - to_chat(user, "It smells clean!") - if(SMELL_STINKY) - to_chat(user, "It's quite stinky!") - var/rags = RAG_COUNT(src) if(rags) to_chat(user, SPAN_SUBTLE("With a sharp object, you could cut \the [src] up into [rags] rag\s.")) diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index bc323d94fea..2d247d30dd2 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -47,7 +47,7 @@ name = "jumpsuit" icon = 'icons/clothing/under/jumpsuits/jumpsuit.dmi' desc = "It's a plain jumpsuit. It seems to have a small dial on the wrist." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -76,7 +76,7 @@ name = "grey cap" desc = "It looks like a plain hat, but upon closer inspection, there's an advanced holographic array installed inside. It seems to have a small dial inside." icon = 'icons/clothing/head/softcap.dmi' - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' body_parts_covered = 0 item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -106,7 +106,7 @@ name = "armor" icon = 'icons/clothing/suit/armor/vest.dmi' desc = "It appears to be a vest of standard armor, except this is embedded with a hidden holographic cloaker, allowing it to change it's appearance, but offering no protection.. It seems to have a small dial inside." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -134,7 +134,7 @@ name = "black shoes" icon = 'icons/clothing/feet/colored_shoes.dmi' desc = "They're comfy black shoes, with clever cloaking technology built in. It seems to have a small dial on the back of each shoe." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -161,7 +161,7 @@ /obj/item/storage/backpack/chameleon name = "backpack" desc = "A backpack outfitted with cloaking tech. It seems to have a small dial inside, kept away from the storage." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON icon = 'icons/obj/items/storage/backpack/backpack.dmi' var/static/list/clothing_choices @@ -197,7 +197,7 @@ color = COLOR_GRAY40 icon = 'icons/clothing/hands/gloves_generic.dmi' desc = "It looks like a pair of gloves, but it seems to have a small dial inside." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -226,7 +226,7 @@ name = "gas mask" icon = 'icons/clothing/mask/gas_mask_full.dmi' desc = "It looks like a plain gask mask, but on closer inspection, it seems to have a small dial inside." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -255,7 +255,7 @@ name = "Optical Meson Scanner" icon = 'icons/clothing/eyes/scanner_meson.dmi' desc = "It looks like a plain set of mesons, but on closer inspection, it seems to have a small dial inside." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -284,7 +284,7 @@ name = "radio headset" icon = 'icons/obj/items/device/radio/headsets/headset.dmi' desc = "An updated, modular intercom that fits over the head. This one seems to have a small dial on it." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -316,7 +316,7 @@ name = "tie" icon = 'icons/clothing/accessories/ties/tie.dmi' desc = "A neosilk clip-on tie. It seems to have a small dial on its back." - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON var/static/list/clothing_choices @@ -355,7 +355,7 @@ icon = 'icons/obj/guns/revolvers.dmi' icon_state = "revolver" w_class = ITEM_SIZE_SMALL - origin_tech = "{'combat':2,'materials':2,'esoteric':8}" + origin_tech = @'{"combat":2,"materials":2,"esoteric":8}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON matter = list() diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 51ec87f2dd1..6965ff74c73 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -32,7 +32,7 @@ if(ispath(hud)) hud = new hud(src) -/obj/item/clothing/glasses/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/glasses/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && active && check_state_in_icon("[overlay.icon_state]-active", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-active" . = ..() @@ -69,7 +69,7 @@ active = _active update_icon() update_clothing_icon() - update_vision() + update_wearer_vision() /obj/item/clothing/glasses/on_update_icon() . = ..() diff --git a/code/modules/clothing/glasses/eyepatch.dm b/code/modules/clothing/glasses/eyepatch.dm index 57b9e63696b..8c463e9df31 100644 --- a/code/modules/clothing/glasses/eyepatch.dm +++ b/code/modules/clothing/glasses/eyepatch.dm @@ -60,7 +60,7 @@ eye.color = eye_color add_overlay(eye) -/obj/item/clothing/glasses/eyepatch/hud/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/glasses/eyepatch/hud/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && active && check_state_in_icon("[overlay.icon_state]-eye", overlay.icon)) var/image/eye = emissive_overlay(overlay.icon, "[overlay.icon_state]-eye") eye.color = eye_color diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 8200333336e..d5be4791a90 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -4,7 +4,7 @@ gender = NEUTER icon = 'icons/clothing/eyes/scanner_meson.dmi' action_button_name = "Toggle Goggles" - origin_tech = "{'magnets':2,'engineering':2}" + origin_tech = @'{"magnets":2,"engineering":2}' toggleable = TRUE vision_flags = SEE_TURFS see_invisible = SEE_INVISIBLE_NOLIGHTING @@ -43,7 +43,7 @@ name = "night vision goggles" desc = "You can totally see in the dark now!" icon = 'icons/clothing/eyes/night_vision.dmi' - origin_tech = "{'magnets':2}" + origin_tech = @'{"magnets":2}' darkness_view = 7 action_button_name = "Toggle Goggles" toggleable = TRUE @@ -59,7 +59,7 @@ name = "tactical goggles" desc = "Self-polarizing goggles with light amplification for dark environments. Made from durable synthetic." icon = 'icons/clothing/eyes/tactical.dmi' - origin_tech = "{'magnets':2,'combat':4}" + origin_tech = @'{"magnets":2,"combat":4}' darkness_view = 5 action_button_name = "Toggle Goggles" toggleable = TRUE @@ -79,7 +79,7 @@ desc = "Very confusing glasses." gender = NEUTER icon = 'icons/clothing/eyes/scanner_material.dmi' - origin_tech = "{'magnets':3,'engineering':3}" + origin_tech = @'{"magnets":3,"engineering":3}' action_button_name = "Toggle Goggles" toggleable = TRUE vision_flags = SEE_OBJS diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 4a4b6dc75a4..7da212e8b23 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -1,7 +1,7 @@ /obj/item/clothing/glasses/hud name = "\improper HUD" desc = "A heads-up display that provides important info in (almost) real time." - origin_tech = "{'magnets':3,'biotech':2}" + origin_tech = @'{"magnets":3,"biotech":2}' electric = TRUE gender = NEUTER toggleable = TRUE diff --git a/code/modules/clothing/glasses/thermals.dm b/code/modules/clothing/glasses/thermals.dm index fdef3ff4234..6938f8ecea8 100644 --- a/code/modules/clothing/glasses/thermals.dm +++ b/code/modules/clothing/glasses/thermals.dm @@ -4,7 +4,7 @@ gender = NEUTER icon = 'icons/clothing/eyes/scanner_thermal.dmi' action_button_name = "Toggle Goggles" - origin_tech = "{'magnets':3}" + origin_tech = @'{"magnets":3}' toggleable = TRUE vision_flags = SEE_MOBS see_invisible = SEE_INVISIBLE_NOLIGHTING @@ -19,7 +19,7 @@ name = "optical meson scanner" desc = "Used for seeing walls, floors, and stuff through anything." icon = 'icons/clothing/eyes/scanner_meson.dmi' - origin_tech = "{'magnets':3,'esoteric':4}" + origin_tech = @'{"magnets":3,"esoteric":4}' /obj/item/clothing/glasses/thermal/plain toggleable = FALSE diff --git a/code/modules/clothing/gloves/thick.dm b/code/modules/clothing/gloves/thick.dm index f6b427c2857..abe645566bb 100644 --- a/code/modules/clothing/gloves/thick.dm +++ b/code/modules/clothing/gloves/thick.dm @@ -42,7 +42,7 @@ . = ..() add_overlay(overlay_image(icon, "[icon_state]-botany_fingertips", flags = RESET_COLOR)) -/obj/item/clothing/gloves/thick/botany/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/gloves/thick/botany/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && slot == slot_gloves_str) var/image/I = image(overlay.icon, "[overlay.icon_state]-botany_fingertips") I.appearance_flags |= RESET_COLOR diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index 4f76465ad68..f827db47936 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -36,8 +36,14 @@ /obj/item/clothing/head/on_update_icon(var/mob/user) . = ..() update_clothing_icon() + if(on) + var/light_state = "[icon_state]_light" + if(check_state_in_icon(light_state, icon)) + var/image/light_overlay = image(icon, light_state) + light_overlay.appearance_flags |= RESET_COLOR + add_overlay(light_overlay) -/obj/item/clothing/head/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && on && check_state_in_icon("[overlay.icon_state]_light", overlay.icon)) var/light_overlay if(user_mob.get_bodytype_category() != bodytype) diff --git a/code/modules/clothing/head/fated_key.dm b/code/modules/clothing/head/fated_key.dm index 7220fb501e8..676131c55e5 100644 --- a/code/modules/clothing/head/fated_key.dm +++ b/code/modules/clothing/head/fated_key.dm @@ -12,7 +12,7 @@ canremove = FALSE to_chat(user, SPAN_DANGER("\The [src] shatters your mind as it sears through [user.isSynthetic() ? "metal and circuitry" : "flesh and bone"], embedding itself into your skull!")) SET_STATUS_MAX(user, STAT_PARA, 5) - addtimer(CALLBACK(src, .proc/activate_role), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(activate_role)), 5 SECONDS) else canremove = TRUE name = initial(name) diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index fe8ec003bd8..fbfcf71f12c 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -21,7 +21,7 @@ max_pressure_protection = FIRESUIT_MAX_PRESSURE material = /decl/material/solid/organic/plastic matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' /obj/item/clothing/head/hardhat/orange icon = 'icons/clothing/head/hardhat/orange.dmi' diff --git a/code/modules/clothing/head/headphones.dm b/code/modules/clothing/head/headphones.dm index 061e6763f37..cf76daf453a 100644 --- a/code/modules/clothing/head/headphones.dm +++ b/code/modules/clothing/head/headphones.dm @@ -23,7 +23,7 @@ icon_state = "[icon_state]-on" update_clothing_icon() -/obj/item/clothing/head/headphones/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/headphones/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && headphones_on) overlay.icon_state = "[overlay.icon_state]-on" . = ..() diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 6912f12d885..7a4968e071d 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -22,7 +22,7 @@ w_class = ITEM_SIZE_NORMAL material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/plasteel = MATTER_AMOUNT_TRACE) - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' protects_against_weather = TRUE /obj/item/clothing/head/helmet/tactical @@ -38,7 +38,7 @@ ) siemens_coefficient = 0.6 material = /decl/material/solid/metal/plasteel - origin_tech = "{'materials':2,'engineering':2,'combat':2}" + origin_tech = @'{"materials":2,"engineering":2,"combat":2}' /obj/item/clothing/head/helmet/merc name = "combat helmet" @@ -54,7 +54,7 @@ siemens_coefficient = 0.5 material = /decl/material/solid/metal/plasteel matter = list(/decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':2,'engineering':2,'combat':2}" + origin_tech = @'{"materials":2,"engineering":2,"combat":2}' /obj/item/clothing/head/helmet/riot name = "riot helmet" @@ -86,7 +86,7 @@ icon_state = "[icon_state]_up" update_clothing_icon() -/obj/item/clothing/head/helmet/riot/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/helmet/riot/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && up && check_state_in_icon("[overlay.icon_state]_up", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_up" . = ..() @@ -122,7 +122,7 @@ /decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':3,'engineering':2,'combat':3}" + origin_tech = @'{"materials":3,"engineering":2,"combat":3}' /obj/item/clothing/head/helmet/swat name = "\improper SWAT helmet" @@ -140,7 +140,7 @@ siemens_coefficient = 0.5 material = /decl/material/solid/metal/plasteel matter = list(/decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':4,'engineering':2,'combat':4}" + origin_tech = @'{"materials":4,"engineering":2,"combat":4}' /obj/item/clothing/head/helmet/thunderdome name = "\improper Thunderdome helmet" @@ -159,7 +159,7 @@ siemens_coefficient = 1 material = /decl/material/solid/metal/plasteel matter = list(/decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':4,'engineering':2,'combat':4}" + origin_tech = @'{"materials":4,"engineering":2,"combat":4}' /obj/item/clothing/head/helmet/gladiator name = "gladiator helmet" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 45afe3be1da..fc94245aa29 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -60,7 +60,7 @@ flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) to_chat(usr, "You push the [src] up out of your face.") update_icon() - update_vision() + update_wearer_vision() usr.update_action_buttons() /obj/item/clothing/head/welding/on_update_icon() @@ -70,7 +70,7 @@ icon_state = "[icon_state]_up" update_clothing_icon() //so our mob-overlays -/obj/item/clothing/head/welding/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/welding/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && up && check_state_in_icon("[overlay.icon_state]_up", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_up" . = ..() @@ -126,7 +126,7 @@ icon_state = "[icon_state]_up" update_clothing_icon() -/obj/item/clothing/head/ushanka/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/ushanka/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && up && check_state_in_icon("[overlay.icon_state]_up", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_up" . = ..() @@ -198,7 +198,7 @@ if(overlay && check_state_in_icon("[overlay.icon_state]-flame", overlay.icon)) return emissive_overlay(overlay.icon, "[overlay.icon_state]-flame") -/obj/item/clothing/head/cakehat/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/cakehat/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && is_on_fire) var/image/I = get_mob_flame_overlay(overlay, bodytype) if(I) diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 885b9195403..48ab694d380 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -13,7 +13,7 @@ if(flipped) icon_state = "[get_world_inventory_state()]_flipped" -/obj/item/clothing/head/soft/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/soft/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && flipped && check_state_in_icon("[overlay.icon_state]_flipped", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_flipped" . = ..() diff --git a/code/modules/clothing/masks/_mask.dm b/code/modules/clothing/masks/_mask.dm index 75983d478c8..58cc28b335f 100644 --- a/code/modules/clothing/masks/_mask.dm +++ b/code/modules/clothing/masks/_mask.dm @@ -7,7 +7,7 @@ blood_overlay_type = "maskblood" material = /decl/material/solid/fiberglass matter = list(/decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' var/voicechange = 0 var/list/say_messages @@ -33,7 +33,7 @@ . = ..() LAZYDISTINCTADD(., slot_wear_mask_str) -/obj/item/clothing/mask/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/mask/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && hanging && slot == slot_wear_mask_str && check_state_in_icon("[overlay.icon_state]-down", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-down" . = ..() diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index f3719365900..06d78421b29 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -12,7 +12,7 @@ down_body_parts_covered = null down_item_flags = ITEM_FLAG_THICKMATERIAL pull_mask = 1 - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/organic/plastic /obj/item/clothing/mask/breath/medical diff --git a/code/modules/clothing/masks/chewable.dm b/code/modules/clothing/masks/chewable.dm index aab492be317..da3a158804b 100644 --- a/code/modules/clothing/masks/chewable.dm +++ b/code/modules/clothing/masks/chewable.dm @@ -91,14 +91,14 @@ desc = "A chewy wad of tobacco. Cut in long strands and treated with syrups so it tastes less like a ash-tray when you stuff it into your face." /obj/item/clothing/mask/chewable/tobacco/lenni/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco, 2) + add_to_reagents(/decl/material/solid/tobacco, 2) /obj/item/clothing/mask/chewable/tobacco/redlady name = "chewing tobacco" desc = "A chewy wad of fine tobacco. Cut in long strands and treated with syrups so it doesn't taste like a ash-tray when you stuff it into your face" /obj/item/clothing/mask/chewable/tobacco/redlady/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/fine, 2) + add_to_reagents(/decl/material/solid/tobacco/fine, 2) /obj/item/clothing/mask/chewable/tobacco/nico name = "nicotine gum" @@ -111,7 +111,7 @@ color = reagents.get_color() /obj/item/clothing/mask/chewable/tobacco/nico/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nicotine, 2) + add_to_reagents(/decl/material/liquid/nicotine, 2) /obj/item/clothing/mask/chewable/candy name = "wad" @@ -127,10 +127,10 @@ var/initial_payload_amount = 3 /obj/item/clothing/mask/chewable/candy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 2) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 2) var/list/possible_payloads = get_possible_initial_reagents() if(length(possible_payloads)) - reagents.add_reagent(pick(possible_payloads), initial_payload_amount) + add_to_reagents(pick(possible_payloads), initial_payload_amount) /obj/item/clothing/mask/chewable/candy/proc/get_possible_initial_reagents() return @@ -221,7 +221,7 @@ /obj/item/clothing/mask/chewable/candy/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 4) //6u in total + add_to_reagents(/decl/material/liquid/nutriment/sugar, 4) //6u in total /obj/item/clothing/mask/chewable/candy/lolli/weak_meds/get_possible_initial_reagents() return list( diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 204c8033c72..d9782216eb0 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -112,7 +112,7 @@ /decl/material/solid/glass = MATTER_AMOUNT_SECONDARY, /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/mask/gas/syndicate name = "tactical mask" @@ -130,7 +130,7 @@ /decl/material/solid/glass = MATTER_AMOUNT_SECONDARY, /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/mask/gas/death_commando name = "\improper Death Commando Mask" @@ -153,7 +153,7 @@ ) body_parts_covered = SLOT_HEAD|SLOT_FACE|SLOT_EYES material = /decl/material/solid/organic/cloth - origin_tech = "{'materials':1,'engineering':2}" + origin_tech = @'{"materials":1,"engineering":2}' /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 830763e2872..4856bf57ba5 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -107,7 +107,7 @@ flags_inv = HIDEFACE body_parts_covered = SLOT_FACE|SLOT_EYES action_button_name = "Toggle MUI" - origin_tech = "{'programming':5,'engineering':5}" + origin_tech = @'{"programming":5,"engineering":5}' /obj/item/clothing/mask/ai/Initialize() . = ..() diff --git a/code/modules/clothing/masks/monitor.dm b/code/modules/clothing/masks/monitor.dm index 0cc94b7409b..cd63c8a0823 100644 --- a/code/modules/clothing/masks/monitor.dm +++ b/code/modules/clothing/masks/monitor.dm @@ -47,7 +47,7 @@ . = ..() update_icon() -/obj/item/clothing/mask/monitor/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/mask/monitor/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) if(!(monitor_state_index in monitor_states)) monitor_state_index = initial(monitor_state_index) diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm index 489b2364f62..d530c9abfad 100644 --- a/code/modules/clothing/masks/smokable.dm +++ b/code/modules/clothing/masks/smokable.dm @@ -22,6 +22,9 @@ var/smoke_effect = 0 var/smoke_amount = 1 +/obj/item/clothing/mask/smokable/get_tool_quality(archetype, property) + return (!lit && archetype == TOOL_CAUTERY) ? TOOL_QUALITY_NONE : ..() + /obj/item/clothing/mask/smokable/dropped(mob/user) . = ..() if(lit) @@ -63,7 +66,7 @@ reagents.trans_to_mob(C, smoke_amount * amount, CHEM_INHALE, 0.2) add_trace_DNA(C) else // else just remove some of the reagents - reagents.remove_any(smoke_amount * amount) + remove_any_reagents(smoke_amount * amount) smoke_effect++ @@ -110,7 +113,7 @@ M.update_equipment_overlay(slot_wear_mask_str, FALSE) M.update_inhand_overlays() -/obj/item/clothing/mask/smokable/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/mask/smokable/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && lit && check_state_in_icon("[overlay.icon_state]-on", overlay.icon)) var/image/on_overlay = emissive_overlay(overlay.icon, "[overlay.icon_state]-on") on_overlay.appearance_flags |= RESET_COLOR @@ -212,7 +215,7 @@ set_extension(src, /datum/extension/tool, list(TOOL_CAUTERY = TOOL_QUALITY_MEDIOCRE)) /obj/item/clothing/mask/smokable/cigarette/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco, 1) + add_to_reagents(/decl/material/solid/tobacco, 1) /obj/item/clothing/mask/smokable/cigarette/light(var/flavor_text = "[usr] lights the [name].") ..() @@ -245,7 +248,7 @@ /obj/item/clothing/mask/smokable/cigarette/menthol/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/menthol, 1) + add_to_reagents(/decl/material/liquid/menthol, 1) /obj/item/trash/cigbutt/menthol icon = 'icons/clothing/mask/smokables/cigarette_menthol_butt.dmi' @@ -261,7 +264,7 @@ type_butt = /obj/item/trash/cigbutt/jerichos /obj/item/clothing/mask/smokable/cigarette/jerichos/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/bad, 1.5) + add_to_reagents(/decl/material/solid/tobacco/bad, 1.5) /obj/item/trash/cigbutt/jerichos icon = 'icons/clothing/mask/smokables/cigarette_jericho_butt.dmi' @@ -278,7 +281,7 @@ type_butt = /obj/item/trash/cigbutt/professionals /obj/item/clothing/mask/smokable/cigarette/professionals/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/bad, 1) + add_to_reagents(/decl/material/solid/tobacco/bad, 1) /obj/item/trash/cigbutt/professionals icon = 'icons/clothing/mask/smokables/cigarette_professional_butt.dmi' @@ -300,7 +303,7 @@ var/band_color /obj/item/clothing/mask/smokable/cigarette/trident/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/fine, 2) + add_to_reagents(/decl/material/solid/tobacco/fine, 2) /obj/item/clothing/mask/smokable/cigarette/trident/on_update_icon() . = ..() @@ -315,42 +318,42 @@ /obj/item/clothing/mask/smokable/cigarette/trident/mint/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/menthol, 2) + add_to_reagents(/decl/material/liquid/menthol, 2) /obj/item/clothing/mask/smokable/cigarette/trident/berry band_color = COLOR_VIOLET /obj/item/clothing/mask/smokable/cigarette/trident/berry/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/berry, 2) + add_to_reagents(/decl/material/liquid/drink/juice/berry, 2) /obj/item/clothing/mask/smokable/cigarette/trident/cherry band_color = COLOR_RED /obj/item/clothing/mask/smokable/cigarette/trident/cherry/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/cherryjelly, 2) + add_to_reagents(/decl/material/liquid/nutriment/cherryjelly, 2) /obj/item/clothing/mask/smokable/cigarette/trident/grape band_color = COLOR_PURPLE /obj/item/clothing/mask/smokable/cigarette/trident/grape/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/grape, 2) + add_to_reagents(/decl/material/liquid/drink/juice/grape, 2) /obj/item/clothing/mask/smokable/cigarette/trident/watermelon band_color = COLOR_GREEN /obj/item/clothing/mask/smokable/cigarette/trident/watermelon/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/watermelon, 2) + add_to_reagents(/decl/material/liquid/drink/juice/watermelon, 2) /obj/item/clothing/mask/smokable/cigarette/trident/orange band_color = COLOR_ORANGE /obj/item/clothing/mask/smokable/cigarette/trident/orange/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/orange, 2) + add_to_reagents(/decl/material/liquid/drink/juice/orange, 2) /obj/item/trash/cigbutt/woodbutt name = "wooden tip" @@ -390,13 +393,12 @@ return ..() /obj/item/clothing/mask/smokable/cigarette/afterattack(obj/item/chems/glass/glass, var/mob/user, proximity) - ..() if(!proximity) return - if(istype(glass)) //you can dip cigarettes into beakers + if(!lit && istype(glass)) //you can dip unlit cigarettes into beakers. todo: extinguishing lit cigarettes in beakers? disambiguation via intent? if(!ATOM_IS_OPEN_CONTAINER(glass)) to_chat(user, SPAN_NOTICE("You need to take the lid off first.")) - return + return TRUE var/transfered = glass.reagents.trans_to_obj(src, chem_volume) if(transfered) //if reagents were transfered, show the message to_chat(user, SPAN_NOTICE("You dip \the [src] into \the [glass].")) @@ -405,6 +407,8 @@ to_chat(user, SPAN_NOTICE("[glass] is empty.")) else to_chat(user, SPAN_NOTICE("[src] is full.")) + return TRUE + return ..() /obj/item/clothing/mask/smokable/cigarette/attack_self(var/mob/user) if(lit == 1) @@ -431,7 +435,7 @@ brand = null /obj/item/clothing/mask/smokable/cigarette/cigar/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/fine, 5) + add_to_reagents(/decl/material/solid/tobacco/fine, 5) /obj/item/clothing/mask/smokable/cigarette/cigar/cohiba name = "\improper Cohiba Robusto cigar" @@ -448,7 +452,7 @@ brand = "Havana" /obj/item/clothing/mask/smokable/cigarette/cigar/havana/populate_reagents() - reagents.add_reagent(/decl/material/solid/tobacco/fine, 10) + add_to_reagents(/decl/material/solid/tobacco/fine, 10) /obj/item/trash/cigbutt name = "cigarette butt" @@ -486,7 +490,7 @@ brand = "sausage... wait what." /obj/item/clothing/mask/smokable/cigarette/rolled/sausage/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/trash/cigbutt/sausagebutt name = "sausage butt" diff --git a/code/modules/clothing/masks/voice.dm b/code/modules/clothing/masks/voice.dm index 9cd680243c9..edee4acd8eb 100644 --- a/code/modules/clothing/masks/voice.dm +++ b/code/modules/clothing/masks/voice.dm @@ -9,7 +9,7 @@ name = "gas mask" desc = "A face-covering mask that can be connected to an air supply. It seems to house some odd electronics." var/obj/item/voice_changer/changer - origin_tech = "{'esoteric':4}" + origin_tech = @'{"esoteric":4}' /obj/item/clothing/mask/chameleon/voice/verb/Toggle_Voice_Changer() set category = "Object" diff --git a/code/modules/clothing/rings/rings.dm b/code/modules/clothing/rings/rings.dm index a6dc2b84426..5e468f80323 100644 --- a/code/modules/clothing/rings/rings.dm +++ b/code/modules/clothing/rings/rings.dm @@ -43,7 +43,7 @@ /obj/item/clothing/ring/reagent atom_flags = ATOM_FLAG_OPEN_CONTAINER - origin_tech = "{'materials':2,'esoteric':4}" + origin_tech = @'{"materials":2,"esoteric":4}' var/tmp/volume = 15 /obj/item/clothing/ring/reagent/Initialize(ml, material_key) @@ -73,11 +73,11 @@ /obj/item/clothing/ring/reagent/sleepy name = "silver ring" desc = "A ring made from what appears to be silver." - origin_tech = "{'materials':2,'esoteric':5}" + origin_tech = @'{"materials":2,"esoteric":5}' /obj/item/clothing/ring/reagent/sleepy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/paralytics, 10) - reagents.add_reagent(/decl/material/liquid/sedatives, 5) + add_to_reagents(/decl/material/liquid/paralytics, 10) + add_to_reagents(/decl/material/liquid/sedatives, 5) ///////////////////////////////////////// //Seals and Signet Rings diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 80722d9862b..76a86048ad4 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -13,7 +13,7 @@ force = 2 blood_overlay_type = "shoeblood" material = /decl/material/solid/organic/leather - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' var/can_fit_under_magboots = TRUE var/can_add_cuffs = TRUE @@ -174,7 +174,7 @@ S.blend_mode = BLEND_ADD add_overlay(S) -/obj/item/clothing/shoes/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/shoes/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && shine > 0 && slot == slot_shoes_str) var/mutable_appearance/S = mutable_appearance(overlay.icon, "shine") S.alpha = 127 * shine / 100 diff --git a/code/modules/clothing/shoes/jobs.dm b/code/modules/clothing/shoes/jobs.dm index a6c15773f9b..38f03b11e15 100644 --- a/code/modules/clothing/shoes/jobs.dm +++ b/code/modules/clothing/shoes/jobs.dm @@ -35,7 +35,7 @@ max_pressure_protection = FIRESUIT_MAX_PRESSURE var/artificail_shine = 20 matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/shoes/jackboots/set_material(var/new_material) ..() @@ -61,4 +61,4 @@ max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE max_pressure_protection = FIRESUIT_MAX_PRESSURE matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index fadfee90984..1196f793f93 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -11,7 +11,7 @@ center_of_mass = null randpixel = 0 matter = list(/decl/material/solid/metal/aluminium = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':2,'engineering':2,'magnets':3}" + origin_tech = @'{"materials":2,"engineering":2,"magnets":3}' var/magpulse = 0 var/obj/item/clothing/shoes/covering_shoes var/online_slowdown = 3 @@ -54,7 +54,7 @@ icon_state = new_state update_clothing_icon() -/obj/item/clothing/shoes/magboots/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/shoes/magboots/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) var/new_state = overlay.icon_state if(magpulse) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 03cf4f3dec2..74aa9e80546 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -6,7 +6,7 @@ markings_color = WOOD_COLOR_CHOCOLATE permeability_coefficient = 0.05 item_flags = ITEM_FLAG_NOSLIP - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' siemens_coefficient = 0.8 bodytype_equip_flags = null matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 0d28b4786f0..7f484566d8c 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -34,7 +34,7 @@ interface_desc = "Disorientates your target by blinding them with this intense palm-mounted light." device = /obj/item/flash - origin_tech = "{'combat':2,'magnets':3,'engineering':5}" + origin_tech = @'{"combat":2,"magnets":3,"engineering":5}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, @@ -44,7 +44,7 @@ /obj/item/rig_module/device/flash/advanced name = "advanced mounted flash" device = /obj/item/flash/advanced - origin_tech = "{'combat':3,'magnets':3,'engineering':5}" + origin_tech = @'{"combat":3,"magnets":3,"engineering":5}' /obj/item/rig_module/device/flash/installed() . = ..() @@ -262,7 +262,7 @@ interface_name = "mounted energy gun" interface_desc = "A shoulder-mounted suit-powered energy gun." - origin_tech = "{'powerstorage':6,'combat':6,'engineering':6}" + origin_tech = @'{"powerstorage":6,"combat":6,"engineering":6}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -284,7 +284,7 @@ interface_name = "mounted electrolaser" interface_desc = "A shoulder-mounted, cell-powered electrolaser." - origin_tech = "{'powerstorage':5,'combat':5,'engineering':6}" + origin_tech = @'{"powerstorage":5,"combat":5,"engineering":6}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, @@ -304,7 +304,7 @@ interface_name = "mounted plasma cutter" interface_desc = "A forearm-mounted suit-powered plasma cutter." - origin_tech = "{'materials':5,'exoticmatter':4,'engineering':7,'combat':5}" + origin_tech = @'{"materials":5,"exoticmatter":4,"engineering":7,"combat":5}' gun = /obj/item/gun/energy/plasmacutter/mounted material = /decl/material/solid/metal/steel diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 954e61f8ea4..d92a4c0e239 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -54,10 +54,10 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) - origin_tech = "{'programming':6,'materials':5,'engineering':6}" + origin_tech = @'{"programming":6,"materials":5,"engineering":6}' var/mob/integrated_ai // Direct reference to the actual mob held in the suit. - var/obj/item/ai_card // Reference to the MMI, posibrain, inteliCard or pAI card previously holding the AI. + var/obj/item/ai_card // Reference to the object previously holding the AI. var/obj/item/ai_verbs/verb_holder /mob @@ -136,7 +136,7 @@ return 1 // Okay, it wasn't a terminal being touched, check for all the simple insertions. - if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/organ/internal/posibrain)) + if(input_device.type in list(/obj/item/paicard, /obj/item/organ/internal/brain_interface)) if(integrated_ai) integrated_ai.attackby(input_device,user) // If the transfer was successful, we can clear out our vars. @@ -340,7 +340,7 @@ interface_name = "niling d-sink" interface_desc = "Colloquially known as a power siphon, this module drains power through the suit hands into the suit battery." - origin_tech = "{'powerstorage':6,'engineering':6}" + origin_tech = @'{"powerstorage":6,"engineering":6}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index e5bf2be851b..91ba1424b49 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -20,7 +20,7 @@ active_power_cost = 6 KILOWATTS // 30 min battery life /w best (3kWh) cell passive_power_cost = 0 module_cooldown = 10 SECONDS - origin_tech = "{'materials':5,'powerstorage':6,'magnets':6,'esoteric':6,'engineering':7}" + origin_tech = @'{"materials":5,"powerstorage":6,"magnets":6,"esoteric":6,"engineering":7}' activate_string = "Enable Cloak" deactivate_string = "Disable Cloak" @@ -153,7 +153,7 @@ fabrication_type = /obj/item/energy_net use_power_cost = 20 KILOWATTS - origin_tech = "{'materials':5,'powerstorage':6,'magnets':5,'esoteric':4,'engineering':6}" + origin_tech = @'{"materials":5,"powerstorage":6,"magnets":5,"esoteric":4,"engineering":6}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 76ed6600e50..d7310193d99 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -37,7 +37,7 @@ engage_string = "Display Readout" usable = 1 use_power_cost = 200 - origin_tech = "{'magnets':3,'biotech':3,'engineering':5}" + origin_tech = @'{"magnets":3,"biotech":3,"engineering":5}' device = /obj/item/scanner/health material = /decl/material/solid/organic/plastic matter = list( @@ -66,7 +66,7 @@ suit_overlay_inactive = null use_power_cost = 3600 //2 Wh per use module_cooldown = 0 - origin_tech = "{'materials':6,'powerstorage':4,'engineering':6}" + origin_tech = @'{"materials":6,"powerstorage":4,"engineering":6}' device = /obj/item/pickaxe/diamonddrill material = /decl/material/solid/metal/steel matter = list( @@ -86,7 +86,7 @@ usable = 1 selectable = 0 device = /obj/item/ano_scanner - origin_tech = "{'wormholes':4,'magnets':4,'engineering':6}" + origin_tech = @'{"wormholes":4,"magnets":4,"engineering":6}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, @@ -105,7 +105,7 @@ toggleable = 1 use_power_cost = 200 device = /obj/item/scanner/mining - origin_tech = "{'materials':4,'magnets':4,'engineering':6}" + origin_tech = @'{"materials":4,"magnets":4,"engineering":6}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, @@ -128,7 +128,7 @@ usable = 1 engage_string = "Configure RCD" use_power_cost = 300 - origin_tech = "{'materials':6,'magnets':5,'engineering':7}" + origin_tech = @'{"materials":6,"magnets":5,"engineering":7}' device = /obj/item/rcd/mounted material = /decl/material/solid/metal/steel matter = list( @@ -221,7 +221,7 @@ if((charge.charges + chems_to_transfer) > max_reagent_volume) chems_to_transfer = max_reagent_volume - charge.charges charge.charges += chems_to_transfer - input_item.reagents.remove_reagent(rtype, chems_to_transfer) + input_item.remove_from_reagents(rtype, chems_to_transfer) total_transferred += chems_to_transfer break @@ -266,7 +266,7 @@ if(target_mob != H) to_chat(H, "You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name].") to_chat(target_mob, "You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.") - target_mob.reagents.add_reagent(charge.product_type, chems_to_use) + target_mob.add_to_reagents(charge.product_type, chems_to_use) charge.charges -= chems_to_use if(charge.charges < 0) charge.charges = 0 @@ -383,7 +383,7 @@ interface_name = "maneuvering jets" interface_desc = "An inbuilt EVA maneuvering system that runs off a seperate gas supply." - origin_tech = "{'materials':6,'engineering':7}" + origin_tech = @'{"materials":6,"engineering":7}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, @@ -523,7 +523,7 @@ icon_state = "ewar" interface_name = "mounted matter decompiler" interface_desc = "Eats trash like no one's business." - origin_tech = "{'materials':5,'engineering':5}" + origin_tech = @'{"materials":5,"engineering":5}' device = /obj/item/matter_decompiler material = /decl/material/solid/metal/steel matter = list( @@ -534,7 +534,7 @@ /obj/item/rig_module/cooling_unit name = "mounted cooling unit" toggleable = 1 - origin_tech = "{'magnets':2,'materials':2,'engineering':5}" + origin_tech = @'{"magnets":2,"materials":2,"engineering":5}' interface_name = "mounted cooling unit" interface_desc = "A heat sink with a liquid cooled radiator." module_cooldown = 0 SECONDS //no cd because its critical for a life-support module diff --git a/code/modules/clothing/spacesuits/rig/modules/vision.dm b/code/modules/clothing/spacesuits/rig/modules/vision.dm index 6728356e8bf..3b19bf49653 100644 --- a/code/modules/clothing/spacesuits/rig/modules/vision.dm +++ b/code/modules/clothing/spacesuits/rig/modules/vision.dm @@ -91,7 +91,7 @@ name = "hardsuit meson scanner" desc = "A layered, translucent visor system for a hardsuit." icon_state = "meson" - origin_tech = "{'magnets':2,'engineering':5}" + origin_tech = @'{"magnets":2,"engineering":5}' usable = 0 interface_name = "meson scanner" @@ -117,7 +117,7 @@ name = "hardsuit night vision interface" desc = "A multi input night vision system for a hardsuit." icon_state = "night" - origin_tech = "{'magnets':6,'engineering':6}" + origin_tech = @'{"magnets":6,"engineering":6}' usable = 0 interface_name = "night vision interface" @@ -136,7 +136,7 @@ name = "hardsuit security hud" desc = "A simple tactical information system for a hardsuit." icon_state = "securityhud" - origin_tech = "{'magnets':3,'biotech':2,'engineering':5}" + origin_tech = @'{"magnets":3,"biotech":2,"engineering":5}' usable = 0 interface_name = "security HUD" @@ -149,7 +149,7 @@ name = "hardsuit medical hud" desc = "A simple medical status indicator for a hardsuit." icon_state = "healthhud" - origin_tech = "{'magnets':3,'biotech':2,'engineering':5}" + origin_tech = @'{"magnets":3,"biotech":2,"engineering":5}' usable = 0 interface_name = "medical HUD" diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index bd39264f249..ed1470a959c 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -200,7 +200,7 @@ LAZYSET(chest.slowdown_per_slot, slot_wear_suit_str, (active? online_slowdown : offline_slowdown)) if(helmet) helmet.tint = (active? vision_restriction : offline_vision_restriction) - helmet.update_vision() + helmet.update_wearer_vision() /obj/item/rig/proc/suit_is_deployed() if(!istype(wearer) || src.loc != wearer || wearer.get_equipped_item(slot_back_str) != src) @@ -579,7 +579,7 @@ for(var/slot in update_rig_slots) wearer.update_equipment_overlay(slot) -/obj/item/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && slot == slot_back_str && !offline && equipment_overlay_icon && LAZYLEN(installed_modules)) for(var/obj/item/rig_module/module in installed_modules) if(module.suit_overlay) diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index a219f13e06d..ff37a3ba3e5 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -29,7 +29,7 @@ if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon)) icon_state = "[icon_state]-sealed" -/obj/item/clothing/head/helmet/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/helmet/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && user_mob?.check_rig_status() && check_state_in_icon("[overlay.icon_state]-sealed", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-sealed" . = ..() @@ -49,7 +49,7 @@ if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon)) icon_state = "[icon_state]-sealed" -/obj/item/clothing/gloves/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/gloves/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && user_mob?.check_rig_status() && check_state_in_icon("[overlay.icon_state]-sealed", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-sealed" . = ..() @@ -69,7 +69,7 @@ if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon)) icon_state = "[icon_state]-sealed" -/obj/item/clothing/shoes/magboots/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/shoes/magboots/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && user_mob?.check_rig_status() && check_state_in_icon("[overlay.icon_state]-sealed", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-sealed" . = ..() @@ -95,7 +95,7 @@ if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon)) icon_state = "[icon_state]-sealed" -/obj/item/clothing/suit/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && user_mob?.check_rig_status() && check_state_in_icon("[overlay.icon_state]-sealed", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-sealed" . = ..() diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 8ffa864d42a..00afebd32d2 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -29,7 +29,7 @@ var/obj/machinery/camera/camera var/tinted = null //Set to non-null for toggleable tint helmets - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel /obj/item/clothing/head/helmet/space/Destroy() @@ -97,20 +97,20 @@ to_chat(usr, "You toggle [src]'s visor tint.") update_tint() -/obj/item/clothing/head/helmet/space/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/helmet/space/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && tint && check_state_in_icon("[overlay.icon_state]_dark", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_dark" . = ..() /obj/item/clothing/head/helmet/space/on_update_icon(mob/user) . = ..() - var/base_icon = get_world_inventory_state() - if(!base_icon) - base_icon = initial(icon_state) - if(tint && check_state_in_icon("[base_icon]_dark", icon)) - icon_state = "[base_icon]_dark" + var/base_icon_state = get_world_inventory_state() + if(!base_icon_state) + base_icon_state = initial(icon_state) + if(tint && check_state_in_icon("[base_icon_state]_dark", icon)) + icon_state = "[base_icon_state]_dark" else - icon_state = base_icon + icon_state = base_icon_state /obj/item/clothing/suit/space name = "space suit" @@ -135,7 +135,7 @@ center_of_mass = null randpixel = 0 valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA, ACCESSORY_SLOT_ARMBAND, ACCESSORY_SLOT_OVER) - origin_tech = "{'materials':3, 'engineering':3}" + origin_tech = @'{"materials":3, "engineering":3}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index bac9c28b8bc..9d00d6d26b4 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -285,7 +285,7 @@ else if(##equipment_var) {\ /obj/item/clothing/suit/space/void/attack_self() //sole purpose of existence is to toggle the helmet toggle_helmet() -/obj/item/clothing/suit/space/void/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/space/void/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && tank && slot == slot_back_str) overlay.overlays += tank.get_mob_overlay(user_mob, slot_back_str) . = ..() diff --git a/code/modules/clothing/suits/_suit.dm b/code/modules/clothing/suits/_suit.dm index 99ed1ab1a02..9015fc0274d 100644 --- a/code/modules/clothing/suits/_suit.dm +++ b/code/modules/clothing/suits/_suit.dm @@ -19,7 +19,7 @@ /obj/item/clothing/suit/preserve_in_cryopod(var/obj/machinery/cryopod/pod) return TRUE -/obj/item/clothing/suit/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && item_state) overlay.icon_state = item_state . = ..() diff --git a/code/modules/clothing/suits/armor/_armor.dm b/code/modules/clothing/suits/armor/_armor.dm index 1369417acf4..eb04ea7d330 100644 --- a/code/modules/clothing/suits/armor/_armor.dm +++ b/code/modules/clothing/suits/armor/_armor.dm @@ -9,4 +9,4 @@ max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE siemens_coefficient = 0.6 blood_overlay_type = "armor" - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' diff --git a/code/modules/clothing/suits/armor/bulletproof.dm b/code/modules/clothing/suits/armor/bulletproof.dm index 198bb143bfd..8c217d5b4f4 100644 --- a/code/modules/clothing/suits/armor/bulletproof.dm +++ b/code/modules/clothing/suits/armor/bulletproof.dm @@ -19,7 +19,7 @@ /decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':3,'engineering':1,'combat':3}" + origin_tech = @'{"materials":3,"engineering":1,"combat":3}' // no accessory /obj/item/clothing/suit/armor/bulletproof/prepared @@ -43,7 +43,7 @@ /decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':3,'engineering':1,'combat':3}" + origin_tech = @'{"materials":3,"engineering":1,"combat":3}' /obj/item/clothing/accessory/legguards/ballistic name = "ballistic leg guards" @@ -64,4 +64,4 @@ /decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':3,'engineering':1,'combat':3}" \ No newline at end of file + origin_tech = @'{"materials":3,"engineering":1,"combat":3}' \ No newline at end of file diff --git a/code/modules/clothing/suits/armor/merc.dm b/code/modules/clothing/suits/armor/merc.dm index 3ee072f2d06..c81931f77f1 100644 --- a/code/modules/clothing/suits/armor/merc.dm +++ b/code/modules/clothing/suits/armor/merc.dm @@ -15,7 +15,7 @@ ) material = /decl/material/solid/metal/titanium matter = list(/decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':5,'engineering':2,'combat':3}" + origin_tech = @'{"materials":5,"engineering":2,"combat":3}' /obj/item/clothing/accessory/armguards/merc name = "heavy arm guards" @@ -30,7 +30,7 @@ ) color = null material = /decl/material/solid/metal/steel - origin_tech = "{'materials':2,'engineering':1,'combat':2}" + origin_tech = @'{"materials":2,"engineering":1,"combat":2}' /obj/item/clothing/accessory/legguards/merc name = "heavy leg guards" @@ -45,4 +45,4 @@ ARMOR_BOMB = ARMOR_BOMB_PADDED ) material = /decl/material/solid/metal/steel - origin_tech = "{'materials':2,'engineering':1,'combat':2}" + origin_tech = @'{"materials":2,"engineering":1,"combat":2}' diff --git a/code/modules/clothing/suits/armor/reactive.dm b/code/modules/clothing/suits/armor/reactive.dm index 8c3a5cae75e..088e086f127 100644 --- a/code/modules/clothing/suits/armor/reactive.dm +++ b/code/modules/clothing/suits/armor/reactive.dm @@ -48,7 +48,7 @@ . = ..() icon_state = "[get_world_inventory_state()][active ? "_on" : ""]" -/obj/item/clothing/suit/armor/reactive/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/armor/reactive/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && active && check_state_in_icon("[overlay.icon_state]_on", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_on" . = ..() diff --git a/code/modules/clothing/suits/armor/riot.dm b/code/modules/clothing/suits/armor/riot.dm index 878ffe7d971..378f70efd61 100644 --- a/code/modules/clothing/suits/armor/riot.dm +++ b/code/modules/clothing/suits/armor/riot.dm @@ -18,7 +18,7 @@ matter = list( /decl/material/solid/organic/cloth = MATTER_AMOUNT_SECONDARY ) - origin_tech = "{'materials':1,'engineering':1,'combat':2}" + origin_tech = @'{"materials":1,"engineering":1,"combat":2}' /obj/item/clothing/suit/armor/riot/prepared starting_accessories = list(/obj/item/clothing/accessory/armguards/riot, /obj/item/clothing/accessory/legguards/riot) @@ -41,7 +41,7 @@ slowdown = 1 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/organic/cloth = MATTER_AMOUNT_SECONDARY) - origin_tech = "{'materials':1,'engineering':1,'combat':2}" + origin_tech = @'{"materials":1,"engineering":1,"combat":2}' /obj/item/clothing/accessory/armguards/riot name = "riot arm guards" @@ -58,5 +58,5 @@ siemens_coefficient = 0.5 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/organic/cloth = MATTER_AMOUNT_SECONDARY) - origin_tech = "{'materials':1,'engineering':1,'combat':2}" + origin_tech = @'{"materials":1,"engineering":1,"combat":2}' diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index dd98a64a70e..d51ec5781f7 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -12,7 +12,7 @@ item_flags = ITEM_FLAG_THICKMATERIAL body_parts_covered = SLOT_HEAD|SLOT_FACE|SLOT_EYES|SLOT_EARS siemens_coefficient = 0.9 - origin_tech = "{'materials':3, 'engineering':3}" + origin_tech = @'{"materials":3, "engineering":3}' matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT @@ -34,7 +34,7 @@ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL item_flags = ITEM_FLAG_THICKMATERIAL siemens_coefficient = 0.9 - origin_tech = "{'materials':3, 'engineering':3}" + origin_tech = @'{"materials":3, "engineering":3}' matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT @@ -89,7 +89,7 @@ desc = "It protected doctors from the Black Death, back then. You bet your arse it's gonna help you against space plague." icon = 'icons/clothing/suit/biosuit/plague.dmi' flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL - origin_tech = "{'materials':1,'engineering':1,'biotech':1}" + origin_tech = @'{"materials":1,"engineering":1,"biotech":1}' matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 394b41d4ddd..6d8dbb01420 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -69,7 +69,7 @@ valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA) blood_overlay_type = "coat" body_parts_covered = SLOT_UPPER_BODY|SLOT_ARMS - allowed = list(/obj/item/tank/emergency,/obj/item/flashlight,/obj/item/gun/energy,/obj/item/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/baton,/obj/item/handcuffs,/obj/item/storage/fancy/cigarettes,/obj/item/flame/lighter,/obj/item/taperecorder) + allowed = list(/obj/item/tank/emergency,/obj/item/flashlight,/obj/item/gun/energy,/obj/item/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/baton,/obj/item/handcuffs,/obj/item/storage/box/fancy/cigarettes,/obj/item/flame/lighter,/obj/item/taperecorder) protects_against_weather = TRUE /obj/item/clothing/suit/storage/det_trench/grey @@ -85,7 +85,7 @@ ARMOR_LASER = ARMOR_LASER_SMALL, ARMOR_ENERGY = ARMOR_ENERGY_MINOR ) - origin_tech = "{'materials':2, 'engineering':2}" + origin_tech = @'{"materials":2, "engineering":2}' matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) //Forensics @@ -101,7 +101,7 @@ ARMOR_LASER = ARMOR_LASER_MINOR, ARMOR_ENERGY = ARMOR_ENERGY_MINOR ) - origin_tech = "{'materials':2, 'engineering':2}" + origin_tech = @'{"materials":2, "engineering":2}' matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) /obj/item/clothing/suit/storage/forensics/red diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index 7ed9c634d74..a5527976a9d 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -26,7 +26,7 @@ restricted_accessory_slots = list(ACCESSORY_SLOT_ARMBAND) markings_icon = "_marking" matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE) - origin_tech = "{'materials':1,'engineering':1,'biotech':1}" + origin_tech = @'{"materials":1,"engineering":1,"biotech":1}' /obj/item/clothing/suit/storage/toggle/labcoat/cmo name = "chief medical officer's labcoat" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index aab123c760a..69ac955d2ce 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -47,7 +47,7 @@ desc = "This robe commands authority." icon = 'icons/clothing/suit/judge.dmi' body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_ARMS - allowed = list(/obj/item/storage/fancy/cigarettes,/obj/item/cash) + allowed = list(/obj/item/storage/box/fancy/cigarettes,/obj/item/cash) flags_inv = HIDEJUMPSUIT /obj/item/clothing/suit/apron/overalls @@ -158,7 +158,7 @@ shine = material.reflectiveness desc = "A long, thick [material.use_name] coat." -/obj/item/clothing/suit/leathercoat/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/leathercoat/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && shine > 0 && slot == slot_wear_suit_str) var/mutable_appearance/S = mutable_appearance(overlay.icon, "shine") S.alpha = max(shine, artificial_shine)/100 * 255 @@ -227,6 +227,21 @@ desc = "A warm, black sweatshirt." color = COLOR_DARK_GRAY +/obj/item/clothing/suit/storage/toggle/hoodie/red + name = "red hoodie" + desc = "A warm, red sweatshirt." + color = COLOR_RED + +/obj/item/clothing/suit/storage/toggle/hoodie/blue + name = "blue hoodie" + desc = "A warm, blue sweatshirt." + color = COLOR_BLUE + +/obj/item/clothing/suit/storage/toggle/hoodie/yellow + name = "yellow hoodie" + desc = "A warm, yellow sweatshirt." + color = COLOR_GOLD + /* * Track Jackets */ diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 2edcb16bafd..8826e560814 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -59,7 +59,7 @@ else icon_state = get_world_inventory_state() -/obj/item/clothing/suit/storage/toggle/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/storage/toggle/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(buttons && overlay && check_state_in_icon("[overlay.icon_state]_open", overlay.icon)) overlay.icon_state = "[overlay.icon_state]_open" . = ..() @@ -130,7 +130,7 @@ ARMOR_BIO = ARMOR_BIO_MINOR ) hood = /obj/item/clothing/head/winterhood - allowed = list (/obj/item/pen, /obj/item/paper, /obj/item/flashlight,/obj/item/storage/fancy/cigarettes, /obj/item/storage/box/matches, /obj/item/chems/drinks/flask) + allowed = list (/obj/item/pen, /obj/item/paper, /obj/item/flashlight,/obj/item/storage/box/fancy/cigarettes, /obj/item/storage/box/matches, /obj/item/chems/drinks/flask) siemens_coefficient = 0.6 protects_against_weather = TRUE diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 5bed5fbad53..c30941bf3b1 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -31,7 +31,7 @@ matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/suit/fire/Initialize() . = ..() @@ -105,7 +105,7 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/suit/radiation name = "radiation suit" @@ -125,7 +125,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/suit/radiation/Initialize() . = ..() @@ -137,7 +137,7 @@ /obj/item/clothing/head/chem_hood name = "chemical hood" - desc = "A hood that protects the head from chemical comtaminants." + desc = "A hood that protects the head from chemical contaminants." icon = 'icons/clothing/head/chem_hood.dmi' permeability_coefficient = 0 armor = list( @@ -146,13 +146,13 @@ ) flags_inv = HIDEEARS|BLOCK_HEAD_HAIR item_flags = ITEM_FLAG_THICKMATERIAL - body_parts_covered = SLOT_HEAD|SLOT_EARS + body_parts_covered = SLOT_HEAD|SLOT_EARS|SLOT_FACE siemens_coefficient = 0.9 matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/clothing/suit/chem_suit name = "chemical suit" @@ -174,4 +174,4 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 04a12bba6ff..f175cb45a8f 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -41,7 +41,7 @@ if(check_state_in_icon("[BODYTYPE_HUMANOID]-[slot_w_uniform_str]-sleeves", icon)) verbs |= /obj/item/clothing/under/proc/roll_up_sleeves -/obj/item/clothing/under/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/under/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && slot == slot_w_uniform_str) if(rolled_down && check_state_in_icon("[overlay.icon_state]-rolled", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-rolled" diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 5d3becfdf66..fe80ee4babf 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -61,7 +61,7 @@ if(uniform.rolled_sleeves && hide_on_uniform_rollsleeves) return FALSE -/obj/item/clothing/accessory/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && istype(loc, /obj/item/clothing/under)) var/new_state = overlay.icon_state var/obj/item/clothing/under/uniform = loc diff --git a/code/modules/clothing/under/accessories/accessory_toggleable.dm b/code/modules/clothing/under/accessories/accessory_toggleable.dm index 56d6a31f1ac..8821c3b4dbc 100644 --- a/code/modules/clothing/under/accessories/accessory_toggleable.dm +++ b/code/modules/clothing/under/accessories/accessory_toggleable.dm @@ -5,7 +5,7 @@ icon_state = ICON_STATE_WORLD var/open = FALSE -/obj/item/clothing/accessory/toggleable/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/toggleable/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && open && check_state_in_icon("[overlay.icon_state]-open", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-open" . = ..() @@ -155,7 +155,7 @@ icon_state = "[icon_state]-tucked" update_clothing_icon() -/obj/item/clothing/accessory/toggleable/flannel/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/toggleable/flannel/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) if(rolled && check_state_in_icon("[overlay.icon_state]-rolled", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-rolled" diff --git a/code/modules/clothing/under/accessories/armor.dm b/code/modules/clothing/under/accessories/armor.dm index 7adb7b15558..5960722be72 100644 --- a/code/modules/clothing/under/accessories/armor.dm +++ b/code/modules/clothing/under/accessories/armor.dm @@ -37,7 +37,7 @@ matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY ) - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' /obj/item/clothing/accessory/armor/plate/get_fibers() return null //plates do not shed @@ -56,7 +56,7 @@ matter = list( /decl/material/solid/metal/plasteel = MATTER_AMOUNT_SECONDARY ) - origin_tech = "{'materials':2,'engineering':1,'combat':2}" + origin_tech = @'{"materials":2,"engineering":1,"combat":2}' /obj/item/clothing/accessory/armor/plate/tactical name = "tactical armor plate" @@ -75,7 +75,7 @@ /decl/material/solid/metal/titanium = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'materials':3,'engineering':2,'combat':2}" + origin_tech = @'{"materials":3,"engineering":2,"combat":2}' //Arm guards /obj/item/clothing/accessory/armguards @@ -98,7 +98,7 @@ matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY ) - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' /obj/item/clothing/accessory/armguards/craftable material_armor_multiplier = 1 @@ -126,7 +126,7 @@ matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_SECONDARY ) - origin_tech = "{'materials':1,'engineering':1,'combat':1}" + origin_tech = @'{"materials":1,"engineering":1,"combat":1}' /obj/item/clothing/accessory/legguards/craftable material_armor_multiplier = 1 diff --git a/code/modules/clothing/under/accessories/cloaks.dm b/code/modules/clothing/under/accessories/cloaks.dm index 390f2eba438..0367ab060c0 100644 --- a/code/modules/clothing/under/accessories/cloaks.dm +++ b/code/modules/clothing/under/accessories/cloaks.dm @@ -25,7 +25,7 @@ // Cloaks should layer over and under everything, so set the layer directly rather // than relying on overlay order. This also overlays over inhands but it looks ok. -/obj/item/clothing/accessory/cloak/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/cloak/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(slot == slot_wear_suit_str || slot == slot_tie_str || slot == slot_w_uniform_str) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index c39a4c0e693..fa9e19c700d 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -16,7 +16,7 @@ ARMOR_ENERGY = ARMOR_ENERGY_MINOR ) body_parts_covered = SLOT_UPPER_BODY - origin_tech = "{'combat':2,'materials':3,'esoteric':2}" + origin_tech = @'{"combat":2,"materials":3,"esoteric":2}' /obj/item/clothing/accessory/suspenders name = "suspenders" @@ -95,7 +95,7 @@ if(sleeves_rolled && check_state_in_icon("[icon_state]-sleeves", icon)) icon_state = "[icon_state]-sleeves" -/obj/item/clothing/accessory/tangzhuang/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/tangzhuang/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && sleeves_rolled && check_state_in_icon("[overlay.icon_state]-sleeves", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-sleeves" . = ..() diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm index 670ecca3518..f026be7e1ae 100644 --- a/code/modules/clothing/under/accessories/storage.dm +++ b/code/modules/clothing/under/accessories/storage.dm @@ -123,7 +123,7 @@ if(contents_count > 0 && check_state_in_icon("[icon_state]-[contents_count]", icon)) icon_state = "[icon_state]-[contents_count]" -/obj/item/clothing/accessory/storage/knifeharness/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/storage/knifeharness/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) var/contents_count = min(length(contents), 2) if(contents_count > 0 && check_state_in_icon("[overlay.icon_state]-[contents_count]", overlay.icon)) diff --git a/code/modules/clothing/under/accessories/ties.dm b/code/modules/clothing/under/accessories/ties.dm index fbff4b81f28..761f629266b 100644 --- a/code/modules/clothing/under/accessories/ties.dm +++ b/code/modules/clothing/under/accessories/ties.dm @@ -75,7 +75,7 @@ tied = !tied update_icon() -/obj/item/clothing/accessory/bowtie/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/accessory/bowtie/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && !tied && check_state_in_icon("[overlay.icon_state]-untied", overlay.icon)) overlay.icon_state = "[overlay.icon_state]-untied" . = ..() diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 7b04b2ea763..b9476b9f16d 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -141,7 +141,7 @@ siemens_coefficient = 0.8 material = /decl/material/solid/organic/leather matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE) - origin_tech = "{'materials':1,'engineering':1, 'combat':1}" + origin_tech = @'{"materials":1,"engineering":1, "combat":1}' /obj/item/clothing/head/HoS name = "Head of Security hat" @@ -170,7 +170,7 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':3,'engineering':1, 'combat':2}" + origin_tech = @'{"materials":3,"engineering":1, "combat":2}' //Jensen cosplay gear /obj/item/clothing/under/head_of_security/jensen @@ -179,7 +179,7 @@ icon = 'icons/clothing/under/jumpsuits/jumpsuit_hos_alt.dmi' siemens_coefficient = 0.6 matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE) - origin_tech = "{'materials':3,'engineering':1, 'combat':2}" + origin_tech = @'{"materials":3,"engineering":1, "combat":2}' /obj/item/clothing/suit/armor/hos/jensen name = "armored trenchcoat" @@ -192,4 +192,4 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT ) - origin_tech = "{'materials':3,'engineering':1, 'combat':2}" + origin_tech = @'{"materials":3,"engineering":1, "combat":2}' diff --git a/code/modules/codex/categories/_materials.dm b/code/modules/codex/categories/_materials.dm new file mode 100644 index 00000000000..6509270555d --- /dev/null +++ b/code/modules/codex/categories/_materials.dm @@ -0,0 +1,98 @@ +/decl/codex_category/materials + abstract_type = /decl/codex_category/materials + var/reaction_category + +/decl/codex_category/materials/Populate() + + guide_html = guide_html + {" +

    Reactions

    +
    [cat.name]" - dat += "
    [cat.name]
    [S.name] ([pref.get_spent_points(job, S)])[S.name] ([pref.get_spent_points(job, S)])
    [button_label][button_label][add_link(skill, job, button_label, "'Current'", effective_level)][add_link(skill, job, button_label, "'Current'", effective_level)][button_label][button_label][add_link(skill, job, button_label, "'Selectable'", effective_level)][add_link(skill, job, button_label, "'Selectable'", effective_level)][button_label][button_label]
    + + "} + + var/list/entries_to_register = list() + var/list/all_reactions = decls_repository.get_decls_of_subtype(/decl/chemical_reaction) + for(var/reactiontype in all_reactions) + var/decl/chemical_reaction/reaction = all_reactions[reactiontype] + if(!reaction || !reaction.name || reaction.hidden_from_codex || istype(reaction, /decl/chemical_reaction/recipe) || reaction.reaction_category != reaction_category) + continue // Food recipes are handled in category_recipes.dm. + var/mechanics_text = "This reaction requires the following reagents:
    " + if(reaction.mechanics_text) + mechanics_text = "[reaction.mechanics_text]
    [mechanics_text]" + var/list/reactant_values = list() + for(var/reactant_id in reaction.required_reagents) + var/decl/material/reactant = GET_DECL(reactant_id) + var/reactant_name = "[reactant.name]" + reactant_values += "[reaction.required_reagents[reactant_id]]u [reactant_name]" + mechanics_text += " [jointext(reactant_values, " + ")]" + var/list/inhibitors = list() + + for(var/inhibitor_id in reaction.inhibitors) + var/decl/material/inhibitor = GET_DECL(inhibitor_id) + var/inhibitor_name = "[inhibitor.name]" + inhibitors += inhibitor_name + if(length(inhibitors)) + mechanics_text += " (inhibitors: [jointext(inhibitors, ", ")])" + + var/list/catalysts = list() + for(var/catalyst_id in reaction.catalysts) + var/decl/material/catalyst = GET_DECL(catalyst_id) + var/catalyst_name = "[catalyst.name]" + catalysts += "[reaction.catalysts[catalyst_id]]u [catalyst_name]" + if(length(catalysts)) + mechanics_text += " (catalysts: [jointext(catalysts, ", ")])" + + var/produces + if(reaction.result && reaction.result_amount) + var/decl/material/product = GET_DECL(reaction.result) + produces = product.codex_name || product.name + mechanics_text += "
    It will produce [reaction.result_amount]u [product.name]." + if(reaction.maximum_temperature != INFINITY) + mechanics_text += "
    The reaction will not occur if the temperature is above [reaction.maximum_temperature]K." + if(reaction.minimum_temperature > 0) + mechanics_text += "
    The reaction will not occur if the temperature is below [reaction.minimum_temperature]K." + + var/reaction_name = produces || lowertext(reaction.name) + if(produces) + guide_html += "
    " + else + guide_html += "" + guide_html += "" + guide_html += "" + if(length(catalysts)) + guide_html += "" + else + guide_html += "" + if(length(inhibitors)) + guide_html += "" + else + guide_html += "" + if(reaction.minimum_temperature > 0 && reaction.minimum_temperature < INFINITY) + guide_html += "" + else + guide_html += "" + if(reaction.maximum_temperature > 0 && reaction.maximum_temperature < INFINITY) + guide_html += "" + else + guide_html += "" + guide_html += "" + + entries_to_register += new /datum/codex_entry( \ + _display_name = "[reaction.name] (reaction)", \ + _associated_strings = list("[reaction.name] (chemical reaction)"), \ + _lore_text = reaction.lore_text, \ + _mechanics_text = mechanics_text \ + ) + guide_html += "
    Product nameProduct amountRequired reagentsCatalystsInhibitorsMin temperatureMax temperatureNotes
    [capitalize(reaction_name)]
    [capitalize(reaction_name)][reaction.result_amount || "N/A"][jointext(reactant_values, "
    ")]
    [jointext(catalysts, "
    ")]
    No catalysts.[jointext(inhibitors, "
    ")]
    No inhibitors.[reaction.minimum_temperature]KAny[reaction.maximum_temperature]KAny" + if(reaction.mechanics_text) + guide_html += reaction.mechanics_text + if(reaction.lore_text) + guide_html += "
    " + if(reaction.lore_text) + guide_html += reaction.lore_text + guide_html += "
    " + + for(var/datum/codex_entry/entry in entries_to_register) + items |= entry.name + + ..() diff --git a/code/modules/codex/categories/category_reactions.dm b/code/modules/codex/categories/category_reactions.dm index f64d5e317b3..c46829e0dfa 100644 --- a/code/modules/codex/categories/category_reactions.dm +++ b/code/modules/codex/categories/category_reactions.dm @@ -1,10 +1,8 @@ -/decl/codex_category/chemistry - name = "Chemical Reactions" - desc = "Chemical reactions with mundane, interesting or spectacular effects." - guide_name = "Chemistry" - -/decl/codex_category/chemistry/Populate() - +/decl/codex_category/materials/chemistry + name = "Pharmacology" + desc = "Chemical reactions with medical or metabolic effects on living things." + guide_name = "Pharmacology" + reaction_category = REACTION_TYPE_PHARMACEUTICAL guide_html = {"

    Chemistry Basics

    @@ -17,93 +15,26 @@

  • Chem grenades make use of a variety of reactions that produce effects like smoke or foam rather than a new chemical.

-

Reactions

- - "} - - var/list/entries_to_register = list() - var/list/all_reactions = decls_repository.get_decls_of_subtype(/decl/chemical_reaction) - for(var/reactiontype in all_reactions) - var/decl/chemical_reaction/reaction = all_reactions[reactiontype] - if(!reaction || !reaction.name || reaction.hidden_from_codex || istype(reaction, /decl/chemical_reaction/recipe)) - continue // Food recipes are handled in category_recipes.dm. - var/mechanics_text = "This reaction requires the following reagents:
" - if(reaction.mechanics_text) - mechanics_text = "[reaction.mechanics_text]
[mechanics_text]" - var/list/reactant_values = list() - for(var/reactant_id in reaction.required_reagents) - var/decl/material/reactant = GET_DECL(reactant_id) - var/reactant_name = "[reactant.name]" - reactant_values += "[reaction.required_reagents[reactant_id]]u [reactant_name]" - mechanics_text += " [jointext(reactant_values, " + ")]" - var/list/inhibitors = list() - - for(var/inhibitor_id in reaction.inhibitors) - var/decl/material/inhibitor = GET_DECL(inhibitor_id) - var/inhibitor_name = "[inhibitor.name]" - inhibitors += inhibitor_name - if(length(inhibitors)) - mechanics_text += " (inhibitors: [jointext(inhibitors, ", ")])" - - var/list/catalysts = list() - for(var/catalyst_id in reaction.catalysts) - var/decl/material/catalyst = GET_DECL(catalyst_id) - var/catalyst_name = "[catalyst.name]" - catalysts += "[reaction.catalysts[catalyst_id]]u [catalyst_name]" - if(length(catalysts)) - mechanics_text += " (catalysts: [jointext(catalysts, ", ")])" - - var/produces - if(reaction.result && reaction.result_amount) - var/decl/material/product = GET_DECL(reaction.result) - produces = product.codex_name || product.name - mechanics_text += "
It will produce [reaction.result_amount]u [product.name]." - if(reaction.maximum_temperature != INFINITY) - mechanics_text += "
The reaction will not occur if the temperature is above [reaction.maximum_temperature]K." - if(reaction.minimum_temperature > 0) - mechanics_text += "
The reaction will not occur if the temperature is below [reaction.minimum_temperature]K." - - var/reaction_name = produces || lowertext(reaction.name) - if(produces) - guide_html += "" - else - guide_html += "" - guide_html += "" - guide_html += "" - if(length(catalysts)) - guide_html += "" - else - guide_html += "" - if(length(inhibitors)) - guide_html += "" - else - guide_html += "" - if(reaction.minimum_temperature > 0 && reaction.minimum_temperature < INFINITY) - guide_html += "" - else - guide_html += "" - if(reaction.maximum_temperature > 0 && reaction.maximum_temperature < INFINITY) - guide_html += "" - else - guide_html += "" - guide_html += "" - - entries_to_register += new /datum/codex_entry( \ - _display_name = "[reaction.name] (reaction)", \ - _associated_strings = list("[reaction.name] (chemical reaction)"), \ - _lore_text = reaction.lore_text, \ - _mechanics_text = mechanics_text \ - ) - guide_html += "
Product nameProduct amountRequired reagentsCatalystsInhibitorsMin temperatureMax temperatureNotes
[capitalize(reaction_name)]
[capitalize(reaction_name)][reaction.result_amount || "N/A"][jointext(reactant_values, "
")]
[jointext(catalysts, "
")]
No catalysts.[jointext(inhibitors, "
")]
No inhibitors.[reaction.minimum_temperature]KAny[reaction.maximum_temperature]KAny" - if(reaction.mechanics_text) - guide_html += reaction.mechanics_text - if(reaction.lore_text) - guide_html += "
" - if(reaction.lore_text) - guide_html += reaction.lore_text - guide_html += "
" - - for(var/datum/codex_entry/entry in entries_to_register) - items |= entry.name - - . = ..() + "} + +/decl/codex_category/materials/chemistry/compounds + name = "Compounds" + desc = "Chemical reactions with non-medical, mundane, interesting or spectacular effects." + guide_name = "Compounds" + reaction_category = REACTION_TYPE_COMPOUND + +/decl/codex_category/materials/chemistry/synthesis + name = "Material Synthesis" + desc = "Chemical reactions that produce solid materials." + guide_name = "Material Synthesis" + reaction_category = REACTION_TYPE_SYNTHESIS + +/decl/codex_category/materials/alloying + name = "Alloys" + desc = "Combinations of metals that form various products." + guide_name = "Metallurgy" + reaction_category = REACTION_TYPE_ALLOYING + guide_html = {" +

Metallurgy Basics

+

Put metal in the smelter!

+ "} diff --git a/code/modules/codex/categories/category_substances.dm b/code/modules/codex/categories/category_substances.dm index a30a0d1fc04..922239595d1 100644 --- a/code/modules/codex/categories/category_substances.dm +++ b/code/modules/codex/categories/category_substances.dm @@ -55,7 +55,7 @@ material_info += "
  • It is a moderately strong solvent, capable of removing ink.
  • " else if(mat.solvent_power <= MAT_SOLVENT_STRONG) material_info += "
  • It is a strong solvent and will burn exposed skin on contact.
  • " - if(LAZYLEN(mat.dissolves_into)) + if(mat.dissolves_in != MAT_SOLVENT_IMMUNE && LAZYLEN(mat.dissolves_into)) var/chems = list() for(var/chemical in mat.dissolves_into) var/decl/material/R = chemical diff --git a/code/modules/codex/codex_cataloguer.dm b/code/modules/codex/codex_cataloguer.dm index a953a8f87b0..0cf00324007 100644 --- a/code/modules/codex/codex_cataloguer.dm +++ b/code/modules/codex/codex_cataloguer.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/items/device/cataloguer.dmi' icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL - origin_tech = "{'materials':2, 'programming':3,'magnets':3}" + origin_tech = @'{"materials":2, "programming":3,"magnets":3}' force = 0 item_flags = ITEM_FLAG_NO_BLUDGEON slot_flags = SLOT_LOWER_BODY @@ -114,7 +114,7 @@ /obj/item/cataloguer/examine(mob/user, distance, infix, suffix) . = ..() if(loaded_disk) - to_chat(user, "It has \a [loaded_disk] slotted into the storage port. The display indicates it currently holds [loaded_disk.data] Good Explorer Point\s.") + to_chat(user, "It has \a [loaded_disk] slotted into the storage port. The display indicates it currently holds [loaded_disk.data] good explorer point\s.") /obj/item/cataloguer/proc/stop_scan(var/interrupted = TRUE, var/mob/user, var/fade_out = 0) @@ -195,7 +195,7 @@ // Draw glow filter over target. if(ismovable(target)) var/atom/movable/thing = target - thing.add_filter("cataloguer_glow", 1, list("drop_shadow", color = glow_colour, size = 4, offset = 1, x = 0, y = 0)) + thing.add_filter("cataloguer_glow", 1, list(type = "drop_shadow", color = glow_colour, size = 4, offset = 1, x = 0, y = 0)) scan_beam = user.Beam(target, "scanner", time = scan_delay, maxdistance = scan_range+1, beam_color = glow_colour) @@ -209,4 +209,4 @@ var/datum/codex_entry/scannable/scan_result = scannable.scanned() if(scan_result) loaded_disk.data += scan_result.worth_points - to_chat(user, SPAN_NOTICE("You complete the scan of \the [target], earning [scan_result.worth_points] Good Explorer Point\s.")) + to_chat(user, SPAN_NOTICE("You complete the scan of \the [target], earning [scan_result.worth_points] good explorer point\s.")) diff --git a/code/modules/codex/codex_client.dm b/code/modules/codex/codex_client.dm index c40a52431ee..180e7624c44 100644 --- a/code/modules/codex/codex_client.dm +++ b/code/modules/codex/codex_client.dm @@ -25,7 +25,7 @@ return codex_on_cooldown = TRUE - addtimer(CALLBACK(src, .proc/reset_codex_cooldown), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_codex_cooldown)), 1 SECOND) var/list/all_entries = SScodex.retrieve_entries_for_string(searching) if(mob && mob.mind && !player_is_antag(mob.mind)) @@ -71,7 +71,7 @@ to_chat(src, SPAN_WARNING("You cannot perform codex actions currently.")) return codex_on_cooldown = TRUE - addtimer(CALLBACK(src, .proc/reset_codex_cooldown), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_codex_cooldown)), 1 SECOND) to_chat(mob, SPAN_NOTICE("The codex forwards you an index file.")) @@ -114,7 +114,7 @@ return codex_on_cooldown = TRUE - addtimer(CALLBACK(src, .proc/reset_codex_cooldown), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(reset_codex_cooldown)), 1 SECOND) var/datum/codex_entry/entry = SScodex.get_codex_entry("nexus") SScodex.present_codex_entry(mob, entry) diff --git a/code/modules/codex/entries/_codex_entry.dm b/code/modules/codex/entries/_codex_entry.dm index ce72d55aa9a..c81ee255fc2 100644 --- a/code/modules/codex/entries/_codex_entry.dm +++ b/code/modules/codex/entries/_codex_entry.dm @@ -3,18 +3,28 @@ /datum/codex_entry var/name + /// Whether or not this entry is stored on the subsystem, or is associated with solely the specific atom. var/store_codex_entry = TRUE + /// A list of string search terms associated with this entry. var/list/associated_strings + /// A list of typepaths used to populate associated_strings. var/list/associated_paths + /// IC text. var/lore_text + /// OOC text. var/mechanics_text + /// Text shown to antagonists. var/antag_text + /// Value used to disambiguate overlapping codex names. var/disambiguator + /// A list of category decls that this codex entry belongs to. var/list/categories /// If TRUE, don't create this entry in codex init. Where possible, consider using abstract_type or store_codex_entry = FALSE instead. var/skip_hardcoded_generation = FALSE /// If TRUE, associated_paths is set to include each path's subtypes in New(). var/include_subtypes = FALSE + /// HTML returned when the entry is used to populate a guide manual. + var/guide_html /datum/codex_entry/temporary store_codex_entry = FALSE @@ -136,4 +146,5 @@ . += "" . += footer . += "" + #undef TRIM_LINEBREAKS diff --git a/code/modules/codex/entries/engineering.dm b/code/modules/codex/entries/engineering.dm index 66c24731bd2..98a90924909 100644 --- a/code/modules/codex/entries/engineering.dm +++ b/code/modules/codex/entries/engineering.dm @@ -46,26 +46,6 @@ mechanics_text = "This device disrupts shields on directly adjacent tiles (in a + shaped pattern), in a similar way the floor mounted variant does. It is, however, portable and run by an internal battery. Can be recharged with a regular recharger." disambiguator = "equipment" -/datum/codex_entry/hacking - associated_strings = list("hacking") - mechanics_text = "Airlocks, vending machines, and various other machinery can be hacked by opening them up and fiddling with the wires. \ - While it might sound like a unlawful deed (and it usually is) this process is also performed by engineers, usually to fix said criminal deeds. \ - Hacking also benefits from the Electrical Engineering skill: a low skill may cause wires to tangle, and a high enough skill will let you examine wires to see what they do. \ -
    Hacking makes use of several items: \ -
    • a screwdriver, for opening maintenance panels.
    • \ -
    • a multitool, for pulsing wires (optional for many tasks, but very useful)
    • \ -
    • wirecutters, for cutting wires
    • \ -
    • insulated gloves, to prevent electrocution (optional but highly recommended)
    • \ -
    • a crowbar, if you're hacking a door to open it.
    \ -
    The first step to most hacking procedures is to use the screwdriver to open a maintenance panel and access the wiring. \ - After, you can click on the machine to view the wires. \ - You then use the multitool to pulse the wires, and in response some of the displayed information may change, causing certain effects to occur or allowing for certain benefits. \ - If you don't have a multitool, you can cut the wires. \ - Pulsing tends to cause temporary changes or toggles something, whereas cutting a wire is usually longer lasting, but this is not always the case. \ - Note that the corresponding wires and effects are randomized between rounds of the game. \ - You can also attach a signaler to pulse wires remotely." - antag_text = "To avoid suspicion or accidents, practice quietly somewhere out of the way and learn the wires you need before doing it for real." - /datum/codex_entry/solars associated_paths = list(/obj/item/solar_assembly, /obj/machinery/power/solar, /obj/machinery/power/tracker, /obj/machinery/power/solar_control) associated_strings = list("solar array") diff --git a/code/modules/codex/entries/guides.dm b/code/modules/codex/entries/guides.dm new file mode 100644 index 00000000000..5a6e7c15f4c --- /dev/null +++ b/code/modules/codex/entries/guides.dm @@ -0,0 +1,618 @@ +/datum/codex_entry/guide + abstract_type = /datum/codex_entry/guide + lore_text = "This guide has not been written yet, sorry!" + +/datum/codex_entry/guide/New() + ..() + if(QDELETED(src)) + return + + // Add to category. + var/decl/codex_category/cat = GET_DECL(/decl/codex_category/guides) + LAZYDISTINCTADD(categories, cat) + LAZYDISTINCTADD(cat.items, name) + + // Generate our guide text. + guide_html = guide_html ? list(guide_html) : list() + if(lore_text) + guide_html += "

    [lore_text]

    " + if(mechanics_text) + guide_html += "

    [mechanics_text]

    " + // No antag text for the guide text. + guide_html = JOINTEXT(guide_html) + +/datum/codex_entry/guide/robotics + name = "Guide to Robotics" + lore_text = {" +

    Cyborgs for Dummies

    + +

    Chapters

    +
      +
    1. Cyborg Related Equipment
    2. +
    3. Cyborg Modules
    4. +
    5. Cyborg Construction
    6. +
    7. Cyborg Maintenance
    8. +
    9. Cyborg Repairs
    10. +
    11. In Case of Emergency
    12. +
    + +

    Cyborg Related Equipment

    + +

    Exosuit Fabricator

    + The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs cannot be built. It seems that they may also benefit from advanced research techniques. + +

    Cyborg Recharging Station

    + This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge. + +

    Robotics Control Console

    + This useful piece of equipment can be used to immobilize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or the Company may see to it that it never happens again. + +

    Cyborg Modules

    + When a cyborg is created it picks out of an array of modules to designate its purpose. There are 11 different cyborg modules.
    + All cyborg modules carry a flash. + + # TODO generate from SSrobots + +

    Cyborg Construction

    + Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies.
    The required materials to make a cyborg are: +
      +
    • Metal
    • +
    • Two Flashes
    • +
    • One Power Cell (Preferably rated to 15000w)
    • +
    • Some electrical wires
    • +
    • One Human Brain
    • +
    • One Man-Machine Interface
    • +
    + Once you have acquired the materials, you can start on construction of your cyborg.
    To construct a cyborg, follow the steps below: +
      +
    1. Start the Exosuit Fabricators constructing all of the cyborg parts
    2. +
    3. While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
    4. +
    5. Once you have a Robot Head, place your two flashes inside the eye sockets
    6. +
    7. Once you have your Robot Chest, wire the Robot chest, then insert the power cell
    8. +
    9. Attach all of the Robot parts to the Robot frame
    10. +
    11. Insert the Man-Machine Interface (With the Brain inside) into the Robot Body
    12. +
    13. Congratulations! You have a new cyborg!
    14. +
    + +

    Cyborg Maintenance

    + Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring. + +

    Replacing a Power Cell

    + Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell.
    The steps to replace a cell are as follows: +
      +
    1. Unlock the Cyborg's Interface by swiping your ID on it
    2. +
    3. Open the Cyborg's outer panel using a crowbar
    4. +
    5. Remove the old power cell
    6. +
    7. Insert the new power cell
    8. +
    9. Close the Cyborg's outer panel using a crowbar
    10. +
    11. Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
    12. +
    + +

    Exposing the Internal Wiring

    + Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs.
    You can easily expose the internal wiring by following the steps below: +
      +
    1. Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
    2. +
    3. Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
    4. +
    + To re-seal the cyborg's internal wiring: +
      +
    1. Use a screwdriver to secure the cyborg's internal panel
    2. +
    3. Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
    4. +
    + +

    Cyborg Repairs

    + Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs). + +

    Dents

    + If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure. + Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder. + +

    Excessive Heat Damage

    + If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly.
    To replace the internal wiring follow the steps below: +
      +
    1. Unlock the Cyborg's Interface by swiping your ID
    2. +
    3. Open the Cyborg's External Panel using a crowbar
    4. +
    5. Remove the Cyborg's Power Cell
    6. +
    7. Using a screwdriver, expose the internal wiring of the Cyborg
    8. +
    9. Replace the damaged wires inside the cyborg
    10. +
    11. Secure the internal wiring cover using a screwdriver
    12. +
    13. Insert the Cyborg's Power Cell
    14. +
    15. Close the Cyborg's External Panel using a crowbar
    16. +
    17. Lock the Cyborg's Interface by swiping your ID
    18. +
    + These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency. + +

    In Case of Emergency

    + In case of emergency, there are a few steps you can take. + +

    "Rogue" Cyborgs

    + If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution. + To repair the situation, follow these steps: +
      +
    1. Locate the nearest robotics console
    2. +
    3. Determine which cyborgs are "Rogue"
    4. +
    5. Press the lockdown button to immobilize the cyborg
    6. +
    7. Locate the cyborg
    8. +
    9. Expose the cyborg's internal wiring
    10. +
    11. Check to make sure the LawSync and AI Sync lights are lit
    12. +
    13. If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's LawSync
    14. +
    15. Proceed to a cyborg upload console. The Company usually places these in the same location as AI upload consoles.
    16. +
    17. Use a "Reset" upload moduleto reset the cyborg's laws
    18. +
    19. Proceed to a Robotics Control console
    20. +
    21. Remove the lockdown on the cyborg
    22. +
    + +

    As a last resort

    + If all else fails in a case of cyborg-related emergency, there may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg. +

    WARNING:

    Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of company equipment, and you may be punished for detonating them without reason. + "} + +/datum/codex_entry/guide/detective + name = "Guide to Forensics" + lore_text = {" +

    Detective Work

    + Between your bouts of self-narration and drinking whiskey on the rocks, you might get a case or two to solve.
    + To have the best chance to solve your case, follow these directions: +

    +

      +
    1. Go to the crime scene.
    2. +
    3. Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog).
    4. +
    5. Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
    6. +
    7. Return to your office.
    8. +
    9. Using your forensic scanning computer, scan your scanner to upload all of your evidence into the database.
    10. +
    11. Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
    12. +
    13. If you have 80% or more of the print (The print is displayed), go to step 10, otherwise continue to step 8.
    14. +
    15. Look for clues from the suit fibres you found on your perpetrator, and go about looking for more evidence with this new information, scanning as you go.
    16. +
    17. Try to get a fingerprint card of your perpetrator, as if used in the computer, the prints will be completed on their dossier.
    18. +
    19. Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
    20. +
    21. Since you now have both your dossier and the name of the person, print both out as evidence and get security to nab your baddie.
    22. +
    23. Give yourself a pat on the back and a bottle of the ship's finest vodka, you did it!
    24. +
    +

    + It really is that easy! Good luck! + "} + +/datum/codex_entry/guide/nuclear_sabotage + name = "Guide to Nuclear Sabotage" + lore_text = {" +

    Nuclear Explosives 101

    + Hello and thank you for choosing the Syndicate for your nuclear information needs. Today's crash course will deal with the operation of a Nuclear Fission Device.

    + + First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done, to unbolt it, one must completely log in, which at this time may not be possible.
    + +

    To make the nuclear device functional

    +
      +
    • Place the nuclear device in the designated detonation zone.
    • +
    • Extend and anchor the nuclear device from its interface.
    • +
    • Insert the nuclear authorisation disk into the slot.
    • +
    • Type the numeric authorisation code into the keypad. This should have been provided.
      + Note: If you make a mistake, press R to reset the device. +
    • Press the E button to log on to the device.
    • +

    + + You now have activated the device. To deactivate the buttons at anytime, for example when you've already prepped the bomb for detonation, remove the authentication disk OR press R on the keypad.

    + Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option. Toggle off the SAFETY.
    + Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.

    + + So use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
    + Note: THE BOMB IS STILL SET AND WILL DETONATE

    + + Now before you remove the disk, if you need to move the bomb, you can toggle off the anchor, move it, and re-anchor.

    + + Remember the order:
    + Disk, Code, Safety, Timer, Disk, RUN!

    + Intelligence Analysts believe that normal corporate procedure is for the Captain to secure the nuclear authentication disk.

    + + Good luck! + "} + +/datum/codex_entry/guide/particle_accelerator + name = "Guide to Particle Accelerators" + lore_text = {" +

    Experienced User's Guide

    +

    Setting up the accelerator

    +
      +
    1. Wrench all pieces to the floor
    2. +
    3. Add wires to all the pieces
    4. +
    5. Close all the panels with your screwdriver
    6. +
    +

    Using the accelerator

    +
      +
    1. Open the control panel
    2. +
    3. Set the speed to 2
    4. +
    5. Start firing at the singularity generator
    6. +
    7. When the singularity reaches a large enough size so it starts moving on it's own set the speed down to 0, but don't shut it off
    8. +
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. +
    + "} + + +/datum/codex_entry/guide/singularity + name = "Guide to Singularity Engines" + lore_text = {" +

    Singularity Safety in Special Circumstances

    +

    Power outage

    + A power problem has made you lose power? Could be wiring problems or syndicate power sinks. In any case follow these steps: +
      +
    1. PANIC!
    2. +
    3. Get your ass over to engineering! QUICKLY!!!
    4. +
    5. Get to the Area Power Controller which controls the power to the emitters.
    6. +
    7. Swipe it with your ID card - if it doesn't unlock, continue with step 15.
    8. +
    9. Open the console and disengage the cover lock.
    10. +
    11. Pry open the APC with a Crowbar.
    12. +
    13. Take out the empty power cell.
    14. +
    15. Put in the new, full power cell - if you don't have one, continue with step 15.
    16. +
    17. Quickly put on a Radiation suit.
    18. +
    19. Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
    20. +
    21. Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering APC is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the APC to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
    22. +
    23. Grab your crowbar and pry away the tile closest to the APC.
    24. +
    25. Use the wirecutters to cut the wire which is connecting the grid to the terminal.
    26. +
    27. Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
    28. +
    29. GET THE FUCK OUT OF THERE!!!
    30. +
    +

    Shields get damaged

    +
      +
    1. GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
    2. +
    + "} + +/datum/codex_entry/guide/mech_construction + name = "Guide to Exosuit Construction" + lore_text = {" +
    +
    + Weyland-Yutani - Building Better Worlds +

    Autonomous Power Loader Unit \"Ripley\"

    +
    +

    Specifications:

    +
      +
    • Class: Autonomous Power Loader
    • +
    • Scope: Logistics and Construction
    • +
    • Weight: 820kg (without operator and with empty cargo compartment)
    • +
    • Height: 2.5m
    • +
    • Width: 1.8m
    • +
    • Top speed: 5km/hour
    • +
    • Operation in vacuum/hostile environment: Possible +
    • Airtank volume: 500 liters
    • +
    • Devices: +
        +
      • Hydraulic clamp
      • +
      • High-speed drill
      • +
      +
    • +
    • Propulsion device: Powercell-powered electro-hydraulic system
    • +
    • Powercell capacity: Varies
    • +
    +

    Construction:

    +
      +
    1. Connect all exosuit parts to the chassis frame.
    2. +
    3. Connect all hydraulic fittings and tighten them up with a wrench.
    4. +
    5. Adjust the servohydraulics with a screwdriver.
    6. +
    7. Wire the chassis (Cable is not included).
    8. +
    9. Use the wirecutters to remove the excess cable if needed.
    10. +
    11. Install the central control module (Not included. Use supplied datadisk to create one).
    12. +
    13. Secure the mainboard with a screwdriver.
    14. +
    15. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    16. +
    17. Secure the peripherals control module with a screwdriver.
    18. +
    19. Install the internal armor plating (Not included due to corporate regulations. Can be made using 5 metal sheets).
    20. +
    21. Secure the internal armor plating with a wrench.
    22. +
    23. Weld the internal armor plating to the chassis.
    24. +
    25. Install the external reinforced armor plating (Not included due to corporate regulations. Can be made using 5 reinforced metal sheets).
    26. +
    27. Secure the external reinforced armor plating with a wrench.
    28. +
    29. Weld the external reinforced armor plating to the chassis.
    30. +
    +

    Additional Information:

    +
      +
    • The firefighting variation is made in a similar fashion.
    • +
    • A firesuit must be connected to the firefighter chassis for heat shielding.
    • +
    • Internal armor is plasteel for additional strength.
    • +
    • External armor must be installed in 2 parts, totalling 10 sheets.
    • +
    • Completed exosuit is more resilient against fire, and is a bit more durable overall.
    • +
    • The Company is determined to ensure the safety of its investments employees.
    • +
    + + "} + +/datum/codex_entry/guide/atmospherics + name = "Guide to Atmospherics" + lore_text = {" +

    Contents

    +
      +
    1. Author's Foreword
    2. +
    3. Basic Piping
    4. +
    5. Insulated Pipes
    6. +
    7. Atmospherics Devices
    8. +
    9. Heat Exchange Systems
    10. +
    11. Final Checks
    12. +

    +

    HOW TO NOT SUCK QUITE SO HARD AT ATMOSPHERICS


    + Or: What the fuck does a "pressure regulator" do?

    + Alright. It has come to my attention that a variety of people are unsure of what a "pipe" is and what it does. + Apparently, there is an unnatural fear of these arcane devices and their "gases." Spooky, spooky. So, + this will tell you what every device constructable by an ordinary pipe dispenser within atmospherics actually does. + You are not going to learn what to do with them to be the super best person ever, or how to play guitar with passive gates, + or something like that. Just what stuff does.

    +

    Basic Pipes

    + The boring ones.
    + Most ordinary pipes are pretty straightforward. They hold gas. If gas is moving in a direction for some reason, gas will flow in that direction. + That's about it. Even so, here's all of your wonderful pipe options.
    +
      +
    • Straight pipes: They're pipes. One-meter sections. Straight line. Pretty simple. Just about every pipe and device is based around this + standard one-meter size, so most things will take up as much space as one of these.
    • +
    • Bent pipes: Pipes with a 90 degree bend at the half-meter mark. My goodness.
    • +
    • Pipe manifolds: Pipes that are essentially a "T" shape, allowing you to connect three things at one point.
    • +
    • 4-way manifold: A four-way junction.
    • +
    • Pipe cap: Caps off the end of a pipe. Open ends don't actually vent air, because of the way the pipes are assembled, so, uh, use them to decorate your house or something.
    • +
    • Manual valve: A valve that will block off airflow when turned. Can't be used by the AI or cyborgs, because they don't have hands.
    • +
    • Manual T-valve: Like a manual valve, but at the center of a manifold instead of a straight pipe.


    • +
    + An important note here is that pipes are now done in three distinct lines - general, supply, and scrubber. You can move gases between these with a universal adapter. Use the correct position for the correct location. + Connecting scrubbers to a supply position pipe makes you an idiot who gives everyone a difficult job. Insulated and HE pipes don't go through these positions. +

    Insulated Pipes

    +
  • Bent pipes: Pipes with a 90 degree bend at the half-meter mark. My goodness.
  • +
  • Pipe manifolds: Pipes that are essentially a "T" shape, allowing you to connect three things at one point.
  • +
  • 4-way manifold: A four-way junction.
  • +
  • Pipe cap: Caps off the end of a pipe. Open ends don't actually vent air, because of the way the pipes are assembled, so, uh. Use them to decorate your house or something.
  • +
  • Manual Valve: A valve that will block off airflow when turned. Can't be used by the AI or cyborgs, because they don't have hands.
  • +
  • Manual T-Valve: Like a manual valve, but at the center of a manifold instead of a straight pipe.


  • +

    Insulated Pipes


    + Special Public Service Announcement.
    + Our regular pipes are already insulated. These are completely worthless. Punch anyone who uses them.

    +

    Devices:

    + They actually do something.
    + This is usually where people get frightened, afraid, and start calling on their gods and/or cowering in fear. Yes, I can see you doing that right now. + Stop it. It's unbecoming. Most of these are fairly straightforward.
    +
      +
    • Gas pump: Take a wild guess. It moves gas in the direction it's pointing (marked by the red line on one end). It moves it based on pressure, the maximum output being 15000 kPa (kilopascals). + Ordinary atmospheric pressure, for comparison, is 101.3 kPa, and the minimum pressure of room-temperature pure oxygen needed to not suffocate in a matter of minutes is 16 kPa + (though 18 kPa is preferred when using internals with pure oxygen, for various reasons). A high-powered variant will move gas more quickly at the expense of consuming more power. Do not turn the distribution loop up to 15000 kPa. + You will make engiborgs cry and the Chief Engineer will beat you.
    • +
    • Pressure regulator: These replaced the old passive gates. You can choose to regulate pressure by input or output, and regulate flow rate. Regulating by input means that when input pressure is above the limit, gas will flow. + Regulating by output means that when pressure is below the limit, gas will flow. Flow rate can be controlled.
    • +
    • Unary vent: The basic vent used in rooms. It pumps gas into the room, but can't suck it back out. Controlled by the room's air alarm system.
    • +
    • Scrubber: The other half of room equipment. Filters air, and can suck it in entirely in what's called a "panic siphon." Activating a panic siphon without very good reason will kill someone. Don't do it.
    • +
    • Meter: A little box with some gauges and numbers. Fasten it to any pipe or manifold and it'll read you the pressure in it. Very useful.
    • +
    • Gas mixer: Two sides are input, one side is output. Mixes the gases pumped into it at the ratio defined. The side perpendicular to the other two is "node 2," for reference, on non-mirrored mixers.. + Output is controlled by flow rate. There is also an "omni" variant that allows you to set input and output sections freely..
    • +
    • Gas filter: Essentially the opposite of a gas mixer. One side is input. The other two sides are output. One gas type will be filtered into the perpendicular output pipe, + the rest will continue out the other side. Can also output from 0-4500 kPa. The "omni" vairant allows you to set input and output sections freely.
    • +
    +

    Heat Exchange Systems

    + Will not set you on fire.
    + These systems are used to only transfer heat between two pipes. They will not move gases or any other element, but will equalize the temperature (eventually). Note that because of how gases work (remember: pv=nRt), + a higher temperature will raise pressure, and a lower one will lower temperature.
    +
  • Pipe: This is a pipe that will exchange heat with the surrounding atmosphere. Place in fire for superheating. Place in space for supercooling.
  • +
  • Bent pipe: Take a wild guess.
  • +
  • Junction: The point where you connect your normal pipes to heat exchange pipes. Not necessary for heat exchangers, but necessary for H/E pipes/bent pipes.
  • +
  • Heat exchanger: These funky-looking bits attach to an open pipe end. Put another heat exchanger directly across from it, and you can transfer heat across two pipes without having to have the gases touch. + This normally shouldn't exchange with the ambient air, despite being totally exposed. Just don't ask questions.

  • + That's about it for pipes. Go forth, armed with this knowledge, and try not to break, burn down, or kill anything. Please. + "} + +/datum/codex_entry/guide/eva + name = "Guide to EVA" + lore_text = {" +

    EVA Gear and You: Not Spending All Day Inside

    + Or: How not to suffocate because there's a hole in your shoes
    +

    Contents

    +
      +
    1. A foreword on using EVA gear
    2. +
    3. Donning a Civilian Suit
    4. +
    5. Putting on a Hardsuit
    6. +
    7. Cyclers and Other Modification Equipment
    8. +
    9. Final Checks
    10. +
    +
    + EVA gear. Wonderful to use. It's useful for mining, engineering, and occasionally just surviving, if things are that bad. Most people have EVA training, + but apparently there are some people out in space who don't. This guide should give you a basic idea of how to use this gear, safely. It's split into two sections: + Civilian suits and hardsuits.

    +

    Civilian Suits

    + The bulkiest things this side of Alpha Centauri
    + These suits are the grey ones that are stored in EVA. They're the more simple to get on, but are also a lot bulkier, and provide less protection from environmental hazards such as radiation or physical impact. + As Medical, Engineering, Security, and Mining all have hardsuits of their own, these don't see much use, but knowing how to put them on is quite useful anyways.

    + First, take the suit. It should be in three pieces: A top, a bottom, and a helmet. Put the bottom on first, shoes and the like will fit in it. If you have magnetic boots, however, + put them on on top of the suit's feet. Next, get the top on, as you would a shirt. It can be somewhat awkward putting these pieces on, due to the makeup of the suit, + but to an extent they will adjust to you. You can then find the snaps and seals around the waist, where the two pieces meet. Fasten these, and double-check their tightness. + The red indicators around the waist of the lower half will turn green when this is done correctly. Next, put on whatever breathing apparatus you're using, be it a gas mask or a breath mask. Make sure the oxygen tube is fastened into it. + Put on the helmet now, straightforward, and make sure the tube goes into the small opening specifically for internals. Again, fasten seals around the neck, a small indicator light in the inside of the helmet should go from red to off when all is fastened. + There is a small slot on the side of the suit where an emergency oxygen tank or extended emergency oxygen tank will fit, + but it is recommended to have a full-sized tank on your back for EVA.

    + These suits tend to be wearable by most species. They're large and flexible. They might be pretty uncomfortable for some, though, so keep that in mind.

    +

    Hardsuits

    + Heavy, uncomfortable, still the best option.
    + These suits come in Engineering, Mining, and the Armory. There's also a couple Medical Hardsuits in EVA. These provide a lot more protection than the standard suits.

    + Similarly to the other suits, these are split into three parts. Fastening the pant and top are mostly the same as the other spacesuits, with the exception that these are a bit heavier, + though not as bulky. The helmet goes on differently, with the air tube feeding into the suit and out a hole near the left shoulder, while the helmet goes on turned ninety degrees counter-clockwise, + and then is screwed in for one and a quarter full rotations clockwise, leaving the faceplate directly in front of you. There is a small button on the right side of the helmet that activates the helmet light. + The tanks that fasten onto the side slot are emergency tanks, as well as full-sized oxygen tanks, leaving your back free for a backpack or satchel.

    + These suits generally only fit one species. Standard-issue suits are usually human-fitting by default, but there's equipment that can make modifications to the hardsuits to fit them to other species.

    +

    Modification Equipment

    + How to actually make hardsuits fit you.
    + There's a variety of equipment that can modify hardsuits to fit species that can't fit into them, making life quite a bit easier.

    + The first piece of equipment is a suit cycler. This is a large machine resembling the storage pods that are in place in some places. These are machines that will automatically tailor a suit to certain specifications. + The largest uses of them are for their cleaning functions and their ability to tailor suits for a species. Do not enter them physically. You will die from any of the functions being activated, and it will be painful. + These machines can both tailor a suit between species, and between types. This means you can convert engineering hardsuits to atmospherics, or the other way. This is useful. Use it if you can.

    + There's also modification kits that let you modify suits yourself. These are extremely difficult to use unless you understand the actual construction of the suit. I do not recommend using them unless no other option is available. +

    Final Checks

    +
      +
    • Are all seals fastened correctly?
    • +
    • If you have modified it manually, is absolutely everything sealed perfectly?
    • +
    • Do you either have shoes on under the suit, or magnetic boots on over it?
    • +
    • Do you have a mask on and internals on the suit or your back?
    • +
    • Do you have a way to communicate with your fellow crew in case something goes wrong?
    • +
    • Do you have a second person watching if this is a training session?

    • +
    + If you don't have any further issues, go out and do whatever is necessary. + "} + +/datum/codex_entry/guide/xenoarchaeology + name = "Guide to Xenoarchaeology" + lore_text = {" +

    Contents

    +
      +
    1. Prepping the expedition
    2. +
    3. Knowing your tools
    4. +
    5. Finding the dig
    6. +
    7. Analysing deposits
    8. +
    9. Extracting your first find
    10. +
    +
    +

    Prepping the expedition

    + Every digsite I've been to, someone has forgotten something and I've never yet been to a dig that hasn't had me hiking to get to it - so gather your gear + and get it to the site the first time. You learn quick that time is money, when you've got a shipful of bandits searching for you the next valley over, + but don't be afraid to clear some space if there are any inconvenient boulders in the way.
    +
      +
    • Floodlights (if it's dark)
    • +
    • Wooden trestle tables (for holding tools and finds)
    • +
    • Suspension field generator
    • +
    • Load bearing servitors (such as a mulebot, or hover-tray)
    • +
    • Spare energy packs
    • +

    + Contents +

    Knowing your tools

    + Every archaeologist has a plethora of tools at their disposal, but here's the important ones:
    +
      +
    • Picks, pickaxes, and brushes - don't underestimate the the smallest or largest in your arsenal, each one clears a different amount + of the rockface so each one has a use.
    • +
    • Measuring tape - don't leave home without it, you can use it to measure the depth a rock face has been excavated to.
    • +
    • GPS locator - knowing where you are is the first step to not be lost.
    • +
    • Core sampler - use this to take core samples from rock faces, which you can then run to the lab for analysis.
    • +
    • Depth scanner - uses X-ray diffraction to locate anomalous densities in rock, indicating archaeological deposits or mineral veins. + Comes with a handy reference log containing coordinates and time of each scan.
    • +
    • Alden-Saraspova counter - uses a patented application of Fourier Transform analysis to determine the difference between background and + exotic radiation. Use it to determine how far you are from anomalous energy sources.
    • +
    • Radio beacon locator - leave a beacon at an item of interest, then track it down later with this handy gadget. Watch for interference from other + devices though.
    • +
    • Flashlight or portable light source - Self explanatory, I hope.
    • +
    • Environmental safety gear - This one's dependent on the environment you're working in, but enclosed footwear and a pack of internals + could save your life.
    • +
    • Anomaly safety gear - A biosealed and catalysis-resistant suit along with eye shielding, tinted hood, and non-reactive disposable gloves are + the best kind of protection you can hope for from the errors our forebears may have unleashed.
    • +
    • Personal defence weapon - Never know what you'll find on the dig: pirates, natives, ancient guardians, carnivorous wildlife... + it pays in blood to be prepared.
    • +

    + Contents +

    Finding the dig

    + Wouldn't be an archaeologist without their dig, but everyone has to start somewhere. Here's a basic procedure I go through when cataloguing a new planet:
    +
      +
    • Get in touch with the locals (in particular geologists, miners, and farmers) - Never know what's been turned up by accident, then left to + gather dust on a shelf.
    • +
    • Check the obvious areas first - even if you're pressed for time, these ones are the generally easiest to search, and the most likely targets + of your rivals.
    • +
    • Do some prospecting - the earth mother isn't in the habit of displaying her secrets to the world (although sometimes you get lucky). + Drop a shaft and clear away a bit of surface rock here and there, you never know what might be lurking below the surface.
    • +
    • Tips on unearthing a deposit - How do you know when you're golden? Look for telltale white strata that looks strange or out of place, or if + something has broken under your pick while you're digging. Your depth scanner is your best friend, but even it can't distinguish between + ordinary minerals and ancient leavings, if in doubt then err on the side of caution.
    • +

    + Contents +

    Analysing the contents of a dig

    + You've found some unusual strata, but it's not all peaches from here. No archaeologist ever managed to pull a bone from the earth without doing thorough + chemical analysis on every two meters of rock face nearby.
    +
      +
    • Take core samples - Grab a rock core for every 4m^2.
    • +
    • Clear around any potential finds - Clear away ordinary rock, leaving your prizes reachable in a clearly marked area.
    • +
    • Haul off excess rock - It's easy for a dig to get cluttered, and a neat archaeologist is a successful archaeologist.
    • +
    • Don't be afraid to be cautious - It's slower sometimes, but the extra time will be worth the payoff when you find an Exolitic relic.
    • +
    • Chemical analysis - I won't go into detail here, but the labwork is essential to any successful extraction. Marshal your core samples, and + send them off to the labcoated geniuses.
    • +

    + Contents +

    Extracting your first find

    +
      +
    • Scan the rock - Use a depth scanner to determine the find's depth and clearance. DON'T FORGET THESE.
    • +
    • Choose stasis field - Chemical analysis on a core sample from the rock face will tell you which field is necessary to extract the find safely.
    • +
    • Setup field gen - Bolt it down, choose the field, check the charge, and activate it. If you forget it, you'll wish you hadn't when that priceless + Uryom vase crumbles as it sees the light of day.
    • +
    • FUNCTIONAL AND SAFE digging - Dig into the rock until you've cleared away a depth equal to (the anomaly depth MINUS the clearance range). The find + should come loose on it's own, but it will be in the midst of a chunk of rock. Use a welder or miniature excavation tool to clear away the excess.
    • +
    • FANCY AND SPEEDY digging - Dig into the rock until you've cleared away a depth equal to the anomaly depth, but without any of your strokes + entering the clearance range.
    • +
    • The big find - Sometimes, you'll chance upon something big, both literally and figuratively. Giant statues and functioning remnants of Precursor + technology are just as exciting, to the right buyers. If your digging leaves a large boulder behind, dig into it normally and see if anything's hidden + inside.
    • +

    + Contents + "} + + +/datum/codex_entry/guide/mass_spectrometry + name = "Guide to Mass Spectrometry" + lore_text = {" +

    Contents

    +
      +
    1. A note on terms
    2. +
    3. Analysis progression
    4. +
    5. Heat management
    6. +
    7. Ambient radiation
    8. +
    +
    +

    A note on terms

    +
      +
    • Mass spectrometry - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of + 'Materials analysis.'
    • +
    • Radiometric dating - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.
    • +
    • Dissonance ratio - This is a pseudoarbitrary value indicating the overall presence of a particular element in a greater composite. + It takes into account volume, density, molecular excitation and isotope spread.
    • +
    • Vacuum seal integrity - A reference to how close an airtight seal is to failure.
    • +

    + Contents +

    Analysis progression

    + Modern mass spectrometry requires constant attention from the diligent researcher in order to be successful. There are many different elements to juggle, + and later chapters will delve into them. For the spectrometry assistant, the first thing you need to know is that the scanner wavelength is automatically + calculated for you. Just tweak the settings and try to match it with the actual wavelength as closely as possible.
    +
    + Contents +

    Seal integrity

    + In order to maintain sterile and environmentally static procedures, a special chamber is set up inside the spectrometer. It's protected by a proprietary vacuum seal + produced by top tier industrial science. It will only last for a certain number of scans before failing outright, but it can be resealed through use of nanite paste. + Unfortunately, it's susceptible to malforming under heat stress so exposing it to higher temperatures will cause it's operation life to drop significantly.
    +
    + Contents +

    Heat management

    + The scanner relies on a gyro-rotational system that varies in speed and intensity. Over the course of an ordinary scan, the RPMs can change dramatically. Higher RPMs + means greater heat generation, but is necessary for the ongoing continuation of the scan. To offset heat production, spectrometers have an inbuilt cooling system. + Researchers can modify the flow rate of water to aid in dropping temperature as necessary, but are advised that frequent water replacements may be necessary + depending on coolant purity. Other substances may be viable substitutes, but nowhere near as effective as water itself.
    +
    + Contents +

    Ambient radiation

    + Researchers are warned that while operational, mass spectrometers emit period bursts of radiation and are thus advised to wear protective gear. In the event of + radiation spikes, there is also a special shield that can be lowered to block emissions. Lowering this, however, will have the effect of blocking the scanner + so use it sparingly.
    +
    + Contents + "} + +/datum/codex_entry/guide/engineering + name = "Guide to Engineering" + +/datum/codex_entry/guide/construction + name = "Guide to Construction" + +/datum/codex_entry/guide/supermatter + name = "Guide to Supermatter Engines" + +/datum/codex_entry/guide/fusion + name = "Guide to Fusion Reactors" + +/datum/codex_entry/guide/hacking + name = "Guide to Hacking" + associated_strings = list("hacking") + mechanics_text = "Airlocks, vending machines, and various other machinery can be hacked by opening them up and fiddling with the wires. \ + While it might sound like a unlawful deed (and it usually is) this process is also performed by engineers, usually to fix said criminal deeds. \ + Hacking also benefits from the Electrical Engineering skill: a low skill may cause wires to tangle, and a high enough skill will let you examine wires to see what they do. \ +
    Hacking makes use of several items: \ +
    • a screwdriver, for opening maintenance panels.
    • \ +
    • a multitool, for pulsing wires (optional for many tasks, but very useful)
    • \ +
    • wirecutters, for cutting wires
    • \ +
    • insulated gloves, to prevent electrocution (optional but highly recommended)
    • \ +
    • a crowbar, if you're hacking a door to open it.
    \ +
    The first step to most hacking procedures is to use the screwdriver to open a maintenance panel and access the wiring. \ + After, you can click on the machine to view the wires. \ + You then use the multitool to pulse the wires, and in response some of the displayed information may change, causing certain effects to occur or allowing for certain benefits. \ + If you don't have a multitool, you can cut the wires. \ + Pulsing tends to cause temporary changes or toggles something, whereas cutting a wire is usually longer lasting, but this is not always the case. \ + Note that the corresponding wires and effects are randomized between rounds of the game. \ + You can also attach a signaler to pulse wires remotely." + antag_text = "To avoid suspicion or accidents, practice quietly somewhere out of the way and learn the wires you need before doing it for real." diff --git a/code/modules/detectivework/microscope/_forensic_machine.dm b/code/modules/detectivework/microscope/_forensic_machine.dm index fab07b75720..91dc7edb207 100644 --- a/code/modules/detectivework/microscope/_forensic_machine.dm +++ b/code/modules/detectivework/microscope/_forensic_machine.dm @@ -27,7 +27,7 @@ /obj/machinery/forensic/proc/set_sample(var/obj/O) if(O != sample && O) clear_sample() - events_repository.register(/decl/observ/destroyed, O, src, /obj/machinery/forensic/proc/clear_sample) + events_repository.register(/decl/observ/destroyed, O, src, TYPE_PROC_REF(/obj/machinery/forensic, clear_sample)) sample = O update_icon() diff --git a/code/modules/detectivework/tools/luminol.dm b/code/modules/detectivework/tools/luminol.dm index a157b789486..d4b7253df55 100644 --- a/code/modules/detectivework/tools/luminol.dm +++ b/code/modules/detectivework/tools/luminol.dm @@ -9,4 +9,4 @@ volume = 250 /obj/item/chems/spray/luminol/populate_reagents() - reagents.add_reagent(/decl/material/liquid/luminol, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/luminol, reagents.maximum_volume) diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index bb5f3708a18..cd1072292b8 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -227,6 +227,6 @@ return if(reagents?.total_volume) - reagents.remove_reagent(/decl/material/liquid/fuel, reagents.maximum_volume/25) + remove_from_reagents(/decl/material/liquid/fuel, reagents.maximum_volume/25) update_name() burn_time-- diff --git a/code/modules/detectivework/tools/uvlight.dm b/code/modules/detectivework/tools/uvlight.dm index b6c2a651303..1b5c3a86b71 100644 --- a/code/modules/detectivework/tools/uvlight.dm +++ b/code/modules/detectivework/tools/uvlight.dm @@ -7,7 +7,7 @@ w_class = ITEM_SIZE_SMALL action_button_name = "Toggle UV light" material = /decl/material/solid/metal/steel - origin_tech = "{'magnets':1,'engineering':1}" + origin_tech = @'{"magnets":1,"engineering":1}' z_flags = ZMM_MANGLE_PLANES var/list/scanned = list() var/list/stored_alpha = list() diff --git a/code/modules/economy/cael/ATM.dm b/code/modules/economy/cael/ATM.dm index 97863816303..af75a724103 100644 --- a/code/modules/economy/cael/ATM.dm +++ b/code/modules/economy/cael/ATM.dm @@ -11,7 +11,7 @@ anchored = TRUE idle_power_usage = 10 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/datum/money_account/authenticated_account var/number_incorrect_tries = 0 diff --git a/code/modules/economy/worth_currency.dm b/code/modules/economy/worth_currency.dm index bc39ff704ca..b9bdff6e541 100644 --- a/code/modules/economy/worth_currency.dm +++ b/code/modules/economy/worth_currency.dm @@ -14,7 +14,7 @@ name = "[value_name] [currency.name_singular] [name || "piece"]" state = state || "cash" marked_value = value - overlay = image(currency, state) + overlay = image(currency.icon, state) overlay.color = colour overlay.appearance_flags |= RESET_COLOR overlay.plane = FLOAT_PLANE diff --git a/code/modules/economy/worth_guns.dm b/code/modules/economy/worth_guns.dm index b4b0afb5916..6c95b04b91f 100644 --- a/code/modules/economy/worth_guns.dm +++ b/code/modules/economy/worth_guns.dm @@ -1,28 +1,45 @@ -// Can't think of a good way to get gun price from projectile (due to +// Can't think of a good way to get gun price from projectile (due to // firemodes, projectile types, etc) so this'll have to do for now. /obj/item/gun/get_base_value() . = 100 - -/obj/item/gun/energy/get_base_value() - . = 150 - -/obj/item/gun/get_base_value() - . = 0 if(silenced) . += 20 - . += one_hand_penalty * -2 - . += bulk * -5 - . += accuracy * 10 - . += scoped_accuracy * 5 - if(!autofire_enabled) + + var/static/list/vars_to_value = list( + "one_hand_penalty" = -2, + "bulk" = -5, + "accuracy" = 10, + "scoped_accuracy" = 5 + ) + + var/list/max_vars_to_value = list( + "one_hand_penalty" = one_hand_penalty, + "bulk" = bulk, + "accuracy" = accuracy, + "scoped_accuracy" = scoped_accuracy + ) + + for(var/datum/firemode/F in firemodes) + for(var/varname in vars_to_value) + if(varname in F.settings) + max_vars_to_value[varname] = max(max_vars_to_value[varname], F.settings[varname]) + + for(var/varname in max_vars_to_value) + . += max_vars_to_value[varname] * vars_to_value[varname] + + var/has_autofire = autofire_enabled + if(!has_autofire) for(var/datum/firemode/F in firemodes) if(F.settings["autofire_enabled"]) - . += 100 + has_autofire = TRUE + break + if(has_autofire) + . += 100 + . *= 10 - . += ..() /obj/item/gun/energy/get_base_value() - . = ..() + . = 150 if(self_recharge) . += 100 var/projectile_value = 1 diff --git a/code/modules/economy/worth_misc.dm b/code/modules/economy/worth_misc.dm index fb9014523d3..b003eb009c9 100644 --- a/code/modules/economy/worth_misc.dm +++ b/code/modules/economy/worth_misc.dm @@ -1,6 +1,3 @@ -/obj/item/disk/survey/get_base_value() - . = holographic ? 0 : (sqrt(data) * 5) - // Arbitrary values (TODO remove as many of these as possible) #define ARBITRARY_WORTH(PATH, AMT) \ PATH/get_value_multiplier() { . = 1 } \ @@ -8,4 +5,4 @@ PATH/get_base_value() { . = AMT } ARBITRARY_WORTH(/obj/machinery/emitter, 700) ARBITRARY_WORTH(/obj/machinery/rad_collector, 500) -ARBITRARY_WORTH(/obj/structure/particle_accelerator, 500) +ARBITRARY_WORTH(/obj/structure/particle_accelerator, 500) diff --git a/code/modules/economy/worth_vendomat.dm b/code/modules/economy/worth_vendomat.dm index 27ec89870bb..224532de14c 100644 --- a/code/modules/economy/worth_vendomat.dm +++ b/code/modules/economy/worth_vendomat.dm @@ -2,14 +2,18 @@ . = ..() var/stored_goods_worth = 0 for(var/datum/stored_items/vending_products/product in product_records) - stored_goods_worth += product.price * product.amount - if(markup) - stored_goods_worth /= markup + // instances will be counted by parent call as they are in the vendor contents + var/product_count = product.amount - length(product.instances) + if(product_count > 0) + stored_goods_worth += atom_info_repository.get_combined_worth_for(product.item_path) * product_count . += round(stored_goods_worth) /obj/structure/vending_refill/get_combined_monetary_worth() . = ..() var/stored_goods_worth = 0 for(var/datum/stored_items/vending_products/product in product_records) - stored_goods_worth += product.price * product.amount + // instances will be counted by parent call as they are in the vendor contents + var/product_count = product.amount - length(product.instances) + if(product_count > 0) + stored_goods_worth += atom_info_repository.get_combined_worth_for(product.item_path) * product_count . += round(stored_goods_worth) diff --git a/code/modules/emotes/definitions/_mob.dm b/code/modules/emotes/definitions/_mob.dm index 90598baaa78..c6fd0855eeb 100644 --- a/code/modules/emotes/definitions/_mob.dm +++ b/code/modules/emotes/definitions/_mob.dm @@ -42,19 +42,7 @@ /decl/emote/audible/choke, /decl/emote/audible/moan, /decl/emote/audible/gnarl - ) - -/mob/living/carbon/brain - default_emotes = list( - /decl/emote/audible/alarm, - /decl/emote/audible/alert, - /decl/emote/audible/notice, - /decl/emote/audible/whistle, - /decl/emote/audible/synth, - /decl/emote/audible/boop, - /decl/emote/visible/blink, - /decl/emote/visible/flash - ) + ) /mob/living/carbon/human default_emotes = list( @@ -168,4 +156,4 @@ /decl/emote/audible/synth/deny, /decl/emote/audible/synth/security, /decl/emote/audible/synth/security/halt - ) + ) diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index 24f6c9dfdb9..7713886e073 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -10,8 +10,8 @@ /mob/living/check_mob_can_emote(var/emote_type) return ..() && !(HAS_STATUS(src, STAT_SILENCE) && emote_type == AUDIBLE_MESSAGE) -/mob/living/carbon/brain/check_mob_can_emote(var/emote_type) - return ..() && (istype(container, /obj/item/mmi) || istype(loc, /obj/item/organ/internal/posibrain)) +/mob/living/brain/check_mob_can_emote(var/emote_type) + return ..() && istype(get_container(), /obj/item/organ/internal/brain_interface) /mob/proc/emote(var/act, var/m_type, var/message) set waitfor = FALSE diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 2e61914c580..39f8dc118d9 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -44,17 +44,9 @@ var/global/regex/actual_error_file_line //Handle cooldowns and silencing spammy errors var/silencing = FALSE - // We can runtime before config is initialized because BYOND initialize objs/map before a bunch of other stuff happens. - // This is a bunch of workaround code for that. Hooray! - - var/configured_error_cooldown = initial(config.error_cooldown) - var/configured_error_limit = initial(config.error_limit) - var/configured_error_silence_time = initial(config.error_silence_time) - if(config) - configured_error_cooldown = config.error_cooldown - configured_error_limit = config.error_limit - configured_error_silence_time = config.error_silence_time - + var/configured_error_cooldown = get_config_value(/decl/config/num/debug_error_cooldown) + var/configured_error_limit = get_config_value(/decl/config/num/debug_error_limit) + var/configured_error_silence_time = get_config_value(/decl/config/num/debug_error_silence_time) //Each occurence of an unique error adds to its cooldown time... cooldown = max(0, cooldown - (world.time - last_seen)) + configured_error_cooldown diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index d08af79ce53..4cf335faab0 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -126,14 +126,9 @@ var/global/datum/error_viewer/error_cache/error_cache // Show the error to admins with debug messages turned on, but only if one // from the same source hasn't been shown too recently if (error_source.next_message_at <= world.time) - var/const/viewtext = "\[view]" // Nesting these in other brackets went poorly + //var/const/viewtext = "\[view]" // Nesting these in other brackets went poorly //log_debug("Runtime in [e.file], line [e.line]: [html_encode(e.name)] [error_entry.make_link(viewtext)]") - var/err_msg_delay - if(config) - err_msg_delay = config.error_msg_delay - else - err_msg_delay = initial(config.error_msg_delay) - error_source.next_message_at = world.time + err_msg_delay + error_source.next_message_at = world.time + get_config_value(/decl/config/num/debug_error_msg_delay) /datum/error_viewer/error_source var/list/errors = list() diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index c44eeda8814..a2cf955a797 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -64,11 +64,11 @@ var/global/list/carp_count = list() // a list of Z levels (string), associated w else M = new /mob/living/simple_animal/hostile/carp/pike(T) I += 3 - events_repository.register(/decl/observ/death, M,src,/datum/event/carp_migration/proc/reduce_carp_count) - events_repository.register(/decl/observ/destroyed, M,src,/datum/event/carp_migration/proc/reduce_carp_count) + events_repository.register(/decl/observ/death, M,src, TYPE_PROC_REF(/datum/event/carp_migration, reduce_carp_count)) + events_repository.register(/decl/observ/destroyed, M,src, TYPE_PROC_REF(/datum/event/carp_migration, reduce_carp_count)) LAZYADD(global.carp_count[num2text(Z)], M) spawned_carp ++ - M.throw_at(get_random_edge_turf(global.reverse_dir[direction],TRANSITIONEDGE + 2, Z), 250, speed, callback = CALLBACK(src,/datum/event/carp_migration/proc/check_gib,M)) + M.throw_at(get_random_edge_turf(global.reverse_dir[direction],TRANSITIONEDGE + 2, Z), 250, speed, callback = CALLBACK(src, TYPE_PROC_REF(/datum/event/carp_migration, check_gib), M)) I++ if(no_show) break @@ -97,8 +97,8 @@ var/global/list/carp_count = list() // a list of Z levels (string), associated w if(M in L) LAZYREMOVE(L,M) break - events_repository.unregister(/decl/observ/death, M,src,/datum/event/carp_migration/proc/reduce_carp_count) - events_repository.unregister(/decl/observ/destroyed, M,src,/datum/event/carp_migration/proc/reduce_carp_count) + events_repository.unregister(/decl/observ/death, M,src, TYPE_PROC_REF(/datum/event/carp_migration, reduce_carp_count)) + events_repository.unregister(/decl/observ/destroyed, M,src, TYPE_PROC_REF(/datum/event/carp_migration, reduce_carp_count)) /datum/event/carp_migration/end() log_debug("Carp migration event spawned [spawned_carp] carp.") diff --git a/code/modules/events/disposals_explosion.dm b/code/modules/events/disposals_explosion.dm index cf1cb63a93b..86f470f6d6e 100644 --- a/code/modules/events/disposals_explosion.dm +++ b/code/modules/events/disposals_explosion.dm @@ -24,7 +24,7 @@ // Event listener for the marked pipe's destruction /datum/event/disposals_explosion/proc/pipe_destroyed() - events_repository.unregister(/decl/observ/destroyed, bursting_pipe, src, .proc/pipe_destroyed) + events_repository.unregister(/decl/observ/destroyed, bursting_pipe, src, PROC_REF(pipe_destroyed)) bursting_pipe = null kill() @@ -43,7 +43,7 @@ if(istype(A, /obj/structure/disposalpipe/segment)) bursting_pipe = A // Subscribe to pipe destruction facts - events_repository.register(/decl/observ/destroyed, A, src, .proc/pipe_destroyed) + events_repository.register(/decl/observ/destroyed, A, src, PROC_REF(pipe_destroyed)) break if(isnull(bursting_pipe)) @@ -70,7 +70,7 @@ if(isnull(bursting_pipe)) return - events_repository.unregister(/decl/observ/destroyed, bursting_pipe, src, .proc/pipe_destroyed) + events_repository.unregister(/decl/observ/destroyed, bursting_pipe, src, PROC_REF(pipe_destroyed)) if(bursting_pipe.health < 5) // Make a disposals holder for the trash diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index e67279c59e5..d404c07a42c 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -15,7 +15,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT if(!next_event_time) set_event_delay() - if(delayed || !config.allow_random_events) + if(delayed || !get_config_value(/decl/config/toggle/allow_random_events)) next_event_time += (world.time - last_world_time) else if(world.time > next_event_time) start_event() @@ -71,17 +71,18 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT var/last_time = last_event_time[EM] if(last_time) var/time_passed = world.time - last_time - var/weight_modifier = max(0, round((config.expected_round_length - time_passed) / 300)) + var/weight_modifier = max(0, round(((get_config_value(/decl/config/num/expected_round_length) HOURS) - time_passed) / 300)) weight = weight - weight_modifier return weight /datum/event_container/proc/set_event_delay() // If the next event time has not yet been set and we have a custom first time start - if(next_event_time == 0 && config.event_first_run[severity]) - var/lower = config.event_first_run[severity]["lower"] - var/upper = config.event_first_run[severity]["upper"] - var/event_delay = rand(lower, upper) + var/list/event_first_run = get_config_value(/decl/config/lists/event_first_run) + if(next_event_time == 0 && event_first_run[severity]) + var/lower = event_first_run[severity]["lower"] + var/upper = event_first_run[severity]["upper"] + var/event_delay = rand(lower, upper) MINUTES next_event_time = world.time + event_delay // Otherwise, follow the standard setup process else @@ -99,7 +100,9 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT playercount_modifier = 0.8 playercount_modifier = playercount_modifier * delay_modifier - var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier + var/list/event_delay_lower = get_config_value(/decl/config/lists/event_delay_lower) + var/list/event_delay_upper = get_config_value(/decl/config/lists/event_delay_upper) + var/event_delay = (rand(event_delay_lower[severity], event_delay_upper[severity]) * playercount_modifier) MINUTES next_event_time = world.time + event_delay log_debug("Next event of severity [severity_to_string[severity]] in [(next_event_time - world.time)/600] minutes.") diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 94d4290d4ff..2bf3dd6ead1 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -2,7 +2,7 @@ var/global/list/event_last_fired = list() //Always triggers an event when called, dynamically chooses events based on job population /proc/spawn_dynamic_event() - if(!config.allow_random_events) + if(!get_config_value(/decl/config/toggle/allow_random_events)) return var/minutes_passed = world.time/600 diff --git a/code/modules/events/mail.dm b/code/modules/events/mail.dm index 3a857b23b0d..a07ad514c3f 100644 --- a/code/modules/events/mail.dm +++ b/code/modules/events/mail.dm @@ -9,7 +9,7 @@ var/list/possible_gifts = list( /obj/item/flashlight/lamp/lava, - /obj/item/storage/fancy/crayons, + /obj/item/storage/box/fancy/crayons, /obj/item/guitar, /obj/item/toy/shipmodel, /obj/item/clothing/accessory/locket, diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index dc894d839de..9b1887f118f 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -1,30 +1,36 @@ /proc/send2irc(var/channel, var/msg) - export2irc(list(type="msg", mesg=msg, chan=channel, pwd=config.comms_password)) + export2irc(list(type="msg", mesg=msg, chan=channel, pwd=get_config_value(/decl/config/text/comms_password))) /proc/export2irc(params) - if(config.use_irc_bot && config.irc_bot_host) + if(!get_config_value(/decl/config/toggle/use_irc_bot)) + return + var/irc_bot_host = get_config_value(/decl/config/text/irc_bot_host) + if(irc_bot_host) spawn(-1) // spawn here prevents hanging in the case that the bot isn't reachable - world.Export("http://[config.irc_bot_host]:45678?[list2params(params)]") + world.Export("http://[irc_bot_host]:45678?[list2params(params)]") /proc/runtimes2irc(runtimes, revision) - export2irc(list(pwd=config.comms_password, type="runtime", runtimes=runtimes, revision=revision)) + export2irc(list(pwd=get_config_value(/decl/config/text/comms_password), type="runtime", runtimes=runtimes, revision=revision)) /proc/send2mainirc(var/msg) - if(config.main_irc) - send2irc(config.main_irc, msg) + var/main_irc = get_config_value(/decl/config/text/main_irc) + if(main_irc) + send2irc(main_irc, msg) return /proc/send2adminirc(var/msg) - if(config.admin_irc) - send2irc(config.admin_irc, msg) + var/admin_irc = get_config_value(/decl/config/text/admin_irc) + if(admin_irc) + send2irc(admin_irc, msg) return /proc/adminmsg2adminirc(client/source, client/target, msg) - if(config.admin_irc) + var/admin_irc = get_config_value(/decl/config/text/admin_irc) + if(admin_irc) var/list/params[0] - params["pwd"] = config.comms_password - params["chan"] = config.admin_irc + params["pwd"] = get_config_value(/decl/config/text/comms_password) + params["chan"] = admin_irc params["msg"] = msg params["src_key"] = source.key params["src_char"] = source.mob.real_name || source.mob.name @@ -42,13 +48,7 @@ export2irc(params) /proc/get_world_url() - . = "byond://" - if(config.serverurl) - . += config.serverurl - else if(config.server) - . += config.server - else - . += "[world.address]:[world.port]" + return "byond://[get_config_value(/decl/config/text/server) || get_config_value(/decl/config/text/serverurl) || "[world.address]:[world.port]"]" /hook/startup/proc/ircNotify() send2mainirc("Server starting up on [get_world_url()]") diff --git a/code/modules/fabrication/designs/general/designs_general.dm b/code/modules/fabrication/designs/general/designs_general.dm index 99b6171862d..5f7065dbaaa 100644 --- a/code/modules/fabrication/designs/general/designs_general.dm +++ b/code/modules/fabrication/designs/general/designs_general.dm @@ -165,3 +165,9 @@ /datum/fabricator_recipe/package_wrapper/gift path = /obj/item/stack/package_wrap/gift + +/datum/fabricator_recipe/clothes_iron + path = /obj/item/ironingiron + +/datum/fabricator_recipe/ironing_board + path = /obj/item/roller/ironingboard \ No newline at end of file diff --git a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm index 4b447a86902..6d29f214c96 100644 --- a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm +++ b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm @@ -338,6 +338,9 @@ /datum/fabricator_recipe/imprinter/circuit/washer path = /obj/item/stock_parts/circuitboard/washer +/datum/fabricator_recipe/imprinter/circuit/autoclave + path = /obj/item/stock_parts/circuitboard/autoclave + /datum/fabricator_recipe/imprinter/circuit/microwave path = /obj/item/stock_parts/circuitboard/microwave diff --git a/code/modules/fabrication/designs/micro/designs_glasses.dm b/code/modules/fabrication/designs/micro/designs_glasses.dm index fe582a40007..1efd81517c2 100644 --- a/code/modules/fabrication/designs/micro/designs_glasses.dm +++ b/code/modules/fabrication/designs/micro/designs_glasses.dm @@ -35,3 +35,14 @@ /datum/fabricator_recipe/drinkingglass/metalcoffecup path = /obj/item/chems/drinks/glass2/coffeecup/metal + +/datum/fabricator_recipe/dinnerware + category = "Dinnerware" + fabricator_types = list(FABRICATOR_CLASS_MICRO) + path = /obj/item/plate + +/datum/fabricator_recipe/dinnerware/platter + path = /obj/item/plate/platter + +/datum/fabricator_recipe/dinnerware/tray + path = /obj/item/plate/tray diff --git a/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm b/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm index 1952ced0dc0..0340a6c60f4 100644 --- a/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm +++ b/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm @@ -8,7 +8,7 @@ name = "disposal pipe segment" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' + build_icon = 'icons/obj/pipes/disposal_pipe.dmi' build_icon_state = "pipe-s" path = /obj/structure/disposalconstruct fabricator_types = list( @@ -18,7 +18,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/bent name = "bent disposal pipe segment" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-c" turn = DISPOSAL_FLIP_RIGHT constructed_path = /obj/structure/disposalpipe/segment/bent @@ -26,7 +25,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/junction name = "disposal pipe junction" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j1" turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/junction @@ -34,7 +32,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/junctionm name = "disposal pipe junction (mirrored)" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j2" turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/junction/mirrored @@ -42,7 +39,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/yjunction name = "disposal pipe y-junction" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-y" turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_RIGHT constructed_path = /obj/structure/disposalpipe/junction @@ -50,7 +46,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/trunk name = "disposal pipe trunk" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-t" constructed_path = /obj/structure/disposalpipe/trunk turn = DISPOSAL_FLIP_NONE @@ -58,7 +53,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/up name = "disposal pipe upwards segment" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-u" constructed_path = /obj/structure/disposalpipe/up turn = DISPOSAL_FLIP_NONE @@ -66,7 +60,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/down name = "disposal pipe downwards segment" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-d" constructed_path = /obj/structure/disposalpipe/down turn = DISPOSAL_FLIP_NONE @@ -74,7 +67,7 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device name = "disposal bin" desc = "A bin used to dispose of trash." - build_icon = 'icons/obj/pipes/disposal.dmi' + build_icon = 'icons/obj/pipes/disposal_bin.dmi' build_icon_state = "disposal" path = /obj/structure/disposalconstruct/machine constructed_path = /obj/machinery/disposal @@ -83,7 +76,7 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/outlet name = "disposal outlet" desc = "an outlet that ejects things from a disposal network." - build_icon = 'icons/obj/pipes/disposal.dmi' + build_icon = 'icons/obj/pipes/disposal_outlet.dmi' build_icon_state = "outlet" path = /obj/structure/disposalconstruct/machine/outlet constructed_path = /obj/structure/disposaloutlet @@ -91,15 +84,14 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/chute name = "disposal chute" desc = "A chute to put things into a disposal network." - build_icon = 'icons/obj/pipes/disposal.dmi' - build_icon_state = "intake" + build_icon = 'icons/obj/pipes/disposal_chute.dmi' + build_icon_state = "chute" constructed_path = /obj/machinery/disposal/deliveryChute path = /obj/structure/disposalconstruct/machine/chute /datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting name = "disposal sorter" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j1s" turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction @@ -108,7 +100,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/wildcard name = "wildcard disposal sorter" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j1s" turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction/wildcard @@ -117,7 +108,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/untagged name = "untagged disposal sorter" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j1s" turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction/untagged @@ -126,7 +116,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/sortingm name = "disposal sorter (mirrored)" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j2s" turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction/flipped @@ -135,7 +124,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/wildcardm name = "wildcard disposal sorter (mirrored)" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j2s" turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction/wildcard/flipped @@ -144,7 +132,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/untaggedm name = "untagged disposal sorter (mirrored)" desc = "Sorts things in a disposal system" - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j2s" turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/sortjunction/untagged/flipped @@ -153,7 +140,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/tagger name = "disposal tagger" desc = "It tags things." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-tagger" turn = DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/tagger @@ -162,7 +148,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/tagger/partial name = "disposal partial tagger" desc = "It tags things." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-tagger-partial" turn = DISPOSAL_FLIP_FLIP constructed_path = /obj/structure/disposalpipe/tagger/partial @@ -171,7 +156,6 @@ /datum/fabricator_recipe/pipe/disposal_dispenser/device/diversion name = "disposal diverter" desc = "A huge pipe segment used for constructing disposal systems." - build_icon = 'icons/obj/pipes/disposal.dmi' build_icon_state = "pipe-j1s" turn = DISPOSAL_FLIP_FLIP | DISPOSAL_FLIP_RIGHT constructed_path = /obj/structure/disposalpipe/diversion_junction diff --git a/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm b/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm index e2a471367ec..3b52762f8f9 100644 --- a/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm +++ b/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm @@ -1,15 +1,15 @@ /datum/fabricator_recipe/protolathe/brains category = "Machine Intelligence" - path = /obj/item/mmi + path = /obj/item/organ/internal/brain_interface/empty /datum/fabricator_recipe/protolathe/brains/get_product_name() . = "intelligence storage ([..()])" +/datum/fabricator_recipe/protolathe/brains/robotic + path = /obj/item/organ/internal/brain/robotic + /datum/fabricator_recipe/protolathe/brains/mmi_radio - path = /obj/item/mmi/radio_enabled - -/datum/fabricator_recipe/protolathe/brains/posibrain - path = /obj/item/organ/internal/posibrain + path = /obj/item/organ/internal/brain_interface/radio_enabled/empty /datum/fabricator_recipe/protolathe/brains/paicard path = /obj/item/paicard diff --git a/code/modules/fabrication/designs/robotics/designs_organs.dm b/code/modules/fabrication/designs/robotics/designs_organs.dm index 10bd93793a0..96e559fe4cc 100644 --- a/code/modules/fabrication/designs/robotics/designs_organs.dm +++ b/code/modules/fabrication/designs/robotics/designs_organs.dm @@ -23,7 +23,7 @@ var/decl/species/species = get_species_by_key(order.get_data("species", global.using_map.default_species)) for(var/obj/item/organ/internal/I in .) I.set_species(species) - I.set_bodytype(species.base_prosthetics_model) + I.set_bodytype(species.base_internal_prosthetics_model) I.status |= ORGAN_CUT_AWAY /datum/fabricator_recipe/robotics/organ/heart diff --git a/code/modules/fabrication/fabricator_bioprinter.dm b/code/modules/fabrication/fabricator_bioprinter.dm index f92e2d8526f..9b1341d1451 100644 --- a/code/modules/fabrication/fabricator_bioprinter.dm +++ b/code/modules/fabrication/fabricator_bioprinter.dm @@ -39,7 +39,7 @@ if(H && istype(H) && H.species && H.dna) loaded_dna = H.dna.Clone() to_chat(user, SPAN_INFO("You inject the blood sample into \the [src].")) - S.reagents.remove_any(BIOPRINTER_BLOOD_SAMPLE_SIZE) + S.remove_any_reagents(BIOPRINTER_BLOOD_SAMPLE_SIZE) //Tell nano to do its job SSnano.update_uis(src) return TRUE @@ -64,7 +64,7 @@ "UE" = loaded_dna.unique_enzymes, "species" = loaded_dna.species, "btype" = loaded_dna.b_type, - ) + ) /obj/machinery/fabricator/bioprinter/ui_draw_config(mob/user, ui_key) return TRUE //Always draw it for us diff --git a/code/modules/fabrication/fabricator_build.dm b/code/modules/fabrication/fabricator_build.dm index 035068cdc72..5ed1bf02adc 100644 --- a/code/modules/fabrication/fabricator_build.dm +++ b/code/modules/fabrication/fabricator_build.dm @@ -22,16 +22,38 @@ step(product, output_dir) /obj/machinery/fabricator/proc/start_building() - if(!(fab_status_flags & FAB_BUSY) && is_functioning()) - fab_status_flags |= FAB_BUSY + if(is_functioning()) update_use_power(POWER_USE_ACTIVE) - sound_token = play_looping_sound(src, sound_id, fabricator_sound, volume = 30) /obj/machinery/fabricator/proc/stop_building() - if(fab_status_flags & FAB_BUSY) + update_use_power(POWER_USE_IDLE) + +/obj/machinery/fabricator/power_change() + . = ..() + if(.) + if(stat & (BROKEN|NOPOWER)) + stop_building() + else if(!currently_building) + get_next_build() + else + start_building() + +/obj/machinery/fabricator/update_use_power() + . = ..() + if(use_power == POWER_USE_ACTIVE) + fab_status_flags |= FAB_BUSY + if(!sound_token) + sound_token = play_looping_sound(src, sound_id, fabricator_sound, volume = 30) + if(!currently_building) + get_next_build() + else fab_status_flags &= ~FAB_BUSY - update_use_power(POWER_USE_IDLE) QDEL_NULL(sound_token) + // This is to allow people to fix the fab when it + // gets stuck building a recipe during power loss. + if(istype(currently_building)) + queued_orders.Insert(1, currently_building) + currently_building = null /obj/machinery/fabricator/proc/get_next_build() currently_building = null diff --git a/code/modules/fabrication/fabricator_food.dm b/code/modules/fabrication/fabricator_food.dm index 65a3f51f109..b275ddc8f4c 100644 --- a/code/modules/fabrication/fabricator_food.dm +++ b/code/modules/fabrication/fabricator_food.dm @@ -13,15 +13,15 @@ return ..() var/true_text = lowertext(html_decode(text)) if(findtext(true_text, "status")) - addtimer(CALLBACK(src, /obj/machinery/fabricator/replicator/proc/state_status), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/fabricator/replicator, state_status)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) else if(findtext(true_text, "menu")) - addtimer(CALLBACK(src, /obj/machinery/fabricator/replicator/proc/state_menu), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - else + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/fabricator/replicator, state_menu)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + else for(var/datum/fabricator_recipe/recipe in design_cache) if(recipe.hidden && !(fab_status_flags & FAB_HACKED)) continue if(findtext(true_text, lowertext(recipe.name))) - addtimer(CALLBACK(src, /obj/machinery/fabricator/proc/try_queue_build, recipe, 1), 2 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/fabricator, try_queue_build), recipe, 1), 2 SECONDS) break ..() diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm index 8baaf1b6ee7..9adb3066b53 100644 --- a/code/modules/fabrication/fabricator_intake.dm +++ b/code/modules/fabrication/fabricator_intake.dm @@ -15,7 +15,7 @@ var/reagent_matter = round(taking_reagent / REAGENT_UNITS_PER_MATERIAL_UNIT) if(reagent_matter <= 0) continue - thing.reagents.remove_reagent(R, taking_reagent) + thing.remove_from_reagents(R, taking_reagent) stored_material[R] += reagent_matter // If we're destroying this, take everything. if(destructive) @@ -66,7 +66,7 @@ adding_mat_overlay.color = mat_colour material_overlays += adding_mat_overlay update_icon() - addtimer(CALLBACK(src, /obj/machinery/fabricator/proc/remove_mat_overlay, adding_mat_overlay), 1 SECOND) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/fabricator, remove_mat_overlay), adding_mat_overlay), 1 SECOND) if(stack_ref && stacks_used) stack_ref.use(stacks_used) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm deleted file mode 100644 index 08cbc66cf1d..00000000000 --- a/code/modules/flufftext/Dreaming.dm +++ /dev/null @@ -1,18 +0,0 @@ - -/mob/living/carbon/proc/dream() - set waitfor = FALSE - dreaming = 1 - - for(var/i = rand(1,4),i > 0, i--) - to_chat(src, "... [pick(SSlore.dreams)] ...") - sleep(rand(40,70)) - if(!HAS_STATUS(src, STAT_PARA)) - dreaming = 0 - return - dreaming = 0 - -/mob/living/carbon/proc/handle_dreams() - if(client && !dreaming && prob(5)) - dream() - -/mob/living/carbon/var/dreaming = 0 diff --git a/code/modules/food/machines/_appliance.dm b/code/modules/food/machines/_appliance.dm index 5c94c682fb9..926160f2b5c 100644 --- a/code/modules/food/machines/_appliance.dm +++ b/code/modules/food/machines/_appliance.dm @@ -593,7 +593,7 @@ meat_name = CH.species?.name || meat_name if(ispath(digest_product_type, /decl/material/liquid/nutriment/protein)) data = list("[meat_name] meat" = reagent_amount) - result.reagents.add_reagent(digest_product_type, reagent_amount, data) + result.add_to_reagents(digest_product_type, reagent_amount, data) if (victim.reagents) victim.reagents.trans_to(result, victim.reagents.total_volume) diff --git a/code/modules/food/machines/container.dm b/code/modules/food/machines/container.dm index 18193642e6b..2dd748babcf 100644 --- a/code/modules/food/machines/container.dm +++ b/code/modules/food/machines/container.dm @@ -43,7 +43,7 @@ return TRUE if(standard_pour_into(user, target)) //Pouring into another beaker? return TRUE - if(standard_feed_mob(user, target)) + if(handle_eaten_by_mob(user, target) != EATEN_INVALID) return TRUE if(user.a_intent == I_HURT) if(standard_splash_mob(user,target)) @@ -249,6 +249,7 @@ return FALSE return TRUE +// TODO: merge with /obj/item/plate somehow? /obj/item/chems/cooking_container/plate name = "serving plate" shortname = "plate" @@ -301,9 +302,9 @@ desc = "A bowl. You bowl foods on this bowl... wait, what?" icon = 'icons/obj/kitchen.dmi' icon_state = "mixingbowl" - center_of_mass = @"{'x':17,'y':7}" + center_of_mass = @'{"x":17,"y":7}' max_space = 30 matter = list(/decl/material/solid/metal/aluminium = 300) volume = 90 amount_per_transfer_from_this = 10 - possible_transfer_amounts = @"[5,10,15,25,30,60, 90]" \ No newline at end of file + possible_transfer_amounts = @'[5,10,15,25,30,60, 90]' \ No newline at end of file diff --git a/code/modules/food/machines/fryer.dm b/code/modules/food/machines/fryer.dm index 570542bc9f5..1693e2861ae 100644 --- a/code/modules/food/machines/fryer.dm +++ b/code/modules/food/machines/fryer.dm @@ -44,7 +44,7 @@ if (prob(20)) //Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled variance = rand()*0.5 - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil/corn, optimal_oil*(1 - variance)) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil/corn, optimal_oil*(1 - variance)) fry_loop = new(list(src), FALSE) /obj/machinery/appliance/cooker/fryer/heat_up() @@ -113,7 +113,7 @@ total_oil += I.reagents.reagent_volumes[_R] if (_R != reagents.primary_reagent) total_removed += I.reagents.reagent_volumes[_R] - I.reagents.remove_reagent(_R, I.reagents.reagent_volumes[_R]) + I.remove_from_reagents(_R, I.reagents.reagent_volumes[_R]) else total_our_oil += I.reagents.reagent_volumes[_R] @@ -134,7 +134,7 @@ if (I.reagents?.total_volume) for (var/_R in I.reagents.reagent_volumes) if (_R == reagents.primary_reagent) - I.reagents.remove_reagent(_R, I.reagents.reagent_volumes[_R]*portion) + I.remove_from_reagents(_R, I.reagents.reagent_volumes[_R]*portion) if(REAGENT_DATA(I.reagents, reagents.primary_reagent)) // cool down the oil LAZYSET(I.reagents.reagent_data[reagents.primary_reagent], "temperature", T0C + rand(35, 45)) // warm, but not hot; avoiding aftereffects of the hot oil @@ -216,8 +216,8 @@ if (ispath(_R, /decl/material/liquid/nutriment/triglyceride/oil)) var/delta = REAGENTS_FREE_SPACE(reagents) delta = min(delta, I.reagents.reagent_volumes[_R]) - reagents.add_reagent(_R, delta) - I.reagents.remove_reagent(_R, delta) + add_to_reagents(_R, delta) + I.remove_from_reagents(_R, delta) amount += delta if (amount > 0) user.visible_message("[user] pours some oil into [src].", SPAN_NOTICE("You pour [amount]u of oil into [src]."), SPAN_NOTICE("You hear something viscous being poured into a metal container.")) diff --git a/code/modules/food/plates/_plate.dm b/code/modules/food/plates/_plate.dm new file mode 100644 index 00000000000..8d10f25e958 --- /dev/null +++ b/code/modules/food/plates/_plate.dm @@ -0,0 +1,72 @@ +// TODO: merge with /obj/item/chems/cooking_container/plate somehow? +/obj/item/plate + name = "plate" + desc = "A small plate, suitable for serving food." + material = /decl/material/solid/stone/ceramic + icon = 'icons/obj/food/plates/small_plate.dmi' + icon_state = ICON_STATE_WORLD + material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME + w_class = ITEM_SIZE_SMALL + var/is_dirty + +/obj/item/plate/Destroy() + if(istype(loc, /obj/item/chems/food)) + var/obj/item/chems/food/food = loc + if(food.plate == src) + food.plate = null + return ..() + +/obj/item/plate/proc/make_dirty(obj/item/chems/food/food) + if(!is_dirty) + is_dirty = food?.filling_color || COLOR_WHITE + update_icon() + +/obj/item/plate/clean(clean_forensics = TRUE) + . = ..() + if(is_dirty) + is_dirty = null + update_icon() + +/obj/item/plate/on_update_icon() + . = ..() + if(is_dirty) + var/image/I = image(icon, "[icon_state]-dirty") + I.appearance_flags |= RESET_COLOR + I.color = is_dirty + add_overlay(I) + +/obj/item/plate/proc/try_plate_food(obj/item/chems/food/food, mob/user) + if(food.plate) + to_chat(user, SPAN_WARNING("\The [food] has already been plated.")) + return + if(ismob(loc)) + var/mob/M = loc + if(!M.try_unequip(src)) + return + forceMove(food) + food.plate = src + user?.visible_message(SPAN_NOTICE("\The [user] places \the [food] on \the [src].")) + food.update_icon() + +/obj/item/plate/attackby(obj/item/W, mob/living/user) + // Plating food. + if(istype(W, /obj/item/chems/food)) + if(!user.try_unequip(W)) + return TRUE + try_plate_food(W, user) + return TRUE + return ..() + +/obj/item/plate/platter + name = "platter" + desc = "A large white platter, suitable for serving cakes or other large food." + icon = 'icons/obj/food/plates/platter.dmi' + material = /decl/material/solid/glass + w_class = ITEM_SIZE_NORMAL + +/obj/item/plate/tray + name = "tray" + desc = "A large tray, suitable for serving several servings of food." + icon = 'icons/obj/food/plates/tray.dmi' + material = /decl/material/solid/organic/plastic + w_class = ITEM_SIZE_NORMAL diff --git a/code/modules/games/boardgame.dm b/code/modules/games/boardgame.dm index eb8a9ccbb3b..8c6fda78496 100644 --- a/code/modules/games/boardgame.dm +++ b/code/modules/games/boardgame.dm @@ -164,65 +164,99 @@ //Checkers -/obj/item/chems/food/checker +/obj/item/checker name = "checker" desc = "It is plastic and shiny." icon = 'icons/obj/pieces.dmi' icon_state = "checker_black" w_class = ITEM_SIZE_TINY - center_of_mass = @"{'x':16,'y':16}" - nutriment_desc = list("a choking hazard" = 4) - nutriment_amt = 1 + center_of_mass = @'{"x":16,"y":16}' var/piece_color ="black" -/obj/item/chems/food/checker/Initialize() +// Override these to let people eat checkers. +/obj/item/checker/is_edible(mob/eater) + return TRUE + +/obj/item/checker/is_food_empty(mob/eater) + return FALSE + +/obj/item/checker/transfer_eaten_material(mob/eater, amount) + if(isliving(eater)) + var/mob/living/living_eater = eater + living_eater.get_ingested_reagents()?.add_reagent(/decl/material/solid/organic/plastic, 3) + +/obj/item/checker/play_feed_sound(mob/user, consumption_method = EATING_METHOD_EAT) + return + +/obj/item/checker/show_food_consumed_message(mob/user, mob/target) + return + +/obj/item/checker/show_feed_message_start(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You begin trying to swallow \the [target].")) + else + user.visible_message(SPAN_NOTICE("\The [user] attempts to force \the [target] to swallow \the [src]!")) + +/obj/item/checker/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] forces \the [target] to swallow \the [src]!")) + +// End food overrides. + +/obj/item/checker/Initialize() . = ..() icon_state = "[name]_[piece_color]" name = "[piece_color] [name]" -/obj/item/chems/food/checker/red +/obj/item/checker/red piece_color ="red" //Chess -/obj/item/chems/food/checker/pawn +/obj/item/checker/pawn name = "pawn" desc = "How many pawns will die in your war?" -/obj/item/chems/food/checker/pawn/red +/obj/item/checker/pawn/red piece_color ="red" -/obj/item/chems/food/checker/knight +/obj/item/checker/knight name = "knight" desc = "The piece chess deserves, and needs to actually play." -/obj/item/chems/food/checker/knight/red +/obj/item/checker/knight/red piece_color ="red" -/obj/item/chems/food/checker/bishop +/obj/item/checker/bishop name = "bishop" desc = "What corruption occured, urging holy men to fight?" -/obj/item/chems/food/checker/bishop/red +/obj/item/checker/bishop/red piece_color ="red" -/obj/item/chems/food/checker/rook +/obj/item/checker/rook name = "rook" desc = "Representing ancient moving towers. So powerful and fast they were banned from wars, forever." -/obj/item/chems/food/checker/rook/red +/obj/item/checker/rook/red piece_color ="red" -/obj/item/chems/food/checker/queen +/obj/item/checker/queen name = "queen" desc = "A queen of battle and pain. She dances across the battlefield." -/obj/item/chems/food/checker/queen/red +/obj/item/checker/queen/red piece_color ="red" -/obj/item/chems/food/checker/king +/obj/item/checker/king name = "king" desc = "Why does a chess game end when the king dies?" -/obj/item/chems/food/checker/king/red +/obj/item/checker/king/red piece_color ="red" \ No newline at end of file diff --git a/code/modules/ghosttrap/trap.dm b/code/modules/ghosttrap/trap.dm index 2728becaa1c..73f2aade08a 100644 --- a/code/modules/ghosttrap/trap.dm +++ b/code/modules/ghosttrap/trap.dm @@ -1,5 +1,4 @@ -// This system is used to grab a ghost from observers with the required preferences -// and lack of bans set. See posibrain.dm for an example of how they are called/used. +// This system is used to grab a ghost from observers with the required preferences and lack of bans set. /decl/ghosttrap var/name var/minutes_since_death = 0 // If non-zero the ghost must have been dead for this many minutes to be allowed to spawn @@ -30,7 +29,7 @@ /decl/ghosttrap/proc/request_player(var/mob/target, var/request_string, var/request_timeout) if(request_timeout) LAZYSET(request_timeouts, target, world.time + request_timeout) - events_repository.register(/decl/observ/destroyed, target, src, /decl/ghosttrap/proc/unregister_target) + events_repository.register(/decl/observ/destroyed, target, src, TYPE_PROC_REF(/decl/ghosttrap, unregister_target)) else unregister_target(target) @@ -44,7 +43,7 @@ /decl/ghosttrap/proc/unregister_target(var/target) LAZYREMOVE(request_timeouts, target) - events_repository.unregister(/decl/observ/destroyed, target, src, /decl/ghosttrap/proc/unregister_target) + events_repository.unregister(/decl/observ/destroyed, target, src, TYPE_PROC_REF(/decl/ghosttrap, unregister_target)) // Handles a response to request_player(). /decl/ghosttrap/Topic(href, href_list) @@ -57,7 +56,7 @@ return if(candidate != usr) return - + var/timeout = LAZYACCESS(request_timeouts, target) if(!isnull(timeout) && world.time > timeout) to_chat(candidate, "This occupation request is no longer valid.") @@ -95,33 +94,42 @@ target.SetName(target.real_name) /*********************************** -* Positronic brains. * +* Computer intelligence cores. * ***********************************/ -/decl/ghosttrap/positronic_brain - name = "positronic brain" +/decl/ghosttrap/machine_intelligence + name = "machine intelligence" ban_checks = list("AI",ASSIGNMENT_ROBOT) - pref_check = "ghost_posibrain" - ghost_trap_message = "They are occupying a positronic brain now." + pref_check = "ghost_machine_intelligence" + ghost_trap_message = "They are occupying a computer intelligence core now." + +/decl/ghosttrap/machine_intelligence/transfer_personality(mob/candidate, mob/target) + if(assess_candidate(candidate)) + + var/obj/item/organ/internal/brain/robotic/brain = target.loc?.loc + if(!istype(brain)) + return FALSE + + brain.transfer_key_to_brainmob(candidate, update_brainmob = FALSE) + brain.searching = FALSE + brain.update_icon() + announce_ghost_joinleave(candidate, 0, "[ghost_trap_message]") + + var/mob/living/brainmob = brain.get_brainmob(create_if_missing = TRUE) + if(brainmob) + welcome_candidate(brainmob) + return TRUE -/decl/ghosttrap/positronic_brain/forced(var/mob/user) - var/obj/item/organ/internal/posibrain/brain = new(get_turf(user)) - if(!brain.brainmob) - brain.init() - request_player(brain.brainmob, "Someone is requesting a personality for a positronic brain.", 60 SECONDS) +/decl/ghosttrap/machine_intelligence/forced(var/mob/user) + var/obj/item/organ/internal/brain/robotic/brain = new(get_turf(user)) + request_player(brain.get_brainmob(create_if_missing = TRUE), "Someone is requesting a player for a machine intelligence.", 60 SECONDS) -/decl/ghosttrap/positronic_brain/welcome_candidate(var/mob/target) - to_chat(target, "You are a positronic brain, brought into existence on [station_name()].") +/decl/ghosttrap/machine_intelligence/welcome_candidate(var/mob/target) + to_chat(target, "You are a machine intelligence, brought into existence on [station_name()].") to_chat(target, "As a synthetic intelligence, you answer to all crewmembers, as well as the AI.") to_chat(target, "Remember, the purpose of your existence is to serve the crew and the [station_name()]. Above all else, do no harm.") to_chat(target, "Use say [target.get_language_prefix()]b to speak to other artificial intelligences.") var/turf/T = get_turf(target) - var/obj/item/organ/internal/posibrain/P = target.loc - T.visible_message("\The [P] chimes quietly.") - if(!istype(P)) //wat - return - P.searching = 0 - P.SetName("positronic brain ([P.brainmob.name])") - P.update_icon() + T.visible_message(SPAN_NOTICE("\The [target] beeps loudly.")) /*********************************** * Walking mushrooms and such. * @@ -131,7 +139,7 @@ ban_checks = list("Botany Roles") pref_check = "ghost_plant" ghost_trap_message = "They are occupying a living plant now." - + /decl/ghosttrap/sentient_plant/forced(var/mob/user) request_player(new /mob/living/simple_animal/mushroom(get_turf(user)), "Someone is harvesting a walking mushroom.", 15 SECONDS) diff --git a/code/modules/goals/_goal.dm b/code/modules/goals/_goal.dm index 41a179c1a9b..fbcf0e55f67 100644 --- a/code/modules/goals/_goal.dm +++ b/code/modules/goals/_goal.dm @@ -8,7 +8,7 @@ /datum/goal/New(var/_owner) owner = _owner - events_repository.register(/decl/observ/destroyed, owner, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/destroyed, owner, src, TYPE_PROC_REF(/datum, qdel_self)) if(istype(owner, /datum/mind)) var/datum/mind/mind = owner LAZYADD(mind.goals, src) diff --git a/code/modules/goals/definitions/personal_achievement_movement.dm b/code/modules/goals/definitions/personal_achievement_movement.dm index 7f5fb6f69bc..5e1e650a0c3 100644 --- a/code/modules/goals/definitions/personal_achievement_movement.dm +++ b/code/modules/goals/definitions/personal_achievement_movement.dm @@ -3,7 +3,7 @@ ..() if(owner) var/datum/mind/mind = owner - events_repository.register(/decl/observ/moved, mind.current, src, .proc/owner_moved) + events_repository.register(/decl/observ/moved, mind.current, src, PROC_REF(owner_moved)) /datum/goal/movement/proc/owner_moved() return @@ -40,7 +40,7 @@ /datum/goal/movement/walk/check_success() return (steps >= required_steps) - + /datum/goal/movement/walk/update_strings() description = "Stave off microgravity muscle atrophy by walking at least [required_steps] step\s this shift." diff --git a/code/modules/hallucinations/_hallucination.dm b/code/modules/hallucinations/_hallucination.dm new file mode 100644 index 00000000000..399fd5dfc0e --- /dev/null +++ b/code/modules/hallucinations/_hallucination.dm @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////////////////////////////////// +//Hallucination effects datums +////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/hallucination + var/mob/living/holder + var/allow_duplicates = 1 + var/duration = 0 + var/min_power = 0 //at what levels of hallucination power mobs should get it + var/max_power = INFINITY + var/activated = FALSE + +/datum/hallucination/proc/start() + SHOULD_CALL_PARENT(TRUE) + activated = TRUE + +/datum/hallucination/proc/end() + SHOULD_CALL_PARENT(TRUE) + activated = FALSE + +/datum/hallucination/proc/can_affect(var/mob/living/victim) + if(!victim.client) + return FALSE + if(min_power > victim.hallucination_power) + return FALSE + if(max_power < victim.hallucination_power) + return FALSE + if(!allow_duplicates && (locate(type) in victim._hallucinations)) + return FALSE + return TRUE + +/datum/hallucination/Destroy() + if(holder) + LAZYREMOVE(holder._hallucinations, src) + holder = null + if(activated) + end() + return ..() + +/datum/hallucination/proc/activate_hallucination() + set waitfor = FALSE + if(!holder || !holder.client || activated) + return + LAZYADD(holder._hallucinations, src) + start() + sleep(duration) + if(!QDELETED(src)) + qdel(src) diff --git a/code/modules/hallucinations/hallucination_fakeattack.dm b/code/modules/hallucinations/hallucination_fakeattack.dm new file mode 100644 index 00000000000..70ba9d36a04 --- /dev/null +++ b/code/modules/hallucinations/hallucination_fakeattack.dm @@ -0,0 +1,20 @@ +//Fake attack +/datum/hallucination/fakeattack + min_power = 30 + +/datum/hallucination/fakeattack/can_affect(var/mob/living/victim) + . = ..() && (locate(/mob/living) in oview(victim,1)) + +/datum/hallucination/fakeattack/start() + . = ..() + for(var/mob/living/assailant in oview(holder,1)) + to_chat(holder, SPAN_DANGER("\The [assailant] has punched \the [holder]!")) + holder.playsound_local(get_turf(holder),"punch",50) + +//Fake injection +/datum/hallucination/fakeattack/hypo + min_power = 30 + +/datum/hallucination/fakeattack/hypo/start() + . = ..() + to_chat(holder, SPAN_NOTICE("You feel a tiny prick!")) diff --git a/code/modules/hallucinations/hallucination_gunfire.dm b/code/modules/hallucinations/hallucination_gunfire.dm new file mode 100644 index 00000000000..d41d6289e65 --- /dev/null +++ b/code/modules/hallucinations/hallucination_gunfire.dm @@ -0,0 +1,31 @@ +//Hearing someone being shot twice +/datum/hallucination/gunfire + duration = 15 + min_power = 30 + var/gunshot + var/turf/origin + var/static/list/gunshot_sounds = list( + 'sound/weapons/gunshot/gunshot_strong.ogg', + 'sound/weapons/gunshot/gunshot2.ogg', + 'sound/weapons/gunshot/shotgun.ogg', + 'sound/weapons/gunshot/gunshot.ogg', + 'sound/weapons/Taser.ogg' + ) + +/datum/hallucination/gunfire/start() + . = ..() + gunshot = pick(gunshot_sounds) + var/turf/holder_turf = get_turf(holder) + if(isturf(holder_turf)) + origin = locate(holder_turf.x + rand(4,8), holder_turf.y + rand(4,8), holder_turf.z) + if(origin) + holder.playsound_local(origin, gunshot, 50) + +/datum/hallucination/gunfire/end() + . = ..() + if(holder && origin) + holder.playsound_local(origin, gunshot, 50) + +/datum/hallucination/gunfire/Destroy() + origin = null + return ..() \ No newline at end of file diff --git a/code/modules/hallucinations/hallucination_mirage.dm b/code/modules/hallucinations/hallucination_mirage.dm new file mode 100644 index 00000000000..279e8db3594 --- /dev/null +++ b/code/modules/hallucinations/hallucination_mirage.dm @@ -0,0 +1,76 @@ +//Seeing stuff +/datum/hallucination/mirage + duration = 30 SECONDS + max_power = 30 + var/number = 1 + var/list/things = list() //list of images to display + var/static/list/trash_states = icon_states('icons/obj/trash.dmi') + +/datum/hallucination/mirage/proc/generate_mirage() + return image('icons/obj/trash.dmi', pick(trash_states), layer = BELOW_TABLE_LAYER) + +/datum/hallucination/mirage/start() + . = ..() + var/list/possible_points = list() + for(var/turf/simulated/floor/F in view(holder, world.view+1)) + possible_points += F + if(possible_points.len) + for(var/i = 1 to number) + var/image/thing = generate_mirage() + things += thing + thing.loc = pick(possible_points) + if(holder?.client && length(things)) + holder.client.images += things + +/datum/hallucination/mirage/end() + if(holder?.client) + holder.client.images -= things + return ..() + +//Blood and aftermath of firefight +/datum/hallucination/mirage/carnage + min_power = 50 + number = 10 + var/static/list/carnage_states = list( + "mfloor1", + "mfloor2", + "mfloor3", + "mfloor4", + "mfloor5", + "mfloor6", + "mfloor7" + ) + +/datum/hallucination/mirage/carnage/generate_mirage() + var/image/I + if(prob(50)) + I = image('icons/effects/blood.dmi', pick(carnage_states), layer = BELOW_TABLE_LAYER) + I.color = COLOR_BLOOD_HUMAN + else + I = image('icons/obj/ammo.dmi', "s-casing-spent", layer = BELOW_TABLE_LAYER) + I.layer = BELOW_TABLE_LAYER + I.dir = pick(global.alldirs) + I.pixel_x = rand(-10,10) + I.pixel_y = rand(-10,10) + return I + +//LOADSEMONEY +/datum/hallucination/mirage/money + min_power = 20 + max_power = 45 + number = 2 + var/static/obj/item/cash/cash + +/datum/hallucination/mirage/money/New() + if(!cash) + cash = new /obj/item/cash/c500 + cash.update_icon() + cash.compile_overlays() + ..() + +/datum/hallucination/mirage/money/generate_mirage() + var/image/I = new + I.appearance = cash + I.layer = BELOW_TABLE_LAYER + qdel(cash) + return I diff --git a/code/modules/hallucinations/hallucination_skitters.dm b/code/modules/hallucinations/hallucination_skitters.dm new file mode 100644 index 00000000000..2ab7f1fdf35 --- /dev/null +++ b/code/modules/hallucinations/hallucination_skitters.dm @@ -0,0 +1,4 @@ +//Spiderling skitters +/datum/hallucination/skitter/start() + . = ..() + to_chat(holder, SPAN_NOTICE("The spiderling skitters[pick(" away"," around","")].")) diff --git a/code/modules/hallucinations/hallucination_sound.dm b/code/modules/hallucinations/hallucination_sound.dm new file mode 100644 index 00000000000..82e2389713b --- /dev/null +++ b/code/modules/hallucinations/hallucination_sound.dm @@ -0,0 +1,71 @@ +//Playing a random sound +/datum/hallucination/imagined_sound/proc/get_imagined_sounds() + var/static/list/sounds = list( + 'sound/machines/airlock.ogg', + 'sound/effects/explosionfar.ogg', + 'sound/machines/windowdoor.ogg', + 'sound/machines/twobeep.ogg' + ) + return sounds + +/datum/hallucination/imagined_sound/start() + . = ..() + var/turf/holder_turf = get_turf(holder) + if(holder_turf) + holder_turf = locate(holder_turf.x + rand(6,11), holder_turf.y + rand(6,11), holder_turf.z) + if(holder_turf) + holder.playsound_local(holder_turf, pick(get_imagined_sounds()) ,70) + +/datum/hallucination/imagined_sound/tools/get_imagined_sounds() + var/static/list/imagined_sounds = list( + 'sound/items/Ratchet.ogg', + 'sound/items/Welder.ogg', + 'sound/items/Crowbar.ogg', + 'sound/items/Screwdriver.ogg' + ) + return imagined_sounds + +/datum/hallucination/imagined_sound/danger + min_power = 30 + +/datum/hallucination/imagined_sound/danger/get_imagined_sounds() + var/static/list/imagined_sounds = list( + 'sound/effects/Explosion1.ogg', + 'sound/effects/Explosion2.ogg', + 'sound/effects/Glassbr1.ogg', + 'sound/effects/Glassbr2.ogg', + 'sound/effects/Glassbr3.ogg', + 'sound/weapons/smash.ogg' + ) + return imagined_sounds + +/datum/hallucination/imagined_sound/spooky + min_power = 50 + +/datum/hallucination/imagined_sound/spooky/get_imagined_sounds() + var/static/list/imagined_sounds = list( + 'sound/effects/ghost.ogg', + 'sound/effects/ghost2.ogg', + 'sound/effects/Heart Beat.ogg', + 'sound/effects/screech.ogg', + 'sound/hallucinations/behind_you1.ogg', + 'sound/hallucinations/behind_you2.ogg', + 'sound/hallucinations/far_noise.ogg', + 'sound/hallucinations/growl1.ogg', + 'sound/hallucinations/growl2.ogg', + 'sound/hallucinations/growl3.ogg', + 'sound/hallucinations/im_here1.ogg', + 'sound/hallucinations/im_here2.ogg', + 'sound/hallucinations/i_see_you1.ogg', + 'sound/hallucinations/i_see_you2.ogg', + 'sound/hallucinations/look_up1.ogg', + 'sound/hallucinations/look_up2.ogg', + 'sound/hallucinations/over_here1.ogg', + 'sound/hallucinations/over_here2.ogg', + 'sound/hallucinations/over_here3.ogg', + 'sound/hallucinations/turn_around1.ogg', + 'sound/hallucinations/turn_around2.ogg', + 'sound/hallucinations/veryfar_noise.ogg', + 'sound/hallucinations/wail.ogg' + ) + return imagined_sounds diff --git a/code/modules/hallucinations/hallucination_spiderbabies.dm b/code/modules/hallucinations/hallucination_spiderbabies.dm new file mode 100644 index 00000000000..f7b4b3bb94a --- /dev/null +++ b/code/modules/hallucinations/hallucination_spiderbabies.dm @@ -0,0 +1,11 @@ +//Spiders in your body +/datum/hallucination/spiderbabies + min_power = 40 + +/datum/hallucination/spiderbabies/start() + . = ..() + var/list/limbs = holder.get_external_organs() + if(!LAZYLEN(limbs)) + return + var/obj/O = pick(limbs) + to_chat(holder, SPAN_WARNING("You feel something [pick("moving","squirming","skittering")] inside of your [O.name]!")) diff --git a/code/modules/hallucinations/hallucination_talking.dm b/code/modules/hallucinations/hallucination_talking.dm new file mode 100644 index 00000000000..a472010a2f3 --- /dev/null +++ b/code/modules/hallucinations/hallucination_talking.dm @@ -0,0 +1,41 @@ +//Hearing someone talking to/about you. +/datum/hallucination/talking/can_affect(var/mob/living/victim) + return ..() && (locate(/mob/living) in oview(victim)) + +/datum/hallucination/talking/start() + . = ..() + var/sanity = 5 //even insanity needs some sanity + for(var/mob/living/talker in oview(holder)) + if(talker.stat) + continue + var/message + if(prob(80)) + var/list/names = list() + var/lastname = copytext(holder.real_name, findtext(holder.real_name, " ")+1) + var/firstname = copytext(holder.real_name, 1, findtext(holder.real_name, " ")) + if(lastname) names += lastname + if(firstname) names += firstname + if(!names.len) + names += holder.real_name + var/add = prob(20) ? ", [pick(names)]" : "" + var/list/phrases = list("[prob(50) ? "Hey, " : ""][pick(names)]!","[prob(50) ? "Hey, " : ""][pick(names)]?","Get out[add]!","Go away[add].","What are you doing[add]?","Where's your ID[add]?") + if(holder.hallucination_power > 50) + phrases += list("What did you come here for[add]?","Don't touch me[add].","You're not getting out of here[add].", "You are a failure, [pick(names)].","Just kill yourself already, [pick(names)].","Put on some clothes[add].","Take off your clothes[add].") + message = pick(phrases) + to_chat(holder,"[talker.name] [holder.say_quote(message)], \"[message]\"") + else + to_chat(holder,"[talker.name] points at [holder.name]") + to_chat(holder,"[talker.name] says something softly.") + + var/speech_state = holder.check_speech_punctuation_state(message) + if(speech_state) + var/image/speech_bubble = image('icons/mob/talk.dmi', talker, speech_state) + addtimer(CALLBACK(src, PROC_REF(qdel_image), speech_bubble), 3 SECONDS) + show_image(holder, speech_bubble) + + sanity-- //don't spam them in very populated rooms. + if(!sanity) + break + +/datum/hallucination/talking/proc/qdel_image(var/image/speech_bubble) + qdel(speech_bubble) diff --git a/code/modules/hallucinations/hallucination_telepathy.dm b/code/modules/hallucinations/hallucination_telepathy.dm new file mode 100644 index 00000000000..36a982c5a36 --- /dev/null +++ b/code/modules/hallucinations/hallucination_telepathy.dm @@ -0,0 +1,42 @@ +//Fake telepathy +/datum/hallucination/telepathy + allow_duplicates = 0 + duration = 20 MINUTES + +/datum/hallucination/telepathy/start() + . = ..() + to_chat(holder, SPAN_NOTICE("You expand your mind outwards.")) + holder.verbs += /mob/living/carbon/human/proc/fakeremotesay + +/datum/hallucination/telepathy/end() + . = ..() + if(holder) + holder.verbs -= /mob/living/carbon/human/proc/fakeremotesay + +/mob/living/carbon/human/proc/fakeremotesay() + set name = "Telepathic Message" + set category = "Superpower" + + if(!hallucination_power) + src.verbs -= /mob/living/carbon/human/proc/fakeremotesay + return + + if(stat) + to_chat(usr, SPAN_WARNING("You're not in any state to use your powers right now!")) + return + + if(has_chemical_effect(CE_MIND, 1)) + to_chat(usr, SPAN_WARNING("Chemicals in your blood prevent you from using your power!")) + + var/list/creatures = list() + for(var/mob/living/carbon/C in SSmobs.mob_list) + creatures += C + creatures -= usr + var/mob/target = input("Who do you want to project your mind to?") as null|anything in creatures + if (isnull(target)) + return + + var/msg = sanitize(input(usr, "What do you wish to transmit")) + show_message(SPAN_NOTICE("You project your mind into [target.name]: \"[msg]\"")) + if(!stat && prob(20)) + say(msg) diff --git a/code/modules/holidays/_holiday.dm b/code/modules/holidays/_holiday.dm index 8e64c191437..ed04429c955 100644 --- a/code/modules/holidays/_holiday.dm +++ b/code/modules/holidays/_holiday.dm @@ -25,10 +25,8 @@ var/global/datum/holiday/current_holiday /proc/set_holiday_data(var/datum/holiday/holiday_data, var/refresh_station_name = FALSE) if(istext(holiday_data)) holiday_data = new(list("name" = holiday_data)) - if(!holiday_data || !istype(holiday_data)) - return - global.current_holiday = holiday_data + if(istype(holiday_data)) + global.current_holiday = holiday_data if(refresh_station_name) - global.using_map.station_name = null - station_name() + global.using_map.station_name = initial(global.using_map.station_name) world.update_status() diff --git a/code/modules/holidays/holiday_hook.dm b/code/modules/holidays/holiday_hook.dm index 766ef3fb3b7..6b6870c5bb0 100644 --- a/code/modules/holidays/holiday_hook.dm +++ b/code/modules/holidays/holiday_hook.dm @@ -1,27 +1,37 @@ -//Uncommenting ALLOW_HOLIDAYS in config.txt will enable this hook. +//Uncommenting ALLOW_HOLIDAYS in configuration will enable this hook. /hook/startup/proc/updateHoliday() - if(config?.allow_holidays) - var/list/holidays = cached_json_decode(safe_file2text("config/holidays.json"), FALSE) - if(length(holidays)) - - var/c_year = text2num(time2text(world.timeofday, "YY")) - var/c_month = text2num(time2text(world.timeofday, "MM")) - var/c_day = text2num(time2text(world.timeofday, "DD")) - var/c_weekday = lowertext(time2text(world.timeofday, "DDD")) - - for(var/list/holiday_data in holidays) - - var/h_year = holiday_data["year"] - var/h_month = holiday_data["month"] - var/h_day = holiday_data["day"] - var/h_weekday = holiday_data["weekday"] - - if((isnull(h_year) || h_year == c_year) && \ - (isnull(h_month) || h_month == c_month) && \ - (isnull(h_day) || h_day == c_day) && \ - (isnull(h_weekday) || h_weekday == c_weekday)) - var/holiday_path = text2path(holiday_data["path"]) || /datum/holiday - set_holiday_data(new holiday_path(holiday_data)) - break - - return 1 \ No newline at end of file + update_holiday() + return TRUE + +/proc/update_holiday() + + if(!get_config_value(/decl/config/toggle/allow_holidays)) + set_holiday_data(null, TRUE) + return FALSE + + var/list/holidays = cached_json_decode(safe_file2text("config/holidays.json"), FALSE) + if(!length(holidays)) + set_holiday_data(null, TRUE) + return FALSE + + var/c_year = text2num(time2text(world.timeofday, "YY")) + var/c_month = text2num(time2text(world.timeofday, "MM")) + var/c_day = text2num(time2text(world.timeofday, "DD")) + var/c_weekday = lowertext(time2text(world.timeofday, "DDD")) + + for(var/list/holiday_data in holidays) + + var/h_year = holiday_data["year"] + var/h_month = holiday_data["month"] + var/h_day = holiday_data["day"] + var/h_weekday = holiday_data["weekday"] + + if((isnull(h_year) || h_year == c_year) && \ + (isnull(h_month) || h_month == c_month) && \ + (isnull(h_day) || h_day == c_day) && \ + (isnull(h_weekday) || h_weekday == c_weekday)) + var/holiday_path = text2path(holiday_data["path"]) || /datum/holiday + set_holiday_data(new holiday_path(holiday_data)) + return TRUE + + return FALSE diff --git a/code/modules/holidays/holiday_name.dm b/code/modules/holidays/holiday_name.dm index b682a49162a..e07e9776a40 100644 --- a/code/modules/holidays/holiday_name.dm +++ b/code/modules/holidays/holiday_name.dm @@ -5,11 +5,13 @@ set category = "Fun" set desc = "Override the default holiday." - if(!check_rights(R_SERVER)) + if(!check_rights(R_SERVER)) return T = sanitize(T, MAX_NAME_LEN) if(T) + if(get_config_value(/decl/config/toggle/allow_holidays)) + set_config_value(/decl/config/toggle/allow_holidays, TRUE) set_holiday_data(T, refresh_station_name = TRUE) to_world("

    [global.current_holiday.announcement]

    ") message_admins(SPAN_NOTICE("ADMIN: Event: [key_name(src)] force-set the holiday to \"[global.current_holiday.name]\"")) diff --git a/code/modules/holomap/holomap.dm b/code/modules/holomap/holomap.dm index cf7e9128bbe..7e1726ab94f 100644 --- a/code/modules/holomap/holomap.dm +++ b/code/modules/holomap/holomap.dm @@ -13,7 +13,7 @@ construct_state = /decl/machine_construction/default/panel_closed base_type = /obj/machinery/holomap layer = ABOVE_WINDOW_LAYER // Above windows. - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/light_power_on = 1 var/light_range_on = 2 @@ -99,8 +99,8 @@ user.client.images |= holomap_datum.station_map watching_mob = user - events_repository.register(/decl/observ/moved, watching_mob, src, /obj/machinery/holomap/proc/checkPosition) - events_repository.register(/decl/observ/destroyed, watching_mob, src, /obj/machinery/holomap/proc/stopWatching) + events_repository.register(/decl/observ/moved, watching_mob, src, TYPE_PROC_REF(/obj/machinery/holomap, checkPosition)) + events_repository.register(/decl/observ/destroyed, watching_mob, src, TYPE_PROC_REF(/obj/machinery/holomap, stopWatching)) update_use_power(POWER_USE_ACTIVE) if(bogus) @@ -124,7 +124,7 @@ if(watching_mob.client) animate(holomap_datum.station_map, alpha = 0, time = 5, easing = LINEAR_EASING) var/mob/M = watching_mob - addtimer(CALLBACK(src, .proc/clear_image, M, holomap_datum.station_map), 5, TIMER_CLIENT_TIME)//we give it time to fade out + addtimer(CALLBACK(src, PROC_REF(clear_image), M, holomap_datum.station_map), 5, TIMER_CLIENT_TIME)//we give it time to fade out events_repository.unregister(/decl/observ/moved, watching_mob, src) events_repository.unregister(/decl/observ/destroyed, watching_mob, src) watching_mob = null diff --git a/code/modules/hydroponics/beekeeping/beehive.dm b/code/modules/hydroponics/beekeeping/beehive.dm index 2ae979cefab..59f47400117 100644 --- a/code/modules/hydroponics/beekeeping/beehive.dm +++ b/code/modules/hydroponics/beekeeping/beehive.dm @@ -212,7 +212,7 @@ return var/obj/item/chems/glass/G = I var/transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, honey) - G.reagents.add_reagent(/decl/material/liquid/nutriment/honey, transferred) + G.add_to_reagents(/decl/material/liquid/nutriment/honey, transferred) honey -= transferred user.visible_message("\The [user] collects honey from \the [src] into \the [G].", "You collect [transferred] units of honey from \the [src] into \the [G].") return 1 diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index e82d24705fe..0d277530868 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -57,7 +57,7 @@ rtotal += round(potency/reagent_amounts[2]) if(rid == /decl/material/liquid/nutriment) LAZYSET(data, seed.seed_name, max(1,rtotal)) - reagents.add_reagent(rid,max(1,rtotal),data) + add_to_reagents(rid,max(1,rtotal),data) /obj/item/chems/food/grown/proc/update_desc() set waitfor = FALSE @@ -254,7 +254,7 @@ var/global/list/_wood_materials = list( if(seed && seed.get_trait(TRAIT_STINGS)) if(!reagents || reagents.total_volume <= 0) return - reagents.remove_any(rand(1,3)) + remove_any_reagents(rand(1,3)) seed.thrown_at(src, target) sleep(-1) if(!src) @@ -312,7 +312,7 @@ var/global/list/_wood_materials = list( return if(!reagents || reagents.total_volume <= 0) return - reagents.remove_any(rand(1,3)) //Todo, make it actually remove the reagents the seed uses. + remove_any_reagents(rand(1,3)) //Todo, make it actually remove the reagents the seed uses. var/affected = pick(BP_R_HAND,BP_L_HAND) seed.do_thorns(H,src,affected) seed.do_sting(H,src,affected) diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index e2798fffd15..b555a1f42f0 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -33,7 +33,7 @@ var/rtotal = reagent_data[1] if(reagent_data.len > 1 && potency > 0) rtotal += round(potency/reagent_data[2]) - reagents.add_reagent(rid,max(1,rtotal)) + add_to_reagents(rid,max(1,rtotal)) /obj/item/corncob name = "corn cob" diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 3a359e1582e..36d31cf6245 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -189,7 +189,7 @@ to_chat(target, "You are stung by \the [fruit] in your [affecting.name]!") for(var/rid in chems) var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/5)) - target.reagents.add_reagent(rid,injecting) + target.add_to_reagents(rid,injecting) else to_chat(target, "Sharp spines scrape against your armour!") @@ -270,7 +270,7 @@ origin_turf.visible_message(SPAN_DANGER("\The [thrown] splatters against [target]!")) splatter(origin_turf,thrown) -/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only) +/datum/seed/proc/handle_plant_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only) var/health_change = 0 // Handle gas consumption. @@ -726,33 +726,41 @@ total_yield = max(1,total_yield) . = list() - for(var/i = 0;i 0) + var/using_yield = min(remaining_yield, per_stack) + remaining_yield -= using_yield + . += new product_type(get_turf(user), using_yield) + else + for(var/i = 1 to total_yield) + var/obj/item/product = new product_type(get_turf(user),name) + . += product - if(get_trait(TRAIT_PRODUCT_COLOUR)) - if(istype(product, /obj/item/chems/food)) + if(get_trait(TRAIT_PRODUCT_COLOUR) && istype(product, /obj/item/chems/food)) var/obj/item/chems/food/snack = product snack.color = get_trait(TRAIT_PRODUCT_COLOUR) snack.filling_color = get_trait(TRAIT_PRODUCT_COLOUR) - if(mysterious) - product.name += "?" - product.desc += " On second thought, something about this one looks strange." - - if(get_trait(TRAIT_BIOLUM)) - var/clr - if(get_trait(TRAIT_BIOLUM_COLOUR)) - clr = get_trait(TRAIT_BIOLUM_COLOUR) - product.set_light(get_trait(TRAIT_BIOLUM), l_color = clr) - - //Handle spawning in living, mobile products. - if(isliving(product)) - product.visible_message("The pod disgorges [product]!") - handle_living_product(product) - if(istype(product,/mob/living/simple_animal/mushroom)) // Gross. - var/mob/living/simple_animal/mushroom/mush = product - mush.seed = src + if(mysterious) + product.name += "?" + product.desc += " On second thought, something about this one looks strange." + + if(get_trait(TRAIT_BIOLUM)) + var/clr + if(get_trait(TRAIT_BIOLUM_COLOUR)) + clr = get_trait(TRAIT_BIOLUM_COLOUR) + product.set_light(get_trait(TRAIT_BIOLUM), l_color = clr) + + //Handle spawning in living, mobile products. + if(isliving(product)) + product.visible_message("The pod disgorges [product]!") + handle_living_product(product) + if(istype(product,/mob/living/simple_animal/mushroom)) // Gross. + var/mob/living/simple_animal/mushroom/mush = product + mush.seed = src // When the seed in this machine mutates/is modified, the tray seed value // is set to a new datum copied from the original. This datum won't actually diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index cbaff15b1d7..be90c0b767c 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -536,6 +536,10 @@ display_name = "towercap thicket" chems = list(/decl/material/solid/organic/wood = list(10,1)) mutants = null + product_type = /obj/item/stack/material/log/towercap + +/obj/item/stack/material/log/towercap + material = /decl/material/solid/organic/wood/fungal /datum/seed/mushroom/towercap/New() ..() diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index 770a7b64168..6125017277d 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -43,10 +43,10 @@ return //Take damage from bad environment if any - adjust_health(-seed.handle_environment(T,T.return_air(),null,1)) + adjust_health(-seed.handle_plant_environment(T,T.return_air(),null,1)) if(health <= 0) return - + //Vine fight! for(var/obj/effect/vine/other in T) if(other.seed != seed) @@ -76,7 +76,7 @@ var/list/neighbors = get_neighbors() if(neighbors.len) spread_to(pick(neighbors)) - + //Try to settle down if(can_spawn_plant()) plant = new(T,seed) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm index b308e466061..5065d15e7eb 100644 --- a/code/modules/hydroponics/trays/tray_process.dm +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -84,9 +84,9 @@ // Seed datum handles gasses, light and pressure. if(mechanical && closed_system) - plant_health -= seed.handle_environment(T,environment,tray_light) + plant_health -= seed.handle_plant_environment(T,environment,tray_light) else - plant_health -= seed.handle_environment(T,environment) + plant_health -= seed.handle_plant_environment(T,environment) // If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses if (closed_system && get_port()) diff --git a/code/modules/integrated_electronics/core/prefab/prefabs.dm b/code/modules/integrated_electronics/core/prefab/prefabs.dm index 6a8663042e0..0efa5181a66 100644 --- a/code/modules/integrated_electronics/core/prefab/prefabs.dm +++ b/code/modules/integrated_electronics/core/prefab/prefabs.dm @@ -1,6 +1,6 @@ /decl/prefab/ic_assembly/hand_teleporter assembly_name = "hand-teleporter" - data = {"{'assembly':{'type':'type-a electronic mechanism','name':'Hand Teleporter', 'detail_color':'#5d99be'},'components':\[{'type':'teleporter locator'},{'type':'wormhole generator'},{'type':'button','name':'Open Wormhole'}\],'wires':\[\[\[1,'O',1\],\[2,'I',1\]\],\[\[2,'A',1\],\[3,'A',1\]\]\]}"} + data = @'{"assembly":{"type":"type-a electronic mechanism","name":"Hand Teleporter", "detail_color":"#5d99be"},"components":[{"type":"teleporter locator"},{"type":"wormhole generator"},{"type":"button","name":"Open Wormhole"}],"wires":[[[1,"O",1],[2,"I",1]],[[2,"A",1],[3,"A",1]]]}' power_cell_type = /obj/item/cell/hyper /obj/prefab/hand_teleporter diff --git a/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm b/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm index b58cf8d309e..c045f16f4a6 100644 --- a/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm +++ b/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm @@ -1,6 +1,6 @@ /decl/prefab/ic_assembly/test_heatercooler assembly_name = "heating-cooling-test" - data = {"{'assembly':{'type':'type-c electronic machine'},'components':\[{'type':'starter'},{'type':'reagent funnel'},{'type':'big reagent storage'},{'type':'reagent pump','name':'Hot Pump','inputs':\[\[3,0,5]]},{'type':'reagent pump','name':'Cool Pump','inputs':\[\[3,0,5]]},{'type':'reagent heater','name':'Heater','inputs':\[\[1,0,80]]},{'type':'reagent cooler','name':'Cooler','inputs':\[\[1,0,-50]]},{'type':'button','name':'Heat And Cool'},{'type':'and gate','name':'Heater Active Check','inputs':\[\[1,0,0],\[2,0,1]]},{'type':'and gate','name':'Cooler Active Check','inputs':\[\[1,0,0],\[2,0,1]]},{'type':'custom delay circuit','name':'Heater Delay','inputs':\[\[1,0,100]]},{'type':'custom delay circuit','name':'Cooler Delay','inputs':\[\[1,0,100]]}],'wires':\[\[\[1,'A',1],\[3,'A',1]],\[\[1,'A',1],\[6,'A',3]],\[\[1,'A',1],\[7,'A',3]],\[\[2,'I',1],\[3,'O',2]],\[\[3,'O',2],\[4,'I',1]],\[\[3,'O',2],\[5,'I',1]],\[\[4,'I',2],\[6,'O',4]],\[\[4,'A',1],\[8,'A',1]],\[\[4,'A',2],\[6,'A',1]],\[\[5,'I',2],\[7,'O',4]],\[\[5,'A',1],\[8,'A',1]],\[\[5,'A',2],\[7,'A',1]],\[\[6,'O',3],\[9,'I',1]],\[\[6,'A',1],\[11,'A',2]],\[\[6,'A',2],\[9,'A',1]],\[\[7,'O',3],\[10,'I',1]],\[\[7,'A',1],\[12,'A',2]],\[\[7,'A',2],\[10,'A',1]],\[\[9,'A',2],\[11,'A',1]],\[\[10,'A',2],\[12,'A',1]]]}"} + data = @'{"assembly":{"type":"type-c electronic machine"},"components":[{"type":"starter"},{"type":"reagent funnel"},{"type":"big reagent storage"},{"type":"reagent pump","name":"Hot Pump","inputs":[[3,0,5]]},{"type":"reagent pump","name":"Cool Pump","inputs":[[3,0,5]]},{"type":"reagent heater","name":"Heater","inputs":[[1,0,80]]},{"type":"reagent cooler","name":"Cooler","inputs":[[1,0,-50]]},{"type":"button","name":"Heat And Cool"},{"type":"and gate","name":"Heater Active Check","inputs":[[1,0,0],[2,0,1]]},{"type":"and gate","name":"Cooler Active Check","inputs":[[1,0,0],[2,0,1]]},{"type":"custom delay circuit","name":"Heater Delay","inputs":[[1,0,100]]},{"type":"custom delay circuit","name":"Cooler Delay","inputs":[[1,0,100]]}],"wires":[[[1,"A",1],[3,"A",1]],[[1,"A",1],[6,"A",3]],[[1,"A",1],[7,"A",3]],[[2,"I",1],[3,"O",2]],[[3,"O",2],[4,"I",1]],[[3,"O",2],[5,"I",1]],[[4,"I",2],[6,"O",4]],[[4,"A",1],[8,"A",1]],[[4,"A",2],[6,"A",1]],[[5,"I",2],[7,"O",4]],[[5,"A",1],[8,"A",1]],[[5,"A",2],[7,"A",1]],[[6,"O",3],[9,"I",1]],[[6,"A",1],[11,"A",2]],[[6,"A",2],[9,"A",1]],[[7,"O",3],[10,"I",1]],[[7,"A",1],[12,"A",2]],[[7,"A",2],[10,"A",1]],[[9,"A",2],[11,"A",1]],[[10,"A",2],[12,"A",1]]]}' power_cell_type = /obj/item/cell/hyper /obj/prefab/test_heatcool diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 225ba85d98b..8a33268251d 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -156,7 +156,7 @@ HTML += jointext(dat, "; ") HTML += ".

    " - if(config.allow_ic_printing || debug) + if(get_config_value(/decl/config/toggle/on/allow_ic_printing) || debug) HTML += "Assembly cloning: [can_clone ? (fast_clone ? "Instant" : "Available") : "Unavailable"].
    " HTML += "Circuits available: [upgraded || debug ? "Advanced":"Regular"]." @@ -164,7 +164,7 @@ HTML += "
    Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit." HTML += "
    " - if((can_clone && config.allow_ic_printing) || debug) + if((can_clone && get_config_value(/decl/config/toggle/on/allow_ic_printing)) || debug) HTML += "Here you can load script for your assembly.
    " if(!cloning) HTML += " {Load Program} " @@ -237,7 +237,7 @@ playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) if(href_list["print"]) - if(!config.allow_ic_printing && !debug) + if(!get_config_value(/decl/config/toggle/on/allow_ic_printing) && !debug) to_chat(usr, "Your facility has disabled printing of custom circuitry due to recent allegations of copyright infringement.") return if(!can_clone) // Copying and printing ICs is cloning @@ -302,7 +302,7 @@ to_chat(usr, "You begin printing a custom assembly. This will take approximately [round(cloning_time/10)] seconds. You can still print \ off normal parts during this time.") playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE) - addtimer(CALLBACK(src, .proc/print_program, usr), cloning_time) + addtimer(CALLBACK(src, PROC_REF(print_program), usr), cloning_time) if("cancel") if(!cloning || !program) @@ -332,16 +332,16 @@ desc = "Install this into your integrated circuit printer to enhance it." color = COLOR_GRAY20 label = "label_up" - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/disk/integrated_circuit/upgrade/advanced name = "integrated circuit printer upgrade disk - advanced designs" desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer." material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'materials':3,'engineering':3}" + origin_tech = @'{"materials":3,"engineering":3}' /obj/item/disk/integrated_circuit/upgrade/clone name = "integrated circuit printer upgrade disk - instant cloner" desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies instantaneously." - origin_tech = "{'materials':3,'programming':5}" + origin_tech = @'{"materials":3,"programming":5}' diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm index 30b0a1895d2..f7543de2f40 100644 --- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm @@ -31,13 +31,7 @@ /datum/integrated_io/color/scramble() if(!is_valid()) return - var/new_data - for(var/i=1;i<=3;i++) - var/temp_col = "[num2hex(rand(0,255))]" - if(length(temp_col )<2) - temp_col = "0[temp_col]" - new_data += temp_col - data = new_data + data = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) push_data() /datum/integrated_io/color/display_pin_type() diff --git a/code/modules/integrated_electronics/core/wirer.dm b/code/modules/integrated_electronics/core/wirer.dm index 3f861b883a7..4b0b6749ca3 100644 --- a/code/modules/integrated_electronics/core/wirer.dm +++ b/code/modules/integrated_electronics/core/wirer.dm @@ -84,7 +84,7 @@ if(selected_io) unselect_io(selected_io) selected_io = io - events_repository.register(/decl/observ/destroyed, selected_io, src, .proc/unselect_io) + events_repository.register(/decl/observ/destroyed, selected_io, src, PROC_REF(unselect_io)) switch(mode) if(UNWIRE) mode = UNWIRING diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 8b97ab6d817..941506bf775 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -122,18 +122,18 @@ /obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change(changetype) ..() - set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + set_pin_data(IC_OUTPUT, 1, reagents?.total_volume || 0) push_data() /obj/item/integrated_circuit/passive/power/chemical_cell/make_energy() if(assembly) if(assembly.battery) var/battery_charge = 5000 - if((assembly.battery.maxcharge-assembly.battery.charge) / CELLRATE > battery_charge && reagents.remove_reagent(/decl/material/liquid/blood, 1)) //only blood is powerful enough to power the station(c) + if((assembly.battery.maxcharge-assembly.battery.charge) / CELLRATE > battery_charge && remove_from_reagents(/decl/material/liquid/blood, 1)) //only blood is powerful enough to power the station(c) assembly.give_power(battery_charge) for(var/I in fuel) if((assembly.battery.maxcharge-assembly.battery.charge) / CELLRATE > fuel[I]) - if(reagents.remove_reagent(I, 1)) + if(remove_from_reagents(I, 1)) assembly.give_power(fuel[I]*multi) /obj/item/integrated_circuit/passive/power/chemical_cell/do_work() diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 50b2868c289..b6401404172 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -648,7 +648,7 @@ . = ..() set_pin_data(IC_INPUT, 1, frequency) set_pin_data(IC_INPUT, 2, code) - addtimer(CALLBACK(src, .proc/set_frequency,frequency), 40) + addtimer(CALLBACK(src, PROC_REF(set_frequency),frequency), 40) /obj/item/integrated_circuit/input/signaler/Destroy() radio_controller.remove_object(src,frequency) diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index a75e68f68b8..a1213df5387 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -111,7 +111,7 @@ //Shooting Code: A.shot_from = assembly.name A.firer = assembly - A.launch(target, BP_CHEST) + A.launch(target) return A /obj/item/integrated_circuit/manipulation/locomotion @@ -207,7 +207,7 @@ dt = clamp(detonation_time.data, 1, 12)*10 else dt = 15 - addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/activate), dt) + addtimer(CALLBACK(attached_grenade, TYPE_PROC_REF(/obj/item/grenade, activate)), dt) var/atom/holder = loc log_and_message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") @@ -420,9 +420,9 @@ set_pin_data(IC_OUTPUT, 1, TRUE) pulling = to_pull acting_object.visible_message("\The [acting_object] starts pulling \the [to_pull] around.") - events_repository.register(/decl/observ/moved, to_pull, src, .proc/check_pull) //Whenever the target moves, make sure we can still pull it! - events_repository.register(/decl/observ/destroyed, to_pull, src, .proc/stop_pulling) //Stop pulling if it gets destroyed - events_repository.register(/decl/observ/moved, acting_object, src, .proc/pull) //Make sure we actually pull it. + events_repository.register(/decl/observ/moved, to_pull, src, PROC_REF(check_pull)) //Whenever the target moves, make sure we can still pull it! + events_repository.register(/decl/observ/destroyed, to_pull, src, PROC_REF(stop_pulling)) //Stop pulling if it gets destroyed + events_repository.register(/decl/observ/moved, acting_object, src, PROC_REF(pull)) //Make sure we actually pull it. push_data() if(3) if(pulling) @@ -555,7 +555,7 @@ spawn_flags = IC_SPAWN_RESEARCH action_flags = IC_ACTION_LONG_RANGE - origin_tech = "{'magnets':1,'wormholes':3}" + origin_tech = @'{"magnets":1,"wormholes":3}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, @@ -606,7 +606,7 @@ power_draw_per_use = 20 var/obj/item/aicard activators = list("Upwards" = IC_PINTYPE_PULSE_OUT, "Downwards" = IC_PINTYPE_PULSE_OUT, "Left" = IC_PINTYPE_PULSE_OUT, "Right" = IC_PINTYPE_PULSE_OUT) - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' spawn_flags = IC_SPAWN_RESEARCH /obj/item/integrated_circuit/manipulation/ai/verb/open_menu() @@ -654,7 +654,7 @@ /obj/item/integrated_circuit/manipulation/ai/attackby(var/obj/item/I, var/mob/user) - if(is_type_in_list(I, list(/obj/item/aicard, /obj/item/paicard, /obj/item/mmi))) + if(is_type_in_list(I, list(/obj/item/aicard, /obj/item/paicard, /obj/item/organ/internal/brain_interface))) load_ai(user, I) else return ..() @@ -681,7 +681,7 @@ cooldown_per_use = 2 SECOND power_draw_per_use = 50 spawn_flags = IC_SPAWN_DEFAULT - origin_tech = "{'engineering':2}" + origin_tech = @'{"engineering":2}' /obj/item/integrated_circuit/manipulation/anchoring/do_work(ord) if(!isturf(assembly.loc)) @@ -724,7 +724,7 @@ cooldown_per_use = 2 SECOND power_draw_per_use = 50 spawn_flags = IC_SPAWN_DEFAULT - origin_tech = "{'engineering':2}" + origin_tech = @'{"engineering":2}' var/lock_enabled = FALSE diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index e6a1fc9f7cc..8ecd8e477b2 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -19,7 +19,7 @@ push_vol() /obj/item/integrated_circuit/reagent/proc/push_vol() - set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + set_pin_data(IC_OUTPUT, 1, reagents?.total_volume || 0) push_data() /obj/item/integrated_circuit/reagent/smoke @@ -49,7 +49,7 @@ var/smoke_radius = 5 var/notified = FALSE -/obj/item/integrated_circuit/reagent/smoke/on_reagent_change() +/obj/item/integrated_circuit/reagent/on_reagent_change() ..() push_vol() @@ -109,10 +109,6 @@ var/transfer_amount = 10 var/busy = FALSE -/obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype) - ..() - push_vol() - /obj/item/integrated_circuit/reagent/injector/on_data_written() var/new_amount = get_pin_data(IC_INPUT, 2) if(new_amount < 0) @@ -199,7 +195,7 @@ L.visible_message("\The [acting_object] is trying to inject [L]!", \ "\The [acting_object] is trying to inject you!") busy = TRUE - addtimer(CALLBACK(src, .proc/inject_after, weakref(L)), injection_delay) + addtimer(CALLBACK(src, PROC_REF(inject_after), weakref(L)), injection_delay) return else if(!ATOM_IS_OPEN_CONTAINER(AM)) @@ -229,7 +225,7 @@ C.visible_message("\The [acting_object] is trying to take a blood sample from [C]!", \ "\The [acting_object] is trying to take a blood sample from you!") busy = TRUE - addtimer(CALLBACK(src, .proc/draw_after, weakref(C), tramount), injection_delay) + addtimer(CALLBACK(src, PROC_REF(draw_after), weakref(C), tramount), injection_delay) return else @@ -324,10 +320,6 @@ set_pin_data(IC_OUTPUT, 2, weakref(src)) push_data() -/obj/item/integrated_circuit/reagent/storage/on_reagent_change(changetype) - ..() - push_vol() - /obj/item/integrated_circuit/reagent/storage/big name = "big reagent storage" icon_state = "reagent_storage_big" @@ -600,10 +592,6 @@ set_pin_data(IC_OUTPUT, 4, weakref(src)) push_data() -/obj/item/integrated_circuit/reagent/temp/on_reagent_change() - ..() - push_vol() - /obj/item/integrated_circuit/reagent/temp/power_fail() active = 0 diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 9012de5054c..25f9dca52a4 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -119,7 +119,7 @@ if(Pl&&islist(Pl)) idc.access = Pl var/turf/a_loc = get_turf(assembly) - var/list/P = AStar(a_loc, locate(get_pin_data(IC_INPUT, 1), get_pin_data(IC_INPUT, 2), a_loc.z), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT, 3, /atom))) + var/list/P = AStar(a_loc, locate(get_pin_data(IC_INPUT, 1), get_pin_data(IC_INPUT, 2), a_loc.z), TYPE_PROC_REF(/turf, CardinalTurfsWithAccess), TYPE_PROC_REF(/turf, Distance), 0, 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT, 3, /atom))) if(!P) activate_pin(3) diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index 1ec0d80676f..c9739ceed0a 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -17,7 +17,7 @@ power_draw_per_use = 2 /obj/item/integrated_circuit/time/delay/do_work() - addtimer(CALLBACK(src, .proc/activate_pin, 2), delay) + addtimer(CALLBACK(src, PROC_REF(activate_pin), 2), delay) /obj/item/integrated_circuit/time/delay/five_sec name = "five-sec delay circuit" @@ -98,7 +98,7 @@ /obj/item/integrated_circuit/time/ticker/proc/tick() if(is_running) - addtimer(CALLBACK(src, .proc/tick), delay) + addtimer(CALLBACK(src, PROC_REF(tick)), delay) if(world.time > next_fire) next_fire = world.time + delay activate_pin(1) diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm index 527e5a11598..6fe32e00f0e 100644 --- a/code/modules/keybindings/bindings_atom.dm +++ b/code/modules/keybindings/bindings_atom.dm @@ -15,7 +15,7 @@ if((movement_dir & EAST) && (movement_dir & WEST)) movement_dir &= ~(EAST|WEST) - if(!config.allow_diagonal_movement) + if(!get_config_value(/decl/config/toggle/allow_diagonal_movement)) if(movement_dir & user.last_move_dir_pressed) movement_dir = user.last_move_dir_pressed else diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index f65e26da951..fb56abe3346 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -37,7 +37,7 @@ if(!(next_move_dir_sub & movement)) next_move_dir_add |= movement - if(movement && !config.allow_diagonal_movement) + if(movement && !get_config_value(/decl/config/toggle/allow_diagonal_movement)) last_move_dir_pressed = movement // Client-level keybindings are ones anyone should be able to do at any time diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 7a22648f25c..36f75134fda 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -136,9 +136,10 @@ // Decompile the hexadecimal colour into lumcounts of each perspective. /datum/light_source/proc/parse_light_color() if (light_color) - lum_r = HEX_RED(light_color) / 255 - lum_g = HEX_GREEN(light_color) / 255 - lum_b = HEX_BLUE(light_color) / 255 + var/list/color_list = rgb2num(light_color) + lum_r = color_list[1] / 255 + lum_g = color_list[2] / 255 + lum_b = color_list[3] / 255 else lum_r = 1 lum_g = 1 diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 912a673d3ad..761ea49d37f 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -155,7 +155,7 @@ lum_g = CLAMP01(lum_g / 4) * 255 lum_b = CLAMP01(lum_b / 4) * 255 - return "#[num2hex(lum_r, 2)][num2hex(lum_g, 2)][num2hex(lum_g, 2)]" + return rgb(lum_r, lum_b, lum_g) #define SCALE(targ,min,max) (targ - min) / (max - min) diff --git a/code/modules/locks/key.dm b/code/modules/locks/key.dm index b4ded50c995..656d36edd07 100644 --- a/code/modules/locks/key.dm +++ b/code/modules/locks/key.dm @@ -6,25 +6,30 @@ w_class = ITEM_SIZE_TINY material = /decl/material/solid/metal/brass material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC - var/key_data = "" - -/obj/item/key/Initialize(var/mapload, var/material_key, var/new_key_data) - . = ..(mapload, material_key) - if(new_key_data) - key_data = new_key_data + var/key_data /obj/item/key/proc/get_data(var/mob/user) return key_data -/obj/item/key/soap +/obj/item/key/Initialize(mapload, material_key, _data) + . = ..(mapload, material_key) + key_data = _data + +/obj/item/key/temporary + name = "key" + desc = "A fragile key with limited uses." material = /decl/material/liquid/cleaner/soap var/uses = 0 -/obj/item/key/soap/get_data(var/mob/user) +/obj/item/key/temporary/Initialize(mapload, material_key, _data, _uses) + . = ..(mapload, material_key, _data) + uses = _uses + +/obj/item/key/temporary/get_data(var/mob/user) uses-- if(uses == 1) - to_chat(user, "\The [src] is going to break soon!") + to_chat(user, SPAN_DANGER("\The [src] is going to break soon!")) else if(uses <= 0) - to_chat(user, "\The [src] crumbles in your hands.") + to_chat(user, SPAN_DANGER("\The [src] crumbles in your hands.")) qdel(src) return ..() diff --git a/code/modules/locks/lock.dm b/code/modules/locks/lock.dm index efe2d0920d3..c288c676395 100644 --- a/code/modules/locks/lock.dm +++ b/code/modules/locks/lock.dm @@ -39,10 +39,7 @@ return 0 /datum/lock/proc/toggle(var/key = "", var/mob/user) - if(status & LOCK_LOCKED) - return unlock(key, user) - else - return lock(key, user) + return (status & LOCK_LOCKED) ? unlock(key, user) : lock(key, user) /datum/lock/proc/getComplexity() return length(lock_data) diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index 819e05abeb2..a0de484be9a 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -27,6 +27,8 @@ var/template_parent_type = /datum/map_template ///The initial type of level_data to instantiate new z-level with initially. (Is replaced by whatever is in the map file.) If null, will use default. var/level_data_type + /// Various tags used for selecting templates for placement on a map. + var/template_tags = 0 /datum/map_template/New(var/created_ad_hoc) if(created_ad_hoc != SSmapping.type) @@ -43,8 +45,8 @@ /datum/map_template/proc/get_template_cost() return 0 -/datum/map_template/proc/get_ruin_tags() - return 0 +/datum/map_template/proc/get_template_tags() + return template_tags /datum/map_template/proc/preload_size() var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) @@ -99,7 +101,7 @@ for (var/turf/T as anything in turfs) if(template_flags & TEMPLATE_FLAG_NO_RUINS) - T.turf_flags |= TURF_FLAG_NORUINS + T.turf_flags |= TURF_FLAG_NO_POINTS_OF_INTEREST if(template_flags & TEMPLATE_FLAG_NO_RADS) qdel(SSradiation.sources_assoc[T]) if(istype(T,/turf/simulated)) @@ -117,12 +119,12 @@ SSshuttle.map_hash_to_areas[map_hash] = initialized_areas_by_type for(var/area/A in initialized_areas_by_type) A.saved_map_hash = map_hash - events_repository.register(/decl/observ/destroyed, A, src, .proc/cleanup_lateloaded_area) + events_repository.register(/decl/observ/destroyed, A, src, PROC_REF(cleanup_lateloaded_area)) SSshuttle.block_queue = pre_init_state SSshuttle.clear_init_queue() // We will flush the queue unless there were other blockers, in which case they will do it. /datum/map_template/proc/cleanup_lateloaded_area(area/destroyed_area) - events_repository.unregister(/decl/observ/destroyed, destroyed_area, src, .proc/cleanup_lateloaded_area) + events_repository.unregister(/decl/observ/destroyed, destroyed_area, src, PROC_REF(cleanup_lateloaded_area)) if(destroyed_area.saved_map_hash) SSshuttle.map_hash_to_areas[destroyed_area.saved_map_hash] -= destroyed_area diff --git a/code/modules/maps/helper_landmarks.dm b/code/modules/maps/helper_landmarks.dm index 12680e46a76..e8c4a5b7547 100644 --- a/code/modules/maps/helper_landmarks.dm +++ b/code/modules/maps/helper_landmarks.dm @@ -4,8 +4,9 @@ var/centered = TRUE var/list/map_template_names //list of template names to pick from -/obj/abstract/landmark/map_load_mark/New(loc) - ..() +INITIALIZE_IMMEDIATE(/obj/abstract/landmark/map_load_mark) +/obj/abstract/landmark/map_load_mark/Initialize() + . = ..() if(Master.map_loading) // If we're created while a map is being loaded return // Let after_load() handle us if(!SSmapping.initialized) // If we're being created prior to SSmapping @@ -14,11 +15,15 @@ // How did we get here? // These should only be loaded from compiled maps or map templates. PRINT_STACK_TRACE("map_load_mark created outside of maploading") - load_subtemplate() + init_load_subtemplate() /obj/abstract/landmark/map_load_mark/proc/get_subtemplate() . = LAZYLEN(map_template_names) && pick(map_template_names) +/obj/abstract/landmark/map_load_mark/proc/init_load_subtemplate() + set waitfor = FALSE + load_subtemplate() + /obj/abstract/landmark/map_load_mark/proc/load_subtemplate() // Commenting this out temporarily as DMMS breaks when asychronously // loading overlapping map templates. TODO: more robust queuing behavior @@ -98,11 +103,11 @@ /obj/abstract/landmark/delete_on_shuttle/Initialize() . = ..() - events_repository.register_global(/decl/observ/shuttle_added, src, .proc/check_shuttle) + events_repository.register_global(/decl/observ/shuttle_added, src, PROC_REF(check_shuttle)) /obj/abstract/landmark/delete_on_shuttle/proc/check_shuttle(var/shuttle) if(SSshuttle.shuttles[shuttle_name] == shuttle) - events_repository.register(/decl/observ/shuttle_moved, shuttle, src, .proc/delete_everything) + events_repository.register(/decl/observ/shuttle_moved, shuttle, src, PROC_REF(delete_everything)) shuttle_datum = shuttle /obj/abstract/landmark/delete_on_shuttle/proc/delete_everything() @@ -112,9 +117,9 @@ qdel(src) /obj/abstract/landmark/delete_on_shuttle/Destroy() - events_repository.unregister_global(/decl/observ/shuttle_added, src, .proc/check_shuttle) + events_repository.unregister_global(/decl/observ/shuttle_added, src, PROC_REF(check_shuttle)) if(shuttle_datum) - events_repository.unregister(/decl/observ/shuttle_moved, shuttle_datum, src, .proc/delete_everything) + events_repository.unregister(/decl/observ/shuttle_moved, shuttle_datum, src, PROC_REF(delete_everything)) . = ..() // Has a percent chance on spawn to set the specified variable on the specified type to the specified value. diff --git a/code/modules/maps/template_types/random_exoplanet/fauna_generator.dm b/code/modules/maps/template_types/random_exoplanet/fauna_generator.dm index b71e8da04e1..03a66a0da3c 100644 --- a/code/modules/maps/template_types/random_exoplanet/fauna_generator.dm +++ b/code/modules/maps/template_types/random_exoplanet/fauna_generator.dm @@ -100,8 +100,8 @@ /datum/fauna_generator/proc/register_fauna(var/mob/living/A) if(A in live_fauna) return - events_repository.register(/decl/observ/destroyed, A, src, /datum/fauna_generator/proc/on_fauna_death) - events_repository.register(/decl/observ/death, A, src, /datum/fauna_generator/proc/on_fauna_death) + events_repository.register(/decl/observ/destroyed, A, src, TYPE_PROC_REF(/datum/fauna_generator, on_fauna_death)) + events_repository.register(/decl/observ/death, A, src, TYPE_PROC_REF(/datum/fauna_generator, on_fauna_death)) LAZYADD(live_fauna, A) /datum/fauna_generator/proc/on_fauna_death(var/mob/living/A) @@ -111,8 +111,8 @@ /datum/fauna_generator/proc/unregister_fauna(var/mob/living/A) if(!(A in live_fauna)) return - events_repository.unregister(/decl/observ/destroyed, A, src, /datum/fauna_generator/proc/on_fauna_death) - events_repository.unregister(/decl/observ/death, A, src, /datum/fauna_generator/proc/on_fauna_death) + events_repository.unregister(/decl/observ/destroyed, A, src, TYPE_PROC_REF(/datum/fauna_generator, on_fauna_death)) + events_repository.unregister(/decl/observ/death, A, src, TYPE_PROC_REF(/datum/fauna_generator, on_fauna_death)) LAZYREMOVE(live_fauna, A) /datum/fauna_generator/proc/generate_fauna(var/datum/gas_mixture/atmosphere, var/list/breath_gases = list(), var/list/toxic_gases = list()) diff --git a/code/modules/maps/template_types/random_exoplanet/flora_generator.dm b/code/modules/maps/template_types/random_exoplanet/flora_generator.dm index 54765963c41..86fd9fb00fc 100644 --- a/code/modules/maps/template_types/random_exoplanet/flora_generator.dm +++ b/code/modules/maps/template_types/random_exoplanet/flora_generator.dm @@ -94,7 +94,7 @@ ///Spawns a randomly chosen big flora from our big flora seed list. /datum/planet_flora/proc/spawn_random_big_flora(var/turf/T) if(LAZYLEN(big_flora_types)) - . = new /obj/structure/flora/plant(T, null, null, pick(big_flora_types)) + . = new /obj/structure/flora/plant/large(T, null, null, pick(big_flora_types)) //////////////////////////////////////////////////////////////////////// diff --git a/code/modules/maps/template_types/random_exoplanet/planet_themes/_planet_theme.dm b/code/modules/maps/template_types/random_exoplanet/planet_themes/_planet_theme.dm index 152ec2acc61..a15b1f47088 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_themes/_planet_theme.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_themes/_planet_theme.dm @@ -17,9 +17,9 @@ /datum/exoplanet_theme/proc/adapt_animal(var/datum/planetoid_data/E, var/mob/A) -/datum/exoplanet_theme/proc/modify_ruin_whitelist(var/whitelist_flags) +/datum/exoplanet_theme/proc/modify_template_whitelist(var/whitelist_flags) -/datum/exoplanet_theme/proc/modify_ruin_blacklist(var/blacklist_flags) +/datum/exoplanet_theme/proc/modify_template_blacklist(var/blacklist_flags) /datum/exoplanet_theme/proc/get_extra_fauna() diff --git a/code/modules/maps/template_types/random_exoplanet/planet_themes/robotic_guardians.dm b/code/modules/maps/template_types/random_exoplanet/planet_themes/robotic_guardians.dm index 9afd458e5bd..3e8c60a5d1a 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_themes/robotic_guardians.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_themes/robotic_guardians.dm @@ -9,8 +9,8 @@ /mob/living/simple_animal/hostile/hivebot/mega ) -/datum/exoplanet_theme/robotic_guardians/modify_ruin_whitelist(whitelist_flags) - return whitelist_flags | RUIN_ALIEN +/datum/exoplanet_theme/robotic_guardians/modify_template_whitelist(whitelist_flags) + return whitelist_flags | TEMPLATE_TAG_ALIEN /datum/exoplanet_theme/robotic_guardians/get_extra_fauna() return guardian_types diff --git a/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm b/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm index 0decc6d51af..457be8d6f2e 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm @@ -15,8 +15,8 @@ 'sound/ambience/ominous3.ogg' ) -/datum/exoplanet_theme/robotic_guardians/modify_ruin_whitelist(whitelist_flags) - return whitelist_flags | RUIN_ALIEN +/datum/exoplanet_theme/robotic_guardians/modify_template_whitelist(whitelist_flags) + return whitelist_flags | TEMPLATE_TAG_ALIEN /datum/exoplanet_theme/ruined_city/get_map_generators(/datum/planetoid_data/E) return list(/datum/random_map/city) diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm index 5ab3ecef148..bc7d23c4670 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/barren.dm @@ -74,7 +74,7 @@ name = "barren exoplanet" planetoid_data_type = /datum/planetoid_data/random/barren overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/barren - ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER + template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER subtemplate_budget = 6 template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/barren diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm index 6d4412dc972..af4657e33ae 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/chlorine.dm @@ -86,7 +86,7 @@ name = "chlorine exoplanet" planetoid_data_type = /datum/planetoid_data/random/chlorine overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/chlorine - ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER + template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/chlorine prefered_level_data_per_z = list( diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm index 22f216e8a0d..754136c025d 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/meat.dm @@ -90,7 +90,7 @@ name = "organic exoplanet" planetoid_data_type = /datum/planetoid_data/random/meat overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/meat - ruin_tags_blacklist = RUIN_HABITAT|RUIN_HUMAN|RUIN_WATER + template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WATER template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/meat prefered_level_data_per_z = null diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm index 1a7fca53079..4d8a2c0ee70 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm @@ -85,7 +85,7 @@ name = "shrouded exoplanet" planetoid_data_type = /datum/planetoid_data/random/shrouded overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/shrouded - ruin_tags_blacklist = RUIN_HABITAT + template_tags_blacklist = TEMPLATE_TAG_HABITAT template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/shrouded prefered_level_data_per_z = list( diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm index 1fce3f9757d..7b7245cb0dd 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm @@ -91,7 +91,7 @@ planetoid_data_type = /datum/planetoid_data/random/volcanic overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/volcanic max_themes = 1 - ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER + template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER template_parent_type = /datum/map_template/planetoid/random/exoplanet level_data_type = /datum/level_data/planetoid/exoplanet/volcanic prefered_level_data_per_z = list( diff --git a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm index 75a9aaa6ca6..4c9be31e655 100644 --- a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm +++ b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm @@ -379,7 +379,7 @@ /datum/planetoid_data/random/proc/generate_daycycle_data() starts_at_night = (surface_light_level > 0.1) - day_duration = rand(global.config.exoplanet_min_day_duration, global.config.exoplanet_max_day_duration) + day_duration = rand(get_config_value(/decl/config/num/exoplanet_min_day_duration), get_config_value(/decl/config/num/exoplanet_max_day_duration)) MINUTES ///If the planet doesn't have a name defined, a name will be randomly generated for it. (Named this way because a global proc generate_planet_name already exists) /datum/planetoid_data/random/proc/make_planet_name() diff --git a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm index 49aa85ee8f0..aa5e3bd1242 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm @@ -4,7 +4,7 @@ abstract_type = /datum/map_template/planetoid/random/exoplanet template_parent_type = /datum/map_template/planetoid/random/exoplanet template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET) - ruin_category = MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE + template_category = MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE tallness = 1 level_data_type = /datum/level_data/planetoid/exoplanet prefered_level_data_per_z = list( diff --git a/code/modules/maps/template_types/random_exoplanet/random_planet.dm b/code/modules/maps/template_types/random_exoplanet/random_planet.dm index bd737e582dc..9fc56448312 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_planet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_planet.dm @@ -43,13 +43,13 @@ ///List of theme types that can be picked by this planet when generating. var/list/possible_themes ///Bit flag of the only ruin tags that may be picked by this planet. - var/ruin_tags_whitelist + var/template_tags_whitelist ///Bit flag of the ruin tags that may never be picked for this planet. - var/ruin_tags_blacklist + var/template_tags_blacklist ///Maximume amount of subtemplates/ruins/sites that may be picked and spawned on the planet. var/subtemplate_budget = 4 ///Ruin sites map template category to use for creating ruins on this planet. - var/ruin_category = MAP_TEMPLATE_CATEGORY_PLANET_SITE + var/template_category = MAP_TEMPLATE_CATEGORY_PLANET_SITE /datum/map_template/planetoid/random/is_runtime_generated() return TRUE @@ -154,16 +154,20 @@ if(!gen_data) gen_data = create_planetoid_instance() + // Update our blacklist for habitability + if(gen_data.habitability_class >= HABITABILITY_BAD) + template_tags_blacklist |= TEMPLATE_TAG_HABITABLE + //Generate some of the background stuff for our new planet before_planet_gen(gen_data) //Prepare themes, and apply ruin overrides - var/new_ruin_whitelist = ruin_tags_whitelist - var/new_ruin_blacklist = ruin_tags_blacklist + var/new_template_whitelist = template_tags_whitelist + var/new_template_blacklist = template_tags_blacklist var/list/theme_map_generators for(var/datum/exoplanet_theme/T in gen_data.themes) - new_ruin_whitelist = T.modify_ruin_whitelist(new_ruin_whitelist) - new_ruin_blacklist = T.modify_ruin_blacklist(new_ruin_blacklist) + new_template_whitelist = T.modify_template_whitelist(new_template_whitelist) + new_template_blacklist = T.modify_template_blacklist(new_template_blacklist) T.before_map_generation(gen_data) var/list/gennies = T.get_map_generators() @@ -188,7 +192,7 @@ ///Create all needed z-levels, tell each of them to generate themselves new_level_data = generate_levels(gen_data, theme_map_generators) //Spawn the ruins and sites on the planet - generate_features(gen_data, new_level_data, new_ruin_whitelist, new_ruin_blacklist) + generate_features(gen_data, new_level_data, new_template_whitelist, new_template_blacklist) //Notify themes we finished gen. Since some themes may not change level gen, we run it for either random or mapped planets for(var/datum/exoplanet_theme/T in gen_data.themes) @@ -259,7 +263,7 @@ var/valid = 1 var/list/block_to_check = block(locate(T.x - landing_radius, T.y - landing_radius, T.z), locate(T.x + landing_radius, T.y + landing_radius, T.z)) for(var/turf/check in block_to_check) - if(!istype(get_area(check), gen_data.surface_area) || check.turf_flags & TURF_FLAG_NORUINS) + if(!istype(get_area(check), gen_data.surface_area) || check.turf_flags & TURF_FLAG_NO_POINTS_OF_INTEREST) valid = 0 break if(attempts >= 10) diff --git a/code/modules/maps/template_types/random_exoplanet/random_planet_level_data.dm b/code/modules/maps/template_types/random_exoplanet/random_planet_level_data.dm index 655368256ed..4ce918c85ac 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_planet_level_data.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_planet_level_data.dm @@ -102,74 +102,3 @@ if(!istype(A, world.area)) global.using_map.area_purity_test_exempt_areas |= A.type //Make sure we add any of those, so unit tests calm down when we rename A.SetName("[location_name]") - -///Try to spawn the given amount of ruins onto our level. Returns the template types that were spawned -/datum/level_data/planetoid/proc/seed_ruins(var/budget = 0, var/list/potentialRuins) - if(!length(potentialRuins)) - log_world("Ruin loader was given no ruins to pick from.") - return list() - //#TODO: Fill in allowed area from a proc or something - var/list/areas_whitelist = list(base_area) - var/list/candidates_ruins = potentialRuins.Copy() - var/list/spawned_ruins = list() - - //Each iteration needs to either place a ruin or strictly decrease either the budget or ruins.len (or break). - while(length(candidates_ruins) && (budget > 0)) - var/datum/map_template/R = pick(candidates_ruins) - if((R.get_template_cost() <= budget) && !LAZYISIN(SSmapping.banned_ruin_names, R.name) && try_place_ruin(R, areas_whitelist)) - spawned_ruins += R - budget -= R.get_template_cost() - //Mark spawned no-duplicate ruins globally - if(!(R.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES)) - LAZYDISTINCTADD(SSmapping.banned_ruin_names, R.name) - candidates_ruins -= R - - if(budget > 0) - log_world("Ruin loader had no ruins to pick from with [budget] left to spend.") - return spawned_ruins - -///Attempts several times to find turfs where a ruin can be placed. -/datum/level_data/planetoid/proc/try_place_ruin(var/datum/map_template/ruin, var/list/area_whitelist) - //#FIXME: Isn't trying to fit in a ruin by rolling randomly a bit inneficient? - // Try to place it - var/sanity = 20 - var/ruin_half_width = RUIN_MAP_EDGE_PAD + round(ruin.width/2) //Half the ruin size plus the map edge spacing, for testing from the centerpoint - var/ruin_half_height = RUIN_MAP_EDGE_PAD + round(ruin.height/2) - var/ruin_full_width = (2 * RUIN_MAP_EDGE_PAD) + ruin.width - var/ruin_full_height = (2 * RUIN_MAP_EDGE_PAD) + ruin.height - if((ruin_full_width > level_inner_width) || (ruin_full_height > level_inner_height)) // Too big and will never fit. - return //Return if it won't even fit on the entire level - - //Try to fit it in somehwere a few times, then give up if we can't - while(sanity > 0) - sanity-- - //Pick coordinates inside the level's border within which the ruin will fit. Including the extra ruin spacing from the level's borders. - var/cturf_x = rand(level_inner_min_x + ruin_half_width, level_inner_max_x - ruin_half_width) - var/cturf_y = rand(level_inner_min_y + ruin_half_height, level_inner_max_y - ruin_half_height) - var/turf/T = locate(cturf_x, cturf_y, level_z) - var/valid = TRUE - - //#TODO: There's definitely a way to cache what turfs use an area, to avoid doing this for every single ruins! - // Could also probably cache TURF_FLAG_NORUINS turfs globally. - var/list/affected_turfs = ruin.get_affected_turfs(T, TRUE) - for(var/turf/test_turf in affected_turfs) - var/area/A = get_area(test_turf) - if(!is_type_in_list(A, area_whitelist) || (test_turf.turf_flags & TURF_FLAG_NORUINS)) - valid = FALSE - break //Break out of the turf check loop, and grab a new set of coordinates - if(!valid) - continue - - log_world("Spawned ruin \"[ruin.name]\", center: ([T.x], [T.y], [T.z]), min: ([T.x - ruin_half_width], [T.y - ruin_half_height]), max: ([T.x + ruin_half_width], [T.y + ruin_half_height])") - load_ruin(T, ruin) - return ruin - -///Actually handles loading a ruin template at the given turf. -/datum/level_data/planetoid/proc/load_ruin(turf/central_turf, datum/map_template/template) - if(!template) - return FALSE - for(var/turf/T in template.get_affected_turfs(central_turf, TRUE)) - for(var/mob/living/simple_animal/monster in T) - qdel(monster) - template.load(central_turf, centered = TRUE) - return TRUE diff --git a/code/modules/maps/template_types/random_exoplanet/random_planet_subtemplates.dm b/code/modules/maps/template_types/random_exoplanet/random_planet_subtemplates.dm index 5102b8adb42..ec100a3847a 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_planet_subtemplates.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_planet_subtemplates.dm @@ -1,24 +1,6 @@ ///Picks all ruins and tries to spawn them on the levels that make up the planet. -/datum/map_template/planetoid/random/proc/generate_features(var/datum/planetoid_data/gen_data, var/list/created_level_data, var/whitelist = ruin_tags_whitelist, var/blacklist = ruin_tags_blacklist) - var/my_budget = gen_data._budget_override || subtemplate_budget - if(my_budget <= 0) - return - - var/list/possible_subtemplates = list() - var/list/ruins = SSmapping.get_templates_by_category(ruin_category) - for(var/ruin_name in ruins) - var/datum/map_template/ruin = ruins[ruin_name] - var/ruin_tags = ruin.get_ruin_tags() - if(whitelist && !(whitelist & ruin_tags)) - continue - if(blacklist & ruin_tags) - continue - possible_subtemplates += ruin - - if(!length(possible_subtemplates)) - return //If we don't have any ruins, don't bother - +/datum/map_template/planetoid/random/proc/generate_features(var/datum/planetoid_data/gen_data, var/list/created_level_data, var/whitelist = template_tags_whitelist, var/blacklist = template_tags_blacklist) //#TODO: Properly handle generating ruins and sites on the various levels of the planet. var/datum/level_data/planetoid/surface_level = SSmapping.levels_by_id[gen_data.surface_level_id] //#TODO: dimensions and area have to be handled on a per level_data basis!! - LAZYADD(gen_data.subtemplates, surface_level.seed_ruins(my_budget, possible_subtemplates)) + LAZYADD(gen_data.subtemplates, surface_level.spawn_subtemplates((gen_data._budget_override || subtemplate_budget), template_category, blacklist, whitelist)) diff --git a/code/modules/maps/template_types/ruins_exoplanet.dm b/code/modules/maps/template_types/ruins_exoplanet.dm index f5e79068984..a0a34f76975 100644 --- a/code/modules/maps/template_types/ruins_exoplanet.dm +++ b/code/modules/maps/template_types/ruins_exoplanet.dm @@ -2,7 +2,3 @@ prefix = "maps/random_ruins/exoplanet_ruins/" template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE) template_parent_type = /datum/map_template/ruin/exoplanet - var/list/ruin_tags - -/datum/map_template/ruin/exoplanet/get_ruin_tags() - return ruin_tags diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index fc680a1eb5e..211b75b8015 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -109,7 +109,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/table_icon_base = "metal" var/table_icon_reinforced = "reinf_metal" - var/list/stack_origin_tech = "{'materials':1}" // Research level for stacks. + var/list/stack_origin_tech = @'{"materials":1}' // Research level for stacks. // Attributes /// How rare is this material in exoplanet xenoflora? @@ -225,6 +225,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/fruit_descriptor // String added to fruit desc if this chemical is present. var/dirtiness = DIRTINESS_NEUTRAL // How dirty turfs are after being exposed to this material. Negative values cause a cleaning/sterilizing effect. + var/decontamination_dose = 0 // Amount required for a decontamination effect, if any. var/solvent_power = MAT_SOLVENT_NONE var/solvent_melt_dose = 0 var/solvent_max_damage = 0 @@ -246,7 +247,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/chilling_message = "crackles and freezes!" var/chilling_sound = 'sound/effects/bubbles.ogg' var/list/chilling_products - var/bypass_cooling_products_for_root_type + var/bypass_chilling_products_for_root_type var/heating_point var/heating_message = "begins to boil!" @@ -278,6 +279,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/sound_manipulate //Default sound something like a material stack made of this material does when picked up var/sound_dropped //Default sound something like a material stack made of this material does when hitting the ground or placed down + var/holographic // Set to true if this material is fake/visual only. + // Placeholders for light tiles and rglass. /decl/material/proc/reinforce(var/mob/user, var/obj/item/stack/material/used_stack, var/obj/item/stack/material/target_stack, var/use_sheets = 1) if(!used_stack.can_use(use_sheets)) @@ -319,6 +322,32 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) solid_name ||= use_name gas_name ||= use_name adjective_name ||= use_name + + // Null/clear a bunch of physical vars as this material is fake. + if(holographic) + shard_type = SHARD_NONE + conductive = 0 + hidden_from_codex = TRUE + value = 0 + exoplanet_rarity_plant = MAT_RARITY_NOWHERE + exoplanet_rarity_gas = MAT_RARITY_NOWHERE + dissolves_into = null + dissolves_in = MAT_SOLVENT_IMMUNE + solvent_power = MAT_SOLVENT_NONE + heating_products = null + chilling_products = null + heating_point = null + chilling_point = null + solvent_melt_dose = 0 + solvent_max_damage = 0 + slipperiness = 0 + ignition_point = null + melting_point = null + boiling_point = null + accelerant_value = FUEL_VALUE_NONE + burn_product = null + vapor_products = null + if(!shard_icon) shard_icon = shard_type if(!burn_armor) @@ -330,12 +359,13 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) global.materials_by_gas_symbol[gas_symbol] = type generate_armor_values() - var/list/cocktails = decls_repository.get_decls_of_subtype(/decl/cocktail) - for(var/ctype in cocktails) - var/decl/cocktail/cocktail = cocktails[ctype] - if(type in cocktail.ratios) - cocktail_ingredient = TRUE - break + if(!holographic) + var/list/cocktails = decls_repository.get_decls_of_subtype(/decl/cocktail) + for(var/ctype in cocktails) + var/decl/cocktail/cocktail = cocktails[ctype] + if(type in cocktail.ratios) + cocktail_ingredient = TRUE + break #define FALSEWALL_STATE "fwall_open" /decl/material/validate() @@ -366,6 +396,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(icon_base && !check_state_in_icon(FALSEWALL_STATE, icon_base)) . += "[type] - '[icon_base]' - missing false wall opening animation '[FALSEWALL_STATE]'" + if(dissolves_in == MAT_SOLVENT_IMMUNE && LAZYLEN(dissolves_into)) + . += "material is immune to solvents, but has dissolves_into products." + for(var/i = 0 to 7) if(icon_base) if(!check_state_in_icon("[i]", icon_base)) @@ -571,11 +604,16 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) else if(defoliant && istype(O, /obj/effect/vine)) qdel(O) else + if(dirtiness <= DIRTINESS_DECONTAMINATE) + if(amount >= decontamination_dose && istype(O, /obj/item)) + var/obj/item/I = O + if(I.contaminated) + I.decontaminate() if(dirtiness <= DIRTINESS_STERILE) O.germ_level -= min(REAGENT_VOLUME(holder, type)*20, O.germ_level) O.was_bloodied = null if(dirtiness <= DIRTINESS_CLEAN) - O.clean_blood() + O.clean() #define FLAMMABLE_LIQUID_DIVISOR 7 // This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. @@ -719,30 +757,30 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(dirtiness <= DIRTINESS_CLEAN) for(var/obj/item/thing in M.get_held_items()) - thing.clean_blood() + thing.clean() var/obj/item/mask = M.get_equipped_item(slot_wear_mask_str) if(mask) - mask.clean_blood() + mask.clean() if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/head = H.get_equipped_item(slot_head_str) if(head) - head.clean_blood() + head.clean() var/obj/item/suit = H.get_equipped_item(slot_wear_suit_str) if(suit) - suit.clean_blood() + suit.clean() else var/obj/item/uniform = H.get_equipped_item(slot_w_uniform_str) if(uniform) - uniform.clean_blood() + uniform.clean() var/obj/item/shoes = H.get_equipped_item(slot_shoes_str) if(shoes) - shoes.clean_blood() + shoes.clean() else - H.clean_blood(1) + H.clean() return - M.clean_blood() + M.clean() if(solvent_power > MAT_SOLVENT_NONE && removed >= solvent_melt_dose && M.solvent_act(min(removed * solvent_power * ((removed < solvent_melt_dose) ? 0.1 : 0.2), solvent_max_damage), solvent_melt_dose, solvent_power)) holder.remove_reagent(type, REAGENT_VOLUME(holder, type)) diff --git a/code/modules/materials/_stack_recipe.dm b/code/modules/materials/_stack_recipe.dm index a40c1ff30fd..1ec3a4a54ed 100644 --- a/code/modules/materials/_stack_recipe.dm +++ b/code/modules/materials/_stack_recipe.dm @@ -15,6 +15,7 @@ var/difficulty = 1 // higher difficulty requires higher skill level to make. var/apply_material_name = 1 //Whether the recipe will prepend a material name to the title - 'steel clipboard' vs 'clipboard' var/set_dir_on_spawn = TRUE + var/expected_product_type = /obj /datum/stack_recipe/New(decl/material/material, var/reinforce_material) if(material) diff --git a/code/modules/materials/definitions/gasses/material_gas_mundane.dm b/code/modules/materials/definitions/gasses/material_gas_mundane.dm index 4408e062fae..9aaffe1ddf1 100644 --- a/code/modules/materials/definitions/gasses/material_gas_mundane.dm +++ b/code/modules/materials/definitions/gasses/material_gas_mundane.dm @@ -325,7 +325,7 @@ lore_text = "A radioactive isotope of hydrogen. Useful as a fusion reactor fuel material." mechanics_text = "Tritium is useable as a fuel in some forms of portable generator. It can also be converted into a fuel rod suitable for a R-UST fusion plant injector by using a fuel compressor. It fuses hotter than deuterium but is correspondingly more unstable." color = "#777777" - stack_origin_tech = "{'materials':5}" + stack_origin_tech = @'{"materials":5}' value = 0.45 gas_symbol_html = "T" gas_symbol = "T" @@ -340,7 +340,7 @@ mechanics_text = "Deuterium can be converted into a fuel rod suitable for a R-UST fusion plant injector by using a fuel compressor. It is the most 'basic' fusion fuel." flags = MAT_FLAG_FUSION_FUEL | MAT_FLAG_FISSIBLE color = "#999999" - stack_origin_tech = "{'materials':3}" + stack_origin_tech = @'{"materials":3}' gas_symbol_html = "D" gas_symbol = "D" value = 0.5 diff --git a/code/modules/materials/definitions/solids/materials_solid_exotic.dm b/code/modules/materials/definitions/solids/materials_solid_exotic.dm index f200678cfde..ec0b022c7ff 100644 --- a/code/modules/materials/definitions/solids/materials_solid_exotic.dm +++ b/code/modules/materials/definitions/solids/materials_solid_exotic.dm @@ -4,7 +4,7 @@ lore_text = "When hydrogen is exposed to extremely high pressures and temperatures, such as at the core of gas giants like Jupiter, it can take on metallic properties and - more importantly - acts as a room temperature superconductor. Achieving solid metallic hydrogen at room temperature, though, has proven to be rather tricky." name = "metallic hydrogen" color = "#e6c5de" - stack_origin_tech = "{'materials':6,'powerstorage':6,'magnets':5}" + stack_origin_tech = @'{"materials":6,"powerstorage":6,"magnets":5}' heating_products = list( /decl/material/gas/hydrogen/tritium = 0.7, /decl/material/gas/hydrogen/deuterium = 0.3 @@ -105,7 +105,7 @@ lore_text = "Hypercrystalline supermatter is a subset of non-baryonic 'exotic' matter. It is found mostly in the heart of large stars, and features heavily in all kinds of fringe physics-defying technology." color = "#ffff00" radioactivity = 20 - stack_origin_tech = "{'bluespace':2,'materials':6,'exoticmatter':4}" + stack_origin_tech = @'{"wormholes":2,"materials":6,"exoticmatter":4}' luminescence = 3 value = 3 icon_base = 'icons/turf/walls/stone.dmi' diff --git a/code/modules/materials/definitions/solids/materials_solid_gemstones.dm b/code/modules/materials/definitions/solids/materials_solid_gemstones.dm index 32a3980dfca..b9c46732ad1 100644 --- a/code/modules/materials/definitions/solids/materials_solid_gemstones.dm +++ b/code/modules/materials/definitions/solids/materials_solid_gemstones.dm @@ -23,7 +23,7 @@ ignition_point = null brute_armor = 10 burn_armor = 50 // Diamond walls are immune to fire, therefore it makes sense for them to be almost undamageable by burn damage type. - stack_origin_tech = "{'materials':6}" + stack_origin_tech = @'{"materials":6}' hardness = MAT_VALUE_VERY_HARD + 20 construction_difficulty = MAT_VALUE_VERY_HARD_DIY ore_name = "rough diamonds" @@ -38,6 +38,8 @@ ore_data_value = 2 exoplanet_rarity_plant = MAT_RARITY_UNCOMMON exoplanet_rarity_gas = MAT_RARITY_NOWHERE + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/gemstone/crystal name = "crystal" @@ -48,3 +50,5 @@ value = 2 exoplanet_rarity_plant = MAT_RARITY_UNCOMMON exoplanet_rarity_gas = MAT_RARITY_NOWHERE + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null diff --git a/code/modules/materials/definitions/solids/materials_solid_glass.dm b/code/modules/materials/definitions/solids/materials_solid_glass.dm index 8baecb051b7..4bf9b0e41a9 100644 --- a/code/modules/materials/definitions/solids/materials_solid_glass.dm +++ b/code/modules/materials/definitions/solids/materials_solid_glass.dm @@ -24,6 +24,8 @@ conductive = 0 wall_support_value = MAT_VALUE_LIGHT default_solid_form = /obj/item/stack/material/pane + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/glass/proc/is_reinforced() return (integrity > 75) //todo @@ -44,7 +46,7 @@ burn_armor = 5 melting_point = 4274 color = GLASS_COLOR_SILICATE - stack_origin_tech = "{'materials':4}" + stack_origin_tech = @'{"materials":4}' construction_difficulty = MAT_VALUE_HARD_DIY value = 1.8 @@ -69,7 +71,7 @@ door_icon_base = "plastic" hardness = MAT_VALUE_FLEXIBLE weight = MAT_VALUE_LIGHT - stack_origin_tech = "{'materials':3}" + stack_origin_tech = @'{"materials":3}' conductive = 0 construction_difficulty = MAT_VALUE_NORMAL_DIY reflectiveness = MAT_VALUE_MATTE diff --git a/code/modules/materials/definitions/solids/materials_solid_metal.dm b/code/modules/materials/definitions/solids/materials_solid_metal.dm index 36730b022d3..19c427f4122 100644 --- a/code/modules/materials/definitions/solids/materials_solid_metal.dm +++ b/code/modules/materials/definitions/solids/materials_solid_metal.dm @@ -37,7 +37,7 @@ icon_reinf = 'icons/turf/walls/reinforced_stone.dmi' color = "#007a00" weight = MAT_VALUE_VERY_HEAVY - stack_origin_tech = "{'materials':5}" + stack_origin_tech = @'{"materials":5}' reflectiveness = MAT_VALUE_MATTE value = 1.5 default_solid_form = /obj/item/stack/material/puck @@ -85,7 +85,7 @@ color = COLOR_GOLD hardness = MAT_VALUE_FLEXIBLE + 5 integrity = 100 - stack_origin_tech = "{'materials':4}" + stack_origin_tech = @'{"materials":4}' ore_result_amount = 5 ore_name = "native gold" ore_spread_chance = 10 @@ -162,7 +162,7 @@ color = COLOR_COPPER weight = MAT_VALUE_NORMAL hardness = MAT_VALUE_FLEXIBLE + 10 - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' /decl/material/solid/metal/silver name = "silver" @@ -172,7 +172,7 @@ boiling_point = 2444 color = "#d1e6e3" hardness = MAT_VALUE_FLEXIBLE + 10 - stack_origin_tech = "{'materials':3}" + stack_origin_tech = @'{"materials":3}' ore_result_amount = 5 ore_spread_chance = 10 ore_name = "native silver" @@ -212,7 +212,7 @@ /decl/material/solid/metal/steel/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.)) + if(!holographic && !reinforce_material && islist(.)) if(!ispath(stack_type)) . += new/datum/stack_recipe/furniture/closet(src) . += new/datum/stack_recipe/furniture/tank_dispenser(src) @@ -236,15 +236,7 @@ /decl/material/solid/metal/steel/holographic name = "holographic steel" uid = "solid_holographic_steel" - shard_type = SHARD_NONE - conductive = 0 - hidden_from_codex = TRUE - value = 0 - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE - -/decl/material/solid/metal/steel/holographic/get_recipes(stack_type, reinf_mat) - return list() + holographic = TRUE /decl/material/solid/metal/stainlesssteel name = "stainless steel" @@ -266,6 +258,8 @@ value = 1.3 exoplanet_rarity_plant = MAT_RARITY_UNCOMMON exoplanet_rarity_gas = MAT_RARITY_NOWHERE + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/metal/aluminium name = "aluminium" @@ -286,20 +280,13 @@ /decl/material/solid/metal/aluminium/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/grenade(src) /decl/material/solid/metal/aluminium/holographic name = "holoaluminium" uid = "solid_holographic_aluminium" - shard_type = SHARD_NONE - conductive = 0 - hidden_from_codex = TRUE - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE - -/decl/material/solid/metal/aluminium/holographic/get_recipes(stack_type, reinf_mat) - return list() + holographic = TRUE /decl/material/solid/metal/plasteel name = "plasteel" @@ -317,17 +304,19 @@ brute_armor = 8 burn_armor = 10 hardness = MAT_VALUE_VERY_HARD - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' hitsound = 'sound/weapons/smash.ogg' value = 1.4 reflectiveness = MAT_VALUE_MATTE default_solid_form = /obj/item/stack/material/reinforced exoplanet_rarity_plant = MAT_RARITY_UNCOMMON exoplanet_rarity_gas = MAT_RARITY_NOWHERE + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/metal/plasteel/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/ai_core(src) . += new/datum/stack_recipe/furniture/crate(src) . += new/datum/stack_recipe/grip(src) @@ -351,14 +340,16 @@ value = 1.5 explosion_resistance = 25 hardness = MAT_VALUE_VERY_HARD - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' hitsound = 'sound/weapons/smash.ogg' reflectiveness = MAT_VALUE_MATTE default_solid_form = /obj/item/stack/material/reinforced + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/metal/titanium/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/ai_core(src) . += new/datum/stack_recipe/furniture/crate(src) . += new/datum/stack_recipe/grip(src) @@ -376,7 +367,7 @@ color = "#9bc6f2" brute_armor = 4 burn_armor = 20 - stack_origin_tech = "{'materials':3}" + stack_origin_tech = @'{"materials":3}' construction_difficulty = MAT_VALUE_VERY_HARD_DIY value = 1.8 exoplanet_rarity_plant = MAT_RARITY_UNCOMMON @@ -389,7 +380,7 @@ melting_point = 3307 boiling_point = 5285 color = "#9999ff" - stack_origin_tech = "{'materials':5}" + stack_origin_tech = @'{"materials":5}' construction_difficulty = MAT_VALUE_VERY_HARD_DIY value = 1.3 @@ -402,7 +393,7 @@ color = "#deddff" weight = MAT_VALUE_VERY_HEAVY wall_support_value = MAT_VALUE_VERY_HEAVY - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' ore_compresses_to = /decl/material/solid/metal/osmium ore_result_amount = 5 ore_spread_chance = 10 diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm index e5ac586eed8..61e286145e0 100644 --- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm +++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm @@ -13,7 +13,7 @@ ore_spread_chance = 10 ore_name = "pitchblende" ore_scan_icon = "mineral_uncommon" - stack_origin_tech = "{'materials':5}" + stack_origin_tech = @'{"materials":5}' xarch_source_mineral = /decl/material/solid/phosphorus ore_icon_overlay = "nugget" value = 0.8 diff --git a/code/modules/materials/definitions/solids/materials_solid_organic.dm b/code/modules/materials/definitions/solids/materials_solid_organic.dm index 3c27446a024..cf4d06a97b4 100644 --- a/code/modules/materials/definitions/solids/materials_solid_organic.dm +++ b/code/modules/materials/definitions/solids/materials_solid_organic.dm @@ -18,7 +18,7 @@ hardness = MAT_VALUE_FLEXIBLE + 10 weight = MAT_VALUE_LIGHT melting_point = T0C+371 //assuming heat resistant plastic - stack_origin_tech = "{'materials':3}" + stack_origin_tech = @'{"materials":3}' conductive = 0 construction_difficulty = MAT_VALUE_NORMAL_DIY reflectiveness = MAT_VALUE_SHINY @@ -32,7 +32,7 @@ /decl/material/solid/organic/plastic/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/furniture/crate/plastic(src) . += new/datum/stack_recipe/bag(src) . += new/datum/stack_recipe/ivbag(src) @@ -68,13 +68,7 @@ /decl/material/solid/organic/plastic/holographic name = "holographic plastic" uid = "solid_holographic_plastic" - shard_type = SHARD_NONE - hidden_from_codex = TRUE - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE - -/decl/material/solid/organic/plastic/holographic/get_recipes(stack_type, reinf_mat) - return list() + holographic = TRUE /decl/material/solid/organic/cardboard name = "cardboard" @@ -92,7 +86,7 @@ weight = MAT_VALUE_EXTREMELY_LIGHT - 5 ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough melting_point = T0C+232 //temperature at which cardboard walls would be destroyed - stack_origin_tech = "{'materials':1}" + stack_origin_tech = @'{"materials":1}' door_icon_base = "wood" destruction_desc = "crumples" conductive = 0 @@ -107,7 +101,7 @@ /decl/material/solid/organic/cardboard/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += create_recipe_list(/datum/stack_recipe/box) . += new/datum/stack_recipe/cardborg_suit(src) . += new/datum/stack_recipe/cardborg_helmet(src) @@ -118,7 +112,7 @@ uid = "solid_paper" lore_text = "Low tech writing medium made from cellulose fibers. Also used in wrappings and packaging." color = "#cfcece" - stack_origin_tech = "{'materials':1}" + stack_origin_tech = @'{"materials":1}' door_icon_base = "wood" destruction_desc = "tears" icon_base = 'icons/turf/walls/solid.dmi' @@ -146,7 +140,7 @@ /decl/material/solid/organic/paper/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/paper_sheets(src) /decl/material/solid/organic/cloth //todo @@ -154,7 +148,7 @@ uid = "solid_cotton" use_name = "cotton" color = "#ffffff" - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' door_icon_base = "wood" ignition_point = T0C+232 melting_point = T0C+300 @@ -175,7 +169,7 @@ /decl/material/solid/organic/cloth/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/cloak(src) . += new/datum/stack_recipe/banner(src) @@ -341,7 +335,7 @@ /decl/material/solid/organic/skin/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/cloak(src) . += new/datum/stack_recipe/banner(src) . += new/datum/stack_recipe/shoes(src) @@ -470,7 +464,7 @@ /decl/material/solid/organic/bone/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type) && wall_support_value >= 10) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type) && wall_support_value >= 10) . += new/datum/stack_recipe/furniture/girder(src) . += new/datum/stack_recipe/furniture/ladder(src) @@ -505,7 +499,7 @@ name = "leather" uid = "solid_leather" color = "#5c4831" - stack_origin_tech = "{'materials':2}" + stack_origin_tech = @'{"materials":2}' flags = MAT_FLAG_PADDING ignition_point = T0C+300 melting_point = T0C+300 @@ -525,7 +519,7 @@ /decl/material/solid/organic/leather/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/cloak(src) . += new/datum/stack_recipe/banner(src) . += new/datum/stack_recipe/shoes(src) diff --git a/code/modules/materials/definitions/solids/materials_solid_stone.dm b/code/modules/materials/definitions/solids/materials_solid_stone.dm index 5ab7f90f149..9aa021b41b2 100644 --- a/code/modules/materials/definitions/solids/materials_solid_stone.dm +++ b/code/modules/materials/definitions/solids/materials_solid_stone.dm @@ -20,7 +20,7 @@ /decl/material/solid/stone/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) if(wall_support_value >= 10) . += new/datum/stack_recipe/furniture/girder(src) . += new/datum/stack_recipe/furniture/planting_bed(src) @@ -56,6 +56,8 @@ uid = "solid_ceramic" lore_text = "A hard substance produced by firing clay in a kiln." color = COLOR_OFF_WHITE + dissolves_in = MAT_SOLVENT_IMMUNE + dissolves_into = null /decl/material/solid/stone/marble name = "marble" diff --git a/code/modules/materials/definitions/solids/materials_solid_wood.dm b/code/modules/materials/definitions/solids/materials_solid_wood.dm index e78d98c7755..ea2dab49f1b 100644 --- a/code/modules/materials/definitions/solids/materials_solid_wood.dm +++ b/code/modules/materials/definitions/solids/materials_solid_wood.dm @@ -22,7 +22,7 @@ weight = MAT_VALUE_NORMAL melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood ignition_point = T0C+288 - stack_origin_tech = "{'materials':1,'biotech':1}" + stack_origin_tech = @'{"materials":1,"biotech":1}' dooropen_noise = 'sound/effects/doorcreaky.ogg' door_icon_base = "wood" destruction_desc = "splinters" @@ -43,7 +43,7 @@ /decl/material/solid/organic/wood/generate_recipes(stack_type, reinforce_material) . = ..() - if(reinforce_material || ispath(stack_type)) + if(holographic || reinforce_material || ispath(stack_type)) return if(wall_support_value >= 10) @@ -76,37 +76,37 @@ . += new/datum/stack_recipe/prosthetic/right_foot(src) . += new/datum/stack_recipe/campfire(src) +/decl/material/solid/organic/wood/fungal + name = "towercap" + uid = "solid_wood_fungal" + color = "#e6d8dd" + hardness = MAT_VALUE_FLEXIBLE + 1 + /decl/material/solid/organic/wood/mahogany/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/tile/mahogany(src) /decl/material/solid/organic/wood/maple/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/tile/maple(src) /decl/material/solid/organic/wood/ebony/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/tile/ebony(src) /decl/material/solid/organic/wood/walnut/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new/datum/stack_recipe/tile/walnut(src) /decl/material/solid/organic/wood/holographic + name = "holographic wood" uid = "solid_holographic_wood" color = WOOD_COLOR_CHOCOLATE //the very concept of wood should be brown - shard_type = SHARD_NONE - value = 0 - hidden_from_codex = TRUE - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE - -/decl/material/solid/organic/wood/holographic/get_recipes(stack_type, reinf_mat) - return list() + holographic = TRUE /decl/material/solid/organic/wood/mahogany name = "mahogany" diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 7945a91df36..3217a361a52 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -1,4 +1,6 @@ /decl/material/proc/get_recipes(stack_type, reinf_mat) + if(holographic) + return list() var/key = "[reinf_mat || "base"]-[stack_type || "general"]" if(!LAZYACCESS(recipes, key)) LAZYSET(recipes, key, generate_recipes(stack_type, reinf_mat)) @@ -12,10 +14,13 @@ /decl/material/proc/generate_recipes(stack_type, reinforce_material) - // By default we don't let anything be crafted with ore, as it's too raw. + if(holographic || phase_at_temperature() != MAT_PHASE_SOLID) + return list() + + // By default we don't let anything be crafted with ore or logs, as they are too raw. // We make an exception for clay as it is being moulded by hand. . = list() - if(ispath(stack_type, /obj/item/stack/material/ore) || phase_at_temperature() != MAT_PHASE_SOLID) + if(ispath(stack_type, /obj/item/stack/material/ore) || ispath(stack_type, /obj/item/stack/material/log)) return // Struts have their own recipe set, so we return early for them. @@ -31,6 +36,9 @@ . += new/datum/stack_recipe/furniture/bed(src) return + if(ispath(stack_type, /obj/item/stack/material/brick) && wall_support_value >= 10) + . += new/datum/stack_recipe/turfs/wall/brick(src) + // We assume a non-ore non-strut stack type is a general type that can use general recipes. if(opacity < 0.6) . += new/datum/stack_recipe/furniture/borderwindow(src, reinforce_material) diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm index 8159fa28a22..c63d15f1657 100644 --- a/code/modules/materials/material_sheets.dm +++ b/code/modules/materials/material_sheets.dm @@ -47,6 +47,7 @@ if(material.sound_dropped) drop_sound = material.sound_dropped update_strings() + update_icon() /obj/item/stack/material/get_recipes() return material.get_recipes(recipe_stack_type, reinf_material?.type) @@ -219,6 +220,7 @@ plural_icon_state = "brick-mult" max_icon_state = "brick-max" stack_merge_type = /obj/item/stack/material/brick + recipe_stack_type = /obj/item/stack/material/brick /obj/item/stack/material/bolt name = "bolts" @@ -303,6 +305,30 @@ plural_icon_state = "sheet-wood-mult" max_icon_state = "sheet-wood-max" stack_merge_type = /obj/item/stack/material/plank + pickup_sound = 'sound/foley/wooden_drop.ogg' + drop_sound = 'sound/foley/wooden_drop.ogg' + +/obj/item/stack/material/log + name = "logs" + singular_name = "log" + plural_name = "logs" + icon_state = "log" + plural_icon_state = "log-mult" + max_icon_state = "log-max" + stack_merge_type = /obj/item/stack/material/log + recipe_stack_type = /obj/item/stack/material/log + var/plank_type = /obj/item/stack/material/plank + +/obj/item/stack/material/log/attackby(obj/item/W, mob/user) + if(plank_type && (IS_HATCHET(W) || IS_SAW(W))) + var/tool_type = W.get_tool_quality(TOOL_HATCHET) >= W.get_tool_quality(TOOL_SAW) ? TOOL_HATCHET : TOOL_SAW + if(W.do_tool_interaction(tool_type, user, src, 1 SECOND, set_cooldown = TRUE) && !QDELETED(src)) + var/obj/item/stack/planks = new plank_type(loc, 1, material?.type, reinf_material?.type) + planks.add_to_stacks(user, TRUE) + playsound(loc, 'sound/foley/wooden_drop.ogg', 40, TRUE) + use(1) + return TRUE + return ..() /obj/item/stack/material/segment name = "segments" diff --git a/code/modules/materials/material_sheets_mapping.dm b/code/modules/materials/material_sheets_mapping.dm index 6cf0aa53139..4b9005a5021 100644 --- a/code/modules/materials/material_sheets_mapping.dm +++ b/code/modules/materials/material_sheets_mapping.dm @@ -68,6 +68,13 @@ STACK_SUBTYPES(ebony, "ebony", solid/organic/wo STACK_SUBTYPES(walnut, "walnut", solid/organic/wood/walnut, plank, null) STACK_SUBTYPES(bamboo, "bamboo", solid/organic/wood/bamboo, plank, null) STACK_SUBTYPES(yew, "yew", solid/organic/wood/yew, plank, null) +STACK_SUBTYPES(wood, "wood", solid/organic/wood, log, null) +STACK_SUBTYPES(mahogany, "mahogany", solid/organic/wood/mahogany, log, null) +STACK_SUBTYPES(maple, "maple", solid/organic/wood/maple, log, null) +STACK_SUBTYPES(ebony, "ebony", solid/organic/wood/ebony, log, null) +STACK_SUBTYPES(walnut, "walnut", solid/organic/wood/walnut, log, null) +STACK_SUBTYPES(bamboo, "bamboo", solid/organic/wood/bamboo, log, null) +STACK_SUBTYPES(yew, "yew", solid/organic/wood/yew, log, null) STACK_SUBTYPES(cardboard, "cardboard", solid/organic/cardboard, cardstock, null) STACK_SUBTYPES(leather, "leather", solid/organic/leather, skin, null) STACK_SUBTYPES(synthleather, "synthleather", solid/organic/leather/synth, skin, null) diff --git a/code/modules/materials/recipes_storage.dm b/code/modules/materials/recipes_storage.dm index 69d2961d12d..be72638ecb7 100644 --- a/code/modules/materials/recipes_storage.dm +++ b/code/modules/materials/recipes_storage.dm @@ -9,11 +9,11 @@ /datum/stack_recipe/box/donut title = "donut box" - result_type = /obj/item/storage/box/donut/empty + result_type = /obj/item/storage/box/fancy/donut/empty /datum/stack_recipe/box/egg title = "egg box" - result_type = /obj/item/storage/fancy/egg_box/empty + result_type = /obj/item/storage/box/fancy/egg_box/empty /datum/stack_recipe/box/light_tubes title = "light tubes box" diff --git a/code/modules/materials/recipes_turfs.dm b/code/modules/materials/recipes_turfs.dm new file mode 100644 index 00000000000..6cf0929bf10 --- /dev/null +++ b/code/modules/materials/recipes_turfs.dm @@ -0,0 +1,28 @@ +/datum/stack_recipe/turfs + abstract_type = /datum/stack_recipe/turfs + expected_product_type = /turf + time = 3 SECONDS + req_amount = 5 // Arbitrary value since turfs don't behave like objs in terms of material/matter + +// See req_amount above. +/datum/stack_recipe/turfs/InitializeMaterials() + return + +/datum/stack_recipe/turfs/spawn_result(mob/user, location, amount) + var/turf/build_turf = get_turf(location) + if(!build_turf) + return + return build_turf.ChangeTurf(result_type) + +/datum/stack_recipe/turfs/wall + abstract_type = /datum/stack_recipe/turfs/wall + expected_product_type = /turf/simulated/wall + +/datum/stack_recipe/turfs/wall/spawn_result(mob/user, location, amount) + var/turf/simulated/wall/wall = ..() + if(istype(wall)) + wall.set_material(use_material, use_reinf_material) + +/datum/stack_recipe/turfs/wall/brick + title = "brick wall" + result_type = /turf/simulated/wall/brick diff --git a/code/modules/mechs/components/_components.dm b/code/modules/mechs/components/_components.dm index fa8ae476b26..8e15b986e06 100644 --- a/code/modules/mechs/components/_components.dm +++ b/code/modules/mechs/components/_components.dm @@ -21,6 +21,7 @@ var/damage_state = 1 var/list/has_hardpoints = list() var/decal + var/decal_blend = BLEND_MULTIPLY var/power_use = 0 /obj/item/mech_component/set_color(new_color) @@ -98,6 +99,7 @@ update_components() /obj/item/mech_component/attackby(var/obj/item/thing, var/mob/user) + if(IS_SCREWDRIVER(thing)) if(contents.len) //Filter non movables @@ -106,27 +108,30 @@ if(!A.anchored) valid_contents += A if(!valid_contents.len) - return + return TRUE var/obj/item/removed = pick(valid_contents) if(!(removed in contents)) - return + return TRUE user.visible_message(SPAN_NOTICE("\The [user] removes \the [removed] from \the [src].")) removed.forceMove(user.loc) playsound(user.loc, 'sound/effects/pop.ogg', 50, 0) update_components() else to_chat(user, SPAN_WARNING("There is nothing to remove.")) - return + return TRUE + if(IS_WELDER(thing)) repair_brute_generic(thing, user) - return + return TRUE + if(IS_COIL(thing)) repair_burn_generic(thing, user) - return + return TRUE + if(istype(thing, /obj/item/robotanalyzer)) to_chat(user, SPAN_NOTICE("Diagnostic Report for \the [src]:")) return_diagnostics(user) - return + return TRUE return ..() diff --git a/code/modules/mechs/components/armour.dm b/code/modules/mechs/components/armour.dm index 79f3d8213db..b86d67295dc 100644 --- a/code/modules/mechs/components/armour.dm +++ b/code/modules/mechs/components/armour.dm @@ -12,7 +12,7 @@ ARMOR_BIO = ARMOR_BIO_SHIELDED, ARMOR_RAD = ARMOR_RAD_MINOR ) - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel /obj/item/robot_parts/robot_component/armour/exosuit/radproof @@ -27,7 +27,7 @@ ARMOR_BIO = ARMOR_BIO_SHIELDED, ARMOR_RAD = ARMOR_RAD_SHIELDED ) - origin_tech = "{'materials':3}" + origin_tech = @'{"materials":3}' material = /decl/material/solid/metal/steel /obj/item/robot_parts/robot_component/armour/exosuit/em @@ -42,7 +42,7 @@ ARMOR_BIO = ARMOR_BIO_SHIELDED, ARMOR_RAD = ARMOR_RAD_SMALL ) - origin_tech = "{'materials':3}" + origin_tech = @'{"materials":3}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) @@ -57,7 +57,7 @@ ARMOR_BOMB = ARMOR_BOMB_RESISTANT, ARMOR_BIO = ARMOR_BIO_SHIELDED ) - origin_tech = "{'materials':5}" + origin_tech = @'{"materials":5}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/modules/mechs/components/frame.dm b/code/modules/mechs/components/frame.dm index 237161939bd..cda4caaf272 100644 --- a/code/modules/mechs/components/frame.dm +++ b/code/modules/mechs/components/frame.dm @@ -56,20 +56,20 @@ /obj/structure/heavy_vehicle_frame/on_update_icon() ..() - for(var/overlay in get_mech_images(list(legs, head, body, arms), layer)) - add_overlay(overlay) + for(var/obj/item/mech_component/comp in list(legs, head, body, arms)) + get_mech_image(comp.decal, comp.decal_blend, comp.icon_state, comp.on_mech_icon, comp.color, overlay_layer = FLOAT_LAYER) if(body) - density = TRUE - overlays += get_mech_image(null, "[body.icon_state]_cockpit", body.icon, body.color) + set_density(TRUE) + add_overlay(get_mech_image(body.decal, body.decal_blend, "[body.icon_state]_cockpit", body.icon, body.color)) if(body.pilot_coverage < 100 || body.transparent_cabin) - add_overlay(get_mech_image(null, "[body.icon_state]_open_overlay", body.icon, body.color)) + add_overlay(get_mech_image(body.decal, body.decal_blend, "[body.icon_state]_open_overlay", body.icon, body.color)) else - density = FALSE + set_density(FALSE) if(density != opacity) set_opacity(density) /obj/structure/heavy_vehicle_frame/set_dir() - ..(SOUTH) + return ..(SOUTH) /obj/structure/heavy_vehicle_frame/attackby(var/obj/item/thing, var/mob/user) diff --git a/code/modules/mechs/components/software.dm b/code/modules/mechs/components/software.dm index 1a7a5f1c916..49cc737083d 100644 --- a/code/modules/mechs/components/software.dm +++ b/code/modules/mechs/components/software.dm @@ -6,22 +6,22 @@ /obj/item/stock_parts/circuitboard/exosystem/engineering name = "exosuit circuit (engineering systems)" contains_software = list(MECH_SOFTWARE_ENGINEERING) - origin_tech = "{'programming':1}" + origin_tech = @'{"programming":1}' /obj/item/stock_parts/circuitboard/exosystem/utility name = "exosuit circuit (utility systems)" contains_software = list(MECH_SOFTWARE_UTILITY) icon = 'icons/obj/modules/module_controller.dmi' - origin_tech = "{'programming':1}" + origin_tech = @'{"programming":1}' /obj/item/stock_parts/circuitboard/exosystem/medical name = "exosuit circuit (medical systems)" contains_software = list(MECH_SOFTWARE_MEDICAL) icon = 'icons/obj/modules/module_controller.dmi' - origin_tech = "{'programming':3,'biotech':2}" + origin_tech = @'{"programming":3,"biotech":2}' /obj/item/stock_parts/circuitboard/exosystem/weapons name = "exosuit circuit (basic weapon systems)" contains_software = list(MECH_SOFTWARE_WEAPONS) icon = 'icons/obj/modules/module_mainboard.dmi' - origin_tech = "{'programming':4,'combat':3}" + origin_tech = @'{"programming":4,"combat":3}' diff --git a/code/modules/mechs/equipment/_equipment.dm b/code/modules/mechs/equipment/_equipment.dm index c77140f9f53..effd53ec4e5 100644 --- a/code/modules/mechs/equipment/_equipment.dm +++ b/code/modules/mechs/equipment/_equipment.dm @@ -104,7 +104,7 @@ /obj/item/mech_equipment/mounted_system/proc/forget_holding() if(holding) //It'd be strange for this to be called with this var unset - events_repository.unregister(/decl/observ/destroyed, holding, src, .proc/forget_holding) + events_repository.unregister(/decl/observ/destroyed, holding, src, PROC_REF(forget_holding)) holding = null if(!QDELETED(src)) qdel(src) @@ -113,7 +113,7 @@ . = ..() if(ispath(holding)) holding = new holding(src) - events_repository.register(/decl/observ/destroyed, holding, src, .proc/forget_holding) + events_repository.register(/decl/observ/destroyed, holding, src, PROC_REF(forget_holding)) if(!istype(holding)) return if(!icon_state) @@ -123,7 +123,7 @@ desc = "[holding.desc] This one is suitable for installation on an exosuit." /obj/item/mech_equipment/mounted_system/Destroy() - events_repository.unregister(/decl/observ/destroyed, holding, src, .proc/forget_holding) + events_repository.unregister(/decl/observ/destroyed, holding, src, PROC_REF(forget_holding)) if(holding) QDEL_NULL(holding) . = ..() diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index 93526231dd9..188c458f3fc 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -2,7 +2,7 @@ name = "mounted electrolaser carbine" desc = "A dual fire mode electrolaser system connected to the exosuit's targetting system." icon_state = "mech_taser" - origin_tech = "{'combat':1,'magnets':1,'engineering':1}" + origin_tech = @'{"combat":1,"magnets":1,"engineering":1}' holding = /obj/item/gun/energy/taser/mounted/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_WEAPONS) @@ -12,14 +12,14 @@ desc = "An exosuit-mounted ion rifle. Handle with care." icon_state = "mech_ionrifle" holding = /obj/item/gun/energy/ionrifle/mounted/mech - origin_tech = "{'combat':2,'powerstorage':2,'magnets':4,'engineering':2}" + origin_tech = @'{"combat":2,"powerstorage":2,"magnets":4,"engineering":2}' /obj/item/mech_equipment/mounted_system/taser/laser name = "\improper CH-PS \"Immolator\" laser" desc = "An exosuit-mounted laser rifle. Handle with care." icon_state = "mech_lasercarbine" holding = /obj/item/gun/energy/laser/mounted/mech - origin_tech = "{'combat':3,'magnets':2,'engineering':2}" + origin_tech = @'{"combat":3,"magnets":2,"engineering":2}' /obj/item/gun/energy/taser/mounted/mech use_external_power = TRUE @@ -57,7 +57,7 @@ restricted_hardpoints = list(HARDPOINT_BACK) restricted_software = list(MECH_SOFTWARE_WEAPONS) material = /decl/material/solid/metal/steel - origin_tech = "{'magnets':3,'powerstorage':4,'materials':2,'engineering':2}" + origin_tech = @'{"magnets":3,"powerstorage":4,"materials":2,"engineering":2}' matter = list( /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE @@ -163,7 +163,7 @@ . = ..() add_vis_contents(target, src) set_dir(target.dir) - events_repository.register(/decl/observ/dir_set, user, src, /obj/aura/mechshield/proc/update_dir) + events_repository.register(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mechshield, update_dir)) /obj/aura/mechshield/proc/update_dir(var/user, var/old_dir, var/dir) set_dir(dir) @@ -176,7 +176,7 @@ /obj/aura/mechshield/Destroy() if(user) - events_repository.unregister(/decl/observ/dir_set, user, src, /obj/aura/mechshield/proc/update_dir) + events_repository.unregister(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mechshield, update_dir)) remove_vis_contents(user, src) shields = null . = ..() @@ -229,7 +229,7 @@ //Melee! As a general rule I would recommend using regular objects and putting logic in them. /obj/item/mech_equipment/mounted_system/melee abstract_type = /obj/item/mech_equipment/mounted_system/melee - origin_tech = "{'combat':1,'materials':1,'engineering':1}" + origin_tech = @'{"combat":1,"materials":1,"engineering":1}' restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_UTILITY) @@ -290,7 +290,7 @@ icon_state = "mech_shield" //Rendering is handled by aura due to layering issues: TODO, figure out a better way to do this restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_UTILITY) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' var/obj/aura/mech_ballistic/aura = null var/last_push = 0 var/chance = 60 //For attacks from the front, diminishing returns @@ -406,14 +406,14 @@ . = ..() add_vis_contents(target, src) set_dir(target.dir) - global.events_repository.register(/decl/observ/dir_set, user, src, /obj/aura/mech_ballistic/proc/update_dir) + global.events_repository.register(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mech_ballistic, update_dir)) /obj/aura/mech_ballistic/proc/update_dir(user, old_dir, dir) set_dir(dir) /obj/aura/mech_ballistic/Destroy() if (user) - global.events_repository.unregister(/decl/observ/dir_set, user, src, /obj/aura/mech_ballistic/proc/update_dir) + global.events_repository.unregister(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mech_ballistic, update_dir)) remove_vis_contents(user, src) shield = null . = ..() @@ -459,7 +459,7 @@ restricted_software = list(MECH_SOFTWARE_WEAPONS) active_power_use = 7 KILOWATTS var/next_use = 0 - origin_tech = "{'magnets':2,'combat':3}" + origin_tech = @'{"magnets":2,"combat":3}' /obj/item/mech_equipment/flash/proc/area_flash() playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) diff --git a/code/modules/mechs/equipment/combat_projectile.dm b/code/modules/mechs/equipment/combat_projectile.dm index 87c4d2ae6df..040ff1497f1 100644 --- a/code/modules/mechs/equipment/combat_projectile.dm +++ b/code/modules/mechs/equipment/combat_projectile.dm @@ -31,7 +31,7 @@ holding = /obj/item/gun/projectile/automatic/smg/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_WEAPONS) - origin_tech = "{'programming':4,'combat':6,'engineering':5}" + origin_tech = @'{"programming":4,"combat":6,"engineering":5}' /obj/item/gun/projectile/automatic/smg/mech magazine_type = /obj/item/ammo_magazine/mech/smg_top @@ -52,7 +52,7 @@ holding = /obj/item/gun/projectile/automatic/assault_rifle/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_WEAPONS) - origin_tech = "{'programming':4,'combat':8,'engineering':6}" + origin_tech = @'{"programming":4,"combat":8,"engineering":6}' /obj/item/gun/projectile/automatic/assault_rifle/mech magazine_type = /obj/item/ammo_magazine/mech/rifle @@ -72,7 +72,7 @@ holding = /obj/item/gun/projectile/automatic/machine/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_WEAPONS) - origin_tech = "{'programming':4,'combat':8,'engineering':6}" + origin_tech = @'{"programming":4,"combat":8,"engineering":6}' /obj/item/gun/projectile/automatic/machine/mech magazine_type = /obj/item/ammo_magazine/mech/rifle/drum diff --git a/code/modules/mechs/equipment/engineering.dm b/code/modules/mechs/equipment/engineering.dm index a53454e1b56..13a6d36bfab 100644 --- a/code/modules/mechs/equipment/engineering.dm +++ b/code/modules/mechs/equipment/engineering.dm @@ -1,7 +1,7 @@ /obj/item/mech_equipment/mounted_system/rcd icon_state = "mech_rcd" holding = /obj/item/rcd/mounted - origin_tech = "{'engineering':4,'materials':3,'powerstorage':1}" + origin_tech = @'{"engineering":4,"materials":3,"powerstorage":1}' restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_ENGINEERING) material = /decl/material/solid/metal/steel @@ -42,7 +42,7 @@ holding = /obj/item/chems/spray/extinguisher/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_ENGINEERING) - origin_tech = "{'engineering':1,'materials':1}" + origin_tech = @'{"engineering":1,"materials":1}' /obj/item/mech_equipment/atmos_shields icon_state = "mech_atmoshield_off" @@ -51,21 +51,21 @@ restricted_hardpoints = list(HARDPOINT_BACK) restricted_software = list(MECH_SOFTWARE_ENGINEERING) equipment_delay = 0.25 SECONDS - origin_tech = "{'engineering':2,'powerstorage':2,'materials':3}" + origin_tech = @'{"engineering":2,"powerstorage":2,"materials":3}' var/list/segments var/current_mode = 0 //0 barrier, 1 bubble var/shield_range = 2 // TODO: convert to alt interaction. -/obj/item/mech_equipment/atmos_shields/CtrlClick(mob/user) - if (owner && ((user in owner.pilots) || user == owner)) +/obj/item/mech_equipment/atmos_shields/AltClick(mob/user) + if (owner?.hatch_closed && ((user in owner.pilots) || user == owner)) if (active) to_chat(user, SPAN_WARNING("You cannot modify the projection mode while the shield is active.")) else current_mode = !current_mode to_chat(user, SPAN_NOTICE("You set the shields to [current_mode ? "bubble" : "barrier"] mode.")) - else - ..() + return TRUE + return ..() /obj/effect/mech_shield name = "energy shield" @@ -144,14 +144,14 @@ if(istype(MS)) MS.shields = src segments += MS - events_repository.register(/decl/observ/moved, MS, src, .proc/on_moved) + events_repository.register(/decl/observ/moved, MS, src, PROC_REF(on_moved)) passive_power_use = 0.8 KILOWATTS * segments.len update_icon() owner.update_icon() - events_repository.register(/decl/observ/moved, owner, src, .proc/on_moved) - events_repository.register(/decl/observ/dir_set, owner, src, .proc/on_turned) + events_repository.register(/decl/observ/moved, owner, src, PROC_REF(on_moved)) + events_repository.register(/decl/observ/dir_set, owner, src, PROC_REF(on_turned)) /obj/item/mech_equipment/atmos_shields/on_update_icon() . = ..() @@ -160,13 +160,13 @@ /obj/item/mech_equipment/atmos_shields/deactivate() for(var/obj/effect/mech_shield/MS in segments) if(istype(MS)) - events_repository.unregister(/decl/observ/moved, MS, src, .proc/on_moved) + events_repository.unregister(/decl/observ/moved, MS, src, PROC_REF(on_moved)) if(segments.len) owner.visible_message(SPAN_WARNING("The energy shields in front of \the [owner] disappear!")) QDEL_NULL_LIST(segments) passive_power_use = 0 - events_repository.unregister(/decl/observ/moved, owner, src, .proc/on_moved) - events_repository.unregister(/decl/observ/dir_set, owner, src, .proc/on_turned) + events_repository.unregister(/decl/observ/moved, owner, src, PROC_REF(on_moved)) + events_repository.unregister(/decl/observ/dir_set, owner, src, PROC_REF(on_turned)) . = ..() update_icon() owner.update_icon() diff --git a/code/modules/mechs/equipment/medical.dm b/code/modules/mechs/equipment/medical.dm index 35473b48113..4dc126c7cc7 100644 --- a/code/modules/mechs/equipment/medical.dm +++ b/code/modules/mechs/equipment/medical.dm @@ -6,7 +6,7 @@ restricted_software = list(MECH_SOFTWARE_MEDICAL) equipment_delay = 30 //don't spam it on people pls active_power_use = 0 //Usage doesn't really require power. We don't want people stuck inside - origin_tech = "{'programming':2,'biotech':3}" + origin_tech = @'{"programming":2,"biotech":3}' passive_power_use = 1.5 KILOWATTS var/obj/machinery/sleeper/mounted/sleeper = null diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm index 783d100cc18..288931c3e9b 100644 --- a/code/modules/mechs/equipment/utility.dm +++ b/code/modules/mechs/equipment/utility.dm @@ -4,7 +4,7 @@ icon_state = "mech_clamp" restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_UTILITY) - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' var/carrying_capacity = 5 var/list/obj/carrying = list() @@ -16,7 +16,13 @@ /obj/item/mech_equipment/clamp/attack_hand(mob/user) if(!owner || !LAZYISIN(owner.pilots, user) || owner.hatch_closed || !length(carrying) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/obj/chosen_obj = input(user, "Choose an object to grab.", "Clamp Claw") as null|anything in carrying + // Filter out non-items. + var/list/carrying_items = list() + for(var/obj/item/thing in carrying) + carrying_items += thing + if(!length(carrying_items)) + return TRUE + var/obj/item/chosen_obj = input(user, "Choose an object to grab.", "Clamp Claw") as null|anything in carrying_items if(chosen_obj && do_after(user, 20, owner) && !owner.hatch_closed && !QDELETED(chosen_obj) && (chosen_obj in carrying)) owner.visible_message(SPAN_NOTICE("\The [user] carefully grabs \the [chosen_obj] from \the [src].")) playsound(src, 'sound/mecha/hydraulic.ogg', 50, 1) @@ -49,7 +55,7 @@ playsound(FD, 'sound/effects/meteorimpact.ogg', 100, 1) playsound(FD, 'sound/machines/airlock_creaking.ogg', 100, 1) FD.blocked = FALSE - addtimer(CALLBACK(FD, /obj/machinery/door/firedoor/.proc/open, TRUE), 0) + addtimer(CALLBACK(FD, TYPE_PROC_REF(/obj/machinery/door/firedoor, open), TRUE), 0) FD.set_broken(TRUE) FD.visible_message(SPAN_WARNING("\The [owner] tears \the [FD] open!")) else @@ -58,10 +64,10 @@ playsound(FD, 'sound/machines/airlock_creaking.ogg', 100, 1) if(FD.density) FD.visible_message(SPAN_DANGER("\The [owner] forces \the [FD] open!")) - addtimer(CALLBACK(FD, /obj/machinery/door/firedoor/.proc/open, TRUE), 0) + addtimer(CALLBACK(FD, TYPE_PROC_REF(/obj/machinery/door/firedoor, open), TRUE), 0) else FD.visible_message(SPAN_WARNING("\The [owner] forces \the [FD] closed!")) - addtimer(CALLBACK(FD, /obj/machinery/door/firedoor/.proc/close, TRUE), 0) + addtimer(CALLBACK(FD, TYPE_PROC_REF(/obj/machinery/door/firedoor, close), TRUE), 0) return else if(istype(O, /obj/machinery/door/airlock)) var/obj/machinery/door/airlock/AD = O @@ -74,7 +80,7 @@ playsound(AD, 'sound/effects/meteorimpact.ogg', 100, 1) playsound(AD, 'sound/machines/airlock_creaking.ogg', 100, 1) AD.visible_message(SPAN_DANGER("\The [owner] tears \the [AD] open!")) - addtimer(CALLBACK(AD, /obj/machinery/door/airlock/.proc/open, TRUE), 0) + addtimer(CALLBACK(AD, TYPE_PROC_REF(/obj/machinery/door/airlock, open), TRUE), 0) AD.set_broken(TRUE) return else @@ -82,12 +88,12 @@ if((AD.is_broken(NOPOWER) || do_after(owner, 5 SECONDS,AD)) && !(AD.operating || AD.welded || AD.locked)) playsound(AD, 'sound/machines/airlock_creaking.ogg', 100, 1) if(AD.density) - addtimer(CALLBACK(AD, /obj/machinery/door/airlock/.proc/open, TRUE), 0) + addtimer(CALLBACK(AD, TYPE_PROC_REF(/obj/machinery/door/airlock, open), TRUE), 0) if(!AD.is_broken(NOPOWER)) AD.set_broken(TRUE) AD.visible_message(SPAN_DANGER("\The [owner] forces \the [AD] open!")) else - addtimer(CALLBACK(AD, /obj/machinery/door/airlock/.proc/close, TRUE), 0) + addtimer(CALLBACK(AD, TYPE_PROC_REF(/obj/machinery/door/airlock, close), TRUE), 0) if(!AD.is_broken(NOPOWER)) AD.set_broken(TRUE) AD.visible_message(SPAN_DANGER("\The [owner] forces \the [AD] closed!")) @@ -133,11 +139,11 @@ if(.) drop_carrying(user, TRUE) -/obj/item/mech_equipment/clamp/CtrlClick(mob/user) - if(owner) +/obj/item/mech_equipment/clamp/AltClick(mob/user) + if(owner?.hatch_closed) drop_carrying(user, FALSE) - else - ..() + return TRUE + return ..() /obj/item/mech_equipment/clamp/proc/drop_carrying(var/mob/user, var/choose_object) if(!length(carrying)) @@ -197,7 +203,7 @@ item_state = "mech_floodlight" restricted_hardpoints = list(HARDPOINT_HEAD, HARDPOINT_LEFT_SHOULDER, HARDPOINT_RIGHT_SHOULDER) mech_layer = MECH_INTERMEDIATE_LAYER - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' var/on = 0 var/l_power = 0.9 @@ -251,7 +257,7 @@ var/mode = CATAPULT_SINGLE var/atom/movable/locked equipment_delay = 30 //Stunlocks are not ideal - origin_tech = "{'materials':4,'engineering':4,'magnets':4}" + origin_tech = @'{"materials":4,"engineering":4,"magnets":4}' require_adjacent = FALSE /obj/item/mech_equipment/catapult/get_hardpoint_maptext() @@ -372,7 +378,7 @@ //Drill can have a head var/obj/item/drill_head/drill_head - origin_tech = "{'materials':2,'engineering':2}" + origin_tech = @'{"materials":2,"engineering":2}' /obj/item/mech_equipment/drill/Initialize() . = ..() @@ -547,14 +553,14 @@ holding = /obj/item/gun/energy/plasmacutter/mounted/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND, HARDPOINT_LEFT_SHOULDER, HARDPOINT_RIGHT_SHOULDER) restricted_software = list(MECH_SOFTWARE_UTILITY) - origin_tech = "{'materials':4,'engineering':6,'exoticmatter':4,'combat':3}" + origin_tech = @'{"materials":4,"engineering":6,"exoticmatter":4,"combat":3}' /obj/item/mech_equipment/mounted_system/taser/autoplasma icon_state = "mech_energy" holding = /obj/item/gun/energy/plasmacutter/mounted/mech/auto restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_UTILITY) - origin_tech = "{'materials':5,'engineering':6,'exoticmatter':4,'combat':4}" + origin_tech = @'{"materials":5,"engineering":6,"exoticmatter":4,"combat":4}' /obj/item/gun/energy/plasmacutter/mounted/mech/auto charge_cost = 13 @@ -576,7 +582,7 @@ passive_power_use = 0 KILOWATTS var/activated_passive_power = 2 KILOWATTS var/movement_power = 75 - origin_tech = "{'magnets':3,'engineering':3,'exoticmatter':3}" + origin_tech = @'{"magnets":3,"engineering":3,"exoticmatter":3}' var/datum/effect/effect/system/trail/ion/ion_trail require_adjacent = FALSE var/stabilizers = FALSE @@ -614,13 +620,12 @@ else activate() -/obj/item/mech_equipment/ionjets/CtrlClick(mob/user) - if (owner && ((user in owner.pilots) || user == owner)) - if (active) - stabilizers = !stabilizers - to_chat(user, SPAN_NOTICE("You toggle the stabilizers [stabilizers ? "on" : "off"]")) - else - ..() +/obj/item/mech_equipment/ionjets/AltClick(mob/user) + if(owner?.hatch_closed && ((user in owner.pilots) || user == owner) && active) + stabilizers = !stabilizers + to_chat(user, SPAN_NOTICE("You toggle the stabilizers [stabilizers ? "on" : "off"]")) + return TRUE + return ..() /obj/item/mech_equipment/ionjets/proc/activate() passive_power_use = activated_passive_power @@ -700,7 +705,7 @@ restricted_software = list(MECH_SOFTWARE_UTILITY) equipment_delay = 10 - origin_tech = "{'materials':1,'engineering':1,'magnets':2}" + origin_tech = @'{"materials":1,"engineering":1,"magnets":2}' /obj/item/mech_equipment/camera/Initialize() diff --git a/code/modules/mechs/interface/_interface.dm b/code/modules/mechs/interface/_interface.dm index 42f184477cf..bced208448d 100644 --- a/code/modules/mechs/interface/_interface.dm +++ b/code/modules/mechs/interface/_interface.dm @@ -56,6 +56,13 @@ refresh_hud() +/mob/living/exosuit/should_do_hud_updates() + . = ..() + if(!. && length(pilots)) + for(var/mob/living/pilot in pilots) + if(pilot.should_do_hud_updates()) + return TRUE + /mob/living/exosuit/handle_hud_icons() for(var/hardpoint in hardpoint_hud_elements) var/obj/screen/exosuit/hardpoint/H = hardpoint_hud_elements[hardpoint] @@ -120,4 +127,4 @@ if(H) H.color = "#a03b3b" animate(H, color = COLOR_WHITE, time = timeout, easing = CUBIC_EASING | EASE_IN) - addtimer(CALLBACK(src, .proc/reset_hardpoint_color), timeout) \ No newline at end of file + addtimer(CALLBACK(src, PROC_REF(reset_hardpoint_color)), timeout) \ No newline at end of file diff --git a/code/modules/mechs/mech_construction.dm b/code/modules/mechs/mech_construction.dm index 35f6b87b440..8a2bfd3b391 100644 --- a/code/modules/mechs/mech_construction.dm +++ b/code/modules/mechs/mech_construction.dm @@ -45,7 +45,7 @@ if(target == selected_hardpoint) clear_selected_hardpoint() - events_repository.unregister(/decl/observ/destroyed, module_to_forget, src, .proc/forget_module) + events_repository.unregister(/decl/observ/destroyed, module_to_forget, src, PROC_REF(forget_module)) var/obj/screen/exosuit/hardpoint/H = hardpoint_hud_elements[target] H.holding = null @@ -96,7 +96,7 @@ playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1) else return FALSE - events_repository.register(/decl/observ/destroyed, system, src, .proc/forget_module) + events_repository.register(/decl/observ/destroyed, system, src, PROC_REF(forget_module)) system.forceMove(src) hardpoints[system_hardpoint] = system @@ -139,7 +139,7 @@ system.forceMove(get_turf(src)) system.screen_loc = null system.layer = initial(system.layer) - events_repository.unregister(/decl/observ/destroyed, system, src, .proc/forget_module) + events_repository.unregister(/decl/observ/destroyed, system, src, PROC_REF(forget_module)) var/obj/screen/exosuit/hardpoint/H = hardpoint_hud_elements[system_hardpoint] H.holding = null diff --git a/code/modules/mechs/mech_icon.dm b/code/modules/mechs/mech_icon.dm index 208505e5219..d0beae15179 100644 --- a/code/modules/mechs/mech_icon.dm +++ b/code/modules/mechs/mech_icon.dm @@ -1,5 +1,6 @@ -/proc/get_mech_image(var/decal, var/cache_key, var/cache_icon, var/image_colour, var/overlay_layer = FLOAT_LAYER) - var/use_key = "[cache_key]-[cache_icon]-[overlay_layer]-[decal ? decal : "none"]-[image_colour ? image_colour : "none"]" +/proc/get_mech_image(var/decal, var/decal_blend = BLEND_MULTIPLY, var/cache_key, var/cache_icon, var/image_colour, var/overlay_layer = FLOAT_LAYER) + + var/use_key = "[cache_key]-[cache_icon]-[overlay_layer]-[decal ? decal : "none"]-[decal_blend]-[image_colour ? image_colour : "none"]" if(!global.mech_image_cache[use_key]) var/image/I = image(icon = cache_icon, icon_state = cache_key) if(image_colour) @@ -8,43 +9,42 @@ masked_color.blend_mode = BLEND_MULTIPLY I.overlays += masked_color if(decal) - var/decal_key = "[decal]-[cache_key]" + var/decal_key = "[decal]-[decal_blend]-[cache_key]" if(!global.mech_icon_cache[decal_key]) var/template_key = "template-[cache_key]" + var/icon/decal_icon = icon('icons/mecha/mech_decals.dmi', decal) if(!global.mech_icon_cache[template_key]) global.mech_icon_cache[template_key] = icon(cache_icon, "[cache_key]_mask") - var/icon/decal_icon = icon('icons/mecha/mech_decals.dmi',decal) decal_icon.AddAlphaMask(global.mech_icon_cache[template_key]) global.mech_icon_cache[decal_key] = decal_icon - var/image/decal_image = get_mech_image(null, decal_key, global.mech_icon_cache[decal_key]) - decal_image.blend_mode = BLEND_MULTIPLY + var/image/decal_image = get_mech_image(null, null, decal_key, global.mech_icon_cache[decal_key]) + decal_image.blend_mode = decal_blend + decal_image.appearance_flags |= RESET_COLOR I.overlays += decal_image I.appearance_flags |= RESET_COLOR I.layer = overlay_layer I.plane = FLOAT_PLANE global.mech_image_cache[use_key] = I - return global.mech_image_cache[use_key] -/proc/get_mech_images(var/list/components = list(), var/overlay_layer = FLOAT_LAYER) - var/list/all_images = list() - for(var/obj/item/mech_component/comp in components) - all_images += get_mech_image(comp.decal, comp.icon_state, comp.on_mech_icon, comp.color, overlay_layer) - return all_images + var/image/I = new + I.appearance = global.mech_image_cache[use_key] + return I /mob/living/exosuit/on_update_icon() ..() - var/list/new_overlays = get_mech_images(list(body, head), MECH_BASE_LAYER) + var/list/new_overlays = list() if(body) - new_overlays += get_mech_image(body.decal, "[body.icon_state]_cockpit", body.on_mech_icon, overlay_layer = MECH_INTERMEDIATE_LAYER) + new_overlays += get_mech_image(body.decal, body.decal_blend, body.icon_state, body.on_mech_icon, body.color, overlay_layer = MECH_BASE_LAYER) + new_overlays += get_mech_image(body.decal, body.decal_blend, "[body.icon_state]_cockpit", body.on_mech_icon, overlay_layer = MECH_INTERMEDIATE_LAYER) update_pilots(FALSE) if(LAZYLEN(pilot_overlays)) new_overlays += pilot_overlays if(body) - new_overlays += get_mech_image(body.decal, "[body.icon_state]_overlay[hatch_closed ? "" : "_open"]", body.on_mech_icon, body.color, MECH_COCKPIT_LAYER) + new_overlays += get_mech_image(body.decal, body.decal_blend, "[body.icon_state]_overlay[hatch_closed ? "" : "_open"]", body.on_mech_icon, body.color, MECH_COCKPIT_LAYER) if(arms) - new_overlays += get_mech_image(arms.decal, arms.icon_state, arms.on_mech_icon, arms.color, MECH_ARM_LAYER) + new_overlays += get_mech_image(arms.decal, arms.decal_blend, arms.icon_state, arms.on_mech_icon, arms.color, MECH_ARM_LAYER) if(legs) - new_overlays += get_mech_image(legs.decal, legs.icon_state, legs.on_mech_icon, legs.color, MECH_LEG_LAYER) + new_overlays += get_mech_image(legs.decal, legs.decal_blend, legs.icon_state, legs.on_mech_icon, legs.color, MECH_LEG_LAYER) for(var/hardpoint in hardpoints) var/obj/item/mech_equipment/hardpoint_object = hardpoints[hardpoint] if(hardpoint_object) @@ -52,17 +52,21 @@ if(use_icon_state in global.mech_weapon_overlays) var/color = COLOR_WHITE var/decal = null + var/decal_blend = BLEND_MULTIPLY if(hardpoint in list(HARDPOINT_BACK, HARDPOINT_RIGHT_SHOULDER, HARDPOINT_LEFT_SHOULDER)) - color = body.color - decal = body.decal + color = body.color + decal = body.decal + decal_blend = body.decal_blend else if(hardpoint in list(HARDPOINT_RIGHT_HAND, HARDPOINT_LEFT_HAND)) - color = arms.color - decal = arms.decal + color = arms.color + decal = arms.decal + decal_blend = arms.decal_blend else - color = head.color - decal = head.decal + color = head.color + decal = head.decal + decal_blend = head.decal_blend + new_overlays += get_mech_image(decal, decal_blend, use_icon_state, 'icons/mecha/mech_weapon_overlays.dmi', color, hardpoint_object.mech_layer ) - new_overlays += get_mech_image(decal, use_icon_state, 'icons/mecha/mech_weapon_overlays.dmi', color, hardpoint_object.mech_layer ) set_overlays(new_overlays) /mob/living/exosuit/proc/update_pilots(var/update_overlays = TRUE) @@ -91,7 +95,7 @@ var/diff_x = 8 - draw_pilot.pixel_x var/diff_y = 8 - draw_pilot.pixel_y draw_pilot.add_filter("pilot_mask", 1, list(type = "alpha", icon = icon(body.on_mech_icon, "[body.icon_state]_pilot_mask[hatch_closed ? "" : "_open"]", dir), x = diff_x, y = diff_y)) - + LAZYADD(pilot_overlays, draw_pilot) if(update_overlays && LAZYLEN(pilot_overlays)) overlays += pilot_overlays diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm index 867f92eed14..55489875a8e 100644 --- a/code/modules/mechs/mech_interaction.dm +++ b/code/modules/mechs/mech_interaction.dm @@ -327,15 +327,14 @@ /mob/living/exosuit/attackby(var/obj/item/thing, var/mob/user) + // Install equipment. if(user.a_intent != I_HURT && istype(thing, /obj/item/mech_equipment)) if(hardpoints_locked) to_chat(user, SPAN_WARNING("Hardpoint system access is disabled.")) - return - + return TRUE var/obj/item/mech_equipment/realThing = thing if(realThing.owner) - return - + return TRUE var/free_hardpoints = list() for(var/hardpoint in hardpoints) if(hardpoints[hardpoint] == null) @@ -343,12 +342,12 @@ var/to_place = input("Where would you like to install it?") as null|anything in (realThing.restricted_hardpoints & free_hardpoints) if(!to_place) to_chat(user, SPAN_WARNING("There is no room to install \the [thing].")) - if(install_system(thing, to_place, user)) - return - to_chat(user, SPAN_WARNING("\The [thing] could not be installed in that hardpoint.")) - return + else if(!install_system(thing, to_place, user)) + to_chat(user, SPAN_WARNING("\The [thing] could not be installed in that hardpoint.")) + return TRUE - else if(istype(thing, /obj/item/kit/paint)) + // Apply customisation. + if(istype(thing, /obj/item/kit/paint)) user.visible_message(SPAN_NOTICE("\The [user] opens \the [thing] and spends some quality time customising \the [src].")) var/obj/item/kit/paint/P = thing @@ -359,77 +358,83 @@ for(var/obj/item/mech_component/comp in list(arms, legs, head, body)) comp.decal = P.new_state + if(!isnull(P.new_blend)) + for(var/obj/item/mech_component/comp in list(arms, legs, head, body)) + comp.decal_blend = P.new_blend + if(P.new_icon) for(var/obj/item/mech_component/comp in list(arms, legs, head, body)) comp.icon = P.new_icon - queue_icon_update() + update_icon() P.use(1, user) - return 1 - - else - if(user.a_intent != I_HURT) - if(IS_MULTITOOL(thing)) - if(hardpoints_locked) - to_chat(user, SPAN_WARNING("Hardpoint system access is disabled.")) - return - - var/list/parts = list() - for(var/hardpoint in hardpoints) - if(hardpoints[hardpoint]) - parts += hardpoint + return TRUE - var/to_remove = input("Which component would you like to remove") as null|anything in parts + // Various tool and construction interactions. + if(user.a_intent != I_HURT) - if(remove_system(to_remove, user)) - return + // Removing systems from hardpoints. + if(IS_MULTITOOL(thing)) + if(hardpoints_locked) + to_chat(user, SPAN_WARNING("Hardpoint system access is disabled.")) + return TRUE + var/list/parts = list() + for(var/hardpoint in hardpoints) + if(hardpoints[hardpoint]) + parts += hardpoint + var/to_remove = input("Which component would you like to remove") as null|anything in parts + if(!remove_system(to_remove, user)) to_chat(user, SPAN_WARNING("\The [src] has no hardpoint systems to remove.")) - return - else if(IS_WRENCH(thing)) - if(!maintenance_protocols) - to_chat(user, SPAN_WARNING("The securing bolts are not visible while maintenance protocols are disabled.")) - return - - visible_message(SPAN_WARNING("\The [user] begins unwrenching the securing bolts holding \the [src] together.")) - var/delay = 60 * user.skill_delay_mult(SKILL_DEVICES) - if(!do_after(user, delay) || !maintenance_protocols) - return + return TRUE + + // Dismantling an exosuit entirely. + if(IS_WRENCH(thing)) + if(!maintenance_protocols) + to_chat(user, SPAN_WARNING("The securing bolts are not visible while maintenance protocols are disabled.")) + return TRUE + visible_message(SPAN_WARNING("\The [user] begins unwrenching the securing bolts holding \the [src] together.")) + var/delay = 60 * user.skill_delay_mult(SKILL_DEVICES) + if(do_after(user, delay) && maintenance_protocols) visible_message(SPAN_NOTICE("\The [user] loosens and removes the securing bolts, dismantling \the [src].")) dismantle() - return - else if(IS_WELDER(thing)) - if(!getBruteLoss()) - return - var/list/damaged_parts = list() - for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) - if(MC && MC.brute_damage) - damaged_parts += MC - var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts - if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.brute_damage) - to_fix.repair_brute_generic(thing, user) - return - else if(IS_COIL(thing)) - if(!getFireLoss()) - return - var/list/damaged_parts = list() - for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) - if(MC && MC.burn_damage) - damaged_parts += MC - var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts - if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.burn_damage) - to_fix.repair_burn_generic(thing, user) - return - else if(IS_SCREWDRIVER(thing)) - if(!maintenance_protocols) - to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) - return - if(!body || !body.cell) - to_chat(user, SPAN_WARNING("There is no cell here for you to remove!")) - return - var/delay = 20 * user.skill_delay_mult(SKILL_DEVICES) - if(!do_after(user, delay) || !maintenance_protocols || !body || !body.cell) - return + return TRUE + // Brute damage repair. + if(IS_WELDER(thing)) + if(!getBruteLoss()) + return TRUE + var/list/damaged_parts = list() + for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) + if(MC && MC.brute_damage) + damaged_parts += MC + var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts + if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.brute_damage) + to_fix.repair_brute_generic(thing, user) + return TRUE + + // Burn damage repair. + if(IS_COIL(thing)) + if(!getFireLoss()) + return TRUE + var/list/damaged_parts = list() + for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) + if(MC && MC.burn_damage) + damaged_parts += MC + var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts + if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.burn_damage) + to_fix.repair_burn_generic(thing, user) + return TRUE + + // Cell removal. + if(IS_SCREWDRIVER(thing)) + if(!maintenance_protocols) + to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) + return TRUE + if(!body || !body.cell) + to_chat(user, SPAN_WARNING("There is no cell here for you to remove!")) + return TRUE + var/delay = (2 SECONDS) * user.skill_delay_mult(SKILL_DEVICES) + if(do_after(user, delay) && maintenance_protocols && body?.cell) user.put_in_hands(body.cell) to_chat(user, SPAN_NOTICE("You remove \the [body.cell] from \the [src].")) playsound(user.loc, 'sound/items/Crowbar.ogg', 50, 1) @@ -437,17 +442,18 @@ power = MECH_POWER_OFF hud_power_control.queue_icon_update() body.cell = null - return - else if(IS_CROWBAR(thing)) - if(!hatch_locked) - to_chat(user, SPAN_NOTICE("The cockpit isn't locked. There is no need for this.")) - return - if(!body) //Error - return - var/delay = min(50 * user.skill_delay_mult(SKILL_DEVICES), 50 * user.skill_delay_mult(SKILL_EVA)) - visible_message(SPAN_NOTICE("\The [user] starts forcing the \the [src]'s emergency [body.hatch_descriptor] release using \the [thing].")) - if(!do_after(user, delay, src)) - return + return TRUE + + // Force-opening the cockpit. + if(IS_CROWBAR(thing)) + if(!hatch_locked) + to_chat(user, SPAN_NOTICE("The cockpit isn't locked. There is no need for this.")) + return TRUE + if(!body) //Error + return TRUE + var/delay = min(50 * user.skill_delay_mult(SKILL_DEVICES), 50 * user.skill_delay_mult(SKILL_EVA)) + visible_message(SPAN_NOTICE("\The [user] starts forcing the \the [src]'s emergency [body.hatch_descriptor] release using \the [thing].")) + if(do_after(user, delay, src)) visible_message(SPAN_NOTICE("\The [user] forces \the [src]'s [body.hatch_descriptor] open using the \the [thing].")) playsound(user.loc, 'sound/machines/bolts_up.ogg', 25, 1) hatch_locked = FALSE @@ -456,28 +462,32 @@ eject(pilot, silent = 1) hud_open.queue_icon_update() queue_icon_update() - return - else if(istype(thing, /obj/item/cell)) - if(!maintenance_protocols) - to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) - return - if(!body || body.cell) - to_chat(user, SPAN_WARNING("There is already a cell in there!")) - return - - if(user.try_unequip(thing)) - thing.forceMove(body) - body.cell = thing - to_chat(user, SPAN_NOTICE("You install \the [body.cell] into \the [src].")) - playsound(user.loc, 'sound/items/Screwdriver.ogg', 50, 1) - visible_message(SPAN_NOTICE("\The [user] installs \the [body.cell] into \the [src].")) - return - else if(istype(thing, /obj/item/robotanalyzer)) - to_chat(user, SPAN_NOTICE("Diagnostic Report for \the [src]:")) - for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) - if(MC) - MC.return_diagnostics(user) - return + return TRUE + + // Cell replacement. + if(istype(thing, /obj/item/cell)) + if(!maintenance_protocols) + to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) + return TRUE + if(body?.cell) + to_chat(user, SPAN_WARNING("There is already a cell in there!")) + return TRUE + if(user.try_unequip(thing)) + thing.forceMove(body) + body.cell = thing + to_chat(user, SPAN_NOTICE("You install \the [body.cell] into \the [src].")) + playsound(user.loc, 'sound/items/Screwdriver.ogg', 50, 1) + visible_message(SPAN_NOTICE("\The [user] installs \the [body.cell] into \the [src].")) + return TRUE + + // Diagnostic scan. + if(istype(thing, /obj/item/robotanalyzer)) + to_chat(user, SPAN_NOTICE("Diagnostic Report for \the [src]:")) + for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) + if(MC) + MC.return_diagnostics(user) + return TRUE + return ..() /mob/living/exosuit/default_interaction(var/mob/user) diff --git a/code/modules/mechs/mech_life.dm b/code/modules/mechs/mech_life.dm index 18975123d54..ad1964eb516 100644 --- a/code/modules/mechs/mech_life.dm +++ b/code/modules/mechs/mech_life.dm @@ -1,7 +1,16 @@ /mob/living/exosuit/handle_disabilities() return -/mob/living/exosuit/Life() +/mob/living/exosuit/update_lying() + lying = FALSE // Prevent carp from proning us + +/mob/living/exosuit/handle_regular_status_updates() + + if(!body && !QDELETED(src)) + physically_destroyed() + return FALSE + + . = ..() for(var/thing in pilots) var/mob/pilot = thing @@ -12,20 +21,10 @@ UNSETEMPTY(pilots) update_pilots() - if(!body && !QDELETED(src)) - qdel(src) - return - if(radio) radio.on = (head && head.radio && head.radio.is_functional() && get_cell()) - body.update_air(hatch_closed && use_air) - - var/powered = FALSE - if(get_cell()) - powered = get_cell().drain_power(0, 0, calc_power_draw()) > 0 - - if(!powered) + if(!is_suit_powered()) //Shut down all systems if(head) head.active_sensors = FALSE @@ -35,16 +34,11 @@ if(istype(M) && M.active && M.passive_power_use) M.deactivate() - update_health() // TODO: move to handle_regular_status_updates(), Life PR - if(emp_damage > 0) emp_damage -= min(1, emp_damage) //Reduce emp accumulation over time - ..() //Handles stuff like environment - - handle_hud_icons() - lying = FALSE // Fuck off, carp. - handle_vision(powered) +/mob/living/exosuit/proc/is_suit_powered() + return (get_cell()?.drain_power(0, 0, calc_power_draw())) > 0 /mob/living/exosuit/get_cell(force) RETURN_TYPE(/obj/item/cell) @@ -71,7 +65,13 @@ /mob/living/exosuit/handle_environment(var/datum/gas_mixture/environment) ..() - if(!environment) return + + if(body) + body.update_air(hatch_closed && use_air) + + if(!environment) + return + //Mechs and vehicles in general can be assumed to just tend to whatever ambient temperature if(abs(environment.temperature - bodytemperature) > 0 ) bodytemperature += ((environment.temperature - bodytemperature) / 6) @@ -123,14 +123,14 @@ qdel(src) return -/mob/living/exosuit/handle_vision(powered) +/mob/living/exosuit/handle_vision() var/was_blind = sight & BLIND if(head) + var/powered = is_suit_powered() sight = head.get_sight(powered) see_invisible = head.get_invisible(powered) if(body && (body.pilot_coverage < 100 || body.transparent_cabin) || !hatch_closed) sight &= ~BLIND - if(sight & BLIND && !was_blind) for(var/mob/pilot in pilots) to_chat(pilot, SPAN_WARNING("The sensors are not operational and you cannot see a thing!")) diff --git a/code/modules/mechs/premade/_premade.dm b/code/modules/mechs/premade/_premade.dm index 98c988b32f8..77914bfc25d 100644 --- a/code/modules/mechs/premade/_premade.dm +++ b/code/modules/mechs/premade/_premade.dm @@ -9,6 +9,7 @@ pixel_x = 0 pixel_y = 0 var/decal + var/decal_blend = BLEND_MULTIPLY /mob/living/exosuit/premade/Initialize() @@ -20,20 +21,16 @@ icon = null icon_state = null - if(arms) - arms.decal = decal - arms.prebuild() - if(legs) - legs.decal = decal - legs.prebuild() - if(head) - head.decal = decal - head.prebuild() - if(body) - body.decal = decal - body.prebuild() + for(var/obj/item/mech_component/comp in list(arms, legs, head, body)) + if(decal) + comp.decal = decal + if(!isnull(decal_blend)) + comp.decal_blend = decal_blend + comp.prebuild() + if(!material) material = GET_DECL(/decl/material/solid/metal/steel) + . = ..() spawn_mech_equipment() diff --git a/code/modules/mechs/premade/powerloader.dm b/code/modules/mechs/premade/powerloader.dm index 45c7c782aa4..20c9babd52f 100644 --- a/code/modules/mechs/premade/powerloader.dm +++ b/code/modules/mechs/premade/powerloader.dm @@ -111,12 +111,13 @@ name = "APLU \"Firestarter\"" desc = "An ancient, but well-liked cargo handling exosuit. This one has cool red flames." decal = "flames_red" + decal_blend = BLEND_OVERLAY /mob/living/exosuit/premade/powerloader/flames_blue name = "APLU \"Burning Chrome\"" desc = "An ancient, but well-liked cargo handling exosuit. This one has cool blue flames." decal = "flames_blue" - + decal_blend = BLEND_OVERLAY /mob/living/exosuit/premade/firefighter name = "firefighting exosuit" diff --git a/code/modules/mining/drilling/drill_act.dm b/code/modules/mining/drilling/drill_act.dm index 30c1e1b9259..bca8f07cc86 100644 --- a/code/modules/mining/drilling/drill_act.dm +++ b/code/modules/mining/drilling/drill_act.dm @@ -19,15 +19,3 @@ /turf/space/drill_act() SHOULD_CALL_PARENT(FALSE) - -/turf/simulated/open/drill_act() - SHOULD_CALL_PARENT(FALSE) - var/turf/T = GetBelow(src) - if(istype(T)) - T.drill_act() - -/turf/exterior/open/drill_act() - SHOULD_CALL_PARENT(FALSE) - var/turf/T = GetBelow(src) - if(istype(T)) - T.drill_act() diff --git a/code/modules/mining/machinery/_material_processing.dm b/code/modules/mining/machinery/_material_processing.dm index 0d20dfaf71b..f149ec055a4 100644 --- a/code/modules/mining/machinery/_material_processing.dm +++ b/code/modules/mining/machinery/_material_processing.dm @@ -90,7 +90,7 @@ /obj/machinery/material_processing/Destroy() input_turf = null output_turf = null - events_repository.unregister(/decl/observ/moved, src, src, .proc/on_moved) + events_repository.unregister(/decl/observ/moved, src, src, PROC_REF(on_moved)) . = ..() /obj/machinery/material_processing/Initialize() @@ -99,7 +99,7 @@ SET_OUTPUT(output_turf) . = ..() queue_icon_update() - events_repository.register(/decl/observ/moved, src, src, .proc/on_moved) + events_repository.register(/decl/observ/moved, src, src, PROC_REF(on_moved)) /obj/machinery/material_processing/proc/on_moved(atom/moving, atom/old_loc, atom/new_loc) if(istype(input_turf, /turf)) diff --git a/code/modules/mining/machinery/material_extractor.dm b/code/modules/mining/machinery/material_extractor.dm index ce75a62e0ed..08c9ad8b7f3 100644 --- a/code/modules/mining/machinery/material_extractor.dm +++ b/code/modules/mining/machinery/material_extractor.dm @@ -88,7 +88,7 @@ if(eating.reagents?.total_volume) eating.reagents.trans_to_obj(src, eating.reagents.total_volume) for(var/mtype in eating.matter) - reagents.add_reagent(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) + add_to_reagents(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) qdel(eating) if(eaten >= MAX_INTAKE_ORE_PER_TICK) break @@ -130,7 +130,7 @@ if(processed_mols) // The ratio processed_moles/moles gives us the ratio of the reagent volume to what should be removed // since the mole to unit conversion is linear. - reagents.remove_reagent(mtype, reagent_vol*(processed_mols/mols), defer_update = TRUE) + remove_from_reagents(mtype, reagent_vol*(processed_mols/mols), defer_update = TRUE) use_power_oneoff(power_draw_per_mol*mols) // Still somewhat arbitary @@ -148,7 +148,7 @@ if(sheets > 0) // If we can't process any sheets at all, leave it for manual processing. adjusted_reagents = TRUE SSmaterials.create_object(mtype, output_turf, sheets) - reagents.remove_reagent(mtype, removing) + remove_from_reagents(mtype, removing) return adjusted_reagents @@ -173,7 +173,7 @@ if(!user.try_unequip(I, src)) return output_container = I - events_repository.register(/decl/observ/destroyed, output_container, src, /obj/machinery/material_processing/extractor/proc/remove_container) + events_repository.register(/decl/observ/destroyed, output_container, src, TYPE_PROC_REF(/obj/machinery/material_processing/extractor, remove_container)) user.visible_message(SPAN_NOTICE("\The [user] places \a [I] in \the [src]."), SPAN_NOTICE("You place \a [I] in \the [src].")) return @@ -185,7 +185,7 @@ if(!output_container) return . = output_container - events_repository.unregister(/decl/observ/destroyed, output_container, src, /obj/machinery/material_processing/extractor/proc/remove_container) + events_repository.unregister(/decl/observ/destroyed, output_container, src, TYPE_PROC_REF(/obj/machinery/material_processing/extractor, remove_container)) output_container = null /obj/machinery/material_processing/extractor/OnTopic(var/mob/user, var/list/href_list) diff --git a/code/modules/mining/machinery/material_smelter.dm b/code/modules/mining/machinery/material_smelter.dm index a696a6a28cc..96c98830139 100644 --- a/code/modules/mining/machinery/material_smelter.dm +++ b/code/modules/mining/machinery/material_smelter.dm @@ -41,7 +41,7 @@ if(mat.boiling_point && temperature >= mat.boiling_point) adjusted_air = TRUE var/removing = REAGENT_VOLUME(reagents, mtype) - reagents.remove_reagent(mtype, removing, defer_update = TRUE) + remove_from_reagents(mtype, removing, defer_update = TRUE) if(environment) environment.adjust_gas_temp(mtype, (removing * 0.2), temperature, FALSE) // Arbitrary conversion constant, TODO consistent one @@ -92,7 +92,7 @@ if(eating.reagents?.total_volume) eating.reagents.trans_to_obj(src, FLOOR(eating.reagents.total_volume * 0.75)) // liquid reagents, lossy for(var/mtype in eating.matter) - reagents.add_reagent(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) + add_to_reagents(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) qdel(eating) if(eaten >= MAX_INTAKE_ORE_PER_TICK) break @@ -103,7 +103,7 @@ continue visible_message(SPAN_DANGER("\The [src] rips \the [H]'s [eating.name] clean off!")) for(var/mtype in eating.matter) - reagents.add_reagent(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) + add_to_reagents(mtype, FLOOR(eating.matter[mtype] * REAGENT_UNITS_PER_MATERIAL_UNIT)) eating.dismember(silent = TRUE) qdel(eating) break @@ -114,7 +114,7 @@ var/samt = FLOOR((ramt / REAGENT_UNITS_PER_MATERIAL_UNIT) / SHEET_MATERIAL_AMOUNT) if(samt > 0) SSmaterials.create_object(mtype, output_turf, samt) - reagents.remove_reagent(mtype, ramt) + remove_from_reagents(mtype, ramt) /obj/machinery/material_processing/smeltery/Topic(var/user, var/list/href_list) . = ..() diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index a5e4141482b..d00889ef2d9 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -36,7 +36,7 @@ throwforce = 4 w_class = ITEM_SIZE_HUGE material = /decl/material/solid/metal/steel - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' attack_verb = list("hit", "pierced", "sliced", "attacked") sharp = 0 @@ -64,7 +64,7 @@ /obj/item/pickaxe/proc/get_initial_tool_qualities() return list(TOOL_SHOVEL = TOOL_QUALITY_MEDIOCRE) -/obj/item/pickaxe/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/pickaxe/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && build_from_parts && check_state_in_icon("[overlay.icon_state]-handle", overlay.icon)) var/image/handle = image(overlay.icon, "[overlay.icon_state]-handle") handle.appearance_flags |= RESET_COLOR @@ -80,7 +80,7 @@ name = "advanced mining drill" // Can dig sand as well! icon = 'icons/obj/items/tool/drills/drill_hand.dmi' digspeed = 30 - origin_tech = "{'materials':2,'powerstorage':3,'engineering':2}" + origin_tech = @'{"materials":2,"powerstorage":3,"engineering":2}' desc = "Yours is the drill that will pierce through the rock walls." drill_verb = "drilling" material = /decl/material/solid/metal/steel @@ -96,7 +96,7 @@ name = "sonic jackhammer" icon = 'icons/obj/items/tool/drills/jackhammer.dmi' digspeed = 20 //faster than drill, but cannot dig - origin_tech = "{'materials':3,'powerstorage':2,'engineering':2}" + origin_tech = @'{"materials":3,"powerstorage":2,"engineering":2}' desc = "Cracks rocks with sonic blasts, perfect for killing cave lizards." drill_verb = "hammering" @@ -109,7 +109,7 @@ name = "diamond mining drill" icon = 'icons/obj/items/tool/drills/drill_diamond.dmi' digspeed = 5 //Digs through walls, girders, and can dig up sand - origin_tech = "{'materials':6,'powerstorage':4,'engineering':5}" + origin_tech = @'{"materials":6,"powerstorage":4,"engineering":5}' desc = "Yours is the drill that will pierce the heavens!" drill_verb = "drilling" material = /decl/material/solid/metal/steel @@ -144,7 +144,7 @@ icon_state = "preview" icon = 'icons/obj/items/tool/drills/pickaxe.dmi' digspeed = 30 - origin_tech = "{'materials':3}" + origin_tech = @'{"materials":3}' drill_verb = "picking" sharp = 1 build_from_parts = TRUE @@ -159,7 +159,7 @@ icon_state = "preview" icon = 'icons/obj/items/tool/drills/pickaxe.dmi' digspeed = 20 - origin_tech = "{'materials':4}" + origin_tech = @'{"materials":4}' drill_verb = "picking" sharp = 1 build_from_parts = TRUE @@ -174,7 +174,7 @@ icon_state = "preview" icon = 'icons/obj/items/tool/drills/pickaxe.dmi' digspeed = 10 - origin_tech = "{'materials':6,'engineering':4}" + origin_tech = @'{"materials":6,"engineering":4}' drill_verb = "picking" sharp = 1 build_from_parts = TRUE @@ -195,7 +195,7 @@ force = 8.0 throwforce = 4 w_class = ITEM_SIZE_HUGE - origin_tech = "{'materials':1,'engineering':1}" + origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/metal/steel attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") edge = 1 diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index 47ec3e93d7c..b2a540c4857 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -93,10 +93,10 @@ I.appearance = weapon I.plane = DEFAULT_PLANE I.layer = A.layer + 0.1 - I.pixel_x = 0 - I.pixel_y = 0 - I.pixel_z = 0 - I.pixel_w = 0 + I.pixel_x = -(A.pixel_x) + I.pixel_y = -(A.pixel_y) + I.pixel_z = -(A.pixel_z) + I.pixel_w = -(A.pixel_w) // Who can see the attack? var/list/viewing = list() @@ -106,27 +106,27 @@ for(var/client/C in viewing) C.images += I - addtimer(CALLBACK(src, .proc/clear_shown_overlays, viewing, I), 5) + addtimer(CALLBACK(src, PROC_REF(clear_shown_overlays), viewing, I), 5) // Scale the icon. I.transform *= 0.75 // Set the direction of the icon animation. var/direction = get_dir(src, A) if(direction & NORTH) - I.pixel_y = -16 + I.pixel_y -= 16 else if(direction & SOUTH) - I.pixel_y = 16 + I.pixel_y += 16 if(direction & EAST) - I.pixel_x = -16 + I.pixel_x -= 16 else if(direction & WEST) - I.pixel_x = 16 + I.pixel_x += 16 if(!direction) // Attacked self?! - I.pixel_z = 16 + I.pixel_z += 16 // And animate the attack! - animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) + animate(I, alpha = 175, pixel_x = -(A.pixel_x), pixel_y = -(A.pixel_y), pixel_z = -(A.pixel_z), pixel_w = -(A.pixel_w), time = 3) /mob/proc/spin(spintime, speed) spawn() diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index e3d6ca61dcb..419f96bb777 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -18,7 +18,7 @@ flick(anim, animation) if(do_gibs) - gibs(loc, _blood_type = get_blood_type(), _unique_enzymes = get_unique_enzymes()) + gibs() QDEL_IN(animation, 15) QDEL_IN(src, 15) @@ -26,7 +26,7 @@ //This is the proc for turning a mob into ash. Mostly a copy of gib code (above). //Originally created for wizard disintegrate. I've removed the virus code since it's irrelevant here. -//Dusting robots does not eject the MMI, so it's a bit more powerful than gib() /N +//Dusting robots does not eject the brain, so it's a bit more powerful than gib() /N /mob/proc/dust(anim="dust-m",remains=/obj/effect/decal/cleanable/ash) death(1) var/atom/movable/overlay/animation = null diff --git a/code/modules/mob/floating_message.dm b/code/modules/mob/floating_message.dm index 1a37abc46d3..a6cc4a3bb3f 100644 --- a/code/modules/mob/floating_message.dm +++ b/code/modules/mob/floating_message.dm @@ -78,8 +78,8 @@ var/global/list/floating_chat_colors = list() LAZYADD(holder.stored_chat_text, I) - addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_floating_text, holder, I), duration) - addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_images_from_clients, I, show_to), duration + CHAT_MESSAGE_EOL_FADE) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_floating_text), holder, I), duration) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_images_from_clients), I, show_to), duration + CHAT_MESSAGE_EOL_FADE) return I diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm index 4f8977cca2b..db84ea2d0e0 100644 --- a/code/modules/mob/grab/grab_object.dm +++ b/code/modules/mob/grab/grab_object.dm @@ -49,19 +49,19 @@ LAZYADD(affecting.grabbed_by, src) // This is how we handle affecting being deleted. adjust_position() action_used() - INVOKE_ASYNC(assailant, /atom/movable/proc/do_attack_animation, affecting) + INVOKE_ASYNC(assailant, TYPE_PROC_REF(/atom/movable, do_attack_animation), affecting) playsound(affecting.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) update_icon() - events_repository.register(/decl/observ/moved, affecting, src, .proc/on_affecting_move) + events_repository.register(/decl/observ/moved, affecting, src, PROC_REF(on_affecting_move)) if(assailant.zone_sel) - events_repository.register(/decl/observ/zone_selected, assailant.zone_sel, src, .proc/on_target_change) + events_repository.register(/decl/observ/zone_selected, assailant.zone_sel, src, PROC_REF(on_target_change)) var/obj/item/organ/O = get_targeted_organ() var/decl/pronouns/G = assailant.get_pronouns() if(affecting_mob && O) // may have grabbed a buckled mob, so may be grabbing their holder SetName("[name] (\the [affecting_mob]'s [O.name])") - events_repository.register(/decl/observ/dismembered, affecting_mob, src, .proc/on_organ_loss) + events_repository.register(/decl/observ/dismembered, affecting_mob, src, PROC_REF(on_organ_loss)) if(affecting_mob != assailant) visible_message(SPAN_DANGER("\The [assailant] has grabbed [affecting_mob]'s [O.name]!")) else diff --git a/code/modules/mob/grab/normal/norm_struggle.dm b/code/modules/mob/grab/normal/norm_struggle.dm index 557e09de7b5..4c83b6c2cba 100644 --- a/code/modules/mob/grab/normal/norm_struggle.dm +++ b/code/modules/mob/grab/normal/norm_struggle.dm @@ -43,7 +43,7 @@ else affecting.visible_message("[affecting] struggles against [assailant]!") G.done_struggle = FALSE - addtimer(CALLBACK(G, .proc/handle_resist), 1 SECOND) + addtimer(CALLBACK(G, PROC_REF(handle_resist)), 1 SECOND) resolve_struggle(G) /decl/grab/normal/struggle/proc/resolve_struggle(var/obj/item/grab/G) diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 56ce79487f4..4f7229bff8e 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -59,16 +59,12 @@ else turn_off() -/mob/living/bot/Life() - ..() - if(stat == DEAD) - return - set_status(STAT_WEAK, 0) - set_status(STAT_STUN, 0) - set_status(STAT_PARA, 0) - - if(on && !client && !busy) - handleAI() +/mob/living/bot/handle_regular_status_updates() + . = ..() + if(.) + set_status(STAT_WEAK, 0) + set_status(STAT_STUN, 0) + set_status(STAT_PARA, 0) /mob/living/bot/get_total_life_damage() return getFireLoss() + getBruteLoss() @@ -204,7 +200,12 @@ /mob/living/bot/emag_act(var/remaining_charges, var/mob/user) return 0 -/mob/living/bot/proc/handleAI() +/mob/living/bot/handle_legacy_ai() + . = ..() + if(on && !busy) + handle_async_ai() + +/mob/living/bot/proc/handle_async_ai() set waitfor = FALSE if(ignore_list.len) for(var/atom/A in ignore_list) @@ -283,7 +284,7 @@ /mob/living/bot/proc/startPatrol() var/turf/T = getPatrolTurf() if(T) - patrol_path = AStar(get_turf(loc), T, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_patrol_dist, id = botcard, exclude = obstacle) + patrol_path = AStar(get_turf(loc), T, TYPE_PROC_REF(/turf, CardinalTurfsWithAccess), TYPE_PROC_REF(/turf, Distance), 0, max_patrol_dist, id = botcard, exclude = obstacle) if(!patrol_path) patrol_path = list() obstacle = null @@ -315,7 +316,7 @@ return /mob/living/bot/proc/calcTargetPath() - target_path = AStar(get_turf(loc), get_turf(target), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard, exclude = obstacle) + target_path = AStar(get_turf(loc), get_turf(target), TYPE_PROC_REF(/turf, CardinalTurfsWithAccess), TYPE_PROC_REF(/turf, Distance), 0, max_target_dist, id = botcard, exclude = obstacle) if(!target_path) if(target && target.loc) ignore_list |= target diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 475ec4566fb..765c5ab7dbc 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -21,15 +21,13 @@ /mob/living/bot/cleanbot/handleIdle() if(!screwloose && !oddbutton && prob(5)) visible_message("\The [src] makes an excited beeping booping sound!") - if(screwloose && prob(5)) // Make a mess if(istype(loc, /turf/simulated)) var/turf/simulated/T = loc T.wet_floor() - if(oddbutton && prob(5)) // Make a big mess visible_message("Something flies out of [src]. He seems to be acting oddly.") - var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc) + var/obj/effect/decal/cleanable/blood/gibs/gib = new(loc) var/weakref/g = weakref(gib) ignore_list += g spawn(600) diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index ea9c7f44041..0f39b806b0a 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -125,7 +125,7 @@ /mob/living/bot/farmbot/calcTargetPath() // We need to land NEXT to the tray, because the tray itself is impassable for(var/trayDir in list(NORTH, SOUTH, EAST, WEST)) - target_path = AStar(get_turf(loc), get_step(get_turf(target), trayDir), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard) + target_path = AStar(get_turf(loc), get_step(get_turf(target), trayDir), TYPE_PROC_REF(/turf, CardinalTurfsWithAccess), TYPE_PROC_REF(/turf, Distance), 0, max_target_dist, id = botcard) if(target_path) break if(!target_path) @@ -187,7 +187,7 @@ busy = 1 if(do_after(src, 30, A)) visible_message("[src] fertilizes \the [A].") - T.reagents.add_reagent(/decl/material/gas/ammonia, 10) + T.add_to_reagents(/decl/material/gas/ammonia, 10) busy = 0 action = "" update_icon() @@ -200,7 +200,7 @@ visible_message("[src] starts refilling its tank from \the [A].") busy = 1 while(do_after(src, 10) && tank.reagents.total_volume < tank.reagents.maximum_volume) - tank.reagents.add_reagent(/decl/material/liquid/water, 100) + tank.add_to_reagents(/decl/material/liquid/water, 100) if(prob(5)) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) busy = 0 diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index 41e96d88d81..e62902667ae 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -140,7 +140,7 @@ if(t == 1) reagent_glass.reagents.trans_to_mob(H, injection_amount, CHEM_INJECT) else - H.reagents.add_reagent(t, injection_amount) + H.add_to_reagents(t, injection_amount) visible_message("[src] injects [H] with the syringe!") busy = 0 update_icon() diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index b4da5f516a8..2a17f24eede 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -132,7 +132,7 @@ broadcast_security_hud_message("[src] is arresting a level [threat] suspect [suspect_name] in [get_area_name(src)].", src) say("Down on the floor, [suspect_name]! You have [SECBOT_WAIT_TIME] seconds to comply.") playsound(src.loc, pick(preparing_arrest_sounds), 50) - events_repository.register(/decl/observ/moved, target, src, /mob/living/bot/secbot/proc/target_moved) + events_repository.register(/decl/observ/moved, target, src, TYPE_PROC_REF(/mob/living/bot/secbot, target_moved)) /mob/living/bot/secbot/proc/target_moved(atom/movable/moving_instance, atom/old_loc, atom/new_loc) if(get_dist(get_turf(src), get_turf(target)) >= 1) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm new file mode 100644 index 00000000000..faa6edb9b7f --- /dev/null +++ b/code/modules/mob/living/brain/brain.dm @@ -0,0 +1,117 @@ +/mob/living/brain + name = "brain" + icon = 'icons/obj/surgery.dmi' + icon_state = "brain1" + default_emotes = list( + /decl/emote/audible/alarm, + /decl/emote/audible/alert, + /decl/emote/audible/notice, + /decl/emote/audible/whistle, + /decl/emote/audible/synth, + /decl/emote/audible/boop, + /decl/emote/visible/blink, + /decl/emote/visible/flash + ) + + // Used for EMP damage when inside an interface or robobrain. + var/emp_damage = 0 + var/last_emp_message = 0 + var/static/max_emp_damage = 30 + var/static/list/emp_reboot_strings = list( + SPAN_NOTICE("System reboot nearly complete."), + SPAN_NOTICE("Primary systems are now online."), + SPAN_DANGER("Major electrical distruption detected: System rebooting.") + ) + +/mob/living/brain/handle_regular_status_updates() + . = ..() + if(emp_damage || stat == DEAD || !is_in_interface()) + SET_STATUS_MAX(src, STAT_SILENCE, 2) + +/mob/living/brain/death() + var/obj/item/organ/holder = loc + . = ..() + if(stat == DEAD && istype(holder)) + holder.die() + +/mob/living/brain/is_deaf() + return emp_damage || stat == DEAD || !is_in_interface() + +/mob/living/brain/is_blind() + return emp_damage || stat == DEAD || !is_in_interface() + +/mob/living/brain/Logout() + . = ..() + var/obj/item/organ/internal/container = get_container() + if(istype(container)) + container.queue_icon_update() + +/mob/living/brain/proc/get_container() + . = loc?.loc + +/mob/living/brain/Login() + . = ..() + var/obj/item/organ/internal/container = get_container() + if(istype(container)) + var/obj/item/organ/internal/brain_interface/interface = container + if(istype(interface)) + interface.locked = TRUE + container.update_icon() + +/mob/living/brain/proc/is_in_interface() + var/container = get_container() + return istype(container, /obj/item/organ/internal/brain_interface) || istype(container, /obj/item/organ/internal/brain/robotic) + +/mob/living/brain/can_emote() + return is_in_interface() && ..() + +/mob/living/brain/can_use_rig() + return is_in_interface() + +/mob/living/brain/Destroy() + ghostize() + . = ..() + +/mob/living/brain/say_understands(var/other) + . = ishuman(other) || (is_in_interface() && issilicon(other)) || ..() + +/mob/living/brain/UpdateLyingBuckledAndVerbStatus() + return + +/mob/living/brain/isSynthetic() + return istype(get_container(), /obj/item/organ/internal/brain/robotic) + +/mob/living/brain/binarycheck() + return isSynthetic() + +/mob/living/brain/check_has_mouth() + return FALSE + +/mob/living/brain/emp_act(severity) + if(!isSynthetic()) + return + switch(severity) + if(1) + emp_damage += rand(20,30) + if(2) + emp_damage += rand(10,20) + if(3) + emp_damage += rand(0,10) + emp_damage = clamp(emp_damage, 0, max_emp_damage) + +/mob/living/brain/handle_regular_status_updates() // Status & health update, are we dead or alive etc. + . = ..() + if(stat == DEAD || !isSynthetic()) + emp_damage = 0 + return + if(emp_damage <= 0) + return + emp_damage -= 1 + var/msg_threshold = clamp(CEILING(emp_damage / (max_emp_damage / length(emp_reboot_strings))), 1, length(emp_reboot_strings)) + if(last_emp_message != msg_threshold) + last_emp_message = msg_threshold + to_chat(src, emp_reboot_strings[msg_threshold]) + if(emp_damage <= 0) + last_emp_message = 0 + emp_damage = 0 + to_chat(src, SPAN_NOTICE("All systems restored.")) diff --git a/code/modules/mob/living/brain/death.dm b/code/modules/mob/living/brain/death.dm new file mode 100644 index 00000000000..0a70b0d7683 --- /dev/null +++ b/code/modules/mob/living/brain/death.dm @@ -0,0 +1,17 @@ +/mob/living/brain/death(gibbed) + var/death_message = "no message" + var/obj/item/organ/internal/brain_interface/container = get_container() + if(!gibbed && istype(container)) + death_message = "beeps shrilly as \the [container] flatlines!" + . = ..(gibbed, death_message) + if(istype(container)) + container.update_icon() + +/mob/living/brain/gib() + var/obj/item/organ/internal/brain_interface/container = get_container() + var/obj/item/organ/internal/brain/sponge = loc + . = ..(null, 1) + if(container && !QDELETED(container)) + qdel(container) + if(istype(sponge) && !QDELETED(sponge)) + qdel(sponge) diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm new file mode 100644 index 00000000000..4a59e86f064 --- /dev/null +++ b/code/modules/mob/living/brain/say.dm @@ -0,0 +1,16 @@ +/mob/living/brain/say(var/message, var/decl/language/speaking, var/verb = "says", var/alt_name = "", whispering) + if(GET_STATUS(src, STAT_SILENCE) || !is_in_interface()) + return + if(prob(emp_damage*4)) + if(prob(10)) + return + message = Gibberish(message, (emp_damage*6)) + . = ..(message, speaking, verb, alt_name, whispering) + var/obj/item/radio/radio = get_radio() + if(radio) + radio.hear_talk(src, sanitize(message), verb, speaking) + +/mob/living/brain/get_radio() + var/obj/item/organ/internal/brain_interface/container = get_container() + if(istype(container)) + return container.get_radio() diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 9a959c07e7b..3237e4f48ed 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -25,6 +25,9 @@ gender = NEUTER . = ..() +/mob/living/carbon/alien/get_blood_color() + return COLOR_LIME + /mob/living/carbon/alien/restrained() return 0 diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index ee76da97b48..58fff70c26a 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,13 +1,3 @@ -// Alien larva are quite simple. -/mob/living/carbon/alien/Life() - set invisibility = FALSE - set background = TRUE - if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - if(!loc) return - ..() - //Status updates, death etc. - update_icon() - /mob/living/carbon/alien/handle_mutations_and_radiation() ..() if(radiation) @@ -20,44 +10,46 @@ /mob/living/carbon/alien/handle_regular_status_updates() - if(status_flags & GODMODE) return 0 + . = ..() - update_health() // TODO: unify with parent call, Life() PR if(stat == DEAD) SET_STATUS_MAX(src, STAT_BLIND, 2) set_status(STAT_SILENCE, 0) - else - if(stat == DEAD) - return 1 - if(HAS_STATUS(src, STAT_PARA)) - SET_STATUS_MAX(src, STAT_BLIND, 2) - set_stat(UNCONSCIOUS) - if(getHalLoss() > 0) - adjustHalLoss(-3) - - if(HAS_STATUS(src, STAT_ASLEEP)) + else if(HAS_STATUS(src, STAT_PARA)) + SET_STATUS_MAX(src, STAT_BLIND, 2) + set_stat(UNCONSCIOUS) + if(getHalLoss() > 0) adjustHalLoss(-3) - SET_STATUS_MAX(src, STAT_BLIND, 2) - set_stat(UNCONSCIOUS) - else if(resting) - if(getHalLoss() > 0) - adjustHalLoss(-3) - - else - set_stat(CONSCIOUS) - if(getHalLoss() > 0) - adjustHalLoss(-1) - - // Eyes and blindness. - if(!check_has_eyes()) - SET_STATUS_MAX(src, STAT_BLIND, 2) - SET_STATUS_MAX(src, STAT_BLURRY, 1) - - update_icon() + if(HAS_STATUS(src, STAT_ASLEEP)) + adjustHalLoss(-3) + if (mind) + if(mind.active && client != null) + ADJ_STATUS(src, STAT_ASLEEP, -1) + SET_STATUS_MAX(src, STAT_BLIND, 2) + set_stat(UNCONSCIOUS) + else if(resting) + if(getHalLoss() > 0) + adjustHalLoss(-3) + else + set_stat(CONSCIOUS) + if(getHalLoss() > 0) + adjustHalLoss(-1) - return 1 + // Eyes and blindness. + if(!check_has_eyes()) + set_status(STAT_BLIND, 1) + SET_STATUS_MAX(src, STAT_BLIND, 2) + set_status(STAT_BLURRY, 1) + else if(GET_STATUS(src, STAT_BLIND)) + ADJ_STATUS(src, STAT_BLIND, -1) + SET_STATUS_MAX(src, STAT_BLIND, 2) + update_icon() + return TRUE /mob/living/carbon/alien/handle_regular_hud_updates() + . = ..() + if(!.) + return update_sight() if (healths) if(stat != DEAD) @@ -90,7 +82,6 @@ if(machine) if(machine.check_eye(src) < 0) reset_view(null) - return 1 /mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment) ..() diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm deleted file mode 100644 index 745a08ca834..00000000000 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ /dev/null @@ -1,189 +0,0 @@ -/obj/item/mmi/digital/Initialize() - brainmob = new(src) - brainmob.set_stat(CONSCIOUS) - brainmob.add_language(/decl/language/binary) - brainmob.add_language(/decl/language/machine) - brainmob.container = src - brainmob.set_status(STAT_SILENCE, 0) - PickName() - . = ..() - -/obj/item/mmi/digital/proc/PickName() - return - -/obj/item/mmi/digital/attackby() - return - -/obj/item/mmi/digital/attack_self() - return - -/obj/item/mmi - name = "\improper Man-Machine Interface" - desc = "A complex life support shell that interfaces between a brain and electronic devices." - icon = 'icons/obj/assemblies.dmi' - icon_state = "mmi_empty" - w_class = ITEM_SIZE_NORMAL - origin_tech = "{'biotech':3}" - material = /decl/material/solid/metal/steel - matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) - req_access = list(access_robotics) - - //Revised. Brainmob is now contained directly within object of transfer. MMI in this case. - - var/locked = 0 - var/mob/living/carbon/brain/brainmob = null//The current occupant. - var/obj/item/organ/internal/brain/brainobj = null //The current brain organ. - -/obj/item/mmi/attackby(var/obj/item/O, var/mob/user) - if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO - - var/obj/item/organ/internal/brain/B = O - if(B.damage >= B.max_damage) - to_chat(user, "That brain is well and truly dead.") - return - else if(!B.brainmob || !B.can_use_mmi) - to_chat(user, "This brain is completely useless to you.") - return - if(!user.try_unequip(O, src)) - return - user.visible_message("\The [user] sticks \a [O] into \the [src].") - - brainmob = B.brainmob - B.brainmob = null - brainmob.forceMove(src) - brainmob.container = src - brainmob.set_stat(CONSCIOUS) - brainmob.switch_from_dead_to_living_mob_list() //Update dem lists - - brainobj = O - - SetName("[initial(name)]: ([brainmob.real_name])") - update_icon() - - locked = 1 - - SSstatistics.add_field("cyborg_mmis_filled",1) - - return - - if((istype(O,/obj/item/card/id)||istype(O,/obj/item/modular_computer)) && brainmob) - if(allowed(user)) - locked = !locked - to_chat(user, "You [locked ? "lock" : "unlock"] the brain holder.") - else - to_chat(user, "Access denied.") - return - if(brainmob) - O.attack(brainmob, user)//Oh noooeeeee - return - ..() - - //TODO: ORGAN REMOVAL UPDATE. Make the brain remain in the MMI so it doesn't lose organ data. -/obj/item/mmi/attack_self(mob/user) - if(!brainmob) - to_chat(user, "You upend the MMI, but there's nothing in it.") - else if(locked) - to_chat(user, "You upend the MMI, but the brain is clamped into place.") - else - to_chat(user, "You upend the MMI, spilling the brain onto the floor.") - var/obj/item/organ/internal/brain/brain - if (brainobj) //Pull brain organ out of MMI. - brainobj.forceMove(user.loc) - brain = brainobj - brainobj = null - else //Or make a new one if empty. - brain = new(user.loc) - brainmob.container = null//Reset brainmob mmi var. - brainmob.forceMove(brain)//Throw mob into brain. - brainmob.remove_from_living_mob_list() //Get outta here - brain.brainmob = brainmob//Set the brain to use the brainmob - brainmob = null//Set mmi brainmob var to null - - update_icon() - SetName(initial(name)) - -/obj/item/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people. - brainmob = new(src) - brainmob.SetName(H.real_name) - brainmob.real_name = H.real_name - brainmob.dna = H.dna - brainmob.container = src - brainmob.timeofhostdeath = H.timeofdeath - brainmob.set_stat(CONSCIOUS) - - SetName("[initial(name)]: [brainmob.real_name]") - update_icon() - locked = 1 - -/obj/item/mmi/preserve_in_cryopod(obj/machinery/cryopod/pod) - return brainmob && brainmob.client && brainmob.key - -/obj/item/mmi/relaymove(var/mob/user, var/direction) - if(user.incapacitated(INCAPACITATION_KNOCKOUT)) - return - var/obj/item/rig/rig = get_rig() - if(rig) - rig.forced_move(direction, user) - -/obj/item/mmi/Destroy() - if(isrobot(loc)) - var/mob/living/silicon/robot/borg = loc - borg.mmi = null - QDEL_NULL(brainmob) - return ..() - -/obj/item/mmi/radio_enabled - name = "radio-enabled man-machine interface" - desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio." - origin_tech = "{'biotech':4}" - material = /decl/material/solid/metal/steel - matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) - var/obj/item/radio/radio = null//Let's give it a radio. - -/obj/item/mmi/radio_enabled/Initialize() - . = ..() - radio = new(src)//Spawns a radio inside the MMI. - radio.broadcasting = 1//So it's broadcasting from the start. - -/obj/item/mmi/radio_enabled/verb/Toggle_Broadcasting() //Allows the brain to toggle the radio functions. - set name = "Toggle Broadcasting" - set desc = "Toggle broadcasting channel on or off." - set category = "MMI" - set src = usr.loc//In user location, or in MMI in this case. - set popup_menu = 0//Will not appear when right clicking. - - if(brainmob.stat)//Only the brainmob will trigger these so no further check is necessary. - to_chat(brainmob, "Can't do that while incapacitated or dead.") - - radio.broadcasting = radio.broadcasting==1 ? 0 : 1 - to_chat(brainmob, "Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting.") - -/obj/item/mmi/radio_enabled/verb/Toggle_Listening() - set name = "Toggle Listening" - set desc = "Toggle listening channel on or off." - set category = "MMI" - set src = usr.loc - set popup_menu = 0 - - if(brainmob.stat) - to_chat(brainmob, "Can't do that while incapacitated or dead.") - - radio.listening = radio.listening==1 ? 0 : 1 - to_chat(brainmob, "Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.") - -/obj/item/mmi/emp_act(severity) - if(!brainmob) - return - else - switch(severity) - if(1) - brainmob.emp_damage += rand(20,30) - if(2) - brainmob.emp_damage += rand(10,20) - if(3) - brainmob.emp_damage += rand(0,10) - ..() - -/obj/item/mmi/on_update_icon() - . = ..() - icon_state = brainmob ? "mmi_full" : "mmi_empty" diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm deleted file mode 100644 index ca5f768be6f..00000000000 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ /dev/null @@ -1,40 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/mob/living/carbon/brain - var/obj/item/container = null - var/timeofhostdeath = 0 - var/emp_damage = 0//Handles a type of MMI damage - var/alert = null - icon = 'icons/obj/surgery.dmi' - icon_state = "brain1" - mob_sort_value = 7 - -/mob/living/carbon/brain/can_emote() - return stat == CONSCIOUS && (istype(container, /obj/item/mmi) || istype(loc, /obj/item/organ/internal/posibrain)) - -/mob/living/carbon/brain/Initialize() - create_reagents(1000) - . = ..() - -/mob/living/carbon/brain/Destroy() - if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. - if(stat!=DEAD) //If not dead. - death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA - ghostize() //Ghostize checks for key so nothing else is necessary. - . = ..() - -/mob/living/carbon/brain/say_understands(mob/speaker, decl/language/speaking) - return (issilicon(speaker) && (istype(container, /obj/item/mmi) || istype(loc, /obj/item/organ/internal/posibrain))) || ishuman(speaker) || ..() - -/mob/living/carbon/brain/UpdateLyingBuckledAndVerbStatus() - return - -/mob/living/carbon/brain/isSynthetic() - return istype(container, /obj/item/mmi/digital) || istype(loc, /obj/item/organ/internal/posibrain) - -/mob/living/carbon/brain/binarycheck() - return isSynthetic() - -/mob/living/carbon/brain/check_has_mouth() - return 0 - diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm deleted file mode 100644 index 5f728287cec..00000000000 --- a/code/modules/mob/living/carbon/brain/death.dm +++ /dev/null @@ -1,14 +0,0 @@ -/mob/living/carbon/brain/death(gibbed) - if(!gibbed && istype(container, /obj/item/mmi)) //If not gibbed but in a container. - container.icon_state = "mmi_dead" - return ..(gibbed,"beeps shrilly as the MMI flatlines!") - else - return ..(gibbed,"no message") - -/mob/living/carbon/brain/gib(anim="gibbed-m",do_gibs) - if(istype(container, /obj/item/mmi)) - qdel(container)//Gets rid of the MMI if there is one - if(loc) - if(istype(loc,/obj/item/organ/internal/brain)) - qdel(loc)//Gets rid of the brain item - ..(null,1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm deleted file mode 100644 index 7b02d7c8a84..00000000000 --- a/code/modules/mob/living/carbon/brain/life.dm +++ /dev/null @@ -1,164 +0,0 @@ -/mob/living/carbon/brain/need_breathe() - return FALSE - -/mob/living/carbon/brain/should_breathe() - return FALSE - -/mob/living/carbon/brain/handle_mutations_and_radiation() - ..() - if (radiation) - if (radiation > 100) - radiation = 100 - if(!container)//If it's not in an MMI - to_chat(src, "You feel weak.") - else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that - to_chat(src, "STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED.") - switch(radiation) - if(1 to 49) - radiation-- - if(prob(25)) - adjustToxLoss(1) - - if(50 to 74) - radiation -= 2 - adjustToxLoss(1) - if(prob(5)) - radiation -= 5 - if(!container) - to_chat(src, "You feel weak.") - else - to_chat(src, "STATUS: DANGEROUS LEVELS OF RADIATION DETECTED.") - - if(75 to 100) - radiation -= 3 - adjustToxLoss(3) - -/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment) - ..() - if(!environment) - return - var/environment_heat_capacity = environment.heat_capacity() - if(isspaceturf(get_turf(src))) - var/turf/heat_turf = get_turf(src) - environment_heat_capacity = heat_turf.heat_capacity - if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10))) - var/transfer_coefficient = 1 - handle_temperature_damage(SLOT_HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient) - if(stat == DEAD) - bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000) - - -/mob/living/carbon/brain/proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity) - if(status_flags & GODMODE) return - if(exposed_temperature > bodytemperature) - var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0) - adjustFireLoss(20.0*discomfort) - else - var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0) - adjustFireLoss(5.0*discomfort) - -/mob/living/carbon/brain/apply_chemical_effects() - . = ..() - if(resting) - ADJ_STATUS(src, STAT_DIZZY, -4) - return TRUE - -/mob/living/carbon/brain/should_be_dead() - return (!container && (current_health < config.health_threshold_dead || (config.revival_brain_life >= 0 && (world.time - timeofhostdeath) > config.revival_brain_life)) ) - -/mob/living/carbon/brain/handle_regular_status_updates() //TODO: comment out the unused bits >_> - - update_health() // TODO: unify with parent call, Life() PR - - if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP - return 1 - - //Handling EMP effect in the Life(), it's made VERY simply, and has some additional effects handled elsewhere - if(emp_damage) //This is pretty much a damage type only used by MMIs, dished out by the emp_act - if(!(container && istype(container, /obj/item/mmi))) - emp_damage = 0 - else - emp_damage = round(emp_damage,1)//Let's have some nice numbers to work with - switch(emp_damage) - if(31 to INFINITY) - emp_damage = 30//Let's not overdo it - if(21 to 30)//High level of EMP damage, unable to see, hear, or speak - set_status(STAT_BLIND, 1) - SET_STATUS_MAX(src, STAT_DEAF, 1) - set_status(STAT_SILENCE, 1) - if(!alert)//Sounds an alarm, but only once per 'level' - emote("alarm") - to_chat(src, "Major electrical distruption detected: System rebooting.") - alert = TRUE - if(prob(75)) - emp_damage -= 1 - if(20) - alert = FALSE - set_status(STAT_BLIND, 0) - set_status(STAT_DEAF, 0) - set_status(STAT_SILENCE, 0) - emp_damage -= 1 - if(11 to 19)//Moderate level of EMP damage, resulting in nearsightedness and ear damage - set_status(STAT_BLURRY, 1) - set_status(STAT_TINNITUS, 1) - if(!alert) - emote("alert") - to_chat(src, "Primary systems are now online.") - alert = TRUE - if(prob(50)) - emp_damage -= 1 - if(10) - alert = FALSE - set_status(STAT_BLURRY, 0) - set_status(STAT_TINNITUS, 0) - emp_damage -= 1 - if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere) - if(!alert) - emote("notice") - to_chat(src, "System reboot nearly complete.") - alert = TRUE - if(prob(25)) - emp_damage -= 1 - if(1) - alert = FALSE - to_chat(src, "All systems restored.") - emp_damage -= 1 - return 1 - -/mob/living/carbon/brain/handle_regular_hud_updates() - update_sight() - if (healths) - if (stat != DEAD) - switch(current_health) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - - if(stat != DEAD) - if(is_blind()) - overlay_fullscreen("blind", /obj/screen/fullscreen/blind) - else - clear_fullscreen("blind") - set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1) - set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry) - set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high) - if (machine) - if (!( machine.check_eye(src) )) - reset_view(null) - return 1 - -/mob/living/carbon/brain/can_change_intent() - return TRUE diff --git a/code/modules/mob/living/carbon/brain/login.dm b/code/modules/mob/living/carbon/brain/login.dm deleted file mode 100644 index 4f8a38ca269..00000000000 --- a/code/modules/mob/living/carbon/brain/login.dm +++ /dev/null @@ -1,3 +0,0 @@ -/mob/living/carbon/brain/Login() - ..() - set_status(STAT_ASLEEP, 0) diff --git a/code/modules/mob/living/carbon/brain/robot.dm b/code/modules/mob/living/carbon/brain/robot.dm deleted file mode 100644 index 1c4a5490ec4..00000000000 --- a/code/modules/mob/living/carbon/brain/robot.dm +++ /dev/null @@ -1,15 +0,0 @@ -/obj/item/mmi/digital/robot - name = "robotic intelligence circuit" - desc = "The pinnacle of artifical intelligence which can be achieved using classical computer science." - icon = 'icons/obj/modules/module_mainboard.dmi' - icon_state = ICON_STATE_WORLD - w_class = ITEM_SIZE_NORMAL - origin_tech = "{'engineering':4,'materials':3,'programming':4}" - -/obj/item/mmi/digital/robot/PickName() - src.brainmob.SetName("[pick(list("ADA","DOS","GNU","MAC","WIN"))]-[random_id(type,1000,9999)]") - src.brainmob.real_name = src.brainmob.name - -/obj/item/mmi/digital/robot/on_update_icon() - . = ..() - icon_state = initial(icon_state) diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm deleted file mode 100644 index 793e0ea9033..00000000000 --- a/code/modules/mob/living/carbon/brain/say.dm +++ /dev/null @@ -1,38 +0,0 @@ -//TODO: Convert this over for languages. -/mob/living/carbon/brain/say(var/message) - if(HAS_STATUS(src, STAT_SILENCE)) - return - - message = sanitize(message) - - if(!(container && istype(container, /obj/item/mmi))) - return //No MMI, can't speak, bucko./N - else - var/decl/language/speaking = parse_language(message) - if(speaking) - message = copytext(message, 2+length(speaking.key)) - var/verb = "says" - var/ending = copytext(message, length(message)) - if (speaking) - verb = speaking.get_spoken_verb(src, ending) - else - if(ending=="!") - verb=pick("exclaims","shouts","yells") - if(ending=="?") - verb="asks" - - if(prob(emp_damage*4)) - if(prob(10))//10% chane to drop the message entirely - return - else - message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher - - if(speaking && speaking.flags & LANG_FLAG_HIVEMIND) - speaking.broadcast(src,trim(message)) - return - - if(istype(container, /obj/item/mmi/radio_enabled)) - var/obj/item/mmi/radio_enabled/R = container - if(R.radio) - spawn(0) R.radio.hear_talk(src, sanitize(message), verb, speaking) - ..(trim(message), speaking, verb) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 84b09cae19c..283ca4f24c1 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -15,7 +15,6 @@ QDEL_NULL(touching) QDEL_NULL(bloodstr) reagents = null //We assume reagents is a reference to bloodstr here - QDEL_NULL_LIST(hallucinations) if(loc) for(var/mob/M in contents) M.dropInto(loc) @@ -299,15 +298,8 @@ /mob/living/carbon/proc/can_devour(atom/movable/victim) return FALSE -/mob/living/carbon/check_has_mouth() - // carbon mobs have mouths by default - // behavior of this proc for humans is overridden in human.dm - return 1 - -/mob/living/carbon/proc/check_mouth_coverage() - // carbon mobs do not have blocked mouths by default - // overridden in human_defense.dm - return null +/mob/living/carbon/get_satiated_nutrition() + return 350 /mob/living/carbon/get_max_nutrition() return 400 @@ -327,9 +319,6 @@ RETURN_TYPE(/decl/species) return species -/mob/living/carbon/get_species_name() - return species.name - /mob/living/carbon/get_contact_reagents() return touching diff --git a/code/modules/mob/living/carbon/carbon_eating.dm b/code/modules/mob/living/carbon/carbon_eating.dm new file mode 100644 index 00000000000..70db1bae0f3 --- /dev/null +++ b/code/modules/mob/living/carbon/carbon_eating.dm @@ -0,0 +1,9 @@ +/mob/living/carbon/can_eat_food_currently(obj/eating, mob/user) + user = user || src + if(get_food_satiation() < get_max_nutrition()) + return TRUE + if(user == src) + to_chat(user, SPAN_WARNING("You cannot force any more of \the [eating] down your throat.")) + else + to_chat(user, SPAN_WARNING("You cannot force anymore of \the [eating] down \the [src]'s throat.")) + return FALSE diff --git a/code/modules/mob/living/carbon/hallucinations.dm b/code/modules/mob/living/carbon/hallucinations.dm deleted file mode 100644 index 3ff542395a8..00000000000 --- a/code/modules/mob/living/carbon/hallucinations.dm +++ /dev/null @@ -1,317 +0,0 @@ -/mob/living/carbon/var/hallucination_power = 0 -/mob/living/carbon/var/hallucination_duration = 0 -/mob/living/carbon/var/next_hallucination -/mob/living/carbon/var/list/hallucinations = list() - -/mob/living/proc/adjust_hallucination(duration, power) - return - -/mob/living/proc/set_hallucination(duration, power) - return - -/mob/living/carbon/set_hallucination(duration, power) - hallucination_duration = max(hallucination_duration, duration) - hallucination_power = max(hallucination_power, power) - -/mob/living/carbon/adjust_hallucination(duration, power) - hallucination_duration = max(0, hallucination_duration + duration) - hallucination_power = max(0, hallucination_power + power) - -/mob/living/carbon/proc/handle_hallucinations() - //Tick down the duration - hallucination_duration = max(0, hallucination_duration - 1) - //Adjust power if we have some chems that affect it - if(has_chemical_effect(CE_MIND, threshold_under = -1)) - hallucination_power = hallucination_power++ - else if(has_chemical_effect(CE_MIND, threshold_under = 0)) - hallucination_power = min(hallucination_power++, 50) - else if(has_chemical_effect(CE_MIND, 1)) - hallucination_duration = max(0, hallucination_duration - 1) - hallucination_power = max(hallucination_power - GET_CHEMICAL_EFFECT(src, CE_MIND), 0) - - //See if hallucination is gone - if(!hallucination_power) - hallucination_duration = 0 - return - if(!hallucination_duration) - hallucination_power = 0 - return - - if(!client || stat || world.time < next_hallucination) - return - if(has_chemical_effect(CE_MIND, 1) && prob(GET_CHEMICAL_EFFECT(src, CE_MIND)*40)) //antipsychotics help - return - var/hall_delay = rand(10,20) SECONDS - - if(hallucination_power < 50) - hall_delay *= 2 - next_hallucination = world.time + hall_delay - var/list/candidates = list() - for(var/T in subtypesof(/datum/hallucination/)) - var/datum/hallucination/H = new T - if(H.can_affect(src)) - candidates += H - if(candidates.len) - var/datum/hallucination/H = pick(candidates) - H.holder = src - H.activate() - -////////////////////////////////////////////////////////////////////////////////////////////////////// -//Hallucination effects datums -////////////////////////////////////////////////////////////////////////////////////////////////////// - -/datum/hallucination - var/mob/living/carbon/holder - var/allow_duplicates = 1 - var/duration = 0 - var/min_power = 0 //at what levels of hallucination power mobs should get it - var/max_power = INFINITY - -/datum/hallucination/proc/start() - -/datum/hallucination/proc/end() - -/datum/hallucination/proc/can_affect(var/mob/living/carbon/C) - if(!C.client) - return 0 - if(min_power > C.hallucination_power) - return 0 - if(max_power < C.hallucination_power) - return 0 - if(!allow_duplicates && (locate(type) in C.hallucinations)) - return 0 - return 1 - -/datum/hallucination/Destroy() - . = ..() - holder = null - -/datum/hallucination/proc/activate() - if(!holder || !holder.client) - return - holder.hallucinations += src - start() - spawn(duration) - if(holder) - end() - holder.hallucinations -= src - qdel(src) - - -//Playing a random sound -/datum/hallucination/sound - var/list/sounds = list('sound/machines/airlock.ogg','sound/effects/explosionfar.ogg','sound/machines/windowdoor.ogg','sound/machines/twobeep.ogg') - -/datum/hallucination/sound/start() - var/turf/T = locate(holder.x + rand(6,11), holder.y + rand(6,11), holder.z) - holder.playsound_local(T,pick(sounds),70) - -/datum/hallucination/sound/tools - sounds = list('sound/items/Ratchet.ogg','sound/items/Welder.ogg','sound/items/Crowbar.ogg','sound/items/Screwdriver.ogg') - -/datum/hallucination/sound/danger - min_power = 30 - sounds = list('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg','sound/weapons/smash.ogg') - -/datum/hallucination/sound/spooky - min_power = 50 - sounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\ - 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ - 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ - 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ - 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') - -//Hearing someone being shot twice -/datum/hallucination/gunfire - var/gunshot - var/turf/origin - duration = 15 - min_power = 30 - -/datum/hallucination/gunfire/start() - gunshot = pick('sound/weapons/gunshot/gunshot_strong.ogg', 'sound/weapons/gunshot/gunshot2.ogg', 'sound/weapons/gunshot/shotgun.ogg', 'sound/weapons/gunshot/gunshot.ogg','sound/weapons/Taser.ogg') - origin = locate(holder.x + rand(4,8), holder.y + rand(4,8), holder.z) - holder.playsound_local(origin,gunshot,50) - -/datum/hallucination/gunfire/end() - holder.playsound_local(origin,gunshot,50) - -//Hearing someone talking to/about you. -/datum/hallucination/talking/can_affect(var/mob/living/carbon/C) - if(!..()) - return 0 - for(var/mob/living/M in oview(C)) - return TRUE - -/datum/hallucination/talking/start() - var/sanity = 5 //even insanity needs some sanity - for(var/mob/living/talker in oview(holder)) - if(talker.stat) - continue - var/message - if(prob(80)) - var/list/names = list() - var/lastname = copytext(holder.real_name, findtext(holder.real_name, " ")+1) - var/firstname = copytext(holder.real_name, 1, findtext(holder.real_name, " ")) - if(lastname) names += lastname - if(firstname) names += firstname - if(!names.len) - names += holder.real_name - var/add = prob(20) ? ", [pick(names)]" : "" - var/list/phrases = list("[prob(50) ? "Hey, " : ""][pick(names)]!","[prob(50) ? "Hey, " : ""][pick(names)]?","Get out[add]!","Go away[add].","What are you doing[add]?","Where's your ID[add]?") - if(holder.hallucination_power > 50) - phrases += list("What did you come here for[add]?","Don't touch me[add].","You're not getting out of here[add].", "You are a failure, [pick(names)].","Just kill yourself already, [pick(names)].","Put on some clothes[add].","Take off your clothes[add].") - message = pick(phrases) - to_chat(holder,"[talker.name] [holder.say_quote(message)], \"[message]\"") - else - to_chat(holder,"[talker.name] points at [holder.name]") - to_chat(holder,"[talker.name] says something softly.") - - var/speech_state = holder.check_speech_punctuation_state(message) - if(speech_state) - var/image/speech_bubble = image('icons/mob/talk.dmi', talker, speech_state) - addtimer(CALLBACK(src, .proc/qdel_image, speech_bubble), 3 SECONDS) - show_image(holder, speech_bubble) - - sanity-- //don't spam them in very populated rooms. - if(!sanity) - return - -/datum/hallucination/talking/proc/qdel_image(var/image/speech_bubble) - qdel(speech_bubble) - -//Spiderling skitters -/datum/hallucination/skitter/start() - to_chat(holder,"The spiderling skitters[pick(" away"," around","")].") - -//Spiders in your body -/datum/hallucination/spiderbabies - min_power = 40 - -/datum/hallucination/spiderbabies/start() - var/mob/living/carbon/H = holder - var/list/limbs = H.get_external_organs() - if(!LAZYLEN(limbs)) - return - var/obj/O = pick(limbs) - to_chat(H,SPAN_WARNING("You feel something [pick("moving","squirming","skittering")] inside of your [O.name]!")) - -//Seeing stuff -/datum/hallucination/mirage - duration = 30 SECONDS - max_power = 30 - var/number = 1 - var/list/things = list() //list of images to display - -/datum/hallucination/mirage/Destroy() - end() - . = ..() - -/datum/hallucination/mirage/proc/generate_mirage() - var/icon/T = new('icons/obj/trash.dmi') - return image(T, pick(T.IconStates()), layer = BELOW_TABLE_LAYER) - -/datum/hallucination/mirage/start() - var/list/possible_points = list() - for(var/turf/simulated/floor/F in view(holder, world.view+1)) - possible_points += F - if(possible_points.len) - for(var/i = 1 to number) - var/image/thing = generate_mirage() - things += thing - thing.loc = pick(possible_points) - holder.client.images += things - -/datum/hallucination/mirage/end() - if(holder.client) - holder.client.images -= things - -//LOADSEMONEY -/datum/hallucination/mirage/money - min_power = 20 - max_power = 45 - number = 2 - -/datum/hallucination/mirage/money/generate_mirage() - return image('icons/obj/items/money.dmi', "cash_x_5]", layer = BELOW_TABLE_LAYER) - -//Blood and aftermath of firefight -/datum/hallucination/mirage/carnage - min_power = 50 - number = 10 - -/datum/hallucination/mirage/carnage/generate_mirage() - if(prob(50)) - var/image/I = image('icons/effects/blood.dmi', pick("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7"), layer = BELOW_TABLE_LAYER) - I.color = COLOR_BLOOD_HUMAN - return I - else - var/image/I = image('icons/obj/ammo.dmi', "s-casing-spent", layer = BELOW_TABLE_LAYER) - I.layer = BELOW_TABLE_LAYER - I.dir = pick(global.alldirs) - I.pixel_x = rand(-10,10) - I.pixel_y = rand(-10,10) - return I - -//Fake telepathy -/datum/hallucination/telepahy - allow_duplicates = 0 - duration = 20 MINUTES - -/datum/hallucination/telepahy/start() - to_chat(holder,"You expand your mind outwards.") - holder.verbs += /mob/living/carbon/human/proc/fakeremotesay - -/datum/hallucination/telepahy/end() - if(holder) - holder.verbs -= /mob/living/carbon/human/proc/fakeremotesay - -/mob/living/carbon/human/proc/fakeremotesay() - set name = "Telepathic Message" - set category = "Superpower" - - if(!hallucination_power) - src.verbs -= /mob/living/carbon/human/proc/fakeremotesay - return - - if(stat) - to_chat(usr, SPAN_WARNING("You're not in any state to use your powers right now!")) - return - - if(has_chemical_effect(CE_MIND, 1)) - to_chat(usr, SPAN_WARNING("Chemicals in your blood prevent you from using your power!")) - - var/list/creatures = list() - for(var/mob/living/carbon/C in SSmobs.mob_list) - creatures += C - creatures -= usr - var/mob/target = input("Who do you want to project your mind to?") as null|anything in creatures - if (isnull(target)) - return - - var/msg = sanitize(input(usr, "What do you wish to transmit")) - show_message(SPAN_NOTICE("You project your mind into [target.name]: \"[msg]\"")) - if(!stat && prob(20)) - say(msg) - -//Fake attack -/datum/hallucination/fakeattack - min_power = 30 - -/datum/hallucination/fakeattack/can_affect(var/mob/living/carbon/C) - if(!..()) - return 0 - for(var/mob/living/M in oview(C,1)) - return TRUE - -/datum/hallucination/fakeattack/start() - for(var/mob/living/M in oview(holder,1)) - to_chat(holder, "[M] has punched [holder]!") - holder.playsound_local(get_turf(holder),"punch",50) - -//Fake injection -/datum/hallucination/fakeattack/hypo - min_power = 30 - -/datum/hallucination/fakeattack/hypo/start() - to_chat(holder, "You feel a tiny prick!") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 187c27dc5ea..a5217f66bf6 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -17,7 +17,7 @@ var/last_loc = loc ..(species.gibbed_anim, do_gibs = FALSE) if(last_loc) - gibs(last_loc, _fleshcolor = species.get_flesh_colour(src), _bloodcolor = species.get_blood_color(src)) + gibs(last_loc) /mob/living/carbon/human/dust() if(species) @@ -43,15 +43,18 @@ if(SSticker.mode) SSticker.mode.check_win() - if(config.show_human_death_message) + if(get_config_value(/decl/config/toggle/health_show_human_death_message)) deathmessage = species.get_death_message(src) || "seizes up and falls limp..." else deathmessage = "no message" + . = ..(gibbed, deathmessage, show_dead_message) + if(!gibbed) handle_organs() if(species.death_sound) playsound(loc, species.death_sound, 80, 1, 1) + handle_hud_list() /mob/living/carbon/human/proc/is_husked() @@ -61,9 +64,8 @@ if(is_husked()) return - f_style = /decl/sprite_accessory/facial_hair/shaved - h_style = /decl/sprite_accessory/hair/bald - update_hair(0) + set_facial_hairstyle(/decl/sprite_accessory/facial_hair/shaved, skip_update = TRUE) + set_hairstyle(/decl/sprite_accessory/hair/bald, skip_update = FALSE) mutations.Add(MUTATION_HUSK) for(var/obj/item/organ/external/E in get_external_organs()) diff --git a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm index 168bc7d0aa9..b3c0846e8fe 100644 --- a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm +++ b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm @@ -63,7 +63,7 @@ /datum/appearance_descriptor/proc/get_mob_scale_adjustments(var/offset_value) return -/datum/appearance_descriptor/proc/get_mob_overlay(var/mob/applying, var/offset_value) +/datum/appearance_descriptor/proc/get_mob_appearance_overlay(var/mob/applying, var/offset_value) return /datum/appearance_descriptor/proc/get_third_person_message_start(var/decl/pronouns/my_gender) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index b68d1e52ac0..fd18140bdee 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -6,7 +6,7 @@ species_name += "[species.cyborg_noun] [species.get_root_species_name(src)]" else species_name += "[species.name]" - msg += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" + msg += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" var/extra_species_text = species.get_additional_examine_text(src) if(extra_species_text) msg += "
    [extra_species_text]" @@ -213,6 +213,22 @@ msg += "Physical status: \[[medical]\]\n" msg += "Medical records: \[View\]\n" + // Show IC/OOC info if available. + if(comments_record_id) + var/datum/character_information/comments = SScharacter_info.get_record(comments_record_id) + if(comments?.show_info_on_examine && (comments.ic_info || comments.ooc_info)) + msg += "*---------*
    " + if(comments.ic_info) + if(length(comments.ic_info) <= 40) + msg += "IC Info:
        [comments.ic_info]
    " + else + msg += "IC Info:
        [copytext_preserve_html(comments.ic_info,1,37)]... More...
    " + if(comments.ooc_info) + if(length(comments.ooc_info) <= 40) + msg += "OOC Info:
        [comments.ooc_info]
    " + else + msg += "OOC Info:
        [copytext_preserve_html(comments.ooc_info,1,37)]... More...
    " + msg += "*---------*
    " msg += applying_pressure diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6ed3e23578f..ac37588b7a9 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -49,14 +49,6 @@ var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH) return stomach?.ingested -/mob/living/carbon/human/get_fullness() - if(!should_have_organ(BP_STOMACH)) - return ..() - var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH, /obj/item/organ/internal/stomach) - if(stomach) - return nutrition + (stomach.ingested?.total_volume * 10) - return 0 //Always hungry, but you can't actually eat. :( - /mob/living/carbon/human/get_inhaled_reagents() if(!should_have_organ(BP_LUNGS)) return @@ -99,7 +91,7 @@ stat(null, "Hardsuit charge: [cell_status]") /mob/living/carbon/human/proc/implant_loyalty(mob/living/carbon/human/M, override = FALSE) // Won't override by default. - if(!config.use_loyalty_implants && !override) return // Nuh-uh. + if(!get_config_value(/decl/config/toggle/use_loyalty_implants) && !override) return // Nuh-uh. var/obj/item/implant/loyalty/L = new/obj/item/implant/loyalty(M) L.imp_in = M @@ -322,16 +314,6 @@ return FALSE return ..() -/mob/living/carbon/human/proc/check_dna() - dna.check_integrity(src) - return - -/mob/living/carbon/human/check_has_mouth() - var/obj/item/organ/external/head/H = get_organ(BP_HEAD, /obj/item/organ/external/head) - if(!H || !istype(H) || !H.can_intake_reagents) - return FALSE - return TRUE - /mob/living/carbon/human/empty_stomach() SET_STATUS_MAX(src, STAT_STUN, 3) @@ -414,7 +396,7 @@ reset_blood() if(!client || !key) //Don't boot out anyone already in the mob. - for(var/mob/living/carbon/brain/brain in global.player_list) // This is really nasty, does it even work anymore? + for(var/mob/living/brain/brain in global.player_list) // This is really nasty, does it even work anymore? if(brain.real_name == src.real_name && brain.mind) brain.mind.transfer_to(src) qdel(brain.loc) @@ -434,23 +416,6 @@ verbs += /mob/living/carbon/human/proc/bloody_doodle return 1 //we applied blood to the item -/mob/living/carbon/human/clean_blood(var/clean_feet) - . = ..() - var/obj/item/gloves = get_equipped_item(slot_gloves_str) - if(gloves) - gloves.clean() - gloves.germ_level = 0 - else - germ_level = 0 - - for(var/obj/item/organ/external/organ in get_external_organs()) - //TODO check that organ is not covered - if(clean_feet || (organ.organ_tag in list(BP_L_HAND,BP_R_HAND))) - organ.clean() - update_equipment_overlay(slot_gloves_str, FALSE) - update_equipment_overlay(slot_shoes_str) - return TRUE - /mob/living/carbon/human/get_visible_implants(var/class = 0) var/list/visible_implants = list() @@ -515,14 +480,16 @@ force_update_limbs() // Check and clear hair. - var/decl/sprite_accessory/hair/hairstyle = GET_DECL(h_style) + var/set_hairstyle = get_hairstyle() + var/decl/sprite_accessory/hair/hairstyle = GET_DECL(set_hairstyle) if(!hairstyle?.accessory_is_available(src, species, new_bodytype)) - change_hair(new_bodytype.default_h_style, FALSE) - var/decl/sprite_accessory/hair/facialhairstyle = GET_DECL(f_style) + set_hairstyle(new_bodytype.default_h_style, skip_update = TRUE) + set_hairstyle = get_facial_hairstyle() + var/decl/sprite_accessory/hair/facialhairstyle = GET_DECL(set_hairstyle) if(!facialhairstyle?.accessory_is_available(src, species, new_bodytype)) - change_facial_hair(new_bodytype.default_f_style, FALSE) + set_facial_hairstyle(new_bodytype.default_f_style, skip_update = TRUE) // TODO: check markings. - + update_hair() update_eyes() return TRUE return FALSE @@ -654,7 +621,7 @@ /mob/living/carbon/human/proc/apply_bodytype_appearance() var/decl/bodytype/root_bodytype = get_bodytype() if(!root_bodytype) - skin_colour = COLOR_BLACK + set_skin_colour(COLOR_BLACK) else root_bodytype.apply_appearance(src) default_pixel_x = initial(pixel_x) + root_bodytype.pixel_offset_x @@ -935,7 +902,7 @@ /mob/living/carbon/human/proc/make_reagent(amount, reagent_type) if(stat == CONSCIOUS) var/limit = max(0, reagents.get_overdose(reagent_type) - REAGENT_VOLUME(reagents, reagent_type)) - reagents.add_reagent(reagent_type, min(amount, limit)) + add_to_reagents(reagent_type, min(amount, limit)) //Get fluffy numbers /mob/living/carbon/human/proc/get_blood_pressure() @@ -1030,19 +997,6 @@ return BULLET_IMPACT_METAL return BULLET_IMPACT_MEAT -/mob/living/carbon/human/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage) - ..() - switch(get_bullet_impact_effect_type(def_zone)) - if(BULLET_IMPACT_MEAT) - if(damage && P.damtype == BRUTE) - var/hit_dir = get_dir(P.starting, src) - var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir) - if(!QDELETED(B)) - B.icon_state = pick("dir_splatter_1","dir_splatter_2") - var/scale = min(1, round(P.damage / 50, 0.2)) - B.set_scale(scale) - new /obj/effect/temp_visual/bloodsplatter(loc, hit_dir, species.get_blood_color(src)) - /mob/living/carbon/human/lose_hair() if(get_bodytype().set_default_hair(src)) . = TRUE @@ -1125,14 +1079,15 @@ set_species(species_name, new_bodytype) var/decl/bodytype/root_bodytype = get_bodytype() // root bodytype is set in set_species - if(!skin_colour) - skin_colour = root_bodytype.base_color - if(!hair_colour) - hair_colour = root_bodytype.base_hair_color - if(!facial_hair_colour) - facial_hair_colour = root_bodytype.base_hair_color - if(!eye_colour) - eye_colour = root_bodytype.base_eye_color + if(!get_skin_colour()) + set_skin_colour(root_bodytype.base_color, skip_update = TRUE) + if(!get_hair_colour()) + set_hair_colour(root_bodytype.base_hair_color, skip_update = TRUE) + if(!get_facial_hair_colour()) + set_facial_hair_colour(root_bodytype.base_hair_color, skip_update = TRUE) + if(!get_eye_colour()) + set_eye_colour(root_bodytype.base_eye_color, skip_update = TRUE) + root_bodytype.set_default_hair(src, override_existing = TRUE, defer_update_hair = TRUE) if(!blood_type && length(species?.blood_types)) blood_type = pickweight(species.blood_types) @@ -1200,3 +1155,9 @@ add_stressor(/datum/stressor/thirsty, STRESSOR_DURATION_INDEFINITE) else remove_stressor(/datum/stressor/thirsty) + +/mob/living/carbon/human/get_comments_record() + if(comments_record_id) + return SScharacter_info.get_record(comments_record_id, TRUE) + return ..() + diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/human_appearance.dm similarity index 60% rename from code/modules/mob/living/carbon/human/appearance.dm rename to code/modules/mob/living/carbon/human/human_appearance.dm index 6c52b5604f6..2f8b796aa5b 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/human_appearance.dm @@ -1,8 +1,82 @@ +/mob/living/carbon/human + var/_h_style + var/_f_style + var/_hair_colour + var/_facial_hair_colour + var/_eye_colour + var/_skin_colour + var/_lip_colour + /mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = global.default_topic_state) var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags AC.ui_interact(user, state = state) +/mob/living/carbon/human/get_lip_colour() + return _lip_colour + +/mob/living/carbon/human/get_eye_colour() + return _eye_colour + +/mob/living/carbon/human/get_skin_colour() + return _skin_colour + +/mob/living/carbon/human/get_hairstyle() + return _h_style + +/mob/living/carbon/human/get_hair_colour() + return _hair_colour + +/mob/living/carbon/human/get_facial_hairstyle() + return _f_style + +/mob/living/carbon/human/get_facial_hair_colour() + return _facial_hair_colour + +/mob/living/carbon/human/set_lip_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _lip_colour = new_color + if(!skip_update) + update_body() + +/mob/living/carbon/human/set_eye_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _eye_colour = new_color + if(!skip_update) + update_eyes() + update_body() + +/mob/living/carbon/human/set_skin_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _skin_colour = new_color + if(!skip_update) + force_update_limbs() + update_body() + +/mob/living/carbon/human/set_hair_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _hair_colour = new_color + if(!skip_update) + update_hair() + +/mob/living/carbon/human/set_hairstyle(var/new_hairstyle, var/skip_update = FALSE) + if((. = ..())) + _h_style = new_hairstyle + if(!skip_update) + update_hair() + +/mob/living/carbon/human/set_facial_hair_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _facial_hair_colour = new_color + if(!skip_update) + update_hair() + +/mob/living/carbon/human/set_facial_hairstyle(var/new_facial_hairstyle, var/skip_update = FALSE) + if((. = ..())) + _f_style = new_facial_hairstyle + if(!skip_update) + update_hair() + /mob/living/carbon/human/proc/change_species(var/new_species, var/new_bodytype = null) if(!new_species) return @@ -46,70 +120,23 @@ var/decl/pronouns/pronouns = pick(species.available_pronouns) set_gender(pronouns.name, TRUE) -/mob/living/carbon/human/proc/change_hair(var/hair_style, var/update_icons = TRUE) - if(!hair_style || h_style == hair_style || !ispath(hair_style, /decl/sprite_accessory/hair)) - return - h_style = hair_style - update_hair(update_icons) - return 1 - -/mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style, var/update_icons = TRUE) - if(!facial_hair_style || f_style == facial_hair_style || !ispath(facial_hair_style, /decl/sprite_accessory/facial_hair)) - return - f_style = facial_hair_style - update_hair(update_icons) - return 1 - /mob/living/carbon/human/proc/reset_hair() var/list/valid_hairstyles = get_valid_hairstyle_types() - var/list/valid_facial_hairstyles = get_valid_facial_hairstyle_types() - if(length(valid_hairstyles)) - h_style = pick(valid_hairstyles) + set_hairstyle(pick(valid_hairstyles), skip_update = TRUE) else //this shouldn't happen - h_style = get_bodytype()?.default_h_style || /decl/sprite_accessory/hair/bald + set_hairstyle(get_bodytype()?.default_h_style || /decl/sprite_accessory/hair/bald, skip_update = TRUE) + var/list/valid_facial_hairstyles = get_valid_facial_hairstyle_types() if(length(valid_facial_hairstyles)) - f_style = pick(valid_facial_hairstyles) + set_facial_hairstyle(pick(valid_facial_hairstyles), skip_update = TRUE) else //this shouldn't happen - f_style = get_bodytype()?.default_f_style || /decl/sprite_accessory/facial_hair/shaved + set_facial_hairstyle(get_bodytype()?.default_f_style || /decl/sprite_accessory/facial_hair/shaved, skip_update = TRUE) update_hair() -/mob/living/carbon/human/proc/change_eye_color(var/new_colour) - if(eye_colour != new_colour) - eye_colour = new_colour - update_eyes() - update_body() - return TRUE - return FALSE - -/mob/living/carbon/human/proc/change_hair_color(var/new_colour) - if(hair_colour != new_colour) - hair_colour = new_colour - force_update_limbs() - update_body() - update_hair() - return TRUE - return FALSE - -/mob/living/carbon/human/proc/change_facial_hair_color(var/new_colour) - if(facial_hair_colour != new_colour) - facial_hair_colour = new_colour - update_hair() - return TRUE - return FALSE - -/mob/living/carbon/human/proc/change_skin_color(var/new_colour) - if(skin_colour == new_colour || !(get_bodytype().appearance_flags & HAS_SKIN_COLOR)) - return FALSE - skin_colour = new_colour - force_update_limbs() - update_body() - return TRUE - /mob/living/carbon/human/proc/change_skin_tone(var/tone) if(skin_tone == tone || !(get_bodytype().appearance_flags & HAS_A_SKIN_TONE)) return diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 50172253223..a5bff716d45 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -334,10 +334,12 @@ return 1 -/mob/living/carbon/human/verb/set_default_unarmed_attack(var/atom/radial_target) +/mob/living/carbon/human/verb/set_default_unarmed_attack() + set name = "Set Default Unarmed Attack" set category = "IC" set src = usr + var/list/choices for(var/thing in get_natural_attacks()) var/decl/natural_attack/u_attack = GET_DECL(thing) @@ -345,7 +347,7 @@ var/image/radial_button = new radial_button.name = capitalize(u_attack.name) LAZYSET(choices, u_attack, radial_button) - var/decl/natural_attack/new_attack = show_radial_menu(src, (radial_target || src), choices, radius = 42, use_labels = TRUE) + var/decl/natural_attack/new_attack = show_radial_menu(src, (attack_selector || src), choices, radius = 42, use_labels = TRUE) if(QDELETED(src) || !istype(new_attack) || !(new_attack.type in get_natural_attacks())) return default_attack = new_attack @@ -354,4 +356,4 @@ var/summary = default_attack.summarize() if(summary) to_chat(src, SPAN_NOTICE(summary)) - attack_selector?.update_icon() \ No newline at end of file + attack_selector?.update_icon() diff --git a/code/modules/organs/blood.dm b/code/modules/mob/living/carbon/human/human_blood.dm similarity index 60% rename from code/modules/organs/blood.dm rename to code/modules/mob/living/carbon/human/human_blood.dm index 834456dd00c..e4d1a6a7e0e 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/mob/living/carbon/human/human_blood.dm @@ -1,7 +1,3 @@ -/**************************************************** - BLOOD SYSTEM -****************************************************/ - /mob/living/carbon/human var/datum/reagents/vessel // Container for blood and BLOOD ONLY. Do not transfer other chems here. @@ -49,7 +45,7 @@ "donor" = weakref(src), "species" = get_species_name(), "blood_DNA" = get_unique_enzymes(), - "blood_color" = species.get_blood_color(src), + "blood_color" = species.get_species_blood_color(src), "blood_type" = get_blood_type(), "trace_chem" = null )) @@ -130,72 +126,32 @@ return 0 if(!amt) return 0 - amt *= ((src.mob_size/MOB_SIZE_MEDIUM) ** 0.5) - return vessel.remove_any(amt) -/**************************************************** - BLOOD TRANSFERS -****************************************************/ - -//Gets blood from mob to the container, preserving all data in it. -/mob/living/carbon/proc/take_blood(obj/item/chems/container, var/amount) - container.reagents.add_reagent(species.blood_reagent, amount, get_blood_data()) - return 1 - -//For humans, blood does not appear from blue, it comes from vessels. -/mob/living/carbon/human/take_blood(obj/item/chems/container, var/amount) - - if(!vessel) - make_blood() - - if(!should_have_organ(BP_HEART)) - reagents.trans_to_obj(container, amount) - return 1 - - if(vessel.total_volume < amount) - return null - if(vessel.has_reagent(species.blood_reagent)) - LAZYSET(vessel.reagent_data, species.blood_reagent, get_blood_data()) - vessel.trans_to_holder(container.reagents, amount) - return 1 - -//Transfers blood from container ot vessels -/mob/living/carbon/proc/inject_blood(var/amount, var/datum/reagents/donor) - if(!species.blood_volume) - return //Don't divide by 0 - var/injected_data = REAGENT_DATA(donor, species.blood_reagent) - var/chems = LAZYACCESS(injected_data, "trace_chem") - for(var/C in chems) - src.reagents.add_reagent(C, (text2num(chems[C]) / species.blood_volume) * amount)//adds trace chemicals to owner's blood - //Transfers blood from reagents to vessel, respecting blood types compatability. /mob/living/carbon/human/inject_blood(var/amount, var/datum/reagents/donor) if(!should_have_organ(BP_HEART)) - reagents.add_reagent(species.blood_reagent, amount, REAGENT_DATA(donor, species.blood_reagent)) + add_to_reagents(species.blood_reagent, amount, REAGENT_DATA(donor, species.blood_reagent)) return var/injected_data = REAGENT_DATA(donor, species.blood_reagent) var/injected_b_type = LAZYACCESS(injected_data, "blood_type") - if(blood_incompatible(injected_b_type)) + if(is_blood_incompatible(injected_b_type)) var/decl/blood_type/blood_decl = injected_b_type && get_blood_type_by_name(injected_b_type) if(istype(blood_decl)) - reagents.add_reagent(blood_decl.transfusion_fail_reagent, amount * blood_decl.transfusion_fail_percentage) + add_to_reagents(blood_decl.transfusion_fail_reagent, amount * blood_decl.transfusion_fail_percentage) else - reagents.add_reagent(/decl/material/liquid/coagulated_blood, amount * 0.5) + add_to_reagents(/decl/material/liquid/coagulated_blood, amount * 0.5) else adjust_blood(amount, injected_data) ..() -/mob/living/carbon/human/proc/blood_incompatible(blood_type) - return species.is_blood_incompatible(dna?.b_type, blood_type) - /mob/living/carbon/human/proc/regenerate_blood(var/amount) amount *= (species.blood_volume / SPECIES_BLOOD_DEFAULT) var/stress_modifier = get_stress_modifier() if(stress_modifier) - amount *= 1-(config.stress_blood_recovery_constant * stress_modifier) + amount *= 1-(get_config_value(/decl/config/num/health_stress_blood_recovery_constant) * stress_modifier) var/blood_volume_raw = vessel.total_volume amount = max(0,min(amount, species.blood_volume - blood_volume_raw)) @@ -203,107 +159,22 @@ adjust_blood(amount, get_blood_data()) return amount -/mob/living/proc/get_blood_data() - - var/data = list() - data["donor"] = weakref(src) - data["blood_DNA"] = get_unique_enzymes() - data["blood_type"] = get_blood_type() - data["species"] = get_species_name() - - var/list/temp_chem = list() - for(var/R in reagents.reagent_volumes) - temp_chem[R] = REAGENT_VOLUME(reagents, R) - data["trace_chem"] = temp_chem - data["dose_chem"] = chem_doses ? chem_doses.Copy() : list() - - var/decl/species/my_species = get_species() - if(my_species) - data["has_oxy"] = my_species.blood_oxy - data["blood_color"] = my_species.get_blood_color(src) - else if(isSynthetic()) - data["has_oxy"] = FALSE - data["blood_color"] = SYNTH_BLOOD_COLOR - else - data["has_oxy"] = TRUE - data["blood_color"] = COLOR_BLOOD_HUMAN - return data - -/proc/blood_splatter(var/target, var/source, var/large, var/spray_dir) - - var/obj/effect/decal/cleanable/blood/splatter - var/decal_type = /obj/effect/decal/cleanable/blood/splatter - var/turf/T = get_turf(target) - - // Are we dripping or splattering? - var/list/drips = list() - // Only a certain number of drips (or one large splatter) can be on a given turf. - for(var/obj/effect/decal/cleanable/blood/drip/drop in T) - drips |= drop.drips - qdel(drop) - if(!large && drips.len < 3) - decal_type = /obj/effect/decal/cleanable/blood/drip - - // Find a blood decal or create a new one. - if(T) - var/list/existing = filter_list(T.contents, decal_type) - if(length(existing) > 3) - splatter = pick(existing) - if(!splatter) - splatter = new decal_type(T) - - if(QDELETED(splatter)) - return +//For humans, blood does not appear from blue, it comes from vessels. +/mob/living/carbon/human/take_blood(obj/item/chems/container, var/amount) - if(istype(splatter, /obj/effect/decal/cleanable/blood/drip) && drips && drips.len && !large) - var/obj/effect/decal/cleanable/blood/drip/drop = splatter - drop.overlays |= drips - drop.drips |= drips - - // If there's no data to copy, call it quits here. - var/blood_data - var/blood_type - if(ishuman(source)) - var/mob/living/carbon/human/donor = source - blood_data = REAGENT_DATA(donor.vessel, donor.species.blood_reagent) - blood_type = donor.get_blood_type() - else if(isatom(source)) - var/atom/donor = source - blood_data = REAGENT_DATA(donor.reagents, /decl/material/liquid/blood) - if(!islist(blood_data)) - return splatter - - if(spray_dir) - splatter.icon_state = "squirt" - splatter.set_dir(spray_dir) - // Update blood information. - if(LAZYACCESS(blood_data, "blood_DNA")) - LAZYSET(splatter.blood_data, blood_data["blood_DNA"], blood_data) - splatter.blood_DNA = list() - if(LAZYACCESS(blood_data, "blood_type")) - splatter.blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"] - else - splatter.blood_DNA[blood_data["blood_DNA"]] = "O+" - var/datum/extension/forensic_evidence/forensics = get_or_create_extension(splatter, /datum/extension/forensic_evidence) - forensics.add_data(/datum/forensics/blood_dna, blood_data["blood_DNA"]) - - if(!blood_type && LAZYACCESS(blood_data, "blood_type")) - blood_type = LAZYACCESS(blood_data, "blood_type") - - // Update appearance. - if(blood_type) - var/decl/blood_type/blood_type_decl = get_blood_type_by_name(blood_type) - splatter.name = blood_type_decl.splatter_name - splatter.desc = blood_type_decl.splatter_desc - splatter.basecolor = blood_type_decl.splatter_colour - - if(LAZYACCESS(blood_data, "blood_color")) - splatter.basecolor = blood_data["blood_color"] - - splatter.update_icon() - splatter.fluorescent = FALSE - splatter.set_invisibility(INVISIBILITY_NONE) - return splatter + if(!vessel) + make_blood() + + if(!should_have_organ(BP_HEART)) + reagents.trans_to_obj(container, amount) + return 1 + + if(vessel.total_volume < amount) + return null + if(vessel.has_reagent(species.blood_reagent)) + LAZYSET(vessel.reagent_data, species.blood_reagent, get_blood_data()) + vessel.trans_to_holder(container.reagents, amount) + return 1 //Percentage of maximum blood volume. /mob/living/carbon/human/proc/get_blood_volume() diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index c1887030611..5f5928aa041 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -5,7 +5,7 @@ /mob/living/carbon/human/update_health() ..() //TODO: fix husking - if(stat == DEAD && (get_max_health() - getFireLoss()) < config.health_threshold_dead) + if(stat == DEAD && (get_max_health() - getFireLoss()) < get_config_value(/decl/config/num/health_health_threshold_dead)) make_husked() /mob/living/carbon/human/adjustBrainLoss(var/amount, var/do_update_health = TRUE) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index d7a9f1dbb8e..0999068197b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -278,7 +278,7 @@ meteor_act return 0 //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb - var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100 + var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * get_config_value(/decl/config/num/health_organ_health_multiplier))*100 if(prob(dislocate_chance * blocked_mult(blocked))) visible_message("[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!") organ.dislocate(1) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 7f9ce538e1c..d57fc319496 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,20 +1,12 @@ /mob/living/carbon/human - var/h_style - var/f_style - - var/hair_colour - var/facial_hair_colour - var/skin_colour - var/eye_colour - var/regenerate_body_icon = FALSE // If true, the next icon update will also regenerate the body. var/skin_tone = 0 //Skin tone var/damage_multiplier = 1 //multiplies melee combat damage - var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup + var/lip_color = null //no lipstick by default- arguably misleading, as it could be used for general makeup var/list/worn_underwear = list() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 0073a9bb5ea..b97bf79c27d 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -64,7 +64,7 @@ if(mRun in mutations) tally = 0 - return (tally+config.human_delay) + return (tally+get_config_value(/decl/config/num/movement_human)) /mob/living/carbon/human/size_strength_mod() . = ..() diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 2573c969a20..00af3106c05 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -283,7 +283,7 @@ update_inhand_overlays(FALSE) update_body(FALSE) update_bandages(FALSE) - update_damage_icon(FALSE) + update_damage_overlays(FALSE) hud_reset() queue_icon_update() //Avoids calling icon updates 50 times when adding multiple organs diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index a3f34561ed9..2a062c62fe9 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -20,8 +20,9 @@ to_chat(src, SPAN_WARNING("You can't mess with your hair right now!")) return - if(h_style) - var/decl/sprite_accessory/hair/hair_style = GET_DECL(h_style) + var/hairstyle = get_hairstyle() + if(hairstyle) + var/decl/sprite_accessory/hair/hair_style = GET_DECL(hairstyle) if(!(hair_style.flags & HAIR_TIEABLE)) to_chat(src, SPAN_WARNING("Your hair isn't long enough to tie.")) return @@ -39,8 +40,8 @@ if(incapacitated()) to_chat(src, SPAN_WARNING("You can't mess with your hair right now!")) return - if(selected_type && h_style != selected_type) - h_style = selected_type + if(selected_type && hairstyle != selected_type) + set_hairstyle(selected_type) try_refresh_visible_overlays() visible_message(SPAN_NOTICE("\The [src] pauses a moment to style their hair.")) else @@ -103,5 +104,5 @@ set name = "Change Colour" set desc = "Choose the colour of your skin." - var/new_skin = input(usr, "Choose your new skin colour: ", "Change Colour", skin_colour) as color|null - change_skin_color(new_skin) + var/new_skin = input(usr, "Choose your new skin colour: ", "Change Colour", get_skin_colour()) as color|null + set_skin_colour(new_skin) diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm index 245c867f446..71eb35481c6 100644 --- a/code/modules/mob/living/carbon/human/human_species.dm +++ b/code/modules/mob/living/carbon/human/human_species.dm @@ -3,12 +3,12 @@ status_flags = GODMODE|CANPUSH virtual_mob = null -/mob/living/carbon/human/dummy/mannequin/Initialize() +/mob/living/carbon/human/dummy/mannequin/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) . = ..() STOP_PROCESSING(SSmobs, src) global.human_mob_list -= src -/mob/living/carbon/human/dummy/selfdress/Initialize() +/mob/living/carbon/human/dummy/selfdress/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) ..() return INITIALIZE_HINT_LATELOAD @@ -59,7 +59,8 @@ /mob/living/carbon/human/monkey gender = PLURAL -/mob/living/carbon/human/monkey/Initialize() +/mob/living/carbon/human/monkey/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) if(gender == PLURAL) gender = pick(MALE, FEMALE) - . = ..(species_name = SPECIES_MONKEY) + species_name = SPECIES_MONKEY + . = ..() diff --git a/code/modules/mob/living/carbon/human/human_verbs.dm b/code/modules/mob/living/carbon/human/human_verbs.dm index c9ed44b806b..f83e9512aee 100644 --- a/code/modules/mob/living/carbon/human/human_verbs.dm +++ b/code/modules/mob/living/carbon/human/human_verbs.dm @@ -11,18 +11,17 @@ src.verbs -= /mob/living/carbon/human/proc/morph return - var/new_facial = input("Please select facial hair color.", "Character Generation", facial_hair_colour) as color + var/new_facial = input("Please select facial hair color.", "Character Generation", get_facial_hair_colour()) as color if(new_facial) - facial_hair_colour = new_facial + set_facial_hair_colour(new_facial, skip_update = TRUE) - var/new_hair = input("Please select hair color.", "Character Generation", hair_colour) as color + var/new_hair = input("Please select hair color.", "Character Generation", get_hair_colour()) as color if(new_hair) - hair_colour = new_hair + set_hair_colour(new_hair, skip_update = TRUE) - var/new_eyes = input("Please select eye color.", "Character Generation", eye_colour) as color + var/new_eyes = input("Please select eye color.", "Character Generation", get_eye_colour()) as color if(new_eyes) - eye_colour = new_eyes - update_eyes() + set_eye_colour(new_eyes) var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-skin_tone]") as text @@ -39,11 +38,11 @@ for(var/x in all_hairs) hairs += all_hairs[x] - var/decl/new_style = input("Please select hair style", "Character Generation",h_style) as null|anything in hairs + var/decl/new_style = input("Please select hair style", "Character Generation",get_hairstyle()) as null|anything in hairs // if new style selected (not cancel) if(new_style) - h_style = new_style.type + set_hairstyle(new_style.type, skip_update = TRUE) // facial hair var/list/all_fhairs = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/facial_hair) @@ -52,10 +51,10 @@ for(var/x in all_fhairs) fhairs += all_fhairs[x] - new_style = input("Please select facial style", "Character Generation",f_style) as null|anything in fhairs + new_style = input("Please select facial style", "Character Generation", get_facial_hairstyle()) as null|anything in fhairs if(new_style) - f_style = new_style.type + set_facial_hairstyle(new_style.type, skip_update = TRUE) var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neutral") if (new_gender) @@ -65,6 +64,8 @@ gender = FEMALE else gender = NEUTER + + update_hair() try_refresh_visible_overlays() check_dna() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 740ce946b08..8afcbb7c37f 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -3,14 +3,6 @@ //NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick! #define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. -#define HUMAN_CRIT_TIME_CUSHION (10 MINUTES) //approximate time limit to stabilize someone in crit -#define HUMAN_CRIT_HEALTH_CUSHION (config.health_threshold_crit - config.health_threshold_dead) - -//The amount of damage you'll get when in critical condition. We want this to be a HUMAN_CRIT_TIME_CUSHION long deal. -//There are HUMAN_CRIT_HEALTH_CUSHION hp to get through, so (HUMAN_CRIT_HEALTH_CUSHION/HUMAN_CRIT_TIME_CUSHION) per tick. -//Breaths however only happen once every MOB_BREATH_DELAY life ticks. The delay between life ticks is set by the mob process. -#define HUMAN_CRIT_MAX_OXYLOSS ( MOB_BREATH_DELAY * process_schedule_interval("mob") * (HUMAN_CRIT_HEALTH_CUSHION/HUMAN_CRIT_TIME_CUSHION) ) - #define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point #define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point #define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point @@ -36,36 +28,16 @@ var/pressure_alert = 0 var/stamina = 100 -/mob/living/carbon/human/Life() - set invisibility = FALSE - set background = BACKGROUND_ENABLED - - if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) - return - - fire_alert = 0 //Reset this here, because both breathe() and handle_environment() have a chance to set it. - - ..() - - if(life_tick%30==15) - hud_updateflag = 1022 - - voice = GetVoice() - - //No need to update all of these procs if the guy is dead. - if(stat != DEAD && !is_in_stasis()) - last_pain = null // Clear the last cached pain value so further getHalloss() calls won't use an old value. - //Organs and blood - handle_organs() - handle_shock() - handle_pain() - handle_stamina() - - if(!handle_some_updates()) - return //We go ahead and process them 5 times for HUD images and other stuff though. - - //Update our name based on whether our face is obscured/disfigured - SetName(get_visible_name()) +/mob/living/carbon/human/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE + last_pain = null // Clear the last cached pain value so further getHalloss() calls won't use an old value. + //Organs and blood + handle_organs() + handle_shock() + handle_pain() + handle_stamina() /mob/living/carbon/human/get_stamina() return stamina @@ -86,7 +58,7 @@ /mob/living/carbon/human/proc/handle_stamina() if((world.time - last_quick_move_time) > 5 SECONDS) var/mod = (lying + (nutrition / get_max_nutrition())) / 2 - adjust_stamina(max(config.minimum_stamina_recovery, config.maximum_stamina_recovery * mod) * (1 + GET_CHEMICAL_EFFECT(src, CE_ENERGETIC))) + adjust_stamina(max(get_config_value(/decl/config/num/movement_max_stamina_recovery), get_config_value(/decl/config/num/movement_min_stamina_recovery) * mod) * (1 + GET_CHEMICAL_EFFECT(src, CE_ENERGETIC))) /mob/living/carbon/human/set_stat(var/new_stat) var/old_stat = stat @@ -144,7 +116,11 @@ return ONE_ATMOSPHERE + pressure_difference /mob/living/carbon/human/handle_impaired_vision() - ..() + + . = ..() + if(!.) + return + //Vision var/obj/item/organ/vision var/decl/bodytype/root_bodytype = get_bodytype() @@ -163,10 +139,9 @@ /mob/living/carbon/human/handle_disabilities() ..() - if(stat != DEAD) - if ((disabilities & COUGHING) && prob(5) && GET_STATUS(src, STAT_PARA) <= 1) - drop_held_items() - cough() + if(stat != DEAD && (disabilities & COUGHING) && prob(5) && GET_STATUS(src, STAT_PARA) <= 1) + drop_held_items() + cough() /mob/living/carbon/human/handle_mutations_and_radiation() if(getFireLoss()) @@ -382,98 +357,79 @@ return TRUE /mob/living/carbon/human/handle_regular_status_updates() - if(!handle_some_updates()) - return 0 - if(status_flags & GODMODE) return 0 + voice = GetVoice() + SetName(get_visible_name()) - update_health() // TODO: unify with parent call, Life() PR - //SSD check, if a logged player is awake put them back to sleep! - if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP - SET_STATUS_MAX(src, STAT_BLIND, 2) - set_status(STAT_SILENCE, 0) - else //ALIVE. LIGHTS ARE ON - - if(hallucination_power) - handle_hallucinations() - - if(get_shock() >= species.total_health) - if(!stat) - to_chat(src, "[species.halloss_message_self]") - src.visible_message("[src] [species.halloss_message]") - SET_STATUS_MAX(src, STAT_PARA, 10) - - if(HAS_STATUS(src, STAT_PARA) || HAS_STATUS(src, STAT_ASLEEP)) - SET_STATUS_MAX(src, STAT_BLIND, 2) - set_stat(UNCONSCIOUS) - animate_tail_reset() - adjustHalLoss(-3) - - if(prob(2) && is_asystole() && isSynthetic()) - visible_message("[src] [pick("emits low pitched whirr","beeps urgently")].") - //CONSCIOUS - else - set_stat(CONSCIOUS) - - // Check everything else. - - //Periodically double-check embedded_flag - if(embedded_flag && !(life_tick % 10)) - if(!embedded_needs_process()) - embedded_flag = 0 - - //Resting - if(resting) - if(HAS_STATUS(src, STAT_DIZZY)) - ADJ_STATUS(src, STAT_DIZZY, -15) - if(HAS_STATUS(src, STAT_JITTER)) - ADJ_STATUS(src, STAT_JITTER, -15) - adjustHalLoss(-3) - else - if(HAS_STATUS(src, STAT_DIZZY)) - ADJ_STATUS(src, STAT_DIZZY, -3) - if(HAS_STATUS(src, STAT_JITTER)) - ADJ_STATUS(src, STAT_JITTER, -3) - adjustHalLoss(-1) + if(status_flags & GODMODE) + return FALSE - if(HAS_STATUS(src, STAT_DROWSY)) - SET_STATUS_MAX(src, STAT_BLURRY, 2) - var/sleepy = GET_STATUS(src, STAT_DROWSY) - if(sleepy > 10) - var/zzzchance = min(5, 5*sleepy/30) - if((prob(zzzchance) || sleepy >= 60)) - if(stat == CONSCIOUS) - to_chat(src, "You are about to fall asleep...") - SET_STATUS_MAX(src, STAT_ASLEEP, 5) - - // If you're dirty, your gloves will become dirty, too. - var/obj/item/gloves = get_equipped_item(slot_gloves_str) - if(gloves && germ_level > gloves.germ_level && prob(10)) - gloves.germ_level += 1 - - if(vsc.contaminant_control.CONTAMINATION_LOSS) - var/total_contamination= 0 - for(var/obj/item/I in src) - if(I.contaminated) - total_contamination += vsc.contaminant_control.CONTAMINATION_LOSS - adjustToxLoss(total_contamination) - - if(stasis_value > 1 && GET_STATUS(src, STAT_DROWSY) < stasis_value * 4) - ADJ_STATUS(src, STAT_DROWSY, min(stasis_value, 3)) - if(!stat && prob(1)) - to_chat(src, "You feel slow and sluggish...") + if(vsc.contaminant_control.CONTAMINATION_LOSS) + var/total_contamination= 0 + for(var/obj/item/I in src) + if(I.contaminated) + total_contamination += vsc.contaminant_control.CONTAMINATION_LOSS + adjustToxLoss(total_contamination) + + . = ..() + if(!.) + return + + if(get_shock() >= species.total_health) + if(!stat) + to_chat(src, "[species.halloss_message_self]") + src.visible_message("[src] [species.halloss_message]") + SET_STATUS_MAX(src, STAT_PARA, 10) + + if(HAS_STATUS(src, STAT_PARA) || HAS_STATUS(src, STAT_ASLEEP)) + set_stat(UNCONSCIOUS) + animate_tail_reset() + adjustHalLoss(-3) + if(prob(2) && is_asystole() && isSynthetic()) + visible_message("[src] [pick("emits low pitched whirr","beeps urgently")].") + else + set_stat(CONSCIOUS) + + // Check everything else. + //Periodically double-check embedded_flag + if(embedded_flag && !(life_tick % 10)) + if(!embedded_needs_process()) + embedded_flag = 0 + + //Resting + if(resting) + if(HAS_STATUS(src, STAT_DIZZY)) + ADJ_STATUS(src, STAT_DIZZY, -15) + if(HAS_STATUS(src, STAT_JITTER)) + ADJ_STATUS(src, STAT_JITTER, -15) + adjustHalLoss(-3) + else + if(HAS_STATUS(src, STAT_DIZZY)) + ADJ_STATUS(src, STAT_DIZZY, -3) + if(HAS_STATUS(src, STAT_JITTER)) + ADJ_STATUS(src, STAT_JITTER, -3) + adjustHalLoss(-1) + + if(HAS_STATUS(src, STAT_DROWSY)) + SET_STATUS_MAX(src, STAT_BLURRY, 2) + var/sleepy = GET_STATUS(src, STAT_DROWSY) + if(sleepy > 10) + var/zzzchance = min(5, 5*sleepy/30) + if((prob(zzzchance) || sleepy >= 60)) + if(stat == CONSCIOUS) + to_chat(src, SPAN_NOTICE("You are about to fall asleep...")) + SET_STATUS_MAX(src, STAT_ASLEEP, 5) - return 1 /mob/living/carbon/human/handle_regular_hud_updates() + fire_alert = 0 //Reset this here, because both breathe() and handle_environment() have a chance to set it. + if(life_tick%30==15) + hud_updateflag = 1022 if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head handle_hud_list() - - // now handle what we see on our screen - - if(!..()) + . = ..() + if(!.) return - if(stat != DEAD) var/half_health = get_max_health()/2 if(stat == UNCONSCIOUS && current_health < half_health) @@ -684,7 +640,7 @@ var/stress_modifier = get_stress_modifier() if(stress_modifier) - stress_modifier *= config.stress_shock_recovery_constant + stress_modifier *= get_config_value(/decl/config/num/health_stress_shock_recovery_constant) if(is_asystole()) shock_stage = max(shock_stage + (BASE_SHOCK_RECOVERY + stress_modifier), 61) diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm index cee24738220..58f39cb763c 100644 --- a/code/modules/mob/living/carbon/human/npcs.dm +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -2,7 +2,7 @@ real_name = "Pun Pun" gender = MALE -/mob/living/carbon/human/monkey/punpun/Initialize() +/mob/living/carbon/human/monkey/punpun/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) ..() return INITIALIZE_HINT_LATELOAD @@ -32,8 +32,9 @@ sensor.set_sensor_mode(VITALS_SENSOR_OFF) attach_accessory(null, sensor) -/mob/living/carbon/human/blank/Initialize() - . = ..(species_name = SPECIES_HUMAN) +/mob/living/carbon/human/blank/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) + species_name = SPECIES_HUMAN + ..() return INITIALIZE_HINT_LATELOAD /mob/living/carbon/human/blank/LateInitialize() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 697bea8e914..b0f8727ff59 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -13,8 +13,9 @@ var/global/list/_limb_mask_cache = list() TODO: Proper documentation icon_key is [bodytype.get_icon_cache_uid(src)][g][husk][skin_tone] */ -var/global/list/human_icon_cache = list() -var/global/list/tail_icon_cache = list() //key is [bodytype.get_icon_cache_uid(src)][skin_colour] +var/global/list/human_icon_cache = list() +var/global/list/eye_icon_cache = list() +var/global/list/tail_icon_cache = list() //key is [bodytype.get_icon_cache_uid(src)][skin_colour] var/global/list/light_overlay_cache = list() /proc/overlay_image(icon,icon_state,color,flags) @@ -65,7 +66,7 @@ There are several things that need to be remembered: > There are also these special cases: update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows - update_damage_icon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it) + update_damage_overlays() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it) update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and ...eyes were merged into update_body) @@ -99,9 +100,6 @@ If you have any questions/constructive-comments/bugs-to-report/or have a massivl Please contact me on #coderbus IRC. ~Carn x */ -/mob/living/carbon/human - var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed - /mob/living/carbon/human/refresh_visible_overlays() update_mutations(FALSE) update_body(FALSE) @@ -112,7 +110,7 @@ Please contact me on #coderbus IRC. ~Carn x update_fire(FALSE) update_surgery(FALSE) update_bandages(FALSE) - update_damage_icon(FALSE) + update_damage_overlays(FALSE) return ..() /mob/living/carbon/human/on_update_icon() @@ -138,6 +136,7 @@ Please contact me on #coderbus IRC. ~Carn x if(lying && (root_bodytype.prone_overlay_offset[1] || root_bodytype.prone_overlay_offset[2])) M.Translate(root_bodytype.prone_overlay_offset[1], root_bodytype.prone_overlay_offset[2]) + var/mangle_planes = FALSE for(var/i = 1 to LAZYLEN(visible_overlays)) var/entry = visible_overlays[i] if(istype(entry, /image)) @@ -145,11 +144,18 @@ Please contact me on #coderbus IRC. ~Carn x if(i != HO_DAMAGE_LAYER) overlay.transform = M add_overlay(entry) + mangle_planes = mangle_planes || overlay.plane >= ABOVE_LIGHTING_PLANE else if(islist(entry)) for(var/image/overlay in entry) if(i != HO_DAMAGE_LAYER) overlay.transform = M add_overlay(overlay) + mangle_planes = mangle_planes || overlay.plane >= ABOVE_LIGHTING_PLANE + + if(mangle_planes) + z_flags |= ZMM_MANGLE_PLANES + else + z_flags &= ~ZMM_MANGLE_PLANES for(var/i = 1 to LAZYLEN(visible_underlays)) var/entry = visible_underlays[i] @@ -161,12 +167,6 @@ Please contact me on #coderbus IRC. ~Carn x underlay.transform = M underlays = visible_underlays - var/obj/item/organ/external/head/head = get_organ(BP_HEAD, /obj/item/organ/external/head) - if(head) - var/image/I = head.get_eye_overlay() - if(I) - add_overlay(I) - /mob/living/carbon/human/proc/get_icon_scale_mult() // If you want stuff like scaling based on species or something, here is a good spot to mix the numbers together. return list(icon_scale_x, icon_scale_y) @@ -210,46 +210,9 @@ Please contact me on #coderbus IRC. ~Carn x return transform -var/global/list/damage_icon_parts = list() - -//DAMAGE OVERLAYS -//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists -/mob/living/carbon/human/update_damage_icon(var/update_icons=1) - - // first check whether something actually changed about damage appearance - var/damage_appearance = "" - for(var/obj/item/organ/external/O in get_external_organs()) - damage_appearance += O.damage_state - - if(damage_appearance == previous_damage_appearance) - // nothing to do here - return - - previous_damage_appearance = damage_appearance - var/decl/bodytype/root_bodytype = get_bodytype() - var/image/standing_image = image(root_bodytype.get_damage_overlays(src), icon_state = "00") - - // blend the individual damage states with our icons - for(var/obj/item/organ/external/O in get_external_organs()) - O.update_damstate() - O.update_icon() - if(O.damage_state == "00") - continue - var/icon/DI - var/use_colour = (BP_IS_PROSTHETIC(O) ? SYNTH_BLOOD_COLOR : O.species.get_blood_color(src)) - var/cache_index = "[O.damage_state]/[O.bodytype.type]/[O.icon_state]/[use_colour]/[species.name]" - if(damage_icon_parts[cache_index] == null) - DI = new /icon(O.bodytype.get_damage_overlays(src), O.damage_state) // the damage icon for whole human - DI.Blend(get_limb_mask_for(O.bodytype, O.icon_state), ICON_MULTIPLY) // mask with this organ's pixels - DI.Blend(use_colour, ICON_MULTIPLY) - damage_icon_parts[cache_index] = DI - else - DI = damage_icon_parts[cache_index] - - standing_image.overlays += DI - +/mob/living/carbon/human/update_damage_overlays(update_icons = TRUE) + . = ..() update_bandages(update_icons) - set_current_mob_overlay(HO_DAMAGE_LAYER, standing_image, update_icons) /mob/living/carbon/human/proc/update_bandages(var/update_icons=1) var/list/bandage_overlays @@ -261,63 +224,35 @@ var/global/list/damage_icon_parts = list() LAZYADD(bandage_overlays, image(bandage_icon, "[O.icon_state][bandage_level]")) set_current_mob_overlay(HO_DAMAGE_LAYER, bandage_overlays, update_icons) +/mob/living/carbon/human/proc/get_human_icon_cache_key() + . = list() + for(var/limb_tag in global.all_limb_tags) + . += "[limb_tag]_" + var/obj/item/organ/external/part = GET_EXTERNAL_ORGAN(src, limb_tag) + if(isnull(part) || part.skip_body_icon_draw) + . += "skip" + continue + part.update_icon() // This wil regenerate their icon if needed, and more importantly set their cache key. + . += part._icon_cache_key + . += "husked_[!!is_husked()]" + . = JOINTEXT(.) + //BASE MOB SPRITE -/mob/living/carbon/human/update_body(var/update_icons=1) +/mob/living/carbon/human/update_body(var/update_icons = TRUE) var/list/limbs = get_external_organs() if(!LAZYLEN(limbs)) return // Something is trying to update our body pre-init (probably loading a preview image during world startup). - var/husk_color_mod = rgb(96,88,80) - var/husk = is_husked() - - //CACHING: Generate an index key from visible bodyparts. - //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. - - //Create a new, blank icon for our mob to use. - if(stand_icon) - qdel(stand_icon) var/decl/bodytype/root_bodytype = get_bodytype() - stand_icon = new(root_bodytype.icon_template || 'icons/mob/human.dmi',"blank") - - var/icon_key = "[root_bodytype.get_icon_cache_uid(src)][skin_tone][skin_colour]" - if(lip_style) - icon_key += "[lip_style]" - else - icon_key += "nolips" - var/obj/item/organ/internal/eyes/eyes = get_organ((root_bodytype.vision_organ || BP_EYES), /obj/item/organ/internal/eyes) - icon_key += istype(eyes) ? eyes.eye_colour : COLOR_BLACK + var/icon_key = get_human_icon_cache_key() - for(var/limb_tag in global.all_limb_tags) - var/obj/item/organ/external/part = GET_EXTERNAL_ORGAN(src, limb_tag) - if(isnull(part) || part.skip_body_icon_draw) - icon_key += "0" - continue - for(var/M in part.markings) - icon_key += "[M][part.markings[M]]" - if(part) - icon_key += "[part.bodytype.get_icon_cache_uid(part.owner)][part.render_alpha]" - icon_key += "[part.skin_tone]" - if(part.skin_colour) - icon_key += "[part.skin_colour]" - icon_key += "[part.skin_blend]" - for(var/M in part.markings) - icon_key += "[M][part.markings[M]]" - if(!BP_IS_PROSTHETIC(part) && (part.status & ORGAN_DEAD)) - icon_key += "2" - else - icon_key += "1" - - icon_key = "[icon_key][husk ? 1 : 0]" - - var/icon/base_icon - if(human_icon_cache[icon_key]) - base_icon = human_icon_cache[icon_key] - else + stand_icon = global.human_icon_cache[icon_key] + if(!stand_icon) //BEGIN CACHED ICON GENERATION. - base_icon = icon(root_bodytype.icon_template) + stand_icon = new(root_bodytype.icon_template || 'icons/mob/human.dmi', "blank") for(var/obj/item/organ/external/part in limbs) - var/icon/temp = part.get_icon() + var/icon/temp = part.icon // Grabbing the icon excludes overlays. //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part) if(part.icon_position & (LEFT | RIGHT)) @@ -328,34 +263,28 @@ var/global/list/damage_icon_parts = list() temp2.Insert(new /icon(temp,dir=EAST),dir=EAST) if(!(part.icon_position & RIGHT)) temp2.Insert(new /icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_OVERLAY) + stand_icon.Blend(temp2, ICON_OVERLAY) if(part.icon_position & LEFT) temp2.Insert(new /icon(temp,dir=EAST),dir=EAST) if(part.icon_position & RIGHT) temp2.Insert(new /icon(temp,dir=WEST),dir=WEST) - base_icon.Blend(temp2, ICON_UNDERLAY) + stand_icon.Blend(temp2, ICON_UNDERLAY) else if(part.icon_position & UNDER) - base_icon.Blend(temp, ICON_UNDERLAY) + stand_icon.Blend(temp, ICON_UNDERLAY) else - base_icon.Blend(temp, ICON_OVERLAY) - - if(husk) - base_icon.ColorTone(husk_color_mod) - + stand_icon.Blend(temp, ICON_OVERLAY) //Handle husk overlay. - if(husk) + if(is_husked()) var/husk_icon = root_bodytype.get_husk_icon(src) if(husk_icon) - var/icon/mask = new(base_icon) + var/icon/mask = new(stand_icon) var/icon/husk_over = new(husk_icon, "") mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0) husk_over.Blend(mask, ICON_ADD) - base_icon.Blend(husk_over, ICON_OVERLAY) - - human_icon_cache[icon_key] = base_icon - - //END CACHED ICON GENERATION. - stand_icon.Blend(base_icon,ICON_OVERLAY) + stand_icon.Blend(husk_over, ICON_OVERLAY) + else + stand_icon.ColorTone("#605850") + global.human_icon_cache[icon_key] = stand_icon //tail update_tail_showing(0) @@ -388,8 +317,8 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/update_hair(var/update_icons=1) var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD, /obj/item/organ/external/head) + set_current_mob_overlay(HO_HAIR_LAYER, (istype(head_organ) ? head_organ.get_mob_overlays() : null), update_icons) - set_current_mob_overlay(HO_HAIR_LAYER, (istype(head_organ) ? head_organ.get_hair_icon() : null), update_icons) /mob/living/carbon/human/proc/update_skin(var/update_icons=1) // todo: make this use bodytype set_current_mob_overlay(HO_SKIN_LAYER, species.update_skin(src), update_icons) @@ -457,6 +386,8 @@ var/global/list/damage_icon_parts = list() return // No tail data! // These values may be null and are generally optional. + var/hair_colour = get_hair_colour() + var/skin_colour = get_skin_colour() var/tail_hair = tail_organ.get_tail_hair() var/tail_blend = tail_organ.get_tail_blend() var/tail_hair_blend = tail_organ.get_tail_hair_blend() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm deleted file mode 100644 index ff3b7588e00..00000000000 --- a/code/modules/mob/living/carbon/life.dm +++ /dev/null @@ -1,22 +0,0 @@ -/mob/living/carbon/Life() - if(!..()) - return - - // Increase germ_level regularly - if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level - germ_level++ - - if(stat != DEAD && !is_in_stasis()) - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - //Random events (vomiting etc) - handle_random_events() - - // eye, ear, brain damages - handle_disabilities() - - . = 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/taste.dm b/code/modules/mob/living/carbon/taste.dm index be5741d61b1..643fe0fbf3c 100644 --- a/code/modules/mob/living/carbon/taste.dm +++ b/code/modules/mob/living/carbon/taste.dm @@ -92,6 +92,3 @@ calculate text size per text. out += "[intensity_desc] [taste_desc]" return english_list(out, "something indescribable") - -/mob/living/carbon/proc/get_fullness() - return nutrition + (REAGENT_VOLUME(reagents, /decl/material/liquid/nutriment) * 25) \ No newline at end of file diff --git a/code/modules/mob/living/deity/deity_phenomena.dm b/code/modules/mob/living/deity/deity_phenomena.dm index dbb65b2782e..0ca6dd7514b 100644 --- a/code/modules/mob/living/deity/deity_phenomena.dm +++ b/code/modules/mob/living/deity/deity_phenomena.dm @@ -27,7 +27,7 @@ if(P.refresh_time) P.refresh_time += amount -/mob/living/deity/Life() +/mob/living/deity/handle_regular_status_updates() . = ..() if(.) if(silenced > 0) diff --git a/code/modules/mob/living/deity/deity_sources.dm b/code/modules/mob/living/deity/deity_sources.dm index 181957044cb..4c479cff036 100644 --- a/code/modules/mob/living/deity/deity_sources.dm +++ b/code/modules/mob/living/deity/deity_sources.dm @@ -10,8 +10,8 @@ if(form) L.faction = form.faction update_followers() - events_repository.register(/decl/observ/destroyed, L,src, .proc/dead_follower) - events_repository.register(/decl/observ/death, L,src, .proc/update_followers) + events_repository.register(/decl/observ/destroyed, L,src, PROC_REF(dead_follower)) + events_repository.register(/decl/observ/death, L,src, PROC_REF(update_followers)) /mob/living/deity/proc/dead_follower(var/mob/living/L) events_repository.unregister(/decl/observ/death, L,src) diff --git a/code/modules/mob/living/deity/deity_tracking.dm b/code/modules/mob/living/deity/deity_tracking.dm index 0ac0cd7ba75..0b8de46e9f4 100644 --- a/code/modules/mob/living/deity/deity_tracking.dm +++ b/code/modules/mob/living/deity/deity_tracking.dm @@ -25,9 +25,9 @@ eyeobj.setLoc(get_turf(L)) to_chat(src, "You begin to follow \the [L].") following = L - events_repository.register(/decl/observ/moved, L, src, /mob/living/deity/proc/keep_following) - events_repository.register(/decl/observ/destroyed, L, src, /mob/living/deity/proc/stop_follow) - events_repository.register(/decl/observ/death, L, src, /mob/living/deity/proc/stop_follow) + events_repository.register(/decl/observ/moved, L, src, TYPE_PROC_REF(/mob/living/deity, keep_following)) + events_repository.register(/decl/observ/destroyed, L, src, TYPE_PROC_REF(/mob/living/deity, stop_follow)) + events_repository.register(/decl/observ/death, L, src, TYPE_PROC_REF(/mob/living/deity, stop_follow)) /mob/living/deity/proc/stop_follow() events_repository.unregister(/decl/observ/moved, following, src) diff --git a/code/modules/mob/living/deity/phenomena/communication.dm b/code/modules/mob/living/deity/phenomena/communication.dm index 72876f3f9e9..9a76f59dba8 100644 --- a/code/modules/mob/living/deity/phenomena/communication.dm +++ b/code/modules/mob/living/deity/phenomena/communication.dm @@ -37,7 +37,7 @@ if((M in view) && M.client) to_chat(M, "Your attention is eerily drawn to \the [a].") M.client.images += arrow - events_repository.register(/decl/observ/logged_out, M, src, /datum/phenomena/point/proc/remove_image) + events_repository.register(/decl/observ/logged_out, M, src, TYPE_PROC_REF(/datum/phenomena/point, remove_image)) spawn(20) if(M.client) remove_image(M) diff --git a/code/modules/mob/living/deity/phenomena/conjuration.dm b/code/modules/mob/living/deity/phenomena/conjuration.dm index 23e9b69fc46..ac0f27c6075 100644 --- a/code/modules/mob/living/deity/phenomena/conjuration.dm +++ b/code/modules/mob/living/deity/phenomena/conjuration.dm @@ -27,7 +27,7 @@ var/obj/effect/portal/P = new(get_turf(a), null, 0) P.failchance = 0 portals += P - events_repository.register(/decl/observ/destroyed, P,src,/datum/phenomena/portals/proc/remove_portal) + events_repository.register(/decl/observ/destroyed, P,src, TYPE_PROC_REF(/datum/phenomena/portals, remove_portal)) if(portals.len > 2) var/removed = portals[1] remove_portal(removed) diff --git a/code/modules/mob/living/deity/phenomena/generic.dm b/code/modules/mob/living/deity/phenomena/generic.dm index 33b53f57bf5..633cd96eb7f 100644 --- a/code/modules/mob/living/deity/phenomena/generic.dm +++ b/code/modules/mob/living/deity/phenomena/generic.dm @@ -18,7 +18,7 @@ if(object_to_move) events_repository.unregister(/decl/observ/destroyed, object_to_move,src) object_to_move = new object_type() - events_repository.register(/decl/observ/destroyed, object_to_move, src, .proc/add_object) + events_repository.register(/decl/observ/destroyed, object_to_move, src, PROC_REF(add_object)) /datum/phenomena/movable_object/activate(var/atom/a, var/mob/living/deity/user) ..() diff --git a/code/modules/mob/living/deity/phenomena/starlight.dm b/code/modules/mob/living/deity/phenomena/starlight.dm index 6a8a98f1990..762cb18d549 100644 --- a/code/modules/mob/living/deity/phenomena/starlight.dm +++ b/code/modules/mob/living/deity/phenomena/starlight.dm @@ -139,8 +139,8 @@ to_chat(L, "[whisper_from ? "The [whisper_from] speaks to you" : "You hear a whisper say"] \"[message]\"") linked.eyenet.add_source(L) - events_repository.register(/decl/observ/destroyed, L, src, .proc/deactivate_look) - addtimer(CALLBACK(src, .proc/deactivate_look, L), 30 SECONDS) + events_repository.register(/decl/observ/destroyed, L, src, PROC_REF(deactivate_look)) + addtimer(CALLBACK(src, PROC_REF(deactivate_look), L), 30 SECONDS) /datum/phenomena/flickering_whisper/proc/deactivate_look(var/mob/viewer) if(!linked.is_follower(viewer)) //Don't remove if they are follower @@ -198,8 +198,8 @@ SET_STATUS_MAX(L, STAT_WEAK, 1) new /obj/aura/starborn(L) L.status_flags |= GODMODE - events_repository.register(/decl/observ/destroyed, L,src,.proc/fail_ritual) - addtimer(CALLBACK(src, .proc/succeed_ritual, L), 600 SECONDS) //6 minutes + events_repository.register(/decl/observ/destroyed, L,src,PROC_REF(fail_ritual)) + addtimer(CALLBACK(src, PROC_REF(succeed_ritual), L), 600 SECONDS) //6 minutes for(var/mob/living/player in global.player_list) sound_to(player, 'sound/effects/cascade.ogg') if(player?.mind?.assigned_job?.is_holy) diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 4adf6cf09d6..1c102bb0552 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -39,17 +39,17 @@ qdel(existing_slot) LAZYDISTINCTADD(_held_item_slots, held_slot.slot_id) add_inventory_slot(held_slot) - if(!get_active_hand()) + if(!get_active_held_item_slot()) select_held_item_slot(held_slot.slot_id) queue_hand_rebuild() /mob/living/remove_held_item_slot(var/slot) var/datum/inventory_slot/inv_slot = istype(slot, /datum/inventory_slot) ? slot : get_inventory_slot_datum(slot) if(inv_slot) - LAZYREMOVE(_held_item_slots, slot) + LAZYREMOVE(_held_item_slots, inv_slot.slot_id) remove_inventory_slot(inv_slot) var/held_slots = get_held_item_slots() - if(get_active_held_item_slot() == slot && length(held_slots)) + if(!get_active_held_item_slot() && length(held_slots)) select_held_item_slot(held_slots[1]) queue_hand_rebuild() @@ -168,7 +168,7 @@ if(held) drop_from_inventory(held) qdel(inv_slot) - LAZYREMOVE(_inventory_slots, slot) + LAZYREMOVE(_inventory_slots, inv_slot.slot_id) /mob/living/proc/get_jetpack() var/obj/item/tank/jetpack/thrust = get_equipped_item(slot_back_str) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 0eb3c2fcc57..591dcf9df68 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -4,7 +4,7 @@ ..() - if (HasMovementHandler(/datum/movement_handler/mob/transformation/)) + if (HasMovementHandler(/datum/movement_handler/mob/transformation)) return // update the current life tick, can be used to e.g. only do something every 4 ticks @@ -20,38 +20,48 @@ //Handle temperature/pressure differences between body and environment handle_environment(loc.return_air()) - - if(stat != DEAD && !is_in_stasis()) - //Breathing, if applicable - handle_breathing() - handle_nutrition_and_hydration() - handle_immunity() - //Body temperature adjusts itself (self-regulation) - stabilize_body_temperature() - - // human/handle_regular_status_updates() needs a cleanup, as blindness should be handled in handle_disabilities() handle_regular_status_updates() // Status & health update, are we dead or alive etc. handle_stasis() if(stat != DEAD) + if(!is_in_stasis()) + . = handle_living_non_stasis_processes() aura_check(AURA_TYPE_LIFE) - //Check if we're on fire - handle_fire() - for(var/obj/item/grab/G in get_active_grabs()) G.Process() + //Check if we're on fire + handle_fire() handle_actions() - UpdateLyingBuckledAndVerbStatus() - handle_regular_hud_updates() - handle_status_effects() return 1 +/mob/living/proc/handle_living_non_stasis_processes() + SHOULD_CALL_PARENT(TRUE) + // hungy + handle_nutrition_and_hydration() + // Breathing, if applicable + handle_breathing() + // Mutations and radiation + handle_mutations_and_radiation() + // Chemicals in the body + handle_chemicals_in_body() + // Random events (vomiting etc) + handle_random_events() + // eye, ear, brain damages + handle_disabilities() + handle_immunity() + //Body temperature adjusts itself (self-regulation) + stabilize_body_temperature() + // Only handle AI stuff if we're not being played. + if(!key) + handle_legacy_ai() + return TRUE + /mob/living/proc/experiences_hunger_and_thirst() return TRUE @@ -67,6 +77,10 @@ return my_species.hunger_factor return 0 +// Used to handle non-datum AI. +/mob/living/proc/handle_legacy_ai() + return + /mob/living/proc/handle_nutrition_and_hydration() SHOULD_CALL_PARENT(TRUE) if(!experiences_hunger_and_thirst()) @@ -85,11 +99,10 @@ SHOULD_CALL_PARENT(TRUE) radiation = clamp(radiation,0,500) - var/decl/species/my_species = get_species() var/decl/bodytype/my_bodytype = get_bodytype() - if(my_species && my_bodytype && (my_bodytype.appearance_flags & RADIATION_GLOWS)) + if(my_bodytype?.appearance_flags & RADIATION_GLOWS) if(radiation) - set_light(max(1,min(10,radiation/10)), max(1,min(20,radiation/20)), my_species.get_flesh_colour(src)) + set_light(max(1,min(10,radiation/10)), max(1,min(20,radiation/20)), get_flesh_color()) else set_light(0) @@ -128,6 +141,7 @@ damage = 8 radiation -= 4 * RADIATION_SPEED_COEFFICIENT + var/decl/species/my_species = get_species() damage = FLOOR(damage * (my_species ? my_species.get_radiation_mod(src) : 1)) if(damage) immunity = max(0, immunity - damage * 15 * RADIATION_SPEED_COEFFICIENT) @@ -253,37 +267,76 @@ //This updates the health and status of the mob (conscious, unconscious, dead) /mob/living/proc/handle_regular_status_updates() + + SHOULD_CALL_PARENT(TRUE) + + // Check if we are (or should be) dead at this point. update_health() - if(stat != DEAD) - if(HAS_STATUS(src, STAT_PARA)) - set_stat(UNCONSCIOUS) - else if (status_flags & FAKEDEATH) - set_stat(UNCONSCIOUS) - else - set_stat(CONSCIOUS) + + if(!handle_some_updates()) + return FALSE + + // Godmode just skips most of this processing. + if(status_flags & GODMODE) + set_stat(CONSCIOUS) + germ_level = 0 return TRUE + // TODO: move hallucinations into a status condition decl. + if(hallucination_power) + handle_hallucinations() + + // Increase germ_level regularly + if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level + germ_level++ + // If you're dirty, your gloves will become dirty, too. + var/obj/item/gloves = get_equipped_item(slot_gloves_str) + if(gloves && germ_level > gloves.germ_level && prob(10)) + gloves.germ_level++ + + // If we're dead, don't continue further. + if(stat == DEAD) + return FALSE + + // Handle some general state updates. + if(HAS_STATUS(src, STAT_PARA)) + set_stat(UNCONSCIOUS) + else if (status_flags & FAKEDEATH) + set_stat(UNCONSCIOUS) + else + set_stat(CONSCIOUS) + return TRUE + /mob/living/proc/handle_disabilities() handle_impaired_vision() handle_impaired_hearing() /mob/living/proc/handle_impaired_vision() - if((sdisabilities & BLINDED) || stat) //blindness from disability or unconsciousness doesn't get better on its own + SHOULD_CALL_PARENT(TRUE) + if(stat == DEAD) + SET_STATUS_MAX(src, STAT_BLIND, 0) + if(stat != CONSCIOUS && (sdisabilities & BLINDED)) //blindness from disability or unconsciousness doesn't get better on its own SET_STATUS_MAX(src, STAT_BLIND, 2) + else + return TRUE + return FALSE /mob/living/proc/handle_impaired_hearing() if((sdisabilities & DEAFENED) || stat) //disabled-deaf, doesn't get better on its own SET_STATUS_MAX(src, STAT_TINNITUS, 2) +/mob/living/proc/should_do_hud_updates() + return client + //this handles hud updates. Calls update_vision() and handle_hud_icons() /mob/living/proc/handle_regular_hud_updates() - if(!client) return 0 - + SHOULD_CALL_PARENT(TRUE) + if(!should_do_hud_updates()) + return FALSE handle_hud_icons() handle_vision() handle_low_light_vision() - - return 1 + return TRUE /mob/living/proc/handle_low_light_vision() @@ -314,10 +367,8 @@ /mob/living/proc/handle_vision() update_sight() - if(stat == DEAD) return - if(is_blind()) overlay_fullscreen("blind", /obj/screen/fullscreen/blind) else @@ -325,9 +376,7 @@ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1) set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry) set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high) - set_fullscreen(stat == UNCONSCIOUS, "blackout", /obj/screen/fullscreen/blackout) - if(machine) var/viewflags = machine.check_eye(src) if(viewflags < 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c595818c3c5..131687f3feb 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -202,10 +202,12 @@ default behaviour is: return (getOxyLoss()+getToxLoss()+getFireLoss()+getBruteLoss()+getCloneLoss()+getHalLoss()) /mob/living/proc/update_health() + SHOULD_CALL_PARENT(TRUE) if(status_flags & GODMODE) current_health = get_max_health() set_stat(CONSCIOUS) return + var/max_health = get_max_health() current_health = clamp(max_health-get_total_life_damage(), -(max_health), max_health) if(stat != DEAD && should_be_dead()) @@ -493,8 +495,42 @@ default behaviour is: brain.update_icon() ..(repair_brain) -/mob/living/proc/update_damage_icon() - return +/mob/living + var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed + var/static/list/damage_icon_parts = list() + +/mob/living/proc/update_damage_overlays(update_icons = TRUE) + + // first check whether something actually changed about damage appearance + var/damage_appearance = "" + for(var/obj/item/organ/external/O in get_external_organs()) + damage_appearance += O.damage_state || "00" + + if(damage_appearance == previous_damage_appearance) + // nothing to do here + return + + previous_damage_appearance = damage_appearance + var/decl/bodytype/root_bodytype = get_bodytype() + var/image/standing_image = image(root_bodytype.get_damage_overlays(src), icon_state = "00") + + // blend the individual damage states with our icons + for(var/obj/item/organ/external/O in get_external_organs()) + if(!O.damage_state || O.damage_state == "00") + continue + var/icon/DI + var/use_colour = (BP_IS_PROSTHETIC(O) ? SYNTH_BLOOD_COLOR : O.species.get_species_blood_color(src)) + var/cache_index = "[O.damage_state]/[O.bodytype.type]/[O.icon_state]/[use_colour]/[O.species.name]" + if(damage_icon_parts[cache_index] == null) + DI = new /icon(O.bodytype.get_damage_overlays(src), O.damage_state) // the damage icon for whole human + DI.Blend(get_limb_mask_for(O.bodytype, O.icon_state), ICON_MULTIPLY) // mask with this organ's pixels + DI.Blend(use_colour, ICON_MULTIPLY) + damage_icon_parts[cache_index] = DI + else + DI = damage_icon_parts[cache_index] + + standing_image.overlays += DI + set_current_mob_overlay(HO_DAMAGE_LAYER, standing_image, update_icons) /mob/living/handle_grabs_after_move(var/turf/old_loc, var/direction) @@ -519,13 +555,15 @@ default behaviour is: if(QDELETED(G) || QDELETED(G.affecting)) mygrabs -= G - if(!length(mygrabs)) - return - if(length(grabbed_by)) + for(var/obj/item/grab/G as anything in grabbed_by) + G.adjust_position() reset_offsets() reset_plane_and_layer() + if(!length(mygrabs)) + return + if(direction & (UP|DOWN)) var/txt_dir = (direction & UP) ? "upwards" : "downwards" if(old_loc) @@ -739,6 +777,9 @@ default behaviour is: return 1 /mob/living/Destroy() + QDEL_NULL(aiming) + QDEL_NULL_LIST(_hallucinations) + QDEL_NULL_LIST(aimed_at_by) if(stressors) // Do not QDEL_NULL, keys are managed instances. stressors = null if(auras) @@ -785,23 +826,22 @@ default behaviour is: return (!L || L.can_drown()) /mob/living/handle_drowning() - var/turf/T = get_turf(src) - if(!can_drown() || !loc.is_flooded(lying)) + if(!can_drown() || !loc?.is_flooded(lying)) return FALSE + var/turf/T = get_turf(src) if(!lying && T.above && T.above.is_open() && !T.above.is_flooded() && can_overcome_gravity()) return FALSE if(prob(5)) var/datum/reagents/metabolism/inhaled = get_inhaled_reagents() var/datum/reagents/metabolism/ingested = get_ingested_reagents() - var/obj/effect/fluid/F = locate() in loc - to_chat(src, SPAN_DANGER("You choke and splutter as you inhale [(F?.reagents && F.reagents.get_primary_reagent_name()) || "liquid"]!")) + to_chat(src, SPAN_DANGER("You choke and splutter as you inhale [T.get_fluid_name()]!")) var/inhale_amount = 0 if(inhaled) inhale_amount = rand(2,5) - F?.reagents?.trans_to_holder(inhaled, min(F.reagents.total_volume, inhale_amount)) + T.reagents?.trans_to_holder(inhaled, min(T.reagents.total_volume, inhale_amount)) if(ingested) var/ingest_amount = 5 - inhale_amount - F?.reagents?.trans_to_holder(ingested, min(F.reagents.total_volume, ingest_amount)) + reagents?.trans_to_holder(ingested, min(T.reagents.total_volume, ingest_amount)) T.show_bubbles() return TRUE // Presumably chemical smoke can't be breathed while you're underwater. @@ -844,14 +884,17 @@ default behaviour is: return null /mob/living/proc/handle_additional_vomit_reagents(var/obj/effect/decal/cleanable/vomit/vomit) - vomit.reagents.add_reagent(/decl/material/liquid/acid/stomach, 5) + vomit.add_to_reagents(/decl/material/liquid/acid/stomach, 5) /mob/living/proc/eyecheck() return FLASH_PROTECTION_NONE -/mob/living/proc/get_max_nutrition() +/mob/living/proc/get_satiated_nutrition() return 500 +/mob/living/proc/get_max_nutrition() + return 550 + /mob/living/proc/set_nutrition(var/amt) nutrition = clamp(amt, 0, get_max_nutrition()) @@ -939,7 +982,11 @@ default behaviour is: /mob/living/proc/can_do_special_ranged_attack(var/check_flag = TRUE) return TRUE +/mob/living/proc/get_food_satiation() + . = get_nutrition() + (get_ingested_reagents()?.total_volume * 10) + /mob/living/proc/get_ingested_reagents() + RETURN_TYPE(/datum/reagents) return reagents /mob/living/proc/should_have_organ(organ_to_check) @@ -953,12 +1000,15 @@ default behaviour is: return root_bodytype?.has_limbs[limb_to_check] /mob/living/proc/get_contact_reagents() + RETURN_TYPE(/datum/reagents) return reagents /mob/living/proc/get_injected_reagents() + RETURN_TYPE(/datum/reagents) return reagents /mob/living/proc/get_inhaled_reagents() + RETURN_TYPE(/datum/reagents) return reagents /mob/living/proc/get_adjusted_metabolism(metabolism) @@ -1141,6 +1191,9 @@ default behaviour is: //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle return life_tick <= 5 || !timeofdeath || (timeofdeath >= 5 && (world.time-timeofdeath) <= 10 MINUTES) +/mob/living/proc/check_dna() + dna?.check_integrity(src) + /mob/living/get_unique_enzymes() return unique_enzymes @@ -1189,12 +1242,12 @@ default behaviour is: var/list/overlays_to_add if(check_state_in_icon(overlay_state, surgery_icon)) var/image/flesh = image(icon = surgery_icon, icon_state = overlay_state, layer = -HO_SURGERY_LAYER) - flesh.color = E.species.get_flesh_colour(src) + flesh.color = E.species.get_species_flesh_color(src) LAZYADD(overlays_to_add, flesh) overlay_state = "[base_state]-blood" if(check_state_in_icon(overlay_state, surgery_icon)) var/image/blood = image(icon = surgery_icon, icon_state = overlay_state, layer = -HO_SURGERY_LAYER) - blood.color = E.species.get_blood_color(src) + blood.color = E.species.get_species_blood_color(src) LAZYADD(overlays_to_add, blood) overlay_state = "[base_state]-bones" if(check_state_in_icon(overlay_state, surgery_icon)) @@ -1290,3 +1343,110 @@ default behaviour is: else CRASH("synthetic get_default_temperature_threshold() called with invalid threshold value.") return ..() + +/mob/living/clean(clean_forensics = TRUE) + + SHOULD_CALL_PARENT(FALSE) + + for(var/obj/item/thing in get_held_items()) + thing.clean() + + var/obj/item/back = get_equipped_item(slot_back_str) + if(back) + back.clean() + + //flush away reagents on the skin + var/datum/reagents/touching_reagents = get_contact_reagents() + if(touching_reagents) + var/remove_amount = touching_reagents.maximum_volume * reagent_permeability() //take off your suit first + touching_reagents.remove_any(remove_amount) + + var/obj/item/mask = get_equipped_item(slot_wear_mask_str) + if(mask) + mask.clean() + + var/washgloves = TRUE + var/washshoes = TRUE + var/washmask = TRUE + var/washears = TRUE + var/washglasses = TRUE + + var/obj/item/suit = get_equipped_item(slot_wear_suit_str) + if(suit) + washgloves = !(suit.flags_inv & HIDEGLOVES) + washshoes = !(suit.flags_inv & HIDESHOES) + + var/obj/item/head = get_equipped_item(slot_head_str) + if(head) + washmask = !(head.flags_inv & HIDEMASK) + washglasses = !(head.flags_inv & HIDEEYES) + washears = !(head.flags_inv & HIDEEARS) + + if(mask) + if (washears) + washears = !(mask.flags_inv & HIDEEARS) + if (washglasses) + washglasses = !(mask.flags_inv & HIDEEYES) + + if(head) + head.clean() + + if(suit) + suit.clean() + else + var/obj/item/uniform = get_equipped_item(slot_w_uniform_str) + if(uniform) + uniform.clean() + + if(washgloves) + var/obj/item/gloves = get_equipped_item(slot_gloves_str) + if(gloves) + gloves.clean() + else + germ_level = 0 + + var/obj/item/shoes = get_equipped_item(slot_shoes_str) + if(shoes && washshoes) + shoes.clean() + + if(mask && washmask) + mask.clean() + + if(washglasses) + var/obj/item/glasses = get_equipped_item(slot_glasses_str) + if(glasses) + glasses.clean() + + if(washears) + var/obj/item/ear = get_equipped_item(slot_l_ear_str) + if(ear) + ear.clean() + ear = get_equipped_item(slot_r_ear_str) + if(ear) + ear.clean() + + var/obj/item/belt = get_equipped_item(slot_belt_str) + if(belt) + belt.clean() + + var/obj/item/gloves = get_equipped_item(slot_gloves_str) + if(gloves) + gloves.clean() + gloves.germ_level = 0 + for(var/organ_tag in get_held_item_slots()) + var/obj/item/organ/external/organ = get_organ(organ_tag) + if(organ) + organ.clean() + else + germ_level = 0 + update_equipment_overlay(slot_gloves_str, FALSE) + + if(!get_equipped_item(slot_shoes_str)) + var/static/list/clean_slots = list(BP_L_FOOT, BP_R_FOOT) + for(var/organ_tag in clean_slots) + var/obj/item/organ/external/organ = get_organ(organ_tag) + if(organ) + organ.clean() + update_equipment_overlay(slot_shoes_str) + + return TRUE diff --git a/code/modules/mob/living/living_appearance.dm b/code/modules/mob/living/living_appearance.dm new file mode 100644 index 00000000000..359cb835ccf --- /dev/null +++ b/code/modules/mob/living/living_appearance.dm @@ -0,0 +1,80 @@ +/mob/living + var/list/mob_overlays[TOTAL_OVER_LAYERS] + var/list/mob_underlays[TOTAL_UNDER_LAYERS] + +/mob/living/update_icon() + ..() + compile_overlays() + +/mob/living/on_update_icon() + SHOULD_CALL_PARENT(TRUE) + ..() + cut_overlays() + if(auras) + for(var/obj/aura/aura as anything in auras) + var/image/A = new() + A.appearance = aura + add_overlay(A) + try_refresh_visible_overlays() + +/mob/living/proc/get_skin_colour() + return + +/mob/living/proc/get_eye_colour() + return + +/mob/living/proc/get_lip_colour() + return + +/mob/living/proc/get_hairstyle() + return + +/mob/living/proc/get_facial_hairstyle() + return + +/mob/living/proc/get_hair_colour() + return + +/mob/living/proc/get_facial_hair_colour() + return + +/mob/living/proc/set_skin_colour(var/new_color) + return get_skin_colour() != new_color + +/mob/living/proc/set_eye_colour(var/new_color) + return get_eye_colour() != new_color + +/mob/living/proc/set_lip_colour(var/new_color) + return get_lip_colour() != new_color + +/mob/living/proc/set_facial_hair_colour(var/new_color, var/skip_update = FALSE) + return get_facial_hair_colour() != new_color + +/mob/living/proc/set_hair_colour(var/new_color, var/skip_update = FALSE) + return get_hair_colour() != new_color + +/mob/living/proc/set_hairstyle(var/new_hairstyle) + return new_hairstyle && get_hairstyle() != new_hairstyle && ispath(new_hairstyle, /decl/sprite_accessory/hair) + +/mob/living/proc/set_facial_hairstyle(var/new_facial_hairstyle) + return new_facial_hairstyle && get_facial_hairstyle() != new_facial_hairstyle && ispath(new_facial_hairstyle, /decl/sprite_accessory/facial_hair) + +/mob/living/get_all_current_mob_overlays() + return mob_overlays + +/mob/living/set_current_mob_overlay(var/overlay_layer, var/image/overlay, var/redraw_mob = TRUE) + mob_overlays[overlay_layer] = overlay + ..() + +/mob/living/get_current_mob_overlay(var/overlay_layer) + return mob_overlays[overlay_layer] + +/mob/living/get_all_current_mob_underlays() + return mob_underlays + +/mob/living/set_current_mob_underlay(var/underlay_layer, var/image/underlay, var/redraw_mob = TRUE) + mob_underlays[underlay_layer] = underlay + ..() + +/mob/living/get_current_mob_underlay(var/underlay_layer) + return mob_underlays[underlay_layer] diff --git a/code/modules/mob/living/living_blood.dm b/code/modules/mob/living/living_blood.dm new file mode 100644 index 00000000000..d2111b42963 --- /dev/null +++ b/code/modules/mob/living/living_blood.dm @@ -0,0 +1,36 @@ +//Transfers blood from container to vessels +/mob/living/proc/inject_blood(var/amount, var/datum/reagents/donor) + var/decl/species/my_species = get_species() + if(!my_species?.blood_volume) + return //Don't divide by 0 + var/injected_data = REAGENT_DATA(donor, my_species.blood_reagent) + var/chems = LAZYACCESS(injected_data, "trace_chem") + for(var/C in chems) + add_to_reagents(C, (text2num(chems[C]) / my_species.blood_volume) * amount)//adds trace chemicals to owner's blood + +/mob/living/get_blood_data() + + var/data = ..() + data["blood_DNA"] = get_unique_enzymes() + data["blood_type"] = get_blood_type() + var/species_name = get_species_name() + if(species_name) + data["species"] = species_name + + var/list/temp_chem = list() + for(var/R in reagents?.reagent_volumes) + temp_chem[R] = REAGENT_VOLUME(reagents, R) + data["trace_chem"] = temp_chem + data["dose_chem"] = chem_doses?.Copy() || list() + + if(isSynthetic()) + data["has_oxy"] = FALSE + data["blood_color"] = SYNTH_BLOOD_COLOR + else + data["has_oxy"] = get_blood_oxy() + data["blood_color"] = get_blood_color() + return data + +/mob/living/proc/is_blood_incompatible(their_blood_type) + var/decl/blood_type/my_blood = get_blood_type_by_name(get_blood_type()) + return !istype(my_blood) || !my_blood.can_take_donation_from(get_blood_type_by_name(their_blood_type)) diff --git a/code/modules/mob/living/living_breath.dm b/code/modules/mob/living/living_breath.dm index b354bc045cf..57ad8ef78a7 100644 --- a/code/modules/mob/living/living_breath.dm +++ b/code/modules/mob/living/living_breath.dm @@ -34,7 +34,7 @@ if(ticks_since_last_successful_breath>0) //Suffocating so do not take a breath ticks_since_last_successful_breath-- if (prob(10) && !is_asystole() && active_breathe) //Gasp per 10 ticks? Sounds about right. - INVOKE_ASYNC(src, .proc/emote, "gasp") + INVOKE_ASYNC(src, PROC_REF(emote), "gasp") else //Okay, we can breathe, now check if we can get air var/volume_needed = get_breath_volume() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 1553c2b6968..96da244863f 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -44,6 +44,17 @@ var/list/impact_sounds = LAZYACCESS(P.impact_sounds, get_bullet_impact_effect_type(def_zone)) if(length(impact_sounds)) playsound(src, pick(impact_sounds), 75) + if(get_bullet_impact_effect_type(def_zone) != BULLET_IMPACT_MEAT) + return + if(!damage || P.damtype != BRUTE) + return + var/hit_dir = get_dir(P.starting, src) + var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir) + if(!QDELETED(B)) + B.icon_state = pick("dir_splatter_1","dir_splatter_2") + var/scale = min(1, round(mob_size / MOB_SIZE_MEDIUM, 0.1)) + B.set_scale(scale) + new /obj/effect/temp_visual/bloodsplatter(loc, hit_dir, get_blood_color()) /mob/living/get_bullet_impact_effect_type(var/def_zone) return BULLET_IMPACT_MEAT @@ -103,15 +114,12 @@ if(I.attack_message_name()) weapon_mention = " with [I.attack_message_name()]" if(effective_force) - visible_message("[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"][weapon_mention] by [user]!") + visible_message(SPAN_DANGER("\The [src] has been [DEFAULTPICK(I.attack_verb, "attacked")][weapon_mention] by [user]!")) else - visible_message("[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"][weapon_mention] by [user]!") - + visible_message(SPAN_WARNING("\The [src] has been [DEFAULTPICK(I.attack_verb, "attacked")][weapon_mention] by \the [user]!")) . = standard_weapon_hit_effects(I, user, effective_force, hit_zone) - - if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too - var/turf/simulated/location = get_turf(src) - if(istype(location)) location.add_blood_floor(src) + if(I.damtype == BRUTE && prob(33)) + blood_splatter(get_turf(loc), src) //returns 0 if the effects failed to apply for some reason, 1 otherwise. /mob/living/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/hit_zone) @@ -170,7 +178,7 @@ /mob/living/momentum_do(var/power, var/datum/thrownthing/TT, var/atom/movable/AM) if(power >= 0.75) //snowflake to enable being pinned to walls var/direction = TT.init_dir - throw_at(get_edge_target_turf(src, direction), min((TT.maxrange - TT.dist_travelled) * power, 10), throw_speed * min(power, 1.5), callback = CALLBACK(src,/mob/living/proc/pin_to_wall,AM,direction)) + throw_at(get_edge_target_turf(src, direction), min((TT.maxrange - TT.dist_travelled) * power, 10), throw_speed * min(power, 1.5), callback = CALLBACK(src, TYPE_PROC_REF(/mob/living, pin_to_wall), AM, direction)) visible_message(SPAN_DANGER("\The [src] staggers under the impact!"),SPAN_DANGER("You stagger under the impact!")) return diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index daa5cf114a7..7eab17ec15a 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -6,7 +6,7 @@ //Health and life related vars var/mob_default_max_health = 100 //Maximum health that should be possible. - var/current_health = INFINITY // A mob's current health. Set by updatehealth(). Defaults to INFINITY so mobs don't die on init. + var/current_health = INFINITY // A mob's current health. Set by update_health(). Defaults to INFINITY so mobs don't die on init. var/hud_updateflag = 0 diff --git a/code/modules/mob/living/living_dreams.dm b/code/modules/mob/living/living_dreams.dm new file mode 100644 index 00000000000..53b15252827 --- /dev/null +++ b/code/modules/mob/living/living_dreams.dm @@ -0,0 +1,14 @@ +/mob/living + var/dreaming = FALSE + +/mob/living/proc/handle_dreams() + set waitfor = FALSE + if(!client || dreaming || !prob(5)) + return + dreaming = TRUE + for(var/i = 1 to rand(1,4)) + to_chat(src, SPAN_NOTICE("... [pick(SSlore.dreams)] ...")) + sleep(rand(4 SECONDS, 7 SECONDS)) + if(!HAS_STATUS(src, STAT_ASLEEP)) + break + dreaming = FALSE diff --git a/code/modules/mob/living/living_grabs.dm b/code/modules/mob/living/living_grabs.dm index e8eda8cec1d..fe5d438c3f5 100644 --- a/code/modules/mob/living/living_grabs.dm +++ b/code/modules/mob/living/living_grabs.dm @@ -7,7 +7,7 @@ to_chat(src, SPAN_WARNING("Your hands are full!")) return FALSE else if(get_active_hand()) - to_chat(src, SPAN_WARNING("Your [parse_zone(get_active_hand())] is full!")) + to_chat(src, SPAN_WARNING("Your [parse_zone(get_active_held_item_slot())] is full!")) return FALSE if(LAZYLEN(grabbed_by)) to_chat(src, SPAN_WARNING("You cannot start grappling while already being grappled!")) diff --git a/code/modules/mob/living/living_hallucinations.dm b/code/modules/mob/living/living_hallucinations.dm new file mode 100644 index 00000000000..c5e4d290f96 --- /dev/null +++ b/code/modules/mob/living/living_hallucinations.dm @@ -0,0 +1,52 @@ +/mob/living + var/hallucination_power = 0 + var/hallucination_duration = 0 + var/next_hallucination + var/list/_hallucinations + +/mob/living/proc/adjust_hallucination(duration, power) + hallucination_duration = max(0, hallucination_duration + duration) + hallucination_power = max(0, hallucination_power + power) + +/mob/living/proc/set_hallucination(duration, power) + hallucination_duration = max(hallucination_duration, duration) + hallucination_power = max(hallucination_power, power) + +/mob/living/proc/handle_hallucinations() + //Tick down the duration + hallucination_duration = max(0, hallucination_duration - 1) + //Adjust power if we have some chems that affect it + if(has_chemical_effect(CE_MIND, threshold_under = -1)) + hallucination_power = hallucination_power++ + else if(has_chemical_effect(CE_MIND, threshold_under = 0)) + hallucination_power = min(hallucination_power++, 50) + else if(has_chemical_effect(CE_MIND, 1)) + hallucination_duration = max(0, hallucination_duration - 1) + hallucination_power = max(hallucination_power - GET_CHEMICAL_EFFECT(src, CE_MIND), 0) + + //See if hallucination is gone + if(!hallucination_power) + hallucination_duration = 0 + return + if(!hallucination_duration) + hallucination_power = 0 + return + + if(!client || stat || world.time < next_hallucination) + return + if(has_chemical_effect(CE_MIND, 1) && prob(GET_CHEMICAL_EFFECT(src, CE_MIND)*40)) //antipsychotics help + return + var/hall_delay = rand(10,20) SECONDS + + if(hallucination_power < 50) + hall_delay *= 2 + next_hallucination = world.time + hall_delay + var/list/candidates = list() + for(var/T in subtypesof(/datum/hallucination)) + var/datum/hallucination/H = new T + if(H.can_affect(src)) + candidates += H + if(candidates.len) + var/datum/hallucination/H = pick(candidates) + H.holder = src + H.activate_hallucination() diff --git a/code/modules/mob/living/living_maneuvers.dm b/code/modules/mob/living/living_maneuvers.dm index 85a2a06bcbe..89a47a1f63b 100644 --- a/code/modules/mob/living/living_maneuvers.dm +++ b/code/modules/mob/living/living_maneuvers.dm @@ -15,7 +15,7 @@ if(!can_fall(location_override = check)) break if(check && check != loc) - addtimer(CALLBACK(src, /mob/living/proc/reflexive_maneuver_callback, lastloc, check), 0) + addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living, reflexive_maneuver_callback), lastloc, check), 0) return . = ..() @@ -25,13 +25,13 @@ forceMove(get_turf(origin)) prepared_maneuver.perform(src, check, get_acrobatics_multiplier(prepared_maneuver), reflexively = TRUE) prepared_maneuver = null - maneuver_icon.icon_state = "maneuver_off" + maneuver_icon?.icon_state = "maneuver_off" /mob/living/proc/try_maneuver(var/atom/target) if(prepared_maneuver && (isturf(target) || isturf(target.loc))) // Avoid trying to jump at your backpack contents. prepared_maneuver.perform(src, get_turf(target), get_acrobatics_multiplier(prepared_maneuver)) prepared_maneuver = null - maneuver_icon.icon_state = "maneuver_off" + maneuver_icon?.icon_state = "maneuver_off" return TRUE return FALSE @@ -59,11 +59,11 @@ if(!maneuver.can_be_used_by(src, null)) return prepared_maneuver = maneuver - maneuver_icon.icon_state = "maneuver_on" + maneuver_icon?.icon_state = "maneuver_on" to_chat(src, SPAN_NOTICE("You prepare to [prepared_maneuver.name].")) else prepared_maneuver = null - maneuver_icon.icon_state = "maneuver_off" + maneuver_icon?.icon_state = "maneuver_off" to_chat(src, SPAN_NOTICE("You are no longer preparing to perform a maneuver.")) /mob/living/proc/perform_maneuver(var/maneuver, var/atom/target) @@ -71,7 +71,7 @@ if(istype(performing_maneuver)) . = performing_maneuver.perform(src, target, get_acrobatics_multiplier(performing_maneuver)) prepared_maneuver = null - maneuver_icon.icon_state = "maneuver_off" + maneuver_icon?.icon_state = "maneuver_off" /mob/living/proc/get_acrobatics_multiplier(var/decl/maneuver/attempting_maneuver) return 1 diff --git a/code/modules/mob/living/living_organs.dm b/code/modules/mob/living/living_organs.dm index 7881fb555df..704e2833f5a 100644 --- a/code/modules/mob/living/living_organs.dm +++ b/code/modules/mob/living/living_organs.dm @@ -20,6 +20,11 @@ /mob/living/proc/has_internal_organs() return LAZYLEN(get_internal_organs()) > 0 +/mob/living/get_contained_matter() + . = ..() + for(var/obj/item/organ in get_organs()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., organ.get_contained_matter()) + //Can be called when we want to add an organ in a detached state or an attached state. /mob/living/proc/add_organ(var/obj/item/organ/O, var/obj/item/organ/external/affected = null, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE, var/skip_health_update = FALSE) . = O.do_install(src, affected, in_place, update_icon, detached) diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index 49d07235d00..8a4fcf94518 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -34,7 +34,7 @@ var/turf/T = get_turf(src) var/obj/effect/effect/water/chempuff/chem = new(T) chem.create_reagents(10) - chem.reagents.add_reagent(/decl/material/liquid/zombie, 2) + chem.add_to_reagents(/decl/material/liquid/zombie, 2) chem.set_up(get_step(T, dir), 2, 10) playsound(T, 'sound/hallucinations/wail.ogg', 20, 1) diff --git a/code/modules/mob/living/living_status.dm b/code/modules/mob/living/living_status.dm index 1014107e700..11c01992201 100644 --- a/code/modules/mob/living/living_status.dm +++ b/code/modules/mob/living/living_status.dm @@ -13,7 +13,7 @@ if(amount == PENDING_STATUS(src, condition)) return FALSE LAZYSET(pending_status_counters, condition, amount) - addtimer(CALLBACK(src, .proc/apply_pending_status_changes), 0, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(apply_pending_status_changes)), 0, TIMER_UNIQUE) return TRUE /mob/living/proc/rebuild_status_markers() diff --git a/code/modules/mob/living/maneuvers/maneuver_leap.dm b/code/modules/mob/living/maneuvers/maneuver_leap.dm index 72243454579..5dd783f2765 100644 --- a/code/modules/mob/living/maneuvers/maneuver_leap.dm +++ b/code/modules/mob/living/maneuvers/maneuver_leap.dm @@ -16,8 +16,8 @@ user.jump_layer_shift() animate(user, pixel_z = 16, time = 3, easing = SINE_EASING | EASE_IN) animate(pixel_z = user.default_pixel_z, time = 3, easing = SINE_EASING | EASE_OUT) - user.throw_at(get_turf(target), strength, 1, user, FALSE, CALLBACK(src, /decl/maneuver/leap/proc/end_leap, user, target, old_pass_flags)) - addtimer(CALLBACK(user, /mob/living/proc/jump_layer_shift_end), 4.5) + user.throw_at(get_turf(target), strength, 1, user, FALSE, CALLBACK(src, TYPE_PROC_REF(/decl/maneuver/leap, end_leap), user, target, old_pass_flags)) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, jump_layer_shift_end)), 4.5) /decl/maneuver/leap/proc/end_leap(var/mob/living/user, var/atom/target, var/pass_flag) user.pass_flags = pass_flag diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 50eee15f469..6bf47b4c9a9 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -300,10 +300,10 @@ if(O) //It's possible that it could be deleted in the meantime. O.hear_talk(src, stars(message), verb, speaking) - INVOKE_ASYNC(GLOBAL_PROC, .proc/animate_speech_bubble, speech_bubble, speech_bubble_recipients | eavesdroppers, 30) - INVOKE_ASYNC(src, /atom/movable/proc/animate_chat, message, speaking, italics, speech_bubble_recipients) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(animate_speech_bubble), speech_bubble, speech_bubble_recipients | eavesdroppers, 30) + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, animate_chat), message, speaking, italics, speech_bubble_recipients) if(length(eavesdroppers)) - INVOKE_ASYNC(src, /atom/movable/proc/animate_chat, stars(message), speaking, italics, eavesdroppers) + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, animate_chat), stars(message), speaking, italics, eavesdroppers) if(whispering) log_whisper("[name]/[key] : [message]") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index dabfafbc503..8f2b8462ee2 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -104,7 +104,7 @@ var/global/list/ai_verbs_default = list( src.verbs -= ai_verbs_default src.verbs += /mob/living/verb/ghost -/mob/living/silicon/ai/Initialize(mapload, var/datum/ai_laws/L, var/obj/item/mmi/B, var/safety = 0) +/mob/living/silicon/ai/Initialize(mapload, var/datum/ai_laws/L, var/obj/item/organ/internal/brain_interface/B, var/safety = 0) announcement = new() announcement.title = "A.I. Announcement" announcement.announcement_type = "A.I. Announcement" @@ -144,11 +144,12 @@ var/global/list/ai_verbs_default = list( add_language(/decl/language/sign, 0) if(!safety)//Only used by AIize() to successfully spawn an AI. - if (!B)//If there is no player/brain inside. + var/mob/living/brainmob = B?.get_brainmob() + if(!brainmob) // If there is no player/brain inside. empty_playable_ai_cores += new/obj/structure/aicore/deactivated(loc)//New empty terminal. . = INITIALIZE_HINT_QDEL - else if(B.brainmob.mind) - B.brainmob.mind.transfer_to(src) + else if(brainmob.mind) + brainmob.mind.transfer_to(src) hud_list[HEALTH_HUD] = new /image/hud_overlay('icons/mob/hud.dmi', src, "hudblank") hud_list[STATUS_HUD] = new /image/hud_overlay('icons/mob/hud.dmi', src, "hudblank") hud_list[LIFE_HUD] = new /image/hud_overlay('icons/mob/hud.dmi', src, "hudblank") diff --git a/code/modules/mob/living/silicon/ai/ai_radio.dm b/code/modules/mob/living/silicon/ai/ai_radio.dm index a4b198194e6..c9a32ee9cd3 100644 --- a/code/modules/mob/living/silicon/ai/ai_radio.dm +++ b/code/modules/mob/living/silicon/ai/ai_radio.dm @@ -12,7 +12,9 @@ /obj/item/encryptionkey/heads/ai_integrated name = "ai integrated encryption key" desc = "Integrated encryption key." - icon_state = "cap_cypherkey" + color = COLOR_GOLD + fill_color = COLOR_PALE_GOLD + inlay_color = COLOR_ROYAL_BLUE can_decrypt = list( access_bridge, access_security, diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index faa97d12108..7985307ca9e 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -1,48 +1,37 @@ /mob/living/silicon/ai/should_be_dead() return get_health_percent() <= 0 || backup_capacitor() <= 0 -/mob/living/silicon/ai/Life() - - SHOULD_CALL_PARENT(FALSE) - - if (src.stat!=CONSCIOUS) +/mob/living/silicon/ai/handle_regular_status_updates() + . = ..() + if(stat != CONSCIOUS) src.cameraFollow = null src.reset_view(null) - update_health() // TODO: move to handle_regular_status_updates() and preserve parent call chain, Life() PR - if(stat == DEAD) - return +/mob/living/silicon/ai/update_lying() + lying = FALSE +/mob/living/silicon/ai/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE // If our powersupply object was destroyed somehow, create new one. if(!psupply) create_powersupply() - - lying = 0 // Handle lying down - // We aren't shut down, and we lack external power. Try to fix it using the restoration routine. if (!self_shutdown && !has_power(0)) // AI's restore power routine is not running. Start it automatically. if(aiRestorePowerRoutine == AI_RESTOREPOWER_IDLE) aiRestorePowerRoutine = AI_RESTOREPOWER_STARTING handle_power_failure() - - handle_impaired_vision() update_power_usage() handle_power_oxyloss() - update_sight() - process_queued_alarms() - handle_regular_hud_updates() - switch(src.sensor_mode) if (SEC_HUD) process_sec_hud(src,0,src.eyeobj,get_computer_network()) if (MED_HUD) process_med_hud(src,0,src.eyeobj,get_computer_network()) - process_os() - handle_status_effects() - if(controlling_drone && stat != CONSCIOUS) controlling_drone.release_ai_control("WARNING: Primary control loop failure. Session terminated.") diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 57d377c45ce..20c57012634 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -1,6 +1,9 @@ /mob/living/silicon/gib() ..("gibbed-r") - gibs(loc, gibber_type = /obj/effect/gibspawner/robot) + gibs() + +/mob/living/silicon/get_gibber_type() + return /obj/effect/gibspawner/robot /mob/living/silicon/dust() ..("dust-r", /obj/item/remains/robot) diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index b6ed6962fff..c59c817f66a 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -1,31 +1,19 @@ -/mob/living/silicon/pai/Life() - - SHOULD_CALL_PARENT(FALSE) - - update_health() - if (src.stat == DEAD) - return - - if(src.cable) - if(get_dist(src, cable) > 1) - visible_message( \ - message = SPAN_NOTICE("The data cable rapidly retracts back into its spool."), \ - blind_message = SPAN_NOTICE("You hear a click and the sound of wire spooling rapidly.")) - QDEL_NULL(cable) - - handle_regular_hud_updates() - - if(src.secHUD == 1) - process_sec_hud(src, 1, network = get_computer_network()) - - if(src.medHUD == 1) - process_med_hud(src, 1, network = get_computer_network()) - +/mob/living/silicon/pai/handle_regular_hud_updates() + . = ..() + if(.) + if(src.secHUD == 1) + process_sec_hud(src, 1, network = get_computer_network()) + if(src.medHUD == 1) + process_med_hud(src, 1, network = get_computer_network()) + +/mob/living/silicon/pai/handle_regular_status_updates() + . = ..() process_os() // better safe than sorry, in case some pAI has it - - if(silence_time) - if(world.timeofday >= silence_time) - silence_time = null - to_chat(src, SPAN_NOTICE("Communication circuit reinitialized. Speech and messaging functionality restored.")) - - handle_status_effects() + if(src.cable && get_dist(src, cable) > 1) + visible_message( \ + message = SPAN_NOTICE("The data cable rapidly retracts back into its spool."), \ + blind_message = SPAN_NOTICE("You hear a click and the sound of wire spooling rapidly.")) + QDEL_NULL(cable) + +/mob/living/silicon/pai/death(gibbed, deathmessage, show_dead_message) + return ..(deathmessage = "gives one shrill beep before falling lifeless.") diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index bc8f1133234..2be9d6e687e 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -59,8 +59,6 @@ var/global/list/possible_say_verbs = list( var/pai_law0 = "Serve your master." var/pai_laws // String for additional operating instructions our master might give us - var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded - // Various software-specific vars var/secHUD = 0 // Toggles whether the Security HUD is active or not @@ -115,9 +113,8 @@ var/global/list/possible_say_verbs = list( // this function shows the information about being silenced as a pAI in the Status panel /mob/living/silicon/pai/proc/show_silenced() - if(silence_time) - var/timeleft = round((silence_time - world.timeofday)/10 ,1) - stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]") + var/timeleft = round((HAS_STATUS(src, STAT_SILENCE) * SSmobs.wait) / 10, 1) + stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]") /mob/living/silicon/pai/Stat() . = ..() @@ -140,7 +137,7 @@ var/global/list/possible_say_verbs = list( // 33% chance to change prime directive (based on severity) // 33% chance of no additional effect - silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes + SET_STATUS_MAX(src, STAT_SILENCE, 2 MINUTES) to_chat(src, SPAN_DANGER("Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete.")) if(prob(20)) visible_message( \ diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm index efc75877826..732261c052d 100644 --- a/code/modules/mob/living/silicon/pai/say.dm +++ b/code/modules/mob/living/silicon/pai/say.dm @@ -1,5 +1,5 @@ /mob/living/silicon/pai/say(var/msg) - if(silence_time) + if(HAS_STATUS(src, STAT_SILENCE)) to_chat(src, SPAN_WARNING("Communication circuits are disabled.")) return return ..(msg) diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index 475f54b884c..c3187cfa3d9 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -12,7 +12,7 @@ w_class = ITEM_SIZE_SMALL throw_speed = 5 throw_range = 10 - origin_tech = "{'magnets':2,'biotech':1,'engineering':2}" + origin_tech = @'{"magnets":2,"biotech":1,"engineering":2}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 245fce44990..3fd56f6b134 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -1,4 +1,4 @@ -// TODO: remove the robot.mmi and robot.cell variables and completely rely on the robot component system +// TODO: remove the robot.central_processor and robot.cell variables and completely rely on the robot component system /datum/robot_component/var/name /datum/robot_component/var/installed = 0 diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index c275e273f0f..655e3a9c54f 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -1,7 +1,5 @@ /mob/living/silicon/robot/dust() - //Delete the MMI first so that it won't go popping out. - if(mmi) - qdel(mmi) + clear_brain() ..() /mob/living/silicon/robot/death(gibbed,deathmessage, show_dead_message) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index c529954a21a..57ed84e6ed3 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -46,7 +46,7 @@ default_language = /decl/language/binary/drone // NO BRAIN. - mmi = null + central_processor = null //We need to screw with their HP a bit. They have around one fifth as much HP as a full borg. for(var/V in components) if(V != "power cell") @@ -56,10 +56,10 @@ verbs -= /mob/living/silicon/robot/verb/Namepick update_icon() - events_repository.register(/decl/observ/moved, src, src, /mob/living/silicon/robot/drone/proc/on_moved) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/mob/living/silicon/robot/drone, on_moved)) /mob/living/silicon/robot/drone/Destroy() - events_repository.unregister(/decl/observ/moved, src, src, /mob/living/silicon/robot/drone/proc/on_moved) + events_repository.unregister(/decl/observ/moved, src, src, TYPE_PROC_REF(/mob/living/silicon/robot/drone, on_moved)) . = ..() /mob/living/silicon/robot/drone/proc/on_moved(var/atom/movable/am, var/turf/old_loc, var/turf/new_loc) @@ -77,7 +77,7 @@ /mob/living/silicon/robot/drone/can_be_possessed_by(var/mob/observer/ghost/possessor) if(!istype(possessor) || !possessor.client || !possessor.ckey) return 0 - if(!config.allow_drone_spawn) + if(!get_config_value(/decl/config/toggle/on/allow_drone_spawn)) to_chat(src, "Playing as drones is not currently permitted.") return 0 if(too_many_active_drones()) @@ -179,7 +179,7 @@ if(stat == DEAD) - if(!config.allow_drone_spawn || emagged || should_be_dead()) //It's dead, Dave. + if(!get_config_value(/decl/config/toggle/on/allow_drone_spawn) || emagged || should_be_dead()) //It's dead, Dave. to_chat(user, "The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.") return @@ -246,8 +246,8 @@ /mob/living/silicon/robot/drone/death() if(stat != DEAD && should_be_dead()) self_destruct() - return - return ..() + return FALSE + . = ..() /mob/living/silicon/robot/drone/self_destruct() timeofdeath = world.time @@ -340,7 +340,7 @@ for(var/mob/living/silicon/robot/drone/D in global.silicon_mob_list) if(D.key && D.client) drones++ - return drones >= config.max_maint_drones + return drones >= get_config_value(/decl/config/num/max_maint_drones) /mob/living/silicon/robot/drone/show_laws(var/everyone = 0) if(!controlling_ai) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 7443a175acd..850b58b088a 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -77,12 +77,11 @@ can_hold = list( /obj/item/cell, /obj/item/stock_parts, - /obj/item/mmi, + /obj/item/organ/internal/brain_interface, /obj/item/robot_parts, /obj/item/borg/upgrade, /obj/item/flash, /obj/item/organ/internal/brain, - /obj/item/organ/internal/posibrain, /obj/item/stack/cable_coil, /obj/item/stock_parts/circuitboard, /obj/item/chems/glass, @@ -200,7 +199,7 @@ var/resolved = wrapped.resolve_attackby(target,user,params) //If resolve_attackby forces waiting before taking wrapped, we need to let it finish before doing the rest. - addtimer(CALLBACK(src, .proc/finish_using, target, user, params, force_holder, resolved), 0) + addtimer(CALLBACK(src, PROC_REF(finish_using), target, user, params, force_holder, resolved), 0) else if(istype(target,/obj/item)) //Check that we're not pocketing a mob. var/obj/item/I = target diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index 8e53f6adbaf..da19e46697c 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -64,14 +64,14 @@ icon_state = "drone_fab_active" var/elapsed = world.time - time_last_drone - drone_progress = round((elapsed/config.drone_build_time)*100) + drone_progress = round((elapsed/get_config_value(/decl/config/num/drone_build_time))*100) if(drone_progress >= 100) visible_message("\The [src] voices a strident beep, indicating a drone chassis is prepared.") /obj/machinery/drone_fabricator/examine(mob/user) . = ..() - if(produce_drones && drone_progress >= 100 && isghost(user) && config.allow_drone_spawn && count_drones() < config.max_maint_drones) + if(produce_drones && drone_progress >= 100 && isghost(user) && get_config_value(/decl/config/toggle/on/allow_drone_spawn) && count_drones() < get_config_value(/decl/config/num/max_maint_drones)) to_chat(user, "
    A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.") /obj/machinery/drone_fabricator/proc/create_drone(var/client/player) @@ -79,7 +79,7 @@ if(stat & NOPOWER) return - if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones) + if(!produce_drones || !get_config_value(/decl/config/toggle/on/allow_drone_spawn) || count_drones() >= get_config_value(/decl/config/num/max_maint_drones)) return if(player && !isghost(player.mob)) @@ -110,7 +110,7 @@ to_chat(user, "The game hasn't started yet!") return - if(!(config.allow_drone_spawn)) + if(!get_config_value(/decl/config/toggle/on/allow_drone_spawn)) to_chat(user, "That verb is not currently permitted.") return @@ -118,7 +118,7 @@ to_chat(user, "You are banned from playing synthetics and cannot spawn as a drone.") return - if(config.use_age_restriction_for_jobs && isnum(user.client.player_age)) + if(get_config_value(/decl/config/num/use_age_restriction_for_jobs) && isnum(user.client.player_age)) if(user.client.player_age <= 3) to_chat(user, " Your account is not old enough to play as a maintenance drone.") return diff --git a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm index fb74bdbf59b..36b89ea29cf 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm @@ -7,7 +7,7 @@ /mob/living/silicon/robot/drone/attack_ai(mob/living/silicon/ai/user) - if(!istype(user) || controlling_ai || !config.allow_drone_spawn) + if(!istype(user) || controlling_ai || !get_config_value(/decl/config/toggle/on/allow_drone_spawn)) return if(stat != DEAD || client || key) @@ -46,7 +46,7 @@ /obj/machinery/drone_fabricator/attack_ai(mob/living/silicon/ai/user) - if(!istype(user) || user.controlling_drone || !config.allow_drone_spawn) + if(!istype(user) || user.controlling_drone || !get_config_value(/decl/config/toggle/on/allow_drone_spawn)) return if(stat & NOPOWER) @@ -61,7 +61,7 @@ to_chat(user, "\The [src] is not ready to produce a new drone.") return - if(count_drones() >= config.max_maint_drones) + if(count_drones() >= get_config_value(/decl/config/num/max_maint_drones)) to_chat(user, "The drone control subsystems are tasked to capacity; they cannot support any more drones.") return diff --git a/code/modules/mob/living/silicon/robot/flying/flying.dm b/code/modules/mob/living/silicon/robot/flying/flying.dm index b242c869bb7..dbd40ea19a0 100644 --- a/code/modules/mob/living/silicon/robot/flying/flying.dm +++ b/code/modules/mob/living/silicon/robot/flying/flying.dm @@ -21,7 +21,7 @@ components["comms"] = new/datum/robot_component/binary_communication(src) components["armour"] = new/datum/robot_component/armour/light(src) -/mob/living/silicon/robot/flying/Life() +/mob/living/silicon/robot/flying/handle_regular_status_updates() . = ..() if(incapacitated() || !is_component_functioning("actuator")) stop_flying() diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm index b5472458470..52bababd1ce 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm @@ -43,7 +43,7 @@ /obj/item/robot_module/flying/emergency/finalize_emag() . = ..() - emag.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 250) + emag.add_to_reagents(/decl/material/liquid/acid/polyacid, 250) emag.SetName("Polyacid spray") /obj/item/robot_module/flying/emergency/finalize_equipment() @@ -73,5 +73,5 @@ if(PS && PS.reagents.total_volume < PS.volume) var/adding = min(PS.volume-PS.reagents.total_volume, 2*amount) if(adding > 0) - PS.reagents.add_reagent(/decl/material/liquid/acid/polyacid, adding) + PS.add_to_reagents(/decl/material/liquid/acid/polyacid, adding) ..() diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm index 06d167b6f44..ed66d252a57 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm @@ -44,5 +44,5 @@ if(luminol.reagents.total_volume < luminol.volume) var/adding = min(luminol.volume-luminol.reagents.total_volume, 2*amount) if(adding > 0) - luminol.reagents.add_reagent(/decl/material/liquid/luminol, adding) + luminol.add_to_reagents(/decl/material/liquid/luminol, adding) ..() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 8aefbe546d1..8a661932583 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -1,38 +1,12 @@ -/mob/living/silicon/robot/Life() - - SHOULD_CALL_PARENT(FALSE) - - set invisibility = FALSE - set background = 1 - - if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) - return - - //Status updates, death etc. - clamp_values() - handle_regular_status_updates() - handle_actions() - - if(client) - handle_regular_hud_updates() - update_items() - if (src.stat != DEAD) //still using power - use_power() - process_killswitch() - process_locks() - process_queued_alarms() - process_os() - - handle_status_effects() - UpdateLyingBuckledAndVerbStatus() - -/mob/living/silicon/robot/proc/clamp_values() - set_status(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30)) - set_status(STAT_ASLEEP, 0) - adjustBruteLoss(0, do_update_health = FALSE) - adjustToxLoss(0, do_update_health = FALSE) - adjustOxyLoss(0, do_update_health = FALSE) - adjustFireLoss(0) +/mob/living/silicon/robot/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE + use_power() + process_killswitch() + process_locks() + process_queued_alarms() + process_os() /mob/living/silicon/robot/proc/use_power() used_power_this_tick = 0 @@ -68,11 +42,13 @@ set_light(0) /mob/living/silicon/robot/should_be_dead() - return current_health < config.health_threshold_dead + return current_health < get_config_value(/decl/config/num/health_health_threshold_dead) /mob/living/silicon/robot/handle_regular_status_updates() + SHOULD_CALL_PARENT(FALSE) update_health() + set_status(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30)) if(HAS_STATUS(src, STAT_ASLEEP)) SET_STATUS_MAX(src, STAT_PARA, 3) @@ -115,8 +91,9 @@ return 1 /mob/living/silicon/robot/handle_regular_hud_updates() - ..() - + . = ..() + if(!.) + return var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src) if(hud && hud.hud) hud.hud.process_hud(src) @@ -165,7 +142,7 @@ if(0 to 50) src.healths.icon_state = "health4" else - if(current_health > config.health_threshold_dead) + if(current_health > get_config_value(/decl/config/num/health_health_threshold_dead)) src.healths.icon_state = "health5" else src.healths.icon_state = "health6" @@ -230,6 +207,7 @@ set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry) set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high) + update_items() return 1 /mob/living/silicon/robot/handle_vision() @@ -265,7 +243,7 @@ if (src.client) src.client.screen -= src.contents for(var/obj/I in src.contents) - if(I && !(istype(I,/obj/item/cell) || istype(I,/obj/item/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/mmi))) + if(I && !(istype(I,/obj/item/cell) || istype(I,/obj/item/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/organ/internal/brain_interface))) src.client.screen += I if(src.module_state_1) src.module_state_1:screen_loc = ui_inv1 diff --git a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm index a716a3b158c..53f4cb60798 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm @@ -72,13 +72,13 @@ /obj/item/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) ..() var/obj/item/chems/condiment/enzyme/E = locate() in equipment - E.reagents.add_reagent(/decl/material/liquid/enzyme, 2 * amount) + E.add_to_reagents(/decl/material/liquid/enzyme, 2 * amount) if(emag) var/obj/item/chems/drinks/bottle/small/beer/B = emag - B.reagents.add_reagent(/decl/material/liquid/ethanol/beer, amount * 0.4) - B.reagents.add_reagent(/decl/material/solid/ice, amount * 0.1) - B.reagents.add_reagent(/decl/material/liquid/paralytics, amount * 0.2) - B.reagents.add_reagent(/decl/material/liquid/sedatives, amount * 0.3) + B.add_to_reagents(/decl/material/liquid/ethanol/beer, amount * 0.4) + B.add_to_reagents(/decl/material/solid/ice, amount * 0.1) + B.add_to_reagents(/decl/material/liquid/paralytics, amount * 0.2) + B.add_to_reagents(/decl/material/liquid/sedatives, amount * 0.3) /obj/item/robot_module/clerical/general name = "clerical robot module" diff --git a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm index 801ec08cb83..ae9d70e5a2b 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm @@ -25,7 +25,7 @@ /obj/item/robot_module/janitor/finalize_emag() . = ..() - emag.reagents.add_reagent(/decl/material/liquid/lube, 250) + emag.add_to_reagents(/decl/material/liquid/lube, 250) emag.SetName("Lube spray") /obj/item/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) @@ -34,4 +34,4 @@ LR.Charge(R, amount) if(emag) var/obj/item/chems/spray/S = emag - S.reagents.add_reagent(/decl/material/liquid/lube, 20 * amount) + S.add_to_reagents(/decl/material/liquid/lube, 20 * amount) diff --git a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm index 012206fe5ee..eeb10eae170 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm @@ -116,7 +116,7 @@ /obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) ..() var/obj/item/chems/spray/cleaner/drone/SC = locate() in equipment - SC.reagents.add_reagent(/decl/material/liquid/cleaner, 8 * amount) + SC.add_to_reagents(/decl/material/liquid/cleaner, 8 * amount) /obj/item/robot_module/drone/construction name = "construction drone module" diff --git a/code/modules/mob/living/silicon/robot/modules/module_medical.dm b/code/modules/mob/living/silicon/robot/modules/module_medical.dm index 26a0b11dcfd..c874dfb5c2a 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_medical.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_medical.dm @@ -70,7 +70,7 @@ /obj/item/robot_module/medical/surgeon/finalize_emag() . = ..() - emag.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 250) + emag.add_to_reagents(/decl/material/liquid/acid/polyacid, 250) emag.SetName("Polyacid spray") /obj/item/robot_module/medical/surgeon/finalize_synths() @@ -86,7 +86,7 @@ /obj/item/robot_module/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) if(emag) var/obj/item/chems/spray/PS = emag - PS.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 2 * amount) + PS.add_to_reagents(/decl/material/liquid/acid/polyacid, 2 * amount) ..() /obj/item/robot_module/medical/crisis @@ -143,7 +143,7 @@ /obj/item/robot_module/medical/crisis/finalize_emag() . = ..() - emag.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 250) + emag.add_to_reagents(/decl/material/liquid/acid/polyacid, 250) emag.SetName("Polyacid spray") /obj/item/robot_module/medical/crisis/finalize_synths() @@ -166,5 +166,5 @@ S.update_icon() if(emag) var/obj/item/chems/spray/PS = emag - PS.reagents.add_reagent(/decl/material/liquid/acid/polyacid, 2 * amount) + PS.add_to_reagents(/decl/material/liquid/acid/polyacid, 2 * amount) ..() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e7c0646d9f3..867a41d4c1a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -60,7 +60,7 @@ // Components are basically robot organs. var/list/components = list() - var/obj/item/mmi/mmi = null + var/obj/item/organ/internal/central_processor var/opened = 0 var/emagged = 0 @@ -195,21 +195,15 @@ return amount return 0 -//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO -//Improved /N /mob/living/silicon/robot/Destroy() - if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. - if(mind) - mmi.dropInto(loc) - if(mmi.brainmob) - mind.transfer_to(mmi.brainmob) - else - to_chat(src, "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug.") - ghostize() - //ERROR("A borg has been destroyed, but its MMI lacked a brainmob, so the mind could not be transferred. Player: [ckey].") - mmi = null + if(central_processor) + central_processor.dropInto(loc) + var/mob/living/brainmob = central_processor.get_brainmob() + if(mind && brainmob) + mind.transfer_to(brainmob) else - QDEL_NULL(mmi) + ghostize() + central_processor = null if(connected_ai) connected_ai.connected_robots -= src connected_ai = null @@ -280,12 +274,10 @@ if(prefix) modtype = prefix - if(istype(mmi, /obj/item/organ/internal/posibrain)) - braintype = "Robot" - else if(istype(mmi, /obj/item/mmi/digital/robot)) - braintype = "Drone" + if(istype(central_processor)) + braintype = central_processor.get_synthetic_owner_name() else - braintype = "Cyborg" + braintype = "Robot" var/changed_name = "" if(custom_name) @@ -514,24 +506,31 @@ else if(IS_CROWBAR(W) && user.a_intent != I_HURT) // crowbar means open or close the cover - we all know what a crowbar is by now if(opened) if(cell) - user.visible_message("\The [user] begins clasping shut \the [src]'s maintenance hatch.", "You begin closing up \the [src].") + + user.visible_message( + SPAN_NOTICE("\The [user] begins clasping shut \the [src]'s maintenance hatch."), + SPAN_NOTICE("You begin closing up \the [src].")) + if(do_after(user, 50, src)) - to_chat(user, "You close \the [src]'s maintenance hatch.") + to_chat(user, SPAN_NOTICE("You close \the [src]'s maintenance hatch.")) opened = 0 update_icon() else if(wiresexposed && wires.IsAllCut()) - //Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob. - if(!mmi) - to_chat(user, "\The [src] has no brain to remove.") + //Cell is out, wires are exposed, remove CPU, produce damaged chassis, baleet original mob. + if(!central_processor) + to_chat(user, "\The [src] has no central processor to remove.") return - user.visible_message("\The [user] begins ripping [mmi] from [src].", "You jam the crowbar into the robot and begin levering [mmi].") + user.visible_message( + SPAN_NOTICE("\The [user] begins ripping \the [central_processor] out of \the [src]."), + SPAN_NOTICE("You jam the crowbar into the robot and begin levering out \the [central_processor].")) + if(do_after(user, 50, src)) dismantle(user) else - // Okay we're not removing the cell or an MMI, but maybe something else? + // Okay we're not removing the cell or a CPU, but maybe something else? var/list/removable_components = list() for(var/V in components) if(V == "power cell") continue @@ -839,7 +838,7 @@ if(module.type == /obj/item/robot_module/janitor) var/turf/tile = loc if(isturf(tile)) - tile.clean_blood() + tile.clean() if (istype(tile, /turf/simulated)) var/turf/simulated/S = tile S.dirt = 0 @@ -849,25 +848,25 @@ qdel(A) else if(istype(A, /obj/item)) var/obj/item/cleaned_item = A - cleaned_item.clean_blood() + cleaned_item.clean() else if(ishuman(A)) var/mob/living/carbon/human/cleaned_human = A if(cleaned_human.lying) var/obj/item/head = cleaned_human.get_equipped_item(slot_head_str) if(head) - head.clean_blood() + head.clean() var/obj/item/suit = cleaned_human.get_equipped_item(slot_wear_suit_str) if(suit) - suit.clean_blood() + suit.clean() else var/obj/item/uniform = cleaned_human.get_equipped_item(slot_w_uniform_str) if(uniform) - uniform.clean_blood() + uniform.clean() var/obj/item/shoes = cleaned_human.get_equipped_item(slot_shoes_str) if(shoes) - shoes.clean_blood() - cleaned_human.clean_blood(1) - to_chat(cleaned_human, "[src] cleans your face!") + shoes.clean() + cleaned_human.clean() + to_chat(cleaned_human, SPAN_WARNING("\The [src] cleans your face!")) return /mob/living/silicon/robot/proc/self_destruct() @@ -1099,7 +1098,10 @@ return ASSIGNMENT_ROBOT /mob/living/silicon/robot/handle_pre_transformation() - QDEL_NULL(mmi) + clear_brain() + +/mob/living/silicon/robot/proc/clear_brain() + QDEL_NULL(central_processor) /mob/living/silicon/robot/do_flash_animation() set waitfor = FALSE diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index f61cee15c28..d368c595b46 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -122,7 +122,7 @@ var/mode = 1 /obj/item/pen/robopen/make_pen_description() - desc = "\A [stroke_colour_name] [medium_name] printing attachment with a paper naming mode." + desc = "\A [stroke_color_name] [medium_name] printing attachment with a paper naming mode." /obj/item/pen/robopen/attack_self(mob/user) diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index ff5553a8004..89e537c8125 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -27,4 +27,4 @@ if(module_active && istype(module_active,/obj/item/borg/combat/mobility)) tally-=3 - return tally+config.robot_delay + return tally+get_config_value(/decl/config/num/movement_robot) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/subsystems.dm b/code/modules/mob/living/silicon/subsystems.dm index be952b3df5e..fb03130e74d 100644 --- a/code/modules/mob/living/silicon/subsystems.dm +++ b/code/modules/mob/living/silicon/subsystems.dm @@ -30,7 +30,7 @@ if(/datum/nano_module/alarm_monitor/all in silicon_subsystems) for(var/datum/alarm_handler/AH in SSalarm.all_handlers) - AH.register_alarm(src, /mob/living/silicon/proc/receive_alarm) + AH.register_alarm(src, TYPE_PROC_REF(/mob/living/silicon, receive_alarm)) queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order /mob/living/silicon/proc/init_subsystem(var/subsystem_type) diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm index 51a5df0a53f..23d000c9ea5 100644 --- a/code/modules/mob/living/simple_animal/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm @@ -43,6 +43,9 @@ var/list/construct_spells = list() +/mob/living/simple_animal/construct/check_has_mouth() + return FALSE + /mob/living/simple_animal/construct/on_defilement() return @@ -119,7 +122,7 @@ hitsound = 'sound/weapons/heavysmash.ogg' force = 30 -/mob/living/simple_animal/construct/armoured/Life() +/mob/living/simple_animal/construct/armoured/handle_regular_status_updates() set_status(STAT_WEAK, 0) if ((. = ..())) return @@ -248,17 +251,21 @@ force = 25 ////////////////HUD////////////////////// +/mob/living/simple_animal/construct/handle_regular_status_updates() + . = ..() + if(.) + silence_spells(purge) -/mob/living/simple_animal/construct/Life() +/mob/living/simple_animal/construct/handle_regular_hud_updates() . = ..() if(.) if(fire) fire.icon_state = "fire[!!fire_alert]" silence_spells(purge) -/mob/living/simple_animal/construct/armoured/Life() +/mob/living/simple_animal/construct/armoured/handle_regular_hud_updates() . = ..() - if(healths) + if(. && healths) switch(current_health) if(250 to INFINITY) healths.icon_state = "juggernaut_health0" if(208 to 249) healths.icon_state = "juggernaut_health1" @@ -270,9 +277,9 @@ else healths.icon_state = "juggernaut_health7" -/mob/living/simple_animal/construct/behemoth/Life() +/mob/living/simple_animal/construct/behemoth/handle_regular_hud_updates() . = ..() - if(healths) + if(. && healths) switch(current_health) if(750 to INFINITY) healths.icon_state = "juggernaut_health0" if(625 to 749) healths.icon_state = "juggernaut_health1" @@ -283,9 +290,9 @@ if(1 to 124) healths.icon_state = "juggernaut_health6" else healths.icon_state = "juggernaut_health7" -/mob/living/simple_animal/construct/builder/Life() +/mob/living/simple_animal/construct/builder/handle_regular_hud_updates() . = ..() - if(healths) + if(. && healths) switch(current_health) if(50 to INFINITY) healths.icon_state = "artificer_health0" if(42 to 49) healths.icon_state = "artificer_health1" @@ -298,9 +305,9 @@ -/mob/living/simple_animal/construct/wraith/Life() +/mob/living/simple_animal/construct/wraith/handle_regular_hud_updates() . = ..() - if(healths) + if(. && healths) switch(current_health) if(75 to INFINITY) healths.icon_state = "wraith_health0" if(62 to 74) healths.icon_state = "wraith_health1" @@ -312,9 +319,9 @@ else healths.icon_state = "wraith_health7" -/mob/living/simple_animal/construct/harvester/Life() +/mob/living/simple_animal/construct/harvester/handle_regular_hud_updates() . = ..() - if(healths) + if(. && healths) switch(current_health) if(150 to INFINITY) healths.icon_state = "harvester_health0" if(125 to 149) healths.icon_state = "harvester_health1" diff --git a/code/modules/mob/living/simple_animal/constructs/soulstone.dm b/code/modules/mob/living/simple_animal/constructs/soulstone.dm index cba1c3eed2f..884576424d5 100644 --- a/code/modules/mob/living/simple_animal/constructs/soulstone.dm +++ b/code/modules/mob/living/simple_animal/constructs/soulstone.dm @@ -5,7 +5,7 @@ desc = "A strange, ridged chunk of some glassy red material. Achingly cold to the touch." w_class = ITEM_SIZE_SMALL slot_flags = SLOT_LOWER_BODY - origin_tech = "{'wormholes':4,'materials':4}" + origin_tech = @'{"wormholes":4,"materials":4}' material = /decl/material/solid/gemstone/crystal var/full = SOULSTONE_EMPTY var/is_evil = 1 diff --git a/code/modules/mob/living/simple_animal/familiars/familiars.dm b/code/modules/mob/living/simple_animal/familiars/familiars.dm index 05a97123b3f..8405efeb321 100644 --- a/code/modules/mob/living/simple_animal/familiars/familiars.dm +++ b/code/modules/mob/living/simple_animal/familiars/familiars.dm @@ -71,11 +71,9 @@ /mob/living/simple_animal/familiar/horror/death(gibbed, deathmessage, show_dead_message) ..(null,"rapidly deteriorates","The bonds tying you to this mortal plane have been severed.") - ghostize() - gibs(src.loc) - qdel(src) - + if(!gibbed) + gib() /mob/living/simple_animal/familiar/minor_amaros name = "minor amaros" diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 2a6dd1cf0c2..5dd92b4c64b 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -233,7 +233,7 @@ holder_type = /obj/item/holder/runtime /obj/item/holder/runtime - origin_tech = "{'programming':1,'biotech':1}" + origin_tech = @'{"programming":1,"biotech":1}' /mob/living/simple_animal/cat/kitten name = "kitten" diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 3334703a4e8..36aa587eb08 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -28,10 +28,9 @@ expected_type = /mob/living/simple_animal/hostile/retaliate/goat /datum/ai/goat/do_process(time_elapsed) - . = ..() - var/mob/living/simple_animal/hostile/retaliate/goat/goat = body //chance to go crazy and start wacking stuff + var/mob/living/simple_animal/hostile/retaliate/goat/goat = body if(!length(goat.enemies) && prob(1)) goat.Retaliate() @@ -66,9 +65,11 @@ QDEL_NULL(udder) . = ..() -/mob/living/simple_animal/hostile/retaliate/goat/handle_regular_status_updates() +/mob/living/simple_animal/hostile/retaliate/goat/handle_living_non_stasis_processes() . = ..() - if(. && stat == CONSCIOUS && udder && prob(5)) + if(!.) + return FALSE + if(stat == CONSCIOUS && udder && prob(5)) udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10)) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() @@ -140,16 +141,18 @@ return TRUE . = ..() -/mob/living/simple_animal/cow/handle_regular_status_updates() +/mob/living/simple_animal/cow/handle_living_non_stasis_processes() . = ..() - if(. && udder && prob(5)) + if(!.) + return FALSE + if(udder && prob(5)) udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10)) /mob/living/simple_animal/cow/default_disarm_interaction(mob/user) if(stat != DEAD && !HAS_STATUS(src, STAT_WEAK)) user.visible_message(SPAN_NOTICE("\The [user] tips over \the [src].")) SET_STATUS_MAX(src, STAT_WEAK, 30) - addtimer(CALLBACK(src, .proc/do_tip_response), rand(20, 50)) + addtimer(CALLBACK(src, PROC_REF(do_tip_response)), rand(20, 50)) return TRUE return ..() @@ -184,19 +187,37 @@ pixel_x = rand(-6, 6) pixel_y = rand(0, 10) -/mob/living/simple_animal/chick/Life() +/mob/living/simple_animal/chick/handle_living_non_stasis_processes() . = ..() if(!.) return FALSE amount_grown += rand(1,2) if(amount_grown >= 100) - new /mob/living/simple_animal/chicken(src.loc) + new /mob/living/simple_animal/fowl/chicken(src.loc) qdel(src) +/mob/living/simple_animal/fowl + mob_default_max_health = 10 + pass_flags = PASS_FLAG_TABLE + mob_size = MOB_SIZE_SMALL + meat_type = /obj/item/chems/food/meat/chicken + meat_amount = 2 + skin_material = /decl/material/solid/organic/skin/feathers + speak_chance = 2 + turns_per_move = 3 + abstract_type = /mob/living/simple_animal/fowl + var/body_color + +/mob/living/simple_animal/fowl/Initialize() + if(!default_pixel_x) + default_pixel_x = rand(-6, 6) + if(!default_pixel_y) + default_pixel_y = rand(0, 10) + . = ..() + var/global/const/MAX_CHICKENS = 50 var/global/chicken_count = 0 - -/mob/living/simple_animal/chicken +/mob/living/simple_animal/fowl/chicken name = "chicken" desc = "Hopefully the eggs are good this season." icon = 'icons/mob/simple_animal/chicken_white.dmi' @@ -204,23 +225,17 @@ var/global/chicken_count = 0 speak_emote = list("clucks","croons") emote_hear = list("clucks") emote_see = list("pecks at the ground","flaps its wings viciously") - speak_chance = 2 - turns_per_move = 3 - mob_default_max_health = 10 - pass_flags = PASS_FLAG_TABLE - mob_size = MOB_SIZE_SMALL - - meat_type = /obj/item/chems/food/meat/chicken - meat_amount = 2 - skin_material = /decl/material/solid/organic/skin/feathers - var/eggsleft = 0 - var/body_color -/mob/living/simple_animal/chicken/Initialize() +/mob/living/simple_animal/fowl/chicken/Initialize() . = ..() if(!body_color) - body_color = pick( list("brown","black","white") ) + body_color = pick("brown", "black", "white") + update_icon() + global.chicken_count += 1 + +/mob/living/simple_animal/fowl/chicken/on_update_icon() + . = ..() switch(body_color) if("brown") icon = 'icons/mob/simple_animal/chicken_brown.dmi' @@ -228,15 +243,12 @@ var/global/chicken_count = 0 icon = 'icons/mob/simple_animal/chicken_black.dmi' else icon = 'icons/mob/simple_animal/chicken_white.dmi' - pixel_x = rand(-6, 6) - pixel_y = rand(0, 10) - chicken_count += 1 -/mob/living/simple_animal/chicken/death(gibbed, deathmessage, show_dead_message) +/mob/living/simple_animal/fowl/chicken/death(gibbed, deathmessage, show_dead_message) ..(gibbed, deathmessage, show_dead_message) - chicken_count -= 1 + global.chicken_count -= 1 -/mob/living/simple_animal/chicken/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_animal/fowl/chicken/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/chems/food/grown)) //feedin' dem chickens var/obj/item/chems/food/grown/G = O if(G.seed && G.seed.kitchen_tag == "wheat") @@ -251,7 +263,7 @@ var/global/chicken_count = 0 else ..() -/mob/living/simple_animal/chicken/Life() +/mob/living/simple_animal/fowl/chicken/handle_living_non_stasis_processes() . = ..() if(!.) return FALSE @@ -265,6 +277,31 @@ var/global/chicken_count = 0 E.amount_grown = 1 START_PROCESSING(SSobj, E) +/mob/living/simple_animal/fowl/duck + name = "duck" + desc = "It's a duck. Quack." + icon = 'icons/mob/simple_animal/duck_white.dmi' + speak = list("Wak!","Wak wak wak!","Wak wak.") + speak_emote = list("quacks") + emote_hear = list("quacks") + emote_see = list("preens itself", "waggles its tail") + +/mob/living/simple_animal/fowl/duck/Initialize() + . = ..() + if(!body_color) + body_color = pick("brown", "mallard", "white") + update_icon() + +/mob/living/simple_animal/fowl/duck/on_update_icon() + . = ..() + switch(body_color) + if("brown") + icon = 'icons/mob/simple_animal/duck_brown.dmi' + if("mallard") + icon = 'icons/mob/simple_animal/duck_mallard.dmi' + else + icon = 'icons/mob/simple_animal/duck_white.dmi' + /obj/item/chems/food/egg var/amount_grown = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index c034134ea0a..4e841b450f1 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -56,7 +56,7 @@ mouse.set_stat(CONSCIOUS) mouse.wander = 1 else if(prob(5)) - INVOKE_ASYNC(mouse, /mob/living/simple_animal/proc/audible_emote, "snuffles.") + INVOKE_ASYNC(mouse, TYPE_PROC_REF(/mob/living/simple_animal, audible_emote), "snuffles.") /mob/living/simple_animal/mouse/Initialize() verbs += /mob/living/proc/ventcrawl diff --git a/code/modules/mob/living/simple_animal/friendly/mushroom.dm b/code/modules/mob/living/simple_animal/friendly/mushroom.dm index 6ce38da19f5..c73bcdd1f8f 100644 --- a/code/modules/mob/living/simple_animal/friendly/mushroom.dm +++ b/code/modules/mob/living/simple_animal/friendly/mushroom.dm @@ -50,7 +50,7 @@ . = ..(gibbed, deathmessage, show_dead_message) if(.) total_mushrooms-- - if(total_mushrooms < config.maximum_mushrooms && prob(30)) + if(total_mushrooms < get_config_value(/decl/config/num/maximum_mushrooms) && prob(30)) spore_explode() /mob/living/simple_animal/mushroom/proc/spore_explode() diff --git a/code/modules/mob/living/simple_animal/friendly/possum.dm b/code/modules/mob/living/simple_animal/friendly/possum.dm index fec7194e9d8..d9d8fef29a4 100644 --- a/code/modules/mob/living/simple_animal/friendly/possum.dm +++ b/code/modules/mob/living/simple_animal/friendly/possum.dm @@ -92,11 +92,11 @@ /mob/living/simple_animal/opossum/poppy/hear_broadcast(decl/language/language, mob/speaker, speaker_name, message) . = ..() - addtimer(CALLBACK(src, .proc/check_keywords, message), rand(1 SECOND, 3 SECONDS)) + addtimer(CALLBACK(src, PROC_REF(check_keywords), message), rand(1 SECOND, 3 SECONDS)) /mob/living/simple_animal/opossum/poppy/hear_say(var/message, var/verb = "says", var/decl/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) . = ..() - addtimer(CALLBACK(src, .proc/check_keywords, message), rand(1 SECOND, 3 SECONDS)) + addtimer(CALLBACK(src, PROC_REF(check_keywords), message), rand(1 SECOND, 3 SECONDS)) /mob/living/simple_animal/opossum/poppy/proc/check_keywords(var/message) if(!client && stat == CONSCIOUS) diff --git a/code/modules/mob/living/simple_animal/hostile/antlion.dm b/code/modules/mob/living/simple_animal/hostile/antlion.dm index bc34f48024e..5f604dfdc9c 100644 --- a/code/modules/mob/living/simple_animal/hostile/antlion.dm +++ b/code/modules/mob/living/simple_animal/hostile/antlion.dm @@ -26,22 +26,17 @@ var/healing = FALSE var/heal_amount = 6 -/mob/living/simple_animal/hostile/antlion/Life() +/mob/living/simple_animal/hostile/antlion/handle_regular_status_updates() . = ..() - process_healing() //this needs to occur before if(!.) because of stop_automation - - if(!.) - return - - if(!is_on_special_ability_cooldown() && can_act() && target_mob) + if(. && !is_on_special_ability_cooldown() && can_act() && target_mob) vanish() /mob/living/simple_animal/hostile/antlion/proc/vanish() visible_message(SPAN_NOTICE("\The [src] burrows into \the [get_turf(src)]!")) set_invisibility(INVISIBILITY_OBSERVER) prep_burrow(TRUE) - addtimer(CALLBACK(src, .proc/diggy), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(diggy)), 5 SECONDS) /mob/living/simple_animal/hostile/antlion/proc/diggy() var/list/turf_targets @@ -60,12 +55,12 @@ continue turf_targets += T if(!LAZYLEN(turf_targets)) //oh no - addtimer(CALLBACK(src, .proc/emerge), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(emerge)), 2 SECONDS) return var/turf/T = pick(turf_targets) if(T && !incapacitated()) forceMove(T) - addtimer(CALLBACK(src, .proc/emerge), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(emerge)), 2 SECONDS) /mob/living/simple_animal/hostile/antlion/proc/emerge() var/turf/T = get_turf(src) diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm b/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm index c8ffd3d5119..87687c40fcf 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/commanded.dm @@ -16,7 +16,7 @@ command_buffer.Add(lowertext(html_decode(message))) return 0 -/mob/living/simple_animal/hostile/commanded/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname, var/vsource) +/mob/living/simple_animal/hostile/commanded/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="", var/vsource) if((weakref(speaker) in friends) || speaker == master) command_buffer.Add(speaker) command_buffer.Add(lowertext(html_decode(message))) diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm index d90264205f5..d72555d90a5 100644 --- a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm +++ b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm @@ -14,6 +14,7 @@ response_help_3p = "$USER$ waves $USER_HIS$ hand through $TARGET$." response_harm = "agitates" response_disarm = "fans at" + ai = /datum/ai/nanomachines var/regen_time = 0 var/emergency_protocols = 0 @@ -24,20 +25,29 @@ force = 2 sharp = TRUE -/mob/living/simple_animal/hostile/commanded/nanomachine/Life() +/datum/ai/nanomachines + expected_type = /mob/living/simple_animal/hostile/commanded/nanomachine + +/datum/ai/nanomachines/do_process(time_elapsed) + . = ..() + var/mob/living/simple_animal/hostile/commanded/nanomachine/swarm = body + switch(swarm.stance) + if(COMMANDED_HEAL) + if(!swarm.target_mob) + swarm.target_mob = swarm.FindTarget(COMMANDED_HEAL) + if(swarm.target_mob) + swarm.move_to_heal() + if(COMMANDED_HEALING) + swarm.heal() + +/mob/living/simple_animal/hostile/commanded/nanomachine/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE regen_time++ if(regen_time == 2 && current_health < get_max_health()) //slow regen regen_time = 0 heal_overall_damage(1) - . = ..() - if(.) - switch(stance) - if(COMMANDED_HEAL) - if(!target_mob) - target_mob = FindTarget(COMMANDED_HEAL) - move_to_heal() - if(COMMANDED_HEALING) - heal() /mob/living/simple_animal/hostile/commanded/nanomachine/death(gibbed, deathmessage, show_dead_message) ..(null, "dissipates into thin air", "You have been destroyed.") diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 9b1643edd88..cd70586b639 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -173,7 +173,7 @@ return var/mob/living/L = . if(L.reagents) - L.reagents.add_reagent(poison_type, rand(0.5 * poison_per_bite, poison_per_bite)) + L.add_to_reagents(poison_type, rand(0.5 * poison_per_bite, poison_per_bite)) if(prob(poison_per_bite)) to_chat(L, "You feel a tiny prick.") @@ -187,7 +187,7 @@ if(!spooder.busy && prob(spooder.hunt_chance)) spooder.stop_automated_movement = 1 walk_to(spooder, pick(orange(20, spooder)), 1, spooder.move_to_delay) - addtimer(CALLBACK(spooder, /mob/living/simple_animal/hostile/giant_spider/proc/disable_stop_automated_movement), 5 SECONDS) + addtimer(CALLBACK(spooder, TYPE_PROC_REF(/mob/living/simple_animal/hostile/giant_spider, disable_stop_automated_movement)), 5 SECONDS) /mob/living/simple_animal/hostile/giant_spider/proc/disable_stop_automated_movement() stop_automated_movement = 0 @@ -241,7 +241,7 @@ Guard caste procs /mob/living/simple_animal/hostile/giant_spider/guard/proc/protect(mob/nurse) stop_automated_movement = 1 walk_to(src, nurse, 2, move_to_delay) - addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/giant_spider/proc/disable_stop_automated_movement), 5 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/simple_animal/hostile/giant_spider, disable_stop_automated_movement)), 5 SECONDS) /mob/living/simple_animal/hostile/giant_spider/guard/proc/go_berserk() audible_message("\The [src] chitters wildly!") @@ -250,7 +250,7 @@ Guard caste procs attacking_with.force = initial(attacking_with.force) + 5 move_to_delay-- break_stuff_probability = 45 - addtimer(CALLBACK(src, .proc/calm_down), 3 MINUTES) + addtimer(CALLBACK(src, PROC_REF(calm_down)), 3 MINUTES) /mob/living/simple_animal/hostile/giant_spider/guard/proc/calm_down() berserking = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 6e43652a81b..2509a5c7c9f 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -25,6 +25,9 @@ skin_material = null skin_amount = 0 +/mob/living/simple_animal/hostile/hivebot/check_has_mouth() + return FALSE + /mob/living/simple_animal/hostile/hivebot/range desc = "A junky looking robot with four spiky legs. It's equipped with some kind of small-bore gun." ranged = 1 @@ -110,12 +113,9 @@ The megabot . = ..() switch_mode(ATTACK_MODE_ROCKET) -/mob/living/simple_animal/hostile/hivebot/mega/Life() +/mob/living/simple_animal/hostile/hivebot/mega/handle_regular_status_updates() . = ..() - if(!.) - return - - if(!is_on_special_ability_cooldown()) + if(. && !is_on_special_ability_cooldown()) switch_mode(ATTACK_MODE_ROCKET) /mob/living/simple_animal/hostile/hivebot/mega/emp_act(severity) @@ -179,7 +179,7 @@ The megabot var/datum/extension/armor/toggle/armor = get_extension(src, /datum/extension/armor) if(armor) armor.toggle(FALSE) - addtimer(CALLBACK(src, .proc/reactivate), 4 SECONDS) + addtimer(CALLBACK(src, PROC_REF(reactivate)), 4 SECONDS) /mob/living/simple_animal/hostile/hivebot/mega/proc/reactivate() stop_automation = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index ce33e516af2..f654310bced 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -173,7 +173,7 @@ ..(gibbed, deathmessage, show_dead_message) walk(src, 0) -/mob/living/simple_animal/hostile/Life() +/mob/living/simple_animal/hostile/handle_regular_status_updates() . = ..() if(!.) walk(src, 0) @@ -238,7 +238,7 @@ visible_message(SPAN_DANGER("\The [src] [fire_desc] at \the [target]!")) if(rapid) - var/datum/callback/shoot_cb = CALLBACK(src, .proc/shoot_wrapper, target, loc, src) + var/datum/callback/shoot_cb = CALLBACK(src, PROC_REF(shoot_wrapper), target, loc, src) addtimer(shoot_cb, 1) addtimer(shoot_cb, 4) addtimer(shoot_cb, 6) diff --git a/code/modules/mob/living/simple_animal/hostile/leech.dm b/code/modules/mob/living/simple_animal/hostile/leech.dm index c08291fe39d..870cb7fee40 100644 --- a/code/modules/mob/living/simple_animal/hostile/leech.dm +++ b/code/modules/mob/living/simple_animal/hostile/leech.dm @@ -19,15 +19,13 @@ adapt_to_current_level() . = ..() -/mob/living/simple_animal/hostile/leech/Life() +/mob/living/simple_animal/hostile/leech/handle_regular_status_updates() . = ..() - if(!.) - return FALSE - - if(target_mob) - belly -= 3 - else - belly -= 1 + if(.) + if(target_mob) + belly -= 3 + else + belly -= 1 /mob/living/simple_animal/hostile/leech/AttackingTarget() . = ..() @@ -59,7 +57,7 @@ /obj/structure/leech_spawner/LateInitialize() ..() - proxy_listener = new /datum/proximity_trigger/square(src, .proc/burst, .proc/burst, 5) + proxy_listener = new /datum/proximity_trigger/square(src, PROC_REF(burst), PROC_REF(burst), 5) proxy_listener.register_turfs() /obj/structure/leech_spawner/Destroy() diff --git a/code/modules/mob/living/simple_animal/hostile/pike.dm b/code/modules/mob/living/simple_animal/hostile/pike.dm index 21f7410b5f4..b544508f295 100644 --- a/code/modules/mob/living/simple_animal/hostile/pike.dm +++ b/code/modules/mob/living/simple_animal/hostile/pike.dm @@ -26,7 +26,3 @@ /mob/living/simple_animal/hostile/carp/pike/carp_randomify() return - -/mob/living/simple_animal/hostile/carp/pike/on_update_icon() - SHOULD_CALL_PARENT(FALSE) - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index 1d69b2a2c3f..d3b4a42e3f7 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -54,6 +54,9 @@ /decl/material/solid/metal/plasteel = null ) +/mob/living/simple_animal/hostile/retaliate/malf_drone/check_has_mouth() + return FALSE + /mob/living/simple_animal/hostile/retaliate/malf_drone/can_act() return disabled <= 0 && ..() @@ -85,7 +88,10 @@ . -= M //self repair systems have a chance to bring the drone back to life -/mob/living/simple_animal/hostile/retaliate/malf_drone/Life() +/mob/living/simple_animal/hostile/retaliate/malf_drone/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE //emps and lots of damage can temporarily shut us down if(disabled > 0) @@ -148,7 +154,7 @@ if(!disabled && exploding) explosion(get_turf(src), 0, 1, 4, 7) death() - ..() + update_icon() /mob/living/simple_animal/hostile/retaliate/malf_drone/on_update_icon() @@ -202,43 +208,43 @@ if(spawnees & 1) C = new(src.loc) C.SetName("Drone CPU motherboard") - C.origin_tech = "{'[TECH_DATA]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_DATA]":[rand(3, 6)]}' if(spawnees & 2) C = new(src.loc) C.SetName("Drone neural interface") - C.origin_tech = "{'[TECH_BIO]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_BIO]":[rand(3, 6)]}' if(spawnees & 4) C = new(src.loc) C.SetName("Drone suspension processor") - C.origin_tech = "{'[TECH_MAGNET]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_MAGNET]":[rand(3, 6)]}' if(spawnees & 8) C = new(src.loc) C.SetName("Drone shielding controller") - C.origin_tech = "{'wormholes':[rand(3, 6)]}" + C.origin_tech = @'{"wormholes":[rand(3, 6)]}' if(spawnees & 16) C = new(src.loc) C.SetName("Drone power capacitor") - C.origin_tech = "{'[TECH_POWER]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_POWER]":[rand(3, 6)]}' if(spawnees & 32) C = new(src.loc) C.SetName("Drone hull reinforcer") - C.origin_tech = "{'[TECH_MATERIAL]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_MATERIAL]":[rand(3, 6)]}' if(spawnees & 64) C = new(src.loc) C.SetName("Drone auto-repair system") - C.origin_tech = "{'[TECH_ENGINEERING]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_ENGINEERING]":[rand(3, 6)]}' if(spawnees & 128) C = new(src.loc) C.SetName("Drone antigravity overcharge counter") - C.origin_tech = "{'[TECH_EXOTIC_MATTER]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_EXOTIC_MATTER]":[rand(3, 6)]}' if(spawnees & 256) C = new(src.loc) C.SetName("Drone targetting circuitboard") - C.origin_tech = "{'[TECH_COMBAT]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_COMBAT]":[rand(3, 6)]}' if(spawnees & 512) C = new(src.loc) C.SetName("Corrupted drone morality core") - C.origin_tech = "{'[TECH_ESOTERIC]':[rand(3, 6)]}" + C.origin_tech = @'{"[TECH_ESOTERIC]":[rand(3, 6)]}' return ..() /obj/item/projectile/beam/drone diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm index c16c8a17f2e..0901acdfbdd 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm @@ -4,6 +4,9 @@ nutrition = 300 var/list/prey +/mob/living/simple_animal/hostile/retaliate/beast/get_satiated_nutrition() + return 250 + /mob/living/simple_animal/hostile/retaliate/beast/get_max_nutrition() return 300 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm index 3741cbb8e78..a13a98f3103 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm @@ -80,7 +80,7 @@ return if(!victim && can_act() && !is_on_special_ability_cooldown() && Adjacent(H)) - events_repository.register(/decl/observ/destroyed, victim, src, .proc/release_grab) + events_repository.register(/decl/observ/destroyed, victim, src, PROC_REF(release_grab)) victim = H SET_STATUS_MAX(H, STAT_WEAK, grab_duration) SET_STATUS_MAX(H, STAT_STUN, grab_duration) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 23f304d1ad1..017b5fe527f 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -190,14 +190,13 @@ set_scale(1.25) default_pixel_y = 10 -/mob/living/simple_animal/hostile/retaliate/goat/king/phase2/Life() +/mob/living/simple_animal/hostile/retaliate/goat/king/phase2/handle_living_non_stasis_processes() . = ..() if(!.) return FALSE if(special_attacks >= 6 && current_damtype != BRUTE) visible_message(SPAN_MFAUNA("The energy surrounding \the [src]'s horns dissipates.")) current_damtype = BRUTE - if(current_health <= 150 && !phase3 && spellscast == 5) //begin phase 3, reset spell limit and heal phase3_transition() diff --git a/code/modules/mob/living/simple_animal/hostile/slug.dm b/code/modules/mob/living/simple_animal/hostile/slug.dm index fb4f8f4f550..6be1362d635 100644 --- a/code/modules/mob/living/simple_animal/hostile/slug.dm +++ b/code/modules/mob/living/simple_animal/hostile/slug.dm @@ -50,7 +50,7 @@ if(prob(H.getBruteLoss()/2)) attach(H) -/mob/living/simple_animal/hostile/slug/Life() +/mob/living/simple_animal/hostile/slug/handle_regular_status_updates() . = ..() if(. && istype(src.loc, /obj/item/holder) && isliving(src.loc.loc)) //We in somebody var/mob/living/L = src.loc.loc diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index bf3bb61bbcc..b0f1997c402 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -17,6 +17,9 @@ minbodytemp = 0 faction = "carp" +/mob/living/simple_animal/hostile/tree/check_has_mouth() + return FALSE + /mob/living/simple_animal/hostile/tree/FindTarget() . = ..() if(.) diff --git a/code/modules/mob/living/simple_animal/hostile/vagrant.dm b/code/modules/mob/living/simple_animal/hostile/vagrant.dm index fc6a43e1380..1be42c481b2 100644 --- a/code/modules/mob/living/simple_animal/hostile/vagrant.dm +++ b/code/modules/mob/living/simple_animal/hostile/vagrant.dm @@ -42,7 +42,7 @@ if(stat == DEAD && !QDELETED(src) && !gibbed) gib() -/mob/living/simple_animal/hostile/vagrant/Life() +/mob/living/simple_animal/hostile/vagrant/handle_living_non_stasis_processes() . = ..() if(!.) return FALSE @@ -56,7 +56,7 @@ gripping.vessel.remove_any(blood_per_tick) heal_overall_damage(health_per_tick) if(prob(15)) - to_chat(gripping, "You feel your fluids being drained!") + to_chat(gripping, SPAN_DANGER("You feel your fluids being drained!")) else gripping = null @@ -74,16 +74,17 @@ /mob/living/simple_animal/hostile/vagrant/on_update_icon() ..() - if(cloaked) //It's fun time - alpha = 75 - set_light(0) - icon_state = initial(icon_state) - move_to_delay = initial(move_to_delay) - else //It's fight time - alpha = 255 - icon_state += "-glowing" - set_light(3, 0.2) - move_to_delay = 2 + if(stat == CONSCIOUS) + if(cloaked) //It's fun time + alpha = 75 + set_light(0) + icon_state = initial(icon_state) + move_to_delay = initial(move_to_delay) + else //It's fight time + alpha = 255 + icon_state += "-glowing" + set_light(3, 0.2) + move_to_delay = 2 /mob/living/simple_animal/hostile/vagrant/AttackingTarget() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/viscerator.dm b/code/modules/mob/living/simple_animal/hostile/viscerator.dm index c9a4ec321a8..fa5f60048ab 100644 --- a/code/modules/mob/living/simple_animal/hostile/viscerator.dm +++ b/code/modules/mob/living/simple_animal/hostile/viscerator.dm @@ -27,6 +27,9 @@ edge = 1 sharp = 1 +/mob/living/simple_animal/hostile/viscerator/check_has_mouth() + return FALSE + /mob/living/simple_animal/hostile/viscerator/death(gibbed, deathmessage, show_dead_message) ..(null, "is smashed into pieces!", show_dead_message) qdel(src) diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index badc97a032b..10742fec191 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -33,6 +33,9 @@ skin_material = null skin_amount = 0 +/mob/living/simple_animal/shade/check_has_mouth() + return FALSE + /obj/item/natural_weapon/shade name = "foul touch" attack_verb = list("drained") @@ -42,13 +45,7 @@ /mob/living/simple_animal/shade/on_defilement() return -/mob/living/simple_animal/shade/Life() - . = ..() - OnDeathInLife() - -/mob/living/simple_animal/shade/proc/OnDeathInLife() - if(stat == DEAD) - new /obj/item/ectoplasm (src.loc) - visible_message(SPAN_WARNING("\The [src] lets out a contented sigh as their form unwinds.")) - ghostize() - qdel(src) +/mob/living/simple_animal/shade/death(gibbed, deathmessage, show_dead_message) + new /obj/item/ectoplasm (src.loc) + ..(deathmessage = "lets out a contented sigh as their form unwinds", show_dead_message = "You have been released from your earthly binds.") + qdel(src) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index bfdf356b4bd..c0dcb6ffb1f 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -174,38 +174,28 @@ var/global/list/simplemob_icon_bitflag_cache = list() QDEL_NULL(natural_weapon) . = ..() -/mob/living/simple_animal/Life() - if(is_aquatic && !submerged() && stat != DEAD) - walk(src, 0) - if(!HAS_STATUS(src, STAT_PARA)) // gated to avoid redundant update_icon() calls. - SET_STATUS_MAX(src, STAT_PARA, 3) - update_icon() +/mob/living/simple_animal/handle_regular_status_updates() + if(purge) + purge -= 1 . = ..() - if(!.) - return FALSE - if(z && !living_observers_present(SSmapping.get_connected_levels(z))) - return - //Health - if(stat == DEAD) - if(current_health > 0) - switch_from_dead_to_living_mob_list() - set_stat(CONSCIOUS) - set_density(1) - update_icon() - return 0 - - handle_atmos() - handle_supernatural() - handle_impaired_vision() - - if(can_bleed && bleed_ticks > 0) - handle_bleeding() - - delayed_life_action() - return 1 + if(.) + if(can_bleed && bleed_ticks > 0) + handle_bleeding() + if(is_aquatic && !submerged()) + walk(src, 0) + if(HAS_STATUS(src, STAT_PARA)) + SET_STATUS_MAX(src, STAT_PARA, 3) + update_icon() + +/mob/living/simple_animal/handle_some_updates() + . = ..() && (!z || living_observers_present(SSmapping.get_connected_levels(z))) + +/mob/living/simple_animal/handle_legacy_ai() + . = ..() + handle_async_life_action() // Handles timed stuff in Life() -/mob/living/simple_animal/proc/delayed_life_action() +/mob/living/simple_animal/proc/handle_async_life_action() set waitfor = FALSE if(performing_delayed_life_action) return @@ -255,12 +245,9 @@ var/global/list/simplemob_icon_bitflag_cache = list() if("emote_see") visible_emote("[pick(emote_see)].") -/mob/living/simple_animal/proc/handle_atmos(var/atmos_suitable = 1) - //Atmos - if(!loc) - return - - var/datum/gas_mixture/environment = loc.return_air() +/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment) + . = ..() + var/atmos_suitable = TRUE if(environment) // don't bother checking it twice if we got a supplied FALSE val. if(atmos_suitable) @@ -296,10 +283,6 @@ var/global/list/simplemob_icon_bitflag_cache = list() O.unbuckle_mob(M) visible_message(SPAN_DANGER("\The [M] escapes from \the [O]!")) -/mob/living/simple_animal/proc/handle_supernatural() - if(purge) - purge -= 1 - /mob/living/simple_animal/gib() ..(((mob_icon_state_flags & MOB_ICON_HAS_GIB_STATE) ? "world-gib" : null), TRUE) @@ -366,6 +349,7 @@ var/global/list/simplemob_icon_bitflag_cache = list() return TRUE /mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/stack/medical)) if(stat != DEAD) var/obj/item/stack/medical/MED = O @@ -380,33 +364,23 @@ var/global/list/simplemob_icon_bitflag_cache = list() to_chat(user, SPAN_WARNING("\The [src] is dead, medical items won't bring [G.him] back to life.")) return TRUE - if(istype(O, /obj/item/flash) && stat != DEAD) - return O.attack(src, user, user.get_target_zone()) - - if(meat_type && (stat == DEAD) && meat_amount) - if(istype(O, /obj/item/knife/kitchen/cleaver)) - var/victim_turf = get_turf(src) - if(!locate(/obj/structure/table, victim_turf)) - to_chat(user, SPAN_WARNING("You need to place \the [src] on a table to butcher it.")) - return TRUE - var/time_to_butcher = (mob_size) - to_chat(user, SPAN_WARNING("You begin harvesting \the [src].")) - if(do_after(user, time_to_butcher, src, same_direction = TRUE)) - if(prob(user.skill_fail_chance(SKILL_COOKING, 60, SKILL_ADEPT))) - to_chat(user, SPAN_DANGER("You botch harvesting \the [src], and ruin some of the meat in the process.")) - subtract_meat(user) - else - harvest(user, user.get_skill_value(SKILL_COOKING)) - else - to_chat(user, SPAN_DANGER("Your hand slips with your movement, and some of the meat is ruined.")) - subtract_meat(user) - return TRUE - - else - if(!O.force || (O.item_flags & ITEM_FLAG_NO_BLUDGEON)) - visible_message(SPAN_NOTICE("\The [user] gently taps [src] with \the [O].")) + if(meat_type && (stat == DEAD) && meat_amount && istype(O, /obj/item/knife/kitchen/cleaver)) + var/victim_turf = get_turf(src) + if(!locate(/obj/structure/table, victim_turf)) + to_chat(user, SPAN_WARNING("You need to place \the [src] on a table to butcher it.")) return TRUE - return O.attack(src, user, user.get_target_zone() || ran_zone()) + var/time_to_butcher = (mob_size) + to_chat(user, SPAN_WARNING("You begin harvesting \the [src].")) + if(do_after(user, time_to_butcher, src, same_direction = TRUE)) + if(prob(user.skill_fail_chance(SKILL_COOKING, 60, SKILL_ADEPT))) + to_chat(user, SPAN_DANGER("You botch harvesting \the [src], and ruin some of the meat in the process.")) + subtract_meat(user) + else + harvest(user, user.get_skill_value(SKILL_COOKING)) + else + to_chat(user, SPAN_DANGER("Your hand slips with your movement, and some of the meat is ruined.")) + subtract_meat(user) + return TRUE return ..() @@ -441,7 +415,7 @@ var/global/list/simplemob_icon_bitflag_cache = list() tally = 1 tally *= purge - return tally+config.animal_delay + return tally+get_config_value(/decl/config/num/movement_animal) /mob/living/simple_animal/Stat() . = ..() @@ -453,7 +427,7 @@ var/global/list/simplemob_icon_bitflag_cache = list() density = FALSE adjustBruteLoss(get_max_health()) //Make sure dey dead. walk_to(src,0) - . = ..(gibbed,deathmessage,show_dead_message) + . = ..(gibbed, deathmessage, show_dead_message) /mob/living/simple_animal/explosion_act(severity) ..() @@ -509,20 +483,6 @@ var/global/list/simplemob_icon_bitflag_cache = list() if(meat_amount <= 0) to_chat(user, SPAN_NOTICE("\The [src] carcass is ruined beyond use.")) -/mob/living/simple_animal/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone) - ..() - switch(get_bullet_impact_effect_type(def_zone)) - if(BULLET_IMPACT_MEAT) - if(P.damtype == BRUTE) - var/hit_dir = get_dir(P.starting, src) - var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir) - if(!QDELETED(B)) - B.icon_state = pick("dir_splatter_1","dir_splatter_2") - B.basecolor = bleed_colour - var/scale = min(1, round(mob_size / MOB_SIZE_MEDIUM, 0.1)) - B.set_scale(scale) - B.update_icon() - /mob/living/simple_animal/handle_fire() return @@ -671,3 +631,6 @@ var/global/list/simplemob_icon_bitflag_cache = list() /mob/living/simple_animal/proc/get_melee_accuracy() return clamp(sa_accuracy - melee_accuracy_mods(), 0, 100) + +/mob/living/simple_animal/check_has_mouth() + return TRUE diff --git a/code/modules/mob/living/stasis.dm b/code/modules/mob/living/stasis.dm index 0876ba90ca8..76fda177df5 100644 --- a/code/modules/mob/living/stasis.dm +++ b/code/modules/mob/living/stasis.dm @@ -16,6 +16,11 @@ stasis_value += stasis_sources[source] stasis_sources = null + if(stasis_value > 1 && GET_STATUS(src, STAT_DROWSY) < stasis_value * 4) + ADJ_STATUS(src, STAT_DROWSY, min(stasis_value, 3)) + if(stat == CONSCIOUS && prob(1)) + to_chat(src, SPAN_NOTICE("You feel slow and sluggish...")) + /mob/living/proc/get_cryogenic_factor(var/bodytemperature) if(isSynthetic()) diff --git a/code/modules/mob/living/stress.dm b/code/modules/mob/living/stress.dm index b67360e26bc..2cb46e0c27b 100644 --- a/code/modules/mob/living/stress.dm +++ b/code/modules/mob/living/stress.dm @@ -1,7 +1,7 @@ #define GET_STRESSOR(S) (istype(S, /datum/stressor) ? S : SSmanaged_instances.get(S, cache_category = /datum/stressor)) /mob/living/proc/get_stress_modifier() - if(!config.adjust_healing_from_stress) + if(!get_config_value(/decl/config/toggle/health_adjust_healing_from_stress)) return 0 return stress diff --git a/code/modules/mob/living/update_icon.dm b/code/modules/mob/living/update_icon.dm deleted file mode 100644 index 29b58f6e0f5..00000000000 --- a/code/modules/mob/living/update_icon.dm +++ /dev/null @@ -1,38 +0,0 @@ -/mob/living - var/list/mob_overlays[TOTAL_OVER_LAYERS] - var/list/mob_underlays[TOTAL_UNDER_LAYERS] - -/mob/living/update_icon() - ..() - compile_overlays() - -/mob/living/on_update_icon() - SHOULD_CALL_PARENT(TRUE) - ..() - cut_overlays() - if(auras) - for(var/obj/aura/aura as anything in auras) - var/image/A = new() - A.appearance = aura - add_overlay(A) - try_refresh_visible_overlays() - -/mob/living/get_all_current_mob_overlays() - return mob_overlays - -/mob/living/set_current_mob_overlay(var/overlay_layer, var/image/overlay, var/redraw_mob = TRUE) - mob_overlays[overlay_layer] = overlay - ..() - -/mob/living/get_current_mob_overlay(var/overlay_layer) - return mob_overlays[overlay_layer] - -/mob/living/get_all_current_mob_underlays() - return mob_underlays - -/mob/living/set_current_mob_underlay(var/underlay_layer, var/image/underlay, var/redraw_mob = TRUE) - mob_underlays[underlay_layer] = underlay - ..() - -/mob/living/get_current_mob_underlay(var/underlay_layer) - return mob_underlays[underlay_layer] diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 790b2ee8eb7..9f367883a5e 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -5,7 +5,7 @@ computer_id = client.computer_id last_ckey = ckey log_access("Login: [key_name(src)] from [lastKnownIP ? lastKnownIP : "localhost"]-[computer_id] || BYOND v[client.byond_version]") - if(config.log_access) + if(get_config_value(/decl/config/toggle/log_access)) var/is_multikeying = 0 for(var/mob/M in global.player_list) if(M == src) continue @@ -29,7 +29,8 @@ spawn(1 SECOND) to_chat(src, "WARNING: It would seem that you are sharing connection or computer with another player. If you haven't done so already, please contact the staff via the Adminhelp verb to resolve this situation. Failure to do so may result in administrative action. You have been warned.") - if(config.login_export_addr) + var/login_export_addr = get_config_value(/decl/config/text/login_export_addr) + if(login_export_addr) spawn(-1) var/list/params = new params["login"] = 1 @@ -40,7 +41,7 @@ params["clientid"] = client.computer_id params["roundid"] = game_id params["name"] = real_name || name - world.Export("[config.login_export_addr]?[list2params(params)]", null, 1) + world.Export("[login_export_addr]?[list2params(params)]", null, 1) /mob/proc/maybe_send_staffwarns(var/action) if(client.staffwarn) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0eb915d88ca..29e1333032a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -403,7 +403,7 @@ face_atom(A) - if(!isghost(src) && config.visible_examine) + if(!isghost(src) && get_config_value(/decl/config/toggle/visible_examine)) if((A.loc != src || (A in get_held_items()))) var/look_target = "at \the [A]" if(isobj(A.loc)) @@ -552,6 +552,9 @@ return TOPIC_HANDLED // If usr != src, or if usr == src but the Topic call was not resolved, this is called next. +/mob/proc/get_comments_record() + return + /mob/OnTopic(mob/user, href_list, datum/topic_state/state) if(href_list["refresh"]) @@ -567,6 +570,14 @@ var/datum/browser/popup = new(user, ckey(name), name, 500, 200) var/list/html = list("

    Appearance

    ") html += replacetext(flavor_text, "\n", "
    ") + var/datum/character_information/comments = get_comments_record() + if(comments) + if(comments.ic_info) + html += "

    IC Information

    " + html += "[comments.ic_info]
    " + if(comments.ooc_info) + html += "

    OOC Information

    " + html += "[comments.ooc_info]
    " popup.set_content(jointext(html, null)) popup.open() return TOPIC_HANDLED @@ -704,10 +715,9 @@ return 0 //Updates lying and icons -/mob/proc/UpdateLyingBuckledAndVerbStatus() - var/last_lying = lying +/mob/proc/update_lying() if(!resting && cannot_stand() && can_stand_overridden()) - lying = 0 + lying = FALSE else if(buckled) anchored = TRUE if(istype(buckled)) @@ -720,12 +730,16 @@ else lying = incapacitated(INCAPACITATION_KNOCKDOWN) +/mob/proc/UpdateLyingBuckledAndVerbStatus() + var/last_lying = lying + update_lying() + if(buckled) + anchored = (!istype(buckled) || !buckled.buckle_movable) if(lying) set_density(0) drop_held_items() else set_density(initial(density)) - reset_layer() //Temporarily moved here from the various life() procs @@ -780,7 +794,12 @@ return /mob/proc/get_species_name() - return "" + SHOULD_CALL_PARENT(TRUE) + return "Unknown" + +/mob/living/get_species_name() + var/decl/species/my_species = get_species() + return my_species?.name || ..() /mob/proc/get_visible_implants(var/class = 0) var/list/visible_implants = list() @@ -1081,10 +1100,12 @@ // Work out if we have any brain damage impacting our dexterity. var/dex_malus = 0 - if(getBrainLoss() && getBrainLoss() > config.dex_malus_brainloss_threshold) ///brainloss shouldn't instantly cripple you, so the effects only start once past the threshold and escalate from there. - dex_malus = clamp(CEILING((getBrainLoss()-config.dex_malus_brainloss_threshold)/10), 0, length(global.dexterity_levels)) - if(dex_malus > 0) - dex_malus = global.dexterity_levels[dex_malus] + if(getBrainLoss()) + var/brainloss_threshold = get_config_value(/decl/config/num/dex_malus_brainloss_threshold) + if(getBrainLoss() > brainloss_threshold) ///brainloss shouldn't instantly cripple you, so the effects only start once past the threshold and escalate from there. + dex_malus = clamp(CEILING((getBrainLoss()-brainloss_threshold)/10), 0, length(global.dexterity_levels)) + if(dex_malus > 0) + dex_malus = global.dexterity_levels[dex_malus] // If this slot does not need an organ we just go off the dexterity of the slot itself. if(isnull(gripper.requires_organ_tag)) @@ -1131,9 +1152,12 @@ to_chat(src, SPAN_WARNING("You scrawl down some meaningless lines.")) . = stars(text_content, 5) -// mobs do not have mouths by default +// mobs do not have mouths by default, unless provided by an organ /mob/proc/check_has_mouth() - return FALSE + var/obj/item/organ/external/head/H = get_organ(BP_HEAD, /obj/item/organ/external/head) + if(!H || !istype(H) || !H.can_intake_reagents) + return FALSE + return TRUE /mob/proc/check_has_eyes() return TRUE @@ -1350,10 +1374,10 @@ /mob/verb/whisper_wrapper() set name = ".Whisper" set hidden = TRUE - if(config.show_typing_indicator_for_whispers) + if(get_config_value(/decl/config/toggle/show_typing_indicator_for_whispers)) SStyping.set_indicator_state(client, TRUE) var/message = input("","me (text)") as text|null - if(config.show_typing_indicator_for_whispers) + if(get_config_value(/decl/config/toggle/show_typing_indicator_for_whispers)) SStyping.set_indicator_state(client, FALSE) if (message) whisper(message) diff --git a/code/modules/mob/mob_blood.dm b/code/modules/mob/mob_blood.dm new file mode 100644 index 00000000000..057b4578b1c --- /dev/null +++ b/code/modules/mob/mob_blood.dm @@ -0,0 +1,30 @@ +/mob/proc/get_flesh_color() + return get_species()?.get_species_flesh_color(src) || COLOR_GRAY + +/mob/proc/get_gibber_type() + return /obj/effect/gibspawner/generic + +/mob/proc/get_blood_color() + return get_species()?.get_species_blood_color(src) || COLOR_BLOOD_HUMAN + +/mob/proc/get_blood_oxy() + var/decl/species/my_species = get_species() + return my_species ? my_species.blood_oxy : TRUE + +//Gets blood from mob to the container, preserving all data in it. +/mob/proc/take_blood(obj/item/chems/container, var/amount) + var/decl/species/my_species = get_species() + if(my_species?.blood_reagent) + container.add_to_reagents(my_species.blood_reagent, amount, get_blood_data()) + return TRUE + return FALSE + +/mob/proc/get_blood_data() + var/data = list() + data["donor"] = weakref(src) + return data + +/mob/proc/gibs(atom/location = loc) + var/gibber_type = get_gibber_type() + if(gibber_type) + return new gibber_type(location, get_blood_type(), get_unique_enzymes(), get_flesh_color(), get_blood_color()) diff --git a/code/modules/mob/mob_eating.dm b/code/modules/mob/mob_eating.dm new file mode 100644 index 00000000000..17155f71569 --- /dev/null +++ b/code/modules/mob/mob_eating.dm @@ -0,0 +1,12 @@ +// mobs do not have blocked mouths by default +// overridden in human_defense.dm +/mob/proc/check_mouth_coverage() + return null + +/mob/proc/get_eaten_transfer_amount(var/default) + . = default + if(issmall(src)) + . = CEILING(.*0.5) + +/mob/proc/can_eat_food_currently(obj/eating, mob/user) + return TRUE diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index f9f04a6e329..e4f273ad596 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -50,7 +50,7 @@ var/global/list/href_to_mob_type = list( //This proc is the most basic of the procs. All it does is make a new mob on the same tile and transfer over a few variables. //Returns the new mob -//Note that this proc does NOT do MMI related stuff! +//Note that this proc does NOT do brain related stuff! /mob/proc/change_mob_type(var/new_type, var/turf/location, var/new_name, var/subspecies) if(!new_type) diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 54bd8e68b81..6951ec383e3 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -46,5 +46,5 @@ // bolds the changelog button on the interface so we know there are updates. if(client.prefs?.lastchangelog != global.changelog_hash) to_chat(client, SPAN_NOTICE("You have unread updates in the changelog.")) - if(config.aggressive_changelog) + if(get_config_value(/decl/config/toggle/aggressive_changelog)) client.changes() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index b06146e9140..93be478e46f 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -108,7 +108,8 @@ INITIALIZE_IMMEDIATE(/mob/new_player) to_chat(src, SPAN_WARNING("Please wait for server initialization to complete...")) return - if(!config.respawn_delay || client.holder || alert(src,"Are you sure you wish to observe? You will have to wait [config.respawn_delay] minute\s before being able to respawn!","Player Setup","Yes","No") == "Yes") + var/respawn_delay = get_config_value(/decl/config/num/respawn_delay) + if(!respawn_delay || client.holder || alert(src,"Are you sure you wish to observe? You will have to wait [respawn_delay] minute\s before being able to respawn!","Player Setup","Yes","No") == "Yes") if(!client) return 1 var/mob/observer/ghost/observer = new() @@ -138,7 +139,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) client.prefs.real_name = client.prefs.get_random_name() observer.real_name = client.prefs.real_name observer.SetName(observer.real_name) - if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + if(!client.holder && !get_config_value(/decl/config/toggle/antag_hud_allowed)) // For new ghosts we remove the verb from even showing up if it's not allowed. observer.verbs -= /mob/observer/ghost/verb/toggle_antagHUD // Poor guys, don't know what they are missing! observer.key = key qdel(src) @@ -183,7 +184,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) to_chat(usr, "The round is either not ready, or has already finished...") return 0 - if(!config.enter_allowed) + if(!get_config_value(/decl/config/toggle/on/enter_allowed)) to_chat(usr, "There is an administrative lock on entering the game!") return 0 @@ -429,6 +430,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) return 1 /mob/new_player/get_species_name() + SHOULD_CALL_PARENT(FALSE) var/decl/species/chosen_species if(client.prefs.species) chosen_species = get_species_by_key(client.prefs.species) @@ -442,7 +444,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) /mob/new_player/hear_say(var/message, var/verb = "says", var/decl/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null) return -/mob/new_player/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname, var/vsource) +/mob/new_player/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="", var/vsource) return /mob/new_player/show_message(msg, type, alt, alt_type) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index c9adcbb336b..5445b9c23dc 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -104,6 +104,7 @@ if(update_icon) mannequin.update_icon() + mannequin.compile_overlays() /datum/preferences/proc/update_preview_icon() var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin(client_ckey) diff --git a/code/modules/mob/observer/eye/blueprints_eye.dm b/code/modules/mob/observer/eye/blueprints_eye.dm index c868ed59ee8..7742f8f2c6b 100644 --- a/code/modules/mob/observer/eye/blueprints_eye.dm +++ b/code/modules/mob/observer/eye/blueprints_eye.dm @@ -325,7 +325,7 @@ var/datum/shuttle/our_shuttle = SSshuttle.shuttles[shuttle_name] our_shuttle.shuttle_area += A SSshuttle.shuttle_areas += A - events_repository.register(/decl/observ/destroyed, A, our_shuttle, /datum/shuttle/proc/remove_shuttle_area) + events_repository.register(/decl/observ/destroyed, A, our_shuttle, TYPE_PROC_REF(/datum/shuttle, remove_shuttle_area)) return A #undef MAX_AREA_SIZE \ No newline at end of file diff --git a/code/modules/mob/observer/eye/freelook/life.dm b/code/modules/mob/observer/eye/freelook/life.dm index 98b9c477e1f..6a8a6975fd7 100644 --- a/code/modules/mob/observer/eye/freelook/life.dm +++ b/code/modules/mob/observer/eye/freelook/life.dm @@ -1,7 +1,7 @@ /mob/observer/eye/freelook/Life() - ..() + . = ..() // If we lost our client, reset the list of visible chunks so they update properly on return - if(owner == src && !client) + if(. && owner == src && !client) visibleChunks.Cut() /*else if(owner && !owner.client) visibleChunks.Cut()*/ diff --git a/code/modules/mob/observer/eye/freelook/visualnet.dm b/code/modules/mob/observer/eye/freelook/visualnet.dm index f49d0c0fe96..0274a87565d 100644 --- a/code/modules/mob/observer/eye/freelook/visualnet.dm +++ b/code/modules/mob/observer/eye/freelook/visualnet.dm @@ -109,7 +109,7 @@ // Never access this proc directly!!!! // This will update the chunk and all the surrounding chunks. /datum/visualnet/proc/major_chunk_change(var/atom/source) - for_all_chunks_in_range(source, /datum/chunk/proc/visibility_changed, list()) + for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, visibility_changed), list()) /datum/visualnet/proc/add_source(var/atom/source, var/update_visibility = TRUE, var/opacity_check = FALSE) if(!(source && is_valid_source(source))) @@ -118,9 +118,9 @@ if(source in sources) return FALSE sources += source - events_repository.register(/decl/observ/moved, source, src, /datum/visualnet/proc/source_moved) - events_repository.register(/decl/observ/destroyed, source, src, /datum/visualnet/proc/remove_source) - for_all_chunks_in_range(source, /datum/chunk/proc/add_source, list(source)) + events_repository.register(/decl/observ/moved, source, src, TYPE_PROC_REF(/datum/visualnet, source_moved)) + events_repository.register(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/datum/visualnet, remove_source)) + for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, add_source), list(source)) if(update_visibility) update_visibility(source, opacity_check) return TRUE @@ -129,9 +129,9 @@ if(!sources.Remove(source)) return FALSE - events_repository.unregister(/decl/observ/moved, source, src, /datum/visualnet/proc/source_moved) - events_repository.unregister(/decl/observ/destroyed, source, src, /datum/visualnet/proc/remove_source) - for_all_chunks_in_range(source, /datum/chunk/proc/remove_source, list(source)) + events_repository.unregister(/decl/observ/moved, source, src, TYPE_PROC_REF(/datum/visualnet, source_moved)) + events_repository.unregister(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/datum/visualnet, remove_source)) + for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, remove_source), list(source)) if(update_visibility) update_visibility(source, opacity_check) return TRUE @@ -150,9 +150,9 @@ // A more proper way would be to figure out which chunks have gone out of range, and which have come into range // and only remove/add to those. if(old_turf) - for_all_chunks_in_range(source, /datum/chunk/proc/remove_source, list(source), old_turf) + for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, remove_source), list(source), old_turf) if(new_turf) - for_all_chunks_in_range(source, /datum/chunk/proc/add_source, list(source), new_turf) + for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, add_source), list(source), new_turf) /datum/visualnet/proc/for_all_chunks_in_range(var/atom/source, var/proc_call, var/list/proc_args, var/turf/T) T = T ? T : get_turf(source) diff --git a/code/modules/mob/observer/ghost/ghost.dm b/code/modules/mob/observer/ghost/ghost.dm index b436aaeffe6..0b34a129d40 100644 --- a/code/modules/mob/observer/ghost/ghost.dm +++ b/code/modules/mob/observer/ghost/ghost.dm @@ -108,9 +108,10 @@ Works together with spawning an observer, noted above. */ /mob/observer/ghost/Life() - ..() - if(!loc) return - if(!client) return 0 + + . = ..() + if(!. || !loc || !client) + return FALSE handle_hud_glasses() @@ -150,7 +151,7 @@ Works together with spawning an observer, noted above. ghost.can_reenter_corpse = can_reenter_corpse ghost.timeofdeath = src.stat == DEAD ? src.timeofdeath : world.time ghost.key = key - if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + if(ghost.client && !ghost.client.holder && !get_config_value(/decl/config/toggle/antag_hud_allowed)) // For new ghosts we remove the verb from even showing up if it's not allowed. ghost.verbs -= /mob/observer/ghost/verb/toggle_antagHUD // Poor guys, don't know what they are missing! return ghost @@ -167,6 +168,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(stat == DEAD) announce_ghost_joinleave(ghostize(1)) else + var/respawn_delay = get_config_value(/decl/config/num/respawn_delay) var/response if(src.client && src.client.holder) response = alert(src, "You have the ability to Admin-Ghost. The regular Ghost verb will announce your presence to dead chat. Both variants will allow you to return to your body using 'aghost'.\n\nWhat do you wish to do?", "Are you sure you want to ghost?", "Ghost", "Admin Ghost", "Stay in body") @@ -174,8 +176,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!src.client) return src.client.admin_ghost() - else if(config.respawn_delay) - response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another [config.respawn_delay] minute\s! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body") + else if(respawn_delay) + response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another [respawn_delay] minute\s! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body") else response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to return to this body! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body") if(response != "Ghost") @@ -237,14 +239,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!client) return - if(!config.antag_hud_allowed && !client.holder) + if(!get_config_value(/decl/config/toggle/antag_hud_allowed) && !client.holder) to_chat(src, SPAN_WARNING("Admins have disabled this for this round")) return var/mob/observer/ghost/M = src if(jobban_isbanned(M, "AntagHUD")) to_chat(src, SPAN_WARNING("You have been banned from using this feature.")) return - if(config.antag_hud_restricted && !M.has_enabled_antagHUD && !client.holder) + if(get_config_value(/decl/config/toggle/antag_hud_restricted) && !M.has_enabled_antagHUD && !client.holder) var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No") if(response == "No") return M.can_reenter_corpse = 0 @@ -307,9 +309,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp stop_following() following = target verbs |= /mob/observer/ghost/proc/scan_target - events_repository.register(/decl/observ/moved, following, src, /atom/movable/proc/move_to_turf) - events_repository.register(/decl/observ/dir_set, following, src, /atom/proc/recursive_dir_set) - events_repository.register(/decl/observ/destroyed, following, src, /mob/observer/ghost/proc/stop_following) + events_repository.register(/decl/observ/moved, following, src, TYPE_PROC_REF(/atom/movable, move_to_turf)) + events_repository.register(/decl/observ/dir_set, following, src, TYPE_PROC_REF(/atom, recursive_dir_set)) + events_repository.register(/decl/observ/destroyed, following, src, TYPE_PROC_REF(/mob/observer/ghost, stop_following)) to_chat(src, "Now following \the [following].") move_to_turf(following, loc, following.loc) @@ -372,7 +374,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Become mouse" set category = "Ghost" - if(config.disable_player_mice) + if(get_config_value(/decl/config/toggle/disable_player_mice)) to_chat(src, "Spawning as a mouse is currently disabled.") return @@ -401,7 +403,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp else to_chat(src, "Unable to find any unwelded vents to spawn mice at.") if(host) - if(config.uneducated_mice) + if(get_config_value(/decl/config/toggle/uneducated_mice)) host.universal_understand = FALSE announce_ghost_joinleave(src, 0, "They are now a mouse.") host.ckey = src.ckey @@ -436,7 +438,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return ..() /mob/observer/ghost/proc/try_possession(var/mob/living/M) - if(!config.ghosts_can_possess_animals) + if(!get_config_value(/decl/config/toggle/ghosts_can_possess_animals)) to_chat(src, SPAN_WARNING("Ghosts are not permitted to possess animals.")) return FALSE if(!M.can_be_possessed_by(src)) @@ -527,7 +529,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(feedback) to_chat(src, "Your non-dead body prevents you from respawning.") return 0 - if(config.antag_hud_restricted && has_enabled_antagHUD == 1) + if(get_config_value(/decl/config/toggle/antag_hud_restricted) && has_enabled_antagHUD == 1) if(feedback) to_chat(src, "antagHUD restrictions prevent you from respawning.") return 0 @@ -584,7 +586,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Respawn" set category = "OOC" - if (!(config.abandon_allowed)) + if (!get_config_value(/decl/config/toggle/on/abandon_allowed)) to_chat(usr, SPAN_WARNING("Respawn is disabled.")) return if (!SSticker.mode) @@ -593,7 +595,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if (SSticker.mode.deny_respawn) to_chat(usr, SPAN_WARNING("Respawn is disabled for this roundtype.")) return - else if(!MayRespawn(1, config.respawn_delay)) + else if(!MayRespawn(1, get_config_value(/decl/config/num/respawn_delay))) return to_chat(usr, SPAN_NOTICE("You can respawn now, enjoy your new life!")) diff --git a/code/modules/mob/observer/virtual/base.dm b/code/modules/mob/observer/virtual/base.dm index 0fecb711fde..c4897378242 100644 --- a/code/modules/mob/observer/virtual/base.dm +++ b/code/modules/mob/observer/virtual/base.dm @@ -23,7 +23,7 @@ var/global/list/all_virtual_listeners = list() . = INITIALIZE_HINT_QDEL CRASH("Received an unexpected host type. Expected [host_type], was [log_info_line(host)].") src.host = host - events_repository.register(/decl/observ/moved, host, src, /atom/movable/proc/move_to_turf_or_null) + events_repository.register(/decl/observ/moved, host, src, TYPE_PROC_REF(/atom/movable, move_to_turf_or_null)) all_virtual_listeners += src @@ -31,7 +31,7 @@ var/global/list/all_virtual_listeners = list() STOP_PROCESSING(SSmobs, src) /mob/observer/virtual/Destroy() - events_repository.unregister(/decl/observ/moved, host, src, /atom/movable/proc/move_to_turf_or_null) + events_repository.unregister(/decl/observ/moved, host, src, TYPE_PROC_REF(/atom/movable, move_to_turf_or_null)) all_virtual_listeners -= src host = null return ..() diff --git a/code/modules/mob/observer/virtual/mob.dm b/code/modules/mob/observer/virtual/mob.dm index eb08a07d3b8..02026201066 100644 --- a/code/modules/mob/observer/virtual/mob.dm +++ b/code/modules/mob/observer/virtual/mob.dm @@ -4,16 +4,16 @@ /mob/observer/virtual/mob/Initialize(mapload, var/mob/host) . = ..() - events_repository.register(/decl/observ/sight_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) - events_repository.register(/decl/observ/see_invisible_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) - events_repository.register(/decl/observ/see_in_dark_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) + events_repository.register(/decl/observ/sight_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) + events_repository.register(/decl/observ/see_invisible_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) + events_repository.register(/decl/observ/see_in_dark_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) sync_sight(host) /mob/observer/virtual/mob/Destroy() - events_repository.unregister(/decl/observ/sight_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) - events_repository.unregister(/decl/observ/see_invisible_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) - events_repository.unregister(/decl/observ/see_in_dark_set, host, src, /mob/observer/virtual/mob/proc/sync_sight) + events_repository.unregister(/decl/observ/sight_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) + events_repository.unregister(/decl/observ/see_invisible_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) + events_repository.unregister(/decl/observ/see_in_dark_set, host, src, TYPE_PROC_REF(/mob/observer/virtual/mob, sync_sight)) . = ..() /mob/observer/virtual/mob/proc/sync_sight(var/mob/mob_host) diff --git a/code/modules/mob/skills/skill.dm b/code/modules/mob/skills/skill.dm index 0e2ff1d48b5..e710f0b40c8 100644 --- a/code/modules/mob/skills/skill.dm +++ b/code/modules/mob/skills/skill.dm @@ -334,7 +334,7 @@ var/global/list/skills = list() levels = list( "Unskilled" = "You know how to use the technology that was present in whatever society you grew up in. You know how to tell when something is malfunctioning, but you have to call tech support to get it fixed.", "Basic" = "You use and repair high-tech equipment in the course of your daily work. You can fix simple problems, and you know how to use a circuit printer or autolathe. You can build simple robots such as cleanbots and medibots.", - "Trained" = "You can build or repair an exosuit or cyborg chassis, use advanced fabricators and analyzers, and build prosthetic limbs. You can safely transfer an MMI or posibrain into a cyborg chassis.
    - You can attach robotic limbs. Its speed increases with level.", + "Trained" = "You can build or repair an exosuit or cyborg chassis, use advanced fabricators and analyzers, and build prosthetic limbs. You can safely transfer a neural interface into a cyborg chassis.
    - You can attach robotic limbs. Its speed increases with level.", "Experienced" = "You have years of experience building or reverse-engineering complex devices. Your use of fabricators and destructive analyzers is efficient and methodical. You can design contraptions to order, and likely sell those designs at a profit.", "Master" = "You are an inventor or researcher. You can design, build, and modify equipment that most people don't even know exists. You are at home in the lab and the workshop and you've never met a gadget you couldn't take apart, put back together, and replicate." ) diff --git a/code/modules/mob/skills/skill_buffs.dm b/code/modules/mob/skills/skill_buffs.dm index 18f538055c3..bf99aa37ed7 100644 --- a/code/modules/mob/skills/skill_buffs.dm +++ b/code/modules/mob/skills/skill_buffs.dm @@ -71,7 +71,7 @@ buff.skillset = skillset skillset.on_levels_change() if(duration) - addtimer(CALLBACK(buff, /datum/skill_buff/proc/remove), duration) + addtimer(CALLBACK(buff, TYPE_PROC_REF(/datum/skill_buff, remove)), duration) return buff //Takes a buff type or datum; typing is false here. diff --git a/code/modules/mob/skills/skill_verbs.dm b/code/modules/mob/skills/skill_verbs.dm index 63d3e94e727..7447f7133be 100644 --- a/code/modules/mob/skills/skill_verbs.dm +++ b/code/modules/mob/skills/skill_verbs.dm @@ -49,7 +49,7 @@ return cooling_down = 1 update_verb() - addtimer(CALLBACK(src, .proc/remove_cooldown), cooldown) + addtimer(CALLBACK(src, PROC_REF(remove_cooldown)), cooldown) /* The Instruct verb. buffs untrained -> basic and requires skill in the skill training as well as leadership. Robots and antags can instruct. diff --git a/code/modules/mob/skills/skillset.dm b/code/modules/mob/skills/skillset.dm index bdddc4e7293..be1d01c9180 100644 --- a/code/modules/mob/skills/skillset.dm +++ b/code/modules/mob/skills/skillset.dm @@ -118,8 +118,8 @@ var/global/list/all_skill_verbs else return max(0, 1 + (SKILL_DEFAULT - points) * factor) -/mob/proc/do_skilled(base_delay, skill_path , atom/target = null, factor = 0.3, check_holding = FALSE) - return do_after(src, base_delay * skill_delay_mult(skill_path, factor), target, check_holding) +/mob/proc/do_skilled(base_delay, skill_path , atom/target = null, factor = 0.3, check_holding = FALSE, set_cooldown = FALSE) + return do_after(src, base_delay * skill_delay_mult(skill_path, factor), target, check_holding, set_cooldown = set_cooldown) // A generic way of modifying success probabilities via skill values. Higher factor means skills have more effect. fail_chance is the chance at SKILL_NONE. /mob/proc/skill_fail_chance(skill_path, fail_chance, no_more_fail = SKILL_MAX, factor = 1) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 38b7caac0fb..ae06234265a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -64,7 +64,7 @@ sound_to(src, sound(null, repeat = 0, wait = 0, volume = 85, channel = sound_channels.lobby_channel))// stop the jams for AIs - var/mob/living/silicon/ai/O = new (loc, global.using_map.default_law_type,,1)//No MMI but safety is in effect. + var/mob/living/silicon/ai/O = new (loc, global.using_map.default_law_type,,1)//No brain but safety is in effect. O.set_invisibility(INVISIBILITY_NONE) O.aiRestorePowerRoutine = 0 if(mind) @@ -128,10 +128,9 @@ mind.transfer_to(O) if(O.mind && O.mind.assigned_role == ASSIGNMENT_ROBOT) O.mind.original = O - var/mmi_type = SSrobots.get_mmi_type_by_title(O.mind.role_alt_title ? O.mind.role_alt_title : O.mind.assigned_role) + var/mmi_type = SSrobots.get_brain_type_by_title(O.mind.role_alt_title ? O.mind.role_alt_title : O.mind.assigned_role) if(mmi_type) - O.mmi = new mmi_type(O) - O.mmi.transfer_identity(src) + O.central_processor = new mmi_type(O) O.dropInto(loc) O.job = ASSIGNMENT_ROBOT diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm index 7b3188a9919..70fd8d0a47d 100644 --- a/code/modules/mob_holder/_holder.dm +++ b/code/modules/mob_holder/_holder.dm @@ -7,10 +7,11 @@ slot_flags = SLOT_HEAD | SLOT_HOLSTER origin_tech = null pixel_y = 8 - origin_tech = "{'biotech':1}" + origin_tech = @'{"biotech":1}' use_single_icon = TRUE item_state = null is_spawnable_type = FALSE + max_health = ITEM_HEALTH_NO_DAMAGE var/last_holder /obj/item/holder/Initialize() @@ -24,8 +25,17 @@ AM.vis_flags |= (VIS_INHERIT_ID|VIS_INHERIT_LAYER|VIS_INHERIT_PLANE) add_vis_contents(src, AM) +// No scooping mobs and handing them to people who can't scoop them. +/obj/item/holder/equipped(mob/user, slot) + . = ..() + for(var/mob/living/mob in contents) + if(!mob.scoop_check(user)) + to_chat(user, SPAN_DANGER("You are unable to keep hold of \the [src]!")) + user.drop_from_inventory(src) + break + // Grab our inhands from the mob we're wrapping, if they have any. -/obj/item/holder/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/holder/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, force_skip_offset = FALSE, skip_offset = FALSE) var/mob/M = locate() in contents if(istype(M)) icon = M.get_holder_icon() diff --git a/code/modules/mob_holder/holder_subtypes.dm b/code/modules/mob_holder/holder_subtypes.dm index 14c3b3a9848..7276d2a41e6 100644 --- a/code/modules/mob_holder/holder_subtypes.dm +++ b/code/modules/mob_holder/holder_subtypes.dm @@ -1,10 +1,10 @@ //Mob specific holders. /obj/item/holder/drone - origin_tech = "{'magnets':3,'engineering':5}" + origin_tech = @'{"magnets":3,"engineering":5}' /obj/item/holder/mouse w_class = ITEM_SIZE_TINY //need own subtype to work with recipes /obj/item/holder/corgi - origin_tech = "{'biotech':4}" + origin_tech = @'{"biotech":4}' diff --git a/code/modules/modular_computers/computers/modular_computer/assembly_computer.dm b/code/modules/modular_computers/computers/modular_computer/assembly_computer.dm index 0e4cc01553a..5df2360f17f 100644 --- a/code/modules/modular_computers/computers/modular_computer/assembly_computer.dm +++ b/code/modules/modular_computers/computers/modular_computer/assembly_computer.dm @@ -89,4 +89,4 @@ . = ..() var/datum/extension/interactive/os/os = get_extension(holder, /datum/extension/interactive/os) if(os) - os.system_shutdown() \ No newline at end of file + os.system_shutdown() diff --git a/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm b/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm index cc2126c7a47..ff514949f13 100644 --- a/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm +++ b/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm @@ -56,7 +56,7 @@ anchored = TRUE density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-20}, 'SOUTH':{'y':24}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-20}, "SOUTH":{"y":24}, "EAST":{"x":-24}, "WEST":{"x":24}}' idle_power_usage = 75 active_power_usage = 300 max_hardware_size = 2 //make sure we can only put smaller components in here diff --git a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm index f5bdeee0d99..953a249f876 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm @@ -91,7 +91,7 @@ for(var/obj/machinery/power/sensor/S in SSmachines.machinery) if(S.long_range || (get_z(S) in connected_z_levels)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. grid_sensors += S - events_repository.register(/decl/observ/destroyed, S, src, /datum/nano_module/program/power_monitor/proc/remove_sensor) + events_repository.register(/decl/observ/destroyed, S, src, TYPE_PROC_REF(/datum/nano_module/program/power_monitor, remove_sensor)) /datum/nano_module/program/power_monitor/proc/remove_sensor(var/removed_sensor, var/update_ui = TRUE) if(active_sensor == removed_sensor) @@ -99,7 +99,7 @@ if(update_ui) SSnano.update_uis(src) grid_sensors -= removed_sensor - events_repository.unregister(/decl/observ/destroyed, removed_sensor, src, /datum/nano_module/program/power_monitor/proc/remove_sensor) + events_repository.unregister(/decl/observ/destroyed, removed_sensor, src, TYPE_PROC_REF(/datum/nano_module/program/power_monitor, remove_sensor)) /datum/nano_module/program/power_monitor/proc/is_sysadmin(var/mob/user) if(program) diff --git a/code/modules/modular_computers/file_system/programs/engineering/shields_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/shields_monitor.dm index a00df078996..6c7955d85e5 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/shields_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/shields_monitor.dm @@ -105,7 +105,7 @@ var/obj/machinery/shield_generator/S = locate(href_list["ref"]) in shields if(S) deselect_shield() - events_repository.register(/decl/observ/destroyed, S, src, /datum/nano_module/program/shields_monitor/proc/deselect_shield) + events_repository.register(/decl/observ/destroyed, S, src, TYPE_PROC_REF(/datum/nano_module/program/shields_monitor, deselect_shield)) active = S return 1 diff --git a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm index 5c886e87632..525f363d285 100644 --- a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm @@ -43,6 +43,8 @@ if(!check_file_download(filename)) return 0 var/datum/computer_file/program/PRG = net.find_file_by_name(filename, OS_PROGRAMS_DIR, MF_ROLE_SOFTWARE) + if(!istype(PRG)) + return 0 var/datum/file_storage/disk/destination = computer.mounted_storage["local"] if(!destination) return 0 diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index 853e088850f..8fb4f56a57a 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -6,7 +6,7 @@ hardware_size = 1 critical = 0 power_usage = 100 - origin_tech = "{'powerstorage':2,'programming':3}" + origin_tech = @'{"powerstorage":2,"programming":3}' external_slot = TRUE material = /decl/material/solid/metal/steel diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 8fb31a8b55f..f877a086114 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -5,7 +5,7 @@ desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. It's rating is 75 Wh." icon_state = "battery_normal" critical = 1 - origin_tech = "{'powerstorage':1,'engineering':1}" + origin_tech = @'{"powerstorage":1,"engineering":1}' material = /decl/material/solid/metal/steel var/battery_rating = 75 @@ -37,7 +37,7 @@ name = "advanced battery" desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. It's rating is 110 Wh." icon_state = "battery_advanced" - origin_tech = "{'powerstorage':2,'engineering':2}" + origin_tech = @'{"powerstorage":2,"engineering":2}' hardware_size = 2 battery_rating = 110 material = /decl/material/solid/metal/steel @@ -46,7 +46,7 @@ name = "super battery" desc = "A very advanced power cell, often used in high-end devices, or as uninterruptable power supply for important consoles or servers. It's rating is 150 Wh." icon_state = "battery_super" - origin_tech = "{'powerstorage':3,'engineering':3}" + origin_tech = @'{"powerstorage":3,"engineering":3}' hardware_size = 2 battery_rating = 150 material = /decl/material/solid/metal/steel @@ -55,7 +55,7 @@ name = "ultra battery" desc = "A very advanced large power cell. It's often used as uninterruptable power supply for critical consoles or servers. It's rating is 200 Wh." icon_state = "battery_ultra" - origin_tech = "{'powerstorage':5,'engineering':4}" + origin_tech = @'{"powerstorage":5,"engineering":4}' hardware_size = 3 battery_rating = 200 material = /decl/material/solid/metal/steel @@ -64,7 +64,7 @@ name = "micro battery" desc = "A small power cell, commonly seen in most portable microcomputers. It's rating is 50 Wh." icon_state = "battery_micro" - origin_tech = "{'powerstorage':2,'engineering':2}" + origin_tech = @'{"powerstorage":2,"engineering":2}' battery_rating = 50 material = /decl/material/solid/metal/steel @@ -72,10 +72,10 @@ name = "nano battery" desc = "A tiny power cell, commonly seen in low-end portable microcomputers. It's rating is 30 Wh." icon_state = "battery_nano" - origin_tech = "{'powerstorage':1,'engineering':1}" + origin_tech = @'{"powerstorage":1,"engineering":1}' battery_rating = 30 material = /decl/material/solid/metal/steel - origin_tech = "{'powerstorage':2,'engineering':1}" + origin_tech = @'{"powerstorage":2,"engineering":1}' // This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. /obj/item/stock_parts/computer/battery_module/lambda diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 7ffaf2c8c24..cb62d1049e9 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -5,7 +5,7 @@ critical = 0 icon_state = "cardreader" hardware_size = 1 - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' usage_flags = PROGRAM_ALL & ~PROGRAM_PDA external_slot = TRUE material = /decl/material/solid/metal/steel diff --git a/code/modules/modular_computers/hardware/charge_stick_slot.dm b/code/modules/modular_computers/hardware/charge_stick_slot.dm index 82c75557765..d2f7b010d7c 100644 --- a/code/modules/modular_computers/hardware/charge_stick_slot.dm +++ b/code/modules/modular_computers/hardware/charge_stick_slot.dm @@ -5,7 +5,7 @@ critical = 0 icon_state = "cardreader" hardware_size = 1 - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' usage_flags = PROGRAM_ALL & ~PROGRAM_PDA external_slot = TRUE material = /decl/material/solid/metal/steel diff --git a/code/modules/modular_computers/hardware/disk_slot.dm b/code/modules/modular_computers/hardware/disk_slot.dm index 36818d4e0ce..3bf653e67b4 100644 --- a/code/modules/modular_computers/hardware/disk_slot.dm +++ b/code/modules/modular_computers/hardware/disk_slot.dm @@ -5,7 +5,7 @@ critical = 0 icon_state = "cardreader" hardware_size = 1 - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' usage_flags = PROGRAM_ALL external_slot = TRUE material = /decl/material/solid/metal/steel diff --git a/code/modules/modular_computers/hardware/drive_slot.dm b/code/modules/modular_computers/hardware/drive_slot.dm index 0e364c9e61a..dacade6012b 100644 --- a/code/modules/modular_computers/hardware/drive_slot.dm +++ b/code/modules/modular_computers/hardware/drive_slot.dm @@ -5,7 +5,7 @@ critical = 0 icon_state = "cardreader" hardware_size = 1 - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' usage_flags = PROGRAM_ALL external_slot = TRUE material = /decl/material/solid/metal/steel diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index fca04084acd..d800a7b4c31 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -4,7 +4,7 @@ power_usage = 25 // SSD or something with low power usage icon_state = "hdd_normal" hardware_size = 1 - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) var/max_capacity = 128 @@ -15,7 +15,7 @@ name = "advanced hard drive" desc = "A small hybrid hard drive with 256GQ of storage capacity for use in higher grade computers where balance between power efficiency and capacity is desired." max_capacity = 256 - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' power_usage = 50 // Hybrid, medium capacity and medium power storage icon_state = "hdd_advanced" hardware_size = 2 @@ -26,7 +26,7 @@ name = "super hard drive" desc = "A small hard drive with 512GQ of storage capacity for use in cluster storage solutions where capacity is more important than power efficiency." max_capacity = 512 - origin_tech = "{'programming':3,'engineering':3}" + origin_tech = @'{"programming":3,"engineering":3}' power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. icon_state = "hdd_super" hardware_size = 2 @@ -37,7 +37,7 @@ name = "cluster hard drive" desc = "A large storage cluster consisting of multiple hard drives for usage in high capacity storage systems. Has capacity of 2048 GQ." power_usage = 500 - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' max_capacity = 2048 icon_state = "hdd_cluster" hardware_size = 3 @@ -49,7 +49,7 @@ name = "small hard drive" desc = "A small highly efficient solid state drive for portable devices." power_usage = 10 - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' max_capacity = 64 icon_state = "hdd_small" hardware_size = 1 @@ -60,7 +60,7 @@ name = "micro hard drive" desc = "A small micro hard drive for portable devices." power_usage = 2 - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' max_capacity = 32 icon_state = "hdd_micro" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/lan_port.dm b/code/modules/modular_computers/hardware/lan_port.dm index a50d49a0c08..09e516f290b 100644 --- a/code/modules/modular_computers/hardware/lan_port.dm +++ b/code/modules/modular_computers/hardware/lan_port.dm @@ -2,7 +2,7 @@ name = "wired connection port" desc = "A basic expansion port for use with wired connections." power_usage = 30 - origin_tech = "{'programming':1,'engineering':1}" + origin_tech = @'{"programming":1,"engineering":1}' icon_state = "netcard_ethernet" hardware_size = 3 material = /decl/material/solid/glass @@ -29,13 +29,13 @@ if(!istype(parent)) return terminal = new(get_turf(parent)) - set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), parent, .proc/check_terminal_prox, get_area(src)) - events_repository.register(/decl/observ/destroyed, terminal, src, .proc/unset_terminal) + set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), parent, PROC_REF(check_terminal_prox), get_area(src)) + events_repository.register(/decl/observ/destroyed, terminal, src, PROC_REF(unset_terminal)) set_status(parent, PART_STAT_CONNECTED) /obj/item/stock_parts/computer/lan_port/proc/unset_terminal() remove_extension(src, /datum/extension/event_registration/shuttle_stationary) - events_repository.unregister(/decl/observ/destroyed, terminal, src, .proc/unset_terminal) + events_repository.unregister(/decl/observ/destroyed, terminal, src, PROC_REF(unset_terminal)) var/obj/machinery/parent = loc if(istype(parent)) unset_status(parent, PART_STAT_CONNECTED) diff --git a/code/modules/modular_computers/hardware/nano_printer.dm b/code/modules/modular_computers/hardware/nano_printer.dm index dd3a4684212..e264fa428b5 100644 --- a/code/modules/modular_computers/hardware/nano_printer.dm +++ b/code/modules/modular_computers/hardware/nano_printer.dm @@ -2,7 +2,7 @@ name = "nano printer" desc = "Small integrated printer with paper recycling module." power_usage = 50 - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' critical = 0 icon_state = "printer" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index a2014e4b061..562ea9a221a 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -2,7 +2,7 @@ name = "basic network card" desc = "A basic network card for usage with standard network protocols." power_usage = 50 - origin_tech = "{'programming':2,'engineering':1}" + origin_tech = @'{"programming":2,"engineering":1}' critical = 0 icon_state = "netcard_basic" hardware_size = 1 @@ -33,7 +33,7 @@ name = "advanced network card" desc = "An advanced network card for usage with standard network protocols. It's transmitter is strong enough to connect even when far away." long_range = 1 - origin_tech = "{'programming':4,'engineering':2}" + origin_tech = @'{"programming":4,"engineering":2}' power_usage = 100 // Better range but higher power usage. icon_state = "netcard_advanced" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/portable_hard_drive.dm b/code/modules/modular_computers/hardware/portable_hard_drive.dm index f854beb0cfd..921f22a0f57 100644 --- a/code/modules/modular_computers/hardware/portable_hard_drive.dm +++ b/code/modules/modular_computers/hardware/portable_hard_drive.dm @@ -6,7 +6,7 @@ icon_state = "flashdrive_basic" hardware_size = 1 max_capacity = 16 - origin_tech = "{'programming':1}" + origin_tech = @'{"programming":1}' material = /decl/material/solid/fiberglass /obj/item/stock_parts/computer/hard_drive/portable/advanced @@ -16,7 +16,7 @@ icon_state = "flashdrive_advanced" hardware_size = 1 max_capacity = 64 - origin_tech = "{'programming':2}" + origin_tech = @'{"programming":2}' /obj/item/stock_parts/computer/hard_drive/portable/super name = "super data crystal" @@ -25,7 +25,7 @@ icon_state = "flashdrive_super" hardware_size = 1 max_capacity = 256 - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' /obj/item/stock_parts/computer/hard_drive/portable/Initialize() . = ..() @@ -63,4 +63,3 @@ readme.stored_data = jointext(readme_data, "\[br\]") readme.filename = "___README___" store_file(readme) - \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/processor_unit.dm b/code/modules/modular_computers/hardware/processor_unit.dm index e1c75121a7c..95cf5d8525d 100644 --- a/code/modules/modular_computers/hardware/processor_unit.dm +++ b/code/modules/modular_computers/hardware/processor_unit.dm @@ -8,7 +8,7 @@ hardware_size = 2 power_usage = 100 critical = 1 - origin_tech = "{'programming':3,'engineering':2}" + origin_tech = @'{"programming":3,"engineering":2}' material = /decl/material/solid/metal/steel var/processing_power = 2 // Used for DDoS speed calculations @@ -20,7 +20,7 @@ hardware_size = 1 power_usage = 25 processing_power = 1 - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' material = /decl/material/solid/metal/steel /obj/item/stock_parts/computer/processor_unit/photonic @@ -30,7 +30,7 @@ hardware_size = 2 power_usage = 50 processing_power = 4 - origin_tech = "{'programming':5,'engineering':4}" + origin_tech = @'{"programming":5,"engineering":4}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) @@ -41,6 +41,6 @@ hardware_size = 1 power_usage = 10 processing_power = 2 - origin_tech = "{'programming':4,'engineering':3}" + origin_tech = @'{"programming":4,"engineering":3}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/modules/modular_computers/hardware/scanners/scanner.dm b/code/modules/modular_computers/hardware/scanners/scanner.dm index cdb1222ab75..b84dc782e6d 100644 --- a/code/modules/modular_computers/hardware/scanners/scanner.dm +++ b/code/modules/modular_computers/hardware/scanners/scanner.dm @@ -7,7 +7,7 @@ icon_state = "printer" hardware_size = 1 critical = 0 - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' var/datum/computer_file/program/scanner/driver_type = /datum/computer_file/program/scanner // A program type that the scanner interfaces with and attempts to install on insertion. var/datum/computer_file/program/scanner/driver // A driver program which has been set up to interface with the scanner. diff --git a/code/modules/modular_computers/hardware/tesla_link.dm b/code/modules/modular_computers/hardware/tesla_link.dm index c80c643abed..6e59fcdb5f9 100644 --- a/code/modules/modular_computers/hardware/tesla_link.dm +++ b/code/modules/modular_computers/hardware/tesla_link.dm @@ -5,7 +5,7 @@ enabled = 1 icon_state = "teslalink" hardware_size = 1 - origin_tech = "{'programming':2,'powerstorage':3,'engineering':2}" + origin_tech = @'{"programming":2,"powerstorage":3,"engineering":2}' material = /decl/material/solid/metal/steel var/passive_charging_rate = 250 // W diff --git a/code/modules/modular_computers/networking/_network.dm b/code/modules/modular_computers/networking/_network.dm index 4e533fe2c9e..73adef3ab7d 100644 --- a/code/modules/modular_computers/networking/_network.dm +++ b/code/modules/modular_computers/networking/_network.dm @@ -314,6 +314,7 @@ if(!islist(channels)) channels = list(channels) for(var/channel in channels) - cameras_by_channel[channel] -= removed - if(!length(cameras_by_channel)) - cameras_by_channel -= channel \ No newline at end of file + if(cameras_by_channel[channel]) + cameras_by_channel[channel] -= removed + if(!length(cameras_by_channel[channel])) + cameras_by_channel -= channel diff --git a/code/modules/modular_computers/networking/machinery/mainframe.dm b/code/modules/modular_computers/networking/machinery/mainframe.dm index b9f8b6cf1cd..3f25c9e811c 100644 --- a/code/modules/modular_computers/networking/machinery/mainframe.dm +++ b/code/modules/modular_computers/networking/machinery/mainframe.dm @@ -18,10 +18,29 @@ /obj/machinery/network/mainframe/Initialize() . = ..() + var/datum/extension/network_device/mainframe/M = get_extension(src, /datum/extension/network_device) M.roles |= initial_roles M.update_roles() + if(!(MF_ROLE_SOFTWARE in initial_roles)) + return + + var/obj/item/stock_parts/computer/hard_drive/drive = get_component_of_type(PART_HDD) + for(var/F in subtypesof(/datum/computer_file/report)) + var/datum/computer_file/report/type = F + if(TYPE_IS_ABSTRACT(type)) + continue + if(initial(type.available_on_network)) + drive.store_file(new type, "reports", TRUE) + + for(var/F in subtypesof(/datum/computer_file/program)) + var/datum/computer_file/program/type = F + if(TYPE_IS_ABSTRACT(type)) + continue + if(initial(type.available_on_network)) + drive.store_file(new type, OS_PROGRAMS_DIR, TRUE) + /obj/machinery/network/mainframe/ui_data(mob/user, ui_key) var/data = ..() var/datum/extension/network_device/mainframe/M = get_extension(src, /datum/extension/network_device) @@ -68,20 +87,3 @@ /obj/machinery/network/mainframe/software initial_roles = list(MF_ROLE_SOFTWARE) - -/obj/machinery/network/mainframe/software/Initialize() - . = ..() - var/obj/item/stock_parts/computer/hard_drive/drive = get_component_of_type(PART_HDD) - for(var/F in subtypesof(/datum/computer_file/report)) - var/datum/computer_file/report/type = F - if(TYPE_IS_ABSTRACT(type)) - continue - if(initial(type.available_on_network)) - drive.store_file(new type, "reports", TRUE) - - for(var/F in subtypesof(/datum/computer_file/program)) - var/datum/computer_file/program/type = F - if(TYPE_IS_ABSTRACT(type)) - continue - if(initial(type.available_on_network)) - drive.store_file(new type, OS_PROGRAMS_DIR, TRUE) \ No newline at end of file diff --git a/code/modules/modular_computers/networking/machinery/telecomms.dm b/code/modules/modular_computers/networking/machinery/telecomms.dm index 6d99caa4d0b..87ef1cca4b7 100644 --- a/code/modules/modular_computers/networking/machinery/telecomms.dm +++ b/code/modules/modular_computers/networking/machinery/telecomms.dm @@ -161,10 +161,7 @@ var/global/list/telecomms_hubs = list() var/formatted_msg = "\[[channel?.name || format_frequency(frequency)]\] " var/send_name = istype(speaker) ? speaker.real_name : ("[speaker]" || "unknown") - var/overmap_send_name = "[send_name] ([send_overmap_object.name])" - var/list/listeners = list() // Dictionary of listener -> boolean (include overmap origin) - // Broadcast to all radio devices in our network. for(var/weakref/W as anything in network.connected_radios) var/obj/item/radio/R = W.resolve() @@ -180,25 +177,20 @@ var/global/list/telecomms_hubs = list() if(!LAZYACCESS(check_channels, channel)) continue - var/listener_overmap_object = istype(speaking_from) && global.overmap_sectors["[speaking_from.z]"] + // If we're sending from an overmap object AND our overmap object transmits its identity AND it's different than the listener's + // then append the overmap object name to it, so they know where we're from + var/listener_overmap_object = istype(speaking_from) && global.overmap_sectors[num2text(speaking_from.z)] + var/send_overmap = send_overmap_object && send_overmap_object.ident_transmitter && send_overmap_object != listener_overmap_object for(var/mob/listener in hearers(R.canhear_range, speaking_from)) - // If we're sending from an overmap object AND our overmap object transmits its identity AND it's different than the listener's - // then append the overmap object name to it, so they know where we're from - var/send_overmap = send_overmap_object && send_overmap_object.ident_transmitter && send_overmap_object != listener_overmap_object - LAZYSET(listeners, listener, send_overmap) + listeners[listener] = send_overmap // Ghostship is magic: Ghosts can hear radio chatter from anywhere for(var/mob/observer/ghost/ghost_listener as anything in global.ghost_mob_list) if(ghost_listener.get_preference_value(/datum/client_preference/ghost_radio) == PREF_ALL_CHATTER) - LAZYSET(listeners, ghost_listener, TRUE) + listeners[ghost_listener] = TRUE for(var/mob/listener in listeners) - var/per_listener_send_name = listeners[listener] ? overmap_send_name : send_name - var/per_listener_loc_name - if(send_overmap_object && send_overmap_object.ident_transmitter && send_overmap_object != listeners[listener]) - // then append the overmap object name to it, so they know where we're from - per_listener_loc_name = send_overmap_object.name - listener.hear_radio(message, message_verb, speaking, formatted_msg, " ", "", speaker, message_compression, per_listener_send_name, per_listener_loc_name) + listener.hear_radio(message, message_verb, speaking, formatted_msg, " ", "", speaker, message_compression, vname = send_name, vsource = (listeners[listener] ? send_overmap_object.name : null)) if(!chain_transmit) return diff --git a/code/modules/modular_computers/networking/machinery/wall_relay.dm b/code/modules/modular_computers/networking/machinery/wall_relay.dm index 9911c3bc20a..dbf5102bf60 100644 --- a/code/modules/modular_computers/networking/machinery/wall_relay.dm +++ b/code/modules/modular_computers/networking/machinery/wall_relay.dm @@ -7,7 +7,7 @@ density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED base_type = /obj/machinery/network/relay/wall_mounted - directional_offset = "{'NORTH':{'y':-21}, 'SOUTH':{'y':21}, 'EAST':{'x':-21}, 'WEST':{'x':21}}" + directional_offset = @'{"NORTH":{"y":-21}, "SOUTH":{"y":21}, "EAST":{"x":-21}, "WEST":{"x":21}}' /obj/machinery/network/relay/wall_mounted/Initialize() . = ..() diff --git a/code/modules/modular_computers/networking/machinery/wall_router.dm b/code/modules/modular_computers/networking/machinery/wall_router.dm index 27c46d4d771..5c408af98d9 100644 --- a/code/modules/modular_computers/networking/machinery/wall_router.dm +++ b/code/modules/modular_computers/networking/machinery/wall_router.dm @@ -7,7 +7,7 @@ density = FALSE obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED base_type = /obj/machinery/network/router/wall_mounted - directional_offset = "{'NORTH':{'y':-21}, 'SOUTH':{'y':21}, 'EAST':{'x':-21}, 'WEST':{'x':21}}" + directional_offset = @'{"NORTH":{"y":-21}, "SOUTH":{"y":21}, "EAST":{"x":-21}, "WEST":{"x":21}}' /obj/machinery/network/router/wall_mounted/Initialize() . = ..() diff --git a/code/modules/modular_computers/networking/network_files.dm b/code/modules/modular_computers/networking/network_files.dm index 66d6e21fc12..34229d711e2 100644 --- a/code/modules/modular_computers/networking/network_files.dm +++ b/code/modules/modular_computers/networking/network_files.dm @@ -1,9 +1,11 @@ /datum/computer_network/proc/find_file_by_name(filename, directory, mainframe_role = MF_ROLE_FILESERVER, list/accesses) for(var/datum/extension/network_device/mainframe/M in get_mainframes_by_role(mainframe_role, accesses)) var/datum/computer_file/F = M.get_file(filename, directory) - if(F) + if(istype(F)) return F + return OS_FILE_NOT_FOUND + /datum/computer_network/proc/get_all_files_of_type(file_type, mainframe_role = MF_ROLE_FILESERVER, uniques_only = FALSE, list/accesses) . = list() var/list/found_filenames = list() diff --git a/code/modules/modular_computers/os/_os.dm b/code/modules/modular_computers/os/_os.dm index f842de5083b..b4115ac188f 100644 --- a/code/modules/modular_computers/os/_os.dm +++ b/code/modules/modular_computers/os/_os.dm @@ -168,6 +168,7 @@ else if(prob(5)) hard_drive.visible_message("[src] emits some ominous clicks.") hard_drive.take_damage(hard_drive.health) + update_host_icon() /datum/extension/interactive/os/proc/system_boot() diff --git a/code/modules/multiz/hoist.dm b/code/modules/multiz/hoist.dm index 838b64e9dc2..02c3988c4a6 100644 --- a/code/modules/multiz/hoist.dm +++ b/code/modules/multiz/hoist.dm @@ -83,7 +83,7 @@ if (get_turf(AM) != get_turf(source_hook)) AM.forceMove(get_turf(source_hook)) - events_repository.register(/decl/observ/destroyed, AM, src, .proc/release_hoistee) + events_repository.register(/decl/observ/destroyed, AM, src, PROC_REF(release_hoistee)) /obj/effect/hoist_hook/handle_mouse_drop(atom/over, mob/user, params) if(source_hoist.hoistee && isturf(over) && over.Adjacent(source_hoist.hoistee)) diff --git a/code/modules/multiz/ladder.dm b/code/modules/multiz/ladder.dm index 8fa04a4f2aa..5338e63f0d3 100644 --- a/code/modules/multiz/ladder.dm +++ b/code/modules/multiz/ladder.dm @@ -107,7 +107,7 @@ var/turf/T = get_turf(src) if(T) for(var/atom/movable/M in T.contents) - addtimer(CALLBACK(M, /atom/movable/proc/fall, T), 0) + addtimer(CALLBACK(M, TYPE_PROC_REF(/atom/movable, fall), T), 0) return ..() /obj/structure/ladder/attackby(obj/item/I, mob/user) diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 6bc6649e4b1..cb726b28841 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -243,7 +243,7 @@ /datum/level_data/proc/setup_ambient() if(!use_global_exterior_ambience) return - ambient_light_level = config.exterior_ambient_light + ambient_light_level = get_config_value(/decl/config/num/exterior_ambient_light) ambient_light_color = SSskybox.background_color ///Setup/generate atmosphere for exterior turfs on the level. @@ -289,22 +289,43 @@ // // Level Load/Gen // +/// Helper proc for subtemplate generation. +/datum/level_data/proc/get_subtemplate_budget() + return 0 +/// Helper proc for subtemplate generation. +/datum/level_data/proc/get_subtemplate_category() + return +/// Helper proc for subtemplate generation. +/datum/level_data/proc/get_subtemplate_blacklist() + return +/// Helper proc for subtemplate generation. +/datum/level_data/proc/get_subtemplate_whitelist() + return ///Called when setting up the level. Apply generators and anything that modifies the turfs of the level. /datum/level_data/proc/generate_level() - if(!global.config.roundstart_level_generation) + + if(!get_config_value(/decl/config/toggle/roundstart_level_generation)) return + var/origx = level_inner_min_x var/origy = level_inner_min_y var/endx = level_inner_min_x + level_inner_width var/endy = level_inner_min_y + level_inner_height + + // Run level generators. for(var/gen_type in level_generators) new gen_type(origx, origy, level_z, endx, endy, FALSE, TRUE) + // Place points of interest. + var/budget = get_subtemplate_budget() + if(budget) + spawn_subtemplates(budget, get_subtemplate_category(), get_subtemplate_blacklist(), get_subtemplate_whitelist()) + ///Apply the parent entity's map generators. (Planets generally) ///This proc is to give a chance to level_data subtypes to individually chose to ignore the parent generators. /datum/level_data/proc/apply_map_generators(var/list/map_gen) - if(!global.config.roundstart_level_generation) + if(!get_config_value(/decl/config/toggle/roundstart_level_generation)) return var/origx = level_inner_min_x var/origy = level_inner_min_y @@ -593,3 +614,90 @@ INITIALIZE_IMMEDIATE(/obj/abstract/level_data_spawner) CHECK_TICK mining_turfs = null +/datum/level_data/proc/get_subtemplate_areas(template_category, blacklist, whitelist) + return list(base_area) + +///Try to allocate the given amount of POIs onto our level. Returns the template types that were spawned +/datum/level_data/proc/spawn_subtemplates(budget = 0, template_category, blacklist, whitelist) + + if(budget <= 0) + return + + var/list/possible_subtemplates = list() + var/list/all_subtemplates = SSmapping.get_templates_by_category(template_category) + for(var/poi_name in all_subtemplates) + var/datum/map_template/poi = all_subtemplates[poi_name] + var/poi_tags = poi.get_template_tags() + if(whitelist && !(whitelist & poi_tags)) + continue + if(blacklist & poi_tags) + continue + possible_subtemplates += poi + + if(!length(possible_subtemplates)) + return //If we don't have any templates, don't bother + + if(!length(possible_subtemplates)) + log_world("Map subtemplate loader was given no templates to pick from.") + return + + var/list/areas_whitelist = get_subtemplate_areas(template_category, blacklist, whitelist) + var/list/candidate_points_of_interest = possible_subtemplates.Copy() + //Each iteration needs to either place a subtemplate or strictly decrease either the budget or templates list length (or break). + while(length(candidate_points_of_interest) && (budget > 0)) + var/datum/map_template/R = pick(candidate_points_of_interest) + if((R.get_template_cost() <= budget) && !LAZYISIN(SSmapping.banned_template_names, R.name) && try_place_subtemplate(R, areas_whitelist)) + LAZYADD(., R) + budget -= R.get_template_cost() + //Mark spawned no-duplicate POI globally + if(!(R.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES)) + LAZYDISTINCTADD(SSmapping.banned_template_names, R.name) + candidate_points_of_interest -= R + + if(budget > 0) + log_world("Map subtemplate loader had no templates to pick from with [budget] left to spend.") + +///Attempts several times to find turfs where a subtemplate can be placed. +/datum/level_data/proc/try_place_subtemplate(var/datum/map_template/template, var/list/area_whitelist) + //#FIXME: Isn't trying to fit in a subtemplate by rolling randomly a bit inneficient? + // Try to place it + var/template_full_width = (2 * TEMPLATE_TAG_MAP_EDGE_PAD) + template.width + var/template_full_height = (2 * TEMPLATE_TAG_MAP_EDGE_PAD) + template.height + if((template_full_width > level_inner_width) || (template_full_height > level_inner_height)) // Too big and will never fit. + return //Return if it won't even fit on the entire level + + var/template_half_width = TEMPLATE_TAG_MAP_EDGE_PAD + round(template.width/2) //Half the template size plus the map edge spacing, for testing from the centerpoint + var/template_half_height = TEMPLATE_TAG_MAP_EDGE_PAD + round(template.height/2) + //Try to fit it in somehwere a few times, then give up if we can't + var/sanity = 20 + while(sanity > 0) + sanity-- + //Pick coordinates inside the level's border within which the template will fit. Including the extra template spacing from the level's borders. + var/cturf_x = rand(level_inner_min_x + template_half_width, level_inner_max_x - template_half_width) + var/cturf_y = rand(level_inner_min_y + template_half_height, level_inner_max_y - template_half_height) + var/turf/T = locate(cturf_x, cturf_y, level_z) + var/valid = TRUE + + //#TODO: There's definitely a way to cache what turfs use an area, to avoid doing this for every single templates! + // Could also probably cache TURF_FLAG_NO_POINTS_OF_INTEREST turfs globally. + var/list/affected_turfs = template.get_affected_turfs(T, TRUE) + for(var/turf/test_turf in affected_turfs) + var/area/A = get_area(test_turf) + if((length(area_whitelist) && !is_type_in_list(A, area_whitelist)) || (test_turf.turf_flags & TURF_FLAG_NO_POINTS_OF_INTEREST)) + valid = FALSE + break //Break out of the turf check loop, and grab a new set of coordinates + if(!valid) + continue + log_world("Spawned template \"[template.name]\", center: ([T.x], [T.y], [T.z]), min: ([T.x - template_half_width], [T.y - template_half_height]), max: ([T.x + template_half_width], [T.y + template_half_height])") + load_subtemplate(T, template) + return template + +///Actually handles loading a template template at the given turf. +/datum/level_data/proc/load_subtemplate(turf/central_turf, datum/map_template/template) + if(!template) + return FALSE + for(var/turf/T in template.get_affected_turfs(central_turf, TRUE)) + for(var/mob/living/simple_animal/monster in T) + qdel(monster) + template.load(central_turf, centered = TRUE) + return TRUE diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 440cc530bd1..b6d058eede1 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -22,7 +22,7 @@ if(loc != old_loc) return - var/turf/simulated/open/O = GetAbove(src) + var/turf/open/O = GetAbove(src) var/atom/climb_target if(istype(O)) for(var/turf/T in RANGE_TURFS(O, 1)) @@ -121,7 +121,7 @@ // Entered() which is part of Move(), by spawn()ing we let that complete. But we want to preserve if we were in client movement // or normal movement so other move behavior can continue. /atom/movable/proc/begin_falling(var/lastloc, var/below) - addtimer(CALLBACK(src, /atom/movable/proc/fall_callback, below), 0) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/movable, fall_callback), below), 0) /atom/movable/proc/fall_callback(var/turf/below) if(!QDELETED(src)) @@ -171,7 +171,7 @@ return TRUE /obj/item/pipe/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc) - var/turf/simulated/open/below = loc + var/turf/open/below = loc below = below.below . = ..() @@ -187,7 +187,11 @@ return species.can_fall(src) /atom/movable/proc/protected_from_fall_damage(var/turf/landing) - return !!(locate(/obj/structure/stairs) in landing) + if(!!(locate(/obj/structure/stairs) in landing)) + return TRUE + var/turf/exterior/wall/ramp = landing + if(istype(ramp) && ramp.ramp_slope_direction) // walking down a ramp + return TRUE /mob/protected_from_fall_damage(var/turf/landing) . = ..() @@ -373,7 +377,7 @@ . = ..() owner = user follow() - events_repository.register(/decl/observ/moved, owner, src, /atom/movable/z_observer/proc/follow) + events_repository.register(/decl/observ/moved, owner, src, TYPE_PROC_REF(/atom/movable/z_observer, follow)) /atom/movable/z_observer/proc/follow() @@ -397,7 +401,7 @@ qdel(src) /atom/movable/z_observer/Destroy() - events_repository.unregister(/decl/observ/moved, owner, src, /atom/movable/z_observer/proc/follow) + events_repository.unregister(/decl/observ/moved, owner, src, TYPE_PROC_REF(/atom/movable/z_observer, follow)) owner = null . = ..() diff --git a/code/modules/multiz/stairs.dm b/code/modules/multiz/stairs.dm index 726d9a0bc7e..6bff344b06d 100644 --- a/code/modules/multiz/stairs.dm +++ b/code/modules/multiz/stairs.dm @@ -14,7 +14,7 @@ warning("Stair created without level above: ([loc.x], [loc.y], [loc.z])") return INITIALIZE_HINT_QDEL if(!above.is_open()) - above.ChangeTurf(/turf/simulated/open) + above.ChangeTurf(/turf/space) // This will be resolved to the appropriate open space type by ChangeTurf(). . = ..() /obj/structure/stairs/CheckExit(atom/movable/mover, turf/target) @@ -43,6 +43,10 @@ /obj/structure/stairs/CanPass(obj/mover, turf/source, height, airflow) return airflow || !density +/obj/structure/stairs/catwalk + name = "catwalk stairs" + icon_state = "catwalk" + // type paths to make mapping easier. /obj/structure/stairs/long @@ -65,3 +69,24 @@ dir = WEST bound_width = 64 bound_height = 32 + +/obj/structure/stairs/long/catwalk + name = "catwalk stairs" + icon_state = "catwalk" + +/obj/structure/stairs/long/catwalk/north + dir = NORTH + bound_y = -32 + pixel_y = -32 + +/obj/structure/stairs/long/catwalk/east + dir = EAST + bound_width = 64 + bound_height = 32 + bound_x = -32 + pixel_x = -32 + +/obj/structure/stairs/long/catwalk/west + dir = WEST + bound_width = 64 + bound_height = 32 \ No newline at end of file diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index a8da2c73496..88b30585700 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -1,41 +1,3 @@ -// Shared attackby behaviors that /turf/exterior/open also uses. -/proc/shared_open_turf_attackhand(var/turf/target, var/mob/user) - for(var/atom/movable/M in target.below) - if(M.movable_flags & MOVABLE_FLAG_Z_INTERACT) - return M.attack_hand_with_interaction_checks(user) - -/proc/shared_open_turf_attackby(var/turf/target, obj/item/thing, mob/user) - - if(istype(thing, /obj/item/stack/material/rods)) - var/ladder = (locate(/obj/structure/ladder) in target) - if(ladder) - to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) - return TRUE - var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, target) - if(lattice) - return lattice.attackby(thing, user) - var/obj/item/stack/material/rods/rods = thing - if (rods.use(1)) - to_chat(user, SPAN_NOTICE("You lay down the support lattice.")) - playsound(target, 'sound/weapons/Genhit.ogg', 50, 1) - new /obj/structure/lattice(locate(target.x, target.y, target.z), rods.material.type) - return TRUE - - if (istype(thing, /obj/item/stack/tile)) - var/obj/item/stack/tile/tile = thing - tile.try_build_turf(user, target) - return TRUE - - //To lay cable. - if(IS_COIL(thing) && target.try_build_cable(thing, user)) - return TRUE - - for(var/atom/movable/M in target.below) - if(M.movable_flags & MOVABLE_FLAG_Z_INTERACT) - return M.attackby(thing, user) - - return FALSE - /// `direction` is the direction the atom is trying to leave by. /turf/proc/CanZPass(atom/A, direction, check_neighbor_canzpass = TRUE) @@ -59,9 +21,9 @@ return Enter(A, A) //////////////////////////////// -// Open SIMULATED +// Open space //////////////////////////////// -/turf/simulated/open +/turf/open name = "open space" icon = 'icons/turf/space.dmi' icon_state = "" @@ -69,30 +31,32 @@ pathweight = 100000 //Seriously, don't try and path over this one numbnuts z_flags = ZM_MIMIC_DEFAULTS | ZM_MIMIC_OVERWRITE | ZM_MIMIC_NO_AO | ZM_ALLOW_ATMOS turf_flags = TURF_FLAG_BACKGROUND + zone_membership_candidate = TRUE + initial_gas = list( + /decl/material/gas/oxygen = MOLES_O2STANDARD, + /decl/material/gas/nitrogen = MOLES_N2STANDARD + ) -/turf/simulated/open/flooded +/turf/open/flooded name = "open water" - flooded = TRUE - -/turf/simulated/open/update_dirt() - return 0 + flooded = /decl/material/liquid/water -/turf/simulated/open/Entered(var/atom/movable/mover, var/atom/oldloc) +/turf/open/Entered(var/atom/movable/mover, var/atom/oldloc) ..() mover.fall(oldloc) // Called when thrown object lands on this turf. -/turf/simulated/open/hitby(var/atom/movable/AM) +/turf/open/hitby(var/atom/movable/AM) ..() if(!QDELETED(AM)) AM.fall() // override to make sure nothing is hidden -/turf/simulated/open/levelupdate() +/turf/open/levelupdate() for(var/obj/O in src) O.hide(0) -/turf/simulated/open/examine(mob/user, distance, infix, suffix) +/turf/open/examine(mob/user, distance, infix, suffix) . = ..() if(distance <= 2) var/depth = 1 @@ -100,64 +64,56 @@ depth += 1 to_chat(user, "It is about [depth] level\s deep.") -/turf/simulated/open/is_open() +/turf/open/is_open() return TRUE -/turf/simulated/open/attackby(obj/item/C, mob/user) - return shared_open_turf_attackby(src, C, user) - -/turf/simulated/open/attack_hand(mob/user) - SHOULD_CALL_PARENT(FALSE) - return shared_open_turf_attackhand(src, user) - -//Most things use is_plating to test if there is a cover tile on top (like regular floors) -/turf/simulated/open/is_plating() - return TRUE - -/turf/simulated/open/cannot_build_cable() - return 0 +/turf/open/attackby(obj/item/C, mob/user) + if(istype(C, /obj/item/stack/material/rods)) + var/ladder = (locate(/obj/structure/ladder) in src) + if(ladder) + to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) + return TRUE + var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) + if(lattice) + return lattice.attackby(C, user) + var/obj/item/stack/material/rods/rods = C + if (rods.use(1)) + to_chat(user, SPAN_NOTICE("You lay down the support lattice.")) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + new /obj/structure/lattice(src, rods.material.type) + return TRUE -//////////////////////////////// -// Open EXTERIOR -//////////////////////////////// -/turf/exterior/open - name = "open space" - icon = 'icons/turf/space.dmi' - icon_state = "" - density = FALSE - pathweight = 100000 - z_flags = ZM_MIMIC_DEFAULTS | ZM_MIMIC_OVERWRITE | ZM_MIMIC_NO_AO | ZM_ALLOW_ATMOS + if (istype(C, /obj/item/stack/tile)) + var/obj/item/stack/tile/tile = C + tile.try_build_turf(user, src) + return TRUE -/turf/exterior/open/flooded - name = "open water" - flooded = TRUE + //To lay cable. + if(IS_COIL(C) && try_build_cable(C, user)) + return TRUE -/turf/exterior/open/Entered(var/atom/movable/mover, var/atom/oldloc) - ..() - mover.fall(oldloc) + for(var/atom/movable/M in below) + if(M.movable_flags & MOVABLE_FLAG_Z_INTERACT) + return M.attackby(C, user) -/turf/exterior/open/hitby(var/atom/movable/AM) - ..() - if(!QDELETED(AM)) - AM.fall() + return FALSE -/turf/exterior/open/examine(mob/user, distance, infix, suffix) - . = ..() - if(distance <= 2) - var/depth = 1 - for(var/turf/T = GetBelow(src); (istype(T) && T.is_open()); T = GetBelow(T)) - depth += 1 - to_chat(user, "It is about [depth] level\s deep.") +/turf/open/attack_hand(mob/user) + SHOULD_CALL_PARENT(FALSE) + for(var/atom/movable/M in below) + if(M.movable_flags & MOVABLE_FLAG_Z_INTERACT) + return M.attack_hand_with_interaction_checks(user) + return FALSE -/turf/exterior/open/is_open() +//Most things use is_plating to test if there is a cover tile on top (like regular floors) +/turf/open/is_plating() return TRUE -/turf/exterior/open/attackby(obj/item/C, mob/user) - return shared_open_turf_attackby(src, C, user) +/turf/open/cannot_build_cable() + return 0 -/turf/exterior/open/attack_hand(mob/user) +/turf/open/drill_act() SHOULD_CALL_PARENT(FALSE) - return shared_open_turf_attackhand(src, user) - -/turf/exterior/open/cannot_build_cable() - return 0 + var/turf/T = GetBelow(src) + if(istype(T)) + T.drill_act() diff --git a/code/modules/multiz/turf_mimic_edge.dm b/code/modules/multiz/turf_mimic_edge.dm index fd18b69e385..39d85b8f8b7 100644 --- a/code/modules/multiz/turf_mimic_edge.dm +++ b/code/modules/multiz/turf_mimic_edge.dm @@ -357,6 +357,9 @@ return shared_transition_edge_bumped(src, AM, mimic_z) +/turf/unsimulated/mimic_edge/transition/flooded + flooded = /decl/material/liquid/water + /turf/unsimulated/mimic_edge/transition/setup_mimic() var/list/coord = shared_transition_edge_get_coordinates_turf_to_mimic(src, shared_transition_edge_get_valid_level_data(src)) set_mimic_turf(coord[1], coord[2], coord[3]) diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index 957c143791b..9526a0dab70 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -15,13 +15,6 @@ else // Not a turf, so we need to destroy immediately instead of waiting for the destruction timer to proc. qdel(bound_overlay) -/atom/movable/Move() - . = ..() - if (. && bound_overlay) - bound_overlay.forceMove(get_step(src, UP)) - if (bound_overlay.dir != dir) - bound_overlay.set_dir(dir) - /atom/movable/set_dir(ndir) . = ..() if (. && bound_overlay) @@ -54,7 +47,7 @@ simulated = FALSE anchored = TRUE mouse_opacity = FALSE - abstract_type = /atom/movable/openspace // unsure if this is valid, check with Lohi + abstract_type = /atom/movable/openspace // unsure if this is valid, check with Lohi -- Yes, it's valid. /atom/movable/openspace/can_fall() return FALSE @@ -84,34 +77,37 @@ var/turf/myturf = loc if (istype(myturf)) myturf.shadower = null + return ..() -/atom/movable/openspace/multiplier/proc/copy_lighting(atom/movable/lighting_overlay/LO) - appearance = LO - layer = MIMICED_LIGHTING_LAYER - plane = OPENTURF_MAX_PLANE - blend_mode = BLEND_MULTIPLY +/atom/movable/openspace/multiplier/proc/copy_lighting(atom/movable/lighting_overlay/LO, use_shadower_mult = TRUE) + var/mutable_appearance/MA = new /mutable_appearance(LO) + MA.layer = MIMICED_LIGHTING_LAYER + MA.plane = OPENTURF_MAX_PLANE + MA.blend_mode = BLEND_MULTIPLY + + if (use_shadower_mult) + if (icon_state == LIGHTING_BASE_ICON_STATE) + // We're using a color matrix, so just darken the colors across the board. + var/list/c_list = color + c_list[CL_MATRIX_RR] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_RG] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_RB] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_GR] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_GG] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_GB] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_BR] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_BG] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_BB] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_AR] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_AG] *= SHADOWER_DARKENING_FACTOR + c_list[CL_MATRIX_AB] *= SHADOWER_DARKENING_FACTOR + MA.color = c_list + else + // Not a color matrix, so we can just use the color var ourselves. + MA.color = SHADOWER_DARKENING_COLOR set_invisibility(INVISIBILITY_NONE) - - if (icon_state == LIGHTING_BASE_ICON_STATE) - // We're using a color matrix, so just darken the colors across the board. - var/list/c_list = color - c_list[CL_MATRIX_RR] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_RG] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_RB] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GR] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GG] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GB] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BR] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BG] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BB] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AR] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AG] *= SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AB] *= SHADOWER_DARKENING_FACTOR - color = c_list - else - // Not a color matrix, so we can just use the color var ourselves. - color = SHADOWER_DARKENING_COLOR + appearance = MA if (our_overlays || priority_overlays) compile_overlays() @@ -163,18 +159,32 @@ . = associated_atom.examine(arglist(args)) // just pass all the args to the copied atom /atom/movable/openspace/mimic/forceMove(turf/dest) + var/atom/old_loc = loc . = ..() if (TURF_IS_MIMICKING(dest)) if (destruction_timer) deltimer(destruction_timer) destruction_timer = null + if (old_loc.z != loc.z) + reset_internal_layering() else if (!destruction_timer) - destruction_timer = addtimer(CALLBACK(src, /datum/.proc/qdel_self), 10 SECONDS, TIMER_STOPPABLE) + destruction_timer = ZM_DESTRUCTION_TIMER(src) // Called when the turf we're on is deleted/changed. /atom/movable/openspace/mimic/proc/owning_turf_changed() if (!destruction_timer) - destruction_timer = addtimer(CALLBACK(src, /datum/.proc/qdel_self), 10 SECONDS, TIMER_STOPPABLE) + destruction_timer = ZM_DESTRUCTION_TIMER(src) + +/atom/movable/openspace/mimic/proc/reset_internal_layering() + if (bound_overlay?.override_depth) + depth = bound_overlay.override_depth + else if (isturf(associated_atom.loc)) + depth = min(SSzcopy.zlev_maximums[associated_atom.z] - associated_atom.z, OPENTURF_MAX_DEPTH) + override_depth = depth + + plane = OPENTURF_MAX_PLANE - depth + + bound_overlay?.reset_internal_layering() // -- TURF PROXY -- diff --git a/code/modules/multiz/zmimic/mimic_turf.dm b/code/modules/multiz/zmimic/mimic_turf.dm index 07d58a0e959..d47230e98e1 100644 --- a/code/modules/multiz/zmimic/mimic_turf.dm +++ b/code/modules/multiz/zmimic/mimic_turf.dm @@ -15,6 +15,8 @@ /// If this Z-turf leads to space, uninterrupted. var/tmp/z_eventually_space = FALSE var/z_flags = 0 + /// Use this appearance for our appearance instead of `appearance`. If ZM_OVERRIDE is set, *only* this will be visible, no movables will be copied. + var/z_appearance // debug var/tmp/z_depth diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 7b19155b7ba..a6772cb01b9 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -41,39 +41,39 @@ return owner.change_skin_tone(new_s_tone) if(href_list["skin_color"] && can_change_skin_color()) - var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", owner.skin_colour) as color|null - if(new_skin && can_still_topic(state) && owner.change_skin_color(new_skin)) + var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", owner.get_skin_colour()) as color|null + if(new_skin && can_still_topic(state) && owner.set_skin_colour(new_skin)) update_dna() return TRUE if(href_list["hair"]) var/decl/sprite_accessory/hair = locate(href_list["hair"]) - if(can_change(APPEARANCE_HAIR) && istype(hair) && (hair.type in owner.get_valid_hairstyle_types()) && owner.change_hair(hair.type)) + if(can_change(APPEARANCE_HAIR) && istype(hair) && (hair.type in owner.get_valid_hairstyle_types()) && owner.set_hairstyle(hair.type)) update_dna() return TRUE if(href_list["hair_color"] && can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", owner.hair_colour) as color|null - if(new_hair && can_still_topic(state) && owner.change_hair_color(new_hair)) + var/new_hair = input("Please select hair color.", "Hair Color", owner.get_hair_colour()) as color|null + if(new_hair && can_still_topic(state) && owner.set_hair_colour(new_hair)) update_dna() return TRUE if(href_list["facial_hair"]) var/decl/sprite_accessory/facial_hair = locate(href_list["facial_hair"]) - if(can_change(APPEARANCE_FACIAL_HAIR) && istype(facial_hair) && (facial_hair.type in owner.get_valid_facial_hairstyle_types()) && owner.change_facial_hair(facial_hair.type)) + if(can_change(APPEARANCE_FACIAL_HAIR) && istype(facial_hair) && (facial_hair.type in owner.get_valid_facial_hairstyle_types()) && owner.set_facial_hairstyle(facial_hair.type)) update_dna() return TRUE if(href_list["facial_hair_color"] && can_change(APPEARANCE_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select facial hair color.", "Facial Hair Color", owner.facial_hair_colour) as color|null - if(new_facial && can_still_topic(state) && owner.change_facial_hair_color(new_facial)) + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", owner.get_facial_hair_colour()) as color|null + if(new_facial && can_still_topic(state) && owner.set_facial_hair_colour(new_facial)) update_dna() return TRUE if(href_list["eye_color"]) if(can_change(APPEARANCE_EYE_COLOR)) - var/new_eyes = input("Please select eye color.", "Eye Color", owner.eye_colour) as color|null - if(new_eyes && can_still_topic(state) && owner.change_eye_color(new_eyes)) + var/new_eyes = input("Please select eye color.", "Eye Color", owner.get_eye_colour()) as color|null + if(new_eyes && can_still_topic(state) && owner.set_eye_colour(new_eyes)) update_dna() return TRUE @@ -119,7 +119,8 @@ var/decl/sprite_accessory/hair_decl = GET_DECL(hair_style) hair_styles[++hair_styles.len] = list("hairstyle" = hair_decl.name, "ref" = "\ref[hair_decl]") data["hair_styles"] = hair_styles - var/decl/sprite_accessory/hair = GET_DECL(owner.h_style) + var/hairstyle = owner.get_hairstyle() + var/decl/sprite_accessory/hair = GET_DECL(hairstyle) data["hair_style"] = hair.name data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) @@ -129,7 +130,8 @@ var/decl/sprite_accessory/facial_hair_decl = GET_DECL(facial_hair_style) facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_decl.name, "ref" = "\ref[facial_hair_decl]") data["facial_hair_styles"] = facial_hair_styles - var/decl/sprite_accessory/facial_hair = GET_DECL(owner.f_style) + var/facial_hairstyle = owner.get_facial_hairstyle() + var/decl/sprite_accessory/facial_hair = GET_DECL(facial_hairstyle) data["facial_hair_style"] = facial_hair.name data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) diff --git a/code/modules/organs/ailments/_ailment.dm b/code/modules/organs/ailments/_ailment.dm index daa00fbe4bb..101f4bb8dd8 100644 --- a/code/modules/organs/ailments/_ailment.dm +++ b/code/modules/organs/ailments/_ailment.dm @@ -56,7 +56,7 @@ /datum/ailment/proc/begin_ailment_event() if(!organ?.owner) return - timer_id = addtimer(CALLBACK(src, .proc/do_malfunction), rand(min_time, max_time), TIMER_STOPPABLE | TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_NO_HASH_WAIT) + timer_id = addtimer(CALLBACK(src, PROC_REF(do_malfunction)), rand(min_time, max_time), TIMER_STOPPABLE | TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_NO_HASH_WAIT) /datum/ailment/proc/do_malfunction() if(!organ?.owner) diff --git a/code/modules/organs/ailments/ailment_codex.dm b/code/modules/organs/ailments/ailment_codex.dm index 8cc388bcb80..a60d78ad2e3 100644 --- a/code/modules/organs/ailments/ailment_codex.dm +++ b/code/modules/organs/ailments/ailment_codex.dm @@ -1,14 +1,12 @@ -/datum/codex_entry/ailments - name = "Medical Ailments" - lore_text = "Day to day life can exert stress on the body, which can manifest in small, non-critical medical conditions like a sore back or a \ - headache. 9/10 doctors recommend a visit to your local physician for treatment before they compound into a chronic or acute condition." - mechanics_text = "Ailments are minor medical conditions that can crop up during a round. They aren't life-threatening, and \ - frequently aren't anything more than slightly annoying, and treating them is generally straightforward." +/datum/codex_entry/guide/ailments + name = "Guide to Medical Ailments" + mechanics_text = "Ailments are minor medical conditions that can crop up during a round. They aren't life-threatening, and frequently aren't anything more than slightly annoying, and treating them is generally straightforward." + lore_text = "Day to day life can exert stress on the body, which can manifest in small, non-critical medical conditions like a sore back or a headache. 9/10 doctors recommend a visit to your local physician for treatment before they compound into a chronic or acute condition." var/show_robotics_recipes = FALSE var/name_column = "Ailment" var/treatment_column = "Recommended treatment" -/datum/codex_entry/ailments/robotic +/datum/codex_entry/guide/ailments/robotic name = "Prosthetic Faults" lore_text = "Prosthetic limbs can be prone to debilitating and often dangerous faults, especially if exposed to hostile conditions." mechanics_text = "EMP damage or improper installation can cause prosthetic limbs to develop problems, some of them more serious than others." @@ -36,7 +34,7 @@ return "stimulant drugs" return null -/datum/codex_entry/ailments/New() +/datum/codex_entry/guide/ailments/New() var/list/ailment_table = list("") ailment_table += "" for(var/atype in subtypesof(/datum/ailment)) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 6d223a855ac..89abfd941d8 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -12,7 +12,7 @@ abstract_type = /obj/item/organ/external var/slowdown = 0 - var/tmp/icon_cache_key + var/tmp/_icon_cache_key // Strings var/broken_description // fracture string if any. var/damage_state = "00" // Modifier used for generating the on-mob damage overlay for this limb. @@ -32,7 +32,6 @@ // Appearance vars. var/body_part = null // Part flag var/icon_position = 0 // Used in mob overlay layering calculations. - var/icon/mob_icon // Cached icon for use in mob overlays. var/skin_tone // Skin tone. var/skin_colour // skin colour var/skin_blend = ICON_ADD // How the skin colour is applied. @@ -124,15 +123,17 @@ LAZYREMOVE(owner.bad_external_organs, src) /obj/item/organ/external/set_species(specie_name) + _icon_cache_key = null . = ..() skin_blend = bodytype.limb_blend for(var/attack_type in species.unarmed_attacks) var/decl/natural_attack/attack = GET_DECL(attack_type) if(istype(attack) && (organ_tag in attack.usable_with_limbs)) LAZYADD(unarmed_attacks, attack_type) - get_icon() + update_icon() /obj/item/organ/external/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE) + _icon_cache_key = null var/decl/bodytype/old_bodytype = bodytype . = ..(new_bodytype, override_material) if(bodytype != old_bodytype && apply_to_internal_organs) @@ -141,6 +142,14 @@ if(.) update_icon(TRUE) +/obj/item/organ/external/set_dna(var/datum/dna/new_dna) + _icon_cache_key = null + return ..() + +/obj/item/organ/external/reset_status() + _icon_cache_key = null + return ..() + /obj/item/organ/external/proc/set_bodytype_with_children(decl/bodytype/new_bodytype, override_material = null) set_bodytype(new_bodytype, override_material) for(var/obj/item/organ/external/child in children) @@ -447,11 +456,8 @@ // //If we contain any child organs add them to the owner // - for(var/obj/item/organ/organ in internal_organs) - owner.add_organ(organ, src, in_place, update_icon, detached) - - for(var/obj/item/organ/external/organ in children) - owner.add_organ(organ, src, in_place, update_icon, detached) + for(var/obj/item/organ/organ in (implants|children|internal_organs)) + owner.add_organ(organ, src, in_place, update_icon, FALSE) // //Add any existing organs in the owner that have us as parent @@ -648,7 +654,7 @@ This function completely restores a damaged organ to perfect condition. switch(type) if(BURN) fluid_loss_severity = FLUIDLOSS_WIDE_BURN if(LASER) fluid_loss_severity = FLUIDLOSS_CONC_BURN - var/fluid_loss = (damage/(owner.get_max_health() - config.health_threshold_dead)) * SPECIES_BLOOD_DEFAULT * fluid_loss_severity + var/fluid_loss = (damage/(owner.get_max_health() - get_config_value(/decl/config/num/health_health_threshold_dead))) * SPECIES_BLOOD_DEFAULT * fluid_loss_severity owner.remove_blood(fluid_loss) // first check whether we can widen an existing wound @@ -873,12 +879,12 @@ Note that amputating the affected organ does in fact remove the infection from t // we only update wounds once in [wound_update_accuracy] ticks so have to emulate realtime heal_amt = heal_amt * wound_update_accuracy // configurable regen speed woo, no-regen hardcore or instaheal hugbox, choose your destiny - heal_amt = heal_amt * config.organ_regeneration_multiplier + heal_amt = heal_amt * get_config_value(/decl/config/num/health_organ_regeneration_multiplier) // Apply a modifier based on how stressed we currently are. if(owner) var/stress_modifier = owner.get_stress_modifier() if(stress_modifier) - heal_amt *= 1-(config.stress_healing_recovery_constant * stress_modifier) + heal_amt *= 1-(get_config_value(/decl/config/num/health_stress_healing_recovery_constant) * stress_modifier) // amount of healing is spread over all the wounds heal_amt = heal_amt / (LAZYLEN(wounds) + 1) // making it look prettier on scanners @@ -895,7 +901,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(update_surgery) owner.update_surgery() if (update_damstate()) - owner.update_damage_icon(TRUE) + owner.update_damage_overlays(TRUE) //Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status. /obj/item/organ/external/proc/update_damages() @@ -942,8 +948,8 @@ Note that amputating the affected organ does in fact remove the infection from t var/n_is = damage_state_text() if (n_is != damage_state) damage_state = n_is - return 1 - return 0 + return TRUE + return FALSE // new damage icon system // returns just the brute/burn damage code @@ -1033,8 +1039,8 @@ Note that amputating the affected organ does in fact remove the infection from t if(species && istype(., /obj/effect/decal/cleanable/blood/gibs)) var/obj/effect/decal/cleanable/blood/gibs/G = . - G.fleshcolor = species.get_flesh_colour(owner) - G.basecolor = species.get_blood_color(owner) + G.fleshcolor = species.get_species_flesh_color(owner) + G.basecolor = species.get_species_blood_color(owner) G.update_icon() //Handles dismemberment @@ -1217,7 +1223,7 @@ Note that amputating the affected organ does in fact remove the infection from t I.exposed() /obj/item/organ/external/proc/fracture() - if(!config.bones_can_break) + if(!get_config_value(/decl/config/toggle/on/health_bones_can_break)) return if(BP_IS_PROSTHETIC(src)) return //ORGAN_BROKEN doesn't have the same meaning for robot limbs @@ -1252,7 +1258,7 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/proc/mend_fracture() if(BP_IS_PROSTHETIC(src)) return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs - if(brute_dam > min_broken_damage * config.organ_health_multiplier) + if(brute_dam > min_broken_damage * get_config_value(/decl/config/num/health_organ_health_multiplier)) return 0 //will just immediately fracture again status &= ~ORGAN_BROKEN @@ -1343,6 +1349,7 @@ Note that amputating the affected organ does in fact remove the infection from t W.forceMove(owner) /obj/item/organ/external/do_uninstall(in_place, detach, ignore_children, update_icon) + var/mob/living/carbon/human/victim = owner //parent proc clears owner if(!(. = ..())) return @@ -1422,7 +1429,7 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/set_detached(is_detached) if(BP_IS_PROSTHETIC(src)) is_detached = FALSE //External prosthetics are never detached - return ..(is_detached) + . = ..(is_detached) /obj/item/organ/external/proc/disfigure(var/type = BRUTE) if(status & ORGAN_DISFIGURED) diff --git a/code/modules/organs/external/_external_damage.dm b/code/modules/organs/external/_external_damage.dm index 32dab6dae8b..ca5c44974f9 100644 --- a/code/modules/organs/external/_external_damage.dm +++ b/code/modules/organs/external/_external_damage.dm @@ -49,9 +49,9 @@ //If limb took enough damage, try to cut or tear it off if(owner && loc == owner) owner.update_health() //droplimb will call update_health() again if it does end up being called - if((limb_flags & ORGAN_FLAG_CAN_AMPUTATE) && config.limbs_can_break) + if((limb_flags & ORGAN_FLAG_CAN_AMPUTATE) && get_config_value(/decl/config/toggle/on/health_limbs_can_break)) var/total_damage = brute_dam + burn_dam + brute + burn + spillover - var/threshold = max_damage * config.organ_health_multiplier + var/threshold = max_damage * get_config_value(/decl/config/num/health_organ_health_multiplier) if(total_damage > threshold) if(attempt_dismemberment(pure_brute, burn, sharp, edge, used_weapon, spillover, total_damage > threshold*6, override_droplimb = override_droplimb)) return @@ -109,7 +109,7 @@ //If there are still hurties to dispense if (spillover) - owner.shock_stage += spillover * config.organ_damage_spillover_multiplier + owner.shock_stage += spillover * get_config_value(/decl/config/num/health_organ_damage_spillover_multiplier) // sync the organ's damage with its wounds update_damages() @@ -118,7 +118,7 @@ owner.update_bandages() if(owner && update_damstate()) - owner.update_damage_icon() + owner.update_damage_overlays() if(created_wound && isobj(used_weapon)) var/obj/O = used_weapon diff --git a/code/modules/organs/external/_external_icons.dm b/code/modules/organs/external/_external_icons.dm index 569c4b67066..aa77c6e51fc 100644 --- a/code/modules/organs/external/_external_icons.dm +++ b/code/modules/organs/external/_external_icons.dm @@ -4,27 +4,31 @@ var/global/list/limb_icon_cache = list() return ..(SOUTH) /obj/item/organ/external/proc/compile_icon() - //#FIXME: We REALLY shouldn't be messing with overlays outside on_update_icon. And on_update_icon doesn't call this. - cut_overlays() // This is a kludge, only one icon has more than one generation of children though. for(var/obj/item/organ/external/organ in contents) if(organ.children && organ.children.len) for(var/obj/item/organ/external/child in organ.children) - add_overlay(child.mob_icon) - add_overlay(organ.mob_icon) + child.update_icon() + child.compile_overlays() + organ.update_icon() + organ.compile_overlays() + update_icon() + compile_overlays() /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) + _icon_cache_key = null skin_tone = null skin_colour = null - hair_colour = human.hair_colour + hair_colour = human.get_hair_colour() // This used to do a bodytype set but that was *really really bad.* Things that need that should do it themselves. skin_blend = bodytype.limb_blend if(!isnull(human.skin_tone) && bodytype?.appearance_flags & HAS_A_SKIN_TONE) skin_tone = human.skin_tone if(bodytype.appearance_flags & HAS_SKIN_COLOR) - skin_colour = human.skin_colour + skin_colour = human.get_skin_colour() /obj/item/organ/external/proc/sync_colour_to_dna() + _icon_cache_key = null skin_tone = null skin_colour = null hair_colour = rgb(dna.GetUIValue(DNA_UI_HAIR_R),dna.GetUIValue(DNA_UI_HAIR_G),dna.GetUIValue(DNA_UI_HAIR_B)) @@ -42,18 +46,8 @@ var/global/list/limb_icon_cache = list() update_icon(1) if(last_owner) SetName("[last_owner.real_name]'s head") - addtimer(CALLBACK(last_owner, /mob/proc/update_hair), 1, TIMER_UNIQUE) - . = ..() - //Head markings, duplicated (sadly) below. - for(var/M in markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - if (mark_style.draw_target == MARKING_TARGET_SKIN) - var/mark_color = markings[M] - var/icon/mark_s = mark_style.get_cached_marking_icon(bodytype, icon_state, mark_color) - //#TODO: This probably should be added to a list that's applied on update icon, otherwise its gonna act really wonky! - add_overlay(mark_s) //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, mark_style.layer_blend) //So when it's on your body, it has icons - icon_cache_key += "[M][mark_color]" + addtimer(CALLBACK(last_owner, TYPE_PROC_REF(/mob, update_hair)), 1, TIMER_UNIQUE) + return ..() /obj/item/organ/external/proc/update_limb_icon_file() if(!BP_IS_PROSTHETIC(src) && (status & ORGAN_MUTATED)) @@ -63,51 +57,92 @@ var/global/list/limb_icon_cache = list() else icon = bodytype.get_base_icon(owner) -/obj/item/organ/external/on_update_icon(var/regenerate = 0) - . = ..() - icon_state = organ_tag - icon_cache_key = "[icon_state]_[species.name][bodytype.name][render_alpha]" +var/global/list/organ_icon_cache = list() +/obj/item/organ/external/proc/generate_mob_icon() - update_limb_icon_file() - mob_icon = apply_colouration(new/icon(icon, icon_state)) + // Generate base icon with colour and tone. + var/icon/ret = bodytype.apply_limb_colouration(src, new /icon(icon, icon_state)) + if(status & ORGAN_DEAD) + ret.ColorTone(rgb(10,50,0)) + ret.SetIntensity(0.7) + if(skin_tone) + if(skin_tone >= 0) + ret.Blend(rgb(skin_tone, skin_tone, skin_tone), ICON_ADD) + else + ret.Blend(rgb(-skin_tone, -skin_tone, -skin_tone), ICON_SUBTRACT) + if((bodytype.appearance_flags & HAS_SKIN_COLOR) && skin_colour) + ret.Blend(skin_colour, skin_blend) - //Body markings, does not include head, duplicated (sadly) above. + //Body markings. for(var/M in markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - if (mark_style.draw_target == MARKING_TARGET_SKIN) - var/mark_color = markings[M] - var/icon/mark_s = mark_style.get_cached_marking_icon(bodytype, icon_state, mark_color) - //#TODO: This probably should be added to a list that's applied on update icon, otherwise its gonna act really wonky! - add_overlay(mark_s) //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, mark_style.layer_blend) //So when it's on your body, it has icons - icon_cache_key += "[M][mark_color]" - + var/decl/sprite_accessory/marking/mark_style = resolve_accessory_to_decl(M) + if(mark_style && !mark_style.sprite_overlay_layer) + ret.Blend(mark_style.get_cached_accessory_icon(src, markings[M]), mark_style.layer_blend) if(render_alpha < 255) - mob_icon += rgb(,,,render_alpha) + ret += rgb(,,,render_alpha) + global.organ_icon_cache[_icon_cache_key] = ret + return ret - icon = mob_icon +/obj/item/organ/external/proc/get_mob_overlays() + for(var/M in markings) + var/decl/sprite_accessory/marking/mark_style = resolve_accessory_to_decl(M) + if(mark_style?.sprite_overlay_layer) + var/image/mark_image = image(mark_style.get_cached_accessory_icon(src, markings[M])) + mark_image.layer = mark_style.sprite_overlay_layer + LAZYADD(., mark_image) + +/obj/item/organ/external/proc/get_icon_cache_key_components() + . = list("[icon_state]_[species.name]_[bodytype.name]_[render_alpha]_[icon]") + for(var/M in markings) + var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) + if(!mark_style.sprite_overlay_layer) + . += "_[M][markings[M]]" + if(status & ORGAN_DEAD) + . += "_dead" + . += "_tone_[skin_tone]_color_[skin_colour]_[skin_blend]" -/obj/item/organ/external/proc/get_icon() - update_icon() - return mob_icon +/obj/item/organ/external/on_update_icon() + . = ..() -// Returns an image for use by the human health dolly HUD element. -// If the limb is in pain, it will be used as a minimum damage -// amount to represent the obfuscation of being in agonizing pain. + // Update our cache key and refresh or create our base icon. + update_limb_icon_file() + if(icon_state != organ_tag) + icon_state = organ_tag + _icon_cache_key = jointext(get_icon_cache_key_components(), null) + var/icon/mob_icon = global.organ_icon_cache[_icon_cache_key] || generate_mob_icon() + if(icon != mob_icon) + icon = mob_icon + + // We may have some overlays of our own (hair, glowing eyes, layered markings) + var/list/additional_overlays = get_mob_overlays() + if(length(additional_overlays)) + for(var/new_overlay in additional_overlays) + add_overlay(new_overlay) + + // If we've been severed, we may contain child organs that should be rendered (feet on legs etc). + if(!owner && length(contents)) + for(var/obj/item/organ/external/child in contents) + child.update_icon() + child.compile_overlays() // We need the appearance immediately. + add_overlay(child) // Global scope, used in code below. var/global/list/flesh_hud_colours = list("#00ff00","#aaff00","#ffff00","#ffaa00","#ff0000","#aa0000","#660000") var/global/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888","#666666","#444444","#222222","#000000") +// Returns an image for use by the human health dolly HUD element. +// If the limb is in pain, it will be used as a minimum damage +// amount to represent the obfuscation of being in agonizing pain. /obj/item/organ/external/proc/get_damage_hud_image() // Generate the greyscale base icon and cache it for later. // icon_cache_key is set by any get_icon() calls that are made. // This looks convoluted, but it's this way to avoid icon proc calls. if(!hud_damage_image) - var/cache_key = "dambase-[icon_cache_key]" - if(!icon_cache_key || !limb_icon_cache[cache_key]) - limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH) + update_icon() + var/cache_key = "dambase-[_icon_cache_key]" + if(!cache_key || !limb_icon_cache[cache_key]) + limb_icon_cache[cache_key] = icon(icon, null, SOUTH) var/image/temp = image(limb_icon_cache[cache_key]) if(species) // Calculate the required colour matrix. @@ -130,27 +165,6 @@ var/global/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888" hud_damage_image.color = hud_colours[max(1,min(CEILING(dam_state*hud_colours.len),hud_colours.len))] return hud_damage_image -/obj/item/organ/external/proc/apply_colouration(var/icon/applying) - - applying = bodytype.apply_limb_colouration(src, applying) - if(status & ORGAN_DEAD) - icon_cache_key += "_dead" - applying.ColorTone(rgb(10,50,0)) - applying.SetIntensity(0.7) - - if(skin_tone) - if(skin_tone >= 0) - applying.Blend(rgb(skin_tone, skin_tone, skin_tone), ICON_ADD) - else - applying.Blend(rgb(-skin_tone, -skin_tone, -skin_tone), ICON_SUBTRACT) - icon_cache_key += "_tone_[skin_tone]" - if(bodytype.appearance_flags & HAS_SKIN_COLOR) - if(skin_colour) - applying.Blend(skin_colour, skin_blend) - icon_cache_key += "_color_[skin_colour]_[skin_blend]" - - return applying - /obj/item/organ/external/proc/bandage_level() if(damage_state_text() == "00") return 0 @@ -163,4 +177,15 @@ var/global/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888" else if (burn_dam + brute_dam < (max_damage * 0.75 / 2)) . = 2 else - . = 3 \ No newline at end of file + . = 3 + +/obj/item/organ/external/proc/resolve_accessory_to_decl(var/decl/sprite_accessory/accessory_style) + if(ispath(accessory_style)) + accessory_style = GET_DECL(accessory_style) + // Check if this style is permitted for this species, period. + if(!accessory_style.accessory_is_available(owner, species, bodytype)) + return null + // Check if we are concealed (long hair under a hat for example). + if(accessory_style.is_hidden(src)) + return accessory_style.get_hidden_substitute() + return accessory_style diff --git a/code/modules/organs/external/head.dm b/code/modules/organs/external/head.dm index 14ebb37894a..9ea8af56647 100644 --- a/code/modules/organs/external/head.dm +++ b/code/modules/organs/external/head.dm @@ -16,23 +16,23 @@ limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_HEALS_OVERKILL | ORGAN_FLAG_CAN_BREAK | ORGAN_FLAG_CAN_DISLOCATE - var/draw_eyes = TRUE var/glowing_eyes = FALSE var/can_intake_reagents = TRUE var/has_lips = TRUE var/forehead_graffiti var/graffiti_style -/obj/item/organ/external/head/proc/get_eye_overlay() - if(glowing_eyes || owner?.has_chemical_effect(CE_GLOWINGEYES, 1)) - var/obj/item/organ/internal/eyes/eyes = owner.get_organ((owner.get_bodytype().vision_organ || BP_EYES), /obj/item/organ/internal/eyes) - if(eyes) - return eyes.get_special_overlay() - -/obj/item/organ/external/head/proc/get_eyes() - var/obj/item/organ/internal/eyes/eyes = owner.get_organ((owner.get_bodytype().vision_organ || BP_EYES), /obj/item/organ/internal/eyes) - if(eyes) - return eyes.get_onhead_icon() +/obj/item/organ/external/head/proc/get_organ_eyes_overlay() + if(!glowing_eyes && !owner?.has_chemical_effect(CE_GLOWINGEYES, 1)) + return + var/obj/item/organ/internal/eyes/eyes = get_eyes_organ() + var/icon/eyes_icon = eyes?.get_onhead_icon() // refreshes cache key + if(!eyes_icon) + return + var/cache_key = "[eyes.last_eye_cache_key]-glow" + if(!global.eye_icon_cache[cache_key]) + global.eye_icon_cache[cache_key] = emissive_overlay(eyes_icon, "") + return global.eye_icon_cache[cache_key] /obj/item/organ/external/head/examine(mob/user) . = ..() @@ -79,7 +79,6 @@ . = ..() has_lips = (bodytype.appearance_flags & HAS_LIPS) can_intake_reagents = !(bodytype.body_flags & BODY_FLAG_NO_EAT) - draw_eyes = bodytype.has_eyes /obj/item/organ/external/head/take_external_damage(brute, burn, damage_flags, used_weapon, override_droplimb) . = ..() @@ -90,75 +89,53 @@ if (burn_dam > 40) disfigure(BURN) -/obj/item/organ/external/head/on_update_icon() - - ..() - +/obj/item/organ/external/head/proc/get_eyes_organ() + RETURN_TYPE(/obj/item/organ/internal/eyes) if(owner) - // Base eye icon. - if(draw_eyes) - var/icon/I = get_eyes() - if(I) - overlays |= I - mob_icon.Blend(I, ICON_OVERLAY) - - // Floating eyes or other effects. - var/image/eye_glow = get_eye_overlay() - if(eye_glow) - overlays |= eye_glow - - if(owner.lip_style && (bodytype.appearance_flags & HAS_LIPS)) - var/icon/lip_icon = new/icon(bodytype.get_lip_icon(owner) || 'icons/mob/human_races/species/lips.dmi', "lipstick_s") - lip_icon.Blend(owner.lip_style, ICON_MULTIPLY) - overlays |= lip_icon - mob_icon.Blend(lip_icon, ICON_OVERLAY) - - overlays |= get_hair_icon() - - return mob_icon - -/obj/item/organ/external/head/proc/get_hair_icon() - var/image/res = image(bodytype.icon_template,"") - if(!owner) - return res + return owner.get_organ((owner.get_bodytype().vision_organ || BP_EYES), /obj/item/organ/internal/eyes) + return locate(/obj/item/organ/internal/eyes) in contents - if(owner.f_style) - var/decl/sprite_accessory/facial_hair_style = GET_DECL(owner.f_style) +/obj/item/organ/external/head/get_icon_cache_key_components() + . = ..() + if(bodytype.has_eyes) + . += "_eyes[get_eyes_organ()?.eye_colour][bodytype.eye_icon]" + if(bodytype.appearance_flags & HAS_LIPS) + var/lip_icon = bodytype.get_lip_icon(owner) + if(lip_icon) + . += "_lips[lip_icon][owner?.lip_color || "skip"]" + +/obj/item/organ/external/head/generate_mob_icon() + var/icon/ret = ..() + // Eye icon. + if(bodytype.has_eyes) + var/icon/eyes_icon = get_eyes_organ()?.get_onhead_icon() + if(eyes_icon) + ret.Blend(eyes_icon, ICON_OVERLAY) + // Lip icon. + if(owner && (bodytype.appearance_flags & HAS_LIPS)) + var/lip_icon = bodytype.get_lip_icon(owner) + if(lip_icon) + var/lip_color = owner?.lip_color + if(lip_color) + var/icon/lip_appearance = new/icon(lip_icon, "lipstick_s") + lip_appearance.Blend(lip_color || COLOR_BLACK, ICON_MULTIPLY) + ret.Blend(lip_appearance, ICON_OVERLAY) + return ret + +/obj/item/organ/external/head/get_mob_overlays() + . = ..() + var/image/eye_glow = get_organ_eyes_overlay() + if(eye_glow) + LAZYADD(., eye_glow) + if(!owner) + return + var/facial_hairstyle = owner.get_facial_hairstyle() + if(facial_hairstyle) + var/decl/sprite_accessory/facial_hair_style = resolve_accessory_to_decl(facial_hairstyle) if(facial_hair_style?.accessory_is_available(owner, species, bodytype)) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(owner.facial_hair_colour && facial_hair_style.do_colouration) - facial_s.Blend(owner.facial_hair_colour, facial_hair_style.blend) - res.overlays |= facial_s - - if(owner.h_style) - var/decl/sprite_accessory/hair/hair_style = GET_DECL(owner.h_style) - var/obj/item/head = owner.get_equipped_item(slot_head_str) - if(head && (head.flags_inv & BLOCK_HEAD_HAIR)) - if(!(hair_style.flags & VERY_SHORT)) - hair_style = GET_DECL(/decl/sprite_accessory/hair/short) + LAZYADD(., image(facial_hair_style.get_cached_accessory_icon(src, owner.get_facial_hair_colour()))) + var/hairstyle = owner.get_hairstyle() + if(hairstyle) + var/decl/sprite_accessory/hair/hair_style = resolve_accessory_to_decl(hairstyle) if(hair_style?.accessory_is_available(owner, species, bodytype)) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(hair_style.do_colouration && hair_colour) - hair_s.Blend(hair_colour, hair_style.blend) - res.overlays |= hair_s - - for (var/M in markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - if (mark_style.draw_target == MARKING_TARGET_HAIR) - - var/mark_color - if (!mark_style.do_colouration && owner.h_style) - var/decl/sprite_accessory/hair/hair_style = GET_DECL(owner.h_style) - if ((~hair_style.flags & HAIR_BALD) && hair_colour) - mark_color = hair_colour - else //only baseline human skin tones; others will need species vars for coloration - mark_color = rgb(200 + skin_tone, 150 + skin_tone, 123 + skin_tone) - else - mark_color = markings[M] - res.overlays |= mark_style.get_cached_marking_icon(bodytype, icon_state, mark_color) - icon_cache_key += "[M][mark_color]" - - return res - -/obj/item/organ/external/head/no_eyes - draw_eyes = FALSE + LAZYADD(., image(hair_style.get_cached_accessory_icon(src, owner.get_hair_colour()))) diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm index 009577fb2d4..28b6da02c03 100644 --- a/code/modules/organs/internal/_internal.dm +++ b/code/modules/organs/internal/_internal.dm @@ -24,6 +24,9 @@ var/min_bruised_damage = 10 // Damage before considered bruised var/damage_reduction = 0.5 //modifier for internal organ injury + /// Whether or not we should try to transfer a brainmob when removed or replaced in a mob. + var/transfer_brainmob_with_organ = FALSE + /obj/item/organ/internal/Initialize(mapload, material_key, datum/dna/given_dna, decl/bodytype/new_bodytype) if(!alive_icon) alive_icon = initial(icon_state) @@ -253,3 +256,43 @@ var/obj/item/organ/O = last_owner.get_organ(parent_organ) if(O) O.vital_to_owner = null + +// Stub to allow brain interfaces to return their wrapped brainmob. +/obj/item/organ/internal/proc/get_brainmob(var/create_if_missing = FALSE) + return + +/obj/item/organ/internal/proc/transfer_key_to_brainmob(var/mob/living/M, var/update_brainmob = TRUE) + var/mob/living/brainmob = get_brainmob(create_if_missing = TRUE) + if(brainmob) + transfer_key_from_mob_to_mob(M, brainmob) + if(update_brainmob) + brainmob.SetName(M.real_name) + brainmob.real_name = M.real_name + brainmob.dna = M.dna?.Clone() + brainmob.languages = M.languages?.Copy() + brainmob.default_language = M.default_language + to_chat(brainmob, SPAN_NOTICE("You feel slightly disoriented. That's normal when you're just \a [initial(src.name)].")) + callHook("debrain", list(brainmob)) + return TRUE + return FALSE + +/obj/item/organ/internal/proc/get_synthetic_owner_name() + return "Cyborg" + +/obj/item/organ/internal/preserve_in_cryopod(var/obj/machinery/cryopod/pod) + var/mob/living/brainmob = get_brainmob() + return brainmob?.key + +// This might need revisiting to stop people successfully implanting brains in groins and transferring minds. +/obj/item/organ/internal/do_install(mob/living/carbon/human/target, obj/item/organ/external/affected, in_place, update_icon, detached) + . = ..() + if(transfer_brainmob_with_organ && istype(owner)) + var/mob/living/brainmob = get_brainmob(create_if_missing = FALSE) + if(brainmob?.key) + transfer_key_from_mob_to_mob(brainmob, owner) + +/obj/item/organ/internal/do_uninstall(in_place, detach, ignore_children, update_icon) + var/mob/living/victim = owner // cleared in parent proc + . = ..() + if(transfer_brainmob_with_organ && istype(victim)) + transfer_key_to_brainmob(victim, update_brainmob = TRUE) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 3d7801a5ff6..d84032440d0 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -9,48 +9,63 @@ throwforce = 1 throw_speed = 3 throw_range = 5 - origin_tech = "{'biotech':3}" + origin_tech = @'{"biotech":3}' attack_verb = list("attacked", "slapped", "whacked") relative_size = 85 damage_reduction = 0 scale_max_damage_to_species_health = FALSE - var/can_use_mmi = TRUE - var/mob/living/carbon/brain/brainmob = null + transfer_brainmob_with_organ = TRUE + var/can_use_brain_interface = TRUE var/should_announce_brain_damage = TRUE var/oxygen_reserve = 6 + VAR_PRIVATE/mob/living/_brainmob = /mob/living/brain + +/obj/item/organ/internal/brain/get_brainmob(var/create_if_missing = FALSE) + if(!istype(_brainmob) && create_if_missing) + initialize_brainmob() + if(istype(_brainmob)) + return _brainmob + +/obj/item/organ/internal/brain/Initialize() + . = ..() + if(species) + set_max_damage(species.total_health) + else + set_max_damage(200) + +/obj/item/organ/internal/brain/proc/initialize_brainmob() + if(istype(_brainmob)) + return + if(!ispath(_brainmob)) + _brainmob = initial(_brainmob) + if(ispath(_brainmob)) + _brainmob = new _brainmob(src) + else + _brainmob = null /obj/item/organ/internal/brain/getToxLoss() return 0 /obj/item/organ/internal/brain/set_species(species_name) . = ..() + icon_state = "brain-prosthetic" if(species) set_max_damage(species.total_health) else set_max_damage(200) /obj/item/organ/internal/brain/Destroy() - QDEL_NULL(brainmob) + if(istype(_brainmob)) + QDEL_NULL(_brainmob) . = ..() -/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H) - - if(!brainmob) - brainmob = new(src) - brainmob.SetName(H.real_name) - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - brainmob.timeofhostdeath = H.timeofdeath - - if(H.mind) - H.mind.transfer_to(brainmob) - - to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just \a [initial(src.name)].") - callHook("debrain", list(brainmob)) - -/obj/item/organ/internal/brain/examine(mob/user) +/obj/item/organ/internal/brain/examine(mob/user, var/distance) . = ..() - if(brainmob && brainmob.client)//if thar be a brain inside... the brain. + if(distance <= 1) + show_brain_status(user) + +/obj/item/organ/internal/brain/proc/show_brain_status(mob/user) + if(istype(_brainmob) && _brainmob?.client) //if thar be a brain inside... the brain. to_chat(user, "You can feel the small spark of life still left in this one.") else to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later..") @@ -67,21 +82,6 @@ if(!(. = ..())) return -/obj/item/organ/internal/brain/on_remove_effects() - if(istype(owner)) - transfer_identity(owner) - return ..() - -/obj/item/organ/internal/brain/on_add_effects() - if(brainmob) - if(brainmob.mind) - if(owner.key) - owner.ghostize() - brainmob.mind.transfer_to(owner) - else - owner.key = brainmob.key - return ..() - /obj/item/organ/internal/brain/can_recover() return !(status & ORGAN_DEAD) @@ -172,7 +172,7 @@ SET_STATUS_MAX(owner, STAT_PARA, damage_secondary) SET_STATUS_MAX(owner, STAT_WEAK, round(damage, 1)) if(prob(30)) - addtimer(CALLBACK(src, .proc/brain_damage_callback, damage), rand(6, 20) SECONDS, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(brain_damage_callback), damage), rand(6, 20) SECONDS, TIMER_UNIQUE) /obj/item/organ/internal/brain/proc/brain_damage_callback(var/damage) //Confuse them as a somewhat uncommon aftershock. Side note: Only here so a spawn isn't used. Also, for the sake of a unique timer. if(!QDELETED(owner)) @@ -221,7 +221,7 @@ /obj/item/organ/internal/brain/surgical_fix(mob/user) var/blood_volume = owner.get_blood_oxygenation() if(blood_volume < BLOOD_VOLUME_SURVIVE) - to_chat(user, "Parts of [src] didn't survive the procedure due to lack of air supply!") + to_chat(user, SPAN_DANGER("Parts of \the [src] didn't survive the procedure due to lack of air supply!")) set_max_damage(FLOOR(max_damage - 0.25*damage)) heal_damage(damage) @@ -229,4 +229,9 @@ . = (species.total_health - max_damage)/species.total_health /obj/item/organ/internal/brain/get_mechanical_assisted_descriptor() - return "machine-interface [name]" \ No newline at end of file + return "machine-interface [name]" + +/obj/item/organ/internal/brain/die() + if(istype(_brainmob) && _brainmob.stat != DEAD) + _brainmob.death() + ..() diff --git a/code/modules/organs/internal/brain_computer.dm b/code/modules/organs/internal/brain_computer.dm new file mode 100644 index 00000000000..50249a47e4e --- /dev/null +++ b/code/modules/organs/internal/brain_computer.dm @@ -0,0 +1,93 @@ +// Robobrain. +/obj/item/organ/internal/brain/robotic + name = "computer intelligence core" + desc = "The pinnacle of artifical intelligence technology, conveniently stored in a fist-sized cube." + icon = 'icons/obj/items/brain_interface_robotic.dmi' + origin_tech = @'{"engineering":4,"materials":4,"wormholes":2,"programming":4}' + material = /decl/material/solid/metal/steel + matter = list( + /decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT, + /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, + /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE, + /decl/material/solid/phoron = MATTER_AMOUNT_TRACE, + /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE + ) + can_use_brain_interface = FALSE + var/searching = FALSE + var/brain_name + +/obj/item/organ/internal/brain/robotic/handle_severe_damage() + return // TODO: computer maladies + +/obj/item/organ/internal/brain/robotic/handle_disabilities() + return // TODO: computer maladies + +/obj/item/organ/internal/brain/robotic/Initialize() + . = ..() + set_bodytype(/decl/bodytype/prosthetic/basic_human) + update_icon() + brain_name = "[pick(list("ADA","DOS","GNU","MAC","WIN"))]-[random_id(type,1000,9999)]" + SetName("[name] ([brain_name])") + +/obj/item/organ/internal/brain/robotic/initialize_brainmob() + ..() + if(istype(_brainmob)) + _brainmob.SetName(brain_name) + _brainmob.add_language(/decl/language/machine) + +/obj/item/organ/internal/brain/robotic/on_update_icon() + var/mob/living/brainmob = get_brainmob() + icon_state = get_world_inventory_state() + if(!searching) + if(!brainmob?.key || brainmob.stat == DEAD) + icon_state = "[icon_state]-dead" + else + icon_state = "[icon_state]-full" + +/obj/item/organ/internal/brain/robotic/attack_self(mob/user) + var/mob/living/brainmob = get_brainmob(create_if_missing = TRUE) + if(!brainmob?.key && !searching) + to_chat(user, SPAN_NOTICE("You press the power button and boot up \the [src].")) + searching = TRUE + update_icon() + var/decl/ghosttrap/G = GET_DECL(/decl/ghosttrap/machine_intelligence) + G.request_player(brainmob, "Someone is requesting a personality for a [name].", 1 MINUTE) + addtimer(CALLBACK(src, PROC_REF(reset_search)), 1 MINUTE) + return TRUE + . = ..() + +/obj/item/organ/internal/brain/robotic/proc/reset_search() + searching = FALSE + update_icon() + var/mob/living/brainmob = get_brainmob() + if(!brainmob?.key) + visible_message(SPAN_WARNING("\The [src] emits a series of loud beeps, indicating a failure to boot. Try again in a few minutes.")) + +/obj/item/organ/internal/brain/robotic/attack_ghost(var/mob/observer/ghost/user) + var/mob/living/brainmob = get_brainmob(create_if_missing = TRUE) + if(brainmob?.key) + to_chat(user, SPAN_WARNING("\The [src] is already inhabited; there's no room for you!")) + return TRUE + + var/decl/ghosttrap/G = GET_DECL(/decl/ghosttrap/machine_intelligence) + if(G.assess_candidate(user)) + var/response = alert(user, "Are you sure you wish to possess \the [src]?", "Possess [capitalize(name)]", "Yes", "No") + if(response == "Yes" && brainmob && !brainmob?.key && G.assess_candidate(user)) + G.transfer_personality(user, brainmob) + +/obj/item/organ/internal/brain/robotic/show_brain_status(mob/user) + var/mob/living/brainmob = get_brainmob() + if(brainmob?.key) + switch(brainmob.stat) + if(CONSCIOUS) + if(!brainmob.client) + to_chat(user, SPAN_WARNING("It appears to be in stand-by mode.")) + if(UNCONSCIOUS) + to_chat(user, SPAN_WARNING("It doesn't seem to be responsive.")) + if(DEAD) + to_chat(user, SPAN_WARNING("It appears to be completely inactive.")) + else + to_chat(user, SPAN_WARNING("It appears to be completely inactive.")) + +/obj/item/organ/internal/brain/robotic/get_synthetic_owner_name() + return "Robot" diff --git a/code/modules/organs/internal/cell.dm b/code/modules/organs/internal/cell.dm new file mode 100644 index 00000000000..b9d478150f1 --- /dev/null +++ b/code/modules/organs/internal/cell.dm @@ -0,0 +1,96 @@ +/obj/item/organ/internal/cell + name = "microbattery" + desc = "A small, powerful cell for use in fully prosthetic bodies." + icon_state = "cell" + dead_icon = "cell_bork" + organ_tag = BP_CELL + parent_organ = BP_CHEST + var/open + var/obj/item/cell/cell = /obj/item/cell/hyper + //at 0.8 completely depleted after 60ish minutes of constant walking or 130 minutes of standing still + var/servo_cost = 0.8 + +/obj/item/organ/internal/cell/Initialize() + if(ispath(cell)) + cell = new cell(src) + . = ..() + +/obj/item/organ/internal/cell/proc/percent() + if(!cell) + return 0 + return get_charge()/cell.maxcharge * 100 + +/obj/item/organ/internal/cell/proc/get_charge() + if(!cell) + return 0 + if(status & ORGAN_DEAD) + return 0 + return round(cell.charge*(1 - damage/max_damage)) + +/obj/item/organ/internal/cell/proc/checked_use(var/amount) + if(!is_usable()) + return FALSE + return cell && cell.checked_use(amount) + +/obj/item/organ/internal/cell/proc/use(var/amount) + if(!is_usable()) + return 0 + return cell && cell.use(amount) + +/obj/item/organ/internal/cell/proc/get_power_drain() + var/damage_factor = 1 + 10 * damage/max_damage + return servo_cost * damage_factor + +/obj/item/organ/internal/cell/Process() + ..() + if(!owner) + return + if(owner.stat == DEAD) //not a drain anymore + return + var/cost = get_power_drain() + if(world.time - owner.l_move_time < 15) + cost *= 2 + if(!checked_use(cost) && owner.isSynthetic()) + if(!owner.lying && !owner.buckled) + to_chat(owner, SPAN_WARNING("You don't have enough energy to function!")) + SET_STATUS_MAX(owner, STAT_PARA, 3) + +/obj/item/organ/internal/cell/emp_act(severity) + ..() + if(cell) + cell.emp_act(severity) + +/obj/item/organ/internal/cell/attackby(obj/item/W, mob/user) + if(IS_SCREWDRIVER(W)) + if(open) + open = 0 + to_chat(user, SPAN_NOTICE("You screw the battery panel in place.")) + else + open = 1 + to_chat(user, SPAN_NOTICE("You unscrew the battery panel.")) + + if(IS_CROWBAR(W)) + if(open) + if(cell) + user.put_in_hands(cell) + to_chat(user, SPAN_NOTICE("You remove \the [cell] from \the [src].")) + cell = null + + if (istype(W, /obj/item/cell)) + if(open) + if(cell) + to_chat(user, SPAN_WARNING("There is a power cell already installed.")) + else if(user.try_unequip(W, src)) + cell = W + to_chat(user, SPAN_NOTICE("You insert \the [cell].")) + +/obj/item/organ/internal/cell/on_add_effects() + . = ..() + // This is very ghetto way of rebooting an IPC. TODO better way. + if(owner && owner.stat == DEAD) + owner.set_stat(CONSCIOUS) + owner.visible_message(SPAN_NOTICE("\The [owner] twitches visibly!")) + +/obj/item/organ/internal/cell/listen() + if(get_charge()) + return "faint hum of the power bank" diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index a995091805b..bdb11a3dd1f 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -33,40 +33,39 @@ /obj/item/organ/internal/eyes/robot/Initialize(mapload, material_key, datum/dna/given_dna, decl/bodytype/new_bodytype) . = ..() - verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color_verb verbs |= /obj/item/organ/internal/eyes/proc/toggle_eye_glow -/obj/item/organ/internal/eyes/proc/get_eye_cache_key() +/obj/item/organ/internal/eyes/proc/get_onhead_icon() last_cached_eye_colour = eye_colour last_eye_cache_key = "[type]-[bodytype.eye_icon]-[last_cached_eye_colour]-[bodytype.eye_offset]" - return last_eye_cache_key - -/obj/item/organ/internal/eyes/proc/get_onhead_icon() - var/cache_key = get_eye_cache_key() - if(!human_icon_cache[cache_key]) + if(!bodytype.eye_icon) + return + if(!global.eye_icon_cache[last_eye_cache_key]) var/icon/eyes_icon = icon(icon = bodytype.eye_icon, icon_state = "") if(bodytype.eye_offset) eyes_icon.Shift(NORTH, bodytype.eye_offset) if(bodytype.apply_eye_colour) eyes_icon.Blend(last_cached_eye_colour, bodytype.eye_blend) - human_icon_cache[cache_key] = eyes_icon - return human_icon_cache[cache_key] - -/obj/item/organ/internal/eyes/proc/get_special_overlay() - var/icon/I = get_onhead_icon() - if(I) - var/cache_key = "[last_eye_cache_key]-glow" - if(!human_icon_cache[cache_key]) - human_icon_cache[cache_key] = emissive_overlay(I, "") - return human_icon_cache[cache_key] + global.eye_icon_cache[last_eye_cache_key] = eyes_icon + return global.eye_icon_cache[last_eye_cache_key] /obj/item/organ/internal/eyes/proc/update_colour() if(!owner) return + // Update our eye colour. + var/new_eye_colour if(owner.has_chemical_effect(CE_GLOWINGEYES, 1)) - eye_colour = "#75bdd6" // blue glow, hardcoded for now. + new_eye_colour = "#75bdd6" // blue glow, hardcoded for now. else - eye_colour = owner.eye_colour + new_eye_colour = owner.get_eye_colour() + + if(new_eye_colour && eye_colour != new_eye_colour) + eye_colour = new_eye_colour + // Clear the head cache key so they can update their cached icon. + var/obj/item/organ/external/head/head = GET_EXTERNAL_ORGAN(owner, BP_HEAD) + if(istype(head)) + head._icon_cache_key = null /obj/item/organ/internal/eyes/take_internal_damage(amount, var/silent=0) var/oldbroken = is_broken() @@ -92,16 +91,16 @@ /obj/item/organ/internal/eyes/do_install(mob/living/carbon/human/target, affected, in_place, update_icon, detached) // Apply our eye colour to the target. if(istype(target) && eye_colour) - target.eye_colour = eye_colour + target.set_eye_colour(eye_colour, skip_update = TRUE) target.update_eyes(update_icons = update_icon) if(owner && BP_IS_PROSTHETIC(src)) - verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color_verb verbs |= /obj/item/organ/internal/eyes/proc/toggle_eye_glow . = ..() /obj/item/organ/internal/eyes/do_uninstall(in_place, detach, ignore_children, update_icon) . = ..() - verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color_verb verbs -= /obj/item/organ/internal/eyes/proc/toggle_eye_glow // TODO: FIND A BETTER WAY TO DO THIS @@ -111,33 +110,33 @@ if(BP_IS_PROSTHETIC(src)) name = "optical sensor" icon = 'icons/obj/robot_component.dmi' - verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color_verb verbs |= /obj/item/organ/internal/eyes/proc/toggle_eye_glow else name = initial(name) icon = initial(icon) - verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color_verb verbs -= /obj/item/organ/internal/eyes/proc/toggle_eye_glow update_colour() /obj/item/organ/internal/eyes/get_mechanical_assisted_descriptor() return "retinal overlayed [name]" -/obj/item/organ/internal/eyes/proc/change_eye_color() +/obj/item/organ/internal/eyes/proc/change_eye_color_verb() set name = "Change Eye Color" set desc = "Changes your robotic eye color." set category = "IC" set src in usr if(!owner || !BP_IS_PROSTHETIC(src)) - verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs -= /obj/item/organ/internal/eyes/proc/change_eye_color_verb return if(owner.incapacitated()) return - var/new_eyes = input("Please select eye color.", "Eye Color", owner.eye_colour) as color|null - if(new_eyes && do_after(owner, 10) && owner.change_eye_color(new_eyes)) + var/new_eyes = input("Please select eye color.", "Eye Color", owner.get_eye_colour()) as color|null + if(new_eyes && do_after(owner, 10) && owner.set_eye_colour(new_eyes)) update_colour() // Finally, update the eye icon on the mob. owner.try_refresh_visible_overlays() diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm index e160e318278..c3f3c08ee8b 100644 --- a/code/modules/organs/internal/heart.dm +++ b/code/modules/organs/internal/heart.dm @@ -5,13 +5,13 @@ icon_state = "heart-on" dead_icon = "heart-off" prosthetic_icon = "heart-prosthetic" + damage_reduction = 0.7 + relative_size = 5 + max_damage = 45 var/pulse = PULSE_NORM var/heartbeat = 0 var/beat_sound = 'sound/effects/singlebeat.ogg' var/tmp/next_blood_squirt = 0 - damage_reduction = 0.7 - relative_size = 5 - max_damage = 45 var/open var/list/external_pump @@ -189,6 +189,10 @@ return is_usable() && (pulse > PULSE_NONE || BP_IS_PROSTHETIC(src) || (owner.status_flags & FAKEDEATH)) /obj/item/organ/internal/heart/listen() + + if(!owner || (status & (ORGAN_DEAD|ORGAN_CUT_AWAY))) + return "no pulse" + if(BP_IS_PROSTHETIC(src) && is_working()) if(is_bruised()) return "sputtering pump" diff --git a/code/modules/organs/internal/kidneys.dm b/code/modules/organs/internal/kidneys.dm index 9e92768a937..38f436630bc 100644 --- a/code/modules/organs/internal/kidneys.dm +++ b/code/modules/organs/internal/kidneys.dm @@ -27,10 +27,10 @@ if(is_bruised()) if(prob(5) && REAGENT_VOLUME(reagents, /decl/material/solid/potassium) < 5) - reagents.add_reagent(/decl/material/solid/potassium, REM*5) + add_to_reagents(/decl/material/solid/potassium, REM*5) if(is_broken()) if(REAGENT_VOLUME(owner.reagents, /decl/material/solid/potassium) < 15) - owner.reagents.add_reagent(/decl/material/solid/potassium, REM*2) + owner.add_to_reagents(/decl/material/solid/potassium, REM*2) //If your kidneys aren't working, your body's going to have a hard time cleaning your blood. if(!GET_CHEMICAL_EFFECT(owner, CE_ANTITOX)) diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm index 841f4c03d6f..5b7da364be2 100644 --- a/code/modules/organs/internal/lungs.dm +++ b/code/modules/organs/internal/lungs.dm @@ -332,7 +332,8 @@ root_bodytype.get_environment_discomfort(owner,"cold") /obj/item/organ/internal/lungs/listen() - if(owner.failed_last_breath || !active_breathing) + + if((status & (ORGAN_DEAD|ORGAN_CUT_AWAY)) || !owner || owner.failed_last_breath || !active_breathing) return "no respiration" if(BP_IS_PROSTHETIC(src)) diff --git a/code/modules/organs/internal/posibrain.dm b/code/modules/organs/internal/posibrain.dm deleted file mode 100644 index 210895c6395..00000000000 --- a/code/modules/organs/internal/posibrain.dm +++ /dev/null @@ -1,334 +0,0 @@ -/obj/item/organ/internal/posibrain - name = "positronic brain" - desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." - icon = 'icons/obj/assemblies.dmi' - icon_state = "posibrain" - organ_tag = BP_POSIBRAIN - parent_organ = BP_CHEST - force = 1.0 - w_class = ITEM_SIZE_NORMAL - throwforce = 1 - throw_speed = 3 - throw_range = 5 - origin_tech = "{'engineering':4,'materials':4,'wormholes':2,'programming':4}" - attack_verb = list("attacked", "slapped", "whacked") - material = /decl/material/solid/metal/steel - matter = list( - /decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT, - /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, - /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE, - /decl/material/solid/phoron = MATTER_AMOUNT_TRACE, - /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE - ) - relative_size = 60 - req_access = list(access_robotics) - organ_properties = ORGAN_PROP_PROSTHETIC //triggers robotization on init - scale_max_damage_to_species_health = FALSE - - var/mob/living/carbon/brain/brainmob = null - var/searching = 0 - var/askDelay = 60 SECONDS - -/obj/item/organ/internal/posibrain/Initialize() - . = ..() - if(!brainmob && iscarbon(loc)) - init(loc) //Not sure why we're creating a braimob on load, and also why not installing it in the owner... - -/obj/item/organ/internal/posibrain/proc/init(var/mob/living/carbon/H) - if(brainmob) - return - brainmob = new(src) - if(istype(H)) - brainmob.SetName(H.real_name) - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - brainmob.add_language(/decl/language/human/common) - brainmob.add_language(/decl/language/binary) - -/obj/item/organ/internal/posibrain/Destroy() - QDEL_NULL(brainmob) - return ..() - -/obj/item/organ/internal/posibrain/attack_self(mob/user) - if(brainmob && !brainmob.key && searching == 0) - //Start the process of searching for a new user. - to_chat(user, "You carefully locate the manual activation switch and start the positronic brain's boot process.") - icon_state = "posibrain-searching" - src.searching = 1 - var/decl/ghosttrap/G = GET_DECL(/decl/ghosttrap/positronic_brain) - G.request_player(brainmob, "Someone is requesting a personality for a positronic brain.", 60 SECONDS) - addtimer(CALLBACK(src, .proc/reset_search), askDelay) - -/obj/item/organ/internal/posibrain/proc/reset_search() //We give the players time to decide, then reset the timer. - if(!brainmob?.key) - searching = FALSE - icon_state = "posibrain" - visible_message(SPAN_WARNING("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")) - -/obj/item/organ/internal/posibrain/attack_ghost(var/mob/observer/ghost/user) - if(!searching || (src.brainmob && src.brainmob.key)) - return - - var/decl/ghosttrap/G = GET_DECL(/decl/ghosttrap/positronic_brain) - if(!G.assess_candidate(user)) - return - var/response = alert(user, "Are you sure you wish to possess this [src]?", "Possess [src]", "Yes", "No") - if(response == "Yes") - G.transfer_personality(user, brainmob) - -/obj/item/organ/internal/posibrain/examine(mob/user) - . = ..() - - var/msg = "*---------*\nThis is [html_icon(src)] \a [src]!\n[desc]\n" - - msg += "" - - if(src.brainmob && src.brainmob.key) - switch(src.brainmob.stat) - if(CONSCIOUS) - if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk - if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" - if(DEAD) msg += "It appears to be completely inactive.\n" - else - msg += "It appears to be completely inactive.\n" - - msg += "*---------*" - to_chat(user, msg) - return - -/obj/item/organ/internal/posibrain/emp_act(severity) - if(!src.brainmob) - return - else - switch(severity) - if(1) - src.brainmob.emp_damage += rand(20,30) - if(2) - src.brainmob.emp_damage += rand(10,20) - if(3) - src.brainmob.emp_damage += rand(0,10) - ..() - -/obj/item/organ/internal/posibrain/proc/PickName() - src.brainmob.SetName("[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[random_id(type,100,999)]") - src.brainmob.real_name = src.brainmob.name - -/obj/item/organ/internal/posibrain/on_update_icon() - . = ..() - if(src.brainmob && src.brainmob.key) - icon_state = "posibrain-occupied" - else - icon_state = "posibrain" - -/obj/item/organ/internal/posibrain/proc/transfer_identity(var/mob/living/carbon/H) - if(H && H.mind) - brainmob.set_stat(CONSCIOUS) - H.mind.transfer_to(brainmob) - brainmob.SetName(H.real_name) - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - - update_icon() - - to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just \a [initial(src.name)].") - callHook("debrain", list(brainmob)) - -/obj/item/organ/internal/posibrain/on_add_effects() - if(brainmob) - if(brainmob.mind) - if(owner.key) - owner.ghostize() - brainmob.mind.transfer_to(owner) - else if(brainmob.key) //posibrain init with a dummy brainmob for some reasons, so gotta do this or its gonna disconnect the client on mob transformation - owner.key = brainmob.key - return ..() - -/obj/item/organ/internal/posibrain/on_remove_effects() - if(istype(owner)) - transfer_identity(owner) - return ..() - -/obj/item/organ/internal/posibrain/do_install(mob/living/carbon/human/target, obj/item/organ/external/affected, in_place, update_icon, detached) - if(!(. = ..())) - return - if(istype(owner)) - SetName(initial(name)) //Reset the organ's name to stay coherent if we're put back into someone's skull - -/obj/item/organ/internal/posibrain/do_uninstall(in_place, detach, ignore_children) - if(!in_place && istype(owner) && name == initial(name)) - SetName("\the [owner.real_name]'s [initial(name)]") - return ..() - -/obj/item/organ/internal/cell - name = "microbattery" - desc = "A small, powerful cell for use in fully prosthetic bodies." - icon_state = "cell" - dead_icon = "cell_bork" - organ_tag = BP_CELL - parent_organ = BP_CHEST - organ_properties = ORGAN_PROP_PROSTHETIC //triggers robotization on init - var/open - var/obj/item/cell/cell = /obj/item/cell/hyper - //at 0.8 completely depleted after 60ish minutes of constant walking or 130 minutes of standing still - var/servo_cost = 0.8 - -/obj/item/organ/internal/cell/Initialize() - if(ispath(cell)) - cell = new cell(src) - . = ..() - -/obj/item/organ/internal/cell/proc/percent() - if(!cell) - return 0 - return get_charge()/cell.maxcharge * 100 - -/obj/item/organ/internal/cell/proc/get_charge() - if(!cell) - return 0 - if(status & ORGAN_DEAD) - return 0 - return round(cell.charge*(1 - damage/max_damage)) - -/obj/item/organ/internal/cell/proc/checked_use(var/amount) - if(!is_usable()) - return FALSE - return cell && cell.checked_use(amount) - -/obj/item/organ/internal/cell/proc/use(var/amount) - if(!is_usable()) - return 0 - return cell && cell.use(amount) - -/obj/item/organ/internal/cell/proc/get_power_drain() - var/damage_factor = 1 + 10 * damage/max_damage - return servo_cost * damage_factor - -/obj/item/organ/internal/cell/Process() - ..() - if(!owner) - return - if(owner.stat == DEAD) //not a drain anymore - return - var/cost = get_power_drain() - if(world.time - owner.l_move_time < 15) - cost *= 2 - if(!checked_use(cost) && owner.isSynthetic()) - if(!owner.lying && !owner.buckled) - to_chat(owner, "You don't have enough energy to function!") - SET_STATUS_MAX(owner, STAT_PARA, 3) - -/obj/item/organ/internal/cell/emp_act(severity) - ..() - if(cell) - cell.emp_act(severity) - -/obj/item/organ/internal/cell/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) - if(open) - open = 0 - to_chat(user, "You screw the battery panel in place.") - else - open = 1 - to_chat(user, "You unscrew the battery panel.") - - if(IS_CROWBAR(W)) - if(open) - if(cell) - user.put_in_hands(cell) - to_chat(user, "You remove \the [cell] from \the [src].") - cell = null - - if (istype(W, /obj/item/cell)) - if(open) - if(cell) - to_chat(user, "There is a power cell already installed.") - else if(user.try_unequip(W, src)) - cell = W - to_chat(user, "You insert \the [cell].") - -/obj/item/organ/internal/cell/on_add_effects() - . = ..() - // This is very ghetto way of rebooting an IPC. TODO better way. - if(owner && owner.stat == DEAD) - owner.set_stat(CONSCIOUS) - owner.visible_message("\The [owner] twitches visibly!") - -/obj/item/organ/internal/cell/listen() - if(get_charge()) - return "faint hum of the power bank" - -// Used for an MMI or posibrain being installed into a human. -/obj/item/organ/internal/mmi_holder - name = "brain interface" - icon_state = "mmi-empty" - organ_tag = BP_BRAIN - parent_organ = BP_HEAD - organ_properties = ORGAN_PROP_PROSTHETIC //triggers robotization on init - scale_max_damage_to_species_health = FALSE - var/obj/item/mmi/stored_mmi - var/datum/mind/persistantMind //Mind that the organ will hold on to after being removed, used for transfer_and_delete - var/ownerckey // used in the event the owner is out of body - -/obj/item/organ/internal/mmi_holder/Destroy() - stored_mmi = null - persistantMind = null - return ..() - -/obj/item/organ/internal/mmi_holder/do_install(mob/living/carbon/human/target, obj/item/organ/external/affected, in_place) - if(status & ORGAN_CUT_AWAY || !(. = ..())) - return - - if(!stored_mmi) - stored_mmi = new(src) - update_from_mmi() - persistantMind = owner.mind - ownerckey = owner.ckey - -/obj/item/organ/internal/mmi_holder/proc/update_from_mmi() - - if(!stored_mmi.brainmob) - stored_mmi.brainmob = new(stored_mmi) - stored_mmi.brainobj = new(stored_mmi) - stored_mmi.brainmob.container = stored_mmi - stored_mmi.brainmob.real_name = owner.real_name - stored_mmi.brainmob.SetName(stored_mmi.brainmob.real_name) - stored_mmi.SetName("[initial(stored_mmi.name)] ([owner.real_name])") - - if(!owner) return - - name = stored_mmi.name - desc = stored_mmi.desc - icon = stored_mmi.icon - - stored_mmi.icon_state = "mmi-full" - icon_state = stored_mmi.icon_state - - if(owner && owner.stat == DEAD) - owner.set_stat(CONSCIOUS) - owner.switch_from_dead_to_living_mob_list() - owner.visible_message("\The [owner] twitches visibly!") - -/obj/item/organ/internal/mmi_holder/on_remove_effects(mob/living/last_owner) - if(last_owner && last_owner.mind) - persistantMind = last_owner.mind - if(last_owner.ckey) - ownerckey = last_owner.ckey - . = ..() - -/obj/item/organ/internal/mmi_holder/proc/transfer_and_delete() - if(stored_mmi) - . = stored_mmi - stored_mmi.forceMove(src.loc) - if(persistantMind) - persistantMind.transfer_to(stored_mmi.brainmob) - else - var/response = input(find_dead_player(ownerckey, 1), "Your [initial(stored_mmi.name)] has been removed from your body. Do you wish to return to life?", "Robotic Rebirth") as anything in list("Yes", "No") - if(response == "Yes") - persistantMind.transfer_to(stored_mmi.brainmob) - qdel(src) - -//Since the mmi_holder is an horrible hacky pos we turn it into a mmi on drop, since it shouldn't exist outside a mob -/obj/item/organ/internal/mmi_holder/dropInto(atom/destination) - . = ..() - if (!QDELETED(src)) - transfer_and_delete() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index ab999a7ec99..3c5a8c73162 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -4,7 +4,7 @@ germ_level = 0 w_class = ITEM_SIZE_TINY default_action_type = /datum/action/item_action/organ - origin_tech = "{'materials':1,'biotech':1}" + origin_tech = @'{"materials":1,"biotech":1}' throwforce = 2 abstract_type = /obj/item/organ @@ -113,7 +113,7 @@ if(bodytype) reagent_to_add = bodytype.edible_reagent // can set this to null and skip the next block if(reagent_to_add) - reagents.add_reagent(reagent_to_add, reagents.maximum_volume) + add_to_reagents(reagent_to_add, reagents.maximum_volume) /obj/item/organ/proc/set_dna(var/datum/dna/new_dna) if(istype(bodytype) && (bodytype.body_flags & BODY_FLAG_NO_DNA)) @@ -202,7 +202,7 @@ //dead already, no need for more processing if(status & ORGAN_DEAD) return - // Don't process if we're in a freezer, an MMI or a stasis bag.or a freezer or something I dunno + // Don't process if we're in a freezer, an interface or a stasis bag. if(is_preserved()) return //Process infections @@ -214,8 +214,8 @@ if(prob(40) && reagents.total_volume >= 0.1) if(reagents.has_reagent(/decl/material/liquid/blood)) blood_splatter(get_turf(src), src, 1) - reagents.remove_any(0.1) - if(config.organs_decay) + remove_any_reagents(0.1) + if(get_config_value(/decl/config/toggle/health_organs_decay)) take_general_damage(rand(1,3)) germ_level += rand(2,6) if(germ_level >= INFECTION_LEVEL_TWO) @@ -248,11 +248,18 @@ ailment.was_treated_by_chem_effect() /obj/item/organ/proc/is_preserved() - if(istype(loc,/obj/item/organ)) + if(istype(loc, /obj/item/organ)) var/obj/item/organ/O = loc return O.is_preserved() - else - return (istype(loc,/obj/item/mmi) || istype(loc,/obj/structure/closet/body_bag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer) || istype(loc,/obj/item/storage/box/freezer)) + var/static/list/preserved_types = list( + /obj/item/storage/box/freezer, + /obj/structure/closet/crate/freezer, + /obj/structure/closet/body_bag/cryobag + ) + for(var/preserved_type in preserved_types) + if(istype(loc, preserved_type)) + return TRUE + return FALSE /obj/item/organ/examine(mob/user) . = ..(user) @@ -302,7 +309,7 @@ return if(dna) if(!rejecting) - if(owner.blood_incompatible(dna.b_type)) + if(owner.is_blood_incompatible(dna.b_type)) rejecting = 1 else rejecting++ //Rejection severity increases over time. @@ -318,9 +325,9 @@ germ_level += rand(3,5) var/decl/blood_type/blood_decl = dna?.b_type && get_blood_type_by_name(dna.b_type) if(istype(blood_decl)) - owner.reagents.add_reagent(blood_decl.transfusion_fail_reagent, round(rand(2,4) * blood_decl.transfusion_fail_percentage)) + owner.add_to_reagents(blood_decl.transfusion_fail_reagent, round(rand(2,4) * blood_decl.transfusion_fail_percentage)) else - owner.reagents.add_reagent(/decl/material/liquid/coagulated_blood, rand(1,2)) + owner.add_to_reagents(/decl/material/liquid/coagulated_blood, rand(1,2)) /obj/item/organ/proc/remove_rejuv() qdel(src) @@ -544,6 +551,8 @@ var/global/list/ailment_reference_cache = list() /obj/item/organ/proc/do_install(var/mob/living/carbon/human/target, var/obj/item/organ/external/affected, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE) //Make sure to force the flag accordingly set_detached(detached) + if(QDELETED(src)) + return owner = target vital_to_owner = null @@ -579,7 +588,8 @@ var/global/list/ailment_reference_cache = list() else owner = null vital_to_owner = null - return src + if(!QDELETED(src)) + return src //Events handling for checks and effects that should happen when removing the organ through interactions. Called by the owner mob. /obj/item/organ/proc/on_remove_effects(var/mob/living/last_owner) diff --git a/code/modules/organs/prosthetics/prosthetics_manufacturer.dm b/code/modules/organs/prosthetics/prosthetics_manufacturer.dm index 32f7f343599..588098e60f6 100644 --- a/code/modules/organs/prosthetics/prosthetics_manufacturer.dm +++ b/code/modules/organs/prosthetics/prosthetics_manufacturer.dm @@ -2,7 +2,7 @@ abstract_type = /decl/bodytype/prosthetic icon_base = 'icons/mob/human_races/cyberlimbs/robotic.dmi' desc = "A generic unbranded robotic prosthesis." - limb_tech = "{'engineering':1,'materials':1,'magnets':1}" + limb_tech = @'{"engineering":1,"materials":1,"magnets":1}' modifier_string = "robotic" is_robotic = TRUE body_flags = BODY_FLAG_NO_DNA | BODY_FLAG_NO_DEFIB | BODY_FLAG_NO_STASIS | BODY_FLAG_NO_PAIN | BODY_FLAG_NO_EAT @@ -14,7 +14,7 @@ 'sound/foley/metal1.ogg' ) has_organ = list( - BP_BRAIN = /obj/item/organ/internal/mmi_holder, + BP_BRAIN = /obj/item/organ/internal/brain_interface, BP_EYES = /obj/item/organ/internal/eyes, BP_CELL = /obj/item/organ/internal/cell ) diff --git a/code/modules/overmap/contacts/_contacts.dm b/code/modules/overmap/contacts/_contacts.dm index 6caa410e957..ea6afc1d83d 100644 --- a/code/modules/overmap/contacts/_contacts.dm +++ b/code/modules/overmap/contacts/_contacts.dm @@ -30,7 +30,9 @@ radar = image(loc = effect, icon = 'icons/obj/overmap.dmi', icon_state = "sensor_range") radar.color = source.color radar.tag = "radar" - radar.add_filter("blur", 1, list("blur", size = 1)) + radar.add_filter("blur", 1, list(type = "blur", size = 1)) + radar.appearance_flags |= RESET_TRANSFORM | KEEP_APART + radar.appearance_flags &= ~PIXEL_SCALE /datum/overmap_contact/proc/update_marker_icon() @@ -88,7 +90,7 @@ pinged = TRUE show() animate(marker, alpha=255, 0.5 SECOND, 1, LINEAR_EASING) - addtimer(CALLBACK(src, .proc/unping), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(unping)), 1 SECOND) /datum/overmap_contact/proc/unping() animate(marker, alpha=75, 2 SECOND, 1, LINEAR_EASING) diff --git a/code/modules/overmap/contacts/contact_sensors.dm b/code/modules/overmap/contacts/contact_sensors.dm index fc847367b5b..372c37b56c3 100644 --- a/code/modules/overmap/contacts/contact_sensors.dm +++ b/code/modules/overmap/contacts/contact_sensors.dm @@ -137,7 +137,7 @@ var/time_delay = max((SENSOR_TIME_DELAY * get_dist(linked, contact)),1) if(!record.pinged) - addtimer(CALLBACK(record, .proc/ping), time_delay) + addtimer(CALLBACK(record, PROC_REF(ping)), time_delay) /obj/machinery/computer/ship/sensors/attackby(var/obj/item/I, var/mob/user) . = ..() @@ -150,11 +150,11 @@ if(tracker in trackers) trackers -= tracker - events_repository.unregister(/decl/observ/destroyed, tracker, src, .proc/remove_tracker) + events_repository.unregister(/decl/observ/destroyed, tracker, src, PROC_REF(remove_tracker)) to_chat(user, SPAN_NOTICE("You unlink the tracker in \the [P]'s buffer from \the [src].")) return trackers += tracker - events_repository.register(/decl/observ/destroyed, tracker, src, .proc/remove_tracker) + events_repository.register(/decl/observ/destroyed, tracker, src, PROC_REF(remove_tracker)) to_chat(user, SPAN_NOTICE("You link the tracker in \the [P]'s buffer to \the [src].")) /obj/machinery/computer/ship/sensors/proc/remove_tracker(var/obj/item/ship_tracker/tracker) diff --git a/code/modules/overmap/contacts/tracker.dm b/code/modules/overmap/contacts/tracker.dm index c8009002396..feb89fe461f 100644 --- a/code/modules/overmap/contacts/tracker.dm +++ b/code/modules/overmap/contacts/tracker.dm @@ -4,8 +4,8 @@ icon = 'icons/obj/ship_tracker.dmi' icon_state = "disabled" w_class = ITEM_SIZE_SMALL - - origin_tech = "{'magnets':3, 'programming':2}" + + origin_tech = @'{"magnets":3, "programming":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT) var/enabled = FALSE diff --git a/code/modules/overmap/disperser/disperser_circuit.dm b/code/modules/overmap/disperser/disperser_circuit.dm index f54bafa7a1f..16b2aa0bf9b 100644 --- a/code/modules/overmap/disperser/disperser_circuit.dm +++ b/code/modules/overmap/disperser/disperser_circuit.dm @@ -1,13 +1,13 @@ /obj/item/stock_parts/circuitboard/disperser name = "circuitboard (obstruction field disperser control)" build_path = /obj/machinery/computer/ship/disperser - origin_tech = "{'engineering':2,'combat':2,'wormholes':2}" + origin_tech = @'{"engineering":2,"combat":2,"wormholes":2}' /obj/item/stock_parts/circuitboard/disperserfront name = "circuitboard (obstruction field disperser beam generator)" build_path = /obj/machinery/disperser/front board_type = "machine" - origin_tech = "{'engineering':2,'combat':2,'wormholes':2}" + origin_tech = @'{"engineering":2,"combat":2,"wormholes":2}' req_components = list ( /obj/item/stock_parts/manipulator/pico = 5 ) @@ -16,7 +16,7 @@ name = "circuitboard (obstruction field disperser fusor)" build_path = /obj/machinery/disperser/middle board_type = "machine" - origin_tech = "{'engineering':2,'combat':2,'wormholes':2}" + origin_tech = @'{"engineering":2,"combat":2,"wormholes":2}' req_components = list ( /obj/item/stock_parts/subspace/crystal = 10 ) @@ -25,7 +25,7 @@ name = "circuitboard (obstruction field disperser material deconstructor)" build_path = /obj/machinery/disperser/back board_type = "machine" - origin_tech = "{'engineering':2,'combat':2,'wormholes':2}" + origin_tech = @'{"engineering":2,"combat":2,"wormholes":2}' req_components = list ( /obj/item/stock_parts/capacitor/super = 5 ) \ No newline at end of file diff --git a/code/modules/overmap/disperser/disperser_console.dm b/code/modules/overmap/disperser/disperser_console.dm index 46166a2bdba..14105d9f912 100644 --- a/code/modules/overmap/disperser/disperser_console.dm +++ b/code/modules/overmap/disperser/disperser_console.dm @@ -54,9 +54,9 @@ middle = M back = B if(is_valid_setup()) - events_repository.register(/decl/observ/destroyed, F, src, .proc/release_links) - events_repository.register(/decl/observ/destroyed, M, src, .proc/release_links) - events_repository.register(/decl/observ/destroyed, B, src, .proc/release_links) + events_repository.register(/decl/observ/destroyed, F, src, PROC_REF(release_links)) + events_repository.register(/decl/observ/destroyed, M, src, PROC_REF(release_links)) + events_repository.register(/decl/observ/destroyed, B, src, PROC_REF(release_links)) return TRUE return FALSE @@ -68,9 +68,9 @@ return FALSE /obj/machinery/computer/ship/disperser/proc/release_links() - events_repository.unregister(/decl/observ/destroyed, front, src, .proc/release_links) - events_repository.unregister(/decl/observ/destroyed, middle, src, .proc/release_links) - events_repository.unregister(/decl/observ/destroyed, back, src, .proc/release_links) + events_repository.unregister(/decl/observ/destroyed, front, src, PROC_REF(release_links)) + events_repository.unregister(/decl/observ/destroyed, middle, src, PROC_REF(release_links)) + events_repository.unregister(/decl/observ/destroyed, back, src, PROC_REF(release_links)) front = null middle = null back = null diff --git a/code/modules/overmap/events/event.dm b/code/modules/overmap/events/event.dm index 64e0e449bdd..922924fdba5 100644 --- a/code/modules/overmap/events/event.dm +++ b/code/modules/overmap/events/event.dm @@ -126,13 +126,13 @@ if(!active_hazards.len) hazard_by_turf -= T - events_repository.unregister(/decl/observ/entered, T, src, .proc/on_turf_entered) - events_repository.unregister(/decl/observ/exited, T, src, .proc/on_turf_exited) + events_repository.unregister(/decl/observ/entered, T, src, PROC_REF(on_turf_entered)) + events_repository.unregister(/decl/observ/exited, T, src, PROC_REF(on_turf_exited)) else hazard_by_turf |= T hazard_by_turf[T] = active_hazards - events_repository.register(/decl/observ/entered, T, src, .proc/on_turf_entered) - events_repository.register(/decl/observ/exited, T, src, .proc/on_turf_exited) + events_repository.register(/decl/observ/entered, T, src, PROC_REF(on_turf_entered)) + events_repository.register(/decl/observ/exited, T, src, PROC_REF(on_turf_exited)) for(var/obj/effect/overmap/visitable/ship/ship in T) for(var/datum/event/E in ship_events[ship]) diff --git a/code/modules/overmap/exoplanets/_exoplanet.dm b/code/modules/overmap/exoplanets/_exoplanet.dm index 3084dd7c0d3..c25daa09869 100644 --- a/code/modules/overmap/exoplanets/_exoplanet.dm +++ b/code/modules/overmap/exoplanets/_exoplanet.dm @@ -17,9 +17,9 @@ . += "Life traces detected
    " if(LAZYLEN(E.subtemplates) && user.skill_check(SKILL_SCIENCE, SKILL_ADEPT)) - var/ruin_num = 0 + var/poi_num = 0 for(var/datum/map_template/R in E.subtemplates) - if(!(R.get_ruin_tags() & RUIN_NATURAL)) - ruin_num++ - if(ruin_num) - . += "
    [ruin_num] possible artificial structure\s detected.
    " + if(!(R.get_template_tags() & TEMPLATE_TAG_NATURAL)) + poi_num++ + if(poi_num) + . += "
    [poi_num] possible artificial structure\s detected.
    " diff --git a/code/modules/overmap/ftl_shunt/computer.dm b/code/modules/overmap/ftl_shunt/computer.dm index 14bc2933ab0..e971f2d5a38 100644 --- a/code/modules/overmap/ftl_shunt/computer.dm +++ b/code/modules/overmap/ftl_shunt/computer.dm @@ -74,7 +74,7 @@ plot_delay_mult = 2 delay = clamp(((jump_dist * BASE_PLOT_TIME_PER_TILE) * plot_delay_mult),1, INFINITY) - jump_plot_timer = addtimer(CALLBACK(src, .proc/finish_plot, x, y), delay, TIMER_STOPPABLE) + jump_plot_timer = addtimer(CALLBACK(src, PROC_REF(finish_plot), x, y), delay, TIMER_STOPPABLE) plotting_jump = TRUE jump_plotted = FALSE return delay diff --git a/code/modules/overmap/ftl_shunt/core.dm b/code/modules/overmap/ftl_shunt/core.dm index dd3542241f8..cc6266b3ed4 100644 --- a/code/modules/overmap/ftl_shunt/core.dm +++ b/code/modules/overmap/ftl_shunt/core.dm @@ -234,7 +234,7 @@ update_icon() if(check_charge()) - jump_timer = addtimer(CALLBACK(src, .proc/execute_shunt), jump_delay, TIMER_STOPPABLE) + jump_timer = addtimer(CALLBACK(src, PROC_REF(execute_shunt)), jump_delay, TIMER_STOPPABLE) return FTL_START_CONFIRMED /obj/machinery/ftl_shunt/core/proc/calculate_jump_requirements() @@ -270,7 +270,7 @@ return if(use_fuel(required_fuel_joules)) - jump_timer = addtimer(CALLBACK(src, .proc/execute_shunt), jump_delay, TIMER_STOPPABLE) + jump_timer = addtimer(CALLBACK(src, PROC_REF(execute_shunt)), jump_delay, TIMER_STOPPABLE) else cancel_shunt() return //If for some reason we don't have fuel now, just return. @@ -281,7 +281,7 @@ var/jumpdist = get_dist(get_turf(ftl_computer.linked), destination) var/obj/effect/portal/wormhole/W = new(destination) //Generate a wormhole effect on overmap to give some indication that something is about to happen. QDEL_IN(W, 6 SECONDS) - addtimer(CALLBACK(src, .proc/do_shunt, shunt_x, shunt_y, jumpdist, destination), 6 SECONDS) + addtimer(CALLBACK(src, PROC_REF(do_shunt), shunt_x, shunt_y, jumpdist, destination), 6 SECONDS) jumping = TRUE update_icon() for(var/mob/living/carbon/M in global.living_mob_list_) @@ -646,13 +646,13 @@ name = "circuit board (superluminal shunt)" board_type = "machine" build_path = /obj/machinery/ftl_shunt/core - origin_tech = "{'programming':3,'magnets':5,'materials':5,'wormholes':5}" + origin_tech = @'{"programming":3,"magnets":5,"materials":5,"wormholes":5}' additional_spawn_components = list(/obj/item/stock_parts/power/terminal = 1) /obj/item/stock_parts/ftl_core name = "exotic matter bridge" desc = "The beating heart of a superluminal shunt - without this, the power to manipulate space-time is out of reach." - origin_tech = "{'programming':3,'magnets':5,'materials':5,'wormholes':5}" + origin_tech = @'{"programming":3,"magnets":5,"materials":5,"wormholes":5}' icon = 'icons/obj/items/stock_parts/stock_parts.dmi' icon_state = "smes_coil" color = COLOR_YELLOW diff --git a/code/modules/overmap/internet/internet_circuitboards.dm b/code/modules/overmap/internet/internet_circuitboards.dm index 5649be365d9..3e865580bda 100644 --- a/code/modules/overmap/internet/internet_circuitboards.dm +++ b/code/modules/overmap/internet/internet_circuitboards.dm @@ -2,7 +2,7 @@ name = "circuitboard (PLEXUS uplink)" board_type = "machine" build_path = /obj/machinery/internet_uplink - origin_tech = "{'magnets':4,'wormholes':3,'powerstorage':3,'engineering':3}" + origin_tech = @'{"magnets":4,"wormholes":3,"powerstorage":3,"engineering":3}' req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/micro_laser = 2, @@ -13,13 +13,13 @@ /obj/item/stock_parts/circuitboard/internet_uplink_computer name = "circuitboard (PLEXUS uplink controller)" build_path = /obj/machinery/computer/internet_uplink - origin_tech = "{'programming':2,'engineering':2}" + origin_tech = @'{"programming":2,"engineering":2}' /obj/item/stock_parts/circuitboard/internet_repeater name = "circuitboard (PLEXUS repeater)" build_path = /obj/machinery/internet_repeater board_type = "machine" - origin_tech = "{'magnets':3,'engineering':2,'programming':2}" + origin_tech = @'{"magnets":3,"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/subspace/filter = 1, /obj/item/stock_parts/capacitor = 2, diff --git a/code/modules/overmap/overmap_object.dm b/code/modules/overmap/overmap_object.dm index c186fb99187..0a91278a5b9 100644 --- a/code/modules/overmap/overmap_object.dm +++ b/code/modules/overmap/overmap_object.dm @@ -61,7 +61,7 @@ var/global/list/overmap_unknown_ids = list() update_moving() - add_filter("glow", 1, list("drop_shadow", color = color + "F0", size = 2, offset = 1,x = 0, y = 0)) + add_filter("glow", 1, list(type = "drop_shadow", color = color + "F0", size = 2, offset = 1,x = 0, y = 0)) update_icon() /obj/effect/overmap/Crossed(atom/movable/AM) diff --git a/code/modules/overmap/planetoids/_planetoids.dm b/code/modules/overmap/planetoids/_planetoids.dm index 31ac51b28f4..f3a87312cb9 100644 --- a/code/modules/overmap/planetoids/_planetoids.dm +++ b/code/modules/overmap/planetoids/_planetoids.dm @@ -49,7 +49,7 @@ ///Update our name, and refs to match the planetoid we're representing /obj/effect/overmap/visitable/sector/planetoid/proc/update_from_data(var/datum/planetoid_data/P) - SetName("[P.name], \a [name]") + SetName("[P.name], \a [initial(name)]") planetoid_id = P.id surface_color = P.surface_color water_color = P.water_color diff --git a/code/modules/overmap/radio_beacon.dm b/code/modules/overmap/radio_beacon.dm index 4d35f60124f..4d6f541b3f7 100644 --- a/code/modules/overmap/radio_beacon.dm +++ b/code/modules/overmap/radio_beacon.dm @@ -13,8 +13,8 @@

    ---END OF TRANSMISSION---" /obj/effect/overmap/radio/proc/set_origin(obj/effect/overmap/origin) - events_repository.register(/decl/observ/moved, origin, src, /obj/effect/overmap/radio/proc/follow) - events_repository.register(/decl/observ/destroyed, origin, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/moved, origin, src, TYPE_PROC_REF(/obj/effect/overmap/radio, follow)) + events_repository.register(/decl/observ/destroyed, origin, src, TYPE_PROC_REF(/datum, qdel_self)) forceMove(origin.loc) source = origin pixel_x = -(origin.bound_width - 6) @@ -35,7 +35,7 @@ icon = 'icons/obj/items/device/radio/beacon.dmi' icon_state = "beacon" - origin_tech = "{'magnets':2, 'programming':2}" + origin_tech = @'{"magnets":2, "programming":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/modules/overmap/ships/circuits.dm b/code/modules/overmap/ships/circuits.dm index bf196ca3792..3d729a46a55 100644 --- a/code/modules/overmap/ships/circuits.dm +++ b/code/modules/overmap/ships/circuits.dm @@ -2,7 +2,7 @@ name = "circuitboard (gas thruster)" icon = 'icons/obj/modules/module_controller.dmi' build_path = /obj/machinery/atmospherics/unary/engine - origin_tech = "{'powerstorage':1,'engineering':2}" + origin_tech = @'{"powerstorage":1,"engineering":2}' req_components = list( /obj/item/stack/cable_coil = 30, /obj/item/pipe = 2 @@ -17,7 +17,7 @@ name = "circuitboard (fusion thruster)" icon = 'icons/obj/modules/module_controller.dmi' build_path = /obj/machinery/atmospherics/unary/engine/fusion - origin_tech = "{'powerstorage':1,'engineering':2}" + origin_tech = @'{"powerstorage":1,"engineering":2}' req_components = list( /obj/item/stack/cable_coil = 30, /obj/item/pipe = 2 diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm index 6302e7926b7..cf103d9e075 100644 --- a/code/modules/overmap/ships/computers/helm.dm +++ b/code/modules/overmap/ships/computers/helm.dm @@ -317,7 +317,7 @@ var/global/list/overmap_helm_computers current_operator = weakref(current_operator_actual) linked.update_operator_skill(current_operator_actual) if (!autopilot && old_operator && viewing_overmap(old_operator)) - addtimer(CALLBACK(src, /obj/machinery/computer/ship/.proc/unlook, old_operator), 0) // Workaround for linter SHOULD_NOT_SLEEP checks. + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/ship, unlook), old_operator), 0) // Workaround for linter SHOULD_NOT_SLEEP checks. log_debug("HELM CONTROL: [current_operator_actual ? current_operator_actual : "NO PILOT"] taking control of [src] from [old_operator ? old_operator : "NO PILOT"] in [get_area_name(src)]. [autopilot ? "(AUTOPILOT MODE)" : null]") diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index c3837101c69..396a4fe2172 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -69,9 +69,9 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov for(var/obj/machinery/computer/ship/sensors/sensor in linked.get_linked_machines_of_type(/obj/machinery/computer/ship)) sensor.reveal_contacts(user) - events_repository.register(/decl/observ/moved, user, src, /obj/machinery/computer/ship/proc/unlook) + events_repository.register(/decl/observ/moved, user, src, TYPE_PROC_REF(/obj/machinery/computer/ship, unlook)) if(isliving(user)) - events_repository.register(/decl/observ/stat_set, user, src, /obj/machinery/computer/ship/proc/unlook) + events_repository.register(/decl/observ/stat_set, user, src, TYPE_PROC_REF(/obj/machinery/computer/ship, unlook)) LAZYDISTINCTADD(viewers, weakref(user)) if(linked) LAZYDISTINCTADD(linked.navigation_viewers, weakref(user)) @@ -84,9 +84,9 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov for(var/obj/machinery/computer/ship/sensors/sensor in linked.get_linked_machines_of_type(/obj/machinery/computer/ship)) sensor.hide_contacts(user) - events_repository.unregister(/decl/observ/moved, user, src, /obj/machinery/computer/ship/proc/unlook) + events_repository.unregister(/decl/observ/moved, user, src, TYPE_PROC_REF(/obj/machinery/computer/ship, unlook)) if(isliving(user)) - events_repository.unregister(/decl/observ/stat_set, user, src, /obj/machinery/computer/ship/proc/unlook) + events_repository.unregister(/decl/observ/stat_set, user, src, TYPE_PROC_REF(/obj/machinery/computer/ship, unlook)) LAZYREMOVE(viewers, weakref(user)) if(linked) LAZYREMOVE(linked.navigation_viewers, weakref(user)) diff --git a/code/modules/overmap/ships/device_types/_engine.dm b/code/modules/overmap/ships/device_types/_engine.dm index e38e8f5484a..707efb35241 100644 --- a/code/modules/overmap/ships/device_types/_engine.dm +++ b/code/modules/overmap/ships/device_types/_engine.dm @@ -76,8 +76,10 @@ var/global/list/ship_engines = list() var/exhaust_dir = global.reverse_dir[M.dir] var/turf/A = get_step(src, exhaust_dir) var/turf/B = A + var/airblock while(isturf(A) && !(isspaceturf(A) || A.is_open())) - if((B.c_airblock(A)) & AIR_BLOCKED) + ATMOS_CANPASS_TURF(airblock, B, A) + if(airblock & AIR_BLOCKED) blockage = TRUE break B = A diff --git a/code/modules/overmap/ships/landable.dm b/code/modules/overmap/ships/landable.dm index 771cd6ed2a5..2948c418427 100644 --- a/code/modules/overmap/ships/landable.dm +++ b/code/modules/overmap/ships/landable.dm @@ -122,7 +122,7 @@ visitor_dir = turn(visitor_dir, 90) // Configure shuttle datum - events_repository.register(/decl/observ/shuttle_moved, shuttle_datum, src, .proc/on_shuttle_jump) + events_repository.register(/decl/observ/shuttle_moved, shuttle_datum, src, PROC_REF(on_shuttle_jump)) on_landing(landmark, shuttle_datum.current_location) // We "land" at round start to properly place ourselves on the overmap. if(landmark == shuttle_datum.current_location) status = SHIP_STATUS_OVERMAP // we spawned on the overmap, so have to initialize our state properly. @@ -161,7 +161,7 @@ core_landmark = master SetName(_name) landmark_tag = master.shuttle_name + _name - events_repository.register(/decl/observ/destroyed, master, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/destroyed, master, src, TYPE_PROC_REF(/datum, qdel_self)) . = ..() /obj/effect/shuttle_landmark/visiting_shuttle/Destroy() diff --git a/code/modules/overmap/ships/machines/ion_thruster.dm b/code/modules/overmap/ships/machines/ion_thruster.dm index 5ca69b414ed..63d98305036 100644 --- a/code/modules/overmap/ships/machines/ion_thruster.dm +++ b/code/modules/overmap/ships/machines/ion_thruster.dm @@ -83,7 +83,7 @@ board_type = "machine" icon = 'icons/obj/modules/module_controller.dmi' build_path = /obj/machinery/ion_thruster - origin_tech = "{'powerstorage':1,'engineering':2}" + origin_tech = @'{"powerstorage":1,"engineering":2}' req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/matter_bin = 1, diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 48b9de4f5e7..8226110bb9a 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -57,6 +57,7 @@ var/mutable_appearance/I = new /mutable_appearance(top_paper) I.appearance_flags |= RESET_COLOR I.plane = FLOAT_PLANE + I.layer = FLOAT_LAYER I.pixel_x = 0 I.pixel_y = 0 I.pixel_w = 0 diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 93e012a37d0..f65e393ca3a 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -14,7 +14,7 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to name = "circuitboard (fax machine)" build_path = /obj/machinery/faxmachine board_type = "machine" - origin_tech = "{'engineering':1, 'programming':1}" + origin_tech = @'{"engineering":1, "programming":1}' req_components = list( /obj/item/stock_parts/printer = 1, /obj/item/stock_parts/manipulator = 1, @@ -116,18 +116,18 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to printer = get_component_of_type(/obj/item/stock_parts/printer) if(disk_reader) - disk_reader.register_on_insert(CALLBACK(src, /obj/machinery/faxmachine/proc/on_insert_disk)) - disk_reader.register_on_eject( CALLBACK(src, /obj/machinery/faxmachine/proc/update_ui)) + disk_reader.register_on_insert(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, on_insert_disk))) + disk_reader.register_on_eject( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, update_ui))) if(card_reader) - card_reader.register_on_insert(CALLBACK(src, /obj/machinery/faxmachine/proc/on_insert_card)) - card_reader.register_on_eject( CALLBACK(src, /obj/machinery/faxmachine/proc/update_ui)) + card_reader.register_on_insert(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, on_insert_card))) + card_reader.register_on_eject( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, update_ui))) if(printer) - printer.register_on_printed_page( CALLBACK(src, /obj/machinery/faxmachine/proc/on_printed_page)) - printer.register_on_finished_queue(CALLBACK(src, /obj/machinery/faxmachine/proc/on_queue_finished)) - printer.register_on_print_error( CALLBACK(src, /obj/machinery/faxmachine/proc/on_print_error)) - printer.register_on_status_changed(CALLBACK(src, /obj/machinery/faxmachine/proc/update_ui)) + printer.register_on_printed_page( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, on_printed_page))) + printer.register_on_finished_queue(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, on_queue_finished))) + printer.register_on_print_error( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, on_print_error))) + printer.register_on_status_changed(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/faxmachine, update_ui))) /obj/machinery/faxmachine/interface_interact(mob/user) ui_interact(user) @@ -683,6 +683,10 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to msg += "(TAKE) (REPLY): " msg += "Receiving '[rcvdcopy.name]' via secure connection ... view message" + if (istype(doc, /obj/item/paper)) + var/obj/item/paper/paper = doc + SSwebhooks.send(WEBHOOK_FAX_SENT, list("title" = "Incoming fax transmission from [sender] in [faxname] for [dest_display_name].", "body" = "[paper.info]")) + for(var/client/C in global.admins) if(check_rights((R_ADMIN|R_MOD),0,C)) to_chat(C, msg) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index e392f32845a..4e728b71bd9 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -70,7 +70,7 @@ desc = "A filing cabinet installed into a cavity in the wall to save space. Wow!" icon_state = "wallcabinet" obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' /obj/structure/filing_cabinet/tall icon_state = "tallcabinet" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index ea84b95ff49..7aef3836cce 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -86,16 +86,20 @@ /obj/item/paper/on_update_icon() . = ..() + if(is_crumpled) icon_state = "scrap" - return //No overlays on crumpled paper else icon_state = initial(icon_state) - update_contents_overlays() + update_contents_overlays() + //The appearence is the key, the type is the value + for(var/image/key in applied_stamps) + add_overlay(key) - //The appearence is the key, the type is the value - for(var/image/key in applied_stamps) - add_overlay(key) + // Update clipboard/paper bundle. + if(istype(loc, /obj/item/clipboard) || istype(loc, /obj/item/paper_bundle)) + compile_overlays() + loc.update_icon() /**Applies the overlay displayed when the paper contains some text. */ /obj/item/paper/proc/update_contents_overlays() @@ -150,25 +154,32 @@ /obj/item/paper/attack(mob/living/carbon/M, mob/living/carbon/user) if(user.get_target_zone() == BP_EYES) - user.visible_message(SPAN_NOTICE("You show the paper to [M]."), \ - SPAN_NOTICE("[user] holds up a paper and shows it to [M].")) + user.visible_message( + SPAN_NOTICE("You show the paper to [M]."), + SPAN_NOTICE("[user] holds up a paper and shows it to [M].") + ) M.examinate(src) + return TRUE - else if(user.get_target_zone() == BP_MOUTH) // lipstick wiping - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H == user) - to_chat(user, SPAN_NOTICE("You wipe off the lipstick with [src].")) - H.lip_style = null - H.update_body() - else - user.visible_message(SPAN_WARNING("[user] begins to wipe [H]'s lipstick off with \the [src]."), \ - SPAN_NOTICE("You begin to wipe off [H]'s lipstick.")) - if(do_after(user, 10, H) && do_after(H, 10, check_holding = 0)) //user needs to keep their active hand, H does not. - user.visible_message(SPAN_NOTICE("[user] wipes [H]'s lipstick off with \the [src]."), \ - SPAN_NOTICE("You wipe off [H]'s lipstick.")) - H.lip_style = null - H.update_body() + if(user.get_target_zone() == BP_MOUTH && M.get_lip_colour()) + var/mob/living/carbon/human/H = M + if(H == user) + to_chat(user, SPAN_NOTICE("You wipe off the lipstick with [src].")) + H.set_lip_colour() + return TRUE + user.visible_message( + SPAN_NOTICE("\The [user] begins to wipe \the [H]'s lipstick off with \the [src]."), + SPAN_NOTICE("You begin to wipe off [H]'s lipstick.") + ) + if(do_after(user, 10, H) && do_after(H, 10, check_holding = 0)) //user needs to keep their active hand, H does not. + user.visible_message( + SPAN_NOTICE("\The [user] wipes \the [H]'s lipstick off with \the [src]."), + SPAN_NOTICE("You wipe off \the [H]'s lipstick.") + ) + H.set_lip_colour() + return TRUE + + . = ..() /obj/item/paper/proc/addtofield(var/id, var/text, var/links = 0) var/locid = 0 @@ -292,7 +303,7 @@ to_chat(user, SPAN_WARNING("You must hold \the [P] steady to burn \the [src].")) /obj/item/paper/CouldNotUseTopic(mob/user) - to_chat(user, SPAN_WARNING("You can't do that!")) + to_chat(user, SPAN_WARNING("You can't reach!")) /obj/item/paper/OnTopic(mob/user, href_list, datum/topic_state/state) @@ -310,9 +321,9 @@ //If we got a pen that's not in our hands, make sure to move it over if(user.get_active_hand() != I && user.get_empty_hand_slot() && user.put_in_hands(I)) - to_chat(user, SPAN_NOTICE("You grab your trusty [I]!")) + to_chat(user, SPAN_NOTICE("You grab your trusty [I.name]!")) else if(user.get_active_hand() != I) - to_chat(user, SPAN_WARNING("You'd use your trusty [I], but your hands are full!")) + to_chat(user, SPAN_WARNING("You'd use your trusty [I.name], but your hands are full!")) return TOPIC_NOACTION var/pen_flags = I.get_tool_property(TOOL_PEN, TOOL_PROP_PEN_FLAG) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 5844573df7d..4a285f714e4 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -50,19 +50,21 @@ return TRUE else if(istype(W, /obj/item/stack/tape_roll/duct_tape)) - var/obj/P = pages[cur_page] - . = P.attackby(W, user) - update_icon() - updateUsrDialog() - return TRUE + var/obj/P = LAZYACCESS(pages, cur_page) + if(P) + . = P.attackby(W, user) + update_icon() + updateUsrDialog() + return else if(IS_PEN(W) || istype(W, /obj/item/stamp)) close_browser(user, "window=[name]") - var/obj/P = pages[cur_page] - . = P.attackby(W, user) - update_icon() - updateUsrDialog() - return . + var/obj/P = LAZYACCESS(pages, cur_page) + if(P) + . = P.attackby(W, user) + update_icon() + updateUsrDialog() + return return ..() @@ -182,7 +184,7 @@ user.visible_message( \ "\The [user] holds \the [P] up to \the [src]. It looks like [G.he] [G.is] trying to burn it!", \ "You hold \the [P] up to \the [src], burning it slowly.") - addtimer(CALLBACK(src, .proc/burn_callback, P, user, span_class), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(burn_callback), P, user, span_class), 2 SECONDS) /obj/item/paper_bundle/examine(mob/user, distance) . = ..() @@ -193,8 +195,7 @@ /obj/item/paper_bundle/interact(mob/user) var/dat - var/obj/item/W = pages[cur_page] - + var/obj/item/W = LAZYACCESS(pages, cur_page) //Header dat = "
    [name_column][treatment_column]
    " dat += "
    " @@ -298,11 +299,11 @@ . = ..() underlays.Cut() - var/obj/item/paper/P = pages[1] - icon = P.icon - icon_state = P.icon_state - copy_overlays(P.overlays) - + var/obj/item/paper/P = LAZYACCESS(pages, 1) + if(P) + icon = P.icon + icon_state = P.icon_state + copy_overlays(P) var/paper_count = 0 var/photo_count = 0 diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm index 47dd62c546c..3df1a1b80ef 100644 --- a/code/modules/paperwork/paper_sticky.dm +++ b/code/modules/paperwork/paper_sticky.dm @@ -97,7 +97,7 @@ /obj/item/paper/sticky/Initialize() . = ..() - events_repository.register(/decl/observ/moved, src, src, /obj/item/paper/sticky/proc/reset_persistence_tracking) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/item/paper/sticky, reset_persistence_tracking)) /obj/item/paper/sticky/proc/reset_persistence_tracking() SSpersistence.forget_value(src, /decl/persistence_handler/paper/sticky) diff --git a/code/modules/paperwork/pen/crayon.dm b/code/modules/paperwork/pen/crayon.dm index 64cd4b94c2a..8db8bdb772d 100644 --- a/code/modules/paperwork/pen/crayon.dm +++ b/code/modules/paperwork/pen/crayon.dm @@ -1,25 +1,34 @@ /obj/item/pen/crayon - name = "crayon" - icon = 'icons/obj/items/crayons.dmi' - icon_state = "crayonred" - w_class = ITEM_SIZE_TINY - attack_verb = list("attacked", "coloured", "crayon'd") - stroke_colour = "#ff0000" //RGB - stroke_colour_name = "red" - medium_name = "crayon" - pen_flag = PEN_FLAG_ACTIVE | PEN_FLAG_CRAYON | PEN_FLAG_DEL_EMPTY - pen_quality = TOOL_QUALITY_BAD //Writing with those things is awkward - max_uses = 30 - pen_font = PEN_FONT_CRAYON - var/shade_colour = "#220000" //RGB + name = "crayon" + icon = 'icons/obj/items/crayon.dmi' + icon_state = ICON_STATE_WORLD + w_class = ITEM_SIZE_TINY + attack_verb = list("attacked", "coloured", "crayon'd") + stroke_color = COLOR_RED + color = COLOR_RED + stroke_color_name = "red" + medium_name = "crayon" + pen_flag = PEN_FLAG_ACTIVE | PEN_FLAG_CRAYON | PEN_FLAG_DEL_EMPTY + pen_quality = TOOL_QUALITY_BAD //Writing with those things is awkward + max_uses = 30 + pen_font = PEN_FONT_CRAYON + material = /decl/material/solid/organic/wax + var/shade_color = "#220000" //RGB + var/pigment_type = /decl/material/liquid/pigment + var/use_stroke_color = TRUE + +/obj/item/pen/crayon/Initialize() + . = ..() + if(use_stroke_color) + color = stroke_color /obj/item/pen/crayon/make_pen_description() - desc = "A colourful [stroke_colour_name] [istype(material)?"[material.name] ":null][medium_name]. Please refrain from eating it or putting it in your nose." + desc = "A colourful [stroke_color_name] [istype(material)?"[material.name] ":null][medium_name]. Please refrain from eating it or putting it in your nose." -/obj/item/pen/crayon/set_medium_color(_color, _color_name, var/_shade_colour) +/obj/item/pen/crayon/set_medium_color(_color, _color_name, var/_shade_color) . = ..(_color, _color_name) - shade_colour = _shade_colour - set_tool_property(TOOL_PEN, TOOL_PROP_PEN_SHADE_COLOR, shade_colour) + shade_color = _shade_color + set_tool_property(TOOL_PEN, TOOL_PROP_PEN_SHADE_COLOR, shade_color) /obj/item/pen/crayon/afterattack(turf/target, mob/user, proximity) if(!proximity) @@ -41,90 +50,82 @@ draw_message = "drawing an arrow" if(do_tool_interaction(TOOL_PEN, user, target, 5 SECONDS, draw_message, "drawing on", fuel_expenditure = 1)) - new /obj/effect/decal/cleanable/crayon(target, stroke_colour, shade_colour, drawtype) + new /obj/effect/decal/cleanable/crayon(target, stroke_color, shade_color, drawtype) target.add_fingerprint(user) // Adds their fingerprints to the floor the crayon is drawn on. return -/obj/item/pen/crayon/attack(mob/living/M, mob/user) - if(istype(M) && M == user) - var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) - playsound(src, 'sound/weapons/bite.ogg', 40) - to_chat(M, SPAN_NOTICE("You take a bite of the crayon and swallow it.")) - M.adjust_nutrition(1) - var/uses = get_tool_property(TOOL_PEN, TOOL_PROP_USES) - M.reagents.add_reagent(/decl/material/liquid/pigment, min(5,uses)/3) - if(parch.decrement_uses(user, src, 5) <= 0) - to_chat(M, SPAN_WARNING("You ate your crayon!")) - return - . = ..() - /obj/item/pen/crayon/red - icon_state = "crayonred" - stroke_colour = "#da0000" - shade_colour = "#810c0c" - stroke_colour_name = "red" + stroke_color = "#da0000" + shade_color = "#810c0c" + stroke_color_name = "red" + pigment_type = /decl/material/liquid/pigment/red /obj/item/pen/crayon/orange - icon_state = "crayonorange" - stroke_colour = "#ff9300" - stroke_colour_name = "orange" - shade_colour = "#a55403" + stroke_color = "#ff9300" + stroke_color_name = "orange" + shade_color = "#a55403" + pigment_type = /decl/material/liquid/pigment/orange /obj/item/pen/crayon/yellow - icon_state = "crayonyellow" - stroke_colour = "#fff200" - shade_colour = "#886422" - stroke_colour_name = "yellow" + stroke_color = "#fff200" + shade_color = "#886422" + stroke_color_name = "yellow" + pigment_type = /decl/material/liquid/pigment/yellow /obj/item/pen/crayon/green - icon_state = "crayongreen" - stroke_colour = "#a8e61d" - shade_colour = "#61840f" - stroke_colour_name = "green" + stroke_color = "#a8e61d" + shade_color = "#61840f" + stroke_color_name = "green" + pigment_type = /decl/material/liquid/pigment/green /obj/item/pen/crayon/blue - icon_state = "crayonblue" - stroke_colour = "#00b7ef" - shade_colour = "#0082a8" - stroke_colour_name = "blue" + stroke_color = "#00b7ef" + shade_color = "#0082a8" + stroke_color_name = "blue" + pigment_type = /decl/material/liquid/pigment/blue /obj/item/pen/crayon/purple - icon_state = "crayonpurple" - stroke_colour = "#da00ff" - shade_colour = "#810cff" - stroke_colour_name = "purple" + stroke_color = "#da00ff" + shade_color = "#810cff" + stroke_color_name = "purple" + pigment_type = /decl/material/liquid/pigment/purple /obj/item/pen/crayon/mime - icon_state = "crayonmime" - stroke_colour = "#ffffff" - shade_colour = "#000000" - stroke_colour_name = "mime" - max_uses = -1 //Infinite + icon = 'icons/obj/items/crayon_mime.dmi' + color = null + stroke_color = "#ffffff" + shade_color = "#000000" + stroke_color_name = "mime" + max_uses = -1 //Infinite + pigment_type = null + use_stroke_color = FALSE /obj/item/pen/crayon/mime/make_pen_description() desc = "A very sad-looking crayon." /obj/item/pen/crayon/mime/attack_self(mob/user) //inversion - if(stroke_colour != "#ffffff" && shade_colour != "#000000") - set_medium_color("#ffffff", stroke_colour_name, "#000000") + if(stroke_color != "#ffffff" && shade_color != "#000000") + set_medium_color("#ffffff", stroke_color_name, "#000000") to_chat(user, "You will now draw in white and black with this crayon.") else - set_medium_color("#000000", stroke_colour_name, "#ffffff") + set_medium_color("#000000", stroke_color_name, "#ffffff") to_chat(user, "You will now draw in black and white with this crayon.") return /obj/item/pen/crayon/rainbow - icon_state = "crayonrainbow" - stroke_colour = "#fff000" - shade_colour = "#000fff" - stroke_colour_name = "rainbow" - max_uses = -1 + icon = 'icons/obj/items/crayon_rainbow.dmi' + color = null + stroke_color = "#fff000" + shade_color = "#000fff" + stroke_color_name = "rainbow" + max_uses = -1 + pigment_type = null + use_stroke_color = FALSE /obj/item/pen/crayon/rainbow/make_pen_description() desc = "A very colourful [istype(material)?"[material.name] ":null][medium_name]. Please refrain from eating it or putting it in your nose." /obj/item/pen/crayon/rainbow/attack_self(mob/user) - stroke_colour = input(user, "Please select the main colour.", "Crayon colour") as color - shade_colour = input(user, "Please select the shade colour.", "Crayon colour") as color - set_medium_color(stroke_colour, stroke_colour_name, shade_colour) - return + stroke_color = input(user, "Please select the main colour.", "Crayon colour") as color + shade_color = input(user, "Please select the shade colour.", "Crayon colour") as color + set_medium_color(stroke_color, stroke_color_name, shade_color) diff --git a/code/modules/paperwork/pen/crayon_edibility.dm b/code/modules/paperwork/pen/crayon_edibility.dm new file mode 100644 index 00000000000..ba7666f17e4 --- /dev/null +++ b/code/modules/paperwork/pen/crayon_edibility.dm @@ -0,0 +1,21 @@ +/obj/item/pen/crayon/transfer_eaten_material(mob/eater, amount) + var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) + parch.decrement_uses(eater, src, amount, destroy_on_zero = FALSE) // we'll qdel in food code if we eat the end of the crayon + if(!isliving(eater)) + return + var/mob/living/living_eater = eater + var/datum/reagents/eater_ingested = living_eater.get_ingested_reagents() + if(!eater_ingested) + return + if(pigment_type) + var/partial_amount = CEILING(amount * 0.4) + eater_ingested.add_reagent(pigment_type, partial_amount) + eater_ingested.add_reagent(/decl/material/solid/organic/wax, amount - partial_amount) + else + eater_ingested.add_reagent(/decl/material/solid/organic/wax, amount) + +/obj/item/pen/crayon/get_edible_material_amount(mob/eater) + return max(0, get_tool_property(TOOL_PEN, TOOL_PROP_USES)) + +/obj/item/pen/crayon/get_food_default_transfer_amount(mob/eater) + return eater?.get_eaten_transfer_amount(5) diff --git a/code/modules/paperwork/pen/fancy.dm b/code/modules/paperwork/pen/fancy.dm index 0bb353669e2..4607e7d754b 100644 --- a/code/modules/paperwork/pen/fancy.dm +++ b/code/modules/paperwork/pen/fancy.dm @@ -1,16 +1,16 @@ /obj/item/pen/fancy - name = "fountain pen" - icon = 'icons/obj/items/pens/pen_fancy.dmi' - sharp = 1 //pointy - stroke_colour = "#1c1713" //dark ashy brownish - stroke_colour_name = "dark ashy brownish" - material = /decl/material/solid/metal/steel - pen_flag = PEN_FLAG_ACTIVE | PEN_FLAG_FANCY - pen_quality = TOOL_QUALITY_GOOD - pen_font = PEN_FONT_FANCY_PEN + name = "fountain pen" + icon = 'icons/obj/items/pens/pen_fancy.dmi' + sharp = 1 //pointy + stroke_color = "#1c1713" //dark ashy brownish + stroke_color_name = "dark ashy brownish" + material = /decl/material/solid/metal/steel + pen_flag = PEN_FLAG_ACTIVE | PEN_FLAG_FANCY + pen_quality = TOOL_QUALITY_GOOD + pen_font = PEN_FONT_FANCY_PEN /obj/item/pen/fancy/make_pen_description() - desc = "A high quality [istype(material)?"[material.name] ":null]traditional [stroke_colour_name] [medium_name] fountain pen with an internal reservoir and an extra fine gold-platinum nib. Guaranteed never to leak." + desc = "A high quality [istype(material)?"[material.name] ":null]traditional [stroke_color_name] [medium_name] fountain pen with an internal reservoir and an extra fine gold-platinum nib. Guaranteed never to leak." /obj/item/pen/fancy/quill name = "dire goose quill" diff --git a/code/modules/paperwork/pen/multi_pen.dm b/code/modules/paperwork/pen/multi_pen.dm index f2c7cb636e6..500a573a8eb 100644 --- a/code/modules/paperwork/pen/multi_pen.dm +++ b/code/modules/paperwork/pen/multi_pen.dm @@ -3,8 +3,8 @@ desc = "It's a pen with multiple colors of ink!" pen_quality = TOOL_QUALITY_MEDIOCRE var/colour_idx = 1 - var/stroke_colours = list("black", "blue", "red", "green") - var/stroke_colour_names = list("black", "blue", "red", "green") + var/stroke_colors = list("black", "blue", "red", "green") + var/stroke_color_names = list("black", "blue", "red", "green") var/colour_icons = list( 'icons/obj/items/pens/pen.dmi', 'icons/obj/items/pens/pen_blue.dmi', @@ -17,15 +17,15 @@ change_colour(colour_idx) /obj/item/pen/multi/make_pen_description() - desc = "It's [istype(material)?"[ADD_ARTICLE(material.name)]":"a"] pen with multiple colors of ink! It's currently set to [stroke_colour_name] [medium_name]." + desc = "It's [istype(material)?"[ADD_ARTICLE(material.name)]":"a"] pen with multiple colors of ink! It's currently set to [stroke_color_name] [medium_name]." /obj/item/pen/multi/proc/change_colour(var/new_idx) colour_idx = new_idx - if(colour_idx > length(stroke_colours)) + if(colour_idx > length(stroke_colors)) colour_idx = 1 icon = colour_icons[colour_idx] - set_medium_color(stroke_colours[colour_idx], stroke_colour_names[colour_idx]) - + set_medium_color(stroke_colors[colour_idx], stroke_color_names[colour_idx]) + /obj/item/pen/multi/attack_self(mob/user) change_colour((++colour_idx)) - to_chat(user, SPAN_NOTICE("Changed color to '[stroke_colour_name] [medium_name].'")) + to_chat(user, SPAN_NOTICE("Changed color to '[stroke_color_name] [medium_name].'")) diff --git a/code/modules/paperwork/pen/pen.dm b/code/modules/paperwork/pen/pen.dm index f145b6795ac..8dfb5b6912c 100644 --- a/code/modules/paperwork/pen/pen.dm +++ b/code/modules/paperwork/pen/pen.dm @@ -10,8 +10,8 @@ throw_range = 15 material = /decl/material/solid/organic/plastic var/pen_flag = PEN_FLAG_ACTIVE //Properties/state of the pen used. - var/stroke_colour = "black" //What colour the ink is! Can be hexadecimal colour or a colour name string. - var/stroke_colour_name = "black" //Human readable name of the stroke colour. Used in text strings, and to identify the nearest colour to the stroke colour. + var/stroke_color = "black" //What colour the ink is! Can be hexadecimal colour or a colour name string. + var/stroke_color_name = "black" //Human readable name of the stroke colour. Used in text strings, and to identify the nearest colour to the stroke colour. var/medium_name = "ink" //Whatever the pen uses to leave its mark. Used in text strings. var/max_uses = -1 //-1 for unlimited uses. var/pen_quality = TOOL_QUALITY_DEFAULT //What will be set as tool quality for the pen @@ -27,28 +27,28 @@ list( TOOL_PEN = list( - TOOL_PROP_COLOR_NAME = stroke_colour_name, - TOOL_PROP_COLOR = stroke_colour, + TOOL_PROP_COLOR_NAME = stroke_color_name, + TOOL_PROP_COLOR = stroke_color, TOOL_PROP_PEN_FLAG = pen_flag, TOOL_PROP_USES = max_uses, TOOL_PROP_PEN_FONT = pen_font))) make_pen_description() /obj/item/pen/attack(atom/A, mob/user, target_zone) - if(ismob(A)) - var/mob/M = A - if(ishuman(A) && user.a_intent == I_HELP && target_zone == BP_HEAD) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/head = H.get_organ(BP_HEAD, /obj/item/organ/external/head) - if(istype(head)) - head.write_on(user, "[stroke_colour_name] [medium_name]") - else - to_chat(user, SPAN_WARNING("You stab [M] with \the [src].")) - admin_attack_log(user, M, "Stabbed using \a [src]", "Was stabbed with \a [src]", "used \a [src] to stab") - else if(istype(A, /obj/item/organ/external/head)) + if(isliving(A) && user.a_intent == I_HELP && target_zone == BP_HEAD) + var/mob/living/M = A + var/obj/item/organ/external/head/head = M.get_organ(BP_HEAD, /obj/item/organ/external/head) + if(istype(head)) + head.write_on(user, "[stroke_color_name] [medium_name]") + return TRUE + + if(istype(A, /obj/item/organ/external/head)) var/obj/item/organ/external/head/head = A - head.write_on(user, "[stroke_colour_name] [medium_name]") + head.write_on(user, "[stroke_color_name] [medium_name]") + return TRUE + + return ..() /obj/item/pen/proc/toggle() if(pen_flag & PEN_FLAG_ACTIVE) @@ -60,34 +60,34 @@ update_icon() /obj/item/pen/proc/set_medium_color(var/_color, var/_color_name) - stroke_colour = _color - stroke_colour_name = _color_name - set_tool_property(TOOL_PEN, TOOL_PROP_COLOR, stroke_colour) - set_tool_property(TOOL_PEN, TOOL_PROP_COLOR_NAME, stroke_colour_name) + stroke_color = _color + stroke_color_name = _color_name + set_tool_property(TOOL_PEN, TOOL_PROP_COLOR, stroke_color) + set_tool_property(TOOL_PEN, TOOL_PROP_COLOR_NAME, stroke_color_name) make_pen_description() /obj/item/pen/proc/make_pen_description() - desc = "Its [ADD_ARTICLE(stroke_colour_name)] [medium_name] [istype(material)? material.name : ""] pen." + desc = "Its [ADD_ARTICLE(stroke_color_name)] [medium_name] [istype(material)? material.name : ""] pen." /obj/item/pen/blue - name = "blue pen" - icon = 'icons/obj/items/pens/pen_blue.dmi' - stroke_colour = "blue" - stroke_colour_name = "blue" + name = "blue pen" + icon = 'icons/obj/items/pens/pen_blue.dmi' + stroke_color = "blue" + stroke_color_name = "blue" /obj/item/pen/red - name = "red pen" - icon = 'icons/obj/items/pens/pen_red.dmi' - stroke_colour = "red" - stroke_colour_name = "red" + name = "red pen" + icon = 'icons/obj/items/pens/pen_red.dmi' + stroke_color = "red" + stroke_color_name = "red" /obj/item/pen/green - name = "green pen" - icon = 'icons/obj/items/pens/pen_green.dmi' - stroke_colour = "green" - stroke_colour_name = "green" + name = "green pen" + icon = 'icons/obj/items/pens/pen_green.dmi' + stroke_color = "green" + stroke_color_name = "green" /obj/item/pen/invisible - name = "pen" - stroke_colour = "white" - stroke_colour_name = "transluscent" + name = "pen" + stroke_color = "white" + stroke_color_name = "transluscent" diff --git a/code/modules/paperwork/pen/reagent_pen.dm b/code/modules/paperwork/pen/reagent_pen.dm index 1b531b72cce..fef8535af42 100644 --- a/code/modules/paperwork/pen/reagent_pen.dm +++ b/code/modules/paperwork/pen/reagent_pen.dm @@ -1,6 +1,6 @@ /obj/item/pen/reagent atom_flags = ATOM_FLAG_OPEN_CONTAINER - origin_tech = "{'materials':2,'esoteric':5}" + origin_tech = @'{"materials":2,"esoteric":5}' sharp = 1 pen_quality = TOOL_QUALITY_MEDIOCRE @@ -38,10 +38,10 @@ * Sleepy Pens */ /obj/item/pen/reagent/sleepy - origin_tech = "{'materials':2,'esoteric':5}" + origin_tech = @'{"materials":2,"esoteric":5}' /obj/item/pen/reagent/sleepy/make_pen_description() - desc = "It's \a [stroke_colour_name] [medium_name] pen with a sharp point and a carefully engraved \"Waffle Co.\"." + desc = "It's \a [stroke_color_name] [medium_name] pen with a sharp point and a carefully engraved \"Waffle Co.\"." /obj/item/pen/reagent/sleepy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/paralytics, round(reagents.maximum_volume/2)) + add_to_reagents(/decl/material/liquid/paralytics, round(reagents.maximum_volume/2)) diff --git a/code/modules/paperwork/pen/retractable_pen.dm b/code/modules/paperwork/pen/retractable_pen.dm index 3e728611f78..ed9c8851fdc 100644 --- a/code/modules/paperwork/pen/retractable_pen.dm +++ b/code/modules/paperwork/pen/retractable_pen.dm @@ -4,23 +4,23 @@ pen_flag = PEN_FLAG_TOGGLEABLE /obj/item/pen/retractable/blue - stroke_colour = "blue" - stroke_colour_name = "blue" - icon = 'icons/obj/items/pens/pen_retractable_blue.dmi' + stroke_color = "blue" + stroke_color_name = "blue" + icon = 'icons/obj/items/pens/pen_retractable_blue.dmi' /obj/item/pen/retractable/red - stroke_colour = "red" - stroke_colour_name = "red" - icon = 'icons/obj/items/pens/pen_retractable_red.dmi' + stroke_color = "red" + stroke_color_name = "red" + icon = 'icons/obj/items/pens/pen_retractable_red.dmi' /obj/item/pen/retractable/green - stroke_colour = "green" - stroke_colour_name = "green" - icon = 'icons/obj/items/pens/pen_retractable_green.dmi' + stroke_color = "green" + stroke_color_name = "green" + icon = 'icons/obj/items/pens/pen_retractable_green.dmi' /obj/item/pen/retractable/Initialize() . = ..() - desc = "It's a retractable [stroke_colour_name] [medium_name] pen." + desc = "It's a retractable [stroke_color_name] [medium_name] pen." /obj/item/pen/retractable/on_update_icon() . = ..() diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 38109cacea2..01ffa0e2528 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -5,7 +5,7 @@ name = "circuitboard (photocopier)" build_path = /obj/machinery/photocopier board_type = "machine" - origin_tech = "{'engineering':1, 'programming':1}" + origin_tech = @'{"engineering":1, "programming":1}' req_components = list( /obj/item/stock_parts/printer/buildable = 1, /obj/item/stock_parts/manipulator = 2, @@ -60,10 +60,10 @@ printer = get_component_of_type(/obj/item/stock_parts/printer) //Cache the printer component if(printer) printer.show_queue_ctrl = FALSE //Make sure we don't let users mess with the print queue - printer.register_on_printed_page( CALLBACK(src, /obj/machinery/photocopier/proc/update_ui)) - printer.register_on_finished_queue(CALLBACK(src, /obj/machinery/photocopier/proc/update_ui)) - printer.register_on_print_error( CALLBACK(src, /obj/machinery/photocopier/proc/update_ui)) - printer.register_on_status_changed(CALLBACK(src, /obj/machinery/photocopier/proc/update_ui)) + printer.register_on_printed_page( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/photocopier, update_ui))) + printer.register_on_finished_queue(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/photocopier, update_ui))) + printer.register_on_print_error( CALLBACK(src, TYPE_PROC_REF(/obj/machinery/photocopier, update_ui))) + printer.register_on_status_changed(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/photocopier, update_ui))) /obj/machinery/photocopier/on_update_icon() cut_overlays() diff --git a/code/modules/paperwork/printer.dm b/code/modules/paperwork/printer.dm index 447d8ee87b7..83c8af53727 100644 --- a/code/modules/paperwork/printer.dm +++ b/code/modules/paperwork/printer.dm @@ -281,7 +281,19 @@ stop_printing_queue() return FALSE print_picture(queued_element) - else + else if(istype(queued_element, /obj/item/paper_bundle)) + var/obj/item/paper_bundle/bundle = queued_element + var/photo_count = 0 + for(var/obj/item/photo/picture in bundle.pages) + photo_count++ + if(!has_enough_to_print((TONER_USAGE_PAPER * (length(bundle.pages) - photo_count)) + (TONER_USAGE_PHOTO * photo_count))) + var/obj/machinery/M = loc + if(istype(M)) + M.state("Warning: Not enough paper or toner!") + stop_printing_queue() + return FALSE + print_paper_bundle(bundle) + else if(istype(queued_element, /obj/item/paper)) if(!has_enough_to_print(TONER_USAGE_PAPER)) var/obj/machinery/M = loc if(istype(M)) @@ -289,6 +301,8 @@ stop_printing_queue() return FALSE print_paper(queued_element) + else + PRINT_STACK_TRACE("A printer printed something that wasn't a paper, paper bundle, or photo: [queued_element] ([queued_element.type])") //#TODO: machinery should allow a component to trigger and wait for an animation sequence. So that we can drop out the paper in sync. queued_element.dropInto(get_turf(loc)) @@ -305,6 +319,14 @@ use_toner(TONER_USAGE_PHOTO, FALSE) //photos use a lot of ink! use_paper(1) + P.update_icon() + +/obj/item/stock_parts/printer/proc/print_paper_bundle(var/obj/item/paper_bundle/bundle) + for(var/obj/item/paper/page in bundle.pages) + print_paper(page) + for(var/obj/item/photo/picture in bundle.pages) + print_picture(picture) + bundle.update_icon() /obj/item/stock_parts/printer/proc/print_paper(var/obj/item/paper/P) //Apply a greyscale filter on all stamps overlays @@ -321,6 +343,7 @@ use_toner(TONER_USAGE_PAPER, FALSE) use_paper(1) + P.update_icon() // reapply stamp overlays /obj/item/stock_parts/printer/proc/use_toner(var/amount, var/update_parent = TRUE) if(!toner?.use_toner(amount)) diff --git a/code/modules/paperwork/toner_cartridge.dm b/code/modules/paperwork/toner_cartridge.dm index 8550afbd739..c5438f3f42c 100644 --- a/code/modules/paperwork/toner_cartridge.dm +++ b/code/modules/paperwork/toner_cartridge.dm @@ -19,8 +19,8 @@ /obj/item/chems/toner_cartridge/populate_reagents() //Normally this would be toner powder, but probably not worth making a material for that. - reagents.add_reagent(/decl/material/liquid/paint, reagents.maximum_volume/2) - reagents.add_reagent(/decl/material/liquid/pigment/black, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/paint, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/pigment/black, reagents.maximum_volume/2) /obj/item/chems/toner_cartridge/dump_contents() . = ..() @@ -48,5 +48,5 @@ return var/amt_each = round(amount/2) if(reagents.has_reagent(/decl/material/liquid/pigment/black, amt_each) && reagents.has_reagent(/decl/material/liquid/paint, amt_each)) - reagents.remove_any(amount) + remove_any_reagents(amount) return TRUE \ No newline at end of file diff --git a/code/modules/persistence/noticeboards.dm b/code/modules/persistence/noticeboards.dm index b66f89eca98..9a6d48d0613 100644 --- a/code/modules/persistence/noticeboards.dm +++ b/code/modules/persistence/noticeboards.dm @@ -8,7 +8,7 @@ layer = ABOVE_WINDOW_LAYER tool_interaction_flags = TOOL_INTERACTION_DECONSTRUCT obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' material = /decl/material/solid/organic/wood var/tmp/max_notices = 5 var/list/notices diff --git a/code/modules/pointdefense/pointdefense.dm b/code/modules/pointdefense/pointdefense.dm index a4f3f91a577..dfec4c84562 100644 --- a/code/modules/pointdefense/pointdefense.dm +++ b/code/modules/pointdefense/pointdefense.dm @@ -159,7 +159,7 @@ var/Angle = round(Get_Angle(src,M)) var/matrix/rot_matrix = matrix() rot_matrix.Turn(Angle) - addtimer(CALLBACK(src, .proc/finish_shot, target), rotation_speed) + addtimer(CALLBACK(src, PROC_REF(finish_shot), target), rotation_speed) animate(src, transform = rot_matrix, rotation_speed, easing = SINE_EASING) set_dir(transform.get_angle() > 0 ? NORTH : SOUTH) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 4190c0b618b..27911cf1baa 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -100,7 +100,7 @@ var/global/list/all_apcs = list() initial_access = list(access_engine_equip) clicksound = "switch" layer = ABOVE_WINDOW_LAYER - directional_offset = "{'NORTH':{'y':22}, 'SOUTH':{'y':-22}, 'EAST':{'x':22}, 'WEST':{'x':-22}}" + directional_offset = @'{"NORTH":{"y":22}, "SOUTH":{"y":-22}, "EAST":{"x":22}, "WEST":{"x":-22}}' var/powered_down = FALSE var/area/area @@ -220,14 +220,14 @@ var/global/list/all_apcs = list() old_area.power_environ = 0 power_alarm.clearAlarm(old_area, src) old_area.power_change() - events_repository.unregister(/decl/observ/name_set, old_area, src, .proc/change_area_name) + events_repository.unregister(/decl/observ/name_set, old_area, src, PROC_REF(change_area_name)) if(new_area) ASSERT(isnull(new_area.apc)) ASSERT(isnull(area)) new_area.apc = src area = new_area change_area_name(new_area, null, new_area.name) - events_repository.register(/decl/observ/name_set, new_area, src, .proc/change_area_name) + events_repository.register(/decl/observ/name_set, new_area, src, PROC_REF(change_area_name)) /obj/machinery/power/apc/get_req_access() if(!locked) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 96294671f18..511f941c84f 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -377,8 +377,7 @@ By design, d1 is the smallest direction and d2 is the highest // Powernets handling helpers ////////////////////////////////////////////// -//if powernetless_only = 1, will only get connections without powernet -/obj/structure/cable/proc/get_connections(var/powernetless_only = 0) +/obj/structure/cable/proc/get_cable_connections(var/skip_assigned_powernets = FALSE) . = list() // this will be a list of all connected power objects var/turf/T @@ -406,17 +405,22 @@ By design, d1 is the smallest direction and d2 is the highest if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) // if either of C's d1 and d2 match either of ours . += C + // if asked, skip any cables with powernts + if(skip_assigned_powernets) + for(var/obj/structure/cable/C in .) + if(C.powernet) + . -= C + +/obj/structure/cable/proc/get_machine_connections(var/skip_assigned_powernets = FALSE) + . = list() // this will be a list of all connected power objects if(d1 == 0) for(var/obj/machinery/power/P in loc) if(P.powernet == 0) continue // exclude APCs with powernet=0 - if(!powernetless_only || !P.powernet) + if(!skip_assigned_powernets || !P.powernet) . += P - // if the caller asked for powernetless cables only, dump the ones with powernets - if(powernetless_only) - for(var/obj/structure/cable/C in .) - if(C.powernet) - . -= C +/obj/structure/cable/proc/get_connections(var/skip_assigned_powernets = FALSE) + return get_cable_connections(skip_assigned_powernets) + get_machine_connections(skip_assigned_powernets) //should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf. //needed as this can, unlike other placements, disconnect cables diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index bea144daa63..e5c5de34844 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/power.dmi' icon_state = "cell" item_state = "cell" - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' force = 5.0 throwforce = 5 throw_speed = 3 @@ -18,7 +18,6 @@ ) var/charge // Current charge var/maxcharge = 1000 // Capacity in Wh - var/overlay_state /obj/item/cell/Initialize() . = ..() @@ -40,19 +39,16 @@ /obj/item/cell/on_update_icon() . = ..() - var/new_overlay_state = null + var/overlay_state = null switch(percent()) if(95 to 100) - new_overlay_state = "cell-o2" + overlay_state = "cell-o2" if(25 to 95) - new_overlay_state = "cell-o1" + overlay_state = "cell-o1" if(0.05 to 25) - new_overlay_state = "cell-o0" - - if(new_overlay_state != overlay_state) - overlay_state = new_overlay_state - if(overlay_state) - add_overlay(overlay_state) + overlay_state = "cell-o0" + if(overlay_state) + add_overlay(overlay_state) /obj/item/cell/proc/percent() // return % charge of cell return maxcharge && (100.0*charge/maxcharge) @@ -152,7 +148,7 @@ maxcharge = 100 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'powerstorage':2}" + origin_tech = @'{"powerstorage":2}' /obj/item/cell/device/infinite name = "experimental device power cell" @@ -191,7 +187,7 @@ /obj/item/cell/crap name = "old power cell" desc = "A cheap old power cell. It's probably been in use for quite some time now." - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' maxcharge = 100 material = /decl/material/solid/metal/steel matter = list( @@ -205,7 +201,7 @@ /obj/item/cell/standard name = "standard power cell" desc = "A standard and relatively cheap power cell, commonly used." - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' maxcharge = 250 material = /decl/material/solid/metal/steel matter = list( @@ -216,7 +212,7 @@ /obj/item/cell/apc name = "APC power cell" desc = "A special power cell designed for heavy-duty use in area power controllers." - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' maxcharge = 500 material = /decl/material/solid/metal/steel matter = list( @@ -228,7 +224,7 @@ /obj/item/cell/high name = "advanced power cell" desc = "An advanced high-grade power cell, for use in important systems." - origin_tech = "{'powerstorage':2}" + origin_tech = @'{"powerstorage":2}' icon_state = "hcell" maxcharge = 1000 material = /decl/material/solid/metal/steel @@ -243,7 +239,7 @@ /obj/item/cell/exosuit name = "exosuit power cell" desc = "A special power cell designed for heavy-duty use in industrial exosuits." - origin_tech = "{'powerstorage':3}" + origin_tech = @'{"powerstorage":3}' icon_state = "hcell" maxcharge = 1500 material = /decl/material/solid/metal/steel @@ -256,7 +252,7 @@ /obj/item/cell/super name = "enhanced power cell" desc = "A very advanced power cell with increased energy density, for use in critical applications." - origin_tech = "{'powerstorage':5}" + origin_tech = @'{"powerstorage":5}' icon_state = "scell" maxcharge = 2000 material = /decl/material/solid/metal/steel @@ -271,7 +267,7 @@ /obj/item/cell/hyper name = "superior power cell" desc = "Pinnacle of power storage technology, this very expensive power cell provides the best energy density reachable with conventional electrochemical cells." - origin_tech = "{'powerstorage':6}" + origin_tech = @'{"powerstorage":6}' icon_state = "hpcell" maxcharge = 3000 material = /decl/material/solid/metal/steel @@ -322,7 +318,7 @@ /obj/item/cell/potato name = "potato battery" desc = "A rechargable starch based power cell." - origin_tech = "{'powerstorage':1}" + origin_tech = @'{"powerstorage":1}' icon = 'icons/obj/power.dmi' icon_state = "potato_cell" maxcharge = 20 @@ -331,7 +327,7 @@ /obj/item/cell/gun name = "weapon energy cell" desc = "A military grade high-density battery, expected to deplete after tens of thousands of complete charge cycles." - origin_tech = "{'combat':2,'materials':2,'powerstorage': 2}" + origin_tech = @'{"combat":2,"materials":2,"powerstorage": 2}' icon_state = "gunbattery" maxcharge = 500 w_class = ITEM_SIZE_SMALL //Perhaps unwise. diff --git a/code/modules/power/fission/fission_circuits.dm b/code/modules/power/fission/fission_circuits.dm index 27c88bea33e..f36b48f2fa3 100644 --- a/code/modules/power/fission/fission_circuits.dm +++ b/code/modules/power/fission/fission_circuits.dm @@ -1,13 +1,13 @@ /obj/item/stock_parts/circuitboard/fission_core_control name = "circuit board (fission core controller)" build_path = /obj/machinery/computer/fission - origin_tech = "{'programming':2,'engineering':3}" + origin_tech = @'{"programming":2,"engineering":3}' /obj/item/stock_parts/circuitboard/unary_atmos/fission_core name = "circuit board (fission core)" build_path = /obj/machinery/atmospherics/unary/fission_core board_type = "machine" - origin_tech = "{'engineering':2,'materials':2}" + origin_tech = @'{"engineering":2,"materials":2}' additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1 ) diff --git a/code/modules/power/fuel_assembly/fuel_compressor.dm b/code/modules/power/fuel_assembly/fuel_compressor.dm index 66f96e83ca1..2511153f996 100644 --- a/code/modules/power/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fuel_assembly/fuel_compressor.dm @@ -123,7 +123,7 @@ if(istype(thing) && thing.reagents && thing.reagents.total_volume && ATOM_IS_OPEN_CONTAINER(thing)) for(var/R in thing.reagents.reagent_volumes) var/taking_reagent = REAGENT_VOLUME(thing.reagents, R) - thing.reagents.remove_reagent(R, taking_reagent) + thing.remove_from_reagents(R, taking_reagent) stored_material[R] += taking_reagent to_chat(user, SPAN_NOTICE("You add the contents of \the [thing] to \the [src]'s material buffer.")) diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index c053090aac8..f1ac424ed41 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -87,7 +87,7 @@ catcher.SetSize((iter*2)+1) particle_catchers.Add(catcher) - addtimer(CALLBACK(src, .proc/update_light_colors), 10 SECONDS, TIMER_LOOP) + addtimer(CALLBACK(src, PROC_REF(update_light_colors)), 10 SECONDS, TIMER_LOOP) /obj/effect/fusion_em_field/proc/handle_tick() //make sure the field generator is still intact @@ -194,7 +194,7 @@ if(field_cohesion == 0) owned_core.Shutdown(force_rupture=1) - + if(percent_unstable > 0.5 && prob(percent_unstable*100)) if(plasma_temperature < FUSION_RUPTURE_THRESHOLD) visible_message("\The [src] ripples uneasily, like a disturbed pond.") diff --git a/code/modules/power/fusion/fusion_circuits.dm b/code/modules/power/fusion/fusion_circuits.dm index 73814a03224..b03d6a03616 100644 --- a/code/modules/power/fusion/fusion_circuits.dm +++ b/code/modules/power/fusion/fusion_circuits.dm @@ -1,13 +1,13 @@ /obj/item/stock_parts/circuitboard/fusion/core_control name = "circuitboard (fusion core controller)" build_path = /obj/machinery/computer/fusion/core_control - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' /obj/item/stock_parts/circuitboard/kinetic_harvester name = "circuitboard (kinetic harvester)" build_path = /obj/machinery/kinetic_harvester board_type = "machine" - origin_tech = "{'programming':4,'engineering':4,'materials':4}" + origin_tech = @'{"programming":4,"engineering":4,"materials":4}' additional_spawn_components = list( /obj/item/stock_parts/console_screen = 1, /obj/item/stock_parts/keyboard = 1 @@ -21,18 +21,18 @@ /obj/item/stock_parts/circuitboard/fusion_fuel_control name = "circuitboard (fusion fuel controller)" build_path = /obj/machinery/computer/fusion/fuel_control - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' /obj/item/stock_parts/circuitboard/gyrotron_control name = "circuitboard (gyrotron controller)" build_path = /obj/machinery/computer/fusion/gyrotron - origin_tech = "{'programming':4,'engineering':4}" + origin_tech = @'{"programming":4,"engineering":4}' /obj/item/stock_parts/circuitboard/fusion_core name = "circuitboard (fusion core)" build_path = /obj/machinery/fusion_core board_type = "machine" - origin_tech = "{'wormholes':2,'magnets':4,'powerstorage':4}" + origin_tech = @'{"wormholes":2,"magnets":4,"powerstorage":4}' additional_spawn_components = list( /obj/item/stock_parts/power/terminal = 1 ) @@ -48,7 +48,7 @@ name = "circuitboard (fusion fuel injector)" build_path = /obj/machinery/fusion_fuel_injector board_type = "machine" - origin_tech = "{'powerstorage':3,'engineering':4,'materials':4}" + origin_tech = @'{"powerstorage":3,"engineering":4,"materials":4}' req_components = list( /obj/item/stock_parts/manipulator/pico = 2, /obj/item/stock_parts/scanning_module/phasic = 1, @@ -61,7 +61,7 @@ name = "circuitboard (gyrotron)" build_path = /obj/machinery/emitter/gyrotron board_type = "machine" - origin_tech = "{'powerstorage':4,'engineering':4}" + origin_tech = @'{"powerstorage":4,"engineering":4}' additional_spawn_components = list( /obj/item/stock_parts/power/terminal = 1 ) diff --git a/code/modules/power/geothermal/_geothermal.dm b/code/modules/power/geothermal/_geothermal.dm index 5b235aec9a3..101fdd6bcbf 100644 --- a/code/modules/power/geothermal/_geothermal.dm +++ b/code/modules/power/geothermal/_geothermal.dm @@ -190,7 +190,7 @@ var/global/const/MAX_GEOTHERMAL_PRESSURE = 12000 current_pressure = clamp(current_pressure + pressure, 0, MAX_GEOTHERMAL_PRESSURE) var/leftover = round(pressure - current_pressure) if(leftover > 0) - addtimer(CALLBACK(src, .proc/propagate_pressure, leftover), 5) + addtimer(CALLBACK(src, PROC_REF(propagate_pressure), leftover), 5) update_icon() START_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF) @@ -207,7 +207,7 @@ var/global/const/MAX_GEOTHERMAL_PRESSURE = 12000 generate_power(last_generated) remaining_pressure = round(remaining_pressure * GEOTHERMAL_PRESSURE_LOSS) if(remaining_pressure) - addtimer(CALLBACK(src, .proc/propagate_pressure, remaining_pressure), 5) + addtimer(CALLBACK(src, PROC_REF(propagate_pressure), remaining_pressure), 5) update_icon() if(current_pressure <= 1) return PROCESS_KILL diff --git a/code/modules/power/geothermal/geothermal_circuit.dm b/code/modules/power/geothermal/geothermal_circuit.dm index 07d451d68fa..f569521f85e 100644 --- a/code/modules/power/geothermal/geothermal_circuit.dm +++ b/code/modules/power/geothermal/geothermal_circuit.dm @@ -2,7 +2,7 @@ name = "circuitboard (geothermal generator)" build_path = /obj/machinery/geothermal board_type = "machine" - origin_tech = "{'magnets':3,'powerstorage':3}" + origin_tech = @'{"magnets":3,"powerstorage":3}' req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/manipulator = 2, diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 1e1e35e3b1d..b0279ba8abd 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -37,7 +37,7 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed/simple base_type = /obj/machinery/light frame_type = /obj/item/frame/light - directional_offset = "{'NORTH':{'y':21}, 'EAST':{'x':10}, 'WEST':{'x':-10}}" + directional_offset = @'{"NORTH":{"y":21}, "EAST":{"x":10}, "WEST":{"x":-10}}' var/on = 0 // 1 if on, 0 if off var/flickering = 0 diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index aecb50256ac..4484366423b 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -467,7 +467,7 @@ if(reagents.has_reagent(/decl/material/liquid/ethanol/vodka)) rad_power = 4 temperature_gain = 60 - reagents.remove_any(1) + remove_any_reagents(1) if(prob(2)) audible_message("[src] churns happily") else diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 9b06f213441..d2db88a1164 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -127,32 +127,25 @@ return . //remove the old powernet and replace it with a new one throughout the network. -/proc/propagate_network(var/obj/O, var/datum/powernet/PN) +/proc/propagate_network(var/obj/structure/cable/cable, var/datum/powernet/PN) //to_world_log("propagating new network") - var/list/worklist = list() + var/list/cables = list() var/list/found_machines = list() var/index = 1 - var/obj/P = null + var/obj/structure/cable/working_cable = null - worklist+=O //start propagating from the passed object - - while(index<=worklist.len) //until we've exhausted all power objects - P = worklist[index] //get the next power object found + // add the first cable to the list + cables[cable] = TRUE // associative list for speedy deduplication + while(index <= length(cables)) //until we've exhausted all power objects + working_cable = cables[index] //get the next power object found index++ - if( istype(P,/obj/structure/cable)) - var/obj/structure/cable/C = P - if(C.powernet != PN) //add it to the powernet, if it isn't already there - PN.add_cable(C) - worklist |= C.get_connections() //get adjacents power objects, with or without a powernet - - else if(P.anchored && istype(P,/obj/machinery/power)) - var/obj/machinery/power/M = P - found_machines |= M //we wait until the powernet is fully propagates to connect the machines - - else - continue + for(var/new_cable in working_cable.get_cable_connections()) //get adjacent cables, with or without a powernet + cables[new_cable] = TRUE + for(var/obj/structure/cable/cable_entry in cables) + PN.add_cable(cable_entry) + found_machines += cable_entry.get_machine_connections() //now that the powernet is set, connect found machines to it for(var/obj/machinery/power/PM in found_machines) if(!PM.connect_to_network()) //couldn't find a node on its turf... diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index 7715489a37a..0c17afb2c3c 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -29,7 +29,7 @@ animation.pixel_y = -32 animation.layer = SINGULARITY_EFFECT_LAYER flick('icons/effects/singularity_effect.dmi', animation) - addtimer(CALLBACK(src, .proc/spawn_contained, T), 6 SECOND) + addtimer(CALLBACK(src, PROC_REF(spawn_contained), T), 6 SECOND) QDEL_IN(animation, 7 SECOND) return PROCESS_KILL diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index 71ac8ba8da2..bea33abcdbf 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -12,7 +12,7 @@ icon = 'icons/obj/items/stock_parts/stock_parts.dmi' icon_state = "smes_coil" w_class = ITEM_SIZE_LARGE // It's LARGE (backpack size) - origin_tech = "{'materials':7,'powerstorage':7,'engineering':5}" + origin_tech = @'{"materials":7,"powerstorage":7,"engineering":5}' base_type = /obj/item/stock_parts/smes_coil part_flags = PART_FLAG_HAND_REMOVE material = /decl/material/solid/metal/steel diff --git a/code/modules/power/stirling.dm b/code/modules/power/stirling.dm index db91f60ed90..b3e94d0f3e5 100644 --- a/code/modules/power/stirling.dm +++ b/code/modules/power/stirling.dm @@ -39,9 +39,15 @@ /obj/machinery/atmospherics/binary/stirling/Process() ..() + if(!active) + return + var/line1_heatcap = air1.heat_capacity() var/line2_heatcap = air2.heat_capacity() + if(!(line1_heatcap + line2_heatcap)) + return + var/delta_t = air1.temperature - air2.temperature // Absolute value of the heat transfer required to bring both lines in equilibrium. diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index ef5f5234dab..2a7598b01da 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -137,7 +137,7 @@ /obj/item/ammo_magazine/pistol name = "pistol magazine" icon_state = "pistol" - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' mag_type = MAGAZINE caliber = CALIBER_PISTOL material = /decl/material/solid/metal/steel @@ -185,7 +185,7 @@ /obj/item/ammo_magazine/box/smallpistol name = "ammunition box (pistol, small)" icon_state = "smallpistol" - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' material = /decl/material/solid/metal/steel caliber = CALIBER_PISTOL_SMALL ammo_type = /obj/item/ammo_casing/pistol/small @@ -194,7 +194,7 @@ /obj/item/ammo_magazine/box/pistol name = "ammunition box (pistol)" icon_state = "smallpistol" - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' caliber = CALIBER_PISTOL material = /decl/material/solid/metal/steel ammo_type = /obj/item/ammo_casing/pistol @@ -210,7 +210,7 @@ ammo_type = /obj/item/ammo_casing/pistol/emp caliber = CALIBER_PISTOL max_ammo = 15 - origin_tech = "{'combat':2,'magnets':2,'powerstorage':2}" + origin_tech = @'{"combat":2,"magnets":2,"powerstorage":2}' /obj/item/ammo_magazine/box/emp/smallpistol name = "ammunition box (pistol, small, haywire)" @@ -219,12 +219,12 @@ ammo_type = /obj/item/ammo_casing/pistol/small/emp caliber = CALIBER_PISTOL_SMALL max_ammo = 8 - origin_tech = "{'combat':2,'magnets':2,'powerstorage':2}" + origin_tech = @'{"combat":2,"magnets":2,"powerstorage":2}' /obj/item/ammo_magazine/rifle name = "assault rifle magazine" icon_state = "bullup" - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' mag_type = MAGAZINE caliber = CALIBER_RIFLE material = /decl/material/solid/metal/steel @@ -242,7 +242,7 @@ /obj/item/ammo_magazine/rifle/drum name = "machine gun drum magazine" icon_state = "drum" - origin_tech = "{'combat':2}" + origin_tech = @'{"combat":2}' mag_type = MAGAZINE caliber = CALIBER_RIFLE material = /decl/material/solid/metal/steel diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 9d73afb91c8..7966b8e04f9 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -85,7 +85,7 @@ leaves_residue = 0 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'combat':3,'materials':3}" + origin_tech = @'{"combat":3,"materials":3}' /obj/item/ammo_casing/shotgun name = "shotgun slug" @@ -140,7 +140,7 @@ leaves_residue = 0 material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'combat':3,'materials':3}" + origin_tech = @'{"combat":3,"materials":3}' /obj/item/ammo_casing/shotgun/stunshell/emp_act(severity) if(prob(100/severity)) BB = null @@ -164,7 +164,7 @@ projectile_type = /obj/item/projectile/ion material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/uranium = MATTER_AMOUNT_REINFORCEMENT) - origin_tech = "{'combat':4,'materials':3}" + origin_tech = @'{"combat":4,"materials":3}' /obj/item/ammo_casing/shell name = "shell casing" diff --git a/code/modules/projectiles/ammunition/chemdart.dm b/code/modules/projectiles/ammunition/chemdart.dm index 96f183544db..6d9d1bc644c 100644 --- a/code/modules/projectiles/ammunition/chemdart.dm +++ b/code/modules/projectiles/ammunition/chemdart.dm @@ -35,7 +35,7 @@ desc = "A rack of hollow darts." icon_state = "darts" item_state = "rcdammo" - origin_tech = "{'materials':2}" + origin_tech = @'{"materials":2}' mag_type = MAGAZINE caliber = CALIBER_DART ammo_type = /obj/item/ammo_casing/chemdart diff --git a/code/modules/projectiles/ammunition/magnetic.dm b/code/modules/projectiles/ammunition/magnetic.dm index 4ad8d749207..893bde26c0c 100644 --- a/code/modules/projectiles/ammunition/magnetic.dm +++ b/code/modules/projectiles/ammunition/magnetic.dm @@ -8,7 +8,7 @@ var/basetype = /obj/item/magnetic_ammo w_class = ITEM_SIZE_SMALL material = /decl/material/solid/metal/steel - origin_tech = "{'combat':1}" + origin_tech = @'{"combat":1}' var/remaining = 9 /obj/item/magnetic_ammo/examine(mob/user) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index e90db8e722f..ef938388a68 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -41,7 +41,7 @@ throw_speed = 4 throw_range = 5 force = 5 - origin_tech = "{'combat':1}" + origin_tech = @'{"combat":1}' attack_verb = list("struck", "hit", "bashed") zoomdevicename = "scope" @@ -123,7 +123,7 @@ autofiring_at = fire_at autofiring_by = fire_by if(!autofiring_timer) - autofiring_timer = addtimer(CALLBACK(src, .proc/handle_autofire, autoturn), burst_delay, (TIMER_STOPPABLE | TIMER_LOOP | TIMER_UNIQUE | TIMER_OVERRIDE)) + autofiring_timer = addtimer(CALLBACK(src, PROC_REF(handle_autofire), autoturn), burst_delay, (TIMER_STOPPABLE | TIMER_LOOP | TIMER_UNIQUE | TIMER_OVERRIDE)) else clear_autofire() @@ -170,11 +170,17 @@ /obj/item/gun/proc/get_safety_indicator() return mutable_appearance(icon, "[get_world_inventory_state()][safety_icon][safety()]") -/obj/item/gun/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) - if(overlay && user_mob.can_wield_item(src) && is_held_twohanded(user_mob) && check_state_in_icon("[overlay.icon_state]-wielded", overlay.icon)) - overlay.icon_state = "[overlay.icon_state]-wielded" +/obj/item/gun/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) + if(overlay && user_mob.can_wield_item(src) && is_held_twohanded(user_mob)) + var/wielded_state = "[overlay.icon_state]-wielded" + if(check_state_in_icon(wielded_state, overlay.icon)) + overlay.icon_state = wielded_state + apply_gun_mob_overlays(user_mob, bodytype, overlay, slot, bodypart) . = ..() +/obj/item/gun/proc/apply_gun_mob_overlays(var/mob/living/user_mob, var/bodytype, var/image/overlay, var/slot, var/bodypart, var/skip_offset = FALSE) + return + //Checks whether a given mob can use the gun //Any checks that shouldn't result in handle_click_empty() being called if they fail should go here. //Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there. @@ -259,6 +265,7 @@ var/mob/living/user = null if(isliving(firer)) user = firer + target_zone = user.get_target_zone() if(istype(user)) add_fingerprint(user) @@ -703,7 +710,7 @@ else M.setClickCooldown(DEFAULT_QUICK_COOLDOWN) // Spam prevention, essentially. M.visible_message(SPAN_DANGER("\The [M] pulls the trigger reflexively!")) - Fire(aiming_at, M, target_zone = M.get_target_zone()) + Fire(aiming_at, M) if(M.aiming) M.aiming.toggle_active(FALSE, TRUE) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index b8fb610335a..d5591d0a683 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -114,7 +114,7 @@ var/global/list/registered_cyborg_weapons = list() if(charge_meter) update_charge_meter() -/obj/item/gun/energy/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/gun/energy/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && charge_meter) var/charge_state = get_charge_state(overlay.icon_state) if(charge_state && check_state_in_icon(charge_state, overlay.icon)) diff --git a/code/modules/projectiles/guns/energy/capacitor.dm b/code/modules/projectiles/guns/energy/capacitor.dm index 47f053dd7b4..c05eddafd3d 100644 --- a/code/modules/projectiles/guns/energy/capacitor.dm +++ b/code/modules/projectiles/guns/energy/capacitor.dm @@ -47,9 +47,10 @@ var/global/list/laser_wavelengths desc = "An excitingly chunky directed energy weapon that uses a modular capacitor array to charge each shot." icon = 'icons/obj/guns/capacitor_pistol.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':4,'materials':4,'powerstorage':4}" + origin_tech = @'{"combat":4,"materials":4,"powerstorage":4}' w_class = ITEM_SIZE_NORMAL charge_cost = 100 + charge_meter = FALSE accuracy = 2 fire_delay = 10 slot_flags = SLOT_LOWER_BODY @@ -140,7 +141,7 @@ var/global/list/laser_wavelengths charging = FALSE else var/new_wavelength = input("Select the desired laser wavelength.", "Capacitor Laser Wavelength", selected_wavelength) as null|anything in global.laser_wavelengths - if(!charging && new_wavelength != selected_wavelength && (loc == user || user.Adjacent(src)) && !user.incapacitated()) + if(!charging && new_wavelength && new_wavelength != selected_wavelength && (loc == user || user.Adjacent(src)) && !user.incapacitated()) selected_wavelength = new_wavelength to_chat(user, SPAN_NOTICE("You dial \the [src] wavelength to [selected_wavelength.name].")) update_icon() @@ -218,7 +219,8 @@ var/global/list/laser_wavelengths var/mob/M = loc M.update_inhand_overlays() -/obj/item/gun/energy/capacitor/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/gun/energy/capacitor/apply_gun_mob_overlays(var/mob/living/user_mob, var/bodytype, var/image/overlay, var/slot, var/bodypart, var/skip_offset = FALSE) + ..() if(overlay && (slot == BP_L_HAND || slot == BP_R_HAND || slot == slot_back_str)) var/image/I = image(overlay.icon, "[overlay.icon_state]-wiring") I.color = wiring_color @@ -227,16 +229,14 @@ var/global/list/laser_wavelengths if(get_cell()) I = image(overlay.icon, "[overlay.icon_state]-cell") overlay.add_overlay(I) - if(slot != slot_back_str) - for(var/i = 1 to length(capacitors)) - var/obj/item/stock_parts/capacitor/capacitor = capacitors[i] - if(capacitor.charge > 0) - I = emissive_overlay(overlay.icon, "[overlay.icon_state]-charging-[i]") - I.alpha = clamp(255 * (capacitor.charge/capacitor.max_charge), 0, 255) - I.color = selected_wavelength.color - I.appearance_flags |= RESET_COLOR - overlay.overlays += I - . = ..() + for(var/i = 1 to length(capacitors)) + var/obj/item/stock_parts/capacitor/capacitor = capacitors[i] + if(capacitor.charge > 0) + I = emissive_overlay(overlay.icon, "[overlay.icon_state]-charging-[i]") + I.alpha = clamp(255 * (capacitor.charge/capacitor.max_charge), 0, 255) + I.color = selected_wavelength.color + I.appearance_flags |= RESET_COLOR + overlay.overlays += I /obj/item/gun/energy/capacitor/consume_next_projectile() diff --git a/code/modules/projectiles/guns/energy/ebow.dm b/code/modules/projectiles/guns/energy/ebow.dm index 08402cffafe..5a1bcde899a 100644 --- a/code/modules/projectiles/guns/energy/ebow.dm +++ b/code/modules/projectiles/guns/energy/ebow.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/guns/energy_crossbow.dmi' icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL - origin_tech = "{'combat':2,'magnets':2,'esoteric':5}" + origin_tech = @'{"combat":2,"magnets":2,"esoteric":5}' material = /decl/material/solid/metal/steel slot_flags = SLOT_LOWER_BODY silenced = 1 diff --git a/code/modules/projectiles/guns/energy/egun.dm b/code/modules/projectiles/guns/energy/egun.dm index f4a58e4eb19..ba6cfb04214 100644 --- a/code/modules/projectiles/guns/energy/egun.dm +++ b/code/modules/projectiles/guns/energy/egun.dm @@ -9,7 +9,7 @@ fire_delay = 10 // To balance for the fact that it is a pistol and can be used one-handed without penalty projectile_type = /obj/item/projectile/beam/stun - origin_tech = "{'combat':3,'magnets':2}" + origin_tech = @'{"combat":3,"magnets":2}' indicator_color = COLOR_CYAN firemodes = list( diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 61583d8d02b..ee23a4ab706 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -8,7 +8,7 @@ force = 10 one_hand_penalty = 2 bulk = GUN_BULK_RIFLE - origin_tech = "{'combat':3,'magnets':2}" + origin_tech = @'{"combat":3,"magnets":2}' material = /decl/material/solid/metal/steel projectile_type = /obj/item/projectile/beam/midlaser matter = list( @@ -74,7 +74,7 @@ icon_state = "lasercannon" icon = 'icons/obj/guns/laser_cannon.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':4,'materials':3,'powerstorage':3}" + origin_tech = @'{"combat":4,"materials":3,"powerstorage":3}' slot_flags = SLOT_LOWER_BODY|SLOT_BACK one_hand_penalty = 6 //large and heavy w_class = ITEM_SIZE_HUGE diff --git a/code/modules/projectiles/guns/energy/laser_sniper.dm b/code/modules/projectiles/guns/energy/laser_sniper.dm index bc037c6c4a0..2b8efadc989 100644 --- a/code/modules/projectiles/guns/energy/laser_sniper.dm +++ b/code/modules/projectiles/guns/energy/laser_sniper.dm @@ -4,7 +4,7 @@ desc = "The HI DMR 9E is an older design. A designated marksman rifle capable of shooting powerful ionized beams, this is a weapon to kill from a distance." icon = 'icons/obj/guns/laser_sniper.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':6,'materials':5,'powerstorage':4}" + origin_tech = @'{"combat":6,"materials":5,"powerstorage":4}' projectile_type = /obj/item/projectile/beam/sniper one_hand_penalty = 5 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand. slot_flags = SLOT_BACK diff --git a/code/modules/projectiles/guns/energy/lasertag.dm b/code/modules/projectiles/guns/energy/lasertag.dm index 2f029665387..e9857630b0b 100644 --- a/code/modules/projectiles/guns/energy/lasertag.dm +++ b/code/modules/projectiles/guns/energy/lasertag.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/guns/laser_carbine.dmi' icon_state = ICON_STATE_WORLD desc = "Standard issue weapon of the Imperial Guard." - origin_tech = "{'combat':1,'magnets':2}" + origin_tech = @'{"combat":1,"magnets":2}' self_recharge = 1 material = /decl/material/solid/metal/steel projectile_type = /obj/item/projectile/beam/lastertag/blue diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index c594990a7f4..b7ccef79df0 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -2,7 +2,7 @@ name = "advanced energy gun" desc = "An energy gun with an experimental miniaturized reactor." icon = 'icons/obj/guns/adv_egun.dmi' - origin_tech = "{'combat':3,'materials':5,'powerstorage':3}" + origin_tech = @'{"combat":3,"materials":5,"powerstorage":3}' slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_LARGE force = 8 //looks heavier than a pistol diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 9aee0847a9c..ab70fb72cdf 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -3,7 +3,7 @@ desc = "The Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats. Not the best of its type." icon = 'icons/obj/guns/ion_rifle.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':2,'magnets':4}" + origin_tech = @'{"combat":2,"magnets":4}' w_class = ITEM_SIZE_HUGE force = 10 obj_flags = OBJ_FLAG_CONDUCTIBLE @@ -34,7 +34,7 @@ desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon = 'icons/obj/guns/decloner.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':5,'materials':4,'powerstorage':3}" + origin_tech = @'{"combat":5,"materials":4,"powerstorage":3}' max_shots = 10 projectile_type = /obj/item/projectile/energy/declone combustion = 0 @@ -49,7 +49,7 @@ charge_cost = 10 max_shots = 10 projectile_type = /obj/item/projectile/energy/floramut - origin_tech = "{'materials':2,'biotech':3,'powerstorage':3}" + origin_tech = @'{"materials":2,"biotech":3,"powerstorage":3}' self_recharge = 1 material = /decl/material/solid/metal/steel matter = list( @@ -108,7 +108,7 @@ icon = 'icons/obj/guns/toxgun.dmi' icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL - origin_tech = "{'combat':5,'exoticmatter':4}" + origin_tech = @'{"combat":5,"exoticmatter":4}' projectile_type = /obj/item/projectile/energy/radiation material = /decl/material/solid/metal/steel matter = list( @@ -126,7 +126,7 @@ slot_flags = SLOT_LOWER_BODY|SLOT_BACK w_class = ITEM_SIZE_NORMAL force = 8 - origin_tech = "{'materials':4,'exoticmatter':4,'engineering':6,'combat':3}" + origin_tech = @'{"materials":4,"exoticmatter":4,"engineering":6,"combat":3}' material = /decl/material/solid/metal/steel projectile_type = /obj/item/projectile/beam/plasmacutter max_shots = 10 @@ -172,7 +172,7 @@ icon = 'icons/obj/guns/incendiary_laser.dmi' icon_state = ICON_STATE_WORLD safety_icon = "safety" - origin_tech = "{'combat':7,'magnets':4,'esoteric':4}" + origin_tech = @'{"combat":7,"magnets":4,"esoteric":4}' material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index ca42527292f..75de92c76f3 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -34,7 +34,7 @@ desc = "The Mars Military Industries MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands." icon = 'icons/obj/guns/plasma_stun.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':2,'materials':2,'powerstorage':3}" + origin_tech = @'{"combat":2,"materials":2,"powerstorage":3}' fire_delay = 20 max_shots = 4 projectile_type = /obj/item/projectile/energy/plasmastun @@ -47,7 +47,7 @@ icon = 'icons/obj/guns/confuseray.dmi' icon_state = ICON_STATE_WORLD safety_icon = "safety" - origin_tech = "{'combat':2,'materials':2,'powerstorage':2}" + origin_tech = @'{"combat":2,"materials":2,"powerstorage":2}' w_class = ITEM_SIZE_SMALL max_shots = 4 projectile_type = /obj/item/projectile/beam/confuseray diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 547aeb0ea06..15cd979e5fd 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -10,7 +10,7 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE ) charge_cost = 10 - origin_tech = "{'combat':3,'materials':4,'powerstorage':3,'magnets':2}" + origin_tech = @'{"combat":3,"materials":4,"powerstorage":3,"magnets":2}' slot_flags = SLOT_LOWER_BODY|SLOT_BACK one_hand_penalty = 2 projectile_type = /obj/item/projectile/temp diff --git a/code/modules/projectiles/guns/energy/xray.dm b/code/modules/projectiles/guns/energy/xray.dm index 6c1bf530b82..cf20a5f1e00 100644 --- a/code/modules/projectiles/guns/energy/xray.dm +++ b/code/modules/projectiles/guns/energy/xray.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/guns/xray.dmi' icon_state = ICON_STATE_WORLD slot_flags = SLOT_LOWER_BODY|SLOT_BACK - origin_tech = "{'combat':5,'materials':3,'magnets':2,'esoteric':2}" + origin_tech = @'{"combat":5,"materials":3,"magnets":2,"esoteric":2}' projectile_type = /obj/item/projectile/beam/xray/midlaser one_hand_penalty = 2 w_class = ITEM_SIZE_LARGE diff --git a/code/modules/projectiles/guns/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/launcher/grenade_launcher.dm index 56e02609c8f..4d9c170277a 100644 --- a/code/modules/projectiles/guns/launcher/grenade_launcher.dm +++ b/code/modules/projectiles/guns/launcher/grenade_launcher.dm @@ -3,7 +3,7 @@ desc = "A bulky pump-action grenade launcher. Holds up to 6 grenades in a revolving magazine." icon = 'icons/obj/guns/launcher/grenade.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':2,'materials':3}" + origin_tech = @'{"combat":2,"materials":3}' w_class = ITEM_SIZE_HUGE force = 10 diff --git a/code/modules/projectiles/guns/launcher/money_cannon.dm b/code/modules/projectiles/guns/launcher/money_cannon.dm index 964cf71c46d..bb585d1c534 100644 --- a/code/modules/projectiles/guns/launcher/money_cannon.dm +++ b/code/modules/projectiles/guns/launcher/money_cannon.dm @@ -3,7 +3,7 @@ desc = "A blocky, plastic novelty launcher that claims to be able to shoot money at considerable velocities." icon = 'icons/obj/guns/launcher/money.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':1,'materials':1}" + origin_tech = @'{"combat":1,"materials":1}' slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_SMALL release_force = 80 diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index 9ea3b16eeb1..ad5eb8a4793 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -3,7 +3,7 @@ desc = "A large gas-powered cannon." icon = 'icons/obj/guns/launcher/pneumatic.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'combat':4,'materials':3}" + origin_tech = @'{"combat":4,"materials":3}' slot_flags = SLOT_LOWER_BODY w_class = ITEM_SIZE_HUGE obj_flags = OBJ_FLAG_CONDUCTIBLE @@ -133,7 +133,7 @@ icon_state = get_world_inventory_state() update_held_icon() -/obj/item/gun/launcher/pneumatic/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/gun/launcher/pneumatic/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && tank) overlay.icon_state += "-tank" . = ..() diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm index 9d5e7429ad5..938eba04ffb 100644 --- a/code/modules/projectiles/guns/launcher/rocket.dm +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -9,7 +9,7 @@ force = 5.0 obj_flags = OBJ_FLAG_CONDUCTIBLE slot_flags = 0 - origin_tech = "{'combat':8,'materials':5}" + origin_tech = @'{"combat":8,"materials":5}' fire_sound = 'sound/effects/bang.ogg' combustion = 1 diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index b94e35cf7d9..3fb228c6ccc 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -5,7 +5,7 @@ icon_state = ICON_STATE_WORLD one_hand_penalty = 5 fire_delay = 20 - origin_tech = "{'combat':5,'materials':4,'esoteric':2,'magnets':4}" + origin_tech = @'{"combat":5,"materials":4,"esoteric":2,"magnets":4}' w_class = ITEM_SIZE_LARGE bulk = GUN_BULK_RIFLE combustion = 1 diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm index 2c00f9eab69..30bb71cea69 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/guns/railgun.dmi' removable_components = TRUE // Can swap out the capacitor for more shots, or cell for longer usage before recharge load_type = /obj/item/rcd_ammo - origin_tech = "{'combat':5,'materials':4,'magnets':4}" + origin_tech = @'{"combat":5,"materials":4,"magnets":4}' projectile_type = /obj/item/projectile/bullet/magnetic/slug one_hand_penalty = 6 power_cost = 300 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 8ea0a2a3da4..0954d63ee06 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -2,7 +2,7 @@ name = "gun" desc = "A gun that fires bullets." icon = 'icons/obj/guns/pistol.dmi' - origin_tech = "{'combat':2,'materials':2}" + origin_tech = @'{"combat":2,"materials":2}' w_class = ITEM_SIZE_NORMAL material = /decl/material/solid/metal/steel screen_shake = 1 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 56fe369ff51..a7614db6028 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -6,7 +6,7 @@ safety_icon = "safety" w_class = ITEM_SIZE_NORMAL caliber = CALIBER_PISTOL_SMALL - origin_tech = "{'combat':5,'materials':2}" + origin_tech = @'{"combat":5,"materials":2}' slot_flags = SLOT_LOWER_BODY|SLOT_BACK ammo_type = /obj/item/ammo_casing/pistol/small load_method = MAGAZINE @@ -44,7 +44,7 @@ w_class = ITEM_SIZE_HUGE force = 10 caliber = CALIBER_RIFLE - origin_tech = "{'combat':7,'materials':3}" + origin_tech = @'{"combat":7,"materials":3}' ammo_type = /obj/item/ammo_casing/rifle slot_flags = SLOT_BACK load_method = MAGAZINE @@ -82,7 +82,7 @@ /obj/item/gun/projectile/automatic/assault_rifle/grenade name = "assault rifle" desc = "The Z8 Bulldog is an older model bullpup carbine. This one has an underslung grenade launcher. REALLY makes you feel like a space marine when you hold it." - origin_tech = "{'combat':8,'materials':3}" + origin_tech = @'{"combat":8,"materials":3}' firemodes = list( list(mode_name="semi auto", burst=1, fire_delay=null, use_launcher=null, one_hand_penalty=8, burst_accuracy=null, dispersion=null), @@ -137,7 +137,7 @@ w_class = ITEM_SIZE_HUGE force = 10 caliber = CALIBER_RIFLE - origin_tech = "{'combat':9,'materials':3}" + origin_tech = @'{"combat":9,"materials":3}' ammo_type = /obj/item/ammo_casing/rifle load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/rifle/drum diff --git a/code/modules/projectiles/guns/projectile/bolt_action.dm b/code/modules/projectiles/guns/projectile/bolt_action.dm index 0647f000429..21f609064ad 100644 --- a/code/modules/projectiles/guns/projectile/bolt_action.dm +++ b/code/modules/projectiles/guns/projectile/bolt_action.dm @@ -6,7 +6,7 @@ w_class = ITEM_SIZE_HUGE force = 5 slot_flags = SLOT_BACK - origin_tech = "{'combat':4,'materials':2}" + origin_tech = @'{"combat":4,"materials":2}' caliber = CALIBER_RIFLE handle_casings = HOLD_CASINGS load_method = SINGLE_CASING @@ -78,7 +78,7 @@ desc = "A portable anti-armour rifle fitted with a scope, the HI PTR-7 Rifle was originally designed to be used against armoured exosuits. It is capable of punching through windows and non-reinforced walls with ease." icon = 'icons/obj/guns/heavysniper.dmi' force = 10 - origin_tech = "{'combat':7,'materials':2,'esoteric':8}" + origin_tech = @'{"combat":7,"materials":2,"esoteric":8}' caliber = CALIBER_ANTI_MATERIEL screen_shake = 2 //extra kickback one_hand_penalty = 6 diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index f5a28572e21..18327f897e9 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -31,7 +31,7 @@ return for(var/chem in starting_chems) var/obj/B = new container_type(src) - B.reagents.add_reagent(chem, 60) + B.add_to_reagents(chem, 60) beakers += B /obj/item/gun/projectile/dartgun/on_update_icon() @@ -41,7 +41,7 @@ else icon_state = get_world_inventory_state() -/obj/item/gun/projectile/dartgun/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/gun/projectile/dartgun/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && (slot in user_mob?.get_held_item_slots()) && ammo_magazine) overlay.icon_state += "-[clamp(length(ammo_magazine.stored_ammo.len), 0, 5)]" . = ..() diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 9917cd8bcca..05f0b25ece0 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -32,7 +32,7 @@ caliber = CALIBER_PISTOL_SMALL silenced = 0 fire_delay = 4 - origin_tech = "{'combat':2,'materials':2,'esoteric':8}" + origin_tech = @'{"combat":2,"materials":2,"esoteric":8}' magazine_type = /obj/item/ammo_magazine/pistol/small allowed_magazines = /obj/item/ammo_magazine/pistol/small diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 4b7ad7b5e72..0358e6eb6b3 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -5,7 +5,7 @@ icon_state = ICON_STATE_WORLD safety_icon = "safety" caliber = CALIBER_PISTOL_MAGNUM - origin_tech = "{'combat':2,'materials':2}" + origin_tech = @'{"combat":2,"materials":2}' handle_casings = CYCLE_CASINGS max_shells = 6 fire_delay = 12 //Revolvers are naturally slower-firing @@ -48,7 +48,7 @@ name = "cap gun" desc = "Looks almost like the real thing! Ages 8 and up." caliber = CALIBER_CAPS - origin_tech = "{'combat':1,'materials':1}" + origin_tech = @'{"combat":1,"materials":1}' ammo_type = /obj/item/ammo_casing/cap var/cap = TRUE diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 5bf38759b8d..f91b9fc9d49 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -9,7 +9,7 @@ obj_flags = OBJ_FLAG_CONDUCTIBLE slot_flags = SLOT_BACK caliber = CALIBER_SHOTGUN - origin_tech = "{'combat':4,'materials':2}" + origin_tech = @'{"combat":4,"materials":2}' load_method = SINGLE_CASING ammo_type = /obj/item/ammo_casing/shotgun/beanbag handle_casings = HOLD_CASINGS @@ -64,7 +64,7 @@ obj_flags = OBJ_FLAG_CONDUCTIBLE slot_flags = SLOT_BACK caliber = CALIBER_SHOTGUN - origin_tech = "{'combat':3,'materials':1}" + origin_tech = @'{"combat":3,"materials":1}' ammo_type = /obj/item/ammo_casing/shotgun/beanbag one_hand_penalty = 2 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 8094266a812..56f60afa091 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -464,7 +464,15 @@ M.Turn(Angle) transform = M trajectory.increment(trajectory_multiplier) + var/turf/T = trajectory.return_turf() + if(!T) + if(!QDELETED(src)) + if(loc) + on_impact(loc) + qdel(src) + return + if(T.z != loc.z) before_move() before_z_change(loc, T) diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 30f3b48d403..a88e4070f8e 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -25,8 +25,8 @@ var/mob/living/silicon/robot/R = new(get_turf(M)) R.set_gender(M.get_gender()) R.job = ASSIGNMENT_ROBOT - R.mmi = new /obj/item/mmi(R) - R.mmi.transfer_identity(M) + R.central_processor = new /obj/item/organ/internal/brain_interface(R) + transfer_key_from_mob_to_mob(M, R) return R if(get_species_by_key(choice)) @@ -53,12 +53,8 @@ for (var/spell/S in M.mind.learned_spells) new_mob.add_spell(new S.type) new_mob.a_intent = "hurt" - if(M.mind) - M.mind.transfer_to(new_mob) - else - new_mob.key = M.key + transfer_key_from_mob_to_mob(M, new_mob) to_chat(new_mob, "Your form morphs into that of \a [choice].") - qdel(M) else to_chat(M, "Your form morphs into that of \a [choice].") diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 037a41b6fc3..b208b0a7335 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -163,7 +163,7 @@ . = ..() var/mob/living/L = target if(L.reagents) - L.reagents.add_reagent(/decl/material/liquid/venom, 5) + L.add_to_reagents(/decl/material/liquid/venom, 5) /obj/item/missile icon = 'icons/obj/items/grenades/missile.dmi' diff --git a/code/modules/projectiles/targeting/targeting_mob.dm b/code/modules/projectiles/targeting/targeting_mob.dm index b03befe664a..1dd13a1aa6d 100644 --- a/code/modules/projectiles/targeting/targeting_mob.dm +++ b/code/modules/projectiles/targeting/targeting_mob.dm @@ -27,11 +27,3 @@ ..() if(lying) stop_aiming(no_message=1) - -/mob/living/Destroy() - if(aiming) - qdel(aiming) - aiming = null - QDEL_NULL_LIST(aimed_at_by) - return ..() - diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm index c9cc33f2a3a..8fd4de31574 100644 --- a/code/modules/projectiles/targeting/targeting_overlay.dm +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -176,9 +176,9 @@ update_icon() lock_time = world.time + 35 - events_repository.register(/decl/observ/moved, owner, src, /obj/aiming_overlay/proc/update_aiming) - events_repository.register(/decl/observ/moved, aiming_at, src, /obj/aiming_overlay/proc/target_moved) - events_repository.register(/decl/observ/destroyed, aiming_at, src, /obj/aiming_overlay/proc/cancel_aiming) + events_repository.register(/decl/observ/moved, owner, src, TYPE_PROC_REF(/obj/aiming_overlay, update_aiming)) + events_repository.register(/decl/observ/moved, aiming_at, src, TYPE_PROC_REF(/obj/aiming_overlay, target_moved)) + events_repository.register(/decl/observ/destroyed, aiming_at, src, TYPE_PROC_REF(/obj/aiming_overlay, cancel_aiming)) /obj/aiming_overlay/on_update_icon() if(locked) diff --git a/code/modules/radiation/radiation.dm b/code/modules/radiation/radiation.dm index df714006ba9..0feee45d773 100644 --- a/code/modules/radiation/radiation.dm +++ b/code/modules/radiation/radiation.dm @@ -23,12 +23,12 @@ /datum/radiation_source/proc/update_rad_power(var/new_power = null) if(new_power == null || new_power == rad_power) return // No change - else if(new_power <= config.radiation_lower_limit) + else if(new_power <= get_config_value(/decl/config/num/radiation_lower_limit)) qdel(src) // Decayed to nothing else rad_power = new_power if(!flat) - range = min(round(sqrt(rad_power / config.radiation_lower_limit)), 31) // R = rad_power / dist**2 - Solve for dist + range = min(round(sqrt(rad_power / get_config_value(/decl/config/num/radiation_lower_limit))), 31) // R = rad_power / dist**2 - Solve for dist /turf var/cached_rad_resistance = 0 @@ -39,13 +39,13 @@ if(!(O.rad_resistance_modifier <= 0) && O.density) var/decl/material/M = O.get_material() if(!M) continue - cached_rad_resistance += (M.weight * O.rad_resistance_modifier) / config.radiation_material_resistance_divisor + cached_rad_resistance += (M.weight * O.rad_resistance_modifier) / get_config_value(/decl/config/num/radiation_material_resistance_divisor) // Looks like storing the contents length is meant to be a basic check if the cache is stale due to items enter/exiting. Better than nothing so I'm leaving it as is. ~Leshana SSradiation.resistance_cache[src] = (length(contents) + 1) /turf/simulated/wall/calc_rad_resistance() SSradiation.resistance_cache[src] = (length(contents) + 1) - cached_rad_resistance = (density ? material.weight / config.radiation_material_resistance_divisor : 0) + cached_rad_resistance = (density ? material.weight / get_config_value(/decl/config/num/radiation_material_resistance_divisor) : 0) /obj var/rad_resistance_modifier = 1 // Allow overriding rad resistance diff --git a/code/modules/random_map/drop/drop_types.dm b/code/modules/random_map/drop/drop_types.dm index f2778b56c02..1e68a9769fe 100644 --- a/code/modules/random_map/drop/drop_types.dm +++ b/code/modules/random_map/drop/drop_types.dm @@ -97,7 +97,7 @@ var/global/list/datum/supply_drop_loot/supply_drop /obj/item/chems/condiment/flour, /obj/item/chems/drinks/milk, /obj/item/chems/drinks/milk, - /obj/item/storage/fancy/egg_box, + /obj/item/storage/box/fancy/egg_box, /obj/item/chems/food/tofu, /obj/item/chems/food/tofu, /obj/item/chems/food/meat, diff --git a/code/modules/reagents/Chemistry-Grinder.dm b/code/modules/reagents/Chemistry-Grinder.dm index af0ebfe26b3..d64776fcd91 100644 --- a/code/modules/reagents/Chemistry-Grinder.dm +++ b/code/modules/reagents/Chemistry-Grinder.dm @@ -192,7 +192,7 @@ update_icon() // Reset the machine. - addtimer(CALLBACK(src, .proc/end_grind, user), 6 SECONDS, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(end_grind), user), 6 SECONDS, TIMER_UNIQUE) var/skill_factor = CLAMP01(1 + 0.3*(user.get_skill_value(skill_to_check) - SKILL_EXPERT)/(SKILL_EXPERT - SKILL_MIN)) // Process. @@ -213,7 +213,7 @@ stack.use(amount_to_take) if(QDELETED(stack)) holdingitems -= stack - beaker.reagents.add_reagent(material.type, (amount_to_take * REAGENT_UNITS_PER_MATERIAL_SHEET * skill_factor)) + beaker.add_to_reagents(material.type, (amount_to_take * REAGENT_UNITS_PER_MATERIAL_SHEET * skill_factor)) continue else if(O.reagents) @@ -238,7 +238,7 @@ user.visible_message(SPAN_DANGER("\The [user]'s hand gets caught in \the [src]!"), SPAN_DANGER("Your hand gets caught in \the [src]!")) user.apply_damage(dam, BRUTE, hand, damage_flags = DAM_SHARP, used_weapon = "grinder") if(BP_IS_PROSTHETIC(hand_organ)) - beaker.reagents.add_reagent(/decl/material/solid/metal/iron, dam) + beaker.add_to_reagents(/decl/material/solid/metal/iron, dam) else user.take_blood(beaker, dam) SET_STATUS_MAX(user, STAT_STUN, 2) diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 6316e81d0e3..253d92cad05 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -1,5 +1,14 @@ var/global/obj/temp_reagents_holder = new +/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE) + return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update) + +/atom/proc/remove_from_reagents(reagent_type, amount, safety = FALSE, defer_update = FALSE) + return reagents?.remove_reagent(reagent_type, amount, safety, defer_update) + +/atom/proc/remove_any_reagents(amount = 1, defer_update = FALSE) + return reagents?.remove_any(amount, defer_update) + /datum/reagents var/primary_reagent var/list/reagent_volumes @@ -24,6 +33,8 @@ var/global/obj/temp_reagents_holder = new if(my_atom) if(my_atom.reagents == src) my_atom.reagents = null + if(total_volume > 0) // we can assume 0 reagents and null reagents are broadly identical for the purposes of atom logic + my_atom.on_reagent_change() my_atom = null /datum/reagents/GetCloneArgs() @@ -91,7 +102,7 @@ var/global/obj/temp_reagents_holder = new var/replace_sound if(!(check_flags & ATOM_FLAG_NO_PHASE_CHANGE)) - if(!isnull(R.chilling_point) && R.type != R.bypass_cooling_products_for_root_type && LAZYLEN(R.chilling_products) && temperature <= R.chilling_point) + if(!isnull(R.chilling_point) && R.type != R.bypass_chilling_products_for_root_type && LAZYLEN(R.chilling_products) && temperature <= R.chilling_point) replace_self_with = R.chilling_products if(R.chilling_message) replace_message = "\The [lowertext(R.name)] [R.chilling_message]" @@ -174,6 +185,9 @@ var/global/obj/temp_reagents_holder = new /* Holder-to-chemical */ /datum/reagents/proc/handle_update(var/safety) + if(QDELETED(src)) + return + SSfluids.holders_to_update -= src update_total() if(!safety) HANDLE_REACTIONS(src) @@ -506,7 +520,7 @@ var/global/obj/temp_reagents_holder = new current.touch_turf(target, REAGENT_VOLUME(src, rtype), src) var/dirtiness = get_dirtiness() if(dirtiness <= DIRTINESS_CLEAN) - target.clean_blood() + target.clean() target.remove_cleanables() if(dirtiness != DIRTINESS_NEUTRAL) if(dirtiness > DIRTINESS_NEUTRAL) @@ -524,7 +538,7 @@ var/global/obj/temp_reagents_holder = new for(var/obj/effect/decal/cleanable/blood/B in target) qdel(B) if(dirtiness <= DIRTINESS_CLEAN) - target.clean_blood() + target.clean() if(istype(target, /turf/simulated)) var/turf/simulated/simulated_turf = target simulated_turf.dirt = 0 @@ -580,9 +594,9 @@ var/global/obj/temp_reagents_holder = new R.touch_turf(target) if(R?.total_volume <= FLUID_QDEL_POINT || QDELETED(target)) return - var/obj/effect/fluid/F = locate() in target - if(!F) F = new(target) - trans_to_holder(F.reagents, amount, multiplier, copy, defer_update = defer_update) + if(!target.reagents) + target.create_reagents(FLUID_MAX_DEPTH) + trans_to_holder(target.reagents, amount, multiplier, copy, defer_update = defer_update) /datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/defer_update = FALSE) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. if(!target || !target.simulated) diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index d18ed79fcc8..eb49c13afad 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -129,9 +129,9 @@ for(var/decl/material/reagent in contaminants) reagents.trans_type_to(beaker, reagent.type, round(rand()*amount, 0.1)) else - reagents.remove_reagent(my_reagents.type, amount) + remove_from_reagents(my_reagents.type, amount) for(var/decl/material/reagent in contaminants) - reagents.remove_reagent(reagent.type, round(rand()*amount, 0.1)) + remove_from_reagents(reagent.type, round(rand()*amount, 0.1)) else if (href_list["removecustom"]) var/decl/material/my_reagents = locate(href_list["removecustom"]) diff --git a/code/modules/reagents/chems/chems_blood.dm b/code/modules/reagents/chems/chems_blood.dm index c56c0a0dc81..1b06f730810 100644 --- a/code/modules/reagents/chems/chems_blood.dm +++ b/code/modules/reagents/chems/chems_blood.dm @@ -51,16 +51,7 @@ if(!istype(T) || REAGENT_VOLUME(holder, type) < 3) return var/weakref/W = LAZYACCESS(data, "donor") - if (!W) - blood_splatter(T, src, 1) - return - W = W.resolve() - if(ishuman(W)) - blood_splatter(T, src, 1) - else if(isalien(W)) - var/obj/effect/decal/cleanable/blood/B = blood_splatter(T, holder.my_atom, 1) - if(!QDELETED(B)) - B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" + blood_splatter(T, W?.resolve() || holder.my_atom, 1) /decl/material/liquid/blood/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder) if(M.HasTrait(/decl/trait/metabolically_inert)) diff --git a/code/modules/reagents/chems/chems_cleaner.dm b/code/modules/reagents/chems/chems_cleaner.dm index e3d3bef442b..5bd2e9454e5 100644 --- a/code/modules/reagents/chems/chems_cleaner.dm +++ b/code/modules/reagents/chems/chems_cleaner.dm @@ -10,6 +10,23 @@ uid = "chem_cleaner" exoplanet_rarity_gas = MAT_RARITY_EXOTIC +/decl/material/liquid/contaminant_cleaner + name = "akaline detergent" + lore_text = "A highly akaline hydrazine based detergent. Able to clean contaminants, but may release ammonia gas if used in open air." + taste_description = "bleach" + vapor_products = list(/decl/material/gas/ammonia = 0.5) + color = "#213799" + touch_met = 5 + toxicity = 5 + scent = "clean linen" + scent_descriptor = SCENT_DESC_FRAGRANCE + value = 0.25 + dirtiness = DIRTINESS_DECONTAMINATE + decontamination_dose = 5 + turf_touch_threshold = 0.1 + uid = "chem_contaminant_cleaner" + exoplanet_rarity_gas = MAT_RARITY_EXOTIC + /decl/material/liquid/cleaner/soap name = "soap" lore_text = "A soft solid compound used to clean things. Usually derived from oil or fat." diff --git a/code/modules/reagents/chems/chems_compounds.dm b/code/modules/reagents/chems/chems_compounds.dm index 997597927ce..791bf3b77de 100644 --- a/code/modules/reagents/chems/chems_compounds.dm +++ b/code/modules/reagents/chems/chems_compounds.dm @@ -33,7 +33,7 @@ /decl/material/liquid/glowsap/on_leaving_metabolism(datum/reagents/metabolism/holder) if(ishuman(holder?.my_atom)) var/mob/living/carbon/human/H = holder.my_atom - addtimer(CALLBACK(H, /mob/living/carbon/human/proc/update_eyes), 5 SECONDS) + addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living/carbon/human, update_eyes)), 5 SECONDS) . = ..() /decl/material/liquid/glowsap/affect_overdose(var/mob/living/M) @@ -320,7 +320,7 @@ /decl/material/solid/tobacco/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) ..() - M.reagents.add_reagent(/decl/material/liquid/nicotine, nicotine) + M.add_to_reagents(/decl/material/liquid/nicotine, nicotine) /decl/material/solid/tobacco/fine name = "fine tobacco" diff --git a/code/modules/reagents/chems/chems_drinks.dm b/code/modules/reagents/chems/chems_drinks.dm index f8279f1155a..d8ee77116f4 100644 --- a/code/modules/reagents/chems/chems_drinks.dm +++ b/code/modules/reagents/chems/chems_drinks.dm @@ -76,7 +76,7 @@ /decl/material/liquid/drink/juice/carrot/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder) ..() - M.reagents.add_reagent(/decl/material/liquid/eyedrops, removed * 0.2) + M.add_to_reagents(/decl/material/liquid/eyedrops, removed * 0.2) /decl/material/liquid/drink/juice/grape name = "grape juice" diff --git a/code/modules/reagents/chems/chems_ethanol.dm b/code/modules/reagents/chems/chems_ethanol.dm index 4996a5fa741..f94d575873c 100644 --- a/code/modules/reagents/chems/chems_ethanol.dm +++ b/code/modules/reagents/chems/chems_ethanol.dm @@ -23,7 +23,7 @@ /decl/material/liquid/ethanol = 0.75, /decl/material/liquid/water = 0.25 ) - bypass_cooling_products_for_root_type = /decl/material/liquid/ethanol + bypass_chilling_products_for_root_type = /decl/material/liquid/ethanol affect_blood_on_ingest = FALSE // prevents automatic toxins/inebriation as though injected var/nutriment_factor = 0 diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm index a703f497f9a..fdf08f79e28 100644 --- a/code/modules/reagents/chems/chems_medicines.dm +++ b/code/modules/reagents/chems/chems_medicines.dm @@ -139,7 +139,7 @@ for(var/R in M.reagents?.reagent_volumes) var/decl/material/chem = GET_DECL(R) if((remove_generic && chem.toxicity) || (R in remove_toxins)) - M.reagents.remove_reagent(R, removing) + M.remove_from_reagents(R, removing) return /decl/material/liquid/immunobooster diff --git a/code/modules/reagents/chems/chems_pigments.dm b/code/modules/reagents/chems/chems_pigments.dm index 1a64670f9ad..dafbb8f7870 100644 --- a/code/modules/reagents/chems/chems_pigments.dm +++ b/code/modules/reagents/chems/chems_pigments.dm @@ -63,6 +63,35 @@ color = "#aaaaaa" uid = "chem_pigment_white" +/decl/material/liquid/paint_stripper + name = "paint stripper" + uid = "liquid_paint_remover" + lore_text = "A highly toxic compound used as an effective paint stripper." + taste_description = "bleach and acid" + color = "#a0a0a0" + metabolism = REM * 0.2 + value = 0.1 + solvent_power = MAT_SOLVENT_MODERATE + toxicity = 10 + +/decl/material/liquid/paint_stripper/proc/remove_paint(var/atom/painting, var/datum/reagents/holder) + if(istype(painting) && istype(holder)) + var/keep_alpha = painting.alpha + painting.reset_color() + painting.set_alpha(keep_alpha) + +/decl/material/liquid/paint_stripper/touch_turf(var/turf/T, var/amount, var/datum/reagents/holder) + if(istype(T) && !isspaceturf(T)) + remove_paint(T, holder) + +/decl/material/liquid/paint_stripper/touch_obj(var/obj/O, var/amount, var/datum/reagents/holder) + if(istype(O)) + remove_paint(O, holder) + +/decl/material/liquid/paint_stripper/touch_mob(var/mob/living/M, var/amount, var/datum/reagents/holder) + if(istype(M)) + remove_paint(M, holder) + /decl/material/liquid/paint name = "paint" lore_text = "This paint will stick to almost any object." @@ -76,8 +105,8 @@ /decl/material/liquid/paint/proc/apply_paint(var/atom/painting, var/datum/reagents/holder) if(istype(painting) && istype(holder)) var/keep_alpha = painting.alpha - painting.color = holder.get_color() - painting.alpha = keep_alpha + painting.set_color(holder.get_color()) + painting.set_alpha(keep_alpha) /decl/material/liquid/paint/touch_turf(var/turf/T, var/amount, var/datum/reagents/holder) if(istype(T) && !isspaceturf(T)) diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/dispenser/cartridge.dm index b91bb821024..a460c354638 100644 --- a/code/modules/reagents/dispenser/cartridge.dm +++ b/code/modules/reagents/dispenser/cartridge.dm @@ -15,6 +15,20 @@ if(populate && reagents.primary_reagent) setLabel(reagents.get_primary_reagent_name()) +/obj/item/chems/chem_disp_cartridge/show_feed_message_end(var/mob/user, var/mob/target) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow a gulp from \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] feeds \the [src] to \the [target]!")) + +/obj/item/chems/chem_disp_cartridge/handle_eaten_by_mob(var/mob/user, var/mob/target) + . = ..() + if(. == EATEN_SUCCESS) + target = target || user + if(target?.has_personal_goal(/datum/goal/achievement/specific_object/drink)) + for(var/R in reagents.reagent_volumes) + target.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) + /obj/item/chems/chem_disp_cartridge/examine(mob/user) . = ..() to_chat(user, "It has a capacity of [volume] units.") @@ -63,7 +77,7 @@ return TRUE if(standard_pour_into(user, target)) return TRUE - if(standard_feed_mob(user, target)) + if(handle_eaten_by_mob(user, target) != EATEN_INVALID) return TRUE if(user.a_intent == I_HURT) if(standard_splash_mob(user,target)) diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm index 7837f1a3c11..fc67bea1606 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/dispenser/cartridge_presets.dm @@ -9,7 +9,7 @@ * CART_TYPE: the type suffix to append to the cartridge type path. * REAGENT_TYPE: The reagent decl path to fill the cartridge with. */ -#define DEFINE_CARTRIDGE_FOR_CHEM(CART_TYPE, REAGENT_TYPE) /obj/item/chems/chem_disp_cartridge/##CART_TYPE/populate_reagents(){reagents.add_reagent(REAGENT_TYPE, reagents.maximum_volume);} +#define DEFINE_CARTRIDGE_FOR_CHEM(CART_TYPE, REAGENT_TYPE) /obj/item/chems/chem_disp_cartridge/##CART_TYPE/populate_reagents(){add_to_reagents(REAGENT_TYPE, reagents.maximum_volume);} // Multiple DEFINE_CARTRIDGE_FOR_CHEM(water, /decl/material/liquid/water) diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/dispenser/cartridge_spawn.dm index 9217acbe9f5..e88e3515f5c 100644 --- a/code/modules/reagents/dispenser/cartridge_spawn.dm +++ b/code/modules/reagents/dispenser/cartridge_spawn.dm @@ -7,7 +7,7 @@ if("small") C = new /obj/item/chems/chem_disp_cartridge/small(usr.loc) if("medium") C = new /obj/item/chems/chem_disp_cartridge/medium(usr.loc) if("large") C = new /obj/item/chems/chem_disp_cartridge(usr.loc) - C.reagents.add_reagent(reagent, C.volume) + C.add_to_reagents(reagent, C.volume) var/decl/material/R = reagent C.setLabel(initial(R.name)) log_and_message_admins("spawned a [size] reagent container containing [reagent]") diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm index ef9070fd880..1a5287a0035 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -130,8 +130,8 @@ events_repository.unregister(/decl/observ/destroyed, container, src) container = new_container if(container) - events_repository.register(/decl/observ/moved, container, src, .proc/check_container_status) - events_repository.register(/decl/observ/destroyed, container, src, .proc/check_container_status) + events_repository.register(/decl/observ/moved, container, src, PROC_REF(check_container_status)) + events_repository.register(/decl/observ/destroyed, container, src, PROC_REF(check_container_status)) update_icon() SSnano.update_uis(src) // update all UIs attached to src diff --git a/code/modules/reagents/reactions/_reaction.dm b/code/modules/reagents/reactions/_reaction.dm index caed59766bf..6e245b6f6ea 100644 --- a/code/modules/reagents/reactions/_reaction.dm +++ b/code/modules/reagents/reactions/_reaction.dm @@ -15,6 +15,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. var/lore_text var/mechanics_text + var/reaction_category /// Flags used when reaction processing. var/chemical_reaction_flags = 0 diff --git a/code/modules/reagents/reactions/reaction_alcohol.dm b/code/modules/reagents/reactions/reaction_alcohol.dm index 3993ba177bc..6fbf57294cc 100644 --- a/code/modules/reagents/reactions/reaction_alcohol.dm +++ b/code/modules/reagents/reactions/reaction_alcohol.dm @@ -1,5 +1,6 @@ /decl/chemical_reaction/recipe abstract_type = /decl/chemical_reaction/recipe + reaction_category = REACTION_TYPE_RECIPE /decl/chemical_reaction/recipe/moonshine name = "Moonshine" diff --git a/code/modules/reagents/reactions/reaction_alloys.dm b/code/modules/reagents/reactions/reaction_alloys.dm index 056c84f260b..61bd616d6a8 100644 --- a/code/modules/reagents/reactions/reaction_alloys.dm +++ b/code/modules/reagents/reactions/reaction_alloys.dm @@ -3,6 +3,7 @@ maximum_temperature = INFINITY reaction_sound = null mix_message = null + reaction_category = REACTION_TYPE_ALLOYING abstract_type = /decl/chemical_reaction/alloy /decl/chemical_reaction/alloy/borosilicate diff --git a/code/modules/reagents/reactions/reaction_compounds.dm b/code/modules/reagents/reactions/reaction_compounds.dm new file mode 100644 index 00000000000..3a5bd56e6de --- /dev/null +++ b/code/modules/reagents/reactions/reaction_compounds.dm @@ -0,0 +1,124 @@ +/decl/chemical_reaction/compound + abstract_type = /decl/chemical_reaction/compound + reaction_category = REACTION_TYPE_COMPOUND + +/decl/chemical_reaction/compound/surfactant + name = "Azosurfactant" + result = /decl/material/liquid/surfactant + required_reagents = list(/decl/material/liquid/fuel/hydrazine = 2, /decl/material/solid/carbon = 2, /decl/material/liquid/acid = 1) + result_amount = 5 + mix_message = "The solution begins to foam gently." + +/decl/chemical_reaction/compound/space_cleaner + name = "Space cleaner" + result = /decl/material/liquid/cleaner + required_reagents = list(/decl/material/gas/ammonia = 1, /decl/material/liquid/water = 1) + inhibitors = list(/decl/material/liquid/stabilizer) + mix_message = "The solution becomes slick and soapy." + result_amount = 2 + +/decl/chemical_reaction/compound/plantbgone + name = "Plant-B-Gone" + result = /decl/material/liquid/weedkiller + required_reagents = list( + /decl/material/liquid/bromide = 1, + /decl/material/liquid/water = 4 + ) + result_amount = 5 + +/decl/chemical_reaction/compound/foaming_agent + name = "Foaming Agent" + result = /decl/material/liquid/foaming_agent + required_reagents = list(/decl/material/solid/lithium = 1, /decl/material/liquid/fuel/hydrazine = 1) + result_amount = 1 + mix_message = "The solution begins to foam vigorously." + +/decl/chemical_reaction/compound/sodiumchloride + name = "Sodium Chloride" + result = /decl/material/solid/sodiumchloride + required_reagents = list(/decl/material/solid/sodium = 1, /decl/material/liquid/acid/hydrochloric = 1) + result_amount = 2 + +/decl/chemical_reaction/compound/hair_remover + name = "Hair Remover" + result = /decl/material/liquid/hair_remover + required_reagents = list(/decl/material/solid/metal/radium = 1, /decl/material/solid/potassium = 1, /decl/material/liquid/acid/hydrochloric = 1) + result_amount = 3 + mix_message = "The solution thins out and emits an acrid smell." + +/decl/chemical_reaction/compound/methyl_bromide + name = "Methyl Bromide" + required_reagents = list( + /decl/material/liquid/bromide = 1, + /decl/material/liquid/ethanol = 1, + /decl/material/liquid/fuel/hydrazine = 1 + ) + result_amount = 3 + result = /decl/material/gas/methyl_bromide + mix_message = "The solution begins to bubble, emitting a dark vapor." + +/decl/chemical_reaction/compound/luminol + name = "Luminol" + result = /decl/material/liquid/luminol + required_reagents = list(/decl/material/liquid/fuel/hydrazine = 2, /decl/material/solid/carbon = 2, /decl/material/gas/ammonia = 2) + result_amount = 6 + mix_message = "The solution begins to gleam with a fey inner light." + +/decl/chemical_reaction/compound/anfo + name = "Fertilizer ANFO" + result = /decl/material/liquid/anfo + required_reagents = list( + /decl/material/liquid/fertilizer = 20, + /decl/material/liquid/fuel = 10 + ) + result_amount = 15 + mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." + +/decl/chemical_reaction/compound/anfo4 + name = "Chemlab ANFO" + result = /decl/material/liquid/anfo + required_reagents = list( + /decl/material/gas/ammonia = 10, + /decl/material/liquid/fuel = 5 + ) + result_amount = 15 + mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." + +/decl/chemical_reaction/compound/anfo_plus + name = "ANFO+" + result = /decl/material/liquid/anfo/plus + required_reagents = list( + /decl/material/liquid/anfo = 15, + /decl/material/solid/metal/aluminium = 5 + ) + result_amount = 20 + mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." + +/decl/chemical_reaction/compound/crystal_agent + name = "Crystallizing Agent" + result = /decl/material/liquid/crystal_agent + required_reagents = list(/decl/material/solid/silicon = 1, /decl/material/solid/metal/tungsten = 1, /decl/material/liquid/acid/polyacid = 1) + minimum_temperature = 150 CELSIUS + maximum_temperature = 200 CELSIUS + result_amount = 3 + +/decl/chemical_reaction/compound/paint + name = "Paint" + result = /decl/material/liquid/paint + required_reagents = list(/decl/material/liquid/plasticide = 1, /decl/material/liquid/water = 3) + result_amount = 5 + mix_message = "The solution thickens and takes on a glossy sheen." + +/decl/chemical_reaction/compound/paint_stripper + name = "Paint Stripper" + //TODO: some way to mix chlorine and methane to make proper paint stripper. + required_reagents = list(/decl/material/liquid/acetone = 2, /decl/material/liquid/acid = 2) + result = /decl/material/liquid/paint_stripper + result_amount = 4 + mix_message = "The mixture thins and clears." + +/decl/chemical_reaction/compound/contaminant_cleaner + name = "Akaline Detergent" + result = /decl/material/liquid/contaminant_cleaner + required_reagents = list(/decl/material/solid/sodium = 1, /decl/material/liquid/surfactant = 1) + result_amount = 2 diff --git a/code/modules/reagents/reactions/reaction_drugs.dm b/code/modules/reagents/reactions/reaction_drugs.dm index e13692636cd..2fbee8b3da2 100644 --- a/code/modules/reagents/reactions/reaction_drugs.dm +++ b/code/modules/reagents/reactions/reaction_drugs.dm @@ -1,10 +1,14 @@ -/decl/chemical_reaction/antitoxins +/decl/chemical_reaction/drug + abstract_type = /decl/chemical_reaction/drug + reaction_category = REACTION_TYPE_PHARMACEUTICAL + +/decl/chemical_reaction/drug/antitoxins name = "Antitoxins" result = /decl/material/liquid/antitoxins required_reagents = list(/decl/material/solid/silicon = 1, /decl/material/solid/potassium = 1, /decl/material/gas/ammonia = 1) result_amount = 3 -/decl/chemical_reaction/painkillers +/decl/chemical_reaction/drug/painkillers name = "Mild Painkillers" result = /decl/material/liquid/painkillers required_reagents = list( @@ -14,7 +18,7 @@ ) result_amount = 3 -/decl/chemical_reaction/strong_painkillers +/decl/chemical_reaction/drug/strong_painkillers name = "Strong Painkillers" result = /decl/material/liquid/painkillers/strong required_reagents = list( @@ -24,19 +28,19 @@ ) result_amount = 3 -/decl/chemical_reaction/antiseptic +/decl/chemical_reaction/drug/antiseptic name = "Antiseptic" result = /decl/material/liquid/antiseptic required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/antitoxins = 1, /decl/material/liquid/acid/hydrochloric = 1) result_amount = 3 -/decl/chemical_reaction/mutagenics +/decl/chemical_reaction/drug/mutagenics name = "Unstable mutagen" result = /decl/material/liquid/mutagenics required_reagents = list(/decl/material/solid/metal/radium = 1, /decl/material/solid/phosphorus = 1, /decl/material/liquid/acid/hydrochloric = 1) result_amount = 3 -/decl/chemical_reaction/psychoactives +/decl/chemical_reaction/drug/psychoactives name = "Psychoactives" result = /decl/material/liquid/psychoactives required_reagents = list(/decl/material/liquid/mercury = 1, /decl/material/liquid/nutriment/sugar = 1, /decl/material/solid/lithium = 1) @@ -44,39 +48,39 @@ minimum_temperature = 50 CELSIUS maximum_temperature = (50 CELSIUS) + 100 -/decl/chemical_reaction/lube +/decl/chemical_reaction/drug/lube name = "Lubricant" result = /decl/material/liquid/lube required_reagents = list(/decl/material/liquid/water = 1, /decl/material/solid/silicon = 1, /decl/material/liquid/acetone = 1) result_amount = 3 mix_message = "The solution becomes thick and slimy." -/decl/chemical_reaction/pacid +/decl/chemical_reaction/drug/pacid name = "Polytrinic acid" result = /decl/material/liquid/acid/polyacid required_reagents = list(/decl/material/liquid/acid = 1, /decl/material/liquid/acid/hydrochloric = 1, /decl/material/solid/potassium = 1) result_amount = 3 -/decl/chemical_reaction/antirads +/decl/chemical_reaction/drug/antirads name = "Anti-Radiation Medication" result = /decl/material/liquid/antirads required_reagents = list(/decl/material/solid/metal/radium = 1, /decl/material/liquid/antitoxins = 1) result_amount = 2 -/decl/chemical_reaction/narcotics +/decl/chemical_reaction/drug/narcotics name = "Narcotics" result = /decl/material/liquid/narcotics required_reagents = list(/decl/material/liquid/mercury = 1, /decl/material/liquid/acetone = 1, /decl/material/liquid/nutriment/sugar = 1) result_amount = 2 -/decl/chemical_reaction/burn_meds +/decl/chemical_reaction/drug/burn_meds name = "Anti-Burn Medication" result = /decl/material/liquid/burn_meds required_reagents = list(/decl/material/solid/silicon = 1, /decl/material/solid/carbon = 1) result_amount = 2 log_is_important = 1 -/decl/chemical_reaction/presyncopics +/decl/chemical_reaction/drug/presyncopics name = "Presyncopics" result = /decl/material/liquid/presyncopics required_reagents = list(/decl/material/solid/potassium = 1, /decl/material/liquid/acetone = 1, /decl/material/liquid/nutriment/sugar = 1) @@ -84,44 +88,44 @@ maximum_temperature = 60 CELSIUS result_amount = 3 -/decl/chemical_reaction/regenerator +/decl/chemical_reaction/drug/regenerator name = "Regenerative Serum" result = /decl/material/liquid/regenerator required_reagents = list(/decl/material/liquid/stabilizer = 1, /decl/material/liquid/antitoxins = 1) result_amount = 2 -/decl/chemical_reaction/neuroannealer +/decl/chemical_reaction/drug/neuroannealer name = "Neuroannealer" result = /decl/material/liquid/neuroannealer required_reagents = list(/decl/material/liquid/acid/hydrochloric = 1, /decl/material/gas/ammonia = 1, /decl/material/liquid/antitoxins = 1) result_amount = 2 -/decl/chemical_reaction/oxy_meds +/decl/chemical_reaction/drug/oxy_meds name = "Oxygen Deprivation Medication" result = /decl/material/liquid/oxy_meds required_reagents = list(/decl/material/liquid/acetone = 1, /decl/material/liquid/water = 1, /decl/material/solid/sulfur = 1) result_amount = 1 -/decl/chemical_reaction/brute_meds +/decl/chemical_reaction/drug/brute_meds name = "Anti-Trauma Medication" result = /decl/material/liquid/brute_meds required_reagents = list(/decl/material/liquid/stabilizer = 1, /decl/material/solid/carbon = 1) inhibitors = list(/decl/material/liquid/nutriment/sugar = 1) // Messes up with adrenaline result_amount = 2 -/decl/chemical_reaction/amphetamines +/decl/chemical_reaction/drug/amphetamines name = "Amphetamines" result = /decl/material/liquid/amphetamines required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/solid/phosphorus = 1, /decl/material/solid/sulfur = 1) result_amount = 3 -/decl/chemical_reaction/retrovirals +/decl/chemical_reaction/drug/retrovirals name = "Retrovirals" result = /decl/material/liquid/retrovirals required_reagents = list(/decl/material/liquid/antirads = 1, /decl/material/solid/carbon = 1) result_amount = 2 -/decl/chemical_reaction/nanitefluid +/decl/chemical_reaction/compound/nanitefluid name = "Nanite Fluid" result = /decl/material/liquid/nanitefluid required_reagents = list(/decl/material/liquid/plasticide = 1, /decl/material/solid/metal/aluminium = 1, /decl/material/liquid/lube = 1) @@ -131,19 +135,19 @@ maximum_temperature = -25 CELSIUS mix_message = "The solution becomes a metallic slime." -/decl/chemical_reaction/antibiotics +/decl/chemical_reaction/drug/antibiotics name = "Antibiotics" result = /decl/material/liquid/antibiotics required_reagents = list(/decl/material/liquid/presyncopics = 1, /decl/material/liquid/stabilizer = 1) result_amount = 2 -/decl/chemical_reaction/eyedrops +/decl/chemical_reaction/drug/eyedrops name = "Eye Drops" result = /decl/material/liquid/eyedrops required_reagents = list(/decl/material/solid/carbon = 1, /decl/material/liquid/fuel/hydrazine = 1, /decl/material/liquid/antitoxins = 1) result_amount = 2 -/decl/chemical_reaction/sedatives +/decl/chemical_reaction/drug/sedatives name = "Sedatives" result = /decl/material/liquid/sedatives required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/nutriment/sugar = 4 @@ -153,13 +157,13 @@ ) // Messes with the smoke result_amount = 5 -/decl/chemical_reaction/paralytics +/decl/chemical_reaction/drug/paralytics name = "Paralytics" result = /decl/material/liquid/paralytics required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/mercury = 2, /decl/material/liquid/fuel/hydrazine = 2) result_amount = 1 -/decl/chemical_reaction/zombiepowder +/decl/chemical_reaction/drug/zombiepowder name = "Zombie Powder" result = /decl/material/liquid/zombiepowder required_reagents = list(/decl/material/liquid/carpotoxin = 5, /decl/material/liquid/sedatives = 5, /decl/material/solid/metal/copper = 5) @@ -168,7 +172,7 @@ maximum_temperature = 99 CELSIUS mix_message = "The solution boils off to form a fine powder." -/decl/chemical_reaction/hallucinogenics +/decl/chemical_reaction/drug/hallucinogenics name = "Hallucinogenics" result = /decl/material/liquid/hallucinogenics required_reagents = list(/decl/material/solid/silicon = 1, /decl/material/liquid/fuel/hydrazine = 1, /decl/material/liquid/antitoxins = 1) @@ -177,86 +181,31 @@ minimum_temperature = 75 CELSIUS maximum_temperature = (75 CELSIUS) + 25 -/decl/chemical_reaction/surfactant - name = "Azosurfactant" - result = /decl/material/liquid/surfactant - required_reagents = list(/decl/material/liquid/fuel/hydrazine = 2, /decl/material/solid/carbon = 2, /decl/material/liquid/acid = 1) - result_amount = 5 - mix_message = "The solution begins to foam gently." - -/decl/chemical_reaction/space_cleaner - name = "Space cleaner" - result = /decl/material/liquid/cleaner - required_reagents = list(/decl/material/gas/ammonia = 1, /decl/material/liquid/water = 1) - inhibitors = list(/decl/material/liquid/stabilizer) - mix_message = "The solution becomes slick and soapy." - result_amount = 2 - -/decl/chemical_reaction/plantbgone - name = "Plant-B-Gone" - result = /decl/material/liquid/weedkiller - required_reagents = list( - /decl/material/liquid/bromide = 1, - /decl/material/liquid/water = 4 - ) - result_amount = 5 - -/decl/chemical_reaction/foaming_agent - name = "Foaming Agent" - result = /decl/material/liquid/foaming_agent - required_reagents = list(/decl/material/solid/lithium = 1, /decl/material/liquid/fuel/hydrazine = 1) - result_amount = 1 - mix_message = "The solution begins to foam vigorously." - -/decl/chemical_reaction/sodiumchloride - name = "Sodium Chloride" - result = /decl/material/solid/sodiumchloride - required_reagents = list(/decl/material/solid/sodium = 1, /decl/material/liquid/acid/hydrochloric = 1) - result_amount = 2 - -/decl/chemical_reaction/stimulants +/decl/chemical_reaction/drug/stimulants name = "Stimulants" result = /decl/material/liquid/stimulants required_reagents = list(/decl/material/liquid/hallucinogenics = 1, /decl/material/solid/lithium = 1) result_amount = 3 -/decl/chemical_reaction/antidepressants +/decl/chemical_reaction/drug/antidepressants name = "Antidepressants" result = /decl/material/liquid/antidepressants required_reagents = list(/decl/material/liquid/hallucinogenics = 1, /decl/material/solid/carbon = 1) result_amount = 3 -/decl/chemical_reaction/hair_remover - name = "Hair Remover" - result = /decl/material/liquid/hair_remover - required_reagents = list(/decl/material/solid/metal/radium = 1, /decl/material/solid/potassium = 1, /decl/material/liquid/acid/hydrochloric = 1) - result_amount = 3 - mix_message = "The solution thins out and emits an acrid smell." - -/decl/chemical_reaction/methyl_bromide - name = "Methyl Bromide" - required_reagents = list( - /decl/material/liquid/bromide = 1, - /decl/material/liquid/ethanol = 1, - /decl/material/liquid/fuel/hydrazine = 1 - ) - result_amount = 3 - result = /decl/material/gas/methyl_bromide - mix_message = "The solution begins to bubble, emitting a dark vapor." - -/decl/chemical_reaction/adrenaline +/decl/chemical_reaction/drug/adrenaline name = "Adrenaline" result = /decl/material/liquid/adrenaline required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/amphetamines = 1, /decl/material/liquid/oxy_meds = 1) result_amount = 3 -/decl/chemical_reaction/stabilizer +/decl/chemical_reaction/drug/stabilizer name = "Stabilizer" result = /decl/material/liquid/stabilizer required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/solid/carbon = 1, /decl/material/liquid/acetone = 1) result_amount = 3 -/decl/chemical_reaction/gleam +/decl/chemical_reaction/drug/gleam name = "Gleam" result = /decl/material/liquid/glowsap/gleam result_amount = 2 @@ -271,14 +220,14 @@ /decl/material/liquid/glowsap = 2 ) -/decl/chemical_reaction/immunobooster +/decl/chemical_reaction/drug/immunobooster name = "Immunobooster" result = /decl/material/liquid/immunobooster required_reagents = list(/decl/material/liquid/presyncopics = 1, /decl/material/liquid/antitoxins = 1) minimum_temperature = 40 CELSIUS result_amount = 2 -/decl/chemical_reaction/clotting_agent +/decl/chemical_reaction/drug/clotting_agent name = "Clotting Agent" result = /decl/material/liquid/clotting_agent required_reagents = list( @@ -287,3 +236,10 @@ /decl/material/liquid/carpotoxin = 1 ) result_amount = 2 + +/decl/chemical_reaction/drug/nanoblood + name = "Nanoblood" + result = /decl/material/liquid/nanoblood + required_reagents = list(/decl/material/liquid/nanitefluid = 1, /decl/material/solid/metal/iron = 1, /decl/material/liquid/blood = 1) + result_amount = 3 + mix_message = "The solution thickens slowly into a glossy liquid." diff --git a/code/modules/reagents/reactions/reaction_other.dm b/code/modules/reagents/reactions/reaction_other.dm index f7dd8eb027a..ff57137820f 100644 --- a/code/modules/reagents/reactions/reaction_other.dm +++ b/code/modules/reagents/reactions/reaction_other.dm @@ -13,65 +13,5 @@ /decl/chemical_reaction/soap_key/on_reaction(var/datum/reagents/holder) var/obj/item/soap/S = holder.get_reaction_loc(chemical_reaction_flags) if(istype(S) && S.key_data) - var/obj/item/key/soap/key = new(get_turf(S), null, S.key_data) - key.uses = strength + new /obj/item/key/temporary(get_turf(S), /decl/material/liquid/cleaner, S.key_data, strength) ..() - -/decl/chemical_reaction/luminol - name = "Luminol" - result = /decl/material/liquid/luminol - required_reagents = list(/decl/material/liquid/fuel/hydrazine = 2, /decl/material/solid/carbon = 2, /decl/material/gas/ammonia = 2) - result_amount = 6 - mix_message = "The solution begins to gleam with a fey inner light." - -/decl/chemical_reaction/nanoblood - name = "Nanoblood" - result = /decl/material/liquid/nanoblood - required_reagents = list(/decl/material/liquid/nanitefluid = 1, /decl/material/solid/metal/iron = 1, /decl/material/liquid/blood = 1) - result_amount = 3 - mix_message = "The solution thickens slowly into a glossy liquid." - -/decl/chemical_reaction/anfo - name = "Fertilizer ANFO" - result = /decl/material/liquid/anfo - required_reagents = list( - /decl/material/liquid/fertilizer = 20, - /decl/material/liquid/fuel = 10 - ) - result_amount = 15 - mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." - -/decl/chemical_reaction/anfo4 - name = "Chemlab ANFO" - result = /decl/material/liquid/anfo - required_reagents = list( - /decl/material/gas/ammonia = 10, - /decl/material/liquid/fuel = 5 - ) - result_amount = 15 - mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." - -/decl/chemical_reaction/anfo_plus - name = "ANFO+" - result = /decl/material/liquid/anfo/plus - required_reagents = list( - /decl/material/liquid/anfo = 15, - /decl/material/solid/metal/aluminium = 5 - ) - result_amount = 20 - mix_message = "The solution gives off the eye-watering reek of spilled fertilizer and petroleum." - -/decl/chemical_reaction/crystal_agent - name = "Crystallizing Agent" - result = /decl/material/liquid/crystal_agent - required_reagents = list(/decl/material/solid/silicon = 1, /decl/material/solid/metal/tungsten = 1, /decl/material/liquid/acid/polyacid = 1) - minimum_temperature = 150 CELSIUS - maximum_temperature = 200 CELSIUS - result_amount = 3 - -/decl/chemical_reaction/paint - name = "Paint" - result = /decl/material/liquid/paint - required_reagents = list(/decl/material/liquid/plasticide = 1, /decl/material/liquid/water = 3) - result_amount = 5 - mix_message = "The solution thickens and takes on a glossy sheen." diff --git a/code/modules/reagents/reactions/reaction_synthesis.dm b/code/modules/reagents/reactions/reaction_synthesis.dm index 27f3938ac91..51eb037fe30 100644 --- a/code/modules/reagents/reactions/reaction_synthesis.dm +++ b/code/modules/reagents/reactions/reaction_synthesis.dm @@ -4,6 +4,7 @@ result_amount = 1 mix_message = "The solution hardens and begins to crystallize." abstract_type = /decl/chemical_reaction/synthesis + reaction_category = REACTION_TYPE_SYNTHESIS /decl/chemical_reaction/synthesis/fiberglass name = "Fiberglass" diff --git a/code/modules/reagents/reagent_container_edibility.dm b/code/modules/reagents/reagent_container_edibility.dm new file mode 100644 index 00000000000..07c9eca5dc1 --- /dev/null +++ b/code/modules/reagents/reagent_container_edibility.dm @@ -0,0 +1,8 @@ +/obj/item/chems/get_edible_material_amount(var/mob/eater) + return reagents?.total_volume + +/obj/item/chems/get_food_default_transfer_amount(mob/eater) + return eater?.get_eaten_transfer_amount(amount_per_transfer_from_this) + +/obj/item/chems/get_food_consumption_method(mob/eater) + return EATING_METHOD_DRINK diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 4e761294000..9ecab313621 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -158,69 +158,6 @@ reagents.splash(target, reagents.total_volume) return 1 -/obj/item/chems/proc/self_feed_message(var/mob/user) - to_chat(user, SPAN_NOTICE("You eat \the [src]")) - -/obj/item/chems/proc/other_feed_message_start(var/mob/user, var/mob/target) - user.visible_message(SPAN_NOTICE("[user] is trying to feed [target] \the [src]!")) - -/obj/item/chems/proc/other_feed_message_finish(var/mob/user, var/mob/target) - user.visible_message(SPAN_NOTICE("[user] has fed [target] \the [src]!")) - -/obj/item/chems/proc/feed_sound(var/mob/user) - return - -/obj/item/chems/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack - if(!istype(target)) - return 0 - - if(!reagents || !reagents.total_volume) - to_chat(user, SPAN_NOTICE("\The [src] is empty.")) - return 1 - - // only carbons can eat - if(iscarbon(target)) - if(target == user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.check_has_mouth()) - to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!") - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - to_chat(user, SPAN_NOTICE("\The [blocked] is in the way!")) - return - - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //puts a limit on how fast people can eat/drink things - self_feed_message(user) - reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2) : amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - add_trace_DNA(user) - return 1 - - - else - if(!user.can_force_feed(target, src)) - return - - other_feed_message_start(user, target) - - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - if(!do_mob(user, target)) - return - - other_feed_message_finish(user, target) - - var/contained = REAGENT_LIST(src) - admin_attack_log(user, target, "Fed the victim with [name] (Reagents: [contained])", "Was fed [src] (Reagents: [contained])", "used [src] (Reagents: [contained]) to feed") - - reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - add_trace_DNA(target) - return 1 - - return 0 - /obj/item/chems/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level if(!target.reagents) return 0 diff --git a/code/modules/reagents/reagent_containers/beaker.dm b/code/modules/reagents/reagent_containers/beaker.dm index 8b6cd473921..bf421139622 100644 --- a/code/modules/reagents/reagent_containers/beaker.dm +++ b/code/modules/reagents/reagent_containers/beaker.dm @@ -4,7 +4,7 @@ desc = "A beaker." icon = 'icons/obj/items/chem/beakers/beaker.dmi' icon_state = ICON_STATE_WORLD - center_of_mass = @"{'x':15,'y':10}" + center_of_mass = @'{"x":15,"y":10}' material = /decl/material/solid/glass material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME material_force_multiplier = 0.25 @@ -69,7 +69,7 @@ name = "large beaker" desc = "A large beaker." icon = 'icons/obj/items/chem/beakers/large.dmi' - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' volume = 120 amount_per_transfer_from_this = 10 possible_transfer_amounts = @"[5,10,15,25,30,60,120]" @@ -80,7 +80,7 @@ name = "mixing bowl" desc = "A large mixing bowl." icon = 'icons/obj/items/chem/mixingbowl.dmi' - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' volume = 180 amount_per_transfer_from_this = 10 possible_transfer_amounts = @"[5,10,15,25,30,60,180]" @@ -92,21 +92,21 @@ name = "cryostasis beaker" desc = "A cryostasis beaker that allows for chemical storage without reactions." icon = 'icons/obj/items/chem/beakers/stasis.dmi' - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' volume = 60 amount_per_transfer_from_this = 10 atom_flags = ATOM_FLAG_OPEN_CONTAINER | ATOM_FLAG_NO_CHEM_CHANGE presentation_flags = PRESENTATION_FLAG_NAME material = /decl/material/solid/metal/steel material_alteration = MAT_FLAG_ALTERATION_NONE - origin_tech = "{'materials':2}" + origin_tech = @'{"materials":2}' lid_color = COLOR_PALE_BLUE_GRAY /obj/item/chems/glass/beaker/advanced name = "advanced beaker" desc = "An advanced beaker, powered by experimental technology." icon = 'icons/obj/items/chem/beakers/advanced.dmi' - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = @"[5,10,15,25,30,60,120,150,200,250,300]" @@ -117,14 +117,14 @@ /decl/material/solid/phoron = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'exoticmatter':2,'materials':6}" + origin_tech = @'{"exoticmatter":2,"materials":6}' lid_color = COLOR_CYAN_BLUE /obj/item/chems/glass/beaker/vial name = "vial" desc = "A small glass vial." icon = 'icons/obj/items/chem/vial.dmi' - center_of_mass = @"{'x':15,'y':8}" + center_of_mass = @'{"x":15,"y":8}' volume = 30 w_class = ITEM_SIZE_TINY //half the volume of a bottle, half the size amount_per_transfer_from_this = 10 @@ -140,7 +140,7 @@ name = "insulated beaker" desc = "A glass beaker surrounded with black insulation." icon = 'icons/obj/items/chem/beakers/insulated.dmi' - center_of_mass = @"{'x':15,'y':8}" + center_of_mass = @'{"x":15,"y":8}' matter = list(/decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT) possible_transfer_amounts = @"[5,10,15,30]" atom_flags = ATOM_FLAG_OPEN_CONTAINER @@ -157,12 +157,12 @@ /obj/item/chems/glass/beaker/insulated/large name = "large insulated beaker" icon = 'icons/obj/items/chem/beakers/insulated_large.dmi' - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' matter = list(/decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT) volume = 120 /obj/item/chems/glass/beaker/sulphuric/populate_reagents() - reagents.add_reagent(/decl/material/liquid/acid, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/acid, reagents.maximum_volume) /obj/item/chems/glass/beaker/measuringcup name = "measuring cup" @@ -170,4 +170,4 @@ icon = 'icons/obj/items/chem/beakers/measuringcup.dmi' /obj/item/chems/glass/beaker/measuringcup/attack_self() - return \ No newline at end of file + return diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 84026bdcafa..559d735adca 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -26,15 +26,15 @@ /obj/item/chems/ivbag/on_reagent_change() ..() - if(reagents.total_volume > volume/2) + if(reagents?.total_volume > volume/2) w_class = ITEM_SIZE_SMALL else w_class = ITEM_SIZE_TINY /obj/item/chems/ivbag/on_update_icon() . = ..() - var/percent = round(reagents.total_volume / volume * 100) - if(reagents.total_volume) + var/percent = round(reagents?.total_volume / volume * 100) + if(percent) add_overlay(overlay_image(icon, "[round(percent,25)]", reagents.get_color())) add_overlay(attached? "dongle" : "top") @@ -87,7 +87,7 @@ /obj/item/chems/ivbag/blood/populate_reagents() if(blood_fill_type) - reagents.add_reagent(blood_fill_type, reagents.maximum_volume, get_initial_blood_data()) + add_to_reagents(blood_fill_type, reagents.maximum_volume, get_initial_blood_data()) /obj/item/chems/ivbag/blood/nanoblood label_text = "synthetic" diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 510ebe26a50..b74335a2e3d 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -79,7 +79,7 @@ if(M.reagents) var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]]) - M.reagents.add_reagent(reagent_ids[mode], t) + M.add_to_reagents(reagent_ids[mode], t) reagent_volumes[reagent_ids[mode]] -= t admin_inject_log(user, M, src, reagent_ids[mode], t) to_chat(user, "[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.") @@ -180,7 +180,7 @@ return var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]]) - target.reagents.add_reagent(reagent_ids[mode], t) + target.add_to_reagents(reagent_ids[mode], t) reagent_volumes[reagent_ids[mode]] -= t to_chat(user, "You transfer [t] units of the solution to [target].") return diff --git a/code/modules/reagents/reagent_containers/condiment.dm b/code/modules/reagents/reagent_containers/condiment.dm index 9997b999d18..df9794efd42 100644 --- a/code/modules/reagents/reagent_containers/condiment.dm +++ b/code/modules/reagents/reagent_containers/condiment.dm @@ -12,7 +12,7 @@ icon_state = "emptycondiment" atom_flags = ATOM_FLAG_OPEN_CONTAINER possible_transfer_amounts = @"[1,5,10]" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' randpixel = 6 volume = 50 var/obj/item/chems/condiment/is_special_bottle @@ -49,13 +49,6 @@ on_reagent_change() return -/obj/item/chems/condiment/attack_self(var/mob/user) - return - -/obj/item/chems/condiment/attack(var/mob/M, var/mob/user, var/def_zone) - if(standard_feed_mob(user, M)) - return - /obj/item/chems/condiment/afterattack(var/obj/target, var/mob/user, var/proximity) if(!proximity) return @@ -79,12 +72,6 @@ else ..() -/obj/item/chems/condiment/feed_sound(var/mob/user) - playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1) - -/obj/item/chems/condiment/self_feed_message(var/mob/user) - to_chat(user, SPAN_NOTICE("You swallow some of contents of \the [src].")) - /obj/item/chems/condiment/proc/update_center_of_mass() center_of_mass = is_special_bottle ? initial(is_special_bottle.center_of_mass) : initial(center_of_mass) @@ -116,7 +103,7 @@ icon_state = "enzyme" /obj/item/chems/condiment/enzyme/populate_reagents() - reagents.add_reagent(/decl/material/liquid/enzyme, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/enzyme, reagents.maximum_volume) /obj/item/chems/condiment/barbecue name = "barbecue sauce" @@ -124,14 +111,14 @@ icon_state = "barbecue" /obj/item/chems/condiment/barbecue/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/barbecue, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/barbecue, reagents.maximum_volume) /obj/item/chems/condiment/sugar name = "sugar" desc = "Cavities in a bottle." /obj/item/chems/condiment/sugar/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) /obj/item/chems/condiment/ketchup name = "ketchup" @@ -139,7 +126,7 @@ icon_state = "ketchup" /obj/item/chems/condiment/ketchup/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/ketchup, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/ketchup, reagents.maximum_volume) /obj/item/chems/condiment/cornoil name = "corn oil" @@ -147,7 +134,7 @@ icon_state = "oliveoil" /obj/item/chems/condiment/cornoil/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/cornoil, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/cornoil, reagents.maximum_volume) /obj/item/chems/condiment/vinegar name = "vinegar" @@ -155,7 +142,7 @@ desc = "As acidic as it gets in the kitchen." /obj/item/chems/condiment/vinegar/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/vinegar, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/vinegar, reagents.maximum_volume) /obj/item/chems/condiment/mayo name = "mayonnaise" @@ -163,7 +150,7 @@ desc = "Mayonnaise, used for centuries to make things edible." /obj/item/chems/condiment/mayo/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/mayo, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/mayo, reagents.maximum_volume) /obj/item/chems/condiment/frostoil name = "coldsauce" @@ -171,7 +158,7 @@ icon_state = "coldsauce" /obj/item/chems/condiment/frostoil/populate_reagents() - reagents.add_reagent(/decl/material/liquid/frostoil, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/frostoil, reagents.maximum_volume) /obj/item/chems/condiment/capsaicin name = "hotsauce" @@ -179,7 +166,7 @@ icon_state = "hotsauce" /obj/item/chems/condiment/capsaicin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/capsaicin, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/capsaicin, reagents.maximum_volume) /obj/item/chems/condiment/small name = "small condiment container" @@ -203,28 +190,28 @@ name = "salt shaker" desc = "Salt. From space oceans, presumably." icon_state = "saltshakersmall" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' /obj/item/chems/condiment/small/saltshaker/populate_reagents() - reagents.add_reagent(/decl/material/solid/sodiumchloride, reagents.maximum_volume) + add_to_reagents(/decl/material/solid/sodiumchloride, reagents.maximum_volume) /obj/item/chems/condiment/small/peppermill name = "pepper mill" desc = "Often used to flavor food or make people sneeze." icon_state = "peppermillsmall" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' /obj/item/chems/condiment/small/peppermill/populate_reagents() - reagents.add_reagent(/decl/material/solid/blackpepper, reagents.maximum_volume) + add_to_reagents(/decl/material/solid/blackpepper, reagents.maximum_volume) /obj/item/chems/condiment/small/sugar name = "sugar" desc = "Sweetness in a bottle" icon_state = "sugarsmall" - center_of_mass = @"{'x':17,'y':9}" + center_of_mass = @'{"x":17,"y":9}' /obj/item/chems/condiment/small/sugar/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) /obj/item/chems/condiment/small/mint name = "mint essential oil" @@ -233,7 +220,7 @@ icon_state = "coldsauce" /obj/item/chems/condiment/small/mint/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/syrup/mint, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/syrup/mint, reagents.maximum_volume) /obj/item/chems/condiment/small/soysauce name = "soy sauce" @@ -241,7 +228,7 @@ icon_state = "soysauce" /obj/item/chems/condiment/small/soysauce/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/soysauce, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/soysauce, reagents.maximum_volume) //MRE condiments and drinks. @@ -258,7 +245,7 @@ icon_state = "packet_small_white" /obj/item/chems/condiment/small/packet/salt/populate_reagents() - reagents.add_reagent(/decl/material/solid/sodiumchloride, reagents.maximum_volume/2) + add_to_reagents(/decl/material/solid/sodiumchloride, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/pepper name = "pepper packet" @@ -266,7 +253,7 @@ icon_state = "packet_small_black" /obj/item/chems/condiment/small/packet/pepper/populate_reagents() - reagents.add_reagent(/decl/material/solid/blackpepper, reagents.maximum_volume/2) + add_to_reagents(/decl/material/solid/blackpepper, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/sugar name = "sugar packet" @@ -274,7 +261,7 @@ icon_state = "packet_small_white" /obj/item/chems/condiment/small/packet/sugar/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/jelly name = "jelly packet" @@ -282,7 +269,7 @@ icon_state = "packet_medium" /obj/item/chems/condiment/small/packet/jelly/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/cherryjelly, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/cherryjelly, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/honey name = "honey packet" @@ -290,7 +277,7 @@ icon_state = "packet_medium" /obj/item/chems/condiment/small/packet/honey/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/sugar, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/capsaicin name = "hot sauce packet" @@ -298,7 +285,7 @@ icon_state = "packet_small_red" /obj/item/chems/condiment/small/packet/capsaicin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/capsaicin, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/capsaicin, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/ketchup name = "ketchup packet" @@ -306,7 +293,7 @@ icon_state = "packet_small_red" /obj/item/chems/condiment/small/packet/ketchup/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/ketchup, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/ketchup, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/mayo name = "mayonnaise packet" @@ -314,7 +301,7 @@ icon_state = "packet_small_white" /obj/item/chems/condiment/small/packet/mayo/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/mayo, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/mayo, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/soy name = "soy sauce packet" @@ -322,56 +309,56 @@ icon_state = "packet_small_black" /obj/item/chems/condiment/small/packet/soy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/soysauce, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/soysauce, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/coffee name = "instant coffee powder packet" desc = "Contains 5u of instant coffee powder. Mix with 25u of water." /obj/item/chems/condiment/small/packet/coffee/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/coffee/instant, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/coffee/instant, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/tea name = "instant tea powder packet" desc = "Contains 5u of instant black tea powder. Mix with 25u of water." /obj/item/chems/condiment/small/packet/tea/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/tea/instant, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/tea/instant, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/cocoa name = "cocoa powder packet" desc = "Contains 5u of cocoa powder. Mix with 25u of water and heat." /obj/item/chems/condiment/small/packet/cocoa/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/coco, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/coco, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/grape name = "grape juice powder packet" desc = "Contains 5u of powdered grape juice. Mix with 15u of water." /obj/item/chems/condiment/small/packet/grape/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/instantjuice/grape, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/instantjuice/grape, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/orange name = "orange juice powder packet" desc = "Contains 5u of powdered orange juice. Mix with 15u of water." /obj/item/chems/condiment/small/packet/orange/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/instantjuice/orange, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/instantjuice/orange, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/watermelon name = "watermelon juice powder packet" desc = "Contains 5u of powdered watermelon juice. Mix with 15u of water." /obj/item/chems/condiment/small/packet/watermelon/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/instantjuice/watermelon, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/instantjuice/watermelon, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/apple name = "apple juice powder packet" desc = "Contains 5u of powdered apple juice. Mix with 15u of water." /obj/item/chems/condiment/small/packet/apple/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/instantjuice/apple, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/instantjuice/apple, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/protein name = "protein powder packet" @@ -379,38 +366,38 @@ icon_state = "packet_medium" /obj/item/chems/condiment/small/packet/protein/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, reagents.maximum_volume/2) + add_to_reagents(/decl/material/liquid/nutriment/protein, reagents.maximum_volume/2) /obj/item/chems/condiment/small/packet/crayon name = "crayon powder packet" desc = "Contains 10u of powdered crayon. Mix with 30u of water." /obj/item/chems/condiment/small/packet/crayon/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/red/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/red, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/red, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/orange/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/orange, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/orange, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/yellow/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/yellow, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/yellow, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/green/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/green, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/green, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/blue/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/blue, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/blue, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/purple/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/purple, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/purple, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/grey/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/grey, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/grey, reagents.maximum_volume) /obj/item/chems/condiment/small/packet/crayon/brown/populate_reagents() - reagents.add_reagent(/decl/material/liquid/pigment/brown, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/pigment/brown, reagents.maximum_volume) //End of MRE stuff. @@ -423,7 +410,7 @@ randpixel = 10 /obj/item/chems/condiment/flour/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment/flour, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nutriment/flour, reagents.maximum_volume) /obj/item/chems/condiment/flour/update_container_name() return @@ -449,7 +436,7 @@ randpixel = 10 /obj/item/chems/condiment/large/salt/populate_reagents() - reagents.add_reagent(/decl/material/solid/sodiumchloride, reagents.maximum_volume) + add_to_reagents(/decl/material/solid/sodiumchloride, reagents.maximum_volume) /obj/item/chems/condiment/large/salt/update_container_name() return diff --git a/code/modules/reagents/reagent_containers/condiment_edibility.dm b/code/modules/reagents/reagent_containers/condiment_edibility.dm new file mode 100644 index 00000000000..a5c98156efe --- /dev/null +++ b/code/modules/reagents/reagent_containers/condiment_edibility.dm @@ -0,0 +1,15 @@ +/obj/item/chems/condiment/show_feed_message_start(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You begin trying to eat some of \the [target].")) + else + user.visible_message(SPAN_NOTICE("\The [user] is trying to feed some of the contents of \the [src] to \the [target]!")) + +/obj/item/chems/condiment/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow some of the contents of \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] feeds some of the contents of \the [src] to \the [target]!")) diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm index bfa2cc737ca..2478bff9d66 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm @@ -26,7 +26,7 @@ var/global/const/DRINK_ICON_NOISY = "noise" var/filling_overlayed //if filling should go on top of the icon (e.g. opaque cups) var/static/list/filling_icons_cache = list() - center_of_mass =@"{'x':16,'y':9}" + center_of_mass =@'{"x":16,"y":9}' amount_per_transfer_from_this = 5 possible_transfer_amounts = @"[5,10,15,30]" @@ -107,16 +107,15 @@ var/global/const/DRINK_ICON_NOISY = "noise" . = custom_desc || ..() /obj/item/chems/drinks/glass2/on_reagent_change() - temperature_coefficient = 4 / max(1, reagents.total_volume) + temperature_coefficient = 4 / max(1, reagents?.total_volume) ..() /obj/item/chems/drinks/glass2/proc/can_add_extra(obj/item/glass_extra/GE) if(!("[overlay_base_icon]_[GE.glass_addition]left" in icon_states(icon))) - return 0 + return FALSE if(!("[overlay_base_icon]_[GE.glass_addition]right" in icon_states(icon))) - return 0 - - return 1 + return FALSE + return TRUE /obj/item/chems/drinks/glass2/examine(mob/user, distance) . = ..() diff --git a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm index b66c69e011e..3391cd27192 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm @@ -8,7 +8,7 @@ filling_states = @"[20,40,60,80,100]" volume = 30 possible_transfer_amounts = @"[5,10,15,30]" - rim_pos = @"{'y':23,'x_left':13,'x_right':20}" + rim_pos = @'{"y":23,"x_left":13,"x_right":20}' /obj/item/chems/drinks/glass2/rocks name = "rocks glass" @@ -20,7 +20,7 @@ filling_states = @"[25,50,75,100]" volume = 20 possible_transfer_amounts = @"[5,10,20]" - rim_pos = @"{'y':21,'x_left':10,'x_right':23}" + rim_pos = @'{"y":21,"x_left":10,"x_right":23}' /obj/item/chems/drinks/glass2/shake name = "sherry glass" @@ -32,7 +32,7 @@ filling_states = @"[25,50,75,100]" volume = 30 possible_transfer_amounts = @"[5,10,15,30]" - rim_pos = @"{'y':25,'x_left':13,'x_right':21}" + rim_pos = @'{"y":25,"x_left":13,"x_right":21}' /obj/item/chems/drinks/glass2/cocktail name = "cocktail glass" @@ -44,7 +44,7 @@ filling_states = @"[33,66,100]" volume = 15 possible_transfer_amounts = @"[5,10,15]" - rim_pos = @"{'y':22,'x_left':13,'x_right':21}" + rim_pos = @'{"y":22,"x_left":13,"x_right":21}' /obj/item/chems/drinks/glass2/shot name = "shot glass" @@ -57,7 +57,7 @@ volume = 5 material = /decl/material/solid/glass possible_transfer_amounts = @"[1,2,5]" - rim_pos = @"{'y':17,'x_left':13,'x_right':21}" + rim_pos = @'{"y":17,"x_left":13,"x_right":21}' /obj/item/chems/drinks/glass2/pint name = "pint glass" @@ -69,7 +69,7 @@ volume = 60 material = /decl/material/solid/glass possible_transfer_amounts = @"[5,10,15,30,60]" - rim_pos = @"{'y':25,'x_left':12,'x_right':21}" + rim_pos = @'{"y":25,"x_left":12,"x_right":21}' /obj/item/chems/drinks/glass2/mug name = "glass mug" @@ -81,7 +81,7 @@ filling_states = @"[25,50,75,100]" volume = 40 possible_transfer_amounts = @"[5,10,20,40]" - rim_pos = @"{'y':22,'x_left':12,'x_right':20}" + rim_pos = @'{"y":22,"x_left":12,"x_right":20}' /obj/item/chems/drinks/glass2/wine name = "wine glass" @@ -93,7 +93,7 @@ filling_states = @"[20,40,60,80,100]" volume = 25 possible_transfer_amounts = @"[5,10,15,25]" - rim_pos = @"{'y':25,'x_left':12,'x_right':21}" + rim_pos = @'{"y":25,"x_left":12,"x_right":21}' /obj/item/chems/drinks/glass2/flute name = "flute glass" @@ -105,7 +105,7 @@ volume = 25 filling_states = @"[20,40,60,80,100]" possible_transfer_amounts = @"[5,10,15,25]" - rim_pos = @"{'y':24,'x_left':13,'x_right':19}" + rim_pos = @'{"y":24,"x_left":13,"x_right":19}' /obj/item/chems/drinks/glass2/carafe name = "pitcher" @@ -118,8 +118,8 @@ volume = 120 material = /decl/material/solid/glass possible_transfer_amounts = @"[5,10,15,30,60,120]" - rim_pos = @"{'y':26,'x_left':12,'x_right':21}" - center_of_mass = @"{'x':16,'y':7}" + rim_pos = @'{"y":26,"x_left":12,"x_right":21}' + center_of_mass = @'{"x":16,"y":7}' /obj/item/chems/drinks/glass2/coffeecup name = "coffee cup" @@ -128,12 +128,12 @@ icon_state = "coffeecup" item_state = "coffee" volume = 30 - center_of_mass = @"{'x':15,'y':13}" + center_of_mass = @'{"x":15,"y":13}' filling_states = @"[40,80,100]" base_name = "cup" base_icon = "coffeecup" overlay_base_icon = "coffeecup" // so that subtypes work properly - rim_pos = @"{'y':22,'x_left':12,'x_right':20}" + rim_pos = @'{"y":22,"x_left":12,"x_right":20}' filling_overlayed = TRUE /obj/item/chems/drinks/glass2/coffeecup/black @@ -172,7 +172,7 @@ base_name = "#1 monkey cup" /obj/item/chems/drinks/glass2/coffeecup/punitelli/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/banana, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/banana, reagents.maximum_volume) /obj/item/chems/drinks/glass2/coffeecup/rainbow name = "rainbow coffee cup" @@ -217,7 +217,7 @@ icon = 'icons/obj/drink_glasses/coffecup_tall.dmi' icon_state = "coffeecup_tall" volume = 60 - center_of_mass = @"{'x':15,'y':19}" + center_of_mass = @'{"x":15,"y":19}' filling_states = @"[50,70,90,100]" base_name = "tall cup" base_icon = "coffeecup_tall" diff --git a/code/modules/reagents/reagent_containers/drinkingglass/shaker.dm b/code/modules/reagents/reagent_containers/drinkingglass/shaker.dm index 9bd2c837869..af76602181b 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/shaker.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/shaker.dm @@ -38,8 +38,8 @@ ) /obj/item/chems/drinks/glass2/fitnessflask/proteinshake/populate_reagents() - reagents.add_reagent(/decl/material/liquid/nutriment, 30) - reagents.add_reagent(/decl/material/solid/metal/iron, 10) - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 15) - reagents.add_reagent(/decl/material/liquid/water, 45) + add_to_reagents(/decl/material/liquid/nutriment, 30) + add_to_reagents(/decl/material/solid/metal/iron, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 15) + add_to_reagents(/decl/material/liquid/water, 45) diff --git a/code/modules/reagents/reagent_containers/drinks.dm b/code/modules/reagents/reagent_containers/drinks.dm index 13aa0a4e7f4..b4ccc62542a 100644 --- a/code/modules/reagents/reagent_containers/drinks.dm +++ b/code/modules/reagents/reagent_containers/drinks.dm @@ -32,67 +32,48 @@ attack(user, user) /obj/item/chems/drinks/proc/open(mob/user) - playsound(loc,'sound/effects/canopen.ogg', rand(10,50), 1) - to_chat(user, SPAN_NOTICE("You open \the [src] with an audible pop!")) - atom_flags |= ATOM_FLAG_OPEN_CONTAINER - -/obj/item/chems/drinks/attack(mob/M, mob/user, def_zone) - if(force && !(item_flags & ITEM_FLAG_NO_BLUDGEON) && user.a_intent == I_HURT) - return ..() - if(standard_feed_mob(user, M)) - return - return 0 + if(!ATOM_IS_OPEN_CONTAINER(src)) + playsound(loc,'sound/effects/canopen.ogg', rand(10,50), 1) + to_chat(user, SPAN_NOTICE("You open \the [src] with an audible pop!")) + atom_flags |= ATOM_FLAG_OPEN_CONTAINER + return TRUE + return FALSE -/obj/item/chems/drinks/afterattack(obj/target, mob/user, proximity) - if(!proximity) return +/obj/item/chems/drinks/proc/do_open_check(mob/user) + if(!ATOM_IS_OPEN_CONTAINER(src)) + to_chat(user, SPAN_NOTICE("You need to open \the [src]!")) + return FALSE + return TRUE +/obj/item/chems/drinks/afterattack(obj/target, mob/user, proximity) + if(!proximity) + return if(standard_dispenser_refill(user, target)) return if(standard_pour_into(user, target)) return return ..() -/obj/item/chems/drinks/standard_feed_mob(var/mob/user, var/mob/target) - if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, "You need to open \the [src]!") - return 1 - return ..() - /obj/item/chems/drinks/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) - if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, "You need to open \the [src]!") - return 1 - return ..() + return do_open_check(user) && ..() /obj/item/chems/drinks/standard_pour_into(var/mob/user, var/atom/target) - if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, "You need to open \the [src]!") - return 1 - return ..() - -/obj/item/chems/drinks/self_feed_message(var/mob/user) - to_chat(user, "You swallow a gulp from \the [src].") - if(user.has_personal_goal(/datum/goal/achievement/specific_object/drink)) - for(var/R in reagents.reagent_volumes) - user.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) - -/obj/item/chems/drinks/feed_sound(var/mob/user) - playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1) + return do_open_check(user) && ..() /obj/item/chems/drinks/examine(mob/user, distance) . = ..() if(distance > 1) return if(!reagents || reagents.total_volume == 0) - to_chat(user, "\The [src] is empty!") + to_chat(user, SPAN_NOTICE("\The [src] is empty!")) else if (reagents.total_volume <= volume * 0.25) - to_chat(user, "\The [src] is almost empty!") + to_chat(user, SPAN_NOTICE("\The [src] is almost empty!")) else if (reagents.total_volume <= volume * 0.66) - to_chat(user, "\The [src] is half full!") + to_chat(user, SPAN_NOTICE("\The [src] is half full!")) else if (reagents.total_volume <= volume * 0.90) - to_chat(user, "\The [src] is almost full!") + to_chat(user, SPAN_NOTICE("\The [src] is almost full!")) else - to_chat(user, "\The [src] is full!") + to_chat(user, SPAN_NOTICE("\The [src] is full!")) /obj/item/chems/drinks/proc/get_filling_state() var/percent = round((reagents.total_volume / volume) * 100) @@ -105,9 +86,8 @@ /obj/item/chems/drinks/on_update_icon() . = ..() - if(LAZYLEN(reagents.reagent_volumes)) - if(filling_states) - add_overlay(overlay_image(icon, "[base_icon][get_filling_state()]", reagents.get_color())) + if(LAZYLEN(reagents?.reagent_volumes) && filling_states) + add_overlay(overlay_image(icon, "[base_icon][get_filling_state()]", reagents.get_color())) //////////////////////////////////////////////////////////////////////////////// @@ -138,20 +118,20 @@ desc = "It's milk. White and nutritious goodness!" icon_state = "milk" item_state = "carton" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' /obj/item/chems/drinks/milk/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/milk, reagents.maximum_volume) /obj/item/chems/drinks/soymilk name = "soymilk carton" desc = "It's soy milk. White and nutritious goodness!" icon_state = "soymilk" item_state = "carton" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' /obj/item/chems/drinks/soymilk/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk/soymilk, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/milk/soymilk, reagents.maximum_volume) /obj/item/chems/drinks/milk/smallcarton name = "small milk carton" @@ -159,52 +139,52 @@ icon_state = "mini-milk" /obj/item/chems/drinks/milk/smallcarton/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/milk, reagents.maximum_volume) /obj/item/chems/drinks/milk/smallcarton/chocolate name = "small chocolate milk carton" desc = "It's milk! This one is in delicious chocolate flavour." /obj/item/chems/drinks/milk/smallcarton/chocolate/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk/chocolate, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/milk/chocolate, reagents.maximum_volume) /obj/item/chems/drinks/coffee name = "\improper Robust Coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot." icon_state = "coffee" - center_of_mass = @"{'x':15,'y':10}" + center_of_mass = @'{"x":15,"y":10}' /obj/item/chems/drinks/coffee/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/coffee, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/coffee, reagents.maximum_volume) /obj/item/chems/drinks/ice name = "cup of ice" desc = "Careful, cold ice, do not chew." icon_state = "coffee" - center_of_mass = @"{'x':15,'y':10}" + center_of_mass = @'{"x":15,"y":10}' /obj/item/chems/drinks/ice/populate_reagents() - reagents.add_reagent(/decl/material/solid/ice, reagents.maximum_volume) + add_to_reagents(/decl/material/solid/ice, reagents.maximum_volume) /obj/item/chems/drinks/h_chocolate name = "cup of hot cocoa" desc = "A tall plastic cup of creamy hot chocolate." icon_state = "coffee" item_state = "coffee" - center_of_mass = @"{'x':15,'y':13}" + center_of_mass = @'{"x":15,"y":13}' /obj/item/chems/drinks/h_chocolate/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/hot_coco, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/hot_coco, reagents.maximum_volume) /obj/item/chems/drinks/dry_ramen name = "cup ramen" gender = PLURAL desc = "Just add 10ml water, self heats! A taste that reminds you of your school years." icon_state = "ramen" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' /obj/item/chems/drinks/dry_ramen/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/dry_ramen, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/dry_ramen, reagents.maximum_volume) /obj/item/chems/drinks/sillycup name = "paper cup" @@ -212,7 +192,7 @@ icon_state = "water_cup_e" possible_transfer_amounts = null volume = 10 - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/sillycup/on_update_icon() . = ..() @@ -234,7 +214,7 @@ item_state = "teapot" amount_per_transfer_from_this = 10 volume = 120 - center_of_mass = @"{'x':17,'y':7}" + center_of_mass = @'{"x":17,"y":7}' material = /decl/material/solid/stone/ceramic /obj/item/chems/drinks/pitcher @@ -243,7 +223,7 @@ icon_state = "pitcher" volume = 120 amount_per_transfer_from_this = 10 - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' filling_states = @"[15,30,50,70,85,100]" base_icon = "pitcher" material = /decl/material/solid/metal/stainlesssteel @@ -253,7 +233,7 @@ desc = "A metal flask belonging to the captain." icon_state = "flask" volume = 60 - center_of_mass = @"{'x':17,'y':7}" + center_of_mass = @'{"x":17,"y":7}' /obj/item/chems/drinks/flask/shiny name = "shiny flask" @@ -270,21 +250,21 @@ desc = "A metal flask with a leather band and golden badge belonging to the detective." icon_state = "detflask" volume = 60 - center_of_mass = @"{'x':17,'y':8}" + center_of_mass = @'{"x":17,"y":8}' /obj/item/chems/drinks/flask/barflask name = "flask" desc = "For those who can't be bothered to hang out at the bar to drink." icon_state = "barflask" volume = 60 - center_of_mass = @"{'x':17,'y':7}" + center_of_mass = @'{"x":17,"y":7}' /obj/item/chems/drinks/flask/vacuumflask name = "vacuum flask" desc = "Keeping your drinks at the perfect temperature since 1892." icon_state = "vacuumflask" volume = 60 - center_of_mass = @"{'x':15,'y':4}" + center_of_mass = @'{"x":15,"y":4}' //tea and tea accessories /obj/item/chems/drinks/tea @@ -292,7 +272,7 @@ desc = "A tall plastic cup full of the concept and ideal of tea." icon_state = "coffee" item_state = "coffee" - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' filling_states = @"[100]" base_name = "cup" base_icon = "cup" @@ -304,19 +284,19 @@ desc = "A tall plastic cup of hot black tea." /obj/item/chems/drinks/tea/black/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/tea/black, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/tea/black, reagents.maximum_volume) /obj/item/chems/drinks/tea/green name = "cup of green tea" desc = "A tall plastic cup of hot green tea." /obj/item/chems/drinks/tea/green/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/tea/green, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/tea/green, reagents.maximum_volume) /obj/item/chems/drinks/tea/chai name = "cup of chai tea" desc = "A tall plastic cup of hot chai tea." /obj/item/chems/drinks/tea/chai/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/tea/chai, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/tea/chai, reagents.maximum_volume) diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index 75d061746e2..c96ca01eaab 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -103,18 +103,20 @@ insert_rag(W, user) return TRUE else if(W.isflamesource()) - rag.attackby(W, user) - return TRUE + return rag.attackby(W, user) return ..() /obj/item/chems/drinks/bottle/attack_self(mob/user) - if(rag) - remove_rag(user) - else - ..() + return rag ? remove_rag(user) : ..() /obj/item/chems/drinks/bottle/proc/insert_rag(obj/item/chems/glass/rag/R, mob/user) - if(!material?.type != /decl/material/solid/glass || rag) return + if(material?.type != /decl/material/solid/glass) + to_chat(user, SPAN_WARNING("\The [src] isn't made of glass, you can't make a good Molotov with it.")) + return TRUE + + if(rag) + to_chat(user, SPAN_WARNING("\The [src] already has \a [rag] stuffed into it.")) + return TRUE if(user.try_unequip(R)) to_chat(user, SPAN_NOTICE("You stuff [R] into [src].")) @@ -133,6 +135,7 @@ atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER update_icon() + return TRUE /obj/item/chems/drinks/bottle/proc/remove_rag(mob/user) if(!rag) return @@ -249,254 +252,254 @@ name = "Griffeater Gin" desc = "A bottle of high quality gin, produced in the New London Space Station." icon_state = "ginbottle" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/gin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/gin, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/gin, reagents.maximum_volume) /obj/item/chems/drinks/bottle/whiskey name = "Uncle Git's Special Reserve" desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES." icon_state = "whiskeybottle" - center_of_mass = @"{'x':16,'y':3}" + center_of_mass = @'{"x":16,"y":3}' /obj/item/chems/drinks/bottle/whiskey/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/whiskey, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/whiskey, reagents.maximum_volume) /obj/item/chems/drinks/bottle/agedwhiskey name = "aged whiskey" desc = "This rich, smooth, hideously expensive beverage was aged for decades." icon_state = "whiskeybottle2" - center_of_mass = @"{'x':16,'y':3}" + center_of_mass = @'{"x":16,"y":3}' /obj/item/chems/drinks/bottle/agedwhiskey/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/aged_whiskey, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/aged_whiskey, reagents.maximum_volume) /obj/item/chems/drinks/bottle/vodka name = "Tunguska Triple Distilled" desc = "Aah, vodka. Prime choice of drink AND fuel by Indies around the galaxy." icon_state = "vodkabottle" - center_of_mass = @"{'x':17,'y':3}" + center_of_mass = @'{"x":17,"y":3}' /obj/item/chems/drinks/bottle/vodka/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume) /obj/item/chems/drinks/bottle/tequila name = "Caccavo Guaranteed Quality tequila" desc = "Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients!" icon_state = "tequilabottle" - center_of_mass = @"{'x':16,'y':3}" + center_of_mass = @'{"x":16,"y":3}' /obj/item/chems/drinks/bottle/tequila/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume) /obj/item/chems/drinks/bottle/patron name = "Wrapp Artiste Patron" desc = "Silver laced tequila, served in space night clubs across the galaxy." icon_state = "patronbottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/patron/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume - 5) - reagents.add_reagent(/decl/material/solid/metal/silver, 5) + add_to_reagents(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume - 5) + add_to_reagents(/decl/material/solid/metal/silver, 5) /obj/item/chems/drinks/bottle/rum name = "Captain Pete's Cuban Spiced Rum" desc = "This isn't just rum, oh no. It's practically GRIFF in a bottle." icon_state = "rumbottle" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' /obj/item/chems/drinks/bottle/rum/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/rum, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/rum, reagents.maximum_volume) /obj/item/chems/drinks/bottle/holywater name = "Flask of Holy Water" desc = "A flask of the chaplain's holy water." icon_state = "holyflask" - center_of_mass = @"{'x':17,'y':10}" + center_of_mass = @'{"x":17,"y":10}' /obj/item/chems/drinks/bottle/holywater/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume, list("holy" = TRUE)) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume, list("holy" = TRUE)) /obj/item/chems/drinks/bottle/vermouth name = "Goldeneye Vermouth" desc = "Sweet, sweet dryness~" icon_state = "vermouthbottle" - center_of_mass = @"{'x':17,'y':3}" + center_of_mass = @'{"x":17,"y":3}' /obj/item/chems/drinks/bottle/vermouth/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/vermouth, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/vermouth, reagents.maximum_volume) /obj/item/chems/drinks/bottle/kahlua name = "Robert Robust's Coffee Liqueur" desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936, HONK!" icon_state = "kahluabottle" - center_of_mass = @"{'x':17,'y':3}" + center_of_mass = @'{"x":17,"y":3}' /obj/item/chems/drinks/bottle/kahlua/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/coffee, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/coffee, reagents.maximum_volume) /obj/item/chems/drinks/bottle/goldschlager name = "College Girl Goldschlager" desc = "Because they are the only ones who will drink 100 proof cinnamon schnapps." icon_state = "goldschlagerbottle" - center_of_mass = @"{'x':15,'y':3}" + center_of_mass = @'{"x":15,"y":3}' /obj/item/chems/drinks/bottle/goldschlager/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume - 5) - reagents.add_reagent(/decl/material/solid/metal/gold, 5) + add_to_reagents(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume - 5) + add_to_reagents(/decl/material/solid/metal/gold, 5) /obj/item/chems/drinks/bottle/cognac name = "Chateau De Baton Premium Cognac" desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time." icon_state = "cognacbottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/cognac/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/cognac, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/cognac, reagents.maximum_volume) /obj/item/chems/drinks/bottle/wine name = "Doublebeard Bearded Special Wine" desc = "A faint aura of unease and asspainery surrounds the bottle." icon_state = "winebottle" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/wine/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/wine, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/wine, reagents.maximum_volume) /obj/item/chems/drinks/bottle/absinthe name = "Jailbreaker Verte" desc = "One sip of this and you just know you're gonna have a good time." icon_state = "absinthebottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/absinthe/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/absinthe, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/absinthe, reagents.maximum_volume) /obj/item/chems/drinks/bottle/melonliquor name = "Emeraldine Melon Liquor" desc = "A bottle of 46 proof Emeraldine Melon Liquor. Sweet and light." icon_state = "alco-green" //Placeholder. - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/melonliquor/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/melonliquor, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/melonliquor, reagents.maximum_volume) /obj/item/chems/drinks/bottle/bluecuracao name = "Miss Blue Curacao" desc = "A fruity, exceptionally azure drink. Does not allow the imbiber to use the fifth magic." icon_state = "alco-blue" //Placeholder. - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/bluecuracao/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/bluecuracao, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/bluecuracao, reagents.maximum_volume) /obj/item/chems/drinks/bottle/herbal name = "Liqueur d'Herbe" desc = "A bottle of the seventh-finest herbal liquor sold under a generic name in the galaxy. The back label has a load of guff about the monks who traditionally made this particular variety." icon_state = "herbal" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/herbal/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/herbal, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/herbal, reagents.maximum_volume) /obj/item/chems/drinks/bottle/grenadine name = "Briar Rose Grenadine Syrup" desc = "Sweet and tangy, a bar syrup used to add color or flavor to drinks." icon_state = "grenadinebottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/grenadine/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/grenadine, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/grenadine, reagents.maximum_volume) /obj/item/chems/drinks/bottle/cola name = "\improper Space Cola" desc = "Cola. in space." icon_state = "colabottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/cola/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/cola, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/cola, reagents.maximum_volume) /obj/item/chems/drinks/bottle/space_up name = "\improper Space-Up" desc = "Tastes like a hull breach in your mouth." icon_state = "space-up_bottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/space_up/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/lemonade, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/lemonade, reagents.maximum_volume) /obj/item/chems/drinks/bottle/space_mountain_wind name = "\improper Space Mountain Wind" desc = "Blows right through you like a space wind." icon_state = "space_mountain_wind_bottle" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/space_mountain_wind/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/citrussoda, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/citrussoda, reagents.maximum_volume) /obj/item/chems/drinks/bottle/pwine name = "Warlock's Velvet" desc = "What a delightful packaging for a surely high quality wine! The vintage must be amazing!" icon_state = "pwinebottle" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/pwine/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/pwine, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/pwine, reagents.maximum_volume) /obj/item/chems/drinks/bottle/sake name = "Takeo Sadow's Combined Sake" desc = "A bottle of the highest-grade sake allowed for import." icon_state = "sake" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/sake/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/sake, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/sake, reagents.maximum_volume) /obj/item/chems/drinks/bottle/champagne name = "Murcelano Vinyard's Premium Champagne" desc = "The regal drink of celebrities and royalty." icon_state = "champagne" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/champagne/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/champagne, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/champagne, reagents.maximum_volume) /obj/item/chems/drinks/bottle/jagermeister name = "Kaisermeister Deluxe" desc = "Jagermeister. This drink just demands a party." icon_state = "herbal" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/jagermeister/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/jagermeister, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/jagermeister, reagents.maximum_volume) //////////////////////////PREMIUM ALCOHOL /////////////////////// /obj/item/chems/drinks/bottle/premiumvodka name = "Four Stripes Quadruple Distilled" desc = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation." icon_state = "premiumvodka" - center_of_mass = @"{'x':17,'y':3}" + center_of_mass = @'{"x":17,"y":3}' /obj/item/chems/drinks/bottle/premiumvodka/populate_reagents() var/namepick = pick("Four Stripes","Gilgamesh","Novaya Zemlya","Indie","STS-35") var/typepick = pick("Absolut","Gold","Quadruple Distilled","Platinum","Standard") name = "[namepick] [typepick]" - reagents.add_reagent(/decl/material/liquid/ethanol/vodka/premium, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/vodka/premium, reagents.maximum_volume) /obj/item/chems/drinks/bottle/premiumwine name = "Uve De Blanc" desc = "You feel pretentious just looking at it." icon_state = "premiumwine" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' /obj/item/chems/drinks/bottle/premiumwine/populate_reagents() var/namepick = pick("Calumont","Sciacchemont","Recioto","Torcalota") var/agedyear = rand(global.using_map.game_year - 150, global.using_map.game_year) name = "Chateau [namepick] De Blanc" desc += " This bottle is marked as [agedyear] Vintage." - reagents.add_reagent(/decl/material/liquid/ethanol/wine/premium, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/wine/premium, reagents.maximum_volume) //////////////////////////JUICES AND STUFF /////////////////////// @@ -505,7 +508,7 @@ desc = "Full of vitamins and deliciousness!" icon_state = "orangejuice" item_state = "carton" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -514,14 +517,14 @@ pickup_sound = 'sound/foley/paperpickup2.ogg' /obj/item/chems/drinks/bottle/orangejuice/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/orange, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/orange, reagents.maximum_volume) /obj/item/chems/drinks/bottle/cream name = "Milk Cream" desc = "It's cream. Made from milk. What else did you think you'd find in there?" icon_state = "cream" item_state = "carton" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -530,14 +533,14 @@ pickup_sound = 'sound/foley/paperpickup2.ogg' /obj/item/chems/drinks/bottle/cream/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk/cream, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/milk/cream, reagents.maximum_volume) /obj/item/chems/drinks/bottle/tomatojuice name = "Tomato Juice" desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness." icon_state = "tomatojuice" item_state = "carton" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -546,14 +549,14 @@ pickup_sound = 'sound/foley/paperpickup2.ogg' /obj/item/chems/drinks/bottle/tomatojuice/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, reagents.maximum_volume) /obj/item/chems/drinks/bottle/limejuice name = "Lime Juice" desc = "Sweet-sour goodness." icon_state = "limejuice" item_state = "carton" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -562,7 +565,7 @@ pickup_sound = 'sound/foley/paperpickup2.ogg' /obj/item/chems/drinks/bottle/limejuice/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/lime, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/lime, reagents.maximum_volume) //Small bottles /obj/item/chems/drinks/bottle/small @@ -575,26 +578,26 @@ name = "space beer" desc = "Contains only water, malt and hops." icon_state = "beer" - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/beer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/beer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume) /obj/item/chems/drinks/bottle/small/ale name = "\improper Magm-Ale" desc = "A true dorf's drink of choice." icon_state = "alebottle" item_state = "beer" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/bottle/small/ale/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/ale, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/ale, reagents.maximum_volume) /obj/item/chems/drinks/bottle/small/gingerbeer name = "Ginger Beer" desc = "A delicious non-alcoholic beverage enjoyed across Sol space." icon_state = "gingerbeer" - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/gingerbeer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/gingerbeer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/gingerbeer, reagents.maximum_volume) diff --git a/code/modules/reagents/reagent_containers/drinks/cans.dm b/code/modules/reagents/reagent_containers/drinks/cans.dm index 6071e79e11c..bebbdb9f24e 100644 --- a/code/modules/reagents/reagent_containers/drinks/cans.dm +++ b/code/modules/reagents/reagent_containers/drinks/cans.dm @@ -16,20 +16,20 @@ name = "\improper Space Cola" desc = "Cola. in space." icon_state = "cola" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/cola/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/cola, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/cola, reagents.maximum_volume) /obj/item/chems/drinks/cans/waterbottle name = "bottled water" desc = "Pure drinking water, imported from the Martian poles." icon_state = "waterbottle" - center_of_mass = @"{'x':15,'y':8}" + center_of_mass = @'{"x":15,"y":8}' material = /decl/material/solid/organic/plastic /obj/item/chems/drinks/cans/waterbottle/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) /obj/item/chems/drinks/cans/waterbottle/open(mob/user) playsound(loc,'sound/effects/bonebreak1.ogg', rand(10,50), 1) @@ -40,101 +40,101 @@ name = "\improper Space Mountain Wind" desc = "Blows right through you like a space wind." icon_state = "space_mountain_wind" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/space_mountain_wind/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/citrussoda, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/citrussoda, reagents.maximum_volume) /obj/item/chems/drinks/cans/thirteenloko name = "\improper Thirteen Loko" desc = "The CMO has advised crew members that consumption of Thirteen Loko may result in seizures, blindness, drunkeness, or even death. Please Drink Responsibly." icon_state = "thirteen_loko" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' /obj/item/chems/drinks/cans/thirteenloko/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/thirteenloko, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/thirteenloko, reagents.maximum_volume) /obj/item/chems/drinks/cans/dr_gibb name = "\improper Dr. Gibb" desc = "A delicious mixture of 42 different flavors." icon_state = "dr_gibb" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/dr_gibb/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/cherrycola, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/cherrycola, reagents.maximum_volume) /obj/item/chems/drinks/cans/starkist name = "\improper Star-Kist" desc = "Can you taste a bit of tuna...?" icon_state = "starkist" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/starkist/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/orangecola, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/orangecola, reagents.maximum_volume) /obj/item/chems/drinks/cans/space_up name = "\improper Space-Up" desc = "Tastes like a hull breach in your mouth." icon_state = "space-up" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/space_up/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/lemonade, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/lemonade, reagents.maximum_volume) /obj/item/chems/drinks/cans/lemon_lime name = "\improper Lemon-Lime" desc = "You wanted ORANGE. It gave you Lemon Lime." icon_state = "lemon-lime" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/lemon_lime/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/lemon_lime, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/lemon_lime, reagents.maximum_volume) /obj/item/chems/drinks/cans/iced_tea name = "\improper Vrisk Serket Iced Tea" desc = "That sweet, refreshing southern earthy flavor. That's where it's from, right? South Earth?" icon_state = "ice_tea_can" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/iced_tea/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/tea/black, reagents.maximum_volume - 5) - reagents.add_reagent(/decl/material/solid/ice, 5) + add_to_reagents(/decl/material/liquid/drink/tea/black, reagents.maximum_volume - 5) + add_to_reagents(/decl/material/solid/ice, 5) /obj/item/chems/drinks/cans/grape_juice name = "\improper Grapel Juice" desc = "500 pages of rules of how to appropriately enter into a combat with this juice!" icon_state = "purple_can" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/grape_juice/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/grape, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/grape, reagents.maximum_volume) /obj/item/chems/drinks/cans/tonic name = "\improper T-Borg's Tonic Water" desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away." icon_state = "tonic" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/tonic/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/tonic, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/tonic, reagents.maximum_volume) /obj/item/chems/drinks/cans/sodawater name = "soda water" desc = "A can of soda water. Still water's more refreshing cousin." icon_state = "sodawater" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/sodawater/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/sodawater, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/sodawater, reagents.maximum_volume) /obj/item/chems/drinks/cans/beastenergy name = "Beast Energy" desc = "100% pure energy, and 150% pure liver disease." icon_state = "beastenergy" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/cans/beastenergy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/beastenergy, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/beastenergy, reagents.maximum_volume) //Items exclusive to the BODA machine on deck 4 and wherever else it pops up. First two are a bit jokey. Second two are genuine article. @@ -142,42 +142,42 @@ name = "\improper Red Army Twist!" desc = "A taste of what keeps our glorious nation running! Served as Space Commissariat Stahlin prefers it! Luke warm." icon_state = "syndi_cola_x" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/syndicolax/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/potato, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/potato, reagents.maximum_volume) /obj/item/chems/drinks/cans/artbru name = "\improper Arstotzka Bru" desc = "Just what any bureaucrat needs to get through the day. Keep stamping those papers!" icon_state = "art_bru" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/artbru/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/turnip, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/turnip, reagents.maximum_volume) /obj/item/chems/drinks/cans/syndicola name = "\improper TerraCola" desc = "A can of the only soft drink state approved for the benefit of the people. Served at room temperature regardless of ambient temperatures thanks to innovative Terran insulation technology." icon_state = "syndi_cola" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/syndicola/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume - 5) - reagents.add_reagent(/decl/material/solid/metal/iron, 5) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume - 5) + add_to_reagents(/decl/material/solid/metal/iron, 5) /obj/item/chems/drinks/glass2/square/boda name = "boda" desc = "A tall glass of refreshing Boda!" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/glass2/square/boda/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/sodawater, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/sodawater, reagents.maximum_volume) /obj/item/chems/drinks/glass2/square/bodaplus name = "tri kopeiki sirop boda" desc = "A tall glass of even more refreshing Boda! Now with Sok!" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/glass2/square/bodaplus/populate_reagents() var/reag = pick(list( @@ -191,8 +191,8 @@ /decl/material/liquid/drink/juice/banana, /decl/material/liquid/drink/juice/berry, /decl/material/liquid/drink/juice/watermelon)) - reagents.add_reagent(/decl/material/liquid/drink/sodawater, reagents.maximum_volume / 2) - reagents.add_reagent(reag, reagents.maximum_volume / 2) + add_to_reagents(/decl/material/liquid/drink/sodawater, reagents.maximum_volume / 2) + add_to_reagents(reag, reagents.maximum_volume / 2) //Canned alcohols. @@ -201,16 +201,16 @@ name = "\improper Space Beer" desc = "Now in a can!" icon_state = "beercan" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/speer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/beer/good, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/beer/good, reagents.maximum_volume) /obj/item/chems/drinks/cans/ale name = "\improper Magm-Ale" desc = "Now in a can!" icon_state = "alecan" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/ale/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/ale, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/ale, reagents.maximum_volume) diff --git a/code/modules/reagents/reagent_containers/drinks/champagne.dm b/code/modules/reagents/reagent_containers/drinks/champagne.dm index a0cffe9359c..3a380131da9 100644 --- a/code/modules/reagents/reagent_containers/drinks/champagne.dm +++ b/code/modules/reagents/reagent_containers/drinks/champagne.dm @@ -23,13 +23,13 @@ desc = "Sparkling wine made from exquisite grape varieties by the method of secondary fermentation in a bottle. Bubbling." icon = 'icons/obj/food.dmi' icon_state = "champagne" - center_of_mass = @"{'x':12,'y':5}" + center_of_mass = @'{"x":12,"y":5}' atom_flags = 0 //starts closed var/opening /obj/item/chems/drinks/bottle/champagne/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/champagne, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/champagne, reagents.maximum_volume) /obj/item/chems/drinks/bottle/champagne/open(mob/user) if(ATOM_IS_OPEN_CONTAINER(src)) diff --git a/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm b/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm index 68655dc9ca6..c2517e3b519 100644 --- a/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm +++ b/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm @@ -5,7 +5,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = @"[5,10,15,25,30,60]" //Professional bartender should be able to transfer as much as needed volume = 120 - center_of_mass = @"{'x':17,'y':10}" + center_of_mass = @'{"x":17,"y":10}' atom_flags = ATOM_FLAG_OPEN_CONTAINER | ATOM_FLAG_NO_REACT /obj/item/chems/drinks/shaker/attack_self(mob/user) @@ -29,7 +29,7 @@ if(reagents && reagents.total_volume) atom_flags &= ~ATOM_FLAG_NO_REACT HANDLE_REACTIONS(reagents) - addtimer(CALLBACK(src, .proc/stop_react), SSmaterials.wait) + addtimer(CALLBACK(src, PROC_REF(stop_react)), SSmaterials.wait) /obj/item/chems/drinks/shaker/proc/stop_react() atom_flags |= ATOM_FLAG_NO_REACT \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/drinks/jar.dm b/code/modules/reagents/reagent_containers/drinks/jar.dm index afe4051e918..aedbbade98d 100644 --- a/code/modules/reagents/reagent_containers/drinks/jar.dm +++ b/code/modules/reagents/reagent_containers/drinks/jar.dm @@ -7,7 +7,7 @@ desc = "A jar. You're not sure what it's supposed to hold." icon_state = "jar" item_state = "beaker" - center_of_mass = @"{'x':15,'y':8}" + center_of_mass = @'{"x":15,"y":8}' material = /decl/material/solid/glass drop_sound = 'sound/foley/bottledrop1.ogg' pickup_sound = 'sound/foley/bottlepickup1.ogg' diff --git a/code/modules/reagents/reagent_containers/drinks/juicebox.dm b/code/modules/reagents/reagent_containers/drinks/juicebox.dm index 5fc23e36c85..92cbf0ea885 100644 --- a/code/modules/reagents/reagent_containers/drinks/juicebox.dm +++ b/code/modules/reagents/reagent_containers/drinks/juicebox.dm @@ -70,7 +70,7 @@ desc = "A small cardboard juicebox with a cartoon apple on it." /obj/item/chems/drinks/juicebox/apple/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/apple, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/apple, reagents.maximum_volume) /obj/item/chems/drinks/juicebox/apple/Initialize() . = ..() @@ -81,7 +81,7 @@ desc = "A small cardboard juicebox with a cartoon orange on it." /obj/item/chems/drinks/juicebox/orange/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/orange, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/orange, reagents.maximum_volume) /obj/item/chems/drinks/juicebox/orange/Initialize() . = ..() @@ -92,7 +92,7 @@ desc = "A small cardboard juicebox with some cartoon grapes on it." /obj/item/chems/drinks/juicebox/grape/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/grape, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/drink/juice/grape, reagents.maximum_volume) /obj/item/chems/drinks/juicebox/grape/Initialize() . = ..() @@ -112,8 +112,8 @@ /obj/item/chems/drinks/juicebox/sensible_random/proc/juice_it() var/list/drinktypes = decls_repository.get_decl_paths_of_subtype(/decl/material/liquid/drink/juice) var/decl/material/J = pick(drinktypes) - reagents.add_reagent(J, 20) - reagents.add_reagent(pick(drinktypes - J), 5) + add_to_reagents(J, 20) + add_to_reagents(pick(drinktypes - J), 5) return reagents.reagent_volumes /obj/item/chems/drinks/juicebox/sensible_random/populate_reagents() diff --git a/code/modules/reagents/reagent_containers/drinks_edibility.dm b/code/modules/reagents/reagent_containers/drinks_edibility.dm new file mode 100644 index 00000000000..7e7969d9acb --- /dev/null +++ b/code/modules/reagents/reagent_containers/drinks_edibility.dm @@ -0,0 +1,15 @@ +/obj/item/chems/drinks/handle_eaten_by_mob(var/mob/user, var/mob/target) + if(!do_open_check(user)) + return EATEN_UNABLE + . = ..() + if(. == EATEN_SUCCESS) + target = target || user + if(target?.has_personal_goal(/datum/goal/achievement/specific_object/drink)) + for(var/R in reagents.reagent_volumes) + target.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) + +/obj/item/chems/drinks/show_feed_message_end(var/mob/user, var/mob/target) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow a gulp from \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] feeds \the [src] to \the [target]!")) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 3c522e538f1..00ed01ba7b3 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -62,7 +62,7 @@ return else trans = reagents.splash(target, amount_per_transfer_from_this, max_spill=0) //sprinkling reagents on generic non-mobs. Droppers are very precise - to_chat(user, SPAN_NOTICE("You transfer [trans] units of the solution.")) + to_chat(user, SPAN_NOTICE("You transfer [trans] unit\s of the solution.")) else // Taking from something @@ -76,7 +76,7 @@ var/trans = target.reagents.trans_to_obj(src, amount_per_transfer_from_this) - to_chat(user, SPAN_NOTICE("You fill the dropper with [trans] units of the solution.")) + to_chat(user, SPAN_NOTICE("You fill the dropper with [trans] unit\s of the solution.")) /obj/item/chems/dropper/update_container_name() return @@ -86,7 +86,7 @@ /obj/item/chems/dropper/on_update_icon() . = ..() - if(reagents.total_volume) + if(reagents?.total_volume) icon_state = "dropper1" else icon_state = "dropper0" diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index f22c09198cb..69c02b2f12c 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -19,7 +19,7 @@ material = /decl/material/liquid/nutriment possible_transfer_amounts = null volume = 50 - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' w_class = ITEM_SIZE_SMALL abstract_type = /obj/item/chems/food @@ -35,7 +35,8 @@ var/list/nutriment_desc = list("food" = 1) // List of flavours and flavour strengths. The flavour strength text is determined by the ratio of flavour strengths in the snack. var/list/eat_sound = 'sound/items/eatfood.ogg' var/filling_color = "#ffffff" //Used by sandwiches. - var/trash = null + var/trash + var/obj/item/plate/plate var/list/attack_products //Items you can craft together. Like bomb making, but with food and less screwdrivers. // Uses format list(ingredient = result_type). The ingredient can be a typepath or a kitchen_tag string (used for mobs or plants) var/batter_coating = null // coating typepath, NOT decl instance @@ -159,24 +160,8 @@ LAZYINITLIST(reagents.reagent_data) // add a new reagent_data entry for each reagent type LAZYSET(reagents.reagent_data[reagent_type], "cooked", TRUE) // batter starts cooked in compile-time foods - - //Placeholder for effect that trigger on eating that aren't tied to reagents. -/obj/item/chems/food/proc/On_Consume(var/mob/M) - if(isliving(M) && cooked_food) - var/mob/living/eater = M - eater.add_stressor(/datum/stressor/ate_cooked_food, 15 MINUTES) - if(!reagents.total_volume) - M.visible_message("[M] finishes eating \the [src].","You finish eating \the [src].") - M.drop_item() - M.update_personal_goal(/datum/goal/achievement/specific_object/food, type) - if(trash) - if(ispath(trash,/obj/item)) - var/obj/item/TrashItem = new trash(get_turf(M)) - M.put_in_hands(TrashItem) - else if(istype(trash,/obj/item)) - M.put_in_hands(trash) - qdel(src) - return + if(ispath(plate)) + plate = new plate(src) /obj/item/chems/food/attack_self(mob/user) attack(user, user) @@ -184,59 +169,20 @@ /obj/item/chems/food/dragged_onto(var/mob/user) attack(user, user) -/obj/item/chems/food/self_feed_message(mob/user) - if(!iscarbon(user)) - return ..() - var/mob/living/carbon/C = user - var/fullness = C.get_fullness() - if (fullness <= 50) - to_chat(C, SPAN_WARNING("You hungrily chew out a piece of [src] and gobble it!")) - if (fullness > 50 && fullness <= 150) - to_chat(C, SPAN_NOTICE("You hungrily begin to eat [src].")) - if (fullness > 150 && fullness <= 350) - to_chat(C, SPAN_NOTICE("You take a bite of [src].")) - if (fullness > 350 && fullness <= 550) - to_chat(C, SPAN_NOTICE("You unwillingly chew a bit of [src].")) - -/obj/item/chems/food/feed_sound(mob/user) - if(eat_sound) - playsound(user, pick(eat_sound), rand(10, 50), 1) - -/obj/item/chems/food/standard_feed_mob(mob/user, mob/target) - . = ..() - if(.) - bitecount++ - On_Consume(target) - -/obj/item/chems/food/attack(mob/M, mob/user, def_zone) - if(!reagents || !reagents.total_volume) - to_chat(user, "None of [src] left!") - qdel(src) - return 0 - if(iscarbon(M)) - //TODO: replace with standard_feed_mob() call. - var/mob/living/carbon/C = M - var/fullness = C.get_fullness() - if (fullness > 550) - var/message = C == user ? "You cannot force any more of [src] to go down your throat." : "[user] cannot force anymore of [src] down [M]'s throat." - to_chat(user, SPAN_WARNING(message)) - return 0 - if(standard_feed_mob(user, M)) - return 1 - return 0 - /obj/item/chems/food/examine(mob/user, distance) . = ..() if(distance > 1) return + if(plate) + to_chat(user, SPAN_NOTICE("\The [src] has been arranged on \a [plate].")) if (bitecount==0) return else if (bitecount==1) - to_chat(user, "\The [src] was bitten by someone!") + to_chat(user, SPAN_NOTICE("\The [src] was bitten by someone!")) else if (bitecount<=3) - to_chat(user, "\The [src] was bitten [bitecount] time\s!") + to_chat(user, SPAN_NOTICE("\The [src] was bitten [bitecount] time\s!")) else - to_chat(user, "\The [src] was bitten multiple times!") + to_chat(user, SPAN_NOTICE("\The [src] was bitten multiple times!")) /obj/item/chems/food/attackby(obj/item/W, mob/living/user) if(!istype(user)) @@ -244,6 +190,13 @@ if(istype(W,/obj/item/storage)) ..()// -> item/attackby() return + + // Plating food. + if(istype(W, /obj/item/plate)) + var/obj/item/plate/plate = W + plate.try_plate_food(src, user) + return TRUE + // Eating with forks if(istype(W,/obj/item/kitchen/utensil)) var/obj/item/kitchen/utensil/U = W @@ -342,6 +295,7 @@ return (slices_num && slice_path && slices_num > 0) /obj/item/chems/food/proc/on_dry(var/atom/newloc) + drop_plate(get_turf(newloc)) if(dried_type == type) SetName("dried [name]") color = "#a38463" @@ -352,25 +306,24 @@ . = new dried_type(newloc || get_turf(src)) qdel(src) +/obj/item/chems/food/proc/drop_plate(var/drop_loc) + if(istype(plate)) + plate.dropInto(drop_loc || loc) + plate.make_dirty(src) + plate = null + +/obj/item/chems/food/physically_destroyed() + drop_plate() + return ..() + /obj/item/chems/food/Destroy() + QDEL_NULL(plate) + trash = null if(contents) for(var/atom/movable/something in contents) something.dropInto(loc) . = ..() -/obj/item/chems/food/attack_animal(var/mob/user) - if(!isanimal(user) && !isalien(user)) - return - user.visible_message("[user] nibbles away at \the [src].","You nibble away at \the [src].") - bitecount++ - if(reagents && user.reagents) - reagents.trans_to_mob(user, bitesize, CHEM_INGEST) - spawn(5) - if(!src && !user.client) - user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]") - qdel(src) - On_Consume(user) - /obj/item/chems/food/proc/update_food_appearance_from(var/obj/item/donor, var/food_color, var/copy_donor_appearance = TRUE) filling_color = food_color if(copy_donor_appearance) @@ -384,9 +337,22 @@ update_icon() /obj/item/chems/food/on_update_icon() + underlays.Cut() . = ..() //Since other things that don't have filling override this, slap it into its own proc to avoid the overhead of scanning through the icon file apply_filling_overlay() //#TODO: Maybe generalise food item icons. + // If we have a plate, add it to our icon. + if(plate) + var/image/I = new + I.appearance = plate + I.layer = FLOAT_LAYER + I.plane = FLOAT_PLANE + I.pixel_x = 0 + I.pixel_y = 0 + I.pixel_z = 0 + I.pixel_w = 0 + I.appearance_flags |= RESET_TRANSFORM|RESET_COLOR + underlays += list(I) /obj/item/chems/food/proc/apply_filling_overlay() if(check_state_in_icon("[icon_state]_filling", icon)) @@ -397,4 +363,4 @@ . = ..() SHOULD_CALL_PARENT(TRUE) if(nutriment_amt) - reagents.add_reagent(nutriment_type, nutriment_amt, nutriment_desc) + add_to_reagents(nutriment_type, nutriment_amt, nutriment_desc) diff --git a/code/modules/reagents/reagent_containers/food/baked_goods.dm b/code/modules/reagents/reagent_containers/food/baked_goods.dm index af486d26432..c1b6e20d979 100644 --- a/code/modules/reagents/reagent_containers/food/baked_goods.dm +++ b/code/modules/reagents/reagent_containers/food/baked_goods.dm @@ -7,7 +7,7 @@ desc = "A delicious and spongy little cake." icon_state = "muffin" filling_color = "#e0cf9b" - center_of_mass = @"{'x':17,'y':4}" + center_of_mass = @'{"x":17,"y":4}' nutriment_desc = list("sweetness" = 3, "muffin" = 3) nutriment_amt = 6 bitesize = 2 @@ -16,16 +16,16 @@ name = "banana cream pie" desc = "Just like back home, on clown planet! HONK!" icon_state = "pie" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fbffb8" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("pie" = 3, "cream" = 2) nutriment_amt = 4 bitesize = 3 /obj/item/chems/food/bananapie/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/banana_cream, 5) + add_to_reagents(/decl/material/liquid/nutriment/banana_cream, 5) /obj/item/chems/food/pie/throw_impact(atom/hit_atom) ..() @@ -37,15 +37,15 @@ name = "berry clafoutis" desc = "No black birds, this is a good sign." icon_state = "berryclafoutis" - trash = /obj/item/trash/plate - center_of_mass = @"{'x':16,'y':13}" + plate = /obj/item/plate + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("sweetness" = 2, "pie" = 3) nutriment_amt = 4 bitesize = 3 /obj/item/chems/food/berryclafoutis/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/berry, 5) + add_to_reagents(/decl/material/liquid/drink/juice/berry, 5) /obj/item/chems/food/waffles name = "waffles" @@ -53,7 +53,7 @@ icon_state = "waffles" trash = /obj/item/trash/waffles filling_color = "#e6deb5" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' nutriment_desc = list("waffle" = 8) nutriment_amt = 8 bitesize = 2 @@ -64,21 +64,21 @@ icon_state = "rofflewaffles" trash = /obj/item/trash/waffles filling_color = "#ff00f7" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' nutriment_desc = list("waffle" = 7, "sweetness" = 1) nutriment_amt = 8 bitesize = 4 /obj/item/chems/food/rofflewaffles/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/psychotropics, 8) + add_to_reagents(/decl/material/liquid/psychotropics, 8) /obj/item/chems/food/pancakes name = "pancakes" desc = "Pancakes without blueberries, still delicious." icon_state = "pancakes" - trash = /obj/item/trash/plate - center_of_mass = @"{'x':15,'y':11}" + plate = /obj/item/plate + center_of_mass = @'{"x":15,"y":11}' nutriment_desc = list("pancake" = 8) nutriment_amt = 8 bitesize = 2 @@ -87,8 +87,8 @@ name = "blueberry pancakes" desc = "Pancakes with blueberries, delicious." icon_state = "pancakes" - trash = /obj/item/trash/plate - center_of_mass = @"{'x':15,'y':11}" + plate = /obj/item/plate + center_of_mass = @'{"x":15,"y":11}' nutriment_desc = list("pancake" = 8) nutriment_amt = 8 bitesize = 2 @@ -97,9 +97,9 @@ name = "eggplant parmigiana" desc = "The only good recipe for eggplant." icon_state = "eggplantparm" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#4d2f5e" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("cheese" = 3, "eggplant" = 3) nutriment_amt = 6 bitesize = 2 @@ -110,12 +110,12 @@ icon_state = "soylent_green" trash = /obj/item/trash/waffles filling_color = "#b8e6b5" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' bitesize = 2 /obj/item/chems/food/soylentgreen/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/soylenviridians name = "\improper Soylen Virdians" @@ -123,7 +123,7 @@ icon_state = "soylent_yellow" trash = /obj/item/trash/waffles filling_color = "#e6fa61" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' nutriment_desc = list("some sort of protein" = 10)//seasoned vERY well. nutriment_amt = 10 bitesize = 2 @@ -132,22 +132,22 @@ name = "meat-pie" icon_state = "meatpie" desc = "An old barber recipe, very delicious!" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#948051" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 2 /obj/item/chems/food/meatpie/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/tofupie name = "tofu-pie" icon_state = "meatpie" desc = "A delicious tofu pie." - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fffee0" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("tofu" = 2, "pie" = 8) nutriment_amt = 10 bitesize = 2 @@ -157,22 +157,22 @@ desc = "Sweet and tasty poison pie." icon_state = "amanita_pie" filling_color = "#ffcccc" - center_of_mass = @"{'x':17,'y':9}" + center_of_mass = @'{"x":17,"y":9}' nutriment_desc = list("sweetness" = 3, "mushroom" = 3, "pie" = 2) nutriment_amt = 5 bitesize = 3 /obj/item/chems/food/amanita_pie/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/amatoxin, 3) - reagents.add_reagent(/decl/material/liquid/psychotropics, 1) + add_to_reagents(/decl/material/liquid/amatoxin, 3) + add_to_reagents(/decl/material/liquid/psychotropics, 1) /obj/item/chems/food/plump_pie name = "plump pie" desc = "I bet you love stuff made out of plump helmets!" icon_state = "plump_pie" filling_color = "#b8279b" - center_of_mass = @"{'x':17,'y':9}" + center_of_mass = @'{"x":17,"y":9}' nutriment_desc = list("heartiness" = 2, "mushroom" = 3, "pie" = 3) nutriment_amt = 8 bitesize = 2 @@ -182,20 +182,20 @@ if(prob(10)) //#TODO: have this depend on cook's skill within the recipe handling instead maybe? name = "exceptional plump pie" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" - reagents.add_reagent(/decl/material/liquid/regenerator, 5) + add_to_reagents(/decl/material/liquid/regenerator, 5) /obj/item/chems/food/xemeatpie name = "xeno-pie" icon_state = "xenomeatpie" desc = "A delicious meatpie. Probably heretical." - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#43de18" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 2 /obj/item/chems/food/xemeatpie/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/poppypretzel name = "poppy pretzel" @@ -203,7 +203,7 @@ icon_state = "poppypretzel" bitesize = 2 filling_color = "#916e36" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("poppy seeds" = 2, "pretzel" = 3) nutriment_amt = 5 bitesize = 2 @@ -213,7 +213,7 @@ desc = "A pie containing sweet sweet love... or apple." icon_state = "applepie" filling_color = "#e0edc5" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("sweetness" = 2, "apple" = 2, "pie" = 2) nutriment_amt = 4 bitesize = 3 @@ -223,7 +223,7 @@ desc = "Taste so good, make a grown man cry." icon_state = "cherrypie" filling_color = "#ff525a" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("sweetness" = 2, "cherry" = 2, "pie" = 2) nutriment_amt = 4 bitesize = 3 @@ -233,7 +233,7 @@ desc = "A true prophecy in each cookie!" icon_state = "fortune_cookie" filling_color = "#e8e79e" - center_of_mass = @"{'x':15,'y':14}" + center_of_mass = @'{"x":15,"y":14}' nutriment_desc = list("fortune cookie" = 2) nutriment_amt = 3 bitesize = 2 \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/bread.dm b/code/modules/reagents/reagent_containers/food/bread.dm index e5c4f56f02f..57f43d97ac0 100644 --- a/code/modules/reagents/reagent_containers/food/bread.dm +++ b/code/modules/reagents/reagent_containers/food/bread.dm @@ -6,9 +6,9 @@ name = "sandwich" desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce!" icon_state = "sandwich" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#d9be29" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' nutriment_desc = list("bread" = 3, "cheese" = 3) nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/bread @@ -16,15 +16,15 @@ /obj/item/chems/food/sandwich/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/toastedsandwich name = "toasted sandwich" desc = "Now if you only had a pepper bar." icon_state = "toastedsandwich" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#d9be29" - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' nutriment_desc = list("toasted bread" = 3, "cheese" = 3) nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/bread @@ -32,14 +32,14 @@ /obj/item/chems/food/toastedsandwich/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/solid/carbon, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/solid/carbon, 2) /obj/item/chems/food/grilledcheese name = "grilled cheese sandwich" desc = "Goes great with Tomato soup!" icon_state = "toastedsandwich" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#d9be29" nutriment_desc = list("toasted bread" = 3, "cheese" = 3) nutriment_amt = 3 @@ -48,14 +48,14 @@ /obj/item/chems/food/grilledcheese/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/baguette name = "baguette" desc = "Good for pretend sword fights." icon_state = "baguette" filling_color = "#e3d796" - center_of_mass = @"{'x':18,'y':12}" + center_of_mass = @'{"x":18,"y":12}' nutriment_desc = list("long bread" = 6) nutriment_amt = 6 bitesize = 3 @@ -63,16 +63,16 @@ /obj/item/chems/food/baguette/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/solid/blackpepper, 1) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/jelliedtoast name = "jellied toast" desc = "A slice of bread covered with delicious jam." icon_state = "jellytoast" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#b572ab" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("toasted bread" = 2) nutriment_amt = 1 bitesize = 3 @@ -80,15 +80,15 @@ /obj/item/chems/food/jelliedtoast/cherry/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/cherryjelly, 5) + add_to_reagents(/decl/material/liquid/nutriment/cherryjelly, 5) /obj/item/chems/food/jellysandwich name = "jelly sandwich" desc = "You wish you had some peanut butter to go with this..." icon_state = "jellysandwich" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#9e3a78" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("bread" = 2) nutriment_amt = 2 bitesize = 3 @@ -96,14 +96,14 @@ /obj/item/chems/food/jellysandwich/cherry/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/cherryjelly, 5) + add_to_reagents(/decl/material/liquid/nutriment/cherryjelly, 5) /obj/item/chems/food/twobread name = "\improper Two Bread" desc = "It is very bitter and winy." icon_state = "twobread" filling_color = "#dbcc9a" - center_of_mass = @"{'x':15,'y':12}" + center_of_mass = @'{"x":15,"y":12}' nutriment_desc = list("sourness" = 2, "bread" = 2) nutriment_amt = 2 bitesize = 3 @@ -114,7 +114,7 @@ desc = "Is such a thing even possible?" icon_state = "threebread" filling_color = "#dbcc9a" - center_of_mass = @"{'x':15,'y':12}" + center_of_mass = @'{"x":15,"y":12}' nutriment_desc = list("sourness" = 2, "bread" = 3) nutriment_amt = 3 bitesize = 4 @@ -126,7 +126,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "flatbread" bitesize = 2 - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' nutriment_desc = list("bread" = 3) nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/bread \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/burgers.dm b/code/modules/reagents/reagent_containers/food/burgers.dm index b201568cc67..031ee9f7daf 100644 --- a/code/modules/reagents/reagent_containers/food/burgers.dm +++ b/code/modules/reagents/reagent_containers/food/burgers.dm @@ -7,21 +7,21 @@ desc = "A strange looking burger. It looks almost sentient." icon_state = "brainburger" filling_color = "#f2b6ea" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' bitesize = 2 material = /decl/material/solid/organic/meat /obj/item/chems/food/brainburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/neuroannealer, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/neuroannealer, 6) /obj/item/chems/food/ghostburger name = "ghost burger" desc = "Spooky! It doesn't look very filling." icon_state = "ghostburger" filling_color = "#fff2ff" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("buns" = 3, "spookiness" = 3) nutriment_amt = 2 bitesize = 2 @@ -35,24 +35,24 @@ name = "-burger" desc = "A bloody burger." icon_state = "hburger" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' bitesize = 2 /obj/item/chems/food/human/burger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/cheeseburger name = "cheeseburger" desc = "The cheese adds a good flavor." icon_state = "cheeseburger" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("cheese" = 2, "bun" = 2) nutriment_amt = 2 /obj/item/chems/food/cheeseburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/burger name = "burger" @@ -60,14 +60,14 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "burger" filling_color = "#d63c3c" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("bun" = 2) nutriment_amt = 3 bitesize = 2 /obj/item/chems/food/burger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/hamburger name = "hamburger" @@ -75,33 +75,33 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "hamburger" filling_color = "#d63c3c" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("bun" = 2) nutriment_amt = 3 bitesize = 2 /obj/item/chems/food/hamburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) /obj/item/chems/food/fishburger name = "fish sandwich" desc = "Almost like a carp is yelling somewhere... Give me back that fillet -o- carp, give me that carp." icon_state = "fishburger" filling_color = "#ffdefe" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' bitesize = 3 /obj/item/chems/food/fishburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/tofuburger name = "tofu burger" desc = "What.. is that meat?" icon_state = "tofuburger" filling_color = "#fffee0" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("bun" = 2, "pseudo-soy meat" = 3) nutriment_amt = 6 bitesize = 2 @@ -111,7 +111,7 @@ desc = "The lettuce is the only organic component. Beep." icon_state = "roburger" filling_color = COLOR_GRAY80 - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("bun" = 2, "metal" = 3) nutriment_amt = 2 bitesize = 2 @@ -119,7 +119,7 @@ /obj/item/chems/food/roburger/populate_reagents() . = ..() if(prob(5)) - reagents.add_reagent(/decl/material/liquid/nanitefluid, 2) + add_to_reagents(/decl/material/liquid/nanitefluid, 2) /obj/item/chems/food/roburgerbig name = "roburger" @@ -127,31 +127,31 @@ icon_state = "roburger" filling_color = COLOR_GRAY80 volume = 100 - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' bitesize = 0.1 /obj/item/chems/food/roburgerbig/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nanitefluid, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/nanitefluid, reagents.maximum_volume) /obj/item/chems/food/xenoburger name = "xenoburger" desc = "Smells caustic. Tastes like heresy." icon_state = "xburger" filling_color = "#43de18" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' bitesize = 2 /obj/item/chems/food/xenoburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) /obj/item/chems/food/clownburger name = "clown burger" desc = "This tastes funny..." icon_state = "clownburger" filling_color = "#ff00ff" - center_of_mass = @"{'x':17,'y':12}" + center_of_mass = @'{"x":17,"y":12}' nutriment_desc = list("bun" = 2, "clown shoe" = 3) nutriment_amt = 6 bitesize = 2 @@ -161,7 +161,7 @@ desc = "Its taste defies language." icon_state = "mimeburger" filling_color = "#ffffff" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("bun" = 2, "mime paint" = 3) nutriment_amt = 6 bitesize = 2 @@ -180,42 +180,42 @@ desc = "Forget the Luna Burger! THIS is the future!" icon_state = "bigbiteburger" filling_color = "#e3d681" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("buns" = 4) nutriment_amt = 4 bitesize = 3 /obj/item/chems/food/bigbiteburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/jellyburger name = "jelly burger" desc = "Culinary delight..?" icon_state = "jellyburger" filling_color = "#b572ab" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("buns" = 5) nutriment_amt = 5 bitesize = 2 /obj/item/chems/food/jellyburger/cherry/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/cherryjelly, 5) + add_to_reagents(/decl/material/liquid/nutriment/cherryjelly, 5) /obj/item/chems/food/superbiteburger name = "super bite burger" desc = "This is a mountain of a burger. FOOD!" icon_state = "superbiteburger" filling_color = "#cca26a" - center_of_mass = @"{'x':16,'y':3}" + center_of_mass = @'{"x":16,"y":3}' nutriment_desc = list("buns" = 25) nutriment_amt = 25 bitesize = 10 /obj/item/chems/food/superbiteburger/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 25) + add_to_reagents(/decl/material/liquid/nutriment/protein, 25) // I am not creating another file just for hot dogs. @@ -224,22 +224,22 @@ desc = "Unrelated to dogs, maybe." icon_state = "hotdog" bitesize = 2 - center_of_mass = @"{'x':16,'y':17}" + center_of_mass = @'{"x":16,"y":17}' nutriment_type = /decl/material/liquid/nutriment/bread material = /decl/material/solid/organic/meat /obj/item/chems/food/hotdog/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/classichotdog name = "classic hotdog" desc = "Going literal." icon_state = "hotcorgi" bitesize = 6 - center_of_mass = @"{'x':16,'y':17}" + center_of_mass = @'{"x":16,"y":17}' material = /decl/material/solid/organic/meat /obj/item/chems/food/classichotdog/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 16) + add_to_reagents(/decl/material/liquid/nutriment/protein, 16) diff --git a/code/modules/reagents/reagent_containers/food/can_edibility.dm b/code/modules/reagents/reagent_containers/food/can_edibility.dm new file mode 100644 index 00000000000..4a1742cb5b4 --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/can_edibility.dm @@ -0,0 +1,5 @@ +/obj/item/chems/food/can/handle_eaten_by_mob(mob/user, mob/target) + if(!ATOM_IS_OPEN_CONTAINER(src)) + to_chat(user, SPAN_NOTICE("You need to open \the [src] first!")) + return EATEN_UNABLE + return ..() diff --git a/code/modules/reagents/reagent_containers/food/canned.dm b/code/modules/reagents/reagent_containers/food/canned.dm index 2bb9e7693f2..2c302892cd4 100644 --- a/code/modules/reagents/reagent_containers/food/canned.dm +++ b/code/modules/reagents/reagent_containers/food/canned.dm @@ -6,7 +6,7 @@ /obj/item/chems/food/can name = "empty can" icon = 'icons/obj/food_canned.dmi' - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' atom_flags = 0 bitesize = 3 @@ -28,22 +28,6 @@ atom_flags |= ATOM_FLAG_OPEN_CONTAINER sealed = FALSE -/obj/item/chems/food/can/attack(mob/M, mob/user, def_zone) - if(force && !(obj_flags & ITEM_FLAG_NO_BLUDGEON) && user.a_intent == I_HURT) - return ..() - - if(standard_feed_mob(user, M)) - update_icon(src) - return TRUE - - return FALSE - -/obj/item/chems/food/can/standard_feed_mob(mob/user, mob/target) - if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, SPAN_NOTICE("You need to open \the [src] first!")) - return TRUE - return ..() - /obj/item/chems/food/can/attack_self(mob/user) if(!ATOM_IS_OPEN_CONTAINER(src) && !open_complexity) to_chat(user, SPAN_NOTICE("You unseal \the [src] with a crack of metal.")) @@ -88,7 +72,7 @@ /obj/item/chems/food/can/beef/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 12) + add_to_reagents(/decl/material/liquid/nutriment/protein, 12) /obj/item/chems/food/can/beans name = "baked beans" @@ -110,10 +94,7 @@ /obj/item/chems/food/can/tomato/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 12) - -/obj/item/chems/food/can/tomato/feed_sound(var/mob/user) - playsound(user, 'sound/items/drink.ogg', rand(10, 50), 1) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 12) /obj/item/chems/food/can/spinach name = "spinach" @@ -126,10 +107,10 @@ /obj/item/chems/food/can/spinach/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment, 5) - reagents.add_reagent(/decl/material/liquid/adrenaline, 5) - reagents.add_reagent(/decl/material/liquid/amphetamines, 5) - reagents.add_reagent(/decl/material/solid/metal/iron, 5) + add_to_reagents(/decl/material/liquid/nutriment, 5) + add_to_reagents(/decl/material/liquid/adrenaline, 5) + add_to_reagents(/decl/material/liquid/amphetamines, 5) + add_to_reagents(/decl/material/solid/metal/iron, 5) //Vending Machine Foods should go here. @@ -153,8 +134,8 @@ /obj/item/chems/food/can/caviar/true/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/liquid/carpotoxin, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/carpotoxin, 1) /obj/item/knife/opener name = "can-opener" diff --git a/code/modules/reagents/reagent_containers/food/dough.dm b/code/modules/reagents/reagent_containers/food/dough.dm index aae9bd46371..4e28901f630 100644 --- a/code/modules/reagents/reagent_containers/food/dough.dm +++ b/code/modules/reagents/reagent_containers/food/dough.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "dough" bitesize = 2 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("dough" = 3) nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/bread @@ -25,12 +25,12 @@ icon_state = "flat dough" slice_path = /obj/item/chems/food/doughslice slices_num = 3 - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' /obj/item/chems/food/sliceable/flatdough/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) - reagents.add_reagent(/decl/material/liquid/nutriment, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/liquid/nutriment, 3) /obj/item/chems/food/doughslice name = "dough slice" @@ -40,7 +40,7 @@ slice_path = /obj/item/chems/food/spagetti slices_num = 1 bitesize = 2 - center_of_mass = @"{'x':17,'y':19}" + center_of_mass = @'{"x":17,"y":19}' nutriment_desc = list("dough" = 1) nutriment_amt = 1 nutriment_type = /decl/material/liquid/nutriment/bread @@ -51,7 +51,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "bun" bitesize = 2 - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' nutriment_desc = list("bun" = 4) nutriment_amt = 4 nutriment_type = /decl/material/liquid/nutriment/bread @@ -76,7 +76,7 @@ desc = "A small bread monkey fashioned from two burger buns." icon_state = "bunbun" bitesize = 2 - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("bun" = 8) nutriment_amt = 8 nutriment_type = /decl/material/liquid/nutriment/bread \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/eggs.dm b/code/modules/reagents/reagent_containers/food/eggs.dm index 9ab1eccd49a..4fa7e499124 100644 --- a/code/modules/reagents/reagent_containers/food/eggs.dm +++ b/code/modules/reagents/reagent_containers/food/eggs.dm @@ -5,10 +5,11 @@ /obj/item/chems/food/egg name = "egg" desc = "An egg!" - icon_state = "egg" + icon = 'icons/obj/food/eggs/egg.dmi' + icon_state = ICON_STATE_WORLD filling_color = "#fdffd1" volume = 10 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/protein/egg @@ -45,71 +46,75 @@ return ..() /obj/item/chems/food/egg/blue - icon_state = "egg-blue" + icon = 'icons/obj/food/eggs/egg_blue.dmi' /obj/item/chems/food/egg/green - icon_state = "egg-green" + icon = 'icons/obj/food/eggs/egg_green.dmi' /obj/item/chems/food/egg/mime - icon_state = "egg-mime" + icon = 'icons/obj/food/eggs/egg_mime.dmi' /obj/item/chems/food/egg/orange - icon_state = "egg-orange" + icon = 'icons/obj/food/eggs/egg_orange.dmi' /obj/item/chems/food/egg/purple - icon_state = "egg-purple" + icon = 'icons/obj/food/eggs/egg_purple.dmi' /obj/item/chems/food/egg/rainbow - icon_state = "egg-rainbow" + icon = 'icons/obj/food/eggs/egg_rainbow.dmi' /obj/item/chems/food/egg/red - icon_state = "egg-red" + icon = 'icons/obj/food/eggs/egg_red.dmi' /obj/item/chems/food/egg/yellow - icon_state = "egg-yellow" + icon = 'icons/obj/food/eggs/egg_yellow.dmi' + +/obj/item/chems/food/egg/lizard + icon = 'icons/obj/food/eggs/egg_lizard.dmi' /obj/item/chems/food/egg/lizard/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 5) if(prob(30)) //extra nutriment - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) /obj/item/chems/food/friedegg name = "fried egg" desc = "A fried egg, with a touch of salt and pepper." icon_state = "friedegg" filling_color = "#ffdf78" - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' bitesize = 1 /obj/item/chems/food/friedegg/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/solid/blackpepper, 1) /obj/item/chems/food/boiledegg name = "boiled egg" desc = "A hard boiled egg." - icon_state = "egg" + icon = 'icons/obj/food/eggs/egg.dmi' + icon_state = ICON_STATE_WORLD filling_color = "#ffffff" /obj/item/chems/food/boiledegg/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/omelette name = "cheese omelette" desc = "Omelette with cheese!" icon_state = "omelette" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fff9a8" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 1 /obj/item/chems/food/omelette/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) /obj/item/chems/food/chawanmushi name = "chawanmushi" @@ -117,9 +122,9 @@ icon_state = "chawanmushi" trash = /obj/item/trash/snack_bowl filling_color = "#f0f2e4" - center_of_mass = @"{'x':17,'y':10}" + center_of_mass = @'{"x":17,"y":10}' bitesize = 1 - + /obj/item/chems/food/chawanmushi/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/fish.dm b/code/modules/reagents/reagent_containers/food/fish.dm index d5ef783e66c..94e55be5bcd 100644 --- a/code/modules/reagents/reagent_containers/food/fish.dm +++ b/code/modules/reagents/reagent_containers/food/fish.dm @@ -3,7 +3,7 @@ desc = "A fillet of fish." icon_state = "fishfillet" filling_color = "#ffdefe" - center_of_mass = @"{'x':17,'y':13}" + center_of_mass = @'{"x":17,"y":13}' bitesize = 6 nutriment_amt = 6 nutriment_type = /decl/material/liquid/nutriment/protein @@ -22,7 +22,7 @@ var/toxin_amt = REAGENT_VOLUME(reagents, /decl/material/liquid/carpotoxin) if(toxin_amt && !prob(user.skill_fail_chance(SKILL_COOKING, 100, SKILL_PROF))) - reagents.remove_reagent(/decl/material/liquid/carpotoxin, toxin_amt) + remove_from_reagents(/decl/material/liquid/carpotoxin, toxin_amt) user.visible_message("\The [user] slices \the [src] into thin strips.") var/transfer_amt = FLOOR(reagents.total_volume * 0.3) @@ -39,7 +39,7 @@ /obj/item/chems/food/fish/poison/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/carpotoxin, 6) + add_to_reagents(/decl/material/liquid/carpotoxin, 6) /obj/item/chems/food/fish/shark fish_type = "shark" diff --git a/code/modules/reagents/reagent_containers/food/fried.dm b/code/modules/reagents/reagent_containers/food/fried.dm index 2aca1e326e8..5bb26f441c7 100644 --- a/code/modules/reagents/reagent_containers/food/fried.dm +++ b/code/modules/reagents/reagent_containers/food/fried.dm @@ -8,9 +8,9 @@ name = "onion rings" desc = "Like circular fries but better." icon_state = "onionrings" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("fried onions" = 5) nutriment_amt = 5 bitesize = 2 @@ -19,9 +19,9 @@ name = "chips" desc = "Frenched potato, fried." icon_state = "fries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("fresh fries" = 4) nutriment_amt = 4 bitesize = 2 @@ -32,7 +32,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "rawsticks" bitesize = 2 - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' nutriment_desc = list("raw potato" = 3) nutriment_amt = 3 @@ -40,13 +40,13 @@ name = "cheesy fries" desc = "Fries. Covered in cheese. Duh." icon_state = "cheesyfries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("fresh fries" = 3, "cheese" = 3) nutriment_amt = 4 bitesize = 2 /obj/item/chems/food/cheesyfries/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) diff --git a/code/modules/reagents/reagent_containers/food/junkfood.dm b/code/modules/reagents/reagent_containers/food/junkfood.dm index 36365b10d56..59024e3e160 100644 --- a/code/modules/reagents/reagent_containers/food/junkfood.dm +++ b/code/modules/reagents/reagent_containers/food/junkfood.dm @@ -4,13 +4,13 @@ desc = "For when you desperately want meat and you don't care what kind. Has the same texture as old leather boots." trash = /obj/item/trash/sosjerky filling_color = "#631212" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' bitesize = 2 material = /decl/material/solid/organic/meat /obj/item/chems/food/sosjerky/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/no_raisin name = "raisins" @@ -18,7 +18,7 @@ desc = "Pouring water on these will not turn them back into grapes, unfortunately." trash = /obj/item/trash/raisins filling_color = "#343834" - center_of_mass = @"{'x':15,'y':4}" + center_of_mass = @'{"x":15,"y":4}' nutriment_desc = list("raisins" = 6) nutriment_amt = 6 @@ -27,12 +27,12 @@ icon_state = "space_twinkie" desc = "So full of preservatives, it's guaranteed to survive longer then you will." filling_color = "#ffe591" - center_of_mass = @"{'x':15,'y':11}" + center_of_mass = @'{"x":15,"y":11}' bitesize = 2 /obj/item/chems/food/spacetwinkie/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 4) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 4) /obj/item/chems/food/cheesiehonkers name = "cheese puffs" @@ -40,7 +40,7 @@ desc = "Bite sized cheese flavoured snacks that will leave your fingers coated in cheese dust." trash = /obj/item/trash/cheesie filling_color = "#ffa305" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("cheese" = 5, "chips" = 2) nutriment_amt = 4 bitesize = 2 @@ -50,7 +50,7 @@ icon_state = "syndi_cakes" desc = "Made using extremely unethical labour, ingredients and marketing methods." filling_color = "#ff5d05" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("sweetness" = 3, "cake" = 1) nutriment_amt = 4 trash = /obj/item/trash/syndi_cakes @@ -58,7 +58,7 @@ /obj/item/chems/food/syndicake/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/regenerator, 5) + add_to_reagents(/decl/material/liquid/regenerator, 5) //terran delights @@ -68,7 +68,7 @@ desc = "Pistachios. There is absolutely nothing remarkable about these." trash = /obj/item/trash/pistachios filling_color = "#825d26" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("nuts" = 1) nutriment_amt = 3 bitesize = 0.5 @@ -79,7 +79,7 @@ desc = "A favorite among birds." trash = /obj/item/trash/semki filling_color = "#68645d" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("sunflower seeds" = 1) nutriment_amt = 6 bitesize = 0.5 @@ -90,14 +90,14 @@ desc = "Space cepholapod tentacles, carefully removed from the squid then dried into strips of delicious rubbery goodness!" trash = /obj/item/trash/squid filling_color = "#c0a9d7" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("fish" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 1 /obj/item/chems/food/squid/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/croutons name = "croutons" @@ -105,7 +105,7 @@ desc = "Fried bread cubes. Good in salad but I guess you can just eat them as is." trash = /obj/item/trash/croutons filling_color = "#c6b17f" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("bread" = 1, "salt" = 1) nutriment_amt = 3 bitesize = 1 @@ -117,14 +117,14 @@ desc = "Pig fat. Salted. Just as good as it sounds." trash = /obj/item/trash/salo filling_color = "#e0bcbc" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("fat" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 2 /obj/item/chems/food/salo/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) /obj/item/chems/food/driedfish name = "vobla" @@ -132,14 +132,14 @@ desc = "Dried salted beer snack fish." trash = /obj/item/trash/driedfish filling_color = "#c8a5bb" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("fish" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 1 /obj/item/chems/food/driedfish/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/liquidfood name = "\improper LiquidFood MRE" @@ -147,27 +147,27 @@ icon_state = "liquidfood" trash = /obj/item/trash/liquidfood filling_color = "#a8a8a8" - center_of_mass = @"{'x':16,'y':15}" + center_of_mass = @'{"x":16,"y":15}' nutriment_desc = list("chalk" = 6) nutriment_amt = 20 bitesize = 4 /obj/item/chems/food/liquidfood/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/solid/metal/iron, 3) + add_to_reagents(/decl/material/solid/metal/iron, 3) /obj/item/chems/food/meatcube name = "cubed meat" desc = "Fried, salted lean meat compressed into a cube. Not very appetizing." icon_state = "meatcube" filling_color = "#7a3d11" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 3 material = /decl/material/solid/organic/meat /obj/item/chems/food/meatcube/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 15) + add_to_reagents(/decl/material/liquid/nutriment/protein, 15) /obj/item/chems/food/tastybread name = "bread tube" @@ -175,7 +175,7 @@ icon_state = "tastybread" trash = /obj/item/trash/tastybread filling_color = "#a66829" - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' nutriment_desc = list("bread" = 2, "sweetness" = 3) nutriment_amt = 6 nutriment_type = /decl/material/liquid/nutriment/bread @@ -187,14 +187,14 @@ icon_state = "candy" trash = /obj/item/trash/candy filling_color = "#7d5f46" - center_of_mass = @"{'x':15,'y':15}" + center_of_mass = @'{"x":15,"y":15}' nutriment_amt = 1 nutriment_desc = list("candy" = 1) bitesize = 2 /obj/item/chems/food/candy/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 3) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 3) /obj/item/chems/food/candy/proteinbar name = "protein bar" @@ -205,9 +205,9 @@ /obj/item/chems/food/candy/proteinbar/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment, 9) - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 4) + add_to_reagents(/decl/material/liquid/nutriment, 9) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 4) /obj/item/chems/food/candy/donor name = "donor candy" @@ -218,23 +218,23 @@ /obj/item/chems/food/candy/donor/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment, 10) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 3) + add_to_reagents(/decl/material/liquid/nutriment, 10) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 3) /obj/item/chems/food/candy_corn name = "candy corn" desc = "It's a handful of candy corn. Not actually candied corn." icon_state = "candy_corn" filling_color = "#fffcb0" - center_of_mass = @"{'x':14,'y':10}" + center_of_mass = @'{"x":14,"y":10}' nutriment_amt = 4 nutriment_desc = list("candy corn" = 4) bitesize = 2 /obj/item/chems/food/candy_corn/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment, 4) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 2) + add_to_reagents(/decl/material/liquid/nutriment, 4) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 2) /obj/item/chems/food/chips name = "chips" @@ -242,7 +242,7 @@ icon_state = "chips" trash = /obj/item/trash/chips filling_color = "#e8c31e" - center_of_mass = @"{'x':15,'y':15}" + center_of_mass = @'{"x":15,"y":15}' nutriment_amt = 3 nutriment_desc = list("salt" = 1, "chips" = 2) bitesize = 1 @@ -253,7 +253,7 @@ desc = "COOKIE!!!" icon_state = "cookie" filling_color = "#dbc94f" - center_of_mass = @"{'x':17,'y':18}" + center_of_mass = @'{"x":17,"y":18}' nutriment_amt = 5 nutriment_desc = list("sweetness" = 3, "cookie" = 2) w_class = ITEM_SIZE_TINY @@ -265,53 +265,51 @@ desc = "Such sweet, fattening food." icon_state = "chocolatebar" filling_color = "#7d5f46" - center_of_mass = @"{'x':15,'y':15}" + center_of_mass = @'{"x":15,"y":15}' nutriment_amt = 2 nutriment_desc = list("chocolate" = 5) bitesize = 2 /obj/item/chems/food/chocolatebar/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/coco, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 2) + add_to_reagents(/decl/material/liquid/nutriment/coco, 2) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 2) /obj/item/chems/food/chocolateegg name = "chocolate egg" desc = "Such sweet, fattening food." icon_state = "chocolateegg" filling_color = "#7d5f46" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_amt = 3 nutriment_desc = list("chocolate" = 5) bitesize = 2 /obj/item/chems/food/chocolateegg/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/coco, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 2) + add_to_reagents(/decl/material/liquid/nutriment/coco, 2) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 2) /obj/item/chems/food/donut name = "donut" desc = "Goes great with Robust Coffee." - icon_state = "donut1" + icon = 'icons/obj/food/donuts/donut.dmi' + icon_state = ICON_STATE_WORLD filling_color = "#d9c386" - center_of_mass = @"{'x':19,'y':16}" + center_of_mass = @'{"x":19,"y":16}' nutriment_desc = list("sweetness", "donut") nutriment_amt = 3 bitesize = 3 nutriment_type = /decl/material/liquid/nutriment/bread var/random_frosting = TRUE - var/overlay_state = "box-donut1" - var/donut_state = "donut" + var/iced_icon = 'icons/obj/food/donuts/donut_iced.dmi' -//FIXME: Again a really weird way of handling that /obj/item/chems/food/donut/populate_reagents() . = ..() - if(random_frosting && prob(30)) - icon_state = "[donut_state]2" - overlay_state = "box-donut2" + if(iced_icon && random_frosting && prob(30) && icon != iced_icon) + icon = iced_icon SetName("frosted [name]") - reagents.add_reagent(/decl/material/liquid/nutriment/sprinkles, 2) + add_to_reagents(/decl/material/liquid/nutriment/sprinkles, 2) /obj/item/chems/food/donut/unfrosted random_frosting = FALSE @@ -339,23 +337,23 @@ /obj/item/chems/food/donut/chaos/populate_reagents() . = ..() - reagents.add_reagent(pick(get_random_fillings()), 3) + add_to_reagents(pick(get_random_fillings()), 3) /obj/item/chems/food/donut/jelly name = "jelly donut" desc = "You jelly?" - icon_state = "jdonut1" + icon = 'icons/obj/food/donuts/donut_jelly.dmi' + iced_icon = 'icons/obj/food/donuts/donut_jelly_iced.dmi' filling_color = "#ed1169" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_amt = 3 bitesize = 5 nutriment_type = /decl/material/liquid/nutriment/bread - donut_state = "jdonut" var/jelly_type = /decl/material/liquid/nutriment/cherryjelly /obj/item/chems/food/donut/jelly/populate_reagents() . = ..() - reagents.add_reagent(jelly_type, 5) + add_to_reagents(jelly_type, 5) /obj/item/chems/food/donut/jelly/berry jelly_type = /decl/material/liquid/drink/juice/berry @@ -367,7 +365,7 @@ desc = "Now with 20% less lawsuit enabling regolith!" trash = /obj/item/trash/cakewrap filling_color = "#ffffff" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("sweet" = 4, "vanilla" = 1) nutriment_amt = 5 bitesize = 2 @@ -395,7 +393,7 @@ desc = "Contains over 9000% of your daily recommended intake of salt." trash = /obj/item/trash/tidegobs filling_color = "#2556b0" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("salt" = 4, "ocean" = 1, "seagull" = 1) nutriment_amt = 5 bitesize = 2 @@ -406,7 +404,7 @@ desc = "A day ration of salt, styrofoam and possibly sawdust." trash = /obj/item/trash/saturno filling_color = "#dca319" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("salt" = 4, "peanut" = 2, "wood?" = 1) nutriment_amt = 5 bitesize = 2 @@ -417,7 +415,7 @@ desc = "Some kind of gel, maybe?" trash = /obj/item/trash/jupiter filling_color = "#dc1919" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("jelly?" = 5) nutriment_amt = 5 bitesize = 2 @@ -428,7 +426,7 @@ desc = "Baseless tasteless nutrient rods to get you through the day. Now even less rash inducing!" trash = /obj/item/trash/pluto filling_color = "#ffffff" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("chalk" = 4, "sadness" = 1) nutriment_amt = 5 bitesize = 2 @@ -439,7 +437,7 @@ desc = "A steaming self-heated bowl of sweet eggs and taters!" trash = /obj/item/trash/mars filling_color = "#d2c63f" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("eggs" = 4, "potato" = 4, "mustard" = 2) nutriment_amt = 8 bitesize = 2 @@ -450,7 +448,7 @@ desc = "Hot takes on hot cakes, a timeless classic now finally fit for human consumption!" trash = /obj/item/trash/venus filling_color = "#d2c63f" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("heat" = 4, "burning" = 1) nutriment_amt = 5 bitesize = 2 @@ -458,7 +456,7 @@ /obj/item/chems/food/venus/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/capsaicin, 5) + add_to_reagents(/decl/material/liquid/capsaicin, 5) /obj/item/chems/food/oort name = "\improper Cloud Rocks" @@ -466,14 +464,14 @@ desc = "Pop rocks. The new formula guarantees fewer shrapnel induced oral injuries." trash = /obj/item/trash/oort filling_color = "#3f7dd2" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("fizz" = 3, "sweet?" = 1, "shrapnel" = 1) nutriment_amt = 5 bitesize = 2 /obj/item/chems/food/oort/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/frostoil, 5) + add_to_reagents(/decl/material/liquid/frostoil, 5) //weebo vend! So japanese it hurts @@ -504,7 +502,7 @@ /obj/item/chems/food/weebonuts/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/capsaicin, 1) + add_to_reagents(/decl/material/liquid/capsaicin, 1) /obj/item/chems/food/chocobanana name = "choco banana" @@ -517,7 +515,7 @@ /obj/item/chems/food/chocobanana/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sprinkles, 10) + add_to_reagents(/decl/material/liquid/nutriment/sprinkles, 10) /obj/item/chems/food/dango name = "dango" @@ -545,7 +543,7 @@ return has_been_heated = 1 user.visible_message("[user] crushes \the [src] package.", "You crush \the [src] package and feel a comfortable heat build up.") - addtimer(CALLBACK(src, .proc/heat, weakref(user)), 20 SECONDS) + addtimer(CALLBACK(src, PROC_REF(heat), weakref(user)), 20 SECONDS) /obj/item/chems/food/donkpocket/sinpocket/heat(weakref/message_to) ..() @@ -559,7 +557,7 @@ desc = "The food of choice for the seasoned traitor." icon_state = "donkpocket" filling_color = "#dedeab" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("heartiness" = 1, "dough" = 2) nutriment_amt = 2 var/warm = 0 @@ -567,17 +565,17 @@ /obj/item/chems/food/donkpocket/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/donkpocket/proc/heat() if(warm) return warm = 1 for(var/reagent in heated_reagents) - reagents.add_reagent(reagent, heated_reagents[reagent]) + add_to_reagents(reagent, heated_reagents[reagent]) bitesize = 6 SetName("warm donk-pocket") - addtimer(CALLBACK(src, .proc/cool), 7 MINUTES) + addtimer(CALLBACK(src, PROC_REF(cool)), 7 MINUTES) /obj/item/chems/food/donkpocket/proc/cool() if(!warm) diff --git a/code/modules/reagents/reagent_containers/food/lunch.dm b/code/modules/reagents/reagent_containers/food/lunch.dm index 2d660fbdab1..0a3685c8cf7 100644 --- a/code/modules/reagents/reagent_containers/food/lunch.dm +++ b/code/modules/reagents/reagent_containers/food/lunch.dm @@ -3,10 +3,10 @@ var/global/list/lunchables_lunches_ = list( /obj/item/chems/food/slice/meatbread/filled, /obj/item/chems/food/slice/tofubread/filled, /obj/item/chems/food/slice/creamcheesebread/filled, - /obj/item/chems/food/slice/margherita/filled, - /obj/item/chems/food/slice/meatpizza/filled, - /obj/item/chems/food/slice/mushroompizza/filled, - /obj/item/chems/food/slice/vegetablepizza/filled, + /obj/item/chems/food/slice/pizza/margherita/filled, + /obj/item/chems/food/slice/pizza/meat/filled, + /obj/item/chems/food/slice/pizza/mushroom/filled, + /obj/item/chems/food/slice/pizza/vegetable/filled, /obj/item/chems/food/tastybread, /obj/item/chems/food/liquidfood, /obj/item/chems/food/jellysandwich/cherry, diff --git a/code/modules/reagents/reagent_containers/food/meat/cubes.dm b/code/modules/reagents/reagent_containers/food/meat/cubes.dm index de8ee6d0955..08195ee5783 100644 --- a/code/modules/reagents/reagent_containers/food/meat/cubes.dm +++ b/code/modules/reagents/reagent_containers/food/meat/cubes.dm @@ -7,15 +7,18 @@ icon_state = "monkeycube" bitesize = 12 filling_color = "#adac7f" - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' var/growing = FALSE var/monkey_type = /mob/living/carbon/human/monkey var/wrapper_type +/obj/item/chems/food/monkeycube/get_food_consumption_method(mob/eater) + return EATING_METHOD_EAT + /obj/item/chems/food/monkeycube/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/monkeycube/get_single_monetary_worth() . = (monkey_type ? round(atom_info_repository.get_combined_worth_for(monkey_type) * 1.25) : 5) @@ -26,12 +29,12 @@ if(wrapper_type) Unwrap(user) -/obj/item/chems/food/monkeycube/proc/Expand() +/obj/item/chems/food/monkeycube/proc/Expand(force_loc) if(!growing) growing = TRUE - src.visible_message(SPAN_NOTICE("\The [src] expands!")) + visible_message(SPAN_NOTICE("\The [src] expands!")) var/mob/monkey = new monkey_type - monkey.dropInto(src.loc) + monkey.dropInto(force_loc || loc) qdel(src) /obj/item/chems/food/monkeycube/proc/Unwrap(var/mob/user) @@ -42,13 +45,16 @@ user.put_in_hands(new wrapper_type(get_turf(user))) wrapper_type = null -/obj/item/chems/food/monkeycube/On_Consume(var/mob/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.visible_message("A screeching creature bursts out of [M]'s chest!") - var/obj/item/organ/external/organ = GET_EXTERNAL_ORGAN(H, BP_CHEST) - organ.take_external_damage(50, 0, 0, "Animal escaping the ribcage") - Expand() +/obj/item/chems/food/monkeycube/handle_eaten_by_mob(mob/user, mob/target) + . = ..() + if(. == EATEN_SUCCESS) + target = target || user + if(target) + target.visible_message(SPAN_DANGER("A screeching creature bursts out of \the [target]!")) + var/obj/item/organ/external/organ = GET_EXTERNAL_ORGAN(target, BP_CHEST) + if(organ) + organ.take_external_damage(50, 0, 0, "Animal escaping the ribcage") + Expand(get_turf(target)) /obj/item/chems/food/monkeycube/on_reagent_change() ..() diff --git a/code/modules/reagents/reagent_containers/food/meat/fish.dm b/code/modules/reagents/reagent_containers/food/meat/fish.dm index abec8e0faf1..d5c9118b9e3 100644 --- a/code/modules/reagents/reagent_containers/food/meat/fish.dm +++ b/code/modules/reagents/reagent_containers/food/meat/fish.dm @@ -3,39 +3,39 @@ desc = "A finger of fish." icon_state = "fishfingers" filling_color = "#ffdefe" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 3 /obj/item/chems/food/fishfingers/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/cubancarp name = "\improper Cuban Carp" desc = "A sandwich that burns your tongue and then leaves it numb!" icon_state = "cubancarp" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#e9adff" - center_of_mass = @"{'x':12,'y':5}" + center_of_mass = @'{"x":12,"y":5}' nutriment_desc = list("toasted bread" = 3) nutriment_amt = 3 bitesize = 3 /obj/item/chems/food/cubancarp/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/liquid/capsaicin, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/capsaicin, 3) /obj/item/chems/food/fishandchips name = "fish and chips" desc = "Best enjoyed wrapped in a newspaper on a cold wet day." icon_state = "fishandchips" filling_color = "#e3d796" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' nutriment_desc = list("salt" = 1, "chips" = 2, "fish" = 2) nutriment_amt = 3 bitesize = 3 /obj/item/chems/food/fishandchips/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/meat/meat.dm b/code/modules/reagents/reagent_containers/food/meat/meat.dm index 79f809cd11e..52a65828d82 100644 --- a/code/modules/reagents/reagent_containers/food/meat/meat.dm +++ b/code/modules/reagents/reagent_containers/food/meat/meat.dm @@ -5,12 +5,12 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "rawcutlet" bitesize = 1 - center_of_mass = @"{'x':17,'y':20}" + center_of_mass = @'{"x":17,"y":20}' material = /decl/material/solid/organic/meat /obj/item/chems/food/rawcutlet/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) /obj/item/chems/food/cutlet name = "cutlet" @@ -18,12 +18,12 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "cutlet" bitesize = 2 - center_of_mass = @"{'x':17,'y':20}" + center_of_mass = @'{"x":17,"y":20}' material = /decl/material/solid/organic/meat /obj/item/chems/food/cutlet/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/rawmeatball name = "raw meatball" @@ -31,25 +31,25 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "rawmeatball" bitesize = 2 - center_of_mass = @"{'x':16,'y':15}" + center_of_mass = @'{"x":16,"y":15}' material = /decl/material/solid/organic/meat /obj/item/chems/food/rawmeatball/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/meatball name = "meatball" desc = "A great meal all round." icon_state = "meatball" filling_color = "#db0000" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 2 material = /decl/material/solid/organic/meat /obj/item/chems/food/meatball/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/plainsteak name = "plain steak" @@ -59,29 +59,29 @@ slice_path = /obj/item/chems/food/cutlet slices_num = 3 filling_color = "#7a3d11" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 3 material = /decl/material/solid/organic/meat /obj/item/chems/food/plainsteak/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/meatsteak name = "meat steak" desc = "A piece of hot spicy meat." icon_state = "meatstake" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#7a3d11" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 3 material = /decl/material/solid/organic/meat /obj/item/chems/food/meatsteak/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/solid/blackpepper, 1) /obj/item/chems/food/meatsteak/synthetic name = "meaty steak" @@ -91,9 +91,9 @@ name = "loaded steak" desc = "A steak slathered in sauce with sauteed onions and mushrooms." icon_state = "meatstake" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#7a3d11" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("onion" = 2, "mushroom" = 2) nutriment_amt = 4 bitesize = 3 @@ -101,15 +101,15 @@ /obj/item/chems/food/loadedsteak/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/garlicsauce, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/garlicsauce, 2) /obj/item/chems/food/tomatomeat name = "tomato slice" desc = "A slice from a huge tomato." icon_state = "tomatomeat" filling_color = "#db0000" - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' nutriment_amt = 3 nutriment_desc = list("raw" = 2, "tomato" = 3) bitesize = 6 @@ -119,27 +119,27 @@ desc = "A very manly slab of meat." icon_state = "bearmeat" filling_color = "#db0000" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' bitesize = 3 material = /decl/material/solid/organic/meat /obj/item/chems/food/bearmeat/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 12) - reagents.add_reagent(/decl/material/liquid/amphetamines, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 12) + add_to_reagents(/decl/material/liquid/amphetamines, 5) /obj/item/chems/food/spider name = "giant spider leg" desc = "An economical replacement for crab. In space! Would probably be a lot nicer cooked." icon_state = "spiderleg" filling_color = "#d5f5dc" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' bitesize = 3 material = /decl/material/solid/organic/meat /obj/item/chems/food/spider/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 9) + add_to_reagents(/decl/material/liquid/nutriment/protein, 9) /obj/item/chems/food/spider/cooked name = "boiled spider meat" @@ -152,14 +152,14 @@ desc = "A slab of green meat. Smells like acid." icon_state = "xenomeat" filling_color = "#43de18" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' bitesize = 6 material = /decl/material/solid/organic/meat /obj/item/chems/food/xenomeat/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/acid/polyacid, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/acid/polyacid, 6) /obj/item/chems/food/sausage name = "sausage" @@ -167,26 +167,26 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "sausage" filling_color = "#db0000" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 2 material = /decl/material/solid/organic/meat /obj/item/chems/food/sausage/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/fatsausage name = "spiced sausage" desc = "A piece of mixed, long meat, with some bite to it." icon_state = "sausage" filling_color = "#db0000" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 2 material = /decl/material/solid/organic/meat /obj/item/chems/food/fatsausage/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) /obj/item/chems/food/organ name = "organ" @@ -194,13 +194,13 @@ icon = 'icons/obj/surgery.dmi' icon_state = "appendix" filling_color = "#e00d34" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 3 /obj/item/chems/food/organ/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, rand(3,5)) - reagents.add_reagent(/decl/material/liquid/bromide, rand(1,3)) //lolwat? + add_to_reagents(/decl/material/liquid/nutriment/protein, rand(3,5)) + add_to_reagents(/decl/material/liquid/bromide, rand(1,3)) //lolwat? /obj/item/chems/food/meatkabob name = "meat-kabob" @@ -208,9 +208,9 @@ desc = "Delicious meat, on a stick." trash = /obj/item/stack/material/rods filling_color = "#a85340" - center_of_mass = @"{'x':17,'y':15}" + center_of_mass = @'{"x":17,"y":15}' bitesize = 2 /obj/item/chems/food/meatkabob/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/meat/slabs.dm b/code/modules/reagents/reagent_containers/food/meat/slabs.dm index f7b078085d7..a933886b501 100644 --- a/code/modules/reagents/reagent_containers/food/meat/slabs.dm +++ b/code/modules/reagents/reagent_containers/food/meat/slabs.dm @@ -7,13 +7,13 @@ slices_num = 3 max_health = 180 filling_color = "#ff1c1c" - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' material = /decl/material/solid/organic/meat bitesize = 3 /obj/item/chems/food/meat/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 9) + add_to_reagents(/decl/material/liquid/nutriment/protein, 9) /obj/item/chems/food/meat/syntiflesh name = "synthetic meat" diff --git a/code/modules/reagents/reagent_containers/food/misc.dm b/code/modules/reagents/reagent_containers/food/misc.dm index 79781c1c3a9..5613bfa0db4 100644 --- a/code/modules/reagents/reagent_containers/food/misc.dm +++ b/code/modules/reagents/reagent_containers/food/misc.dm @@ -3,20 +3,20 @@ desc = "Someone should be demoted from chef for this." icon_state = "badrecipe" filling_color = "#211f02" - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' bitesize = 2 /obj/item/chems/food/badrecipe/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) - reagents.add_reagent(/decl/material/solid/carbon, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/solid/carbon, 3) /obj/item/chems/food/stuffing name = "stuffing" desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" icon_state = "stuffing" filling_color = "#c9ac83" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_amt = 3 nutriment_desc = list("dryness" = 2, "bread" = 2) bitesize = 1 @@ -27,7 +27,7 @@ icon_state = "popcorn" trash = /obj/item/trash/popcorn filling_color = "#fffad4" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("popcorn" = 3) nutriment_amt = 2 bitesize = 0.1 @@ -37,14 +37,14 @@ desc = "Totally baked." icon_state = "loadedbakedpotato" filling_color = "#9c7a68" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("baked potato" = 3) nutriment_amt = 3 bitesize = 2 /obj/item/chems/food/loadedbakedpotato/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/spacylibertyduff name = "party jelly" @@ -52,14 +52,14 @@ icon_state = "spacylibertyduff" trash = /obj/item/trash/snack_bowl filling_color = "#42b873" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("mushroom" = 5, "rainbow" = 1) nutriment_amt = 6 bitesize = 3 /obj/item/chems/food/spacylibertyduff/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/psychotropics, 6) + add_to_reagents(/decl/material/liquid/psychotropics, 6) /obj/item/chems/food/amanitajelly name = "amanita jelly" @@ -67,54 +67,54 @@ icon_state = "amanitajelly" trash = /obj/item/trash/snack_bowl filling_color = "#ed0758" - center_of_mass = @"{'x':16,'y':5}" + center_of_mass = @'{"x":16,"y":5}' nutriment_desc = list("jelly" = 3, "mushroom" = 3) nutriment_amt = 6 bitesize = 3 /obj/item/chems/food/amanitajelly/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/amatoxin, 6) - reagents.add_reagent(/decl/material/liquid/psychotropics, 3) + add_to_reagents(/decl/material/liquid/amatoxin, 6) + add_to_reagents(/decl/material/liquid/psychotropics, 3) /obj/item/chems/food/enchiladas name = "enchiladas" desc = "Not to be confused with an echidna, though I don't know how you would." icon_state = "enchiladas" - trash = /obj/item/trash/tray + plate = /obj/item/plate/tray filling_color = "#a36a1f" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("tortilla" = 3, "corn" = 3) nutriment_amt = 2 bitesize = 4 /obj/item/chems/food/enchiladas/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/capsaicin, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/capsaicin, 6) /obj/item/chems/food/monkeysdelight name = "monkey's delight" desc = "Eeee Eee!" icon_state = "monkeysdelight" - trash = /obj/item/trash/tray + plate = /obj/item/plate/tray filling_color = "#5c3c11" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' bitesize = 6 /obj/item/chems/food/monkeysdelight/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) - reagents.add_reagent(/decl/material/liquid/drink/juice/banana, 5) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/drink/juice/banana, 5) + add_to_reagents(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/candiedapple name = "candied apple" desc = "An apple coated in sugary sweetness." icon_state = "candiedapple" filling_color = "#f21873" - center_of_mass = @"{'x':15,'y':13}" + center_of_mass = @'{"x":15,"y":13}' nutriment_desc = list("apple" = 3, "caramel" = 3, "sweetness" = 2) nutriment_amt = 3 bitesize = 3 @@ -124,19 +124,19 @@ desc = "A tasty after-dinner mint. It is only wafer thin." icon_state = "mint" filling_color = "#f2f2f2" - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' bitesize = 1 /obj/item/chems/food/mint/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/syrup/mint, 1) + add_to_reagents(/decl/material/liquid/drink/syrup/mint, 1) /obj/item/chems/food/plumphelmetbiscuit name = "plump helmet biscuit" desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced wheat flour." icon_state = "phelmbiscuit" filling_color = "#cfb4c4" - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' nutriment_desc = list("mushroom" = 4) nutriment_amt = 5 bitesize = 2 @@ -146,30 +146,31 @@ if(prob(10)) name = "exceptional plump helmet biscuit" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" - reagents.add_reagent(/decl/material/liquid/nutriment, 3) - reagents.add_reagent(/decl/material/liquid/regenerator, 5) + add_to_reagents(/decl/material/liquid/nutriment, 3) + add_to_reagents(/decl/material/liquid/regenerator, 5) /obj/item/chems/food/appletart name = "golden apple streusel tart" desc = "A tasty dessert that won't make it through a metal detector." icon_state = "gappletart" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ffff00" - center_of_mass = @"{'x':16,'y':18}" + center_of_mass = @'{"x":16,"y":18}' nutriment_desc = list("apple" = 8) nutriment_amt = 8 bitesize = 3 /obj/item/chems/food/appletart/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/solid/metal/gold, 5) + add_to_reagents(/decl/material/solid/metal/gold, 5) /obj/item/chems/food/cracker name = "cracker" desc = "It's a salted cracker." - icon_state = "cracker" + icon = 'icons/obj/food/cracker.dmi' + icon_state = ICON_STATE_WORLD filling_color = "#f5deb8" - center_of_mass = @"{'x':17,'y':6}" + center_of_mass = @'{"x":17,"y":6}' nutriment_desc = list("salt" = 1, "cracker" = 2) w_class = ITEM_SIZE_TINY nutriment_amt = 1 @@ -184,35 +185,35 @@ desc = "Take a bite!" icon_state = "taco" bitesize = 3 - center_of_mass = @"{'x':21,'y':12}" + center_of_mass = @'{"x":21,"y":12}' nutriment_desc = list("cheese" = 2,"taco shell" = 2) nutriment_amt = 4 nutriment_type = /decl/material/liquid/nutriment/bread /obj/item/chems/food/taco/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/pelmen name = "meat pelmen" desc = "Raw meat appetizer." icon_state = "pelmen" filling_color = "#ffffff" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 2 /obj/item/chems/food/pelmen/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) /obj/item/chems/food/pelmeni_boiled name = "boiled pelmeni" desc = "A dish consisting of boiled pieces of meat wrapped in dough. Delicious!" icon_state = "pelmeni_boiled" filling_color = "#ffffff" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' bitesize = 2 /obj/item/chems/food/pelmeni_boiled/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 30) + add_to_reagents(/decl/material/liquid/nutriment/protein, 30) diff --git a/code/modules/reagents/reagent_containers/food/pasta.dm b/code/modules/reagents/reagent_containers/food/pasta.dm index 97f839d2db3..572d3fd02ee 100644 --- a/code/modules/reagents/reagent_containers/food/pasta.dm +++ b/code/modules/reagents/reagent_containers/food/pasta.dm @@ -7,7 +7,7 @@ desc = "A bundle of raw spaghetti." icon_state = "spagetti" filling_color = "#eddd00" - center_of_mass = @"{'x':16,'y':16}" + center_of_mass = @'{"x":16,"y":16}' nutriment_desc = list("noodles" = 2) nutriment_amt = 1 bitesize = 1 @@ -16,9 +16,9 @@ name = "boiled spaghetti" desc = "A plain dish of pasta, just screaming for sauce." icon_state = "spagettiboiled" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fcee81" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("noodles" = 2) nutriment_amt = 2 bitesize = 2 @@ -27,55 +27,55 @@ name = "spaghetti & tomato" desc = "Spaghetti and crushed tomatoes." icon_state = "pastatomato" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#de4545" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("tomato" = 3, "noodles" = 3) nutriment_amt = 6 bitesize = 4 /obj/item/chems/food/pastatomato/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 10) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 10) /obj/item/chems/food/nanopasta name = "nanopasta" desc = "Nanomachines, son!" icon_state = "nanopasta" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#535e66" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_amt = 6 bitesize = 4 /obj/item/chems/food/nanopasta/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nanitefluid, 10) + add_to_reagents(/decl/material/liquid/nanitefluid, 10) /obj/item/chems/food/meatballspagetti name = "spaghetti & meatballs" desc = "Now thats a nice meatball!" icon_state = "meatballspagetti" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#de4545" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("noodles" = 4) nutriment_amt = 4 bitesize = 2 /obj/item/chems/food/meatballspagetti/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/spesslaw name = "spaghetti & too many meatballs" desc = "Do you want some pasta with those meatballs?" icon_state = "spesslaw" filling_color = "#de4545" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("noodles" = 4) nutriment_amt = 4 bitesize = 2 /obj/item/chems/food/spesslaw/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) diff --git a/code/modules/reagents/reagent_containers/food/rice.dm b/code/modules/reagents/reagent_containers/food/rice.dm index f95a46518c2..34db6b3e997 100644 --- a/code/modules/reagents/reagent_containers/food/rice.dm +++ b/code/modules/reagents/reagent_containers/food/rice.dm @@ -8,7 +8,7 @@ icon_state = "boiledrice" trash = /obj/item/trash/snack_bowl filling_color = "#fffbdb" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_desc = list("rice" = 2) nutriment_amt = 6 bitesize = 2 @@ -27,7 +27,7 @@ icon_state = "katsu" trash = /obj/item/trash/snack_bowl filling_color = "#faa005" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_desc = list("rice" = 2, "apple" = 2, "potato" = 2, "carrot" = 2, "bread" = 2, ) nutriment_amt = 6 bitesize = 2 @@ -38,7 +38,7 @@ icon_state = "rpudding" trash = /obj/item/trash/snack_bowl filling_color = "#fffbdb" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_desc = list("rice" = 2) nutriment_amt = 4 bitesize = 2 \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/rotten.dm b/code/modules/reagents/reagent_containers/food/rotten.dm index 4ec76666392..6cc5e6f98eb 100644 --- a/code/modules/reagents/reagent_containers/food/rotten.dm +++ b/code/modules/reagents/reagent_containers/food/rotten.dm @@ -3,7 +3,7 @@ /obj/item/chems/food/old name = "master old-food" desc = "they're all inedible and potentially dangerous items" - center_of_mass = @"{'x':15,'y':12}" + center_of_mass = @'{"x":15,"y":12}' nutriment_desc = list("rot" = 5, "mold" = 5) nutriment_amt = 10 bitesize = 3 @@ -12,7 +12,7 @@ /obj/item/chems/food/old/populate_reagents() . = ..() - reagents.add_reagent(pick( + add_to_reagents(pick( /decl/material/liquid/fuel, /decl/material/liquid/amatoxin, /decl/material/liquid/carpotoxin, diff --git a/code/modules/reagents/reagent_containers/food/sandwich.dm b/code/modules/reagents/reagent_containers/food/sandwich.dm index 1ce36ad4255..00d0fbf391c 100644 --- a/code/modules/reagents/reagent_containers/food/sandwich.dm +++ b/code/modules/reagents/reagent_containers/food/sandwich.dm @@ -11,7 +11,7 @@ name = "sandwich" desc = "The best thing since sliced bread." icon_state = "breadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate bitesize = 2 var/list/ingredients = list() diff --git a/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm b/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm index f9e9bd01be4..f7b1f0ccb11 100644 --- a/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm +++ b/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm @@ -5,7 +5,7 @@ slice_path = /obj/item/chems/food/slice/carrotcake slices_num = 5 filling_color = "#ffd675" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "carrot" = 15) nutriment_amt = 25 bitesize = 2 @@ -13,16 +13,16 @@ /obj/item/chems/food/sliceable/carrotcake/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/eyedrops, 10) + add_to_reagents(/decl/material/liquid/eyedrops, 10) /obj/item/chems/food/slice/carrotcake name = "carrot cake slice" desc = "Carrotty slice of carrot cake, carrots are good for your eyes! It's true! Probably!" icon_state = "carrotcake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ffd675" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/carrotcake /obj/item/chems/food/slice/carrotcake/filled @@ -35,7 +35,7 @@ slice_path = /obj/item/chems/food/slice/braincake slices_num = 5 filling_color = "#e6aedb" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "slime" = 15) nutriment_amt = 5 bitesize = 2 @@ -43,17 +43,17 @@ /obj/item/chems/food/sliceable/braincake/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 25) - reagents.add_reagent(/decl/material/liquid/neuroannealer, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 25) + add_to_reagents(/decl/material/liquid/neuroannealer, 10) /obj/item/chems/food/slice/braincake name = "brain cake slice" desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." icon_state = "braincakeslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#e6aedb" bitesize = 2 - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' whole_path = /obj/item/chems/food/sliceable/braincake /obj/item/chems/food/slice/braincake/filled @@ -66,23 +66,23 @@ slice_path = /obj/item/chems/food/slice/cheesecake slices_num = 5 filling_color = "#faf7af" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "cream" = 10, "cheese" = 15) nutriment_amt = 10 bitesize = 2 /obj/item/chems/food/sliceable/cheesecake/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 15) + add_to_reagents(/decl/material/liquid/nutriment/protein, 15) /obj/item/chems/food/slice/cheesecake name = "cheese cake slice" desc = "Slice of pure cheestisfaction." icon_state = "cheesecake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#faf7af" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/cheesecake /obj/item/chems/food/slice/cheesecake/filled @@ -95,7 +95,7 @@ slice_path = /obj/item/chems/food/slice/plaincake slices_num = 5 filling_color = "#f7edd5" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "vanilla" = 15) nutriment_amt = 20 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -104,10 +104,10 @@ name = "vanilla cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "plaincake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f7edd5" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/plaincake /obj/item/chems/food/slice/plaincake/filled @@ -120,7 +120,7 @@ slice_path = /obj/item/chems/food/slice/orangecake slices_num = 5 filling_color = "#fada8e" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "orange" = 15) nutriment_amt = 20 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -129,10 +129,10 @@ name = "orange cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "orangecake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fada8e" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/orangecake /obj/item/chems/food/slice/orangecake/filled @@ -145,7 +145,7 @@ slice_path = /obj/item/chems/food/slice/limecake slices_num = 5 filling_color = "#cbfa8e" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "lime" = 15) nutriment_amt = 20 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -154,10 +154,10 @@ name = "lime cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "limecake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#cbfa8e" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/limecake /obj/item/chems/food/slice/limecake/filled @@ -170,7 +170,7 @@ slice_path = /obj/item/chems/food/slice/lemoncake slices_num = 5 filling_color = "#fafa8e" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "lemon" = 15) nutriment_amt = 20 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -179,10 +179,10 @@ name = "lemon cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "lemoncake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fafa8e" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/lemoncake /obj/item/chems/food/slice/lemoncake/filled @@ -195,7 +195,7 @@ slice_path = /obj/item/chems/food/slice/chocolatecake slices_num = 5 filling_color = "#805930" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "chocolate" = 15) nutriment_amt = 20 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -204,10 +204,10 @@ name = "chocolate cake slice" desc = "Just a slice of cake, it is enough for everyone." icon_state = "chocolatecake_slice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#805930" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/chocolatecake /obj/item/chems/food/slice/chocolatecake/filled @@ -220,7 +220,7 @@ slice_path = /obj/item/chems/food/slice/birthdaycake slices_num = 5 filling_color = "#ffd6d6" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10) nutriment_amt = 20 bitesize = 3 @@ -228,16 +228,16 @@ /obj/item/chems/food/sliceable/birthdaycake/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sprinkles, 10) + add_to_reagents(/decl/material/liquid/nutriment/sprinkles, 10) /obj/item/chems/food/slice/birthdaycake name = "birthday cake slice" desc = "A slice of your birthday." icon_state = "birthdaycakeslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ffd6d6" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/birthdaycake /obj/item/chems/food/slice/birthdaycake/filled @@ -250,7 +250,7 @@ slice_path = /obj/item/chems/food/slice/applecake slices_num = 5 filling_color = "#ebf5b8" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cake" = 10, "sweetness" = 10, "apple" = 15) nutriment_amt = 15 nutriment_type = /decl/material/liquid/nutriment/bread/cake @@ -259,10 +259,10 @@ name = "apple cake slice" desc = "A slice of heavenly cake." icon_state = "applecakeslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ebf5b8" bitesize = 2 - center_of_mass = @"{'x':16,'y':14}" + center_of_mass = @'{"x":16,"y":14}' whole_path = /obj/item/chems/food/sliceable/applecake /obj/item/chems/food/slice/applecake/filled @@ -275,7 +275,7 @@ slice_path = /obj/item/chems/food/slice/pumpkinpie slices_num = 5 filling_color = "#f5b951" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("pie" = 5, "cream" = 5, "pumpkin" = 5) nutriment_amt = 15 @@ -283,10 +283,10 @@ name = "pumpkin pie slice" desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." icon_state = "pumpkinpieslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f5b951" bitesize = 2 - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' whole_path = /obj/item/chems/food/sliceable/pumpkinpie /obj/item/chems/food/slice/pumpkinpie/filled diff --git a/code/modules/reagents/reagent_containers/food/sliceable/cheeses.dm b/code/modules/reagents/reagent_containers/food/sliceable/cheeses.dm index fb076444459..b2b03bc52d9 100644 --- a/code/modules/reagents/reagent_containers/food/sliceable/cheeses.dm +++ b/code/modules/reagents/reagent_containers/food/sliceable/cheeses.dm @@ -5,14 +5,14 @@ slice_path = /obj/item/chems/food/cheesewedge slices_num = 5 filling_color = "#fff700" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("cheese" = 10) nutriment_amt = 10 bitesize = 2 /obj/item/chems/food/sliceable/cheesewheel/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/cheesewedge name = "cheese wedge" @@ -20,6 +20,6 @@ icon_state = "cheesewedge" filling_color = "#fff700" bitesize = 2 - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' // todo: non-cheddar cheeses \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/sliceable/loaves.dm b/code/modules/reagents/reagent_containers/food/sliceable/loaves.dm index b5c168fd449..6c7d8a70ba2 100644 --- a/code/modules/reagents/reagent_containers/food/sliceable/loaves.dm +++ b/code/modules/reagents/reagent_containers/food/sliceable/loaves.dm @@ -5,7 +5,7 @@ slice_path = /obj/item/chems/food/slice/meatbread slices_num = 5 filling_color = "#ff7575" - center_of_mass = @"{'x':19,'y':9}" + center_of_mass = @'{"x":19,"y":9}' nutriment_desc = list("bread" = 10) nutriment_amt = 10 bitesize = 2 @@ -13,16 +13,16 @@ /obj/item/chems/food/sliceable/meatbread/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 20) + add_to_reagents(/decl/material/liquid/nutriment/protein, 20) /obj/item/chems/food/slice/meatbread name = "meatbread slice" desc = "A slice of delicious meatbread." icon_state = "meatbreadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ff7575" bitesize = 2 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' whole_path = /obj/item/chems/food/sliceable/meatbread /obj/item/chems/food/slice/meatbread/filled @@ -35,7 +35,7 @@ slice_path = /obj/item/chems/food/slice/xenomeatbread slices_num = 5 filling_color = "#8aff75" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' nutriment_desc = list("bread" = 10) nutriment_amt = 10 bitesize = 2 @@ -43,16 +43,16 @@ /obj/item/chems/food/sliceable/xenomeatbread/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 20) + add_to_reagents(/decl/material/liquid/nutriment/protein, 20) /obj/item/chems/food/slice/xenomeatbread name = "xenomeatbread slice" desc = "A slice of delicious meatbread. Extra Heretical." icon_state = "xenobreadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#8aff75" bitesize = 2 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' whole_path = /obj/item/chems/food/sliceable/xenomeatbread /obj/item/chems/food/slice/xenomeatbread/filled @@ -65,7 +65,7 @@ slice_path = /obj/item/chems/food/slice/bananabread slices_num = 5 filling_color = "#ede5ad" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' nutriment_desc = list("bread" = 10) nutriment_amt = 10 bitesize = 2 @@ -73,16 +73,16 @@ /obj/item/chems/food/sliceable/bananabread/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/banana_cream, 20) + add_to_reagents(/decl/material/liquid/nutriment/banana_cream, 20) /obj/item/chems/food/slice/bananabread name = "banana-nut bread slice" desc = "A slice of delicious banana bread." icon_state = "bananabreadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ede5ad" bitesize = 2 - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' whole_path = /obj/item/chems/food/sliceable/bananabread /obj/item/chems/food/slice/bananabread/filled @@ -95,7 +95,7 @@ slice_path = /obj/item/chems/food/slice/tofubread slices_num = 5 filling_color = "#f7ffe0" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' nutriment_desc = list("tofu" = 10) nutriment_amt = 10 bitesize = 2 @@ -105,10 +105,10 @@ name = "tofubread slice" desc = "A slice of delicious tofubread." icon_state = "tofubreadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f7ffe0" bitesize = 2 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' whole_path = /obj/item/chems/food/sliceable/tofubread /obj/item/chems/food/slice/tofubread/filled @@ -121,7 +121,7 @@ slice_path = /obj/item/chems/food/slice/bread slices_num = 5 filling_color = "#ffe396" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' nutriment_desc = list("bread" = 6) nutriment_amt = 6 bitesize = 2 @@ -131,10 +131,10 @@ name = "bread slice" desc = "A slice of home." icon_state = "breadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#d27332" bitesize = 2 - center_of_mass = @"{'x':16,'y':4}" + center_of_mass = @'{"x":16,"y":4}' whole_path = /obj/item/chems/food/sliceable/bread /obj/item/chems/food/slice/bread/filled @@ -147,7 +147,7 @@ slice_path = /obj/item/chems/food/slice/creamcheesebread slices_num = 5 filling_color = "#fff896" - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' nutriment_desc = list("bread" = 6, "cream" = 3, "cheese" = 3) nutriment_amt = 5 bitesize = 2 @@ -155,16 +155,16 @@ /obj/item/chems/food/sliceable/creamcheesebread/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 15) + add_to_reagents(/decl/material/liquid/nutriment/protein, 15) /obj/item/chems/food/slice/creamcheesebread name = "cream cheese bread slice" desc = "A slice of yum!" icon_state = "creamcheesebreadslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fff896" bitesize = 2 - center_of_mass = @"{'x':16,'y':13}" + center_of_mass = @'{"x":16,"y":13}' whole_path = /obj/item/chems/food/sliceable/creamcheesebread /obj/item/chems/food/slice/creamcheesebread/filled diff --git a/code/modules/reagents/reagent_containers/food/sliceable/misc_slices.dm b/code/modules/reagents/reagent_containers/food/sliceable/misc_slices.dm index 1232094ad3f..cb6dc5b9cc5 100644 --- a/code/modules/reagents/reagent_containers/food/sliceable/misc_slices.dm +++ b/code/modules/reagents/reagent_containers/food/sliceable/misc_slices.dm @@ -4,4 +4,4 @@ icon_state = "watermelonslice" filling_color = "#ff3867" bitesize = 2 - center_of_mass = @"{'x':16,'y':10}" \ No newline at end of file + center_of_mass = @'{"x":16,"y":10}' \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza.dm deleted file mode 100644 index 8f66d203b88..00000000000 --- a/code/modules/reagents/reagent_containers/food/sliceable/pizza.dm +++ /dev/null @@ -1,295 +0,0 @@ -/////////// -// PIZZA // -/////////// - -/obj/item/chems/food/sliceable/pizza - slices_num = 6 - filling_color = "#baa14c" - -/obj/item/chems/food/sliceable/pizza/margherita - name = "margherita" - desc = "The golden standard of pizzas." - icon_state = "pizzamargherita" - slice_path = /obj/item/chems/food/slice/margherita - slices_num = 6 - center_of_mass = @"{'x':16,'y':11}" - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) - nutriment_amt = 35 - bitesize = 2 - nutriment_type = /decl/material/liquid/nutriment/bread - -/obj/item/chems/food/sliceable/pizza/margherita/populate_reagents() - . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 6) - -/obj/item/chems/food/slice/margherita - name = "margherita slice" - desc = "A slice of the classic pizza." - icon_state = "pizzamargheritaslice" - filling_color = "#baa14c" - bitesize = 2 - center_of_mass = @"{'x':18,'y':13}" - whole_path = /obj/item/chems/food/sliceable/pizza/margherita - -/obj/item/chems/food/slice/margherita/filled - filled = TRUE - -/obj/item/chems/food/sliceable/pizza/meatpizza - name = "meatpizza" - desc = "A pizza with meat topping." - icon_state = "meatpizza" - slice_path = /obj/item/chems/food/slice/meatpizza - slices_num = 6 - center_of_mass = @"{'x':16,'y':11}" - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) - nutriment_amt = 10 - bitesize = 2 - nutriment_type = /decl/material/liquid/nutriment/bread - -/obj/item/chems/food/sliceable/pizza/meatpizza/populate_reagents() - . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 34) - reagents.add_reagent(/decl/material/liquid/nutriment/barbecue, 6) - -/obj/item/chems/food/slice/meatpizza - name = "meatpizza slice" - desc = "A slice of a meaty pizza." - icon_state = "meatpizzaslice" - filling_color = "#baa14c" - bitesize = 2 - center_of_mass = @"{'x':18,'y':13}" - whole_path = /obj/item/chems/food/sliceable/pizza/meatpizza - -/obj/item/chems/food/slice/meatpizza/filled - filled = TRUE - -/obj/item/chems/food/sliceable/pizza/mushroompizza - name = "mushroompizza" - desc = "Very special pizza." - icon_state = "mushroompizza" - slice_path = /obj/item/chems/food/slice/mushroompizza - slices_num = 6 - center_of_mass = @"{'x':16,'y':11}" - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "mushroom" = 10) - nutriment_amt = 35 - bitesize = 2 - nutriment_type = /decl/material/liquid/nutriment/bread - -/obj/item/chems/food/sliceable/pizza/mushroompizza/populate_reagents() - . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) - -/obj/item/chems/food/slice/mushroompizza - name = "mushroompizza slice" - desc = "Maybe it is the last slice of pizza in your life." - icon_state = "mushroompizzaslice" - filling_color = "#baa14c" - bitesize = 2 - center_of_mass = @"{'x':18,'y':13}" - whole_path = /obj/item/chems/food/sliceable/pizza/mushroompizza - -/obj/item/chems/food/slice/mushroompizza/filled - filled = TRUE - -/obj/item/chems/food/sliceable/pizza/vegetablepizza - name = "vegetable pizza" - desc = "Vegetarian pizza huh? What about all the plants that were slaughtered to make this huh?? Hypocrite." - icon_state = "vegetablepizza" - slice_path = /obj/item/chems/food/slice/vegetablepizza - slices_num = 6 - center_of_mass = @"{'x':16,'y':11}" - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "eggplant" = 5, "carrot" = 5, "corn" = 5) - nutriment_amt = 25 - bitesize = 2 - nutriment_type = /decl/material/liquid/nutriment/bread - -/obj/item/chems/food/sliceable/pizza/vegetablepizza/populate_reagents() - . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) - reagents.add_reagent(/decl/material/liquid/nutriment/ketchup, 6) - reagents.add_reagent(/decl/material/liquid/eyedrops, 12) - -/obj/item/chems/food/slice/vegetablepizza - name = "vegetable pizza slice" - desc = "A slice of the most green pizza of all pizzas not containing green ingredients." - icon_state = "vegetablepizzaslice" - filling_color = "#baa14c" - bitesize = 2 - center_of_mass = @"{'x':18,'y':13}" - whole_path = /obj/item/chems/food/sliceable/pizza/vegetablepizza - -/obj/item/chems/food/slice/vegetablepizza/filled - filled = TRUE - -/obj/item/pizzabox - name = "pizza box" - desc = "A box suited for pizzas." - icon = 'icons/obj/food.dmi' - icon_state = "pizzabox1" - material = /decl/material/solid/organic/cardboard - var/open = 0 // Is the box open? - var/ismessy = 0 // Fancy mess on the lid - var/obj/item/chems/food/sliceable/pizza/pizza // content pizza - var/list/boxes = list()// If the boxes are stacked, they come here - var/boxtag = "" - -/obj/item/pizzabox/Initialize(ml, material_key) - . = ..() - if(ispath(pizza)) - pizza = new pizza(src) - -/obj/item/pizzabox/on_update_icon() - . = ..() - - // Set appropriate description - if( open && pizza ) - desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." - else if( boxes.len > 0 ) - desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." - - var/obj/item/pizzabox/topbox = boxes[boxes.len] - var/toptag = topbox.boxtag - if( toptag != "" ) - desc = "[desc] The box on top has a tag, it reads: '[toptag]'." - else - desc = "A box suited for pizzas." - - if( boxtag != "" ) - desc = "[desc] The box has a tag, it reads: '[boxtag]'." - - // Icon states and overlays - if( open ) - if( ismessy ) - icon_state = "pizzabox_messy" - else - icon_state = "pizzabox_open" - - if( pizza ) - var/mutable_appearance/pizzaimg = new(pizza) - pizzaimg.pixel_y = -3 - add_overlay(pizzaimg) - return - else - // Stupid code because byondcode sucks - var/doimgtag = 0 - if( boxes.len > 0 ) - var/obj/item/pizzabox/topbox = boxes[boxes.len] - if( topbox.boxtag != "" ) - doimgtag = 1 - else - if( boxtag != "" ) - doimgtag = 1 - - if( doimgtag ) - add_overlay(image("food.dmi", "pizzabox_tag", pixel_y = (boxes.len * 3))) - - icon_state = "pizzabox[boxes.len+1]" - -/obj/item/pizzabox/attack_hand(mob/user) - - if(open && pizza) - if(user.check_dexterity(DEXTERITY_HOLD_ITEM)) - user.put_in_hands(pizza) - to_chat(user, SPAN_NOTICE("You take \the [src.pizza] out of \the [src].")) - pizza = null - update_icon() - return TRUE - - if(length(boxes) && user.is_holding_offhand(src) && user.check_dexterity(DEXTERITY_HOLD_ITEM)) - var/obj/item/pizzabox/box = boxes[boxes.len] - boxes -= box - user.put_in_hands(box) - to_chat(user, SPAN_WARNING("You remove the topmost [src] from your hand.")) - box.update_icon() - update_icon() - return TRUE - - return ..() - -/obj/item/pizzabox/attack_self(mob/user) - - if( boxes.len > 0 ) - return - - open = !open - - if( open && pizza ) - ismessy = 1 - - update_icon() - -/obj/item/pizzabox/attackby(obj/item/I, mob/user) - if( istype(I, /obj/item/pizzabox/) ) - var/obj/item/pizzabox/box = I - - if( !box.open && !src.open ) - // make a list of all boxes to be added - var/list/boxestoadd = list() - boxestoadd += box - for(var/obj/item/pizzabox/i in box.boxes) - boxestoadd += i - - if( (boxes.len+1) + boxestoadd.len <= 5 ) - if(!user.try_unequip(box, src)) - return TRUE - box.boxes = list()// clear the box boxes so we don't have boxes inside boxes. - Xzibit - src.boxes.Add( boxestoadd ) - - box.update_icon() - update_icon() - - to_chat(user, "You put \the [box] ontop of \the [src]!") - else - to_chat(user, "The stack is too high!") - else - to_chat(user, "Close \the [box] first!") - - return TRUE - - if( istype(I, /obj/item/chems/food/sliceable/pizza/) ) - - if( src.open ) - if(!user.try_unequip(I, src)) - return TRUE - src.pizza = I - - update_icon() - - to_chat(user, "You put \the [I] in \the [src]!") - else - to_chat(user, "You try to push \the [I] through the lid but it doesn't work!") - return TRUE - - if(IS_PEN(I)) - - if( src.open ) - return TRUE - - var/t = sanitize(input("Enter what you want to add to the tag:", "Write", null, null) as text, 30) - - var/obj/item/pizzabox/boxtotagto = src - if( boxes.len > 0 ) - boxtotagto = boxes[boxes.len] - - boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) - - update_icon() - return TRUE - return ..() - -/obj/item/pizzabox/margherita - pizza = /obj/item/chems/food/sliceable/pizza/margherita - boxtag = "Margherita Deluxe" - -/obj/item/pizzabox/vegetable - pizza = /obj/item/chems/food/sliceable/pizza/vegetablepizza - boxtag = "Gourmet Vegatable" - -/obj/item/pizzabox/mushroom - pizza = /obj/item/chems/food/sliceable/pizza/mushroompizza - boxtag = "Mushroom Special" - -/obj/item/pizzabox/meat - pizza = /obj/item/chems/food/sliceable/pizza/meatpizza - boxtag = "Meatlover's Supreme" \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/_pizza.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/_pizza.dm new file mode 100644 index 00000000000..45d5b1ca36c --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/_pizza.dm @@ -0,0 +1,32 @@ +/obj/item/chems/food/sliceable/pizza + icon_state = ICON_STATE_WORLD + slices_num = 6 + nutriment_amt = 25 + bitesize = 2 + nutriment_type = /decl/material/liquid/nutriment/bread + center_of_mass = @'{"x":16,"y":11}' + filling_color = "#baa14c" + abstract_type = /obj/item/chems/food/sliceable/pizza + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) + var/ruined = FALSE // Visual only, doesn't actually impact the edibility or sliceability of the pizza. + +/obj/item/chems/food/sliceable/pizza/proc/ruin() + if(!ruined) + ruined = TRUE + name = "ruined [name]" + update_icon() + +/obj/item/chems/food/sliceable/pizza/on_update_icon() + . = ..() + icon_state = get_world_inventory_state() + if(ruined) + var/ruined_state = "[icon_state]_ruined" + if(check_state_in_icon(ruined_state, icon)) + icon_state = ruined_state + +/obj/item/chems/food/slice/pizza + icon = 'icons/obj/food/pizzas/pizza_slices.dmi' + filling_color = "#baa14c" + bitesize = 2 + center_of_mass = @'{"x":18,"y":13}' + abstract_type = /obj/item/chems/food/slice/pizza diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm new file mode 100644 index 00000000000..008878f25fc --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm @@ -0,0 +1,333 @@ +/obj/item/pizzabox + name = "pizza box" + desc = "A box suited for pizzas." + icon = 'icons/obj/food/containers/pizzabox.dmi' + icon_state = ICON_STATE_WORLD + material = /decl/material/solid/organic/cardboard + + var/const/RISKY_PIZZA_STACK = 6 + var/const/MAXIMUM_PIZZA_STACK = 15 + var/open = FALSE // Is the box open? + var/image/messy_overlay + var/obj/item/chems/food/sliceable/pizza/pizza + var/list/stacked_boxes + var/box_tag + var/box_tag_color = COLOR_BLACK + +/obj/item/pizzabox/Initialize(ml, material_key) + . = ..() + if(ispath(pizza)) + pizza = new pizza(src) + if(open) + open = FALSE + toggle_open() + else if(box_tag || pizza) + update_strings() + update_icon() + // We care about our own moved event in case of structural failure. + events_repository.register(/decl/observ/moved, src, src, PROC_REF(check_stack_failure)) + +/obj/item/pizzabox/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) + if(overlay && length(stacked_boxes)) + var/i = 1 + for(var/obj/item/pizzabox/box in stacked_boxes) + var/image/I = box.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) + if(I) + I.pixel_y = i * 3 + I.pixel_x = pick(-1,0,1) + overlay.overlays += I + i++ + . = ..() + +// Tossing a pizza around can have terrible effects... +/obj/item/pizzabox/attack(mob/living/M, mob/living/user, var/target_zone) + ..() + return FALSE + +/obj/item/pizzabox/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(proximity_flag && user?.a_intent == I_HURT && user != target) + jostle_pizza() + explode_stack() + +/obj/item/pizzabox/proc/jostle_pizza() + if(pizza && !pizza.ruined && prob(20)) + pizza.ruin() + if(!open && prob(30)) + toggle_open() + else + if(open) + update_icon() + update_strings() + +/obj/item/pizzabox/proc/explode_stack() + var/turf/our_turf = get_turf(src) + if(!our_turf || !LAZYLEN(stacked_boxes)) + return + while(LAZYLEN(stacked_boxes)) + var/obj/item/pizzabox/top_box = stacked_boxes[LAZYLEN(stacked_boxes)] + LAZYREMOVE(stacked_boxes, top_box) + top_box.throw_at(get_edge_target_turf(our_turf, pick(global.alldirs)), 1, 1) // just enough to bonk people + update_strings() + update_icon() + if(ismob(loc)) + var/mob/owner = loc + owner.update_inhand_overlays() + +// This is disgusting, but I can't work out a good way to catch +// the end of a throw regardless of whether or not it hit something. +/obj/item/pizzabox/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback) + . = ..() + wait_for_throw_end_then_spill() + +/obj/item/pizzabox/proc/wait_for_throw_end_then_spill() + set waitfor = FALSE + while(!QDELETED(throwing)) + sleep(1) + if(QDELETED(src)) + return + jostle_pizza() + explode_stack() + +/obj/item/pizzabox/proc/check_stack_failure() + + if(isobj(loc) || LAZYLEN(stacked_boxes)+1 < RISKY_PIZZA_STACK) + return // no stack, no worries + + var/fell_off = 0 + var/turf/our_turf = get_turf(src) + if(!isturf(our_turf)) + return // shouldn't happen due to checks above + + var/mob/mover = loc + var/moving_deliberately = ismob(mover) && MOVING_DELIBERATELY(mover) + while(LAZYLEN(stacked_boxes)+1 > RISKY_PIZZA_STACK) + var/danger_zone = ((LAZYLEN(stacked_boxes)+1)-RISKY_PIZZA_STACK) * 10 + if(moving_deliberately) + danger_zone *= 0.5 + if(danger_zone <= 0 || !prob(danger_zone)) + break // we are safe... for now... + var/obj/item/pizzabox/top_box = stacked_boxes[LAZYLEN(stacked_boxes)] + LAZYREMOVE(stacked_boxes, top_box) + top_box.dropInto(our_turf) + top_box.throw_at(get_edge_target_turf(our_turf, pick(global.alldirs)), 1, 1) // just enough to bonk people + fell_off++ + if(fell_off > 0) + our_turf.visible_message(SPAN_DANGER("[fell_off] [fell_off == 1 ? "pizza" : "pizzas"] [fell_off == 1 ? "falls" : "fall"] off the stack!")) + update_strings() + update_icon() + if(ismob(mover)) + mover.update_inhand_overlays() + else if(prob(15) && ismob(mover)) + to_chat(loc, SPAN_WARNING("The stack of pizza boxes sways alarmingly...")) + +/obj/item/pizzabox/proc/toggle_open() + if(LAZYLEN(stacked_boxes)) + return FALSE + open = !open + if(open && pizza && !messy_overlay) + var/mess_state = "[pizza.icon_state]_mess" + if(check_state_in_icon(mess_state, pizza.icon)) + messy_overlay = image(pizza.icon, mess_state) + update_icon() + compile_overlays() // to avoid our tags and messy state flickering + return TRUE + +/obj/item/pizzabox/proc/update_strings() + name = initial(name) + var/list/desc_strings = list(initial(desc)) + if(open && pizza) + desc_strings += "It appears to have \a [pizza] inside." + else if(length(stacked_boxes)) + name = "stack of pizza boxes" + desc_strings += "A pile of boxes suited for pizzas. There appears to be [length(stacked_boxes)+1] boxes in the pile." + var/obj/item/pizzabox/topbox = stacked_boxes[length(stacked_boxes)] + if(topbox?.box_tag) + desc_strings += "The box on top has a tag reading: '[topbox.box_tag]'." + else if(box_tag) + desc_strings += "The box has a tag reading: '[box_tag]'." + desc = jointext(desc_strings, " ") + +/obj/item/pizzabox/on_update_icon() + . = ..() + // Update our own appearance. + icon_state = get_world_inventory_state() + if(open) + icon_state = "[icon_state]_open" + if(messy_overlay) + add_overlay(messy_overlay) + if(pizza) + var/mutable_appearance/pizzaimg = new(pizza) + pizzaimg.layer = FLOAT_LAYER + pizzaimg.plane = FLOAT_PLANE + pizzaimg.pixel_x = 0 + pizzaimg.pixel_y = -3 + pizzaimg.pixel_z = 0 + pizzaimg.pixel_w = 0 + add_overlay(pizzaimg) + return + + // If we're closed, draw our tag and all the pizzas in the stack. + if(box_tag) + add_overlay(overlay_image(icon, "[icon_state]_tag", box_tag_color, RESET_COLOR)) + + // Add all the boxes in the stack. + var/i = 1 + for(var/obj/item/pizzabox/pizza_box in stacked_boxes) + var/mutable_appearance/box_img = new(pizza_box) + box_img.layer = FLOAT_LAYER + box_img.plane = FLOAT_PLANE + box_img.pixel_y = i * 3 + pick(-1,0,1) + box_img.pixel_x = pick(-1,0,1) + box_img.pixel_z = 0 + box_img.pixel_w = 0 + add_overlay(box_img) + i++ + +/obj/item/pizzabox/attack_hand(mob/user) + + if(open && pizza && user.a_intent != I_GRAB) + if(user.check_dexterity(DEXTERITY_HOLD_ITEM)) + user.put_in_hands(pizza) + to_chat(user, SPAN_NOTICE("You take \the [pizza] out of \the [src].")) + pizza = null + update_icon() + return TRUE + + var/box_count = LAZYLEN(stacked_boxes) + if(box_count && user.is_holding_offhand(src) && user.check_dexterity(DEXTERITY_HOLD_ITEM)) + var/obj/item/pizzabox/box = stacked_boxes[box_count] + LAZYREMOVE(stacked_boxes, box) + user.put_in_hands(box) + to_chat(user, SPAN_WARNING("You remove the topmost [src] from your hand.")) + + if((LAZYLEN(stacked_boxes)+1) == (RISKY_PIZZA_STACK-1)) + to_chat(user, SPAN_NOTICE("The stack looks a bit more stable. It's probably safe to carry now.")) + + box.update_icon() + box.update_strings() + update_icon() + update_strings() + return TRUE + + return ..() + +/obj/item/pizzabox/attack_self(mob/user) + if(toggle_open()) + return TRUE + return ..() + +/obj/item/pizzabox/attackby(obj/item/I, mob/user) + + // Stacking pizza boxes. + if(istype(I, /obj/item/pizzabox)) + var/obj/item/pizzabox/box = I + if(box.open) + to_chat(user, SPAN_WARNING("You need to close \the [box] first!")) + return TRUE + + if(open) + to_chat(user, SPAN_WARNING("You need to close \the [src] first!")) + return TRUE + + var/stack_count = (LAZYLEN(stacked_boxes) + LAZYLEN(box.stacked_boxes) + 2) + if(stack_count > MAXIMUM_PIZZA_STACK) + to_chat(user, SPAN_WARNING("That pizza stack would be too high!")) + return TRUE + + if(!user.try_unequip(box, src)) + return TRUE + + LAZYDISTINCTADD(stacked_boxes, box) + if(box.stacked_boxes) + LAZYDISTINCTADD(stacked_boxes, box.stacked_boxes) + LAZYCLEARLIST(box.stacked_boxes) + update_icon() + update_strings() + box.update_icon() + box.update_strings() + + user.visible_message(SPAN_NOTICE("\The [user] stacks \the [box] on top of \the [src].")) + if(stack_count == RISKY_PIZZA_STACK) + to_chat(user, SPAN_WARNING("The stack sags a bit. You have a bad feeling about carrying it...")) + + return TRUE + + // Putting a pizza back in the box. + if(istype(I, /obj/item/chems/food/sliceable/pizza)) + + if(!open) + to_chat(user, SPAN_WARNING("Open \the [src] first!")) + return TRUE + + if(pizza) + to_chat(user, SPAN_WARNING("\The [src] already has \the [pizza] inside!")) + return TRUE + + if(!user.try_unequip(I, src)) + return TRUE + + pizza = I + update_strings() + update_icon() + user.visible_message(SPAN_NOTICE("\The [user] slides \the [I] into \the [src].")) + return TRUE + + // Appending to the tag. + if(IS_PEN(I)) + + if(open) + to_chat(user, SPAN_WARNING("Close \the [src] first!")) + return TRUE + + var/tag_string = sanitize(input("Enter what you want to add to the tag.", "Write", null, null) as text|null, 30) + if(!CanPhysicallyInteract(user) || !tag_string || open) + return TRUE + + var/box_count = LAZYLEN(stacked_boxes) + var/obj/item/pizzabox/tagging_box = (box_count > 0) ? stacked_boxes[box_count] : src + tagging_box.box_tag = copytext("[tagging_box.box_tag][tag_string]", 1, 30) + tagging_box.box_tag_color = I.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR) || COLOR_BLACK + user.visible_message(SPAN_NOTICE("\The [user] writes something on \the [src].")) + update_strings() + update_icon() + return TRUE + + return ..() + +/obj/item/pizzabox/get_alt_interactions(mob/user) + . = ..() + LAZYADD(., /decl/interaction_handler/open_pizza_box) + +/decl/interaction_handler/open_pizza_box + expected_target_type = /obj/item/pizzabox + +/decl/interaction_handler/open_pizza_box/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() + if(.) + var/obj/item/pizzabox/box = target + . = LAZYLEN(box.stacked_boxes) <= 0 + +/decl/interaction_handler/open_pizza_box/invoked(atom/target, mob/user, obj/item/prop) + var/obj/item/pizzabox/box = target + box.toggle_open() + +// Subtypes below. +/obj/item/pizzabox/margherita + pizza = /obj/item/chems/food/sliceable/pizza/margherita + box_tag = "Margherita Deluxe" + box_tag_color = COLOR_DARK_RED + +/obj/item/pizzabox/vegetable + pizza = /obj/item/chems/food/sliceable/pizza/vegetablepizza + box_tag = "Gourmet Vegetable" + box_tag_color = COLOR_PAKISTAN_GREEN + +/obj/item/pizzabox/mushroom + pizza = /obj/item/chems/food/sliceable/pizza/mushroompizza + box_tag = "Mushroom Special" + box_tag_color = COLOR_PURPLE_GRAY + +/obj/item/pizzabox/meat + pizza = /obj/item/chems/food/sliceable/pizza/meatpizza + box_tag = "Meatlover's Supreme" + box_tag_color = COLOR_BROWN_ORANGE diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_margherita.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_margherita.dm new file mode 100644 index 00000000000..331877b75f5 --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_margherita.dm @@ -0,0 +1,19 @@ +/obj/item/chems/food/sliceable/pizza/margherita + name = "margherita" + desc = "The golden standard of pizzas." + slice_path = /obj/item/chems/food/slice/pizza/margherita + icon = 'icons/obj/food/pizzas/pizza_margherita.dmi' + +/obj/item/chems/food/sliceable/pizza/margherita/populate_reagents() + . = ..() + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 6) + +/obj/item/chems/food/slice/pizza/margherita + name = "margherita slice" + desc = "A slice of the classic pizza." + icon_state = "pizzamargheritaslice" + whole_path = /obj/item/chems/food/sliceable/pizza/margherita + +/obj/item/chems/food/slice/pizza/margherita/filled + filled = TRUE diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_meat.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_meat.dm new file mode 100644 index 00000000000..053603f280f --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_meat.dm @@ -0,0 +1,20 @@ +/obj/item/chems/food/sliceable/pizza/meatpizza + name = "meatpizza" + desc = "A pizza with meat topping." + slice_path = /obj/item/chems/food/slice/pizza/meat + nutriment_amt = 10 + icon = 'icons/obj/food/pizzas/pizza_meat.dmi' + +/obj/item/chems/food/sliceable/pizza/meatpizza/populate_reagents() + . = ..() + add_to_reagents(/decl/material/liquid/nutriment/protein, 34) + add_to_reagents(/decl/material/liquid/nutriment/barbecue, 6) + +/obj/item/chems/food/slice/pizza/meat + name = "meatpizza slice" + desc = "A slice of a meaty pizza." + icon_state = "meatpizzaslice" + whole_path = /obj/item/chems/food/sliceable/pizza/meatpizza + +/obj/item/chems/food/slice/pizza/meat/filled + filled = TRUE diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_mushroom.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_mushroom.dm new file mode 100644 index 00000000000..b38b930655d --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_mushroom.dm @@ -0,0 +1,19 @@ +/obj/item/chems/food/sliceable/pizza/mushroompizza + name = "mushroompizza" + desc = "Very special pizza." + slice_path = /obj/item/chems/food/slice/pizza/mushroom + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "mushroom" = 10) + icon = 'icons/obj/food/pizzas/pizza_mushroom.dmi' + +/obj/item/chems/food/sliceable/pizza/mushroompizza/populate_reagents() + . = ..() + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) + +/obj/item/chems/food/slice/pizza/mushroom + name = "mushroompizza slice" + desc = "Maybe it is the last slice of pizza in your life." + icon_state = "mushroompizzaslice" + whole_path = /obj/item/chems/food/sliceable/pizza/mushroompizza + +/obj/item/chems/food/slice/pizza/mushroom/filled + filled = TRUE diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_vegetable.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_vegetable.dm new file mode 100644 index 00000000000..77eff776340 --- /dev/null +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_vegetable.dm @@ -0,0 +1,21 @@ +/obj/item/chems/food/sliceable/pizza/vegetablepizza + name = "vegetable pizza" + desc = "Vegetarian pizza, huh? What about all the plants that were slaughtered to make this, huh!? Hypocrite." + slice_path = /obj/item/chems/food/slice/pizza/vegetable + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "eggplant" = 5, "carrot" = 5, "corn" = 5) + icon = 'icons/obj/food/pizzas/pizza_vegetable.dmi' + +/obj/item/chems/food/sliceable/pizza/vegetablepizza/populate_reagents() + . = ..() + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/nutriment/ketchup, 6) + add_to_reagents(/decl/material/liquid/eyedrops, 12) + +/obj/item/chems/food/slice/pizza/vegetable + name = "vegetable pizza slice" + desc = "A slice of the most green pizza of all pizzas not containing green ingredients." + icon_state = "vegetablepizzaslice" + whole_path = /obj/item/chems/food/sliceable/pizza/vegetablepizza + +/obj/item/chems/food/slice/pizza/vegetable/filled + filled = TRUE diff --git a/code/modules/reagents/reagent_containers/food/soup.dm b/code/modules/reagents/reagent_containers/food/soup.dm index c2a8a192450..11d178feffc 100644 --- a/code/modules/reagents/reagent_containers/food/soup.dm +++ b/code/modules/reagents/reagent_containers/food/soup.dm @@ -8,36 +8,36 @@ icon_state = "meatballsoup" trash = /obj/item/trash/snack_bowl filling_color = "#785210" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' bitesize = 5 eat_sound = list('sound/items/eatfood.ogg', 'sound/items/drink.ogg') /obj/item/chems/food/meatballsoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/bloodsoup name = "tomato soup" desc = "Smells like copper." icon_state = "tomatosoup" filling_color = "#ff0000" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' bitesize = 5 eat_sound = 'sound/items/drink.ogg' /obj/item/chems/food/bloodsoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) - reagents.add_reagent(/decl/material/liquid/blood, 10) - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/blood, 10) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/clownstears name = "clown's tears" desc = "Not very funny." icon_state = "clownstears" filling_color = "#c4fbff" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' nutriment_desc = list("salt" = 1, "the worst joke" = 3) nutriment_amt = 4 bitesize = 5 @@ -45,8 +45,8 @@ /obj/item/chems/food/clownstears/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/banana, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/drink/juice/banana, 5) + add_to_reagents(/decl/material/liquid/water, 10) /obj/item/chems/food/vegetablesoup name = "vegetable soup" @@ -54,7 +54,7 @@ icon_state = "vegetablesoup" trash = /obj/item/trash/snack_bowl filling_color = "#afc4b5" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_desc = list("carrot" = 2, "corn" = 2, "eggplant" = 2, "potato" = 2) nutriment_amt = 8 bitesize = 5 @@ -62,7 +62,7 @@ /obj/item/chems/food/vegetablesoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/nettlesoup name = "nettle soup" @@ -70,7 +70,7 @@ icon_state = "nettlesoup" trash = /obj/item/trash/snack_bowl filling_color = "#afc4b5" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' nutriment_desc = list("salad" = 4, "egg" = 2, "potato" = 2) nutriment_amt = 8 bitesize = 5 @@ -78,8 +78,8 @@ /obj/item/chems/food/nettlesoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/water, 5) - reagents.add_reagent(/decl/material/liquid/regenerator, 5) + add_to_reagents(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/regenerator, 5) /obj/item/chems/food/mysterysoup name = "mystery soup" @@ -87,7 +87,7 @@ icon_state = "mysterysoup" trash = /obj/item/trash/snack_bowl filling_color = "#f082ff" - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' nutriment_desc = list("backwash" = 1) nutriment_amt = 1 bitesize = 5 @@ -141,7 +141,7 @@ . = ..() var/list/fillings = pick(get_random_fillings()) for(var/filling in fillings) - reagents.add_reagent(filling, fillings[filling]) + add_to_reagents(filling, fillings[filling]) /obj/item/chems/food/wishsoup name = "\improper Wish Soup" @@ -149,16 +149,16 @@ icon_state = "wishsoup" trash = /obj/item/trash/snack_bowl filling_color = "#d1f4ff" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' bitesize = 5 eat_sound = 'sound/items/drink.ogg' /obj/item/chems/food/wishsoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/water, 10) if(prob(25)) src.desc = "A wish come true!" - reagents.add_reagent(/decl/material/liquid/nutriment, 8, list("something good" = 8)) + add_to_reagents(/decl/material/liquid/nutriment, 8, list("something good" = 8)) /obj/item/chems/food/hotchili name = "hot chili" @@ -166,23 +166,23 @@ icon_state = "hotchili" trash = /obj/item/trash/snack_bowl filling_color = "#ff3c00" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("chilli peppers" = 2, "burning" = 1) nutriment_amt = 3 bitesize = 5 /obj/item/chems/food/hotchili/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/liquid/capsaicin, 3) - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/capsaicin, 3) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 2) /obj/item/chems/food/coldchili name = "cold chili" desc = "This slush is barely a liquid!" icon_state = "coldchili" filling_color = "#2b00ff" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_desc = list("chilly peppers" = 3) nutriment_amt = 3 trash = /obj/item/trash/snack_bowl @@ -190,9 +190,9 @@ /obj/item/chems/food/coldchili/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/liquid/frostoil, 3) - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/frostoil, 3) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 2) /obj/item/chems/food/tomatosoup name = "tomato soup" @@ -200,7 +200,7 @@ icon_state = "tomatosoup" trash = /obj/item/trash/snack_bowl filling_color = "#d92929" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' nutriment_desc = list("soup" = 5) nutriment_amt = 5 bitesize = 3 @@ -208,31 +208,31 @@ /obj/item/chems/food/tomatosoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 10) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 10) /obj/item/chems/food/stew name = "stew" desc = "A nice and warm stew. Healthy and strong." icon_state = "stew" filling_color = "#9e673a" - center_of_mass = @"{'x':16,'y':5}" + center_of_mass = @'{"x":16,"y":5}' nutriment_desc = list("tomato" = 2, "potato" = 2, "carrot" = 2, "eggplant" = 2, "mushroom" = 2) nutriment_amt = 6 bitesize = 10 /obj/item/chems/food/stew/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/liquid/drink/juice/tomato, 5) - reagents.add_reagent(/decl/material/liquid/eyedrops, 5) - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/drink/juice/tomato, 5) + add_to_reagents(/decl/material/liquid/eyedrops, 5) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/milosoup name = "milosoup" desc = "The universes best soup! Yum!!!" icon_state = "milosoup" trash = /obj/item/trash/snack_bowl - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' nutriment_desc = list("soy" = 8) nutriment_amt = 8 bitesize = 4 @@ -240,7 +240,7 @@ /obj/item/chems/food/milosoup/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/mushroomsoup name = "chantrelle soup" @@ -248,7 +248,7 @@ icon_state = "mushroomsoup" trash = /obj/item/trash/snack_bowl filling_color = "#e386bf" - center_of_mass = @"{'x':17,'y':10}" + center_of_mass = @'{"x":17,"y":10}' nutriment_desc = list("mushroom" = 8, "milk" = 2) nutriment_amt = 8 bitesize = 3 @@ -260,7 +260,7 @@ icon_state = "beetsoup" trash = /obj/item/trash/snack_bowl filling_color = "#fac9ff" - center_of_mass = @"{'x':15,'y':8}" + center_of_mass = @'{"x":15,"y":8}' nutriment_desc = list("tomato" = 4, "beet" = 4) nutriment_amt = 8 bitesize = 2 diff --git a/code/modules/reagents/reagent_containers/food/soy.dm b/code/modules/reagents/reagent_containers/food/soy.dm index 727043f19be..15b7363f88a 100644 --- a/code/modules/reagents/reagent_containers/food/soy.dm +++ b/code/modules/reagents/reagent_containers/food/soy.dm @@ -3,22 +3,22 @@ icon_state = "tofu" desc = "We all love tofu." filling_color = "#fffee0" - center_of_mass = @"{'x':17,'y':10}" + center_of_mass = @'{"x":17,"y":10}' nutriment_amt = 3 nutriment_desc = list("tofu" = 3, "softness" = 3) bitesize = 3 /obj/item/chems/food/tofu/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/plant_protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/plant_protein, 6) /obj/item/chems/food/soydope name = "soy dope" desc = "Dope from a soy." icon_state = "soydope" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#c4bf76" - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("slime" = 2, "soy" = 2) nutriment_amt = 2 bitesize = 2 @@ -29,7 +29,7 @@ desc = "Vegan meat, on a stick." trash = /obj/item/stack/material/rods filling_color = "#fffee0" - center_of_mass = @"{'x':17,'y':15}" + center_of_mass = @'{"x":17,"y":15}' nutriment_desc = list("tofu" = 3, "metal" = 1) nutriment_amt = 8 bitesize = 2 @@ -39,7 +39,7 @@ desc = "A fake turkey made from tofu." icon_state = "tofurkey" filling_color = "#fffee0" - center_of_mass = @"{'x':16,'y':8}" + center_of_mass = @'{"x":16,"y":8}' nutriment_amt = 12 nutriment_desc = list("turkey" = 3, "tofu" = 5, "softness" = 4) bitesize = 3 @@ -48,8 +48,8 @@ name = "stewed soy meat" desc = "Even non-vegetarians will LOVE this!" icon_state = "stewedsoymeat" - trash = /obj/item/trash/plate - center_of_mass = @"{'x':16,'y':10}" + plate = /obj/item/plate + center_of_mass = @'{"x":16,"y":10}' nutriment_desc = list("soy" = 4, "tomato" = 4) nutriment_amt = 8 bitesize = 2 \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/veggie.dm b/code/modules/reagents/reagent_containers/food/veggie.dm index 3f8a53ff5dd..88f1945e956 100644 --- a/code/modules/reagents/reagent_containers/food/veggie.dm +++ b/code/modules/reagents/reagent_containers/food/veggie.dm @@ -8,14 +8,14 @@ icon_state = "aesirsalad" trash = /obj/item/trash/snack_bowl filling_color = "#468c00" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_amt = 8 nutriment_desc = list("apples" = 3,"salad" = 4, "quintessence" = 2) bitesize = 3 /obj/item/chems/food/aesirsalad/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/regenerator, 8) + add_to_reagents(/decl/material/liquid/regenerator, 8) /obj/item/chems/food/tossedsalad name = "tossed salad" @@ -23,7 +23,7 @@ icon_state = "herbsalad" trash = /obj/item/trash/snack_bowl filling_color = "#76b87f" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_desc = list("salad" = 2, "tomato" = 2, "carrot" = 2, "apple" = 2) nutriment_amt = 8 bitesize = 3 @@ -34,40 +34,40 @@ icon_state = "validsalad" trash = /obj/item/trash/snack_bowl filling_color = "#76b87f" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_desc = list("100% real salad") nutriment_amt = 6 bitesize = 3 /obj/item/chems/food/validsalad/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/carrotfries name = "carrot fries" desc = "Tasty fries from fresh carrots." icon_state = "carrotfries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#faa005" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_desc = list("carrot" = 3, "salt" = 1) nutriment_amt = 3 bitesize = 2 /obj/item/chems/food/carrotfries/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/eyedrops, 3) + add_to_reagents(/decl/material/liquid/eyedrops, 3) /obj/item/chems/food/hugemushroomslice name = "huge mushroom slice" desc = "A slice from a huge mushroom." icon_state = "hugemushroomslice" filling_color = "#e0d7c5" - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' nutriment_amt = 3 nutriment_desc = list("raw" = 2, "mushroom" = 2) bitesize = 6 /obj/item/chems/food/hugemushroomslice/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/psychotropics, 3) \ No newline at end of file + add_to_reagents(/decl/material/liquid/psychotropics, 3) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food_edibility.dm b/code/modules/reagents/reagent_containers/food_edibility.dm new file mode 100644 index 00000000000..adf50ab5db8 --- /dev/null +++ b/code/modules/reagents/reagent_containers/food_edibility.dm @@ -0,0 +1,48 @@ +/obj/item/chems/food/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user && user == target && isliving(user)) + var/mob/living/living_user = user + switch(living_user.get_food_satiation() / living_user.get_satiated_nutrition()) + if(-(INFINITY) to 0.2) + to_chat(living_user, SPAN_WARNING("You hungrily chew out a piece of [src] and gobble it!")) + if(0.2 to 0.4) + to_chat(living_user, SPAN_NOTICE("You hungrily begin to eat [src].")) + if(0.4 to 0.8) + . = ..() + else + to_chat(living_user, SPAN_NOTICE("You unwillingly chew a bit of [src].")) + +/obj/item/chems/food/play_feed_sound(mob/user, consumption_method = EATING_METHOD_EAT) + if(eat_sound) + playsound(user, pick(eat_sound), rand(10, 50), 1) + return + return ..() + +/obj/item/chems/food/handle_eaten_by_mob(mob/user, mob/target) + . = ..() + if(. == EATEN_SUCCESS) + bitecount++ + +/obj/item/chems/food/get_food_default_transfer_amount(mob/eater) + return eater?.get_eaten_transfer_amount(bitesize) + +/obj/item/chems/food/handle_consumed(mob/feeder, mob/eater, consumption_method = EATING_METHOD_EAT) + + if(isliving(eater) && cooked_food) + var/mob/living/living_eater = eater + living_eater.add_stressor(/datum/stressor/ate_cooked_food, 15 MINUTES) + + var/obj/item/plate_ref = plate + var/trash_ref = trash + . = ..() + if(.) + if(trash_ref) + if(ispath(trash_ref, /obj/item)) + var/obj/item/trash_item = new trash_ref(get_turf(feeder)) + feeder.put_in_hands(trash_item) + else if(istype(trash_ref, /obj/item)) + var/obj/item/trash_item = trash_ref + if(!QDELETED(trash_item)) + feeder.put_in_hands(trash_ref) + if(plate_ref && !QDELETED(plate_ref)) + feeder.put_in_hands(plate_ref) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index a8ef1a33350..7850344db12 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -47,19 +47,19 @@ return if(reagents?.total_volume) - to_chat(user, "It contains [reagents.total_volume] units of liquid.") + to_chat(user, SPAN_NOTICE("It contains [reagents.total_volume] units of liquid.")) else - to_chat(user, "It is empty.") + to_chat(user, SPAN_NOTICE("It is empty.")) if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, "The airtight lid seals it completely.") + to_chat(user,SPAN_NOTICE("The airtight lid seals it completely.")) /obj/item/chems/glass/attack_self() ..() if(ATOM_IS_OPEN_CONTAINER(src)) - to_chat(usr, "You put the lid on \the [src].") + to_chat(usr, SPAN_NOTICE("You put the lid on \the [src].")) atom_flags ^= ATOM_FLAG_OPEN_CONTAINER else - to_chat(usr, "You take the lid off \the [src].") + to_chat(usr, SPAN_NOTICE("You take the lid off \the [src].")) atom_flags |= ATOM_FLAG_OPEN_CONTAINER update_icon() @@ -68,20 +68,6 @@ return ..() return FALSE -/obj/item/chems/glass/standard_feed_mob(var/mob/user, var/mob/target) - if(!ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, "You need to open \the [src] first.") - return 1 - if(user.a_intent == I_HURT) - return 1 - return ..() - -/obj/item/chems/glass/self_feed_message(var/mob/user) - to_chat(user, "You swallow a gulp from \the [src].") - if(user.has_personal_goal(/datum/goal/achievement/specific_object/drink)) - for(var/R in reagents.reagent_volumes) - user.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) - /obj/item/chems/glass/afterattack(var/obj/target, var/mob/user, var/proximity) if(!ATOM_IS_OPEN_CONTAINER(src) || !proximity) //Is the container open & are they next to whatever they're clicking? return FALSE //If not, do nothing. @@ -92,7 +78,7 @@ return TRUE if(standard_pour_into(user, target)) //Pouring into another beaker? return TRUE - if(standard_feed_mob(user, target)) + if(handle_eaten_by_mob(user, target) != EATEN_INVALID) return TRUE if(user.a_intent == I_HURT) if(standard_splash_mob(user,target)) @@ -112,7 +98,7 @@ desc = "It's a bucket." icon = 'icons/obj/items/bucket.dmi' icon_state = ICON_STATE_WORLD - center_of_mass = @"{'x':16,'y':9}" + center_of_mass = @'{"x":16,"y":9}' w_class = ITEM_SIZE_NORMAL amount_per_transfer_from_this = 20 possible_transfer_amounts = @"[10,20,30,60,120,150,180]" diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 8e553466d3d..2eb7837f5a2 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/items/chem/bottle.dmi' icon_state = ICON_STATE_WORLD randpixel = 7 - center_of_mass = @"{'x':16,'y':15}" + center_of_mass = @'{"x":16,"y":15}' amount_per_transfer_from_this = 10 possible_transfer_amounts = @"[5,10,15,25,30,60]" w_class = ITEM_SIZE_SMALL @@ -64,8 +64,8 @@ update_icon() /obj/item/chems/glass/bottle/populate_reagents() - . = ..() SHOULD_CALL_PARENT(TRUE) + . = ..() if(reagents.total_volume > 0 && autolabel && !label_text) // don't override preset labels label_text = reagents.get_primary_reagent_name() update_container_name() @@ -74,46 +74,46 @@ desc = "A small bottle. Contains stabilizer - used to stabilize patients." /obj/item/chems/glass/bottle/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/stabilizer, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/bromide desc = "A small bottle of bromide. Do not drink, it is poisonous." /obj/item/chems/glass/bottle/bromide/populate_reagents() - reagents.add_reagent(/decl/material/liquid/bromide, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/bromide, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/cyanide desc = "A small bottle of cyanide. Bitter almonds?" /obj/item/chems/glass/bottle/cyanide/populate_reagents() - reagents.add_reagent(/decl/material/liquid/cyanide, reagents.maximum_volume / 2) //volume changed to match chloral + add_to_reagents(/decl/material/liquid/cyanide, reagents.maximum_volume / 2) //volume changed to match chloral . = ..() /obj/item/chems/glass/bottle/sedatives desc = "A small bottle of soporific medication. Just the fumes make you sleepy." /obj/item/chems/glass/bottle/sedatives/populate_reagents() - reagents.add_reagent(/decl/material/liquid/sedatives, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/sedatives, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/antitoxin desc = "A small bottle of antitoxins. Counters poisons, and repairs damage. A wonder drug." /obj/item/chems/glass/bottle/antitoxin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antitoxins, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/mutagenics desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact." /obj/item/chems/glass/bottle/mutagenics/populate_reagents() - reagents.add_reagent(/decl/material/liquid/mutagenics, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/mutagenics, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/ammonia/populate_reagents() - reagents.add_reagent(/decl/material/gas/ammonia, reagents.maximum_volume) + add_to_reagents(/decl/material/gas/ammonia, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/eznutrient @@ -124,7 +124,7 @@ material = /decl/material/solid/organic/plastic /obj/item/chems/glass/bottle/eznutrient/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fertilizer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/fertilizer, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/left4zed @@ -136,8 +136,8 @@ /obj/item/chems/glass/bottle/left4zed/populate_reagents() var/mutagen_amount = round(reagents.maximum_volume / 6) - reagents.add_reagent(/decl/material/liquid/fertilizer, reagents.maximum_volume - mutagen_amount) - reagents.add_reagent(/decl/material/liquid/mutagenics, mutagen_amount) + add_to_reagents(/decl/material/liquid/fertilizer, reagents.maximum_volume - mutagen_amount) + add_to_reagents(/decl/material/liquid/mutagenics, mutagen_amount) . = ..() /obj/item/chems/glass/bottle/robustharvest @@ -149,12 +149,12 @@ /obj/item/chems/glass/bottle/robustharvest/populate_reagents() var/amonia_amount = round(reagents.maximum_volume / 6) - reagents.add_reagent(/decl/material/liquid/fertilizer, reagents.maximum_volume - amonia_amount) - reagents.add_reagent(/decl/material/gas/ammonia, amonia_amount) + add_to_reagents(/decl/material/liquid/fertilizer, reagents.maximum_volume - amonia_amount) + add_to_reagents(/decl/material/gas/ammonia, amonia_amount) . = ..() /obj/item/chems/glass/bottle/pacid/populate_reagents() - reagents.add_reagent(/decl/material/liquid/acid/polyacid, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/acid/polyacid, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/adminordrazine desc = "A small bottle. Contains the liquid essence of the gods." @@ -163,19 +163,19 @@ label_color = COLOR_CYAN_BLUE /obj/item/chems/glass/bottle/adminordrazine/populate_reagents() - reagents.add_reagent(/decl/material/liquid/adminordrazine, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/adminordrazine, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/capsaicin desc = "A small bottle. Contains hot sauce." /obj/item/chems/glass/bottle/capsaicin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/capsaicin, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/capsaicin, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/frostoil desc = "A small bottle. Contains cold sauce." /obj/item/chems/glass/bottle/frostoil/populate_reagents() - reagents.add_reagent(/decl/material/liquid/frostoil, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/frostoil, reagents.maximum_volume) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm index 91ba1fd1c1d..54464dc8912 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm @@ -16,7 +16,7 @@ desc = "A small bottle. Contains stabilizer - used to stabilize patients." /obj/item/chems/glass/bottle/robot/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/stabilizer, reagents.maximum_volume) . = ..() /obj/item/chems/glass/bottle/robot/antitoxin @@ -26,5 +26,5 @@ icon_state = "bottle-4" /obj/item/chems/glass/bottle/robot/antitoxin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antitoxins, reagents.maximum_volume) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass_edibility.dm b/code/modules/reagents/reagent_containers/glass_edibility.dm new file mode 100644 index 00000000000..2ffbb91be5b --- /dev/null +++ b/code/modules/reagents/reagent_containers/glass_edibility.dm @@ -0,0 +1,26 @@ +/obj/item/chems/glass/handle_eaten_by_mob(var/mob/user, var/mob/target) + if(!ATOM_IS_OPEN_CONTAINER(src)) + to_chat(user, SPAN_WARNING("You need to open \the [src] first.")) + return EATEN_UNABLE + if(user.a_intent == I_HURT) + return EATEN_INVALID + . = ..() + if(. == EATEN_SUCCESS && target?.has_personal_goal(/datum/goal/achievement/specific_object/drink)) + for(var/R in reagents.reagent_volumes) + target.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) + +/obj/item/chems/glass/show_feed_message_start(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You begin trying to drink from \the [target].")) + else + user.visible_message(SPAN_NOTICE("\The [user] is trying to feed some of the contents of \the [src] to \the [target]!")) + +/obj/item/chems/glass/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow a gulp from \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] feeds some of the contents of \the [src] to \the [target]!")) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 9ad4c7d1243..cf4312166c3 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/hypospray.dmi' icon_state = ICON_STATE_WORLD abstract_type = /obj/item/chems/hypospray - origin_tech = "{'materials':4,'biotech':5}" + origin_tech = @'{"materials":4,"biotech":5}' amount_per_transfer_from_this = 5 volume = 30 possible_transfer_amounts = null @@ -174,7 +174,7 @@ icon = 'icons/obj/autoinjector.dmi' amount_per_transfer_from_this = 5 volume = 5 - origin_tech = "{'materials':2,'biotech':2}" + origin_tech = @'{"materials":2,"biotech":2}' slot_flags = SLOT_LOWER_BODY | SLOT_EARS w_class = ITEM_SIZE_TINY detail_state = "_band" @@ -182,7 +182,7 @@ /obj/item/chems/hypospray/autoinjector/populate_reagents() - reagents.add_reagent(/decl/material/liquid/adrenaline, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/adrenaline, reagents.maximum_volume) /obj/item/chems/hypospray/autoinjector/Initialize() . = ..() @@ -212,7 +212,7 @@ detail_color = COLOR_GREEN /obj/item/chems/hypospray/autoinjector/detox/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antitoxins, reagents.maximum_volume) //////////////////////////////////////////////////////////////////////////////// // Autoinjector - Pain @@ -222,7 +222,7 @@ detail_color = COLOR_PURPLE /obj/item/chems/hypospray/autoinjector/pain/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/painkillers, reagents.maximum_volume) //////////////////////////////////////////////////////////////////////////////// // Autoinjector - Antirad @@ -232,7 +232,7 @@ detail_color = COLOR_AMBER /obj/item/chems/hypospray/autoinjector/antirad/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antirads, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antirads, reagents.maximum_volume) //////////////////////////////////////////////////////////////////////////////// // Autoinjector - Hallucinogenics @@ -242,7 +242,7 @@ detail_color = COLOR_DARK_GRAY /obj/item/chems/hypospray/autoinjector/hallucinogenics/populate_reagents() - reagents.add_reagent(/decl/material/liquid/hallucinogenics, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/hallucinogenics, reagents.maximum_volume) //////////////////////////////////////////////////////////////////////////////// // Autoinjector - Clotting agent @@ -255,8 +255,8 @@ /obj/item/chems/hypospray/autoinjector/clotting/populate_reagents() . = ..() var/amt = round(reagents.maximum_volume*0.5) - reagents.add_reagent(/decl/material/liquid/stabilizer, amt) - reagents.add_reagent(/decl/material/liquid/clotting_agent, (reagents.maximum_volume - amt)) + add_to_reagents(/decl/material/liquid/stabilizer, amt) + add_to_reagents(/decl/material/liquid/clotting_agent, (reagents.maximum_volume - amt)) //////////////////////////////////////////////////////////////////////////////// // Autoinjector - Empty diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm index b265d36b703..f78262a4cfa 100644 --- a/code/modules/reagents/reagent_containers/inhaler.dm +++ b/code/modules/reagents/reagent_containers/inhaler.dm @@ -5,14 +5,14 @@ desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel." icon = 'icons/obj/inhaler.dmi' icon_state = ICON_STATE_WORLD - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' amount_per_transfer_from_this = 5 volume = 5 w_class = ITEM_SIZE_SMALL possible_transfer_amounts = null atom_flags = ATOM_FLAG_OPEN_CONTAINER slot_flags = SLOT_LOWER_BODY - origin_tech = "{'materials':2,'biotech':2}" + origin_tech = @'{"materials":2,"biotech":2}' material = /decl/material/solid/organic/plastic matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, @@ -27,7 +27,7 @@ /obj/item/chems/inhaler/Initialize() . = ..() for(var/T in starts_with) - reagents.add_reagent(T, starts_with[T]) + add_to_reagents(T, starts_with[T]) if(ATOM_IS_OPEN_CONTAINER(src) && reagents.total_volume > 0) atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER update_icon() diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 712e8426a1c..2a78029c5cf 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -25,7 +25,7 @@ /obj/item/chems/pill/on_update_icon() . = ..() if(icon_state in colorizable_icon_states) - color = reagents.get_color() + color = reagents?.get_color() alpha = 255 // above probably reset our alpha else color = null @@ -36,49 +36,18 @@ /obj/item/chems/pill/dragged_onto(var/mob/user) attack(user, user) -/obj/item/chems/pill/attack(mob/M, mob/user, def_zone) - //TODO: replace with standard_feed_mob() call. - if(M == user) - if(!M.can_eat(src)) - return - M.visible_message(SPAN_NOTICE("[M] swallows a pill."), SPAN_NOTICE("You swallow \the [src]."), null, 2) - if(reagents?.total_volume) - reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST) - qdel(src) - return 1 - - else if(ishuman(M)) - if(!M.can_force_feed(user, src)) - return - - user.visible_message(SPAN_WARNING("[user] attempts to force [M] to swallow \the [src].")) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - if(!do_mob(user, M)) - return - user.visible_message(SPAN_WARNING("[user] forces [M] to swallow \the [src].")) - var/contained = REAGENT_LIST(src) - admin_attack_log(user, M, "Fed the victim with [name] (Reagents: [contained])", "Was fed [src] (Reagents: [contained])", "used [src] (Reagents: [contained]) to feed") - if(reagents.total_volume) - reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST) - qdel(src) - return 1 - - return 0 - /obj/item/chems/pill/afterattack(obj/target, mob/user, proximity) - if(!proximity) return - - if(ATOM_IS_OPEN_CONTAINER(target) && target.reagents) + if(proximity && ATOM_IS_OPEN_CONTAINER(target) && target.reagents) if(!target.reagents.total_volume) - to_chat(user, "[target] is empty. Can't dissolve \the [src].") + to_chat(user, SPAN_WARNING("\The [target] is empty. You can't dissolve \the [src] in it.")) return - to_chat(user, "You dissolve \the [src] in [target].") - + to_chat(user, SPAN_NOTICE("You dissolve \the [src] in \the [target].")) + user.visible_message(SPAN_NOTICE("\The [user] puts something in \the [target]."), range = 2) admin_attacker_log(user, "spiked \a [target] with a pill. Reagents: [REAGENT_LIST(src)]") reagents.trans_to(target, reagents.total_volume) - user.visible_message(SPAN_NOTICE("\The [user] puts something in \the [target]."), range = 2) qdel(src) - return + return + return ..() //////////////////////////////////////////////////////////////////////////////// /// Pills. END @@ -92,7 +61,7 @@ volume = 50 /obj/item/chems/pill/bromide/populate_reagents() - reagents.add_reagent(/decl/material/liquid/bromide, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/bromide, reagents.maximum_volume) /obj/item/chems/pill/cyanide name = "strange pill" @@ -101,7 +70,7 @@ volume = 50 /obj/item/chems/pill/cyanide/populate_reagents() - reagents.add_reagent(/decl/material/liquid/cyanide, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/cyanide, reagents.maximum_volume) /obj/item/chems/pill/adminordrazine name = "Adminordrazine pill" @@ -109,7 +78,7 @@ icon_state = "pillA" /obj/item/chems/pill/adminordrazine/populate_reagents() - reagents.add_reagent(/decl/material/liquid/adminordrazine, 1) + add_to_reagents(/decl/material/liquid/adminordrazine, 1) /obj/item/chems/pill/stox name = "sedatives (15u)" @@ -117,7 +86,7 @@ icon_state = "pill3" /obj/item/chems/pill/stox/populate_reagents() - reagents.add_reagent(/decl/material/liquid/sedatives, 15) + add_to_reagents(/decl/material/liquid/sedatives, 15) /obj/item/chems/pill/burn_meds name = "synthskin (15u)" @@ -125,7 +94,7 @@ icon_state = "pill2" /obj/item/chems/pill/burn_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/burn_meds, 15) + add_to_reagents(/decl/material/liquid/burn_meds, 15) /obj/item/chems/pill/painkillers name = "painkillers (15u)" @@ -133,7 +102,7 @@ icon_state = "pill3" /obj/item/chems/pill/painkillers/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers, 15) + add_to_reagents(/decl/material/liquid/painkillers, 15) /obj/item/chems/pill/strong_painkillers name = "strong painkillers (15u)" @@ -141,7 +110,7 @@ icon_state = "pill3" /obj/item/chems/pill/strong_painkillers/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers/strong, 15) + add_to_reagents(/decl/material/liquid/painkillers/strong, 15) /obj/item/chems/pill/stabilizer name = "stabilizer (30u)" @@ -149,7 +118,7 @@ icon_state = "pill1" /obj/item/chems/pill/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, 30) + add_to_reagents(/decl/material/liquid/stabilizer, 30) /obj/item/chems/pill/oxygen name = "oxygen (15u)" @@ -157,7 +126,7 @@ icon_state = "pill1" /obj/item/chems/pill/oxygen/populate_reagents() - reagents.add_reagent(/decl/material/liquid/oxy_meds, 15) + add_to_reagents(/decl/material/liquid/oxy_meds, 15) /obj/item/chems/pill/antitoxins name = "antitoxins (25u)" @@ -166,7 +135,7 @@ /obj/item/chems/pill/antitoxins/populate_reagents() // Antitox is easy to make and has no OD threshold so we can get away with big pills. - reagents.add_reagent(/decl/material/liquid/antitoxins, 25) + add_to_reagents(/decl/material/liquid/antitoxins, 25) /obj/item/chems/pill/brute_meds name = "styptic (20u)" @@ -174,7 +143,7 @@ icon_state = "pill2" /obj/item/chems/pill/brute_meds/populate_reagents() - reagents.add_reagent(/decl/material/liquid/brute_meds, 20) + add_to_reagents(/decl/material/liquid/brute_meds, 20) /obj/item/chems/pill/happy name = "happy pill" @@ -182,8 +151,8 @@ icon_state = "pill4" /obj/item/chems/pill/happy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/psychoactives, 15) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 15) + add_to_reagents(/decl/material/liquid/psychoactives, 15) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 15) /obj/item/chems/pill/zoom name = "zoom pill" @@ -191,10 +160,10 @@ icon_state = "pill4" /obj/item/chems/pill/zoom/populate_reagents() - reagents.add_reagent(/decl/material/liquid/narcotics, 5) - reagents.add_reagent(/decl/material/liquid/antidepressants, 5) - reagents.add_reagent(/decl/material/liquid/stimulants, 5) - reagents.add_reagent(/decl/material/liquid/amphetamines, 5) + add_to_reagents(/decl/material/liquid/narcotics, 5) + add_to_reagents(/decl/material/liquid/antidepressants, 5) + add_to_reagents(/decl/material/liquid/stimulants, 5) + add_to_reagents(/decl/material/liquid/amphetamines, 5) /obj/item/chems/pill/gleam name = "strange pill" @@ -202,7 +171,7 @@ icon_state = "pill2" /obj/item/chems/pill/gleam/populate_reagents() - reagents.add_reagent(/decl/material/liquid/glowsap/gleam, 10) + add_to_reagents(/decl/material/liquid/glowsap/gleam, 10) /obj/item/chems/pill/antibiotics name = "antibiotics (10u)" @@ -210,7 +179,7 @@ icon_state = "pill3" /obj/item/chems/pill/antibiotics/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antibiotics, 10) + add_to_reagents(/decl/material/liquid/antibiotics, 10) //Psychiatry pills. /obj/item/chems/pill/stimulants @@ -219,7 +188,7 @@ icon_state = "pill2" /obj/item/chems/pill/stimulants/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stimulants, 15) + add_to_reagents(/decl/material/liquid/stimulants, 15) /obj/item/chems/pill/antidepressants name = "antidepressants (15u)" @@ -227,7 +196,7 @@ icon_state = "pill4" /obj/item/chems/pill/antidepressants/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antidepressants, 15) + add_to_reagents(/decl/material/liquid/antidepressants, 15) /obj/item/chems/pill/antirads name = "antirads (7u)" @@ -235,7 +204,7 @@ icon_state = "pill1" /obj/item/chems/pill/antirads/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antirads, 7) + add_to_reagents(/decl/material/liquid/antirads, 7) /obj/item/chems/pill/antirad name = "AntiRad" @@ -243,8 +212,8 @@ icon_state = "yellow" /obj/item/chems/pill/antirad/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antirads, 5) - reagents.add_reagent(/decl/material/liquid/antitoxins, 10) + add_to_reagents(/decl/material/liquid/antirads, 5) + add_to_reagents(/decl/material/liquid/antitoxins, 10) /obj/item/chems/pill/sugariron name = "Sugar-Iron (10u)" @@ -252,21 +221,20 @@ icon_state = "pill1" /obj/item/chems/pill/sugariron/populate_reagents() - reagents.add_reagent(/decl/material/solid/metal/iron, 5) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 5) + add_to_reagents(/decl/material/solid/metal/iron, 5) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 5) /obj/item/chems/pill/detergent name = "detergent pod" desc = "Put in water to get space cleaner. Do not eat. Really." icon_state = "pod21" - var/smell_clean_time = 10 MINUTES // Don't overwrite the custom name. /obj/item/chems/pill/detergent/update_container_name() return /obj/item/chems/pill/detergent/populate_reagents() - reagents.add_reagent(/decl/material/gas/ammonia, 30) + add_to_reagents(/decl/material/liquid/contaminant_cleaner, 30) /obj/item/chems/pill/pod name = "master flavorpod item" @@ -281,22 +249,22 @@ name = "creamer pod" /obj/item/chems/pill/pod/cream/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk, 5) + add_to_reagents(/decl/material/liquid/drink/milk, 5) /obj/item/chems/pill/pod/cream_soy name = "non-dairy creamer pod" /obj/item/chems/pill/pod/cream_soy/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/milk/soymilk, 5) + add_to_reagents(/decl/material/liquid/drink/milk/soymilk, 5) /obj/item/chems/pill/pod/orange name = "orange flavorpod" /obj/item/chems/pill/pod/orange/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/juice/orange, 5) + add_to_reagents(/decl/material/liquid/drink/juice/orange, 5) /obj/item/chems/pill/pod/mint name = "mint flavorpod" /obj/item/chems/pill/pod/mint/populate_reagents() - reagents.add_reagent(/decl/material/liquid/drink/syrup/mint, 1) + add_to_reagents(/decl/material/liquid/drink/syrup/mint, 1) diff --git a/code/modules/reagents/reagent_containers/pill_edibility.dm b/code/modules/reagents/reagent_containers/pill_edibility.dm new file mode 100644 index 00000000000..9aa114344fc --- /dev/null +++ b/code/modules/reagents/reagent_containers/pill_edibility.dm @@ -0,0 +1,24 @@ +/obj/item/chems/pill/get_food_default_transfer_amount(mob/eater) + return reagents?.total_volume // Always eat it in one bite. + +/obj/item/chems/pill/show_feed_message_start(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You begin trying to swallow \the [target].")) + else + user.visible_message(SPAN_NOTICE("\The [user] attempts to force \the [target] to swallow \the [src]!")) + +/obj/item/chems/pill/show_feed_message_end(var/mob/user, var/mob/target) + target = target || user + if(user) + if(user == target) + to_chat(user, SPAN_NOTICE("You swallow \the [src].")) + else + user.visible_message(SPAN_NOTICE("\The [user] forces \the [target] to swallow \the [src]!")) + +/obj/item/chems/pill/play_feed_sound(mob/user, consumption_method = EATING_METHOD_EAT) + return + +/obj/item/chems/pill/show_food_consumed_message(mob/user, mob/target) + return diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 3d16cb63e44..8b9a9447bad 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -137,21 +137,21 @@ particle_move_delay = 6 /obj/item/chems/spray/cleaner/populate_reagents() - reagents.add_reagent(/decl/material/liquid/cleaner, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/cleaner, reagents.maximum_volume) /obj/item/chems/spray/antiseptic name = "antiseptic spray" desc = "Great for hiding incriminating bloodstains and sterilizing scalpels." /obj/item/chems/spray/antiseptic/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antiseptic, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antiseptic, reagents.maximum_volume) /obj/item/chems/spray/hair_remover name = "hair remover" desc = "Very effective at removing hair, feathers, spines and horns." /obj/item/chems/spray/hair_remover/populate_reagents() - reagents.add_reagent(/decl/material/liquid/hair_remover, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/hair_remover, reagents.maximum_volume) /obj/item/chems/spray/pepper name = "pepperspray" @@ -164,7 +164,7 @@ safety = TRUE /obj/item/chems/spray/pepper/populate_reagents() - reagents.add_reagent(/decl/material/liquid/capsaicin/condensed, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/capsaicin/condensed, reagents.maximum_volume) /obj/item/chems/spray/pepper/has_safety() return TRUE @@ -180,7 +180,7 @@ volume = 10 /obj/item/chems/spray/waterflower/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) /obj/item/chems/spray/chemsprayer name = "chem sprayer" @@ -192,7 +192,7 @@ w_class = ITEM_SIZE_LARGE possible_transfer_amounts = null volume = 600 - origin_tech = "{'combat':3,'materials':3,'engineering':3}" + origin_tech = @'{"combat":3,"materials":3,"engineering":3}' particle_move_delay = 2 //Was hardcoded to 2 before, and 8 was slower than most mob's move speed material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) @@ -219,7 +219,7 @@ volume = 100 /obj/item/chems/spray/plantbgone/populate_reagents() - reagents.add_reagent(/decl/material/liquid/weedkiller, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/weedkiller, reagents.maximum_volume) /obj/item/chems/spray/plantbgone/afterattack(atom/A, mob/user, proximity) if(!proximity) return diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index b6b9c0dcd66..b16b1d8ce33 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -19,15 +19,29 @@ slot_flags = SLOT_EARS sharp = 1 item_flags = ITEM_FLAG_NO_BLUDGEON + var/mode = SYRINGE_DRAW var/visible_name = "a syringe" var/time = 30 + var/autolabel = TRUE // if set, will add label with the name of the first initial reagent var/can_stab = TRUE /obj/item/chems/syringe/Initialize(var/mapload) . = ..() update_icon() +/obj/item/chems/syringe/populate_reagents() + SHOULD_CALL_PARENT(TRUE) + . = ..() + if(reagents.total_volume > 0 && autolabel && !label_text) // don't override preset labels + label_text = reagents.get_primary_reagent_name() + update_container_name() + + +/obj/item/chems/syringe/on_reagent_change() + . = ..() + update_icon() + /obj/item/chems/syringe/on_picked_up(mob/user) . = ..() update_icon() @@ -309,10 +323,12 @@ visible_name = "a giant syringe" time = 300 mode = SYRINGE_INJECT + autolabel = FALSE can_stab = FALSE /obj/item/chems/syringe/ld50_syringe/populate_reagents() - reagents.add_reagent(/decl/material/liquid/heartstopper, reagents.maximum_volume) + SHOULD_CALL_PARENT(FALSE) + add_to_reagents(/decl/material/liquid/heartstopper, reagents.maximum_volume) /obj/item/chems/syringe/ld50_syringe/drawReagents(var/target, var/mob/user) if(ismob(target)) // No drawing 60 units of blood at once @@ -325,49 +341,49 @@ //////////////////////////////////////////////////////////////////////////////// /obj/item/chems/syringe/stabilizer - name = "syringe (stabilizer)" desc = "Contains stabilizer - for patients in danger of brain damage." mode = SYRINGE_INJECT /obj/item/chems/syringe/stabilizer/populate_reagents() - reagents.add_reagent(/decl/material/liquid/stabilizer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/stabilizer, reagents.maximum_volume) + return ..() /obj/item/chems/syringe/antitoxin - name = "syringe (anti-toxin)" desc = "Contains anti-toxins." mode = SYRINGE_INJECT /obj/item/chems/syringe/antitoxin/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antitoxins, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antitoxins, reagents.maximum_volume) + return ..() /obj/item/chems/syringe/antibiotic - name = "syringe (antibiotics)" desc = "Contains antibiotic agents." mode = SYRINGE_INJECT /obj/item/chems/syringe/antibiotic/populate_reagents() - reagents.add_reagent(/decl/material/liquid/antibiotics, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/antibiotics, reagents.maximum_volume) + return ..() /obj/item/chems/syringe/drugs - name = "syringe (drugs)" desc = "Contains aggressive drugs meant for torture." mode = SYRINGE_INJECT /obj/item/chems/syringe/drugs/populate_reagents() var/vol_each = round(reagents.maximum_volume / 3) - reagents.add_reagent(/decl/material/liquid/psychoactives, vol_each) - reagents.add_reagent(/decl/material/liquid/hallucinogenics, vol_each) - reagents.add_reagent(/decl/material/liquid/presyncopics, vol_each) + add_to_reagents(/decl/material/liquid/psychoactives, vol_each) + add_to_reagents(/decl/material/liquid/hallucinogenics, vol_each) + add_to_reagents(/decl/material/liquid/presyncopics, vol_each) + return ..() /obj/item/chems/syringe/steroid - name = "syringe (anabolic steroids)" desc = "Contains drugs for muscle growth." mode = SYRINGE_INJECT /obj/item/chems/syringe/steroid/populate_reagents() var/vol_third = round(reagents.maximum_volume/3) - reagents.add_reagent(/decl/material/liquid/adrenaline, vol_third) - reagents.add_reagent(/decl/material/liquid/amphetamines, 2 * vol_third) + add_to_reagents(/decl/material/liquid/adrenaline, vol_third) + add_to_reagents(/decl/material/liquid/amphetamines, 2 * vol_third) + return ..() // TG ports @@ -382,7 +398,7 @@ /decl/material/solid/phoron = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) - origin_tech = "{'biotech':3,'materials':4,'exoticmatter':2}" + origin_tech = @'{"biotech":3,"materials":4,"exoticmatter":2}' /obj/item/chems/syringe/noreact name = "cryostasis syringe" @@ -395,4 +411,4 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/organic/plastic = MATTER_AMOUNT_TRACE ) - origin_tech = "{'biotech':4,'materials':4}" + origin_tech = @'{"biotech":4,"materials":4}' diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index b7ea1a71c81..65c59c24d42 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -45,11 +45,6 @@ if(. && unwrenched) leak() -/obj/structure/reagent_dispensers/Process() - if(!unwrenched) - return PROCESS_KILL - leak() - /obj/structure/reagent_dispensers/examine(mob/user, distance) . = ..() if(unwrenched) @@ -70,19 +65,13 @@ if(reagents?.maximum_volume) to_chat(user, "It may contain up to [reagents.maximum_volume] units of fluid.") -/obj/structure/reagent_dispensers/Destroy() - . = ..() - STOP_PROCESSING(SSprocessing, src) - /obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user) if(IS_WRENCH(W)) unwrenched = !unwrenched visible_message(SPAN_NOTICE("\The [user] wrenches \the [src]'s tap [unwrenched ? "open" : "shut"].")) if(unwrenched) log_and_message_admins("opened a tank at [get_area_name(loc)].") - START_PROCESSING(SSprocessing, src) - else - STOP_PROCESSING(SSprocessing, src) + leak() return TRUE . = ..() @@ -133,7 +122,7 @@ movable_flags = MOVABLE_FLAG_WHEELED /obj/structure/reagent_dispensers/watertank/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) /obj/structure/reagent_dispensers/watertank/firefighter name = "firefighting water reserve" @@ -158,7 +147,7 @@ var/obj/item/assembly_holder/rig /obj/structure/reagent_dispensers/fueltank/populate_reagents() - reagents.add_reagent(/decl/material/liquid/fuel, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/fuel, reagents.maximum_volume) /obj/structure/reagent_dispensers/fueltank/examine(mob/user, distance) . = ..() @@ -238,7 +227,7 @@ amount_dispensed = 45 /obj/structure/reagent_dispensers/peppertank/populate_reagents() - reagents.add_reagent(/decl/material/liquid/capsaicin/condensed, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/capsaicin/condensed, reagents.maximum_volume) /obj/structure/reagent_dispensers/water_cooler name = "water cooler" @@ -255,7 +244,7 @@ var/tmp/cup_type = /obj/item/chems/drinks/sillycup /obj/structure/reagent_dispensers/water_cooler/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume) /obj/structure/reagent_dispensers/water_cooler/attack_hand(var/mob/user) if(user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) @@ -301,7 +290,7 @@ matter = list(/decl/material/solid/metal/stainlesssteel = MATTER_AMOUNT_TRACE) /obj/structure/reagent_dispensers/beerkeg/populate_reagents() - reagents.add_reagent(/decl/material/liquid/ethanol/beer, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume) /obj/structure/reagent_dispensers/acid name = "sulphuric acid dispenser" @@ -311,7 +300,7 @@ anchored = TRUE /obj/structure/reagent_dispensers/acid/populate_reagents() - reagents.add_reagent(/decl/material/liquid/acid, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/acid, reagents.maximum_volume) //Interactions /obj/structure/reagent_dispensers/get_alt_interactions(var/mob/user) diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 0d264554032..872ba33b569 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -4,8 +4,8 @@ /obj/structure/disposalconstruct name = "disposal pipe segment" desc = "A huge pipe segment used for constructing disposal systems." - icon = 'icons/obj/pipes/disposal.dmi' icon_state = "conpipe-s" + icon = 'icons/obj/pipes/disposal_pipe.dmi' anchored = FALSE density = FALSE material = /decl/material/solid/metal/steel diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 27a50a3634d..3ce1e27d9d3 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -14,7 +14,7 @@ var/global/list/diversion_junctions = list() /obj/machinery/disposal name = "disposal unit" desc = "A pneumatic waste disposal unit." - icon = 'icons/obj/pipes/disposal.dmi' + icon = 'icons/obj/pipes/disposal_bin.dmi' icon_state = "disposal" anchored = TRUE density = TRUE @@ -302,7 +302,7 @@ var/global/list/diversion_junctions = list() // update the icon & overlays to reflect mode & status /obj/machinery/disposal/on_update_icon() - overlays.Cut() + cut_overlays() if(stat & BROKEN) mode = 0 flush = 0 @@ -310,7 +310,7 @@ var/global/list/diversion_junctions = list() // flush handle if(flush) - overlays += image('icons/obj/pipes/disposal.dmi', "dispover-handle") + add_overlay("[icon_state]-handle") // only handle is shown if no power if(stat & NOPOWER || mode == -1) @@ -318,13 +318,13 @@ var/global/list/diversion_junctions = list() // check for items in disposal - occupied light if(contents.len > LAZYLEN(component_parts)) - overlays += image('icons/obj/pipes/disposal.dmi', "dispover-full") + add_overlay("[icon_state]-full") // charging and ready light if(mode == 1) - overlays += image('icons/obj/pipes/disposal.dmi', "dispover-charge") + add_overlay("[icon_state]-charge") else if(mode == 2) - overlays += image('icons/obj/pipes/disposal.dmi', "dispover-ready") + add_overlay("[icon_state]-ready") // timed process // charge the gas reservoir and perform flush if ready @@ -532,7 +532,7 @@ var/global/list/diversion_junctions = list() /obj/structure/disposaloutlet name = "disposal outlet" desc = "An outlet for the pneumatic disposal system." - icon = 'icons/obj/pipes/disposal.dmi' + icon = 'icons/obj/pipes/disposal_outlet.dmi' icon_state = "outlet" density = TRUE anchored = TRUE @@ -565,7 +565,7 @@ var/global/list/diversion_junctions = list() /obj/structure/disposaloutlet/proc/animate_expel() set waitfor = FALSE - flick("outlet-open", src) + flick("[icon_state]-open", src) playsound(src, 'sound/machines/warning-buzzer.ogg', 50, 0, 0) sleep(20) //wait until correct animation frame playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm index 1ef619ed011..c187f585b02 100644 --- a/code/modules/recycling/disposalpipe.dm +++ b/code/modules/recycling/disposalpipe.dm @@ -1,7 +1,7 @@ // Disposal pipes /obj/structure/disposalpipe - icon = 'icons/obj/pipes/disposal.dmi' + icon = 'icons/obj/pipes/disposal_pipe.dmi' name = "disposal pipe" desc = "An underfloor disposal pipe." anchored = TRUE diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 048a2674cbf..1a1ecb8cd9c 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -2,7 +2,8 @@ name = "delivery chute" desc = "A chute for big and small packages alike!" density = TRUE - icon_state = "intake" + icon = 'icons/obj/pipes/disposal_chute.dmi' + icon_state = "chute" base_type = /obj/machinery/disposal/deliveryChute/buildable frame_type = /obj/structure/disposalconstruct/machine/chute @@ -47,7 +48,7 @@ /obj/machinery/disposal/deliveryChute/flush() flushing = 1 - flick("intake-closing", src) + flick("[icon_state]-closing", src) var/obj/structure/disposalholder/H = new() // virtual holder object which actually // travels through the pipes. air_contents = new() // new empty gas resv. diff --git a/code/modules/research/design_database_analyzer.dm b/code/modules/research/design_database_analyzer.dm index bce7bff5a42..b0c3c4150bb 100644 --- a/code/modules/research/design_database_analyzer.dm +++ b/code/modules/research/design_database_analyzer.dm @@ -114,7 +114,7 @@ loaded_item = O to_chat(user, SPAN_NOTICE("You add \the [O] to \the [src].")) flick("d_analyzer_la", src) - addtimer(CALLBACK(src, .proc/refresh_busy), 1 SECOND) + addtimer(CALLBACK(src, PROC_REF(refresh_busy)), 1 SECOND) return TRUE /obj/machinery/destructive_analyzer/proc/refresh_busy() @@ -140,12 +140,12 @@ else loaded_item = null flick("d_analyzer_process", src) - addtimer(CALLBACK(src, .proc/refresh_busy), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(refresh_busy)), 2 SECONDS) /obj/item/research name = "research debugging device" desc = "Instant research tool. For testing purposes only." icon = 'icons/obj/items/stock_parts/stock_parts.dmi' icon_state = "smes_coil" - origin_tech = "{'materials':19,'engineering':19,'exoticmatter':19,'powerstorage':19,'wormholes':19,'biotech':19,'combat':19,'magnets':19,'programming':19,'esoteric':19}" + origin_tech = @'{"materials":19,"engineering":19,"exoticmatter":19,"powerstorage":19,"wormholes":19,"biotech":19,"combat":19,"magnets":19,"programming":19,"esoteric":19}' max_health = ITEM_HEALTH_NO_DAMAGE diff --git a/code/modules/sealant_gun/sealant_gun.dm b/code/modules/sealant_gun/sealant_gun.dm index 527d0fc4448..9d7ed168682 100644 --- a/code/modules/sealant_gun/sealant_gun.dm +++ b/code/modules/sealant_gun/sealant_gun.dm @@ -22,10 +22,12 @@ if(loaded_tank) add_overlay("[icon_state]-tank") -/obj/item/gun/launcher/sealant/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/gun/launcher/sealant/apply_gun_mob_overlays(var/mob/living/user_mob, var/bodytype, var/image/overlay, var/slot, var/bodypart, var/skip_offset = FALSE) if(overlay && loaded_tank) - overlay.overlays += image(overlay.icon, "[overlay.icon_state]-tank") - . = ..() + var/tank_state = "[overlay.icon_state]-tank" + if(check_state_in_icon(tank_state, overlay.icon)) + overlay.overlays += image(overlay.icon, tank_state) + ..() /obj/item/gun/launcher/sealant/mapped loaded_tank = /obj/item/sealant_tank/mapped diff --git a/code/modules/sealant_gun/sealant_injector.dm b/code/modules/sealant_gun/sealant_injector.dm index 8eee5ee365a..d48d47109e3 100644 --- a/code/modules/sealant_gun/sealant_injector.dm +++ b/code/modules/sealant_gun/sealant_injector.dm @@ -1,8 +1,8 @@ /obj/item/chems/chem_disp_cartridge/foaming_agent/populate_reagents() - reagents.add_reagent(/decl/material/liquid/foaming_agent, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/foaming_agent, reagents.maximum_volume) /obj/item/chems/chem_disp_cartridge/polyacid/populate_reagents() - reagents.add_reagent(/decl/material/liquid/acid/polyacid, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/acid/polyacid, reagents.maximum_volume) /obj/structure/sealant_injector name = "sealant tank injector" diff --git a/code/modules/security levels/keycard_authentication.dm b/code/modules/security levels/keycard_authentication.dm index 036f61b6f6b..6af4ec58fdc 100644 --- a/code/modules/security levels/keycard_authentication.dm +++ b/code/modules/security levels/keycard_authentication.dm @@ -9,7 +9,7 @@ active_power_usage = 6 power_channel = ENVIRON obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-20}, 'SOUTH':{'y':28}, 'EAST':{'x':-24}, 'WEST':{'x':24}}" + directional_offset = @'{"NORTH":{"y":-20}, "SOUTH":{"y":28}, "EAST":{"x":-24}, "WEST":{"x":24}}' var/active = 0 //This gets set to 1 on all devices except the one where the initial request was made. var/event = "" @@ -79,7 +79,7 @@ else dat += "
  • Engage [security_state.high_security_level.name]
  • " - if(!config.ert_admin_call_only) + if(!get_config_value(/decl/config/toggle/ert_admin_call_only)) dat += "
  • Emergency Response Team
  • " dat += "
  • Grant Emergency Maintenance Access
  • " @@ -130,10 +130,10 @@ if(KA == src) continue KA.reset() - addtimer(CALLBACK(src, .proc/receive_request, src, initial_card.resolve())) + addtimer(CALLBACK(src, PROC_REF(receive_request), src, initial_card.resolve())) if(confirm_delay) - addtimer(CALLBACK(src, .proc/broadcast_check), confirm_delay) + addtimer(CALLBACK(src, PROC_REF(broadcast_check)), confirm_delay) /obj/machinery/keycard_auth/proc/broadcast_check() if(confirmed) @@ -192,8 +192,9 @@ SSstatistics.add_field("alert_keycard_auth_nukecode",1) /obj/machinery/keycard_auth/proc/is_ert_blocked() - if(config.ert_admin_call_only) return 1 - return SSticker.mode && SSticker.mode.ert_disabled + if(get_config_value(/decl/config/toggle/ert_admin_call_only)) + return TRUE + return SSticker.mode?.ert_disabled /obj/machinery/keycard_auth/update_directional_offset(force = FALSE) if(!force && (!length(directional_offset) || !is_wall_mounted())) //Check if the thing is actually mapped onto a table or something diff --git a/code/modules/shield_generators/handheld_diffuser.dm b/code/modules/shield_generators/handheld_diffuser.dm index 466ca25642f..d74998a1b38 100644 --- a/code/modules/shield_generators/handheld_diffuser.dm +++ b/code/modules/shield_generators/handheld_diffuser.dm @@ -3,7 +3,7 @@ desc = "A small handheld device designed to disrupt energy barriers." icon = 'icons/obj/machines/shielding.dmi' icon_state = "hdiffuser_off" - origin_tech = "{'magnets':5,'powerstorage':5,'esoteric':2}" + origin_tech = @'{"magnets":5,"powerstorage":5,"esoteric":2}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/shield_generators/shield.dm b/code/modules/shield_generators/shield.dm index f4f1c140349..166c267169d 100644 --- a/code/modules/shield_generators/shield.dm +++ b/code/modules/shield_generators/shield.dm @@ -169,23 +169,15 @@ if(!gen) qdel(src) return 1 - if(disabled_for || diffused_for) return 1 - // Atmosphere containment. if(air_group) return !gen.check_flag(MODEFLAG_ATMOSPHERIC) - if(mover) return mover.can_pass_shield(gen) return 1 - -/obj/effect/shield/c_airblock(turf/other) - return gen.check_flag(MODEFLAG_ATMOSPHERIC) ? BLOCKED : 0 - - // EMP. It may seem weak but keep in mind that multiple shield segments are likely to be affected. /obj/effect/shield/emp_act(var/severity) if(!disabled_for) @@ -322,7 +314,7 @@ affected_shields |= src i-- if(i) - addtimer(CALLBACK(src, .proc/spread_impact_effect, i, affected_shields), 2) + addtimer(CALLBACK(src, PROC_REF(spread_impact_effect), i, affected_shields), 2) /obj/effect/shield/proc/spread_impact_effect(var/i, var/list/affected_shields = list()) for(var/direction in global.cardinal) diff --git a/code/modules/shield_generators/shield_generator.dm b/code/modules/shield_generators/shield_generator.dm index d0a84fc3e8f..0b4a9d14a47 100644 --- a/code/modules/shield_generators/shield_generator.dm +++ b/code/modules/shield_generators/shield_generator.dm @@ -57,7 +57,7 @@ for(var/st in subtypesof(/datum/shield_mode/)) var/datum/shield_mode/SM = new st() mode_list.Add(SM) - events_repository.register(/decl/observ/moved, src, src, .proc/update_overmap_shield_list) + events_repository.register(/decl/observ/moved, src, src, PROC_REF(update_overmap_shield_list)) . = INITIALIZE_HINT_LATELOAD /obj/machinery/shield_generator/LateInitialize() diff --git a/code/modules/shuttles/docking_beacon.dm b/code/modules/shuttles/docking_beacon.dm index a8b99cbc9e1..84721e66431 100644 --- a/code/modules/shuttles/docking_beacon.dm +++ b/code/modules/shuttles/docking_beacon.dm @@ -153,7 +153,7 @@ for(var/turf/T in get_turfs()) new /obj/effect/temporary(T, 5 SECONDS,'icons/effects/alphacolors.dmi', "green") projecting = TRUE - addtimer(CALLBACK(src, .proc/allow_projection), 10 SECONDS) // No spamming holograms. + addtimer(CALLBACK(src, PROC_REF(allow_projection)), 10 SECONDS) // No spamming holograms. if(href_list["settings"]) D.ui_interact(user) diff --git a/code/modules/shuttles/landmarks.dm b/code/modules/shuttles/landmarks.dm index 755791d1755..9eaf7554147 100644 --- a/code/modules/shuttles/landmarks.dm +++ b/code/modules/shuttles/landmarks.dm @@ -144,7 +144,7 @@ var/global/list/shuttle_landmarks = list() for(var/turf/T in range(radius, src)) if(T.density) T.ChangeTurf(get_base_turf_by_area(T)) - T.turf_flags |= TURF_FLAG_NORUINS + T.turf_flags |= TURF_FLAG_NO_POINTS_OF_INTEREST //Used for custom landing locations. Self deletes after a shuttle leaves. /obj/effect/shuttle_landmark/temporary diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 3d75695bb52..d350dc21c37 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -16,6 +16,7 @@ var/multiz = 0 //how many multiz levels, starts at 0 var/ceiling_type = /turf/unsimulated/floor/shuttle_ceiling + var/force_ceiling_on_init = TRUE // Whether or not to force ceilings turfs to be created above on initialization. var/sound_takeoff = 'sound/effects/shuttle_takeoff.ogg' var/sound_landing = 'sound/effects/shuttle_landing.ogg' @@ -48,7 +49,7 @@ for(var/area_type in shuttle_area) if(istype(area_type, /area)) // If the shuttle area is already an instance, it does not need to be located. areas += area_type - events_repository.register(/decl/observ/destroyed, area_type, src, .proc/remove_shuttle_area) + events_repository.register(/decl/observ/destroyed, area_type, src, PROC_REF(remove_shuttle_area)) continue var/area/A if(map_hash && islist(SSshuttle.map_hash_to_areas[map_hash])) @@ -58,7 +59,7 @@ if(!istype(A)) CRASH("Shuttle \"[name]\" couldn't locate area [area_type].") areas += A - events_repository.register(/decl/observ/destroyed, A, src, .proc/remove_shuttle_area) + events_repository.register(/decl/observ/destroyed, A, src, PROC_REF(remove_shuttle_area)) shuttle_area = areas if(initial_location) @@ -80,8 +81,10 @@ CRASH("A supply shuttle is already defined.") SSsupply.shuttle = src + create_ceiling(force_ceiling_on_init) + /datum/shuttle/proc/remove_shuttle_area(area/area_to_remove) - events_repository.unregister(/decl/observ/destroyed, area_to_remove, src, .proc/remove_shuttle_area) + events_repository.unregister(/decl/observ/destroyed, area_to_remove, src, PROC_REF(remove_shuttle_area)) SSshuttle.shuttle_areas -= area_to_remove shuttle_area -= area_to_remove if(!length(shuttle_area)) @@ -252,14 +255,7 @@ current_location = destination // if there's a zlevel above our destination, paint in a ceiling on it so we retain our air - if(HasAbove(current_location.z)) - for(var/area/A in shuttle_area) - for(var/turf/TD in A.contents) - var/turf/TA = GetAbove(TD) - if(istype(TA, get_base_turf_by_area(TA)) || (istype(TA) && TA.is_open())) - if(get_area(TA) in shuttle_area) - continue - TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE) + create_ceiling() handle_pipes_and_power_on_move(new_turfs) @@ -305,6 +301,20 @@ for(var/obj/machinery/atmospherics/pipe as anything in pipes) pipe.build_network() +/datum/shuttle/proc/create_ceiling(force) + if(!HasAbove(current_location.z)) + return + for(var/area/A in shuttle_area) + for(var/turf/TD in A.contents) + // Background turfs don't get a ceiling. + if(TD.turf_flags & TURF_FLAG_BACKGROUND) + continue + var/turf/TA = GetAbove(TD) + if(force || (istype(TA, get_base_turf_by_area(TA)) || (istype(TA) && TA.is_open()))) + if(get_area(TA) in shuttle_area) + continue + TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE, TRUE) + //returns 1 if the shuttle has a valid arrive time /datum/shuttle/proc/has_arrive_time() return (moving_status == SHUTTLE_INTRANSIT) diff --git a/code/modules/species/outsider/random.dm b/code/modules/species/outsider/random.dm index 25f6d1e3709..29f43d6fdf0 100644 --- a/code/modules/species/outsider/random.dm +++ b/code/modules/species/outsider/random.dm @@ -101,7 +101,7 @@ . = ..() -/decl/species/alium/get_blood_color(mob/living/carbon/human/H) +/decl/species/alium/get_species_blood_color(mob/living/carbon/human/H) if(istype(H) && H.isSynthetic()) return ..() return blood_color diff --git a/code/modules/species/outsider/starlight.dm b/code/modules/species/outsider/starlight.dm index bda48e58f77..19833e06964 100644 --- a/code/modules/species/outsider/starlight.dm +++ b/code/modules/species/outsider/starlight.dm @@ -69,7 +69,7 @@ splatter_colour = "#ffff00" /decl/species/starlight/handle_death(var/mob/living/carbon/human/H) - addtimer(CALLBACK(H,/mob/proc/dust),0) + addtimer(CALLBACK(H, TYPE_PROC_REF(/mob, dust)),0) /decl/species/starlight/starborn name = "Starborn" @@ -103,9 +103,7 @@ /decl/species/starlight/starborn/handle_death(var/mob/living/carbon/human/H) ..() var/turf/T = get_turf(H) - var/obj/effect/fluid/F = locate() in T - if(!F) F = new(T) - F.reagents.add_reagent(/decl/material/liquid/fuel, 20) + T.add_to_reagents(/decl/material/liquid/fuel, 20) T.hotspot_expose(FLAMMABLE_GAS_MINIMUM_BURN_TEMPERATURE) /decl/bodytype/starlight/blueforged diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 9241c1365eb..905c0593045 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -20,7 +20,14 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/holder_icon var/list/available_bodytypes = list() var/decl/bodytype/default_bodytype - var/base_prosthetics_model = /decl/bodytype/prosthetic/basic_human + var/base_external_prosthetics_model = /decl/bodytype/prosthetic/basic_human + var/base_internal_prosthetics_model + + // Lists of accessory types for modpack modification of accessory restrictions. + // These lists are pretty broad and indiscriminate in application, don't use + // them for fine detail restriction/allowing if you can avoid it. + var/list/allow_specific_sprite_accessories + var/list/disallow_specific_sprite_accessories var/list/blood_types = list( /decl/blood_type/aplus, @@ -280,6 +287,9 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 . = ..() + if(!base_internal_prosthetics_model && base_external_prosthetics_model) + base_internal_prosthetics_model = base_external_prosthetics_model + // Populate blood type table. for(var/blood_type in blood_types) var/decl/blood_type/blood_decl = GET_DECL(blood_type) @@ -290,6 +300,42 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 available_bodytypes -= bodytype available_bodytypes += GET_DECL(bodytype) + // Update sprite accessory lists for these species. + for(var/accessory_type in allow_specific_sprite_accessories) + var/decl/sprite_accessory/accessory = GET_DECL(accessory_type) + // If this accessory is species restricted, add us to the list. + if(accessory.species_allowed) + accessory.species_allowed |= name + if(!isnull(accessory.body_flags_allowed)) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.body_flags_allowed |= bodytype.body_flags + if(!isnull(accessory.body_flags_denied)) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.body_flags_denied &= ~bodytype.body_flags + if(accessory.bodytype_categories_allowed) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.bodytype_categories_allowed |= bodytype.bodytype_category + if(accessory.bodytype_categories_denied) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.bodytype_categories_allowed -= bodytype.bodytype_category + + for(var/accessory_type in disallow_specific_sprite_accessories) + var/decl/sprite_accessory/accessory = GET_DECL(accessory_type) + if(accessory.species_allowed) + accessory.species_allowed -= name + if(!isnull(accessory.body_flags_allowed)) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.body_flags_allowed &= ~bodytype.body_flags + if(!isnull(accessory.body_flags_denied)) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.body_flags_denied |= bodytype.body_flags + if(accessory.bodytype_categories_allowed) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.bodytype_categories_allowed -= bodytype.bodytype_category + if(accessory.bodytype_categories_denied) + for(var/decl/bodytype/bodytype in available_bodytypes) + accessory.bodytype_categories_allowed |= bodytype.bodytype_category + if(ispath(default_bodytype)) default_bodytype = GET_DECL(default_bodytype) else if(length(available_bodytypes) && !default_bodytype) @@ -502,7 +548,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 H.set_fullscreen(GET_STATUS(H, STAT_BLIND) && !H.equipment_prescription, "blind", /obj/screen/fullscreen/blind) H.set_fullscreen(H.stat == UNCONSCIOUS, "blackout", /obj/screen/fullscreen/blackout) - if(config.welder_vision) + if(get_config_value(/decl/config/toggle/on/welder_vision)) H.set_fullscreen(H.equipment_tint_total, "welder", /obj/screen/fullscreen/impaired, H.equipment_tint_total) var/how_nearsighted = get_how_nearsighted(H) H.set_fullscreen(how_nearsighted, "nearsighted", /obj/screen/fullscreen/oxy, how_nearsighted) @@ -554,7 +600,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/decl/blood_type/blood = get_blood_decl(H) return istype(blood) ? blood.splatter_name : "blood" -/decl/species/proc/get_blood_color(var/mob/living/carbon/human/H) +/decl/species/proc/get_species_blood_color(var/mob/living/carbon/human/H) var/decl/blood_type/blood = get_blood_decl(H) return istype(blood) ? blood.splatter_colour : COLOR_BLOOD_HUMAN diff --git a/code/modules/species/species_bodytype.dm b/code/modules/species/species_bodytype.dm index bd903dbcf0d..7697de76c55 100644 --- a/code/modules/species/species_bodytype.dm +++ b/code/modules/species/species_bodytype.dm @@ -23,7 +23,7 @@ var/global/list/bodytypes_by_category = list() var/appearance_flags = 0 // Appearance/display related features. /// What tech levels should limbs of this type use/need? - var/limb_tech = "{'biotech':2}" + var/limb_tech = @'{"biotech":2}' var/icon_cache_uid /// Determines if eyes should render on heads using this bodytype. var/has_eyes = TRUE @@ -204,9 +204,9 @@ var/global/list/bodytypes_by_category = list() if(!breathing_organ && has_organ[BP_LUNGS]) breathing_organ = BP_LUNGS - if(config.grant_default_darksight) - eye_darksight_range = max(eye_darksight_range, config.default_darksight_range) - eye_low_light_vision_effectiveness = max(eye_low_light_vision_effectiveness, config.default_darksight_effectiveness) + if(get_config_value(/decl/config/toggle/grant_default_darksight)) + eye_darksight_range = max(eye_darksight_range, get_config_value(/decl/config/num/default_darksight_range)) + eye_low_light_vision_effectiveness = max(eye_low_light_vision_effectiveness, get_config_value(/decl/config/num/default_darksight_effectiveness)) // Modify organ lists if necessary. if(islist(override_organ_types)) @@ -235,6 +235,18 @@ var/global/list/bodytypes_by_category = list() /decl/bodytype/validate() . = ..() + var/damage_icon = get_damage_overlays() + if(damage_icon) + for(var/brute = 0 to 3) + for(var/burn = 0 to 3) + var/damage_state = "[brute][burn]" + if(!check_state_in_icon(damage_state, damage_icon)) + . += "missing state '[damage_state]' in icon '[damage_icon]'" + if(!check_state_in_icon("", damage_icon)) + . += "missing default empty state in icon '[damage_icon]'" + else + . += "null damage overlay icon" + if(eye_base_low_light_vision > 1) . += "base low light vision is greater than 1 (over 100%)" else if(eye_base_low_light_vision < 0) @@ -424,11 +436,11 @@ var/global/list/bodytypes_by_category = list() limb.cavity_max_w_class = max(limb.cavity_max_w_class, get_resized_organ_w_class(initial(I.w_class))) /decl/bodytype/proc/set_default_hair(mob/living/carbon/human/organism, override_existing = TRUE, defer_update_hair = FALSE) - if(!organism.h_style || (override_existing && (organism.h_style != default_h_style))) - organism.h_style = default_h_style + if(!organism.get_hairstyle() || (override_existing && (organism.get_hairstyle() != default_h_style))) + organism.set_hairstyle(default_h_style) . = TRUE - if(!organism.h_style || (override_existing && (organism.f_style != default_f_style))) - organism.f_style = default_f_style + if(!organism.get_hairstyle() || (override_existing && (organism.get_facial_hairstyle() != default_f_style))) + organism.set_facial_hairstyle(default_f_style) . = TRUE if(. && !defer_update_hair) organism.update_hair() @@ -445,9 +457,9 @@ var/global/list/bodytypes_by_category = list() for(var/obj/item/organ/external/E in mannequin.get_external_organs()) E.skin_colour = base_color - mannequin.eye_colour = base_eye_color - mannequin.hair_colour = base_hair_color - mannequin.facial_hair_colour = base_hair_color + mannequin.set_eye_colour(base_eye_color, skip_update = TRUE) + mannequin.set_hair_colour(base_hair_color, skip_update = TRUE) + mannequin.set_facial_hair_colour(base_hair_color, skip_update = TRUE) set_default_hair(mannequin) mannequin.force_update_limbs() diff --git a/code/modules/species/species_bodytype_helpers.dm b/code/modules/species/species_bodytype_helpers.dm index d2efe0d3bca..591054675dc 100644 --- a/code/modules/species/species_bodytype_helpers.dm +++ b/code/modules/species/species_bodytype_helpers.dm @@ -38,4 +38,5 @@ pref.body_markings = base_markings?.Copy() /decl/bodytype/proc/apply_appearance(var/mob/living/carbon/human/H) - H.skin_colour = base_color + if(base_color) + H.set_skin_colour(base_color) diff --git a/code/modules/species/species_bodytype_random.dm b/code/modules/species/species_bodytype_random.dm index 31f90a9fb86..ee73c83f994 100644 --- a/code/modules/species/species_bodytype_random.dm +++ b/code/modules/species/species_bodytype_random.dm @@ -29,7 +29,7 @@ SETUP_RANDOM_COLOR_GETTER(skin_color, skin_colors, HAS_SKIN_COLOR, list( /decl/color_generator/blue_light, /decl/color_generator/green, /decl/color_generator/white)) -SETUP_RANDOM_COLOR_SETTER(skin_color, change_skin_color) +SETUP_RANDOM_COLOR_SETTER(skin_color, set_skin_colour) SETUP_RANDOM_COLOR_GETTER(hair_color, hair_colors, HAS_HAIR_COLOR, list( /decl/color_generator/black, @@ -40,7 +40,7 @@ SETUP_RANDOM_COLOR_GETTER(hair_color, hair_colors, HAS_HAIR_COLOR, list( /decl/color_generator/wheat, /decl/color_generator/old, /decl/color_generator/punk)) -SETUP_RANDOM_COLOR_SETTER(hair_color, change_hair_color) +SETUP_RANDOM_COLOR_SETTER(hair_color, set_hair_colour) SETUP_RANDOM_COLOR_GETTER(eye_color, eye_colors, HAS_EYE_COLOR, list( /decl/color_generator/black, @@ -51,12 +51,12 @@ SETUP_RANDOM_COLOR_GETTER(eye_color, eye_colors, HAS_EYE_COLOR, list( /decl/color_generator/blue_light, /decl/color_generator/green, /decl/color_generator/albino_eye)) -SETUP_RANDOM_COLOR_SETTER(eye_color, change_eye_color) +SETUP_RANDOM_COLOR_SETTER(eye_color, set_eye_colour) /decl/bodytype/proc/get_random_facial_hair_color() return get_random_hair_color() -SETUP_RANDOM_COLOR_SETTER(facial_hair_color, change_facial_hair_color) +SETUP_RANDOM_COLOR_SETTER(facial_hair_color, set_facial_hair_colour) /decl/bodytype/proc/get_random_skin_tone() return random_skin_tone(src) @@ -71,10 +71,10 @@ SETUP_RANDOM_COLOR_SETTER(facial_hair_color, change_facial_hair_color) /mob/living/carbon/human/proc/randomize_hair_style() var/list/L = get_valid_hairstyle_types() - change_hair(SAFEPICK(L)) + set_hairstyle(SAFEPICK(L)) /mob/living/carbon/human/proc/randomize_facial_hair_style() var/list/L = get_valid_facial_hairstyle_types() - change_facial_hair(SAFEPICK(L)) + set_facial_hairstyle(SAFEPICK(L)) #undef SETUP_RANDOM_COLOR_GETTER diff --git a/code/modules/species/species_crystalline_bodytypes.dm b/code/modules/species/species_crystalline_bodytypes.dm index 01082af44cc..15c0f6047bb 100644 --- a/code/modules/species/species_crystalline_bodytypes.dm +++ b/code/modules/species/species_crystalline_bodytypes.dm @@ -5,7 +5,7 @@ **/ /decl/bodytype/crystalline abstract_type = /decl/bodytype/crystalline - limb_tech = "{'materials':4}" + limb_tech = @'{"materials":4}' is_robotic = FALSE material = /decl/material/solid/gemstone/crystal body_flags = BODY_FLAG_CRYSTAL_REFORM | BODY_FLAG_NO_DNA | BODY_FLAG_NO_DEFIB | BODY_FLAG_NO_STASIS diff --git a/code/modules/species/species_getters.dm b/code/modules/species/species_getters.dm index a54b2fdc015..b1c2a7e50cb 100644 --- a/code/modules/species/species_getters.dm +++ b/code/modules/species/species_getters.dm @@ -19,7 +19,7 @@ /decl/species/proc/get_ssd(var/mob/living/carbon/human/H) return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd) -/decl/species/proc/get_flesh_colour(var/mob/living/carbon/human/H) +/decl/species/proc/get_species_flesh_color(var/mob/living/carbon/human/H) return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color) /decl/species/proc/get_vision_flags(var/mob/living/carbon/human/H) diff --git a/code/modules/species/species_helpers.dm b/code/modules/species/species_helpers.dm index 6b8aef39799..bfeb70b5b74 100644 --- a/code/modules/species/species_helpers.dm +++ b/code/modules/species/species_helpers.dm @@ -45,9 +45,3 @@ var/global/list/stored_shock_by_ref = list() /decl/species/proc/equip_default_fallback_uniform(var/mob/living/carbon/human/H) if(istype(H)) H.equip_to_slot_or_del(new /obj/item/clothing/under/harness, slot_w_uniform_str) - -/decl/species/proc/is_blood_incompatible(var/my_blood_type, var/their_blood_type) - var/decl/blood_type/my_blood = get_blood_type_by_name(my_blood_type) - if(!istype(my_blood)) - return FALSE - return !my_blood.can_take_donation_from(get_blood_type_by_name(their_blood_type)) diff --git a/code/modules/species/species_shapeshifter.dm b/code/modules/species/species_shapeshifter.dm index 3a8bff664eb..2e8a3ba1059 100644 --- a/code/modules/species/species_shapeshifter.dm +++ b/code/modules/species/species_shapeshifter.dm @@ -33,8 +33,9 @@ var/global/list/wrapped_species_by_ref = list() /decl/species/shapeshifter/handle_post_spawn(var/mob/living/carbon/human/H) if(monochromatic) - H.hair_colour = H.skin_colour - H.facial_hair_colour = H.skin_colour + var/skin_colour = H.get_skin_colour() + H.set_hair_colour(skin_colour, skip_update = TRUE) + H.set_facial_hair_colour(skin_colour, skip_update = TRUE) ..() /decl/species/shapeshifter/get_pain_emote(var/mob/living/carbon/human/H, var/pain_power) @@ -57,12 +58,12 @@ var/global/list/wrapped_species_by_ref = list() var/list/hairstyles = species.get_hair_styles(root_bodytype) if(length(hairstyles)) var/decl/sprite_accessory/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in hairstyles - change_hair(new_hair ? new_hair.type : /decl/sprite_accessory/hair/bald) + set_hairstyle(new_hair ? new_hair.type : /decl/sprite_accessory/hair/bald) var/list/beardstyles = species.get_facial_hair_styles(root_bodytype) if(length(beardstyles)) var/decl/sprite_accessory/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in beardstyles - change_facial_hair(new_hair ? new_hair.type : /decl/sprite_accessory/facial_hair/shaved) + set_facial_hairstyle(new_hair ? new_hair.type : /decl/sprite_accessory/facial_hair/shaved) /mob/living/carbon/human/proc/shapeshifter_select_gender() @@ -115,15 +116,12 @@ var/global/list/wrapped_species_by_ref = list() shapeshifter_set_colour(new_skin) /mob/living/carbon/human/proc/shapeshifter_set_colour(var/new_skin) - - skin_colour = new_skin - + set_skin_colour(new_skin, skip_update = TRUE) var/decl/species/shapeshifter/S = species if(S.monochromatic) - hair_colour = skin_colour - facial_hair_colour = skin_colour - + var/skin_colour = get_skin_colour() + set_hair_colour(skin_colour, skip_update = TRUE) + set_facial_hair_colour(skin_colour, skip_update = TRUE) for(var/obj/item/organ/external/E in get_external_organs()) E.sync_colour_to_human(src) - try_refresh_visible_overlays() diff --git a/code/modules/species/station/monkey_bodytypes.dm b/code/modules/species/station/monkey_bodytypes.dm index 7d7fb09acb7..3d622631b7e 100644 --- a/code/modules/species/station/monkey_bodytypes.dm +++ b/code/modules/species/station/monkey_bodytypes.dm @@ -5,8 +5,8 @@ blood_overlays = 'icons/mob/human_races/species/monkey/blood_overlays.dmi' health_hud_intensity = 1.75 bodytype_flag = BODY_FLAG_MONKEY + eye_icon = null override_limb_types = list( - BP_HEAD = /obj/item/organ/external/head/no_eyes, BP_TAIL = /obj/item/organ/external/tail/monkey ) mob_size = MOB_SIZE_SMALL diff --git a/code/modules/spells/general/acid_spray.dm b/code/modules/spells/general/acid_spray.dm index c39d043bfc8..a1aebd2df04 100644 --- a/code/modules/spells/general/acid_spray.dm +++ b/code/modules/spells/general/acid_spray.dm @@ -21,7 +21,7 @@ for(var/mod in list(315, 0, 45)) var/obj/effect/effect/water/chempuff/chem = new(get_turf(target)) chem.create_reagents(10) - chem.reagents.add_reagent(reagent_type,10) + chem.add_to_reagents(reagent_type,10) chem.set_color() spawn(0) chem.set_up(get_ranged_target_turf(target, angle2dir(angle+mod), 3)) diff --git a/code/modules/spells/general/veil_of_shadows.dm b/code/modules/spells/general/veil_of_shadows.dm index 0b189f8efbc..4d328e65db0 100644 --- a/code/modules/spells/general/veil_of_shadows.dm +++ b/code/modules/spells/general/veil_of_shadows.dm @@ -22,8 +22,8 @@ H.AddMovementHandler(/datum/movement_handler/mob/incorporeal) if(H.add_cloaking_source(src)) H.visible_message("\The [H] shrinks from view!") - events_repository.register(/decl/observ/moved, H,src,.proc/check_light) - timer_id = addtimer(CALLBACK(src,.proc/cancel_veil),duration, TIMER_STOPPABLE) + events_repository.register(/decl/observ/moved, H,src,PROC_REF(check_light)) + timer_id = addtimer(CALLBACK(src,PROC_REF(cancel_veil)),duration, TIMER_STOPPABLE) /spell/veil_of_shadows/proc/cancel_veil() var/mob/living/carbon/human/H = holder @@ -35,7 +35,7 @@ drop_cloak() else events_repository.unregister(/decl/observ/moved, H,src) - events_repository.register(/decl/observ/moved, H,src,.proc/drop_cloak) + events_repository.register(/decl/observ/moved, H,src,PROC_REF(drop_cloak)) /spell/veil_of_shadows/proc/drop_cloak() var/mob/living/carbon/human/H = holder diff --git a/code/modules/spells/hand/hand.dm b/code/modules/spells/hand/hand.dm index f17f55c1707..a533cc3dbb3 100644 --- a/code/modules/spells/hand/hand.dm +++ b/code/modules/spells/hand/hand.dm @@ -75,7 +75,7 @@ /spell/hand/duration/cast(var/list/targets, var/mob/user) . = ..() if(.) - hand_timer = addtimer(CALLBACK(src, .proc/cancel_hand), hand_duration, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE) + hand_timer = addtimer(CALLBACK(src, PROC_REF(cancel_hand)), hand_duration, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE) /spell/hand/duration/cancel_hand() deltimer(hand_timer) diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index cb5af2f7598..79a64522435 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -70,7 +70,7 @@ var/global/list/artefact_feedback = list( return if(reagent) if(I.reagents?.has_reagent(reagent, 5)) - I.reagents.remove_reagent(reagent, 5) + I.remove_from_reagents(reagent, 5) else if(LAZYACCESS(I.matter, reagent) >= (SHEET_MATERIAL_AMOUNT * 5)) qdel(I) else diff --git a/code/modules/spells/spells.dm b/code/modules/spells/spells.dm index d2dc6a0201e..ad550747a7f 100644 --- a/code/modules/spells/spells.dm +++ b/code/modules/spells/spells.dm @@ -31,7 +31,7 @@ /mob/proc/add_spell(var/spell/spell_to_add, var/spell_base = "wiz_spell_ready") if(!ability_master) - ability_master = new() + ability_master = new(null, src) spell_to_add.holder = src if(mind) if(!mind.learned_spells) diff --git a/code/modules/spells/targeted/cleric_spells.dm b/code/modules/spells/targeted/cleric_spells.dm index e3ea0071e9f..59545660c56 100644 --- a/code/modules/spells/targeted/cleric_spells.dm +++ b/code/modules/spells/targeted/cleric_spells.dm @@ -181,7 +181,7 @@ var/time = (L.getBruteLoss() + L.getFireLoss()) * 20 L.status_flags &= GODMODE to_chat(L,"You will be in stasis for [time/10] second\s.") - addtimer(CALLBACK(src,.proc/cancel_rift),time) + addtimer(CALLBACK(src,PROC_REF(cancel_rift)),time) /spell/targeted/heal_target/trance/Destroy() cancel_rift() @@ -220,7 +220,7 @@ should_wait = 0 break //Don't need to check anymore. if(should_wait) - addtimer(CALLBACK(src,.proc/check_for_revoke,targets), 30 SECONDS) + addtimer(CALLBACK(src,PROC_REF(check_for_revoke),targets), 30 SECONDS) else revoke_spells() diff --git a/code/modules/spells/targeted/ethereal_jaunt.dm b/code/modules/spells/targeted/ethereal_jaunt.dm index 9f3885664c9..fd741613209 100644 --- a/code/modules/spells/targeted/ethereal_jaunt.dm +++ b/code/modules/spells/targeted/ethereal_jaunt.dm @@ -107,7 +107,7 @@ else to_chat(user, "Some strange aura is blocking the way!") canmove = 0 - addtimer(CALLBACK(src, .proc/allow_move), 2) + addtimer(CALLBACK(src, PROC_REF(allow_move)), 2) /obj/effect/dummy/spell_jaunt/proc/allow_move() canmove = TRUE diff --git a/code/modules/spells/targeted/shapeshift.dm b/code/modules/spells/targeted/shapeshift.dm index e8dd5093dac..b45e03c42eb 100644 --- a/code/modules/spells/targeted/shapeshift.dm +++ b/code/modules/spells/targeted/shapeshift.dm @@ -55,9 +55,9 @@ M.forceMove(trans) //move inside the new dude to hide him. M.status_flags |= GODMODE //dont want him to die or breathe or do ANYTHING transformed_dudes[trans] = M - events_repository.register(/decl/observ/death, trans,src,/spell/targeted/shapeshift/proc/stop_transformation) - events_repository.register(/decl/observ/destroyed, trans,src,/spell/targeted/shapeshift/proc/stop_transformation) - events_repository.register(/decl/observ/destroyed, M, src, /spell/targeted/shapeshift/proc/destroyed_transformer) + events_repository.register(/decl/observ/death, trans,src, TYPE_PROC_REF(/spell/targeted/shapeshift, stop_transformation)) + events_repository.register(/decl/observ/destroyed, trans,src, TYPE_PROC_REF(/spell/targeted/shapeshift, stop_transformation)) + events_repository.register(/decl/observ/destroyed, M, src, TYPE_PROC_REF(/spell/targeted/shapeshift, destroyed_transformer)) if(duration) spawn(duration) stop_transformation(trans) diff --git a/code/modules/spells/targeted/torment.dm b/code/modules/spells/targeted/torment.dm index ea1cdff12a2..96ef53c3fb3 100644 --- a/code/modules/spells/targeted/torment.dm +++ b/code/modules/spells/targeted/torment.dm @@ -21,7 +21,7 @@ cast_sound = 'sound/magic/cowhead_curse.ogg' /spell/targeted/torment/cast(var/list/targets, var/mob/user) - gibs(user.loc) + user.gibs() for(var/mob/living/carbon/human/H in targets) H.adjustHalLoss(loss) diff --git a/code/modules/sprite_accessories/_accessory.dm b/code/modules/sprite_accessories/_accessory.dm index a78cab57bf4..78ade6f2489 100644 --- a/code/modules/sprite_accessories/_accessory.dm +++ b/code/modules/sprite_accessories/_accessory.dm @@ -10,33 +10,63 @@ have to define any UI values for sprite accessories manually for hair and facial hair. Just add in new hair types and the game will naturally adapt. - !!WARNING!!: changing existing hair information can be VERY hazardous to savefiles, - to the point where you may completely corrupt a server's savefiles. Please refrain - from doing this unless you absolutely know what you are doing, and have defined a - conversion in savefile.dm + Changing icon states, icon files and names should not represent any risks to + existing savefiles, but please do not change decl uids unless you are very sure + you know what you're doing and don't mind potentially causing people's savefiles + to load the default values for the marking category in question. */ /decl/sprite_accessory abstract_type = /decl/sprite_accessory decl_flags = DECL_FLAG_MANDATORY_UID - var/name // The preview name of the accessory - var/icon // the icon file the accessory is located in - var/icon_state // the icon_state of the accessory - var/required_gender = null // Restricted to specific genders. null matches any - var/list/species_allowed = list(SPECIES_HUMAN) // Restrict some styles to specific root species names - var/list/subspecies_allowed // Restrict some styles to specific species names, irrespective of root species name - var/body_flags_allowed = null // Restrict some styles to specific bodytype flags - var/body_flags_denied = null // Restrict some styles to specific bodytype flags - var/list/bodytype_categories_allowed = null // Restricts some styles to specific bodytype categories - var/list/bodytype_categories_denied = null // Restricts some styles to specific bodytype categories - - var/do_colouration = 1 // Whether or not the accessory can be affected by colouration - var/blend = ICON_ADD + /// The preview name of the accessory + var/name + /// the icon file the accessory is located in + var/icon + /// the icon_state of the accessory + var/icon_state + /// Restricted to specific bodytypes. null matches any + var/list/decl/bodytype/bodytypes_allowed + /// Restricted from specific bodytypes. null matches none + var/list/decl/bodytype/bodytypes_denied + /// Restrict some styles to specific root species names + var/list/species_allowed = list(SPECIES_HUMAN) + /// Restrict some styles to specific species names, irrespective of root species name + var/list/subspecies_allowed + /// Restrict some styles to specific bodytype flags. + var/body_flags_allowed + /// Restrict some styles to specific bodytype flags. + var/body_flags_denied + /// Restricts some styles to specific bodytype categories + var/list/bodytype_categories_allowed + /// Restricts some styles to specific bodytype categories + var/list/bodytype_categories_denied + /// Slot to check equipment for when hiding this accessory. + var/hidden_by_gear_slot + /// Flag to check equipment for when hiding this accessory. + var/hidden_by_gear_flag + /// Whether or not the accessory can be affected by colouration + var/do_colouration = TRUE + /// Various flags controlling some checks and behavior. var/flags = 0 + /// Flags to check when applying this accessory to the mob. + var/requires_appearance_flags = 0 + /// Icon cache for various icon generation steps. + var/list/cached_icons = list() + /// Whether or not this overlay should be trimmed to fit the base bodypart icon. + var/mask_to_bodypart = FALSE + /// What blend mode to use when colourizing this accessory. + var/color_blend = ICON_ADD + /// What blend mode to use when applying this accessory to the compiled organ. + var/layer_blend = ICON_OVERLAY + /// What bodypart tags does this marking apply to? + var/list/body_parts + /// Set to a layer integer to apply this as an overlay over the top of hair and such. + var/sprite_overlay_layer + /// A list of sprite accessory types that are disallowed by this one being included. + var/list/disallows_accessories /decl/sprite_accessory/proc/accessory_is_available(var/mob/owner, var/decl/species/species, var/decl/bodytype/bodytype) - if(!isnull(required_gender) && bodytype.associated_gender != required_gender) - return FALSE if(species) var/species_is_permitted = TRUE if(species_allowed) @@ -46,6 +76,10 @@ if(!species_is_permitted) return FALSE if(bodytype) + if(LAZYLEN(bodytypes_allowed) && !(bodytype.type in bodytypes_allowed)) + return FALSE + if(LAZYISIN(bodytypes_denied, bodytype.type)) + return FALSE if(!isnull(bodytype_categories_allowed) && !(bodytype.bodytype_category in bodytype_categories_allowed)) return FALSE if(!isnull(bodytype_categories_denied) && (bodytype.bodytype_category in bodytype_categories_denied)) @@ -54,18 +88,51 @@ return FALSE if(!isnull(body_flags_denied) && (body_flags_denied & bodytype.bodytype_flag)) return FALSE + if(requires_appearance_flags && !(bodytype.appearance_flags & requires_appearance_flags)) + return FALSE return TRUE -/decl/sprite_accessory/proc/get_validatable_icon_state() - return icon_state - /decl/sprite_accessory/validate() . = ..() if(!icon) . += "missing icon" else - var/actual_icon_state = get_validatable_icon_state() - if(!actual_icon_state) + if(!icon_state) . += "missing icon_state" - else if(!check_state_in_icon(actual_icon_state, icon)) - . += "missing icon state \"[actual_icon_state]\" in [icon]" + else if(!check_state_in_icon(icon_state, icon)) + . += "missing icon state \"[icon_state]\" in [icon]" + +/decl/sprite_accessory/proc/get_hidden_substitute() + return + +/decl/sprite_accessory/proc/is_hidden(var/obj/item/organ/external/organ) + if(!organ?.owner) + return FALSE + if(hidden_by_gear_slot) + var/obj/item/hiding = organ.owner.get_equipped_item(hidden_by_gear_slot) + if(!hiding) + return FALSE + return (hiding.flags_inv & hidden_by_gear_flag) + return FALSE + +/decl/sprite_accessory/proc/get_accessory_icon(var/obj/item/organ/external/organ) + return icon + +/decl/sprite_accessory/proc/get_cached_accessory_icon(var/obj/item/organ/external/organ, var/color = COLOR_WHITE) + ASSERT(istext(color) && (length(color) == 7 || length(color) == 9)) + if(!icon_state) + return null + LAZYINITLIST(cached_icons[organ.bodytype]) + LAZYINITLIST(cached_icons[organ.bodytype][organ.organ_tag]) + var/icon/accessory_icon = cached_icons[organ.bodytype][organ.organ_tag][color] + if(!accessory_icon) + accessory_icon = icon(get_accessory_icon(organ), icon_state) // make a new one to avoid mutating the base + if(!accessory_icon) + cached_icons[organ.bodytype][organ.organ_tag][color] = null + return null + if(mask_to_bodypart) + accessory_icon.Blend(get_limb_mask_for(organ.bodytype, organ.organ_tag), ICON_MULTIPLY) + if(do_colouration && color) + accessory_icon.Blend(color, color_blend) + cached_icons[organ.bodytype][organ.organ_tag][color] = accessory_icon + return accessory_icon diff --git a/code/modules/sprite_accessories/_accessory_facial.dm b/code/modules/sprite_accessories/_accessory_facial.dm index ea5338b8db0..37a00b5254b 100644 --- a/code/modules/sprite_accessories/_accessory_facial.dm +++ b/code/modules/sprite_accessories/_accessory_facial.dm @@ -9,14 +9,18 @@ /decl/sprite_accessory/facial_hair abstract_type = /decl/sprite_accessory/facial_hair icon = 'icons/mob/human_races/species/human/facial.dmi' + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) -/decl/sprite_accessory/facial_hair/get_validatable_icon_state() - return "[icon_state]_s" +/decl/sprite_accessory/facial_hair/get_hidden_substitute() + return GET_DECL(/decl/sprite_accessory/facial_hair/shaved) /decl/sprite_accessory/facial_hair/shaved name = "Shaved" icon_state = "bald" - required_gender = null + bodytypes_allowed = null + bodytypes_denied = null species_allowed = null subspecies_allowed = null bodytype_categories_allowed = null diff --git a/code/modules/sprite_accessories/_accessory_hair.dm b/code/modules/sprite_accessories/_accessory_hair.dm index 8025c20c1c2..3641d0e7cf6 100644 --- a/code/modules/sprite_accessories/_accessory_hair.dm +++ b/code/modules/sprite_accessories/_accessory_hair.dm @@ -9,15 +9,21 @@ /decl/sprite_accessory/hair abstract_type = /decl/sprite_accessory/hair icon = 'icons/mob/human_races/species/human/hair.dmi' + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) -/decl/sprite_accessory/hair/get_validatable_icon_state() - return "[icon_state]_s" +/decl/sprite_accessory/hair/get_hidden_substitute() + if(flags & VERY_SHORT) + return src + return GET_DECL(/decl/sprite_accessory/hair/short) /decl/sprite_accessory/hair/bald name = "Bald" icon_state = "bald" flags = VERY_SHORT | HAIR_BALD - required_gender = null + bodytypes_allowed = null + bodytypes_denied = null species_allowed = null subspecies_allowed = null bodytype_categories_allowed = null diff --git a/code/modules/sprite_accessories/_accessory_markings.dm b/code/modules/sprite_accessories/_accessory_markings.dm index 99d73ccab36..6abf3c86e31 100644 --- a/code/modules/sprite_accessories/_accessory_markings.dm +++ b/code/modules/sprite_accessories/_accessory_markings.dm @@ -3,31 +3,7 @@ icon = 'icons/mob/human_races/species/default_markings.dmi' do_colouration = 1 //Almost all of them have it, COLOR_ADD abstract_type = /decl/sprite_accessory/marking - //Empty list is unrestricted. Should only restrict the ones that make NO SENSE on other species, - //like IPC optics overlay stuff. - var/layer_blend = ICON_OVERLAY - var/body_parts = list() //A list of bodyparts this covers, in organ_tag defines - //Reminder: BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_CHEST,BP_GROIN,BP_HEAD - var/draw_target = MARKING_TARGET_SKIN - var/list/disallows = list() //A list of other marking types to ban from adding when this marking is already added - var/list/icons = list() - var/mask_to_bodypart = TRUE - -/decl/sprite_accessory/marking/proc/get_cached_marking_icon(var/decl/bodytype/bodytype, var/bodypart, var/color = COLOR_WHITE) - LAZYINITLIST(icons[bodytype]) - LAZYINITLIST(icons[bodytype][bodypart]) - if(!icons[bodytype][bodypart][color]) - var/icon/marking_icon = icon(icon, icon_state) // make a new one to avoid mutating the base - if(mask_to_bodypart) - marking_icon.Blend(get_limb_mask_for(bodytype, bodypart), ICON_MULTIPLY) - marking_icon.Blend(color, blend) - icons[bodytype][bodypart][color] = marking_icon - return icons[bodytype][bodypart][color] - -/decl/sprite_accessory/marking/validate() - . = ..() - if(!check_state_in_icon(icon_state, icon)) - . += "missing icon state \"[icon_state]\" in [icon]" + mask_to_bodypart = TRUE /decl/sprite_accessory/marking/tat_hive name = "Tattoo (Hive, Back)" diff --git a/code/modules/status_conditions/status_sleeping.dm b/code/modules/status_conditions/status_sleeping.dm index d70e8c3b8b5..7c64e3b2083 100644 --- a/code/modules/status_conditions/status_sleeping.dm +++ b/code/modules/status_conditions/status_sleeping.dm @@ -9,14 +9,10 @@ . = ..() victim.facing_dir = null victim.UpdateLyingBuckledAndVerbStatus() - if(ishuman(victim)) - var/mob/living/carbon/human/H = victim - H.handle_dreams() - H.species.handle_sleeping(H) + victim.handle_dreams() + victim.get_species()?.handle_sleeping(victim) /decl/status_condition/sleeping/handle_status(mob/living/victim, var/amount) . = ..() - if(ishuman(victim)) - var/mob/living/carbon/human/H = victim - H.handle_dreams() - H.species.handle_sleeping(H) + victim.handle_dreams() + victim.get_species()?.handle_sleeping(victim) diff --git a/code/modules/submaps/submap_landmark.dm b/code/modules/submaps/submap_landmark.dm index 65cf96aa48e..7bf42c3fec0 100644 --- a/code/modules/submaps/submap_landmark.dm +++ b/code/modules/submaps/submap_landmark.dm @@ -1,10 +1,12 @@ /obj/abstract/submap_landmark - icon = 'icons/misc/mark.dmi' - invisibility = INVISIBILITY_MAXIMUM - anchored = TRUE - simulated = FALSE - density = FALSE - opacity = FALSE + icon = 'icons/misc/mark.dmi' + invisibility = INVISIBILITY_MAXIMUM + anchored = TRUE + simulated = FALSE + density = FALSE + opacity = FALSE + abstract_type = /obj/abstract/submap_landmark + is_spawnable_type = FALSE /obj/abstract/submap_landmark/joinable_submap icon_state = "x4" diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index a76a68e24d8..f4e89e6cce2 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -202,7 +202,7 @@ var/global/list/supermatter_delam_accent_sounds = list( uid = gl_uid++ soundloop = new(list(src), TRUE) update_icon() - add_filter("outline",1,list(type = "drop_shadow", size = 0, color = COLOR_WHITE, x = 0, y = 0)) + add_filter("outline", 1, list(type = "drop_shadow", size = 0, color = COLOR_WHITE, x = 0, y = 0)) /obj/machinery/power/supermatter/Destroy() . = ..() @@ -556,13 +556,13 @@ var/global/list/supermatter_delam_accent_sounds = list( if(damage_animation) return if(!get_filter("rays")) - add_filter("rays",1,list(type="rays", size = 64, color = emergency_color, factor = 0.6, density = 12)) + add_filter("rays", 1 ,list(type = "rays", size = 64, color = emergency_color, factor = 0.6, density = 12)) animate_filter("rays", list(time = 10 SECONDS, offset = 10, loop=-1)) animate(time = 10 SECONDS, loop=-1) animate_filter("rays",list(time = 2 SECONDS, size = 80, loop=-1, flags = ANIMATION_PARALLEL)) animate(time = 2 SECONDS, size = 10, loop=-1, flags = ANIMATION_PARALLEL) - addtimer(CALLBACK(src, .proc/finish_damage_animation), 12 SECONDS) + addtimer(CALLBACK(src, PROC_REF(finish_damage_animation)), 12 SECONDS) /obj/machinery/power/supermatter/proc/finish_damage_animation() damage_animation = FALSE diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 71a67326c50..d51f538ac2a 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -128,7 +128,7 @@ name = "Connect limb" description = "This procedure is used to reconnect a replaced severed limb." allowed_tools = list( - TOOL_HEMOSTAT = 100, + TOOL_SUTURES = 100, TOOL_CABLECOIL = 75 ) can_infect = 1 @@ -145,15 +145,15 @@ /decl/surgery_step/limb/connect/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You start connecting tendons and muscle in [target]'s [E.amputation_point].") + user.visible_message("[user] starts reattaching tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You start reattaching tendons and muscle in [target]'s [E.amputation_point].") ..() /decl/surgery_step/limb/connect/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(target, target_zone) var/obj/item/organ/external/P = GET_EXTERNAL_ORGAN(target, E.parent_organ) - user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") + user.visible_message("[user] has reattached tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You have reattached tendons and muscles in [target]'s [E.amputation_point] with [tool].") //This time we call add_organ but we want it to install in a non detached state target.add_organ(E, P, FALSE, TRUE, FALSE) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 5ee4834aa70..d873e0406eb 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -190,19 +190,12 @@ /decl/surgery_step/internal/remove_organ/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) user.visible_message("\The [user] has removed \the [target]'s [LAZYACCESS(global.surgeries_in_progress["\ref[target]"], target_zone)] with \the [tool].", \ "You have removed \the [target]'s [LAZYACCESS(global.surgeries_in_progress["\ref[target]"], target_zone)] with \the [tool].") - // Extract the organ! var/obj/item/organ/O = LAZYACCESS(global.surgeries_in_progress["\ref[target]"], target_zone) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) if(istype(O) && istype(affected)) //Now call remove again with detach = FALSE so we fully remove it target.remove_organ(O, TRUE, FALSE) - - // Just in case somehow the organ we're extracting from an organic is an MMI - if(istype(O, /obj/item/organ/internal/mmi_holder)) - var/obj/item/organ/internal/mmi_holder/brain = O - brain.transfer_and_delete() - log_warning("Organ removal surgery on '[target]' returned a mmi_holder '[O]' instead of a mmi!!") ..() /decl/surgery_step/internal/remove_organ/fail_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) @@ -251,9 +244,7 @@ CRASH("Target ([target]) of surgery [type] has no bodytype!") else var/decl/pronouns/G = O.get_pronouns() - if(O.organ_tag == BP_POSIBRAIN && !target.should_have_organ(BP_POSIBRAIN)) - to_chat(user, SPAN_WARNING("There's no place in [target] to fit \the [O.organ_tag].")) - else if(O.damage > (O.max_damage * 0.75)) + if(O.damage > (O.max_damage * 0.75)) to_chat(user, SPAN_WARNING("\The [O.name] [G.is] in no state to be transplanted.")) else if(O.w_class > affected.cavity_max_w_class) to_chat(user, SPAN_WARNING("\The [O.name] [G.is] too big for [affected.cavity_name] cavity!")) @@ -325,8 +316,8 @@ var/list/attachable_organs var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - for(var/obj/item/organ/I in affected.implants) - if(I && (I.status & ORGAN_CUT_AWAY)) + for(var/obj/item/organ/I in (affected.implants|affected.internal_organs)) + if(I.status & ORGAN_CUT_AWAY) var/image/radial_button = image(icon = I.icon, icon_state = I.icon_state) radial_button.name = "Attach \the [I.name]" LAZYSET(attachable_organs, I, radial_button) diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index e972107b4b2..e4c55f59a1d 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -1,4 +1,4 @@ -//Procedures in this file: Robotic surgery steps, organ removal, replacement. MMI insertion, synthetic organ repair. +//Procedures in this file: Robotic surgery steps, organ removal, replacement, synthetic organ repair. ////////////////////////////////////////////////////////////////// // ROBOTIC SURGERY // ////////////////////////////////////////////////////////////////// @@ -494,73 +494,6 @@ "Your hand slips, unseating \the [tool].") ..() -////////////////////////////////////////////////////////////////// -// mmi installation surgery step -////////////////////////////////////////////////////////////////// -/decl/surgery_step/robotics/install_mmi - name = "Install MMI" - description = "This procedure installs an MMI within a prosthetic organ." - allowed_tools = list( - /obj/item/mmi = 100 - ) - min_duration = 60 - max_duration = 80 - surgery_candidate_flags = SURGERY_NO_CRYSTAL | SURGERY_NO_FLESH | SURGERY_NEEDS_ENCASEMENT - -/decl/surgery_step/robotics/install_mmi/pre_surgery_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/mmi/M = tool - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - if(affected && istype(M)) - if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) - to_chat(user, SPAN_WARNING("That brain is not usable.")) - else if(BP_IS_CRYSTAL(affected)) - to_chat(user, SPAN_WARNING("The crystalline interior of \the [affected] is incompatible with \the [M].")) - else if(!target.isSynthetic()) - to_chat(user, SPAN_WARNING("You cannot install a computer brain into a meat body.")) - else if(!target.should_have_organ(BP_BRAIN)) - var/decl/species/species = target.get_species() - to_chat(user, SPAN_WARNING("You're pretty sure [species ? "[species.name_plural] don't" : "\the [target] doesn't"] normally have a brain.")) - else if(target.has_brain()) - to_chat(user, SPAN_WARNING("Your subject already has a brain.")) - else - return TRUE - return FALSE - -/decl/surgery_step/robotics/install_mmi/assess_bodypart(mob/living/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = ..() - if(affected && target_zone == BP_HEAD) - return affected - -/decl/surgery_step/robotics/install_mmi/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ - "You start installing \the [tool] into [target]'s [affected.name].") - ..() - -/decl/surgery_step/robotics/install_mmi/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) - if(!user.try_unequip(tool) || !ishuman(target)) - return - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] has installed \the [tool] into [target]'s [affected.name].", \ - "You have installed \the [tool] into [target]'s [affected.name].") - - var/obj/item/mmi/M = tool - var/obj/item/organ/internal/mmi_holder/holder = new(target, 1) - var/mob/living/carbon/human/H = target - H.add_organ(holder, affected, TRUE) - tool.forceMove(holder) - holder.stored_mmi = tool - holder.update_from_mmi() - - if(M.brainmob && M.brainmob.mind) - M.brainmob.mind.transfer_to(target) - ..() - -/decl/surgery_step/robotics/install_mmi/fail_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips.", \ - "Your hand slips.") - ..() - /decl/surgery_step/internal/remove_organ/robotic name = "Remove robotic component" description = "This procedure removes a robotic component." @@ -573,54 +506,3 @@ can_infect = 0 robotic_surgery = TRUE surgery_candidate_flags = SURGERY_NO_CRYSTAL | SURGERY_NO_FLESH | SURGERY_NEEDS_ENCASEMENT - -/decl/surgery_step/remove_mmi - name = "Remove MMI" - description = "This procedure removes an MMI from a prosthetic organ." - min_duration = 60 - max_duration = 80 - allowed_tools = list( - TOOL_HEMOSTAT = 100, - TOOL_WIRECUTTERS = 75, - ) - can_infect = 0 - surgery_candidate_flags = SURGERY_NO_CRYSTAL | SURGERY_NO_FLESH | SURGERY_NEEDS_ENCASEMENT - -/decl/surgery_step/remove_mmi/get_skill_reqs(mob/living/user, mob/living/target, obj/item/tool) - return SURGERY_SKILLS_ROBOTIC - -/decl/surgery_step/remove_mmi/assess_bodypart(mob/living/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = ..() - if(affected && (locate(/obj/item/mmi) in affected.implants)) - return affected - -/decl/surgery_step/remove_mmi/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message( \ - "\The [user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ - "You start poking around inside [target]'s [affected.name] with \the [tool]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1,affecting = affected) - ..() - -/decl/surgery_step/remove_mmi/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - if(affected) - var/obj/item/mmi/mmi = locate() in affected.implants - if(affected && mmi) - user.visible_message( \ - SPAN_NOTICE("\The [user] removes \the [mmi] from \the [target]'s [affected.name] with \the [tool]."), \ - SPAN_NOTICE("You remove \the [mmi] from \the [target]'s [affected.name] with \the [tool].")) - target.remove_implant(mmi, TRUE, affected) - else - user.visible_message( \ - SPAN_NOTICE("\The [user] could not find anything inside [target]'s [affected.name]."), \ - SPAN_NOTICE("You could not find anything inside [target]'s [affected.name].")) - ..() - -/decl/surgery_step/remove_mmi/fail_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message( \ - SPAN_WARNING("\The [user]'s hand slips, damaging \the [target]'s [affected.name] with \the [tool]!"), \ - SPAN_WARNING("Your hand slips, damaging \the [target]'s [affected.name] with \the [tool]!")) - affected.take_external_damage(3, 0, used_weapon = tool) - ..() diff --git a/code/modules/synthesized_instruments/event_manager.dm b/code/modules/synthesized_instruments/event_manager.dm index 8ca067e6716..182ab68b3b0 100644 --- a/code/modules/synthesized_instruments/event_manager.dm +++ b/code/modules/synthesized_instruments/event_manager.dm @@ -68,7 +68,7 @@ if (active) return 0 src.active = 1 - addtimer(CALLBACK(src, .proc/handle_events), 0) + addtimer(CALLBACK(src, PROC_REF(handle_events)), 0) /datum/musical_event_manager/proc/deactivate() if (src.kill_loop) return 0 diff --git a/code/modules/synthesized_instruments/song.dm b/code/modules/synthesized_instruments/song.dm index f24bdf289f1..090324ac2af 100644 --- a/code/modules/synthesized_instruments/song.dm +++ b/code/modules/synthesized_instruments/song.dm @@ -191,7 +191,7 @@ var/list/allowed_suff = list("b", "n", "#", "s") var/list/note_off_delta = list("a"=91, "b"=91, "c"=98, "d"=98, "e"=98, "f"=98, "g"=98) var/list/lines_copy = src.lines.Copy() - addtimer(CALLBACK(src, .proc/play_lines, user, allowed_suff, note_off_delta, lines_copy), 0) + addtimer(CALLBACK(src, PROC_REF(play_lines), user, allowed_suff, note_off_delta, lines_copy), 0) #undef CP #undef IS_DIGIT diff --git a/code/modules/synthesized_instruments/sound_player.dm b/code/modules/synthesized_instruments/sound_player.dm index 2224721e424..20df81d5456 100644 --- a/code/modules/synthesized_instruments/sound_player.dm +++ b/code/modules/synthesized_instruments/sound_player.dm @@ -26,7 +26,7 @@ src.actual_instrument = where src.echo = global.musical_config.echo_default.Copy() src.env = global.musical_config.env_default.Copy() - src.proxy_listener = new(src.actual_instrument, /datum/sound_player/proc/on_turf_entered_relay, /datum/sound_player/proc/on_turfs_changed_relay, range, proc_owner = src) + src.proxy_listener = new(src.actual_instrument, TYPE_PROC_REF(/datum/sound_player, on_turf_entered_relay), TYPE_PROC_REF(/datum/sound_player, on_turfs_changed_relay), range, proc_owner = src) proxy_listener.register_turfs() /datum/sound_player/Destroy() diff --git a/code/modules/synthesized_instruments/sound_token.dm b/code/modules/synthesized_instruments/sound_token.dm index 3de8c409edf..a495fe3dd3c 100644 --- a/code/modules/synthesized_instruments/sound_token.dm +++ b/code/modules/synthesized_instruments/sound_token.dm @@ -32,7 +32,7 @@ listeners = list() listener_status = list() - events_repository.register(/decl/observ/destroyed, source, src, /datum/proc/qdel_self) + events_repository.register(/decl/observ/destroyed, source, src, TYPE_PROC_REF(/datum, qdel_self)) player.subscribe(src) diff --git a/code/modules/tools/tool_archetype_definition_pen.dm b/code/modules/tools/tool_archetype_definition_pen.dm index 87c7aae992c..59c4e08d875 100644 --- a/code/modules/tools/tool_archetype_definition_pen.dm +++ b/code/modules/tools/tool_archetype_definition_pen.dm @@ -21,14 +21,16 @@ else . = "Anonymous" -/decl/tool_archetype/pen/proc/decrement_uses(var/mob/user, var/obj/item/tool, var/decrement = 1) +/decl/tool_archetype/pen/proc/decrement_uses(var/mob/user, var/obj/item/tool, var/decrement = 1, var/destroy_on_zero = TRUE) . = tool.get_tool_property(TOOL_PEN, TOOL_PROP_USES) if(. < 0) return TRUE . -= decrement tool.set_tool_property(TOOL_PEN, TOOL_PROP_USES, max(0, .)) //Prevent negatives and turning the pen into an infinite uses pen if(. <= 0 && (tool.get_tool_property(TOOL_PEN, TOOL_PROP_PEN_FLAG) & PEN_FLAG_DEL_EMPTY)) - qdel(tool) + . = 0 + if(destroy_on_zero) + qdel(tool) /**Toggles the active/inactive state of some pens */ /decl/tool_archetype/pen/proc/toggle_active(var/mob/user, var/obj/item/pen/tool) diff --git a/code/modules/tools/tool_extension.dm b/code/modules/tools/tool_extension.dm index 61c41dfba6a..9b1c7d9a040 100644 --- a/code/modules/tools/tool_extension.dm +++ b/code/modules/tools/tool_extension.dm @@ -56,7 +56,7 @@ return FALSE // Returns a failure message as a string if the interaction fails. -/datum/extension/tool/proc/do_tool_interaction(var/archetype, var/mob/user, var/atom/target, var/delay = (1 SECOND), var/start_message, var/success_message, var/failure_message, var/fuel_expenditure = 0, var/check_skill = SKILL_CONSTRUCTION, var/check_skill_threshold, var/check_skill_prob = 50) +/datum/extension/tool/proc/do_tool_interaction(var/archetype, var/mob/user, var/atom/target, var/delay = (1 SECOND), var/start_message, var/success_message, var/failure_message, var/fuel_expenditure = 0, var/check_skill = SKILL_CONSTRUCTION, var/check_skill_threshold, var/check_skill_prob = 50, var/set_cooldown = FALSE) if(!istype(user) || !istype(target)) return TOOL_USE_FAILURE_NOMESSAGE @@ -87,10 +87,10 @@ if(delay) delay = max(5, CEILING(delay * get_tool_speed(archetype))) if(check_skill) - if(!user.do_skilled(delay, check_skill, target, check_holding = TRUE)) + if(!user.do_skilled(delay, check_skill, target, check_holding = TRUE, set_cooldown = set_cooldown)) return TOOL_USE_FAILURE_NOMESSAGE else - if(!do_after(user, delay, target, check_holding = TRUE)) + if(!do_after(user, delay, target, check_holding = TRUE, set_cooldown = set_cooldown)) return TOOL_USE_FAILURE_NOMESSAGE // Basic skill check for the action - do it post-delay so they can't just spamclick. diff --git a/code/modules/tools/tool_item.dm b/code/modules/tools/tool_item.dm index 4091fc364ef..b850a2e651f 100644 --- a/code/modules/tools/tool_item.dm +++ b/code/modules/tools/tool_item.dm @@ -16,13 +16,13 @@ var/datum/extension/tool/tool = get_extension(src, /datum/extension/tool) . = tool?.set_tool_property(archetype, property, value) -/obj/item/proc/do_tool_interaction(var/archetype, var/mob/user, var/atom/target, var/delay = (1 SECOND), var/start_message, var/success_message, var/failure_message, var/fuel_expenditure = 0, var/check_skill = SKILL_CONSTRUCTION, var/check_skill_threshold, var/check_skill_prob = 50) +/obj/item/proc/do_tool_interaction(var/archetype, var/mob/user, var/atom/target, var/delay = (1 SECOND), var/start_message, var/success_message, var/failure_message, var/fuel_expenditure = 0, var/check_skill = SKILL_CONSTRUCTION, var/check_skill_threshold, var/check_skill_prob = 50, var/set_cooldown = FALSE) if(get_tool_quality(archetype) <= 0) return FALSE var/datum/extension/tool/tool = get_extension(src, /datum/extension/tool) - . = tool.do_tool_interaction(archetype, user, target, delay, start_message, success_message, failure_message, fuel_expenditure, check_skill, check_skill_threshold, check_skill_prob) + . = tool.do_tool_interaction(archetype, user, target, delay, start_message, success_message, failure_message, fuel_expenditure, check_skill, check_skill_threshold, check_skill_prob, set_cooldown) if(QDELETED(user) || QDELETED(target)) return FALSE diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index 6ff51f087a4..edd50670dce 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -88,7 +88,7 @@ Notes: queueHide = !!showing if (queueHide) - addtimer(CALLBACK(src, .proc/do_hide), 1) + addtimer(CALLBACK(src, PROC_REF(do_hide)), 1) else do_hide() diff --git a/code/modules/turbolift/turbolift.dm b/code/modules/turbolift/turbolift.dm index 7005f2f332c..96c8276a2af 100644 --- a/code/modules/turbolift/turbolift.dm +++ b/code/modules/turbolift/turbolift.dm @@ -40,11 +40,11 @@ /datum/turbolift/proc/open_doors(var/datum/turbolift_floor/use_floor = current_floor) for(var/obj/machinery/door/airlock/door in (use_floor ? (doors + use_floor.doors) : doors)) - INVOKE_ASYNC(door, /obj/machinery/door/proc/open) + INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door, open)) /datum/turbolift/proc/close_doors(var/datum/turbolift_floor/use_floor = current_floor) for(var/obj/machinery/door/airlock/door in (use_floor ? (doors + use_floor.doors) : doors)) - INVOKE_ASYNC(door, /obj/machinery/door/proc/close) + INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door, close)) #define LIFT_MOVING 1 #define LIFT_WAITING_A 2 diff --git a/code/modules/turbolift/turbolift_areas.dm b/code/modules/turbolift/turbolift_areas.dm index 10276564fac..0d59bde8d0e 100644 --- a/code/modules/turbolift/turbolift_areas.dm +++ b/code/modules/turbolift/turbolift_areas.dm @@ -1,7 +1,7 @@ // Used for creating the exchange areas. /area/turbolift name = "Turbolift" - base_turf = /turf/simulated/open + base_turf = /turf/open requires_power = 0 sound_env = SMALL_ENCLOSED holomap_color = HOLOMAP_AREACOLOR_LIFTS diff --git a/code/modules/turbolift/turbolift_console.dm b/code/modules/turbolift/turbolift_console.dm index dfa7c14bb52..e570d0421ea 100644 --- a/code/modules/turbolift/turbolift_console.dm +++ b/code/modules/turbolift/turbolift_console.dm @@ -6,7 +6,7 @@ density = FALSE layer = ABOVE_OBJ_LAYER obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - directional_offset = "{'NORTH':{'y':-32}, 'SOUTH':{'y':32}, 'EAST':{'x':-32}, 'WEST':{'x':32}}" + directional_offset = @'{"NORTH":{"y":-32}, "SOUTH":{"y":32}, "EAST":{"x":-32}, "WEST":{"x":32}}' var/datum/turbolift/lift /obj/structure/lift/proc/pressed(var/mob/user) diff --git a/code/modules/turbolift/turbolift_map.dm b/code/modules/turbolift/turbolift_map.dm index 9e29e1d2688..e3794e6fc11 100644 --- a/code/modules/turbolift/turbolift_map.dm +++ b/code/modules/turbolift/turbolift_map.dm @@ -159,7 +159,7 @@ INITIALIZE_IMMEDIATE(/obj/abstract/turbolift_spawner) return // Update path appropriately if needed. - var/swap_to = /turf/simulated/open + var/swap_to = /turf/space // this will be resolved to the appropriate open turf type by ChangeTurf(). if(cz == uz) // Elevator. if(wall_type && (tx == ux || ty == uy || tx == ex || ty == ey) && !(tx >= door_x1 && tx <= door_x2 && ty >= door_y1 && ty <= door_y2)) swap_to = wall_type diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index b3facf35c84..e995266e03f 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -361,10 +361,10 @@ if(!is_train_head() || !on) move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind else - move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains - move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines) - move_delay += config.run_delay //base reference speed - move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight + move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) // limits base overweight so you cant overspeed trains + move_delay *= (1 / max(1, active_engines)) * 2 // overweight penalty (scaled by the number of engines) + move_delay += get_config_value(/decl/config/num/movement_run) // base reference speed + move_delay *= 1.1 // makes cargo trains 10% slower than running when not overweight /obj/vehicle/train/cargo/trolley/update_car(var/train_length, var/active_engines) src.train_length = train_length diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 2bc98d39530..a354dbd2e0a 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -17,18 +17,19 @@ var/global/list/ventcrawl_machinery = list( /obj/item/sword/cultblade ) -/mob/living/var/list/icon/pipes_shown = list() -/mob/living/var/is_ventcrawling = 0 -/mob/var/next_play_vent = 0 +/mob/living + var/list/image/pipes_shown + var/is_ventcrawling = FALSE + var/next_play_vent = 0 /mob/living/proc/can_ventcrawl() if(!client) return FALSE if(!(/mob/living/proc/ventcrawl in verbs)) - to_chat(src, "You don't possess the ability to ventcrawl!") + to_chat(src, SPAN_WARNING("You don't possess the ability to ventcrawl!")) return FALSE if(incapacitated()) - to_chat(src, "You cannot ventcrawl in your current state!") + to_chat(src, SPAN_WARNING("You cannot ventcrawl in your current state!")) return FALSE return ventcrawl_carry() @@ -56,7 +57,7 @@ var/global/list/ventcrawl_machinery = list( /mob/living/proc/ventcrawl_carry() for(var/atom/A in contents) if(!is_allowed_vent_crawl_item(A)) - to_chat(src, "You can't carry \the [A] while ventcrawling!") + to_chat(src, SPAN_WARNING("You can't carry \the [A] while ventcrawling!")) return FALSE return TRUE @@ -86,67 +87,62 @@ var/global/list/ventcrawl_machinery = list( return 1 /mob/living/proc/handle_ventcrawl(var/atom/clicked_on) + if(!can_ventcrawl()) return - var/obj/machinery/atmospherics/unary/vent_found - if(clicked_on && Adjacent(clicked_on)) - vent_found = clicked_on - if(!istype(vent_found) || !vent_found.can_crawl_through()) - vent_found = null + var/obj/machinery/atmospherics/unary/vent_found = clicked_on + if(!istype(vent_found) || !vent_found.can_crawl_through() || !Adjacent(vent_found)) + vent_found = null + for(var/obj/machinery/atmospherics/unary/machine in range(1,src)) + if(!Adjacent(machine)) + continue + if(!is_type_in_list(machine, ventcrawl_machinery)) + continue + if(!machine.can_crawl_through()) + continue + vent_found = machine + break if(!vent_found) - for(var/obj/machinery/atmospherics/machine in range(1,src)) - if(is_type_in_list(machine, ventcrawl_machinery)) - vent_found = machine - - if(!vent_found || !vent_found.can_crawl_through()) - vent_found = null - - if(vent_found) - break - - if(vent_found) - var/datum/pipe_network/network = vent_found.network_in_dir(vent_found.dir) - if(network && (network.normal_members.len || network.line_members.len)) - - to_chat(src, "You begin climbing into the ventilation system...") - if(vent_found.air_contents && !issilicon(src)) - - switch(vent_found.air_contents.temperature) - if(0 to BODYTEMP_COLD_DAMAGE_LIMIT) - to_chat(src, "You feel a painful freeze coming from the vent!") - if(BODYTEMP_COLD_DAMAGE_LIMIT to T0C) - to_chat(src, "You feel an icy chill coming from the vent.") - if(T0C + 40 to BODYTEMP_HEAT_DAMAGE_LIMIT) - to_chat(src, "You feel a hot wash coming from the vent.") - if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) - to_chat(src, "You feel a searing heat coming from the vent!") - switch(vent_found.air_contents.return_pressure()) - if(0 to HAZARD_LOW_PRESSURE) - to_chat(src, "You feel a rushing draw pulling you into the vent!") - if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) - to_chat(src, "You feel a strong drag pulling you into the vent.") - if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) - to_chat(src, "You feel a strong current pushing you away from the vent.") - if(HAZARD_HIGH_PRESSURE to INFINITY) - to_chat(src, "You feel a roaring wind pushing you away from the vent!") - if(!do_after(src, 45, vent_found, 1, 1)) - return - if(!can_ventcrawl()) - return - - visible_message("[src] scrambles into the ventilation ducts!", "You climb into the ventilation system.") - - forceMove(vent_found) - add_ventcrawl(vent_found) - - else - to_chat(src, "This vent is not connected to anything.") - else to_chat(src, "You must be standing on or beside an air vent to enter it.") + return + + var/datum/pipe_network/network = vent_found.network_in_dir(vent_found.dir) + if(!network || (!length(network.normal_members) && !length(network.line_members))) + to_chat(src, "This vent is not connected to anything.") + return + + to_chat(src, "You begin climbing into the ventilation system...") + if(vent_found.air_contents && !issilicon(src)) + switch(vent_found.air_contents.temperature) + if(0 to BODYTEMP_COLD_DAMAGE_LIMIT) + to_chat(src, SPAN_DANGER("You feel a painful freeze coming from the vent!")) + if(BODYTEMP_COLD_DAMAGE_LIMIT to T0C) + to_chat(src, SPAN_WARNING("You feel an icy chill coming from the vent.")) + if(T0C + 40 to BODYTEMP_HEAT_DAMAGE_LIMIT) + to_chat(src, SPAN_WARNING("You feel a hot wash coming from the vent.")) + if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) + to_chat(src, SPAN_DANGER("You feel a searing heat coming from the vent!")) + switch(vent_found.air_contents.return_pressure()) + if(0 to HAZARD_LOW_PRESSURE) + to_chat(src, SPAN_DANGER("You feel a rushing draw pulling you into the vent!")) + if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) + to_chat(src, SPAN_WARNING("You feel a strong drag pulling you into the vent.")) + if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) + to_chat(src, SPAN_WARNING("You feel a strong current pushing you away from the vent.")) + if(HAZARD_HIGH_PRESSURE to INFINITY) + to_chat(src, SPAN_DANGER("You feel a roaring wind pushing you away from the vent!")) + + if(!do_after(src, 45, vent_found, 1, 1) || !can_ventcrawl()) + return + + visible_message("\The [src] scrambles into the ventilation ducts!", "You climb into the ventilation system.") + forceMove(vent_found) + add_ventcrawl(vent_found) + /mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine) - is_ventcrawling = 1 + is_ventcrawling = TRUE //candrop = 0 var/datum/pipe_network/network = starting_machine.return_network(starting_machine) if(!network) @@ -155,15 +151,13 @@ var/global/list/ventcrawl_machinery = list( for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) if(!A.pipe_image) A.pipe_image = emissive_overlay(icon = A, loc = A.loc, dir = A.dir) - pipes_shown += A.pipe_image + LAZYDISTINCTADD(pipes_shown, A.pipe_image) client.images += A.pipe_image /mob/living/proc/remove_ventcrawl() - is_ventcrawling = 0 - //candrop = 1 + is_ventcrawling = FALSE if(client) for(var/image/current_image in pipes_shown) client.images -= current_image client.eye = src - - pipes_shown.len = 0 + LAZYCLEARLIST(pipes_shown) diff --git a/code/modules/ventcrawl/ventcrawl_atmospherics.dm b/code/modules/ventcrawl/ventcrawl_atmospherics.dm index a12184e78e3..1399a9df5b1 100644 --- a/code/modules/ventcrawl/ventcrawl_atmospherics.dm +++ b/code/modules/ventcrawl/ventcrawl_atmospherics.dm @@ -8,7 +8,7 @@ for(var/mob/living/M in global.player_list) if(M.client) M.client.images -= pipe_image - M.pipes_shown -= pipe_image + LAZYREMOVE(M.pipes_shown, pipe_image) pipe_image = null . = ..() diff --git a/code/modules/weather/_weather.dm b/code/modules/weather/_weather.dm index 53c581e5774..7f27ab62ca1 100644 --- a/code/modules/weather/_weather.dm +++ b/code/modules/weather/_weather.dm @@ -23,12 +23,13 @@ */ /obj/abstract/weather_system - plane = DEFAULT_PLANE - layer = ABOVE_PROJECTILE_LAYER - icon = 'icons/effects/weather.dmi' - icon_state = "blank" - invisibility = INVISIBILITY_NONE - appearance_flags = (RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) + plane = DEFAULT_PLANE + layer = ABOVE_PROJECTILE_LAYER + icon = 'icons/effects/weather.dmi' + icon_state = "blank" + invisibility = INVISIBILITY_NONE + appearance_flags = (RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) + is_spawnable_type = FALSE var/water_material = /decl/material/liquid/water // Material to use for the properties of rain. var/ice_material = /decl/material/solid/ice // Material to use for the properties of snow and hail. @@ -91,9 +92,10 @@ // Dummy object for lightning flash animation. /obj/abstract/lightning_overlay - plane = EMISSIVE_PLANE - layer = ABOVE_LIGHTING_LAYER - icon = 'icons/effects/weather.dmi' - icon_state = "full" - alpha = 0 - invisibility = INVISIBILITY_NONE + plane = EMISSIVE_PLANE + layer = ABOVE_LIGHTING_LAYER + icon = 'icons/effects/weather.dmi' + icon_state = "full" + alpha = 0 + invisibility = INVISIBILITY_NONE + is_spawnable_type = FALSE diff --git a/code/modules/weather/weather_init.dm b/code/modules/weather/weather_init.dm index c8533997c8d..d5fdc4e5632 100644 --- a/code/modules/weather/weather_init.dm +++ b/code/modules/weather/weather_init.dm @@ -21,7 +21,7 @@ INITIALIZE_IMMEDIATE(/obj/abstract/weather_system) // If we're post-init, init immediately. if(SSweather.initialized) - addtimer(CALLBACK(src, .proc/init_weather), 0) + addtimer(CALLBACK(src, PROC_REF(init_weather)), 0) // Start the weather effects from the highest point; they will propagate downwards during update. /obj/abstract/weather_system/proc/init_weather() diff --git a/code/modules/weather/weather_mob_tracking.dm b/code/modules/weather/weather_mob_tracking.dm index 0a1a318700b..4355918aa8f 100644 --- a/code/modules/weather/weather_mob_tracking.dm +++ b/code/modules/weather/weather_mob_tracking.dm @@ -2,8 +2,8 @@ var/global/list/current_mob_ambience = list() /obj/abstract/weather_system - // Weakref lists used to track mobs within our weather - // system; alternative to keeping big lists of actual mobs or + // Weakref lists used to track mobs within our weather + // system; alternative to keeping big lists of actual mobs or // having mobs constantly poked by weather systems. var/tmp/list/mobs_on_cooldown = list() // Has this mob recently been messed with by the weather? @@ -15,7 +15,7 @@ var/global/list/current_mob_ambience = list() var/mobref = weakref(M) if(!(mobref in mobs_on_cooldown)) mobs_on_cooldown[mobref] = TRUE - addtimer(CALLBACK(src, .proc/clear_cooldown, mobref), delay) + addtimer(CALLBACK(src, PROC_REF(clear_cooldown), mobref), delay) return TRUE return FALSE diff --git a/code/modules/webhooks/_webhook.dm b/code/modules/webhooks/_webhook.dm index e7cfb646cd7..ed5087c06bd 100644 --- a/code/modules/webhooks/_webhook.dm +++ b/code/modules/webhooks/_webhook.dm @@ -10,7 +10,7 @@ if (!target_url) return -1 - var/result = call(HTTP_POST_DLL_LOCATION, "send_post_request")(target_url, payload, json_encode(list("Content-Type" = "application/json"))) + var/result = LIBCALL(HTTP_POST_DLL_LOCATION, "send_post_request")(target_url, payload, json_encode(list("Content-Type" = "application/json"))) result = cached_json_decode(result) if (result["error_code"]) @@ -27,7 +27,7 @@ if(!length(message)) return FALSE - if(config.disable_webhook_embeds) + if(get_config_value(/decl/config/toggle/disable_webhook_embeds)) var/list/embed_content for(var/list/embed in message["embeds"]) if(embed["title"]) diff --git a/code/modules/webhooks/webhook_fax.dm b/code/modules/webhooks/webhook_fax.dm new file mode 100644 index 00000000000..aed15715efd --- /dev/null +++ b/code/modules/webhooks/webhook_fax.dm @@ -0,0 +1,11 @@ +/decl/webhook/fax_sent + id = WEBHOOK_FAX_SENT + +// Data expects a "body" field containing a message. +/decl/webhook/fax_sent/get_message(var/list/data) + . = ..() + .["embeds"] = list(list( + "title" = (data && data["title"]) || "undefined", + "description" = (data && data["body"]) || "undefined", + "color" = COLOR_WEBHOOK_DEFAULT + )) diff --git a/code/modules/xenoarcheaology/artifacts/standalone/autocloner.dm b/code/modules/xenoarcheaology/artifacts/standalone/autocloner.dm index 7490ac3ccf0..4c3ed1a86ec 100644 --- a/code/modules/xenoarcheaology/artifacts/standalone/autocloner.dm +++ b/code/modules/xenoarcheaology/artifacts/standalone/autocloner.dm @@ -25,7 +25,7 @@ /mob/living/simple_animal/cat, /mob/living/simple_animal/corgi, /mob/living/simple_animal/corgi/puppy, - /mob/living/simple_animal/chicken, + /mob/living/simple_animal/fowl/chicken, /mob/living/simple_animal/cow, /mob/living/simple_animal/hostile/retaliate/parrot, /mob/living/simple_animal/crab, diff --git a/code/modules/xenoarcheaology/artifacts/triggers/chemical.dm b/code/modules/xenoarcheaology/artifacts/triggers/chemical.dm index 85ba282053a..b9e734a595a 100644 --- a/code/modules/xenoarcheaology/artifacts/triggers/chemical.dm +++ b/code/modules/xenoarcheaology/artifacts/triggers/chemical.dm @@ -16,7 +16,7 @@ . = ..() if(istype(O, /obj/item/chems)) for(var/reagent in required_chemicals) - if(O.reagents.remove_reagent(reagent, 1)) + if(O.remove_from_reagents(reagent, 1)) return TRUE /datum/artifact_trigger/chemical/water diff --git a/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm b/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm index b6d2d50adef..9cd5a4e78ae 100644 --- a/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm +++ b/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm @@ -42,4 +42,4 @@ START_PROCESSING(SSobj, src) /obj/item/chems/glass/replenishing/Process() - reagents.add_reagent(spawning_id, 0.3) \ No newline at end of file + add_to_reagents(spawning_id, 0.3) \ No newline at end of file diff --git a/code/modules/xenoarcheaology/finds/strange_rock.dm b/code/modules/xenoarcheaology/finds/strange_rock.dm index e30753a5abb..73a4009878f 100644 --- a/code/modules/xenoarcheaology/finds/strange_rock.dm +++ b/code/modules/xenoarcheaology/finds/strange_rock.dm @@ -4,7 +4,7 @@ desc = "Seems to have some unusal strata evident throughout it." icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "strange" - origin_tech = "{'materials':5}" + origin_tech = @'{"materials":5}' material = /decl/material/solid/stone/sandstone var/obj/item/inside diff --git a/code/modules/xenoarcheaology/machinery/artifact_analyser.dm b/code/modules/xenoarcheaology/machinery/artifact_analyser.dm index 5cf1f67dc33..af753c97347 100644 --- a/code/modules/xenoarcheaology/machinery/artifact_analyser.dm +++ b/code/modules/xenoarcheaology/machinery/artifact_analyser.dm @@ -29,7 +29,7 @@ if(!owned_scanner) owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src) if(owned_scanner) - events_repository.register(/decl/observ/destroyed, owned_scanner, src, /obj/machinery/artifact_analyser/proc/clear_scanner) + events_repository.register(/decl/observ/destroyed, owned_scanner, src, TYPE_PROC_REF(/obj/machinery/artifact_analyser, clear_scanner)) /obj/machinery/artifact_analyser/proc/clear_scanner() if(owned_scanner) @@ -39,7 +39,7 @@ /obj/machinery/artifact_analyser/proc/set_object(var/obj/O) if(O != scanned_object && O) clear_object() - events_repository.register(/decl/observ/destroyed, O, src, /obj/machinery/artifact_analyser/proc/clear_object) + events_repository.register(/decl/observ/destroyed, O, src, TYPE_PROC_REF(/obj/machinery/artifact_analyser, clear_object)) scanned_object = O /obj/machinery/artifact_analyser/proc/clear_object() diff --git a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm index e04ff905dac..3b7f727b735 100644 --- a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm +++ b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm @@ -31,7 +31,7 @@ if(!owned_scanner) owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src) if(owned_scanner) - events_repository.register(/decl/observ/destroyed, owned_scanner, src, /obj/machinery/artifact_analyser/proc/clear_scanner) + events_repository.register(/decl/observ/destroyed, owned_scanner, src, TYPE_PROC_REF(/obj/machinery/artifact_analyser, clear_scanner)) /obj/machinery/artifact_harvester/Destroy() clear_scanner() @@ -53,7 +53,7 @@ if(cur_artifact == new_artifact || !new_artifact) return clear_artifact() - events_repository.register(/decl/observ/destroyed, new_artifact, src, /obj/machinery/artifact_harvester/proc/clear_artifact) + events_repository.register(/decl/observ/destroyed, new_artifact, src, TYPE_PROC_REF(/obj/machinery/artifact_harvester, clear_artifact)) cur_artifact = new_artifact /obj/machinery/artifact_harvester/attackby(var/obj/I, var/mob/user) diff --git a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm index b4df95cc6e1..a88e5046041 100644 --- a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm +++ b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm @@ -265,7 +265,7 @@ radiation = 0 t_left_radspike = 0 if(used_coolant) - src.reagents.remove_any(used_coolant) + remove_any_reagents(used_coolant) used_coolant = 0 /obj/machinery/radiocarbon_spectrometer/proc/complete_scan() diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index 3f10112a63b..03510f0db9e 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -134,7 +134,7 @@ activated = 1 current_tick = 0 START_PROCESSING(SSobj, src) - events_repository.register(/decl/observ/moved, src, src, /obj/item/anodevice/proc/on_move) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/obj/item/anodevice, on_move)) if(inserted_battery?.battery_effect?.activated == 0) inserted_battery.battery_effect.ToggleActivate(1) diff --git a/code/modules/xenoarcheaology/tools/anomaly_scanner.dm b/code/modules/xenoarcheaology/tools/anomaly_scanner.dm index 9a09ac427fd..94555b7c17c 100644 --- a/code/modules/xenoarcheaology/tools/anomaly_scanner.dm +++ b/code/modules/xenoarcheaology/tools/anomaly_scanner.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "flashgun" item_state = "flashgun" - origin_tech = "{'wormholes':3,'magnets':3}" + origin_tech = @'{"wormholes":3,"magnets":3}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/metal/aluminium = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/xenoarcheaology/tools/depth_scanner.dm b/code/modules/xenoarcheaology/tools/depth_scanner.dm index 5698d8d2566..c09dedbda44 100644 --- a/code/modules/xenoarcheaology/tools/depth_scanner.dm +++ b/code/modules/xenoarcheaology/tools/depth_scanner.dm @@ -3,7 +3,7 @@ desc = "A device used to check spatial depth and density of rock outcroppings." icon = 'icons/obj/items/device/depth_scanner.dmi' icon_state = ICON_STATE_WORLD - origin_tech = "{'magnets':2,'engineering':2,'wormholes':2}" + origin_tech = @'{"magnets":2,"engineering":2,"wormholes":2}' material = /decl/material/solid/metal/steel matter = list( /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT, diff --git a/code/modules/xenoarcheaology/tools/misc.dm b/code/modules/xenoarcheaology/tools/misc.dm index 3e75af3789c..538539e1bdd 100644 --- a/code/modules/xenoarcheaology/tools/misc.dm +++ b/code/modules/xenoarcheaology/tools/misc.dm @@ -5,10 +5,10 @@ return list( /obj/item/book/manual/excavation, /obj/item/book/manual/mass_spectrometry, - /obj/item/book/manual/materials_chemistry_analysis, - /obj/item/book/manual/anomaly_testing, - /obj/item/book/manual/anomaly_spectroscopy, - /obj/item/book/manual/stasis, + /obj/item/book/fluff/materials_chemistry_analysis, + /obj/item/book/fluff/anomaly_testing, + /obj/item/book/fluff/anomaly_spectroscopy, + /obj/item/book/fluff/stasis, ) /obj/structure/closet/secure_closet/xenoarchaeologist @@ -68,7 +68,7 @@ //Structures /decl/material/solid/metal/chromium/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += /datum/stack_recipe/structure/anomaly_container /datum/stack_recipe/structure/anomaly_container diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index 39eb1497975..d2daf82b18d 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -3,7 +3,7 @@ desc = "A coiled metallic tape used to check dimensions and lengths." icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "measuring" - origin_tech = "{'materials':1}" + origin_tech = @'{"materials":1}' material = /decl/material/solid/metal/steel w_class = ITEM_SIZE_SMALL diff --git a/code/procs/AStar.dm b/code/procs/AStar.dm index e3cf62730d7..01e4213f805 100644 --- a/code/procs/AStar.dm +++ b/code/procs/AStar.dm @@ -12,7 +12,7 @@ And for the distance one i wrote: /turf/proc/Distance So an example use might be: -src.path_list = AStar(src.loc, target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance) +src.path_list = AStar(src.loc, target.loc, TYPE_PROC_REF(/turf, AdjacentTurfs), TYPE_PROC_REF(/turf, Distance)) Note: The path is returned starting at the END node, so i wrote reverselist to reverse it for ease of use. diff --git a/code/unit_tests/chemistry_tests.dm b/code/unit_tests/chemistry_tests.dm index 6b16b290696..344b3d3a4e7 100644 --- a/code/unit_tests/chemistry_tests.dm +++ b/code/unit_tests/chemistry_tests.dm @@ -12,7 +12,7 @@ var/atom/from = new donor_type(test_loc) from.create_reagents(container_volume) - from.reagents.add_reagent(/decl/material/liquid/water, container_volume) + from.add_to_reagents(/decl/material/liquid/water, container_volume) var/atom/target if(ispath(recipient_type, /turf) && istype(test_loc, recipient_type)) @@ -219,9 +219,8 @@ // Cleanup pt. 2 chem_refs.Cut() - var/obj/effect/fluid/fluid = locate() in spawn_spot - if(fluid) - qdel(fluid) + if(spawn_spot.reagents?.total_volume) + spawn_spot.reagents.clear_reagents() failures += "- spawn turf had fluids post-test" // Report status. diff --git a/code/unit_tests/del_the_world.dm b/code/unit_tests/del_the_world.dm index a61220afb3e..8a831476e31 100644 --- a/code/unit_tests/del_the_world.dm +++ b/code/unit_tests/del_the_world.dm @@ -6,6 +6,16 @@ /datum/unit_test/del_the_world/start_test() var/turf/spawn_loc = get_safe_turf() var/list/cached_contents = spawn_loc.contents.Copy() + + /// Types to except from GC checking tests. + var/list/gc_exceptions = list( + // I hate doing this, but until the graph tests are fixed by someone who actually understands them, + // this is the best I can do without breaking other stuff. + /datum/node/physical, + // Randomly fails to GC during CI, cause unclear. Remove this if the root cause is identified. + /obj/item/organ/external/chest + ) + var/list/ignore = typesof( // will error if the area already has one /obj/machinery/power/apc, @@ -24,8 +34,7 @@ // Needs a level above. /obj/structure/stairs, // Fluid system related; causes issues with atoms spawned on the turf. - /obj/abstract/fluid_mapped, - /obj/effect/fluid, + /obj/abstract/landmark/mapped_fluid, /obj/effect/flood, // Not valid when spawned manually. /obj/effect/overmap, @@ -120,9 +129,7 @@ //Alright, time to see if anything messed up var/list/cache_for_sonic_speed = SSgarbage.items for(var/path in cache_for_sonic_speed) - if(ispath(path, /datum/node/physical)) - // I hate doing this, but until the graph tests are fixed by someone who actually understands them, - // this is the best I can do without breaking other stuff. + if(path in gc_exceptions) continue var/datum/qdel_item/item = cache_for_sonic_speed[path] if(item.failures) diff --git a/code/unit_tests/food_tests.dm b/code/unit_tests/food_tests.dm index 864a5709320..9c2ceb4f1ec 100644 --- a/code/unit_tests/food_tests.dm +++ b/code/unit_tests/food_tests.dm @@ -13,6 +13,10 @@ for (var/subtype in subtypesof(/obj/item/chems/food/slice)) var/obj/item/chems/food/slice/slice = subtype + + if(TYPE_IS_ABSTRACT(slice)) + continue + if(!initial(slice.whole_path)) log_bad("[slice] does not define a whole_path.") any_failed = TRUE diff --git a/code/unit_tests/icon_tests.dm b/code/unit_tests/icon_tests.dm index 3bebd89e95d..8a03c5f1aa2 100644 --- a/code/unit_tests/icon_tests.dm +++ b/code/unit_tests/icon_tests.dm @@ -8,8 +8,7 @@ /turf/unsimulated/mimic_edge, /turf/exterior/mimic_edge, /turf/simulated/mimic_edge, - /turf/exterior/open, - /turf/simulated/open + /turf/open ) /datum/unit_test/icon_test/turfs_shall_have_icon_states/start_test() diff --git a/code/unit_tests/items.dm b/code/unit_tests/items.dm index 2bdf8d336a3..e6d7dce493d 100644 --- a/code/unit_tests/items.dm +++ b/code/unit_tests/items.dm @@ -69,4 +69,41 @@ /datum/item_unit_test/constant //Checks that modify the objects -/datum/item_unit_test/volatile \ No newline at end of file +/datum/item_unit_test/volatile + +///////////////////////////////////////////////////////// +// Additional miscellaneous item tests below. +///////////////////////////////////////////////////////// + +// Not really an items test in an inheritance sense, but here for organization. +/datum/unit_test/paint_kits_shall_have_existing_states + name = "ITEMS: Paint Kits Shall Have Existing Icon States" + var/mech_decal_icon = 'icons/mecha/mech_decals.dmi' + var/static/list/blend_modes = list( + BLEND_OVERLAY, + BLEND_ADD, + BLEND_MULTIPLY, + BLEND_SUBTRACT + ) +// TODO: add other kits in here for validation somehow. +/datum/unit_test/paint_kits_shall_have_existing_states/start_test() + var/list/failures + for(var/kit_type in typesof(/obj/item/kit/paint)) + var/obj/item/kit/paintkit = kit_type + if(TYPE_IS_ABSTRACT(paintkit)) + continue + var/kit_state = initial(paintkit.new_state) + if(!kit_state) + LAZYADD(failures, "kit type [kit_type] has no decal state defined.") + else if(!check_state_in_icon(kit_state, mech_decal_icon)) + LAZYADD(failures, "kit type [kit_type] decal state '[kit_state]' not present in '[mech_decal_icon]'") + else + var/kit_blend = initial(paintkit.new_blend) + if(!(kit_blend in blend_modes)) + LAZYADD(failures, "kit type [kit_type] decal blend '[kit_blend || "NULL"]' not present in blend mode list") + + if(length(failures)) + fail("[length(failures)] type\s had problems:\n[jointext(failures, "\n")]") + else + pass("No kit types had errors.") + return 1 diff --git a/code/unit_tests/json.dm b/code/unit_tests/json.dm index 84002b7ad5c..a5be63f35bb 100644 --- a/code/unit_tests/json.dm +++ b/code/unit_tests/json.dm @@ -37,6 +37,11 @@ var/list/failures var/list/json_to_check + for(var/subtype in typesof(/obj)) + var/obj/test = subtype + var/check_json = initial(test.directional_offset) + if(!isnull(check_json)) + LAZYSET(json_to_check, "[subtype].directional_offset", check_json) for(var/subtype in typesof(/obj/item)) var/obj/item/test = subtype var/check_json = initial(test.center_of_mass) @@ -62,11 +67,17 @@ var/check_json = initial(test.possible_transfer_amounts) if(!isnull(check_json)) LAZYSET(json_to_check, "[subtype].possible_transfer_amounts", check_json) + var/list/prefabs = decls_repository.get_decls_of_subtype(/decl/prefab/ic_assembly) + for(var/assembly_path in prefabs) + var/decl/prefab/ic_assembly/assembly = prefabs[assembly_path] + var/check_json = assembly.data + if(!isnull(check_json)) + LAZYSET(json_to_check, "[assembly_path].data", check_json) // Validate JSON. for(var/check_key in json_to_check) try var/list/output = cached_json_decode(json_to_check[check_key]) - if(!islist(output) || !length(output)) + if(findtext(json_to_check[check_key], "{'") || !islist(output) || !length(output)) LAZYADD(failures, check_key) catch() LAZYADD(failures, check_key) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index 54e56f315d0..6d30b9ba257 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -922,7 +922,7 @@ var/is_bad_door = FALSE for(var/turf/T in D.locs) - if((istype(T, /turf/simulated/open) || isspaceturf(T)) && !(T.type in turf_exceptions)) + if(T.is_open() && !(T.type in turf_exceptions)) is_bad_door = TRUE log_bad("Invalid door turf: [log_info_line(T)]") if(is_bad_door) diff --git a/code/unit_tests/materials.dm b/code/unit_tests/materials.dm index dcfbd4ed483..0c29de05fe4 100644 --- a/code/unit_tests/materials.dm +++ b/code/unit_tests/materials.dm @@ -27,23 +27,24 @@ recipes |= recipe_stack.recipes for(var/datum/stack_recipe/recipe as anything in recipes) - var/obj/product = recipe.spawn_result() + var/atom/product = recipe.spawn_result() var/failed if(!product) failed = "no product returned" - else if(!istype(product)) - failed = "non-obj product returned ([product.type])" - else - LAZYINITLIST(product.matter) // For the purposes of the following tests not runtiming. + else if(!istype(product, recipe.expected_product_type)) + failed = "unexpected product type returned ([product.type])" + else if(isobj(product)) + var/obj/product_obj = product + LAZYINITLIST(product_obj.matter) // For the purposes of the following tests not runtiming. if(!recipe.use_material && !recipe.use_reinf_material) - if(length(product.matter)) + if(length(product_obj.matter)) failed = "unsupplied material types" - else if(recipe.use_material && (product.matter[recipe.use_material]/SHEET_MATERIAL_AMOUNT) > recipe.req_amount) - failed = "excessive base material ([recipe.req_amount]/[CEILING(product.matter[recipe.use_material]/SHEET_MATERIAL_AMOUNT)])" - else if(recipe.use_reinf_material && (product.matter[recipe.use_reinf_material]/SHEET_MATERIAL_AMOUNT) > recipe.req_amount) - failed = "excessive reinf material ([recipe.req_amount]/[CEILING(product.matter[recipe.use_reinf_material]/SHEET_MATERIAL_AMOUNT)])" + else if(recipe.use_material && (product_obj.matter[recipe.use_material]/SHEET_MATERIAL_AMOUNT) > recipe.req_amount) + failed = "excessive base material ([recipe.req_amount]/[CEILING(product_obj.matter[recipe.use_material]/SHEET_MATERIAL_AMOUNT)])" + else if(recipe.use_reinf_material && (product_obj.matter[recipe.use_reinf_material]/SHEET_MATERIAL_AMOUNT) > recipe.req_amount) + failed = "excessive reinf material ([recipe.req_amount]/[CEILING(product_obj.matter[recipe.use_reinf_material]/SHEET_MATERIAL_AMOUNT)])" else - for(var/mat in product.matter) + for(var/mat in product_obj.matter) if(mat != recipe.use_material && mat != recipe.use_reinf_material) failed = "extra material type ([mat])" if(failed) // Try to prune out some duplicate error spam, we have too many materials now diff --git a/code/unit_tests/observation_tests.dm b/code/unit_tests/observation_tests.dm index 1ea0867030c..0837fc2c0d3 100644 --- a/code/unit_tests/observation_tests.dm +++ b/code/unit_tests/observation_tests.dm @@ -10,8 +10,6 @@ var/list/received_name_set_events var/list/stored_global_listen_count - var/list/stored_event_sources_count - var/list/stored_event_listen_count /datum/unit_test/observation/start_test() received_moves = received_moves || list() @@ -24,8 +22,6 @@ events_repository.unregister_global(/decl/observ/moved, global_listener) stored_global_listen_count = global.global_listen_count.Copy() - stored_event_sources_count = global.event_sources_count.Copy() - stored_event_listen_count = global.event_listen_count.Copy() sanity_check_events("Pre-Test") . = conduct_test() @@ -62,10 +58,6 @@ for(var/entry in (global.global_listen_count - stored_global_listen_count)) fail("[phase]: global_listen_count - Contained [log_info_line(entry)].") - for(var/entry in (global.event_sources_count - stored_event_sources_count)) - fail("[phase]: event_sources_count - Contained [log_info_line(entry)].") - for(var/entry in (global.event_listen_count - stored_event_listen_count)) - fail("[phase]: event_listen_count - Contained [log_info_line(entry)].") /datum/unit_test/observation/proc/conduct_test() return 0 @@ -97,7 +89,7 @@ old_name = O.name new_name = O.name + " (New)" - events_repository.register_global(/decl/observ/name_set, src, /datum/unit_test/observation/proc/receive_name_change) + events_repository.register_global(/decl/observ/name_set, src, TYPE_PROC_REF(/datum/unit_test/observation, receive_name_change)) O.SetName(new_name) if(received_name_set_events.len != 1) @@ -240,7 +232,7 @@ exosuit.occupant = holding_mob - events_repository.register(/decl/observ/moved, held_item, src, /datum/unit_test/observation/proc/receive_move) + events_repository.register(/decl/observ/moved, held_item, src, TYPE_PROC_REF(/datum/unit_test/observation, receive_move)) holding_mob.drop_from_inventory(held_item) if(received_moves.len != 1) @@ -320,7 +312,7 @@ var/turf/T = get_safe_turf() var/obj/O = get_named_instance(/obj, T) - events_repository.register_global(/decl/observ/name_set, O, /atom/movable/proc/move_to_turf) + events_repository.register_global(/decl/observ/name_set, O, TYPE_PROC_REF(/atom/movable, move_to_turf)) qdel(O) var/decl/observ/name_set/name_set_event = GET_DECL(/decl/observ/name_set) @@ -347,7 +339,7 @@ var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener = get_named_instance(/mob, T, "Event Listener") - events_repository.register(/decl/observ/moved, event_source, listener, /atom/movable/proc/recursive_move) + events_repository.register(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) qdel(event_source) var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) @@ -375,7 +367,7 @@ var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener = get_named_instance(/mob, T, "Event Listener") - events_repository.register(/decl/observ/moved, event_source, listener, /atom/movable/proc/recursive_move) + events_repository.register(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) qdel(listener) var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) diff --git a/code/unit_tests/proximity_tests.dm b/code/unit_tests/proximity_tests.dm index ef196a9b7a8..e9d9729c182 100644 --- a/code/unit_tests/proximity_tests.dm +++ b/code/unit_tests/proximity_tests.dm @@ -133,7 +133,7 @@ /obj/proximity_listener/proc/SetTrigger(trigger_type, listener_flags) QDEL_NULL(trigger) - trigger = new trigger_type(src, /obj/proximity_listener/proc/OnTurfEntered, /obj/proximity_listener/proc/OnTurfsChanged, 7, listener_flags, null, 90, 270) + trigger = new trigger_type(src, TYPE_PROC_REF(/obj/proximity_listener, OnTurfEntered), TYPE_PROC_REF(/obj/proximity_listener, OnTurfsChanged), 7, listener_flags, null, 90, 270) trigger.register_turfs() /obj/proximity_listener/Destroy() diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm index f23f690b8b9..ac232116fb8 100644 --- a/code/unit_tests/unit_test.dm +++ b/code/unit_tests/unit_test.dm @@ -151,14 +151,6 @@ var/global/ascii_reset = "[ascii_esc]\[0m" /datum/unit_test/proc/subsystems_to_await() return list() -/proc/load_unit_test_changes() -/* - //This takes about 60 seconds to run during unit testing and is only used for the ZAS vacume check on The Asteroid. - if(config.roundstart_level_generation != 1) - log_unit_test("Overiding Configuration option for Asteroid Generation to ENABLED") - config.roundstart_level_generation = 1 // The default map requires it, the example config doesn't have this enabled. - */ - /proc/get_test_datums() . = list() for(var/test in subtypesof(/datum/unit_test)) diff --git a/code/unit_tests/~unit_test_subsystems.dm b/code/unit_tests/~unit_test_subsystems.dm index 31b6c97c7eb..9cb2e10f314 100644 --- a/code/unit_tests/~unit_test_subsystems.dm +++ b/code/unit_tests/~unit_test_subsystems.dm @@ -16,6 +16,7 @@ SUBSYSTEM_DEF(unit_tests) MAP_TEMPLATE_CATEGORY_AWAYSITE, MAP_TEMPLATE_CATEGORY_PLANET, MAP_TEMPLATE_CATEGORY_EXOPLANET, + MAP_TEMPLATE_CATEGORY_LANDMARK_LOADED ) /datum/controller/subsystem/unit_tests/Initialize(timeofday) diff --git a/config/example/config.txt b/config/example/config.txt deleted file mode 100644 index d41d8fa92cd..00000000000 --- a/config/example/config.txt +++ /dev/null @@ -1,470 +0,0 @@ -## Server name: This appears at the top of the screen in-game. In this case it will read "tgstation: station_name" where station_name is the randomly generated name of the station for the round. Remove the # infront of SERVERNAME and replace 'tgstation' with the name of your choice -# SERVERNAME spacestation13 - -## Hub visibility: If you want to be visible on the hub, uncomment the below line and be sure that Dream Daemon is set to "Visible." This can be changed in-round as well with toggle-hub-visibility if Dream Daemon is set correctly. -# HUB - -## Add a # infront of this if you want to use the SQL based admin system, the legacy system uses admins.txt. You need to set up your database to use the SQL based system. -ADMIN_LEGACY_SYSTEM - -## Add a # infront of this if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system. -BAN_LEGACY_SYSTEM - -## Add a # here if you wish to use the setup where jobs have more access. This is intended for servers with low populations - where there are not enough players to fill all roles, so players need to do more than just one job. Also for servers where they don't want people to hide in their own departments. -JOBS_HAVE_MINIMAL_ACCESS - -## Uncomment this and set it to a file path relative to the executing binary to prefix all custom item icon locations with this location ie. '[CUSTOM_ITEM_ICON_LOCATION]/[custom item icon path value]' -# CUSTOM_ITEM_ICON_LOCATION config/custom_items/icons - -## Uncomment this and set it to a file path relative to the executing binary to prefix all custom icon locations with this location ie. '[CUSTOM_ICON_ICON_LOCATION]/[custom icon path value]' -# CUSTOM_ICON_ICON_LOCATION config/custom_icons/icons - -## Unhash this entry to have certain jobs require your account to be at least a certain number of days old to select. You can configure the exact age requirement for different jobs by editing -## the minimal_player_age variable in the files in folder /code/game/jobs/job/.. for the job you want to edit. Set minimal_player_age to 0 to disable age requirement for that job. -## REQUIRES the database set up to work. Keep it hashed if you don't have a database set up. -## NOTE: If you have just set-up the database keep this DISABLED, as player age is determined from the first time they connect to the server with the database up. If you just set it up, it means -## you have noone older than 0 days, since noone has been logged yet. Only turn this on once you have had the database up for 30 days. -#USE_AGE_RESTRICTION_FOR_JOBS - -## Unhash this entry to have certain antag roles require your account to be at least a certain number of days old for round start and auto-spawn selection. -## Non-automatic antagonist recruitment, such as being converted to cultism is not affected. Has the same database requirements and notes as USE_AGE_RESTRICTION_FOR_JOBS. -#USE_AGE_RESTRICTION_FOR_ANTAGS - -## Unhash this to use iterative explosions, keep it hashed to use circle explosions. -#USE_ITERATIVE_EXPLOSIONS - -# The power of explosion required for it to cross Z-levels. -#EXPLOSION_Z_THRESHOLD 10 - -# What to multiply power by when crossing Z-levels. -#EXPLOSION_Z_MULT 0.75 - -## Radiation weakens with distance from the source; stop calculating when the strength falls below this value. Lower values mean radiation reaches smaller (with increasingly trivial damage) at the cost of more CPU usage. Max range = DISTANCE^2 * POWER / RADIATION_LOWER_LIMIT -# RADIATION_LOWER_LIMIT 0.35 - -## log OOC channel -LOG_OOC - -## log client Say -LOG_SAY - -## log admin actions -LOG_ADMIN - -## log client access (logon/logoff) -LOG_ACCESS - -## log game actions (start of round, results, etc.) -LOG_GAME - -## log player votes -LOG_VOTE - -## log client Whisper -LOG_WHISPER - -## log emotes -LOG_EMOTE - -## log attack messages -LOG_ATTACK - -## log pda messages -LOG_PDA - -## log world.log messages -# LOG_WORLD_OUTPUT - -## log all Topic() calls (for use by coders in tracking down Topic issues) -# LOG_HREFS - -## log world.log and runtime errors to a file -# LOG_RUNTIME - -## log admin warning messages -##LOG_ADMINWARN ## Also duplicates a bunch of other messages. - -## disconnect players who did nothing during the set amount of minutes -# KICK_INACTIVE 10 - -## Chooses whether mods have the ability to tempban or not -MODS_CAN_TEMPBAN - -## Chooses whether mods have the ability to issue tempbans for jobs or not -MODS_CAN_JOB_TEMPBAN - -## Maximum mod tempban duration (in minutes) -MOD_TEMPBAN_MAX 1440 - -## Maximum mod job tempban duration (in minutes) -MOD_JOB_TEMPBAN_MAX 1440 - - -## probablities for game modes chosen in "secret" and "random" modes -## -## default probablity is 1, increase to make that mode more likely to be picked -## set to 0 to disable that mode -PROBABILITY EXTENDED 1 -PROBABILITY MALFUNCTION 1 -PROBABILITY MERCENARY 1 -PROBABILITY WIZARD 1 -PROBABILITY CHANGELING 1 -PROBABILITY CULT 1 -PROBABILITY EXTEND-A-TRAITORMONGOUS 6 - -## if possible round types will be hidden from players for secret rounds -#SECRET_HIDE_POSSIBILITIES - -## Hash out to disable random events during the round. -ALLOW_RANDOM_EVENTS - -## if amount of traitors scales or not -TRAITOR_SCALING - -## if objectives are disabled -#OBJECTIVES_DISABLED - -## make ERT's be only called by admins -#ERT_ADMIN_ONLY - -## If uncommented, votes can be called to add extra antags to the round. -#ALLOW_EXTRA_ANTAGS - -## If security is prohibited from being most antagonists -#PROTECT_ROLES_FROM_ANTAGONIST - -## Comment this out to stop admins being able to choose their personal ooccolor -ALLOW_ADMIN_OOCCOLOR - -## allow players to initiate a restart vote -ALLOW_VOTE_RESTART - -## allow players to initate a mode-change start -ALLOW_VOTE_MODE - -## min delay (deciseconds) between voting sessions (default 10 minutes) -VOTE_DELAY 6000 - -## time period (deciseconds) which voting session will last (default 1 minute) -VOTE_PERIOD 600 - -## autovote initial delay (deciseconds) before first automatic transfer vote call (default 180 minutes) -VOTE_AUTOTRANSFER_INITIAL 108000 - -##autovote delay (deciseconds) before sequential automatic transfer votes are called (default 30 minutes) -VOTE_AUTOTRANSFER_INTERVAL 18000 - -## Time left (seconds) before round start when automatic gamemote vote is called (default 160). -VOTE_AUTOGAMEMODE_TIMELEFT 160 - -## prevents dead players from voting or starting votes -#NO_DEAD_VOTE - -## Prevents players not in-round from voting on crew transfer votes. -#NO_DEAD_VOTE_CREW_TRANSFER - -## players' votes default to "No vote" (otherwise, default to "No change") -DEFAULT_NO_VOTE - -## Allow ghosts to see antagonist through AntagHUD -ALLOW_ANTAG_HUD - -## If ghosts use antagHUD they are no longer allowed to join the round. -ANTAG_HUD_RESTRICTED - -## allow AI job -ALLOW_AI - -## disable abandon mob -# NORESPAWN - -## disables calling del(src) on newmobs if they logout before spawnin in -# DONT_DEL_NEWMOB - -## set a hosted by name for unix platforms -HOSTEDBY yournamehere - -## Set to jobban "Guest-" accounts from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions. -## Set to 1 to jobban them from those positions, set to 0 to allow them. -GUEST_JOBBAN - -## Uncomment this to stop people connecting to your server without a registered ckey. (i.e. guest-* are all blocked from connecting) -GUEST_BAN -## Set to jobban everyone who's key is not listed in data/whitelist.txt from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions. -## Uncomment to 1 to jobban, leave commented out to allow these positions for everyone (but see GUEST_JOBBAN above and regular jobbans) -# USEWHITELIST - -## set a server location for world reboot. Don't include the byond://, just give the address and port. -#SERVER server.net:port - -## set a server URL for the IRC bot to use; like SERVER, don't include the byond:// -## Unlike SERVER, this one shouldn't break auto-reconnect -#SERVERURL server.net:port - -## forum address -# FORUMURL http://example.com - -## discord server permanent invite address -# DISCORDURL https://discord.gg/example - -## Wiki address -# WIKIURL http://example.com - -## GitHub address -# GITHUBURL https://github.com/example-user/example-repository - -## GitHub new issue address -# ISSUEREPORTURL https://github.com/example-user/example-repository/issues/new - -## Ban appeals URL - usually for a forum or wherever people should go to contact your admins. -# BANAPPEALS http://example.com - -## In-game features -## spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard -# FEATURE_OBJECT_SPELL_SYSTEM - -##Toggle for having jobs load up from the .txt -# LOAD_JOBS_FROM_TXT - -##Remove the # mark infront of this to forbid admins from posssessing the singularity. -#FORBID_SINGULO_POSSESSION - -## Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM. -## The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off) -#POPUP_ADMIN_PM - -## Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR -ALLOW_HOLIDAYS - -##Defines the ticklag for the world. 0.9 is the normal one, 0.5 is smoother. -TICKLAG 0.7 - -##Defines world FPS. Defaults to 20. -# FPS 20 - -## Whether the server will talk to other processes through socket_talk -SOCKET_TALK 0 - -## Comment this out to disable automuting -#AUTOMUTE_ON - -## How long the delay is before the Away Mission gate opens. Default is half an hour. -GATEWAY_DELAY 18000 - -## Remove the # to give assistants maint access. -#ASSISTANT_MAINT - -## Remove the # to make rounds which end instantly (Rev, Wizard, Malf) to continue until the shuttle is called or the station is nuked. -## Malf and Rev will let the shuttle be called when the antags/protags are dead. -#CONTINUOUS_ROUNDS - -## Uncomment to restrict non-admins from using humanoid alien races -USEALIENWHITELIST -## Uncomment to use the alien whitelist system with SQL instead. (requires the above uncommented aswell) -#USEALIENWHITELIST_SQL - -## Comment this to unrestrict the number of alien players allowed in the round. The number represents the number of alien players for every human player. -#ALIEN_PLAYER_RATIO 0.2 -##Remove the # to let ghosts spin chairs -#GHOST_INTERACTION - -## Password used for authorizing ircbot and other external tools. -#COMMS_PASSWORD - -## Password used for authorizing external tools that can apply bans -#BAN_COMMS_PASSWORD - -## BYOND builds that will result the client using them to be banned. -#FORBIDDEN_VERSIONS 512.0001;512.0002 - -## Export address where external tools that monitor logins are located -#LOGIN_EXPORT_ADDR - -## Uncomment to enable sending data to the IRC bot. -#USE_IRC_BOT - -## Host where the IRC bot is hosted. Port 45678 needs to be open. -#IRC_BOT_HOST localhost - -## IRC channel to send information to. Leave blank to disable. -#MAIN_IRC #main - -## IRC channel to send adminhelps to. Leave blank to disable adminhelps-to-irc. -#ADMIN_IRC #admin - -## Uncommen to allow ghosts to write in blood during Cult rounds. -ALLOW_CULT_GHOSTWRITER - -## Sets the minimum number of cultists needed for ghosts to write in blood. -REQ_CULT_GHOSTWRITER 6 - -## Sets the number of available character slots -CHARACTER_SLOTS 10 - -## Sets the number of loadout slots per character -LOADOUT_SLOTS 3 - -## Expected round length in minutes -EXPECTED_ROUND_LENGTH 180 - -## The lower delay between events in minutes. -## Affect mundane, moderate, and major events respectively -EVENT_DELAY_LOWER 10;30;50 - -## The upper delay between events in minutes. -## Affect mundane, moderate, and major events respectively -EVENT_DELAY_UPPER 15;45;70 - -## The delay until the first time an event of the given severity runs in minutes. -## Unset setting use the EVENT_DELAY_LOWER and EVENT_DELAY_UPPER values instead. -# EVENT_CUSTOM_START_MINOR 10;15 -# EVENT_CUSTOM_START_MODERATE 30;45 -EVENT_CUSTOM_START_MAJOR 80;100 - -## Uncomment to make proccall require R_ADMIN instead of R_DEBUG -## designed for environments where you have testers but don't want them -## able to use the more powerful debug options. -#DEBUG_PARANOID - -## Uncomment to allow aliens to spawn. -#ALIENS_ALLOWED - -## Uncomment to allow alien xenomorph queens to lay eggs. -#ALIEN_EGGS_ALLOWED - -## Uncomment to allow xenos to spawn. -#NINJAS_ALLOWED - -## Uncomment to disable the restrictive weldervision overlay. -#DISABLE_WELDER_VISION - -## Uncomment to prevent anyone from joining the round by default. -#DISABLE_ENTRY - -## Uncomment to disable the OOC channel by default. -#DISABLE_OOC - -## Uncomment to disable the LOOC channel by default. -#DISABLE_LOOC - -## Uncomment to disable the dead OOC channel by default. -#DISABLE_DEAD_OOC - -## Uncomment to disable the AOOC channel by default. -#DISABLE_AOOC - -## Uncomment to disable ghost chat by default. -#DISABLE_DSAY - -## Uncomment to disable respawning by default. -#DISABLE_RESPAWN - -## Respawn delay in minutes before one may respawn as a crew member. -#RESPAWN_DELAY 30 - -## Percentile strength of exterior ambient light (such as starlight). 0.5 is 50% lit. -EXTERIOR_AMBIENT_LIGHT 0 - - -## Defines how Law Zero is phrased. Primarily used in the Malfunction gamemode. -# LAW_ZERO ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010 - - -## Enable/Disable random level generation. Will behave strangely if turned off with a map that expects it on. -#ROUNDSTART_LEVEL_GENERATION 1 - -## Uncomment to enable organ decay outside of a body or storage item. -#ORGANS_CAN_DECAY - -## Uncomment to have the changelog file automatically open when a user connects and hasn't seen the latest changelog -#AGGRESSIVE_CHANGELOG - -## Uncomment to make Discord webhooks send in plaintext rather than as embeds. -# DISABLE_WEBHOOK_EMBEDS - -## Uncomment to override default brain health. -#DEFAULT_BRAIN_HEALTH 400 - -## Uncomment this line to announce shuttle dock announcements to the main IRC channel, if MAIN_IRC has also been setup. -# ANNOUNCE_SHUTTLE_DOCK_TO_IRC - -## Uncomment to enable map voting; you'll need to use the script at tools/server.sh or an equivalent for it to take effect -## You'll also likely need to enable WAIT_FOR_SIGUSR1 below -# MAP_SWITCHING - -## Uncomment to enable an automatic map vote and switch at end of round. MAP_SWITCHING must also be enabled. -# AUTO_MAP_VOTE - -## Uncomment to make Dream Daemon refuse to reboot for any reason other than SIGUSR1 -# WAIT_FOR_SIGUSR1 - -## Uncomment to enable auto-stealthing staff who are AFK for more than specified minutes -# AUTOSTEALTH 30 - -## Set to 0/1 to disable/enable automatic admin rights for users connecting from the host the server is running on. -AUTO_LOCAL_ADMIN 0 - -## How many loadout points are available. Use 0 to disable loadout, and any negative number to indicate infinite points. -MAX_GEAR_COST 10 - -## How much radiation levels self-reduce by each tick. -RADIATION_DECAY_RATE 1 - -## The amount of radiation resistance on a turf is multiplied by this value -RADIATION_RESISTANCE_MULTIPLIER 1.25 - -## General material radiation resistance is divided by this value -RADIATION_MATERIAL_RESISTANCE_DIVISOR 2 - -## Below this point, radiation is ignored -RADIATION_LOWER_LIMIT 0.15 - -## Uncomment this to prevent players from printing copy/pasted circuits -#DISABLE_CIRCUIT_PRINTING - -## Uncomment this to allow admins to narrate using HTML tags -#ALLOW_UNSAFE_NARRATES - -## Uncomment this to DISABLE action spam kicking. Not recommended; this helps protect from spam attacks. -#DO_NOT_PREVENT_SPAM - -## Uncomment this to modify the length of the spam kicking interval in seconds. -#ACT_INTERVAL 0.1 - -## Uncomment this to modify the number of actions permitted per interval before being kicked for spam. -#MAX_ACTS_PER_INTERVAL 140 - -## Is the panic bunker currently on by default. -#PANIC_BUNKER - -## A message when user did not pass the panic bunker. -#PANIC_BUNKER_MESSAGE Sorry! The panic bunker is enabled. Please head to our Discord or forum to get yourself added to the panic bunker bypass. - -##Clients will be unable to connect unless their version is equal to or higher than this (a number, e.g. 511) -#MINIMUM_BYOND_VERSION - -## Clients will be unable to connect unless their build is equal to or higher than this (a number, e.g. 1000) -#MINIMUM_BYOND_BUILD - -## Direct clients to preload the server resource file from a URL pointing to a .rsc file. NOTE: At this time (byond 512), -## the client/resource_rsc var does not function as one would expect. See client_defines.dm, the "preload_rsc" var's -## comments on how to use it properly. If you use a resource URL, you must set preload_rsc to 0 at compile time or -## clients will still download from the server *too*. This will randomly select one URL if more than one is provided. -## Spaces are prohibited in each URL by spec, you must use encoded spaces. -#RESOURCE_URLS URL URL2 URL3 - -## Whether or not to make localhost immune to throttling. -## Localhost will still be throttled internally; it just won't be affected by it. -#NO_THROTTLE_LOCALHOST - -## Uncomment this to enable expanded alt interactions with objects. -#EXPANDED_ALT_INTERACTIONS - -## Uncomment this to show a typing indicator for people writing whispers. -#SHOW_TYPING_INDICATOR_FOR_WHISPERS - -## Set this to 0 to hide visible examine messages. -VISIBLE_EXAMINE 1 - -## Uncomment this to allow loadout name/desc customization by default. -#ALLOW_LOADOUT_CUSTOMIZATION diff --git a/config/example/configuration.txt b/config/example/configuration.txt new file mode 100644 index 00000000000..2bba71ef03f --- /dev/null +++ b/config/example/configuration.txt @@ -0,0 +1,630 @@ +## +# ADMIN +# Configuration options relating to administration. +## + +## Allows admin jumping. +#ALLOW_ADMIN_JUMP 1 + +## Comment this out to stop admins being able to choose their personal OOC color. Uncomment to enable. +#ALLOW_ADMIN_OOCCOLOR + +## Allows admin revives. +#ALLOW_ADMIN_REV 1 + +## Allows admin item spawning. +#ALLOW_ADMIN_SPAWNING 1 + +## Uncomment this to allow admins to narrate using HTML tags. Uncomment to enable. +#ALLOW_UNSAFE_NARRATES + +## Uncomment to enable auto-stealthing staff who are AFK for more than specified minutes. +#AUTOSTEALTH 0 + +## Set to 0/1 to disable/enable automatic admin rights for users connecting from the host the server is running on. +#AUTO_LOCAL_ADMIN 1 + +## Set to jobban 'Guest-' accounts from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions. +## Set to 1 to jobban them from those positions, set to 0 to allow them. +#GUEST_JOBBAN 1 + +## Chooses whether mods have the ability to issue tempbans for jobs or not. Uncomment to enable. +#MODS_CAN_JOB_TEMPBAN + +## Chooses whether mods have the ability to tempban or not. Uncomment to enable. +#MODS_CAN_TEMPBAN + +## Maximum mod job tempban duration (in minutes). +#MOD_JOB_TEMPBAN_MAX 1440 + +## Maximum mod tempban duration (in minutes). +#MOD_TEMPBAN_MAX 1440 + +## +# DEBUG +# Configuration options relating to error reporting. +## + +## Uncomment to make proccall require R_ADMIN instead of R_DEBUG +## designed for environments where you have testers but don't want them +## able to use the more powerful debug options. +## Uncomment to enable. +#DEBUG_PARANOID + +## The "cooldown" time for each occurrence of a unique error. +#ERROR_COOLDOWN 600 + +## How many occurrences before the next will silence them. +#ERROR_LIMIT 50 + +## How long to wait between messaging admins about occurrences of a unique error. +#ERROR_MSG_DELAY 50 + +## How long a unique error will be silenced for. +#ERROR_SILENCE_TIME 6000 + +## +# EVENTS +# Configuration options relating to event timers and probabilities. +## + +## Hash out to disable random events during the round. Uncomment to enable. +#ALLOW_RANDOM_EVENTS + +## The lower delay between events in minutes. +## Affect mundane, moderate, and major events respectively. +#EVENT_DELAY_LOWER [10,30,50] + +## The upper delay between events in minutes. +## Affect mundane, moderate, and major events respectively. +#EVENT_DELAY_UPPER [15,45,70] + +## If the first delay has a custom start time. Defined in minutes. +#EVENT_FIRST_RUN [null,null,{"lower":80,"upper":100}] + +## Determines if objectives are disabled. +#OBJECTIVES_DISABLED 2 + +## +# GAME OPTIONS +# Configuration options relating to gameplay, such as movement, health and stamina. +## + +## Uncomment this to modify the length of the spam kicking interval in seconds. +#ACT_INTERVAL 0.1 + +## Remove the # to let aliens spawn. Uncomment to enable. +#ALIENS_ALLOWED + +## Remove the # to allow people to leave public comments on each other's characters via the comments system. Uncomment to enable. +#ALLOW_CHARACTER_COMMENTS + +## Allow multiple input keys to be pressed for diagonal movement. Uncomment to enable. +#ALLOW_DIAGONAL_MOVEMENT + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#ANIMAL_DELAY 0 + +## Remove the # to give assistants maint access. Uncomment to enable. +#ASSISTANT_MAINT + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#CREEP_DELAY 6 + +## The effectiveness of default darksight if above is uncommented. +#DEFAULT_DARKSIGHT_EFFECTIVENESS 0.05 + +## The range of default darksight if above is uncommented. +#DEFAULT_DARKSIGHT_RANGE 2 + +## Threshold of where brain damage begins to affect dexterity (70 brainloss above this means zero dexterity). Default is 30. +#DEX_MALUS_BRAINLOSS_THRESHOLD 30 + +## Restricted ERT to be only called by admins. Uncomment to enable. +#ERT_ADMIN_CALL_ONLY + +## Uncomment this to enable expanded alt interactions with objects. Uncomment to enable. +#EXPANDED_ALT_INTERACTIONS + +## Expected round length in hours. +#EXPECTED_ROUND_LENGTH 3 + +## Uncomment to allow ghosts to possess any animal. Uncomment to enable. +#GHOSTS_CAN_POSSESS_ANIMALS + +## Remove the # to let ghosts spin chairs. Uncomment to enable. +#GHOST_INTERACTION + +## Set this to 0 for perfectly smooth movement gliding, or 1 or more for delayed chess move style movements. +#GLIDE_SIZE_DELAY 1 + +## Whether or not all human mobs have very basic darksight by default. Uncomment to enable. +#GRANT_DEFAULT_DARKSIGHT + +## Specify a number of days after which to hide comments on public profiles (to avoid bloat from retired characters). +#HIDE_COMMENTS_OLDER_THAN 0 + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#HUMAN_DELAY 0 + +## Maximum stamina recovered per tick when resting. +#MAXIMUM_STAMINA_RECOVERY 3 + +## Uncomment this to modify the number of actions permitted per interval before being kicked for spam. +#MAX_ACTS_PER_INTERVAL 140 + +## How many loadout points are available. Use 0 to disable loadout, and any negative number to indicate infinite points. +#MAX_GEAR_COST 10 + +## Value used for expending stamina during sprinting. +#MINIMUM_SPRINT_COST 0.8 + +## Minimum stamina recovered per tick when resting. +#MINIMUM_STAMINA_RECOVERY 1 + +## Remove the # to let ninjas spawn. Uncomment to enable. +#NINJAS_ALLOWED + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#ROBOT_DELAY 0 + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#RUN_DELAY 2 + +## Determines the severity of athletics skill when applied to stamina cost. +#SKILL_SPRINT_COST_RANGE 0.8 + +## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. +#WALK_DELAY 4 + +## +# GAME WORLD +# Configuration options relating to the game world and simulation. +## + +## Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR Uncomment to enable. +#ALLOW_HOLIDAYS + +## Uncomment this to prevent players from printing copy/pasted circuits. +#ALLOW_IC_PRINTING 1 + +## Uncomment to allow ghosts to write in blood during Cult rounds. +#CULT_GHOSTWRITER 1 + +## The maximum duration of an exoplanet day, in minutes. +#EXOPLANET_MAX_DAY_DURATION 40 + +## The minimum duration of an exoplanet day, in minutes. +#EXOPLANET_MIN_DAY_DURATION 10 + +## Percentile strength of exterior ambient light (such as starlight). 0.5 is 50% lit. +#EXTERIOR_AMBIENT_LIGHT 0 + +## How long the delay is before the Away Mission gate opens. Default is half an hour. +#GATEWAY_DELAY 18000 + +## Humans are forced to have surnames if this is uncommented. Uncomment to enable. +#HUMANS_NEED_SURNAMES + +## What to multiply power by when crossing Z-levels. +#ITERATIVE_EXPLOSIVES_Z_MULTIPLIER 0.75 + +## The power of explosion required for it to cross Z-levels. +#ITERATIVE_EXPLOSIVES_Z_THRESHOLD 10 + +## Defines how Law Zero is phrased. Primarily used in the Malfunction gamemode. +#LAW_ZERO ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010 + +## After this amount alive, walking mushrooms spawned from botany will not reproduce. +#MAXIMUM_MUSHROOMS 15 + +## How much radiation levels self-reduce by each tick. +#RADIATION_DECAY_RATE 1 + +## Below this point, radiation is ignored. +## Radiation weakens with distance from the source; stop calculating when the strength falls below this value. Lower values mean radiation reaches smaller (with increasingly trivial damage) at the cost of more CPU usage. +## Max range = DISTANCE^2 * POWER / RADIATION_LOWER_LIMIT +#RADIATION_LOWER_LIMIT 0.15 + +## General material radiation resistance is divided by this value. +#RADIATION_MATERIAL_RESISTANCE_DIVISOR 2 + +## The amount of radiation resistance on a turf is multiplied by this value. +#RADIATION_RESISTANCE_MULTIPLIER 1.25 + +## Enable/Disable random level generation. Will behave strangely if turned off with a map that expects it on. Uncomment to enable. +#ROUNDSTART_LEVEL_GENERATION + +## Unhash this to use iterative explosions, keep it hashed to use circle explosions. Uncomment to enable. +#USE_ITERATIVE_EXPLOSIONS + +## Uncomment to disable the restrictive weldervision overlay. +#WELDER_VISION 1 + +## +# HEALTH +# Configuration options relating to the health simulation. +## + +## Determines whether bones can be broken through excessive damage to the organ. +## 0 means bones can't break, 1 means they can. +#BONES_CAN_BREAK 1 + +## Level of health at which a mob becomes dead. +#HEALTH_THRESHOLD_DEAD -100 + +## Determines whether limbs can be amputated through excessive damage to the organ. +## 0 means limbs can't be amputated, 1 means they can. +#LIMBS_CAN_BREAK 1 + +## Percentage multiplier that influences how damage spreads around organs. 100 means normal, 50 means half. +#ORGAN_DAMAGE_SPILLOVER_MULTIPLIER 0.5 + +## Percentage multiplier which enables organs to take more damage before bones breaking or limbs being destroyed. +#ORGAN_HEALTH_MULTIPLIER 0.9 + +## Percentage multiplier which influences how fast organs regenerate naturally. +#ORGAN_REGENERATION_MULTIPLIER 0.25 + +## Amount of time (in hundredths of seconds) for which a brain retains the 'spark of life' after the person's death (set to -1 for infinite). +#REVIVAL_BRAIN_LIFE -1 + +## A multiplier for the impact stress has on blood regeneration, as above. +#STRESS_BLOOD_RECOVERY_CONSTANT 0.3 + +## A multiplier for the impact stress has on wound passive healing, as above. +#STRESS_HEALING_RECOVERY_CONSTANT 0.3 + +## A multiplier for the impact stress has on shock recovery - 0.3 means maximum stress imposes a 30% penalty on shock recovery. +#STRESS_SHOCK_RECOVERY_CONSTANT 0.5 + +## +# LOGGING +# Configuration options relating to logging. +## + +## log client access (logon/logoff) Uncomment to enable. +#LOG_ACCESS + +## log admin actions Uncomment to enable. +#LOG_ADMIN + +## log admin chat Uncomment to enable. +#LOG_ADMINCHAT + +## Log admin warning messages. Also duplicates a bunch of other messages. Uncomment to enable. +#LOG_ADMINWARN + +## log attack messages Uncomment to enable. +#LOG_ATTACK + +## log debug output Uncomment to enable. +#LOG_DEBUG + +## log emotes Uncomment to enable. +#LOG_EMOTE + +## log game actions (start of round, results, etc.) Uncomment to enable. +#LOG_GAME + +## Log all Topic() calls (for use by coders in tracking down Topic issues). Uncomment to enable. +#LOG_HREFS + +## log OOC channel Uncomment to enable. +#LOG_OOC + +## Log PDA messages. Uncomment to enable. +#LOG_PDA + +## Log world.log and runtime errors to a file. Uncomment to enable. +#LOG_RUNTIME + +## log client Say Uncomment to enable. +#LOG_SAY + +## log player votes Uncomment to enable. +#LOG_VOTE + +## log client Whisper Uncomment to enable. +#LOG_WHISPER + +## Log world.log messages. Uncomment to enable. +#LOG_WORLD_OUTPUT + +## +# MODES +# Configuration options relating to game modes. +## + +## If uncommented, votes can be called to add extra antags to the round. Uncomment to enable. +#ALLOW_EXTRA_ANTAGS + +## Remove the # to make rounds which end instantly (Rev, Wizard, Malf) to continue until the shuttle is called or the station is nuked. +## Malf and Rev will let the shuttle be called when the antags/protags are dead. +## Uncomment to enable. +#CONTINUOUS_ROUNDS + +## Spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard. Uncomment to enable. +#FEATURE_OBJECT_SPELL_SYSTEM + +## Allowed modes. +#MODES ["crossfire","cult","extended","god","heist","mercenary","ninja","revolution","siege","spyvspy","traitor","uprising","wizard"] + +## Mode names. +#MODE_NAMES {"calamity":"Calamity","cult":"Cult","extended":"Extended","god":"Deity","heist":"Heist","meteor":"Meteor","crossfire":"Mercenary & heist","siege":"Mercenary & revolution","spyvspy":"Spy v. spy","uprising":"Cult & revolution","ninja":"Ninja","mercenary":"Mercenary","revolution":"Revolution","traitor":"Traitor","wizard":"Wizard"} + +## Relative probability of each mode. +#PROBABILITIES {"calamity":0,"cult":1,"extended":1,"god":0,"heist":0,"meteor":0,"crossfire":0,"siege":0,"spyvspy":0,"uprising":0,"ninja":0,"mercenary":1,"revolution":0,"traitor":0,"wizard":1} + +## If security is prohibited from being most antagonists. Uncomment to enable. +#PROTECT_ROLES_FROM_ANTAGONIST + +## If amount of traitors scales or not. Uncomment to enable. +#TRAITOR_SCALING + +## A list of modes that should be votable. +#VOTABLE_MODES ["crossfire","cult","extended","god","heist","mercenary","meteor","ninja","revolution","secret","siege","spyvspy","traitor","uprising","wizard"] + +## +# PROTECTED +# Configuration options protected from manipulation on-server. +## + +## Password used for authorizing external tools that can apply bans. +#BAN_COMMS_PASSWORD + +## Password used for authorizing ircbot and other external tools. +#COMMS_PASSWORD + +## Export address where external tools that monitor logins are located. +#LOGIN_EXPORT_ADDR + +## +# RESOURCES +# Configuration options relating to server resources. +## + +## Uncomment this and set it to a file path relative to the executing binary to prefix all custom icon locations with this location ie. '[CUSTOM_ICON_ICON_LOCATION]/[custom icon path value]' +#CUSTOM_ICON_ICON_LOCATION config/custom_icons/icons + +## Set this to a file path relative to the executing binary to prefix all custom item icon locations with this location ie. '[CUSTOM_ITEM_ICON_LOCATION]/[custom item icon path value]' +#CUSTOM_ITEM_ICON_LOCATION config/custom_items/icons + +## Direct clients to preload the server resource file from a URL pointing to a .rsc file. NOTE: At this time (byond 512), +## the client/resource_rsc var does not function as one would expect. See client_defines.dm, the 'preload_rsc' var's +## comments on how to use it properly. If you use a resource URL, you must set preload_rsc to 0 at compile time or +## clients will still download from the server *too*. This will randomly select one URL if more than one is provided. +## Spaces are prohibited in each URL by spec, you must use encoded spaces. +## ex. RESOURCE_URLS URL URL2 URL3 +#RESOURCE_URLS [] + +## +# SERVER +# Configuration options relating to the server itself. +## + +## Comment to disable respawning by default. +#ABANDON_ALLOWED 1 + +## IRC channel to send adminhelps to. Leave blank to disable adminhelps-to-irc. +#ADMIN_IRC + +## Add a # infront of this if you want to use the SQL based admin system, the legacy system uses admins.txt. You need to set up your database to use the SQL based system. +#ADMIN_LEGACY_SYSTEM 1 + +## Allow AI job. +#ALLOW_AI 1 + +## Allow ghosts to join as maintenance drones. +#ALLOW_DRONE_SPAWN 1 + +## Uncomment this line to announce shuttle dock announcements to the main IRC channel, if MAIN_IRC has also been setup. Uncomment to enable. +#ANNOUNCE_SHUTTLE_DOCK_TO_IRC + +## Comment to disable the AOOC channel by default. +#AOOC_ALLOWED 1 + +## Ban appeals URL - usually for a forum or wherever people should go to contact your admins. +#BANAPPEALS + +## Add a # infront of this if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system. +#BAN_LEGACY_SYSTEM 1 + +## Sets the number of available character slots. +#CHARACTER_SLOTS 10 + +## Sets the minimum number of cultists needed for ghosts to write in blood. +#CULT_GHOSTWRITER_REQ_CULTISTS 10 + +## Uncomment this to remove the server from the hub. Uncomment to enable. +#DELIST_WHEN_NO_ADMINS + +## Uncomment to enable. +#DISABLE_PLAYER_MICE + +## Uncomment to make Discord webhooks send in plaintext rather than as embeds. Uncomment to enable. +#DISABLE_WEBHOOK_EMBEDS + +## Discord server permanent invite address. +#DISCORDURL + +## Comment to disable the dead OOC channel by default. +#DOOC_ALLOWED 1 + +## Uncomment this to DISABLE action spam kicking. Not recommended; this helps protect from spam attacks. Uncomment to enable. +#DO_NOT_PREVENT_SPAM + +## A drone will become available every X ticks since last drone spawn. Default is 2 minutes. +#DRONE_BUILD_TIME 1200 + +## Comment to disable ghost chat by default. +#DSAY_ALLOWED 1 + +## Comment to prevent anyone from joining the round by default. +#ENTER_ALLOWED 1 + +## Remove the # mark infront of this to forbid admins from posssessing the singularity. Uncomment to enable. +#FORBID_SINGULO_POSSESSION + +## Discussion forum address. +#FORUMURL + +## Defines world FPS. Defaults to 20. +## Can also accept ticklag values (0.9, 0.5, etc) which will automatically be converted to FPS. +#FPS 20 + +## GitHub address. +#GITHUBURL + +## Uncomment this to stop people connecting to your server without a registered ckey. (i.e. guest-* are all blocked from connecting). Uncomment to enable. +#GUESTS_ALLOWED + +## Set a hosted by name for UNIX platforms. +#HOSTEDBY + +## Hub visibility: If you want to be visible on the hub, uncomment the below line and be sure that Dream Daemon is set to visible. This can be changed in-round as well with toggle-hub-visibility if Dream Daemon is set correctly. Uncomment to enable. +#HUB_VISIBILITY + +## Host where the IRC bot is hosted. Port 45678 needs to be open. +#IRC_BOT_HOST localhost + +## GitHub new issue address. +#ISSUEREPORTURL + +## Add a # here if you wish to use the setup where jobs have more access. This is intended for servers with low populations - where there are not enough players to fill all roles, so players need to do more than just one job. Also for servers where they don't want people to hide in their own departments. +#JOBS_HAVE_MINIMAL_ACCESS 1 + +## Disconnect players who did nothing during the set amount of minutes. +#KICK_INACTIVE 0 + +## Sets the number of loadout slots per character. +#LOADOUT_SLOTS 3 + +## Toggle for having jobs load up from the .txt Uncomment to enable. +#LOAD_JOBS_FROM_TXT + +## Comment to disable the LOOC channel by default. +#LOOC_ALLOWED 1 + +## IRC channel to send information to. Leave blank to disable. +#MAIN_IRC #main + +## Remove the # to define a different cap for aspect points in chargen. +#MAX_CHARACTER_ASPECTS 5 + +## This many drones can be active at the same time. +#MAX_MAINT_DRONES 5 + +## Clients will be unable to connect unless their build is equal to or higher than this (a number, e.g. 1000). +#MINIMUM_BYOND_BUILD 0 + +## Clients will be unable to connect unless their version is equal to or higher than this (a number, e.g. 511). +#MINIMUM_BYOND_VERSION 0 + +## Uncomment to enable. +#NO_CLICK_COOLDOWN + +## Whether or not to make localhost immune to throttling. +## Localhost will still be throttled internally; it just won't be affected by it. +## Uncomment to enable. +#NO_THROTTLE_LOCALHOST + +## Comment to disable the OOC channel by default. +#OOC_ALLOWED 1 + +## Is the panic bunker currently on by default? Uncomment to enable. +#PANIC_BUNKER + +## A message when user did not pass the panic bunker. +#PANIC_BUNKER_MESSAGE Sorry! The panic bunker is enabled. Please head to our Discord or forum to get yourself added to the panic bunker bypass. + +## The maximum number of non-admin players online. +#PLAYER_LIMIT 0 + +## Respawn delay in minutes before one may respawn as a crew member. +#RESPAWN_DELAY 30 + +## Set a server location for world reboot. Don't include the byond://, just give the address and port. +#SERVER + +## Set a server URL for the IRC bot to use; like SERVER, don't include the byond:// +## Unlike SERVER, this one shouldn't break auto-reconnect. +#SERVERURL + +## Server name: This appears at the top of the screen in-game. +#SERVER_NAME Nebula 13 + +## Uncomment this to show a typing indicator for people writing whispers. Uncomment to enable. +#SHOW_TYPING_INDICATOR_FOR_WHISPERS + +## SSinitialization throttling. +#TICK_LIMIT_MC_INIT 98 + +## Set to 1 to prevent newly-spawned mice from understanding human speech. Uncomment to enable. +#UNEDUCATED_MICE + +## Uncomment to restrict non-admins from using humanoid alien races. Uncomment to enable. +#USEALIENWHITELIST + +## Uncomment to use the alien whitelist system with SQL instead. (requires the above uncommented as well). Uncomment to enable. +#USEALIENWHITELIST_SQL + +## Set to jobban everyone who's key is not listed in data/whitelist.txt from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions. +## Uncomment to 1 to jobban, leave commented out to allow these positions for everyone (but see GUEST_JOBBAN above and regular jobbans). +## Uncomment to enable. +#USEWHITELIST + +## Uncomment to enable sending data to the IRC bot. Uncomment to enable. +#USE_IRC_BOT + +## Remove the # in front of this config option to have loyalty implants spawn by default on your server. Uncomment to enable. +#USE_LOYALTY_IMPLANTS + +## Uncomment to make Dream Daemon refuse to reboot for any reason other than SIGUSR1. Uncomment to enable. +#WAIT_FOR_SIGUSR1_REBOOT + +## Wiki address. +#WIKIURL + +## +# VOTING +# Configuration options relating to votes at runtime. +## + +## Uncomment to enable map voting; you'll need to use the script at tools/server.sh or an equivalent for it to take effect. +## You'll also likely need to enable WAIT_FOR_SIGUSR1 below. +## Uncomment to enable. +#ALLOW_MAP_SWITCHING + +## Allow players to initate a mode-change start. Uncomment to enable. +#ALLOW_VOTE_MODE + +## Allow players to initiate a restart vote. Uncomment to enable. +#ALLOW_VOTE_RESTART + +## Uncomment to enable an automatic map vote and switch at end of round. MAP_SWITCHING must also be enabled. Uncomment to enable. +#AUTO_MAP_VOTE + +## Time left (seconds) before round start when automatic gamemote vote is called (default 160). +#VOTE_AUTOGAMEMODE_TIMELEFT 100 + +## Autovote initial delay (deciseconds) before first automatic transfer vote call (default 180 minutes). +#VOTE_AUTOTRANSFER_INITIAL 108000 + +## Autovote delay (deciseconds) before sequential automatic transfer votes are called (default 30 minutes). +#VOTE_AUTOTRANSFER_INTERVAL 18000 + +## Min delay (deciseconds) between voting sessions (default 10 minutes). +#VOTE_DELAY 6000 + +## Prevents dead players from voting or starting votes. +#VOTE_NO_DEAD 0 + +## Prevents players not in-round from voting on crew transfer votes. +#VOTE_NO_DEAD_CREW_TRANSFER 0 + +## Players' votes default to 'No vote' (otherwise, default to 'No change'). +#VOTE_NO_DEFAULT 0 + +## Time period (deciseconds) which voting session will last (default 1 minute). +#VOTE_PERIOD 600 diff --git a/config/example/game_options.txt b/config/example/game_options.txt deleted file mode 100644 index cce0a2ad04d..00000000000 --- a/config/example/game_options.txt +++ /dev/null @@ -1,109 +0,0 @@ -### HEALTH ### - -## level of health at which a mob goes into continual shock (soft crit) -HEALTH_THRESHOLD_SOFTCRIT 0 - -## level of health at which a mob becomes unconscious (crit) -HEALTH_THRESHOLD_CRIT -50 - -## level of health at which a mob becomes dead -HEALTH_THRESHOLD_DEAD -100 - -## Uncomment this line to enable humans showing a visible message upon death ('X seizes up then falls limp, eyes dead and lifeless'). -# SHOW_HUMAN_DEATH_MESSAGE - -## Determines whether bones can be broken through excessive damage to the organ -## 0 means bones can't break, 1 means they can -BONES_CAN_BREAK 1 -## Determines whether limbs can be amputated through excessive damage to the organ -## 0 means limbs can't be amputated, 1 means they can -LIMBS_CAN_BREAK 1 - -## multiplier which enables organs to take more damage before bones breaking or limbs being destroyed -## 100 means normal, 50 means half -ORGAN_HEALTH_MULTIPLIER 90 - -## multiplier which influences how fast organs regenerate naturally -## 100 means normal, 50 means half -ORGAN_REGENERATION_MULTIPLIER 25 - -### REVIVAL ### - -## whether pod plants work or not -REVIVAL_POD_PLANTS 1 - -## whether cloning tubes work or not -REVIVAL_CLONING 1 - -## amount of time (in hundredths of seconds) for which a brain retains the "spark of life" after the person's death (set to -1 for infinite) -REVIVAL_BRAIN_LIFE -1 - - - -### MOB MOVEMENT ### - -## We suggest editing these variabled in-game to find a good speed for your server. To do this you must be a high level admin. Open the 'debug' tab ingame. Select "Debug Controller" and then, in the popup, select "Configuration". These variables should have the same name. - -## These values get directly added to values and totals in-game. To speed things up make the number negative, to slow things down, make the number positive. - - -## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. -RUN_DELAY 2 -WALK_DELAY 4 -CREEP_DELAY 6 - -## Set this to 0 for perfectly smooth movement gliding, or 1 or more for delayed chess move style movements. -#GLIDE_SIZE_DELAY 0 - -MINIMUM_SPRINT_COST 0.8 -SKILL_SPRINT_COST_RANGE 0.8 -MINIMUM_STAMINA_RECOVERY 5 -MAXIMUM_STAMINA_RECOVERY 5 - -## The variables below affect the movement of specific mob types. -HUMAN_DELAY 0 -ROBOT_DELAY 0 -MONKEY_DELAY 0 -ALIEN_DELAY 0 -ANIMAL_DELAY 0 - - -### Miscellaneous ### - -## Config options which, of course, don't fit into previous categories. - -## Remove the # in front of this config option to have loyalty implants spawn by default on your server. -#USE_LOYALTY_IMPLANTS - -## Uncomment to lock the automatic client view scaling on the X or Y boundary. -#LOCK_CLIENT_VIEW_X 15 -#LOCK_CLIENT_VIEW_Y 15 - -## Change to set a maximum size for the client view scaling. -MAX_CLIENT_VIEW_X 30 -MAX_CLIENT_VIEW_Y 30 - -## Remove the # to define a different cap for aspect points in chargen. -#MAX_CHARACTER_ASPECTS 5 - -## Allow multiple input keys to be pressed for diagonal movement. -#ALLOW_DIAGONAL_MOVEMENT - -## Threshold of where brain damage begins to affect dexterity (70 brainloss above this means zero dexterity). Default is 30. -#DEXTERITY_MALUS_BRAINLOSS_THRESHOLD 30 - -## Whether or not all human mobs have very basic darksight by default. -#GRANT_DEFAULT_DARKSIGHT - -## The range and effectiveness of default darksight if above is uncommented. -#DEFAULT_DARKSIGHT_EFFECTIVENESS 0.05 -#DEFAULT_DARKSIGHT_RANGE 2 - -## Uncomment to allow stressors to impact shock, healing and blood recovery. -#ADJUST_HEALING_FROM_STRESS -## A multiplier for the impact stress has on shock recovery - 0.3 means maximum stress imposes a 30% penalty on shock recovery. -#STRESS_SHOCK_RECOVERY_CONSTANT 0.5 -## A multiplier for the impact stress has on wound passive healing, as above. -#STRESS_HEALING_RECOVERY_CONSTANT 0.3 -## A multiplier for the impact stress has on blood regeneration, as above. -#STRESS_BLOOD_RECOVERY_CONSTANT 0.3 diff --git a/data/character_info/.gitkeep b/data/character_info/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/html/browser/common.css b/html/browser/common.css index 29ea058136d..68579cf39ad 100644 --- a/html/browser/common.css +++ b/html/browser/common.css @@ -135,10 +135,8 @@ h4 .uiWrapper { - width: 100%; height: 100%; - padding-top:32px; } .uiTitle @@ -153,19 +151,11 @@ h4 .uiTitleWrapper { - position:fixed; - top:0px; - left:0px; - right:0px; - z-index: 10 + z-index: 10; } .uiTitleButtons { - position:fixed; - top:0px; - right:0px; - height:32px; z-index:11; } diff --git a/html/changelog.html b/html/changelog.html index dfbb7e7b567..0907002ff94 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,62 +52,96 @@ -->
    -

    08 January 2024

    -

    Greenjoe12345 updated:

    +

    19 February 2024

    +

    MistakeNot4892 updated:

      -
    • Pew sprites from Aurorastation
    • +
    • Trees can be cut down into logs.
    -

    28 December 2023

    +

    17 February 2024

    MistakeNot4892 updated:

      -
    • Some mech equipment origin tech has changed. Please report any missing or odd values.
    • +
    • Bricks can now be used to build walls without girders.
    -

    27 December 2023

    +

    16 February 2024

    MistakeNot4892 updated:

      -
    • Heating atoms like beakers with fire or a welding torch should be more consistent now.
    • +
    • Plates are no longer part of food when it emerges from the microwave, and must be retrieved from the dinnerware vendor and used to plate food.
    • +
    + +

    10 February 2024

    +

    MistakeNot4892 updated:

    +
      +
    • Loot piles have been added to the Tradeship underside.
    • +
    + +

    01 February 2024

    +

    MistakeNot4892 updated:

    +
      +
    • Bearcat wreck now has network infrastructure.
    • +
    • Egg and donut boxes are slightly fancier.
    • +
    • Pizza stacks have been enhanced to dangerous levels.
    • +
    + +

    24 January 2024

    +

    MistakeNot4892 updated:

    +
      +
    • All living mobs can now hallucinate.
    -

    19 December 2023

    -

    CheeseDogg0 updated:

    +

    23 January 2024

    +

    MistakeNot4892 updated:

      -
    • Changed some of the more ridiculous numbers to bring them more in line with real life
    • +
    • All living mobs can now dream.
    -

    18 December 2023

    +

    16 January 2024

    MistakeNot4892 updated:

      -
    • Updated ministation from ScavStation. Lots of changes, see PR.
    • -
    • Jump is now handled by selecting jump from the prepare button on the bottom right of the UI, then clicking the target.
    • +
    • Configuration has been rewritten to a new format. Servers with configuration changes from defaults will need to run the server to generate the new config file, then mirror their configuration changes in the new config system. Check the PR body for details.
    -

    14 December 2023

    +

    15 January 2024

    MistakeNot4892 updated:

      -
    • Neo-avian icons have been reindexed so may look slightly different.
    • -
    • Drills now function as shovels.
    • -
    • Clay can now be dug up from stationary drills.
    • -
    • Duct tape can be used to repair prosthetic faults.
    • +
    • You can now use arrow buttons to adjust markings and hair in character setup.
    -

    09 December 2023

    +

    14 January 2024

    MistakeNot4892 updated:

      -
    • Examining batons and energy guns should now show you the cell they have loaded, or require loading.
    • +
    • Manuals have been rewritten to pull information from the codex instead of the wiki.
    • +
    + +

    12 January 2024

    +

    NataKilar updated:

    +
      +
    • Eases contamination protection requirements slightly
    -

    07 December 2023

    +

    09 January 2024

    MistakeNot4892 updated:

      -
    • Suit sensors are now an accessory on your uniform that can be removed.
    • +
    • Simple mobs will now show a windup before hitting you in melee, allowing you to dodge.
    -

    09 November 2023

    +

    08 January 2024

    +

    Greenjoe12345 updated:

    +
      +
    • Pew sprites from Aurorastation
    • +
    + +

    28 December 2023

    MistakeNot4892 updated:

      -
    • Taj can now cycle voidsuits and have custom icons for them.
    • +
    • Some mech equipment origin tech has changed. Please report any missing or odd values.
    • +
    + +

    27 December 2023

    +

    MistakeNot4892 updated:

    +
      +
    • Heating atoms like beakers with fire or a welding torch should be more consistent now.
    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index fa7c9fc6def..a02c189a829 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14585,3 +14585,48 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2024-01-08: Greenjoe12345: - imageadd: Pew sprites from Aurorastation +2024-01-09: + MistakeNot4892: + - tweak: Simple mobs will now show a windup before hitting you in melee, allowing + you to dodge. +2024-01-12: + NataKilar: + - tweak: Eases contamination protection requirements slightly +2024-01-14: + MistakeNot4892: + - tweak: Manuals have been rewritten to pull information from the codex instead + of the wiki. +2024-01-15: + MistakeNot4892: + - tweak: You can now use arrow buttons to adjust markings and hair in character + setup. +2024-01-16: + MistakeNot4892: + - tweak: Configuration has been rewritten to a new format. Servers with configuration + changes from defaults will need to run the server to generate the new config + file, then mirror their configuration changes in the new config system. Check + the PR body for details. +2024-01-23: + MistakeNot4892: + - tweak: All living mobs can now dream. +2024-01-24: + MistakeNot4892: + - tweak: All living mobs can now hallucinate. +2024-02-01: + MistakeNot4892: + - tweak: Bearcat wreck now has network infrastructure. + - tweak: Egg and donut boxes are slightly fancier. + - tweak: Pizza stacks have been enhanced to dangerous levels. +2024-02-10: + MistakeNot4892: + - tweak: Loot piles have been added to the Tradeship underside. +2024-02-16: + MistakeNot4892: + - tweak: Plates are no longer part of food when it emerges from the microwave, and + must be retrieved from the dinnerware vendor and used to plate food. +2024-02-17: + MistakeNot4892: + - tweak: Bricks can now be used to build walls without girders. +2024-02-19: + MistakeNot4892: + - tweak: Trees can be cut down into logs. diff --git a/html/changelogs/AutoChangeLog-pr-3553.yml b/html/changelogs/AutoChangeLog-pr-3553.yml deleted file mode 100644 index b5639a14c50..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3553.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: 'Simple mobs will now show a windup before hitting you in melee, allowing - you to dodge.'} -delete-after: true diff --git a/icons/clothing/head/hardhat/medic.dmi b/icons/clothing/head/hardhat/medic.dmi index 92c875a6d31..d6a350b74c0 100644 Binary files a/icons/clothing/head/hardhat/medic.dmi and b/icons/clothing/head/hardhat/medic.dmi differ diff --git a/icons/clothing/rigs/helmets/helmet_null.dmi b/icons/clothing/rigs/helmets/helmet_null.dmi index 8911b076d16..ceb0366983c 100644 Binary files a/icons/clothing/rigs/helmets/helmet_null.dmi and b/icons/clothing/rigs/helmets/helmet_null.dmi differ diff --git a/icons/effects/landmarks.dmi b/icons/effects/landmarks.dmi index ee024440fb3..c69935c2a6d 100644 Binary files a/icons/effects/landmarks.dmi and b/icons/effects/landmarks.dmi differ diff --git a/icons/mob/human_races/species/default_damage_overlays.dmi b/icons/mob/human_races/species/default_damage_overlays.dmi index 31986efb86e..76110a61235 100644 Binary files a/icons/mob/human_races/species/default_damage_overlays.dmi and b/icons/mob/human_races/species/default_damage_overlays.dmi differ diff --git a/icons/mob/human_races/species/human/facial.dmi b/icons/mob/human_races/species/human/facial.dmi index 25fde2d870d..d3e78a757bf 100644 Binary files a/icons/mob/human_races/species/human/facial.dmi and b/icons/mob/human_races/species/human/facial.dmi differ diff --git a/icons/mob/human_races/species/human/hair.dmi b/icons/mob/human_races/species/human/hair.dmi index fae7d11712d..31a96a5128b 100644 Binary files a/icons/mob/human_races/species/human/hair.dmi and b/icons/mob/human_races/species/human/hair.dmi differ diff --git a/icons/mob/onmob/items/lefthand.dmi b/icons/mob/onmob/items/lefthand.dmi index 325eb614446..e5e4d78ee27 100644 Binary files a/icons/mob/onmob/items/lefthand.dmi and b/icons/mob/onmob/items/lefthand.dmi differ diff --git a/icons/mob/onmob/items/righthand.dmi b/icons/mob/onmob/items/righthand.dmi index 2638b0bf92a..9259c7c36e6 100644 Binary files a/icons/mob/onmob/items/righthand.dmi and b/icons/mob/onmob/items/righthand.dmi differ diff --git a/icons/mob/simple_animal/duck_brown.dmi b/icons/mob/simple_animal/duck_brown.dmi new file mode 100644 index 00000000000..5bcb6bc0e66 Binary files /dev/null and b/icons/mob/simple_animal/duck_brown.dmi differ diff --git a/icons/mob/simple_animal/duck_mallard.dmi b/icons/mob/simple_animal/duck_mallard.dmi new file mode 100644 index 00000000000..e03ae0e4df4 Binary files /dev/null and b/icons/mob/simple_animal/duck_mallard.dmi differ diff --git a/icons/mob/simple_animal/duck_white.dmi b/icons/mob/simple_animal/duck_white.dmi new file mode 100644 index 00000000000..b036096f4a8 Binary files /dev/null and b/icons/mob/simple_animal/duck_white.dmi differ diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index 93f5bb50f6f..26ee3a4c8d6 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ diff --git a/icons/obj/flora/deadtrees.dmi b/icons/obj/flora/deadtrees.dmi index f76ffd442f9..2afd9416cbf 100644 Binary files a/icons/obj/flora/deadtrees.dmi and b/icons/obj/flora/deadtrees.dmi differ diff --git a/icons/obj/flora/hardwood.dmi b/icons/obj/flora/hardwood.dmi new file mode 100644 index 00000000000..6e5976eb3d3 Binary files /dev/null and b/icons/obj/flora/hardwood.dmi differ diff --git a/icons/obj/flora/softwood.dmi b/icons/obj/flora/softwood.dmi new file mode 100644 index 00000000000..efbc33beba5 Binary files /dev/null and b/icons/obj/flora/softwood.dmi differ diff --git a/icons/obj/flora/tree_stumps.dmi b/icons/obj/flora/tree_stumps.dmi index 744771942f1..c79500d1786 100644 Binary files a/icons/obj/flora/tree_stumps.dmi and b/icons/obj/flora/tree_stumps.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index a6817ec4a00..c84284efeb2 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/food/containers/crackerbag.dmi b/icons/obj/food/containers/crackerbag.dmi new file mode 100644 index 00000000000..cb98badfa6c Binary files /dev/null and b/icons/obj/food/containers/crackerbag.dmi differ diff --git a/icons/obj/food/containers/donutbox.dmi b/icons/obj/food/containers/donutbox.dmi new file mode 100644 index 00000000000..6ca555b434e Binary files /dev/null and b/icons/obj/food/containers/donutbox.dmi differ diff --git a/icons/obj/food/containers/eggbox.dmi b/icons/obj/food/containers/eggbox.dmi new file mode 100644 index 00000000000..e90b439e1c9 Binary files /dev/null and b/icons/obj/food/containers/eggbox.dmi differ diff --git a/icons/obj/food/containers/pizzabox.dmi b/icons/obj/food/containers/pizzabox.dmi new file mode 100644 index 00000000000..38845bea26a Binary files /dev/null and b/icons/obj/food/containers/pizzabox.dmi differ diff --git a/icons/obj/food/cracker.dmi b/icons/obj/food/cracker.dmi new file mode 100644 index 00000000000..096c812145a Binary files /dev/null and b/icons/obj/food/cracker.dmi differ diff --git a/icons/obj/food/donuts/donut.dmi b/icons/obj/food/donuts/donut.dmi new file mode 100644 index 00000000000..31f7bece8a4 Binary files /dev/null and b/icons/obj/food/donuts/donut.dmi differ diff --git a/icons/obj/food/donuts/donut_iced.dmi b/icons/obj/food/donuts/donut_iced.dmi new file mode 100644 index 00000000000..c6cc1b7a8b7 Binary files /dev/null and b/icons/obj/food/donuts/donut_iced.dmi differ diff --git a/icons/obj/food/donuts/donut_jelly.dmi b/icons/obj/food/donuts/donut_jelly.dmi new file mode 100644 index 00000000000..a4632cc9d52 Binary files /dev/null and b/icons/obj/food/donuts/donut_jelly.dmi differ diff --git a/icons/obj/food/donuts/donut_jelly_iced.dmi b/icons/obj/food/donuts/donut_jelly_iced.dmi new file mode 100644 index 00000000000..a6581ed9a6a Binary files /dev/null and b/icons/obj/food/donuts/donut_jelly_iced.dmi differ diff --git a/icons/obj/food/eggs/egg.dmi b/icons/obj/food/eggs/egg.dmi new file mode 100644 index 00000000000..ca50ab06bb4 Binary files /dev/null and b/icons/obj/food/eggs/egg.dmi differ diff --git a/icons/obj/food/eggs/egg_blue.dmi b/icons/obj/food/eggs/egg_blue.dmi new file mode 100644 index 00000000000..88410742e3b Binary files /dev/null and b/icons/obj/food/eggs/egg_blue.dmi differ diff --git a/icons/obj/food/eggs/egg_chocolate.dmi b/icons/obj/food/eggs/egg_chocolate.dmi new file mode 100644 index 00000000000..3bad377aea6 Binary files /dev/null and b/icons/obj/food/eggs/egg_chocolate.dmi differ diff --git a/icons/obj/food/eggs/egg_green.dmi b/icons/obj/food/eggs/egg_green.dmi new file mode 100644 index 00000000000..11d19c48290 Binary files /dev/null and b/icons/obj/food/eggs/egg_green.dmi differ diff --git a/icons/obj/food/eggs/egg_lizard.dmi b/icons/obj/food/eggs/egg_lizard.dmi new file mode 100644 index 00000000000..475dcb8d625 Binary files /dev/null and b/icons/obj/food/eggs/egg_lizard.dmi differ diff --git a/icons/obj/food/eggs/egg_mime.dmi b/icons/obj/food/eggs/egg_mime.dmi new file mode 100644 index 00000000000..3b512981a9f Binary files /dev/null and b/icons/obj/food/eggs/egg_mime.dmi differ diff --git a/icons/obj/food/eggs/egg_orange.dmi b/icons/obj/food/eggs/egg_orange.dmi new file mode 100644 index 00000000000..12288907222 Binary files /dev/null and b/icons/obj/food/eggs/egg_orange.dmi differ diff --git a/icons/obj/food/eggs/egg_purple.dmi b/icons/obj/food/eggs/egg_purple.dmi new file mode 100644 index 00000000000..eaab67ae244 Binary files /dev/null and b/icons/obj/food/eggs/egg_purple.dmi differ diff --git a/icons/obj/food/eggs/egg_rainbow.dmi b/icons/obj/food/eggs/egg_rainbow.dmi new file mode 100644 index 00000000000..c7cf6648904 Binary files /dev/null and b/icons/obj/food/eggs/egg_rainbow.dmi differ diff --git a/icons/obj/food/eggs/egg_red.dmi b/icons/obj/food/eggs/egg_red.dmi new file mode 100644 index 00000000000..40baf4c7605 Binary files /dev/null and b/icons/obj/food/eggs/egg_red.dmi differ diff --git a/icons/obj/food/eggs/egg_yellow.dmi b/icons/obj/food/eggs/egg_yellow.dmi new file mode 100644 index 00000000000..4d55493625d Binary files /dev/null and b/icons/obj/food/eggs/egg_yellow.dmi differ diff --git a/icons/obj/food/pizzas/pizza_margherita.dmi b/icons/obj/food/pizzas/pizza_margherita.dmi new file mode 100644 index 00000000000..598370a7c77 Binary files /dev/null and b/icons/obj/food/pizzas/pizza_margherita.dmi differ diff --git a/icons/obj/food/pizzas/pizza_meat.dmi b/icons/obj/food/pizzas/pizza_meat.dmi new file mode 100644 index 00000000000..6d7c4848721 Binary files /dev/null and b/icons/obj/food/pizzas/pizza_meat.dmi differ diff --git a/icons/obj/food/pizzas/pizza_mushroom.dmi b/icons/obj/food/pizzas/pizza_mushroom.dmi new file mode 100644 index 00000000000..411b5e2923a Binary files /dev/null and b/icons/obj/food/pizzas/pizza_mushroom.dmi differ diff --git a/icons/obj/food/pizzas/pizza_slices.dmi b/icons/obj/food/pizzas/pizza_slices.dmi new file mode 100644 index 00000000000..002ef375903 Binary files /dev/null and b/icons/obj/food/pizzas/pizza_slices.dmi differ diff --git a/icons/obj/food/pizzas/pizza_vegetable.dmi b/icons/obj/food/pizzas/pizza_vegetable.dmi new file mode 100644 index 00000000000..672c5f27bcc Binary files /dev/null and b/icons/obj/food/pizzas/pizza_vegetable.dmi differ diff --git a/icons/obj/food/plates/bowl.dmi b/icons/obj/food/plates/bowl.dmi new file mode 100644 index 00000000000..91fc9bd18ba Binary files /dev/null and b/icons/obj/food/plates/bowl.dmi differ diff --git a/icons/obj/food/plates/platter.dmi b/icons/obj/food/plates/platter.dmi new file mode 100644 index 00000000000..1c278ed82b8 Binary files /dev/null and b/icons/obj/food/plates/platter.dmi differ diff --git a/icons/obj/food/plates/small_plate.dmi b/icons/obj/food/plates/small_plate.dmi new file mode 100644 index 00000000000..1d73c7d1d61 Binary files /dev/null and b/icons/obj/food/plates/small_plate.dmi differ diff --git a/icons/obj/food/plates/tray.dmi b/icons/obj/food/plates/tray.dmi new file mode 100644 index 00000000000..86a5033a69c Binary files /dev/null and b/icons/obj/food/plates/tray.dmi differ diff --git a/icons/obj/food_ingredients.dmi b/icons/obj/food_ingredients.dmi index ad4ecd8d83f..5e34ee4eff5 100644 Binary files a/icons/obj/food_ingredients.dmi and b/icons/obj/food_ingredients.dmi differ diff --git a/icons/obj/food_trays.dmi b/icons/obj/food_trays.dmi new file mode 100644 index 00000000000..9fc471af6fe Binary files /dev/null and b/icons/obj/food_trays.dmi differ diff --git a/icons/obj/guns/capacitor_rifle.dmi b/icons/obj/guns/capacitor_rifle.dmi index 02e0ccc712b..442f54df852 100644 Binary files a/icons/obj/guns/capacitor_rifle.dmi and b/icons/obj/guns/capacitor_rifle.dmi differ diff --git a/icons/obj/guns/pistol.dmi b/icons/obj/guns/pistol.dmi index cc84d7e40ef..e6e1deb6149 100644 Binary files a/icons/obj/guns/pistol.dmi and b/icons/obj/guns/pistol.dmi differ diff --git a/icons/obj/items/brain_interface_organic.dmi b/icons/obj/items/brain_interface_organic.dmi new file mode 100644 index 00000000000..940f246aecd Binary files /dev/null and b/icons/obj/items/brain_interface_organic.dmi differ diff --git a/icons/obj/items/brain_interface_robotic.dmi b/icons/obj/items/brain_interface_robotic.dmi new file mode 100644 index 00000000000..065f7a2cf2f Binary files /dev/null and b/icons/obj/items/brain_interface_robotic.dmi differ diff --git a/icons/obj/items/crayon.dmi b/icons/obj/items/crayon.dmi new file mode 100644 index 00000000000..f65e4503f32 Binary files /dev/null and b/icons/obj/items/crayon.dmi differ diff --git a/icons/obj/items/crayon_box.dmi b/icons/obj/items/crayon_box.dmi new file mode 100644 index 00000000000..f8fc5497b38 Binary files /dev/null and b/icons/obj/items/crayon_box.dmi differ diff --git a/icons/obj/items/crayon_mime.dmi b/icons/obj/items/crayon_mime.dmi new file mode 100644 index 00000000000..e5f136ffca3 Binary files /dev/null and b/icons/obj/items/crayon_mime.dmi differ diff --git a/icons/obj/items/crayon_rainbow.dmi b/icons/obj/items/crayon_rainbow.dmi new file mode 100644 index 00000000000..c16ddbc5218 Binary files /dev/null and b/icons/obj/items/crayon_rainbow.dmi differ diff --git a/icons/obj/items/crayons.dmi b/icons/obj/items/crayons.dmi index 7ebabd5a81e..1f1a9982024 100644 Binary files a/icons/obj/items/crayons.dmi and b/icons/obj/items/crayons.dmi differ diff --git a/icons/obj/items/device/boombox.dmi b/icons/obj/items/device/boombox.dmi index e49b198a7b0..41efdeca09a 100644 Binary files a/icons/obj/items/device/boombox.dmi and b/icons/obj/items/device/boombox.dmi differ diff --git a/icons/obj/items/device/radio/key.dmi b/icons/obj/items/device/radio/key.dmi index 458a6376067..565d78b8e0f 100644 Binary files a/icons/obj/items/device/radio/key.dmi and b/icons/obj/items/device/radio/key.dmi differ diff --git a/icons/obj/items/device/radio/spybug.dmi b/icons/obj/items/device/radio/spybug.dmi new file mode 100644 index 00000000000..549907f2a59 Binary files /dev/null and b/icons/obj/items/device/radio/spybug.dmi differ diff --git a/icons/obj/items/storage/lunchbox.dmi b/icons/obj/items/storage/lunchbox.dmi deleted file mode 100644 index 8d283cc8369..00000000000 Binary files a/icons/obj/items/storage/lunchbox.dmi and /dev/null differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_cat.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_cat.dmi new file mode 100644 index 00000000000..c1f76eb3d6f Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_cat.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_cti.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_cti.dmi new file mode 100644 index 00000000000..012aa094669 Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_cti.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_evil.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_evil.dmi new file mode 100644 index 00000000000..0c8fea6284c Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_evil.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_heart.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_heart.dmi new file mode 100644 index 00000000000..4410d4f354a Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_heart.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_mars.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_mars.dmi new file mode 100644 index 00000000000..d5842898985 Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_mars.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_rainbow.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_rainbow.dmi new file mode 100644 index 00000000000..de5a0587e2d Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_rainbow.dmi differ diff --git a/icons/obj/items/storage/lunchboxes/lunchbox_tcc.dmi b/icons/obj/items/storage/lunchboxes/lunchbox_tcc.dmi new file mode 100644 index 00000000000..4d008c3237d Binary files /dev/null and b/icons/obj/items/storage/lunchboxes/lunchbox_tcc.dmi differ diff --git a/icons/obj/items/storage/toolbox.dmi b/icons/obj/items/storage/toolbox.dmi deleted file mode 100644 index f3b61cd4763..00000000000 Binary files a/icons/obj/items/storage/toolbox.dmi and /dev/null differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_black_red.dmi b/icons/obj/items/storage/toolboxes/toolbox_black_red.dmi new file mode 100644 index 00000000000..b04e3356d9f Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_black_red.dmi differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_blue.dmi b/icons/obj/items/storage/toolboxes/toolbox_blue.dmi new file mode 100644 index 00000000000..94dc99ec379 Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_blue.dmi differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_green.dmi b/icons/obj/items/storage/toolboxes/toolbox_green.dmi new file mode 100644 index 00000000000..37c24f0e718 Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_green.dmi differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_red.dmi b/icons/obj/items/storage/toolboxes/toolbox_red.dmi new file mode 100644 index 00000000000..f26ba27fab1 Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_red.dmi differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_yellow.dmi b/icons/obj/items/storage/toolboxes/toolbox_yellow.dmi new file mode 100644 index 00000000000..6a68ee9fd47 Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_yellow.dmi differ diff --git a/icons/obj/items/storage/toolboxes/toolbox_yellow_striped.dmi b/icons/obj/items/storage/toolboxes/toolbox_yellow_striped.dmi new file mode 100644 index 00000000000..559fcabba2a Binary files /dev/null and b/icons/obj/items/storage/toolboxes/toolbox_yellow_striped.dmi differ diff --git a/icons/obj/light_overlays.dmi b/icons/obj/light_overlays.dmi deleted file mode 100644 index 4440f265523..00000000000 Binary files a/icons/obj/light_overlays.dmi and /dev/null differ diff --git a/icons/obj/materials.dmi b/icons/obj/materials.dmi index 57a97039779..1552365ba7f 100644 Binary files a/icons/obj/materials.dmi and b/icons/obj/materials.dmi differ diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi deleted file mode 100644 index 4a3037b7de8..00000000000 Binary files a/icons/obj/pipes/disposal.dmi and /dev/null differ diff --git a/icons/obj/pipes/disposal_bin.dmi b/icons/obj/pipes/disposal_bin.dmi new file mode 100644 index 00000000000..4760d29f4a0 Binary files /dev/null and b/icons/obj/pipes/disposal_bin.dmi differ diff --git a/icons/obj/pipes/disposal_chute.dmi b/icons/obj/pipes/disposal_chute.dmi new file mode 100644 index 00000000000..277338f9bc9 Binary files /dev/null and b/icons/obj/pipes/disposal_chute.dmi differ diff --git a/icons/obj/pipes/disposal_outlet.dmi b/icons/obj/pipes/disposal_outlet.dmi new file mode 100644 index 00000000000..61c2ae36ae3 Binary files /dev/null and b/icons/obj/pipes/disposal_outlet.dmi differ diff --git a/icons/obj/pipes/disposal_pipe.dmi b/icons/obj/pipes/disposal_pipe.dmi new file mode 100644 index 00000000000..dc7dc38b596 Binary files /dev/null and b/icons/obj/pipes/disposal_pipe.dmi differ diff --git a/icons/obj/stairs.dmi b/icons/obj/stairs.dmi index e850f6b68a8..d75c2c0aa4a 100644 Binary files a/icons/obj/stairs.dmi and b/icons/obj/stairs.dmi differ diff --git a/icons/obj/stairs_64.dmi b/icons/obj/stairs_64.dmi index b0c14147e5f..7b5d4b7c57e 100644 Binary files a/icons/obj/stairs_64.dmi and b/icons/obj/stairs_64.dmi differ diff --git a/icons/turf/walls/_previews.dmi b/icons/turf/walls/_previews.dmi index 9089954cdd2..0ce6dd767e2 100644 Binary files a/icons/turf/walls/_previews.dmi and b/icons/turf/walls/_previews.dmi differ diff --git a/icons/turf/walls/cult.dmi b/icons/turf/walls/cult.dmi index de8e02a5a7e..5b2dd836c3b 100644 Binary files a/icons/turf/walls/cult.dmi and b/icons/turf/walls/cult.dmi differ diff --git a/icons/turf/walls/debug.dmi b/icons/turf/walls/debug.dmi index 2de94776c40..76e8845f752 100644 Binary files a/icons/turf/walls/debug.dmi and b/icons/turf/walls/debug.dmi differ diff --git a/icons/turf/walls/metal.dmi b/icons/turf/walls/metal.dmi index a8ab0f10d86..8199a29f39d 100644 Binary files a/icons/turf/walls/metal.dmi and b/icons/turf/walls/metal.dmi differ diff --git a/icons/turf/walls/natural.dmi b/icons/turf/walls/natural.dmi index 40cf525581f..d8509d2f1ba 100644 Binary files a/icons/turf/walls/natural.dmi and b/icons/turf/walls/natural.dmi differ diff --git a/icons/turf/walls/plastic.dmi b/icons/turf/walls/plastic.dmi index 899f2a30a72..034c494a357 100644 Binary files a/icons/turf/walls/plastic.dmi and b/icons/turf/walls/plastic.dmi differ diff --git a/icons/turf/walls/reinforced.dmi b/icons/turf/walls/reinforced.dmi index b889f3c8327..ec9936fe157 100644 Binary files a/icons/turf/walls/reinforced.dmi and b/icons/turf/walls/reinforced.dmi differ diff --git a/icons/turf/walls/solid.dmi b/icons/turf/walls/solid.dmi index d961715cf64..ea504b65330 100644 Binary files a/icons/turf/walls/solid.dmi and b/icons/turf/walls/solid.dmi differ diff --git a/icons/turf/walls/stone.dmi b/icons/turf/walls/stone.dmi index 313bca3b564..285201a5e8b 100644 Binary files a/icons/turf/walls/stone.dmi and b/icons/turf/walls/stone.dmi differ diff --git a/icons/turf/walls/wood.dmi b/icons/turf/walls/wood.dmi index c1ee1f9eec1..9b2304dcec8 100644 Binary files a/icons/turf/walls/wood.dmi and b/icons/turf/walls/wood.dmi differ diff --git a/interface/interface.dm b/interface/interface.dm index d3bc6dcb54d..9f1e923dc44 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -3,10 +3,10 @@ set name = "Wiki" set desc = "Visit the wiki." set hidden = 1 - if(config.wikiurl) + if(get_config_value(/decl/config/text/wikiurl)) if(alert("This will open the wiki in your browser. Are you sure?",,"Yes","No")=="No") return - send_link(src, config.wikiurl) + send_link(src, get_config_value(/decl/config/text/wikiurl)) else to_chat(src, SPAN_WARNING("The wiki URL is not set in the server configuration.")) return @@ -15,10 +15,10 @@ set name = "GitHub" set desc = "Visit the GitHub repository." set hidden = 1 - if(config.githuburl) + if(get_config_value(/decl/config/text/githuburl)) if(alert("This will open GitHub in your browser. Are you sure?",,"Yes","No")=="No") return - send_link(src, config.githuburl) + send_link(src, get_config_value(/decl/config/text/githuburl)) else to_chat(src, SPAN_WARNING("The github URL is not set in the server configuration.")) return @@ -27,10 +27,10 @@ set name = "Bug Report" set desc = "Visit the GitHub repository to report an issue or bug." set hidden = 1 - if(config.issuereporturl) + if(get_config_value(/decl/config/text/issuereporturl)) if(alert("This will open GitHub in your browser. Are you sure?",,"Yes","No")=="No") return - send_link(src, config.issuereporturl) + send_link(src, get_config_value(/decl/config/text/issuereporturl)) else to_chat(src, SPAN_WARNING("The issue report URL is not set in the server configuration.")) return @@ -39,10 +39,10 @@ set name = "Forum" set desc = "Visit the forum." set hidden = 1 - if(config.forumurl) + if(get_config_value(/decl/config/text/forumurl)) if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No") return - send_link(src, config.forumurl) + send_link(src, get_config_value(/decl/config/text/forumurl)) else to_chat(src, SPAN_WARNING("The forum URL is not set in the server configuration.")) return @@ -51,10 +51,10 @@ set name = "Discord" set desc = "Visit the Discord server." set hidden = 1 - if(config.discordurl) + if(get_config_value(/decl/config/text/discordurl)) if(alert("This will open the Discord invition link in your browser. Are you sure?",,"Yes","No")=="No") return - send_link(src, config.discordurl) + send_link(src, get_config_value(/decl/config/text/discordurl)) else to_chat(src, SPAN_WARNING("The Discord server URL is not set in the server configuration.")) return diff --git a/interface/skin.dmf b/interface/skin.dmf index 1201b778688..3778ffcd7c1 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -148,6 +148,7 @@ window "mainwindow" anchor1 = 0,0 anchor2 = 100,100 saved-params = "splitter" + left = "mapwindow" right = "rpane" is-vert = true elem "asset_cache_browser" @@ -192,8 +193,6 @@ window "mapwindow" font-size = 7 is-default = true saved-params = "icon-size;zoom-mode" - on-show = ".winset\"mainwindow.split.left=mapwindow\"" - on-hide = ".winset\"mainwindow.split.left=\"" elem "lobbybrowser" type = BROWSER pos = 0,0 @@ -276,11 +275,12 @@ window "rpane" is-pane = true elem "rpanewindow" type = CHILD - pos = 0,0 - size = 640x474 + pos = 0,30 + size = 0x0 anchor1 = 0,0 anchor2 = 100,100 saved-params = "splitter" + left = "infowindow" right = "outputwindow" is-vert = false elem "github" @@ -357,7 +357,6 @@ window "rpane" size = 60x15 anchor1 = none anchor2 = none - is-visible = false saved-params = "is-checked" text = "Text" command = ".winset \"rpanewindow.left=;\"" @@ -370,7 +369,6 @@ window "rpane" size = 60x15 anchor1 = none anchor2 = none - is-visible = false saved-params = "is-checked" text = "Info" command = ".winset \"rpanewindow.left=infowindow\"" @@ -432,6 +430,6 @@ window "infowindow" is-default = true saved-params = "" highlight-color = #00aa00 - on-show = ".winset\"rpane.infob.is-visible=true;rpane.textb.is-visible=true rpane.infob.is-checked=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=infowindow\"" - on-hide = ".winset\"rpane.infob.is-visible=false;rpane.textb.is-visible=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=\"" + on-show = ".winset\"rpane.infob.is-checked=true\"" + on-hide = ".winset\"rpane.infob.is-checked=false\"" diff --git a/maps/antag_spawn/ert/ert_base.dmm b/maps/antag_spawn/ert/ert_base.dmm index f959d87cd04..70acf0bf828 100644 --- a/maps/antag_spawn/ert/ert_base.dmm +++ b/maps/antag_spawn/ert/ert_base.dmm @@ -1915,7 +1915,7 @@ /area/map_template/rescue_base/base) "dU" = ( /obj/structure/table/steel, -/obj/item/storage/fancy/cigar, +/obj/item/storage/box/fancy/cigar, /turf/unsimulated/floor{ icon_state = "dark" }, @@ -2839,7 +2839,7 @@ /area/map_template/rescue_base/start) "fU" = ( /obj/structure/table/steel_reinforced, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /turf/simulated/floor/tiled/dark, /area/map_template/rescue_base/start) "fV" = ( diff --git a/maps/antag_spawn/heist/heist_base.dmm b/maps/antag_spawn/heist/heist_base.dmm index 024258958f6..fda0b88d91a 100644 --- a/maps/antag_spawn/heist/heist_base.dmm +++ b/maps/antag_spawn/heist/heist_base.dmm @@ -449,7 +449,7 @@ /obj/structure/sign/warning/nosmoking_1/heist{ pixel_y = 32 }, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /turf/unsimulated/floor{ icon_state = "plating"; name = "plating" @@ -851,7 +851,7 @@ /obj/machinery/vending/cigarette{ name = "hacked cigarette machine"; markup = 0; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo/random = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo/random = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/unsimulated/floor{ icon_state = "dark" @@ -1300,7 +1300,7 @@ /area/map_template/skipjack_station/start) "di" = ( /obj/structure/table, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /obj/item/flame/lighter/zippo/random, /obj/item/clothing/gloves/insulated, /obj/item/stack/material/sheet/mapped/steel/fifty, diff --git a/maps/antag_spawn/mercenary/mercenary_base.dmm b/maps/antag_spawn/mercenary/mercenary_base.dmm index d04ede53ceb..4c9e65b6cf8 100644 --- a/maps/antag_spawn/mercenary/mercenary_base.dmm +++ b/maps/antag_spawn/mercenary/mercenary_base.dmm @@ -2247,7 +2247,7 @@ dir = 8; markup = 0; name = "hacked cigarette machine"; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo/random = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo/random = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /obj/structure/railing/mapped/no_density{ dir = 8 diff --git a/maps/antag_spawn/wizard/wizard_base.dmm b/maps/antag_spawn/wizard/wizard_base.dmm index 188917eb63c..cbc1e7c6694 100644 --- a/maps/antag_spawn/wizard/wizard_base.dmm +++ b/maps/antag_spawn/wizard/wizard_base.dmm @@ -364,7 +364,7 @@ /area/map_template/wizard_station) "aY" = ( /obj/structure/table/woodentable, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/unsimulated/floor{ dir = 8; icon_state = "wood" diff --git a/maps/away/bearcat/bearcat-1.dmm b/maps/away/bearcat/bearcat-1.dmm index 91ebec9abd1..78dc12c086c 100644 --- a/maps/away/bearcat/bearcat-1.dmm +++ b/maps/away/bearcat/bearcat-1.dmm @@ -11,8 +11,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/space) @@ -41,8 +40,7 @@ }, /obj/effect/floor_decal/industrial/outline/yellow, /obj/machinery/computer/cryopod/robot{ - dir = 8; - pixel_x = 0 + dir = 8 }, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/broken1) @@ -57,8 +55,7 @@ /area/ship/scrap/escape_port) "ai" = ( /obj/machinery/door/blast/regular/open{ - id_tag = "engwindow"; - + id_tag = "engwindow" }, /turf/simulated/floor/airless, /area/ship/scrap/escape_port) @@ -92,8 +89,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -104,8 +100,7 @@ /area/ship/scrap/cargo/lower) "ap" = ( /obj/machinery/door/blast/regular/open{ - id_tag = "engwindow"; - + id_tag = "engwindow" }, /turf/simulated/floor/airless, /area/ship/scrap/escape_star) @@ -125,8 +120,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/ship/scrap/cargo/lower) @@ -139,8 +133,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/ship/scrap/cargo/lower) @@ -522,8 +515,7 @@ "bi" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -690,8 +682,7 @@ "bA" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -1043,8 +1034,7 @@ "cm" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -1192,8 +1182,7 @@ "cC" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -1495,8 +1484,7 @@ "dk" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -1608,8 +1596,7 @@ "dw" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, @@ -1892,15 +1879,17 @@ req_access = newlist() }, /obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/item/stock_parts/circuitboard/autolathe, +/obj/item/stock_parts/circuitboard/unary_atmos/heater, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/maintenance/techstorage) "ed" = ( -/obj/item/stock_parts/circuitboard/autolathe, -/obj/item/stock_parts/circuitboard/unary_atmos/heater, -/obj/structure/rack, /obj/effect/floor_decal/corner/yellow{ dir = 5 }, +/obj/machinery/network/relay{ + initial_network_id = "freightnet_0451" +}, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/maintenance/techstorage) "ee" = ( @@ -2172,8 +2161,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/ship/scrap/maintenance/eva) @@ -2431,8 +2419,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/effect/wallframe_spawn/reinforced, diff --git a/maps/away/bearcat/bearcat-2.dmm b/maps/away/bearcat/bearcat-2.dmm index c8f8a24a860..e26e99ab157 100644 --- a/maps/away/bearcat/bearcat-2.dmm +++ b/maps/away/bearcat/bearcat-2.dmm @@ -6,8 +6,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -17,8 +16,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -29,8 +27,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/ship/scrap/command/bridge) @@ -149,7 +146,8 @@ /obj/machinery/network/requests_console{ announcementConsole = 1; department = "Captain"; - pixel_x = 32 + pixel_x = 32; + initial_network_id = "freightnet_0451" }, /obj/structure/bed/chair{ dir = 1 @@ -204,8 +202,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -318,14 +315,15 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, /area/ship/scrap/comms) "aO" = ( -/obj/machinery/network/message_server, +/obj/machinery/network/message_server{ + initial_network_id = "freightnet_0451" +}, /turf/simulated/floor/bluegrid/airless, /area/ship/scrap/comms) "aP" = ( @@ -410,8 +408,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -494,8 +491,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -521,8 +517,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -572,8 +567,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/space) @@ -715,8 +709,7 @@ "bx" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/button/access/interior{ id_tag = "bearcat_dock_port"; @@ -816,8 +809,7 @@ "bF" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/button/access/interior{ id_tag = "bearcat_starboard_dock"; @@ -888,8 +880,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -903,8 +894,7 @@ }, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/portable_atmospherics/canister/empty/air, /obj/structure/window/reinforced{ @@ -967,8 +957,7 @@ }, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/portable_atmospherics/canister/empty/air, /obj/structure/window/reinforced{ @@ -981,8 +970,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/usedup, /area/space) @@ -1000,8 +988,7 @@ /obj/structure/lattice, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/effect/wallframe_spawn/reinforced, /turf/simulated/floor/usedup, @@ -1021,8 +1008,7 @@ "bZ" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/effect/wallframe_spawn/reinforced, /turf/simulated/floor/usedup, @@ -1033,8 +1019,7 @@ "cc" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/effect/wallframe_spawn/reinforced, /turf/simulated/floor/usedup, @@ -1042,8 +1027,7 @@ "ce" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/effect/wallframe_spawn/reinforced, /turf/simulated/floor/usedup, @@ -1130,8 +1114,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -1179,7 +1162,7 @@ /obj/structure/sign/poster{ pixel_x = 32 }, -/obj/item/trash/tray, +/obj/item/plate/tray, /obj/item/circular_saw, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/crew/saloon) @@ -1202,8 +1185,7 @@ /obj/machinery/door/blast/regular/open{ dir = 4; id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/tiled/usedup, @@ -1337,8 +1319,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -1349,7 +1330,7 @@ dir = 4; icon_state = "right"; name = "Reception Window"; - opacity = TRUE + opacity = 1 }, /obj/machinery/light/small{ dir = 8; @@ -1365,7 +1346,7 @@ dir = 4; icon_state = "right"; name = "Reception Window"; - opacity = TRUE + opacity = 1 }, /obj/effect/floor_decal/corner/white/diagonal, /turf/simulated/floor/tiled/usedup, @@ -1530,8 +1511,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -1884,8 +1864,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -2031,8 +2010,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/structure/cable{ @@ -2279,8 +2257,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/structure/cable{ @@ -2631,7 +2608,7 @@ pixel_x = 24; req_access = newlist() }, -/turf/simulated/open, +/turf/open, /area/ship/scrap/crew/hallway/starboard) "fg" = ( /obj/structure/lattice, @@ -2776,7 +2753,7 @@ /turf/simulated/floor/tiled/usedup, /area/ship/scrap/crew/hallway/port) "ft" = ( -/turf/simulated/open, +/turf/open, /area/ship/scrap/cargo) "fu" = ( /obj/structure/cable{ @@ -2861,6 +2838,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/fuel{ dir = 10 }, +/obj/machinery/network/relay{ + initial_network_id = "freightnet_0451" +}, /turf/simulated/floor/usedup, /area/ship/scrap/unused) "fA" = ( @@ -2876,8 +2856,7 @@ "fE" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/airless, /area/ship/scrap/maintenance/engine/port) @@ -2892,8 +2871,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/fuel{ @@ -2951,7 +2929,7 @@ /area/ship/scrap/crew/hallway/port) "fM" = ( /obj/effect/shuttle_landmark/lift/top, -/turf/simulated/open, +/turf/open, /area/ship/scrap/cargo) "fN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -3014,8 +2992,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/fuel{ @@ -3278,8 +3255,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment{ @@ -4002,7 +3978,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/maintenance/engineering) "hI" = ( @@ -4190,7 +4166,7 @@ /obj/effect/floor_decal/corner/yellow{ dir = 10 }, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/machinery/vending/cigarette, /turf/simulated/floor/tiled/usedup, /area/ship/scrap/maintenance/engineering) @@ -4199,7 +4175,7 @@ /obj/effect/floor_decal/corner/yellow{ dir = 10 }, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/sign/warning/nosmoking_1{ pixel_y = -32 }, @@ -4238,8 +4214,7 @@ /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/machinery/door/firedoor, /turf/simulated/floor/usedup, @@ -4301,8 +4276,7 @@ /area/ship/scrap/maintenance/engine/aft) "ik" = ( /obj/machinery/door/blast/regular/open{ - id_tag = "engwindow"; - + id_tag = "engwindow" }, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -4526,8 +4500,7 @@ /obj/machinery/door/window/northleft, /obj/machinery/door/blast/regular/open{ dir = 2; - id_tag = "radaway"; - + id_tag = "radaway" }, /obj/structure/sign/warning/radioactive{ pixel_x = -32 @@ -4680,8 +4653,7 @@ }, /obj/machinery/door/blast/regular/open{ dir = 2; - id_tag = "radaway"; - + id_tag = "radaway" }, /obj/machinery/meter/turf, /turf/simulated/floor/usedup, @@ -5010,8 +4982,7 @@ "jY" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /obj/structure/sign/warning/hot_exhaust{ pixel_y = 32 @@ -5021,8 +4992,7 @@ "jZ" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/airless, /area/ship/scrap/maintenance/engine/aft) @@ -5092,8 +5062,7 @@ "oR" = ( /obj/machinery/door/blast/regular/open{ id_tag = "scraplock"; - name = "External Blast Doors"; - + name = "External Blast Doors" }, /turf/simulated/floor/airless, /area/ship/scrap/maintenance/engine/starboard) @@ -5208,6 +5177,12 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/simulated/floor/reinforced/airless, /area/ship/scrap/maintenance/atmos) +"Ix" = ( +/obj/machinery/network/router{ + initial_network_id = "freightnet_0451" +}, +/turf/simulated/floor/bluegrid/airless, +/area/ship/scrap/comms) "IG" = ( /obj/item/shard, /obj/machinery/atmospherics/unary/outlet_injector{ @@ -11992,7 +11967,7 @@ xU Yv Yv ar -aH +Ix aO aX Yv diff --git a/maps/away/bearcat/bearcat_areas.dm b/maps/away/bearcat/bearcat_areas.dm index afb062f609b..4d7c5c2eb3b 100644 --- a/maps/away/bearcat/bearcat_areas.dm +++ b/maps/away/bearcat/bearcat_areas.dm @@ -168,4 +168,4 @@ /area/ship/scrap/shuttle/lift name = "Cargo Lift" icon_state = "shuttle3" - base_turf = /turf/simulated/open \ No newline at end of file + base_turf = /turf/open \ No newline at end of file diff --git a/maps/away/casino/casino.dmm b/maps/away/casino/casino.dmm index 330c398e175..f046b9bbe1a 100644 --- a/maps/away/casino/casino.dmm +++ b/maps/away/casino/casino.dmm @@ -1301,19 +1301,19 @@ /area/casino/casino_storage) "dQ" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, /obj/random/tool, @@ -2067,7 +2067,7 @@ /obj/structure/table{ name = "plastic table frame" }, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/casino/casino_crew_cantina) "fU" = ( @@ -2095,7 +2095,7 @@ /obj/structure/table{ name = "plastic table frame" }, -/obj/item/trash/plate, +/obj/item/plate, /obj/random/snack, /obj/random/snack, /turf/simulated/floor/tiled, @@ -2270,8 +2270,8 @@ /area/casino/casino_mainfloor) "gv" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigar, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar, +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, /turf/simulated/floor/carpet, @@ -2742,7 +2742,7 @@ /area/casino/casino_mainfloor) "ia" = ( /obj/structure/table/woodentable, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /turf/simulated/floor/carpet, /area/casino/casino_mainfloor) @@ -2830,9 +2830,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, /obj/item/chems/condiment/flour, /obj/item/chems/condiment/sugar, /turf/simulated/floor/tiled, @@ -2869,13 +2869,13 @@ /area/casino/casino_mainfloor) "iq" = ( /obj/structure/table/woodentable, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/chems/food/applepie, /turf/simulated/floor/carpet, /area/casino/casino_mainfloor) "ir" = ( /obj/structure/table/woodentable, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/chems/food/bigbiteburger, /turf/simulated/floor/carpet, /area/casino/casino_mainfloor) @@ -2988,7 +2988,7 @@ /area/casino/casino_kitchen) "iG" = ( /obj/structure/table/marble, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/casino/casino_kitchen) "iH" = ( @@ -3056,13 +3056,13 @@ "iQ" = ( /obj/machinery/door/firedoor, /obj/structure/table/marble, -/obj/item/trash/tray, +/obj/item/plate/tray, /obj/item/chems/food/stew, /turf/simulated/floor/tiled, /area/casino/casino_kitchen) "iR" = ( /obj/structure/table/woodentable, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/spoon, /turf/simulated/floor/carpet, /area/casino/casino_mainfloor) @@ -3477,7 +3477,7 @@ /area/casino/casino_mainfloor) "jU" = ( /obj/structure/table/woodentable, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/chems/food/waffles, /obj/item/chems/drinks/cans/iced_tea, /turf/simulated/floor/carpet, @@ -3624,7 +3624,7 @@ /area/casino/casino_mainfloor) "kp" = ( /obj/structure/table/marble, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, /turf/simulated/floor/tiled, @@ -4233,7 +4233,7 @@ /area/casino/casino_private_vip) "lZ" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigar{ +/obj/item/storage/box/fancy/cigar{ pixel_y = 5 }, /turf/simulated/floor/wood, diff --git a/maps/away/derelict/derelict-station.dmm b/maps/away/derelict/derelict-station.dmm index 712e8d999ef..a2da531d305 100644 --- a/maps/away/derelict/derelict-station.dmm +++ b/maps/away/derelict/derelict-station.dmm @@ -3379,7 +3379,7 @@ /area/AIsattele) "lZ" = ( /obj/machinery/emitter{ - anchored = TRUE; + anchored = 1; dir = 4; state = 2 }, @@ -3391,7 +3391,7 @@ /area/constructionsite/engineering) "mb" = ( /obj/machinery/emitter{ - anchored = TRUE; + anchored = 1; dir = 8; state = 2 }, diff --git a/maps/away/errant_pisces/errant_pisces.dm b/maps/away/errant_pisces/errant_pisces.dm index 5af04eef731..03d1d4f1516 100644 --- a/maps/away/errant_pisces/errant_pisces.dm +++ b/maps/away/errant_pisces/errant_pisces.dm @@ -63,14 +63,14 @@ desc = "A fillet of cosmoshark meat." icon_state = "fishfillet" filling_color = "#cecece" - center_of_mass = @"{'x':17,'y':13}" + center_of_mass = @'{"x":17,"y":13}' bitesize = 8 /obj/item/chems/food/sharkmeat/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) - reagents.add_reagent(/decl/material/liquid/psychoactives, 1) - reagents.add_reagent(/decl/material/solid/phoron, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/psychoactives, 1) + add_to_reagents(/decl/material/solid/phoron, 1) /obj/structure/net//if you want to have fun, make them to be draggable as a whole unless at least one piece is attached to a non-space turf or anchored object name = "industrial net" diff --git a/maps/away/errant_pisces/errant_pisces.dmm b/maps/away/errant_pisces/errant_pisces.dmm index 75b4dd6ba84..006b4392ab5 100644 --- a/maps/away/errant_pisces/errant_pisces.dmm +++ b/maps/away/errant_pisces/errant_pisces.dmm @@ -3236,7 +3236,7 @@ /area/errant_pisces/infirmary) "iF" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /turf/simulated/floor/tiled, /area/errant_pisces/dorms) @@ -3247,7 +3247,7 @@ /area/errant_pisces/dorms) "iH" = ( /obj/structure/table/marble, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/errant_pisces/dorms) "iI" = ( @@ -3950,8 +3950,8 @@ dir = 1 }, /obj/structure/bookcase, -/obj/item/book/manual/anomaly_testing, -/obj/item/book/manual/anomaly_spectroscopy, +/obj/item/book/fluff/anomaly_testing, +/obj/item/book/fluff/anomaly_spectroscopy, /turf/simulated/floor/tiled, /area/errant_pisces/science_wing) "kB" = ( @@ -3962,7 +3962,7 @@ /area/errant_pisces/science_wing) "kC" = ( /obj/structure/bookcase, -/obj/item/book/manual/materials_chemistry_analysis, +/obj/item/book/fluff/materials_chemistry_analysis, /turf/simulated/floor/tiled, /area/errant_pisces/science_wing) "kD" = ( diff --git a/maps/away/liberia/liberia.dmm b/maps/away/liberia/liberia.dmm index f8466b1e6a0..eb0f3f0d530 100644 --- a/maps/away/liberia/liberia.dmm +++ b/maps/away/liberia/liberia.dmm @@ -322,7 +322,7 @@ dir = 9 }, /obj/structure/closet/emcloset{ - anchored = TRUE; + anchored = 1; name = "anchored emergency closet" }, /turf/simulated/floor/tiled/techfloor/grid, @@ -2444,7 +2444,7 @@ }, /obj/effect/floor_decal/industrial/outline/yellow, /obj/structure/closet/emcloset{ - anchored = TRUE; + anchored = 1; name = "anchored emergency closet" }, /turf/simulated/floor/tiled/monotile, @@ -4186,7 +4186,7 @@ "hz" = ( /obj/machinery/vending/cigarette{ dir = 1; - products = list(/obj/item/storage/fancy/cigarettes=10,/obj/item/storage/box/matches=10,/obj/item/flame/lighter/zippo=4,/obj/item/clothing/mask/smokable/cigarette/cigar/havana=2) + products = list(/obj/item/storage/box/fancy/cigarettes=10,/obj/item/storage/box/matches=10,/obj/item/flame/lighter/zippo=4,/obj/item/clothing/mask/smokable/cigarette/cigar/havana=2) }, /turf/simulated/floor/wood/walnut, /area/liberia/bar) @@ -5249,7 +5249,7 @@ /area/liberia/library) "kc" = ( /obj/structure/table/woodentable/walnut, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/effect/floor_decal/spline/fancy/wood{ dir = 6 }, @@ -7976,7 +7976,7 @@ dir = 6 }, /obj/structure/closet/emcloset{ - anchored = TRUE; + anchored = 1; name = "anchored emergency closet" }, /turf/simulated/floor/tiled/techfloor, diff --git a/maps/away/lost_supply_base/lost_supply_base.dmm b/maps/away/lost_supply_base/lost_supply_base.dmm index 0595df716ba..31aa2503190 100644 --- a/maps/away/lost_supply_base/lost_supply_base.dmm +++ b/maps/away/lost_supply_base/lost_supply_base.dmm @@ -1069,10 +1069,10 @@ /area/lost_supply_base/common) "dc" = ( /obj/structure/table, -/obj/item/trash/tray{ +/obj/item/plate/tray{ pixel_x = 10 }, -/obj/item/trash/tray, +/obj/item/plate/tray, /turf/simulated/floor/tiled/airless, /area/lost_supply_base/common) "dd" = ( @@ -1210,7 +1210,7 @@ /obj/structure/table{ name = "plastic table frame" }, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled/airless, /area/lost_supply_base/common) "dA" = ( diff --git a/maps/away/magshield/magshield.dm b/maps/away/magshield/magshield.dm index 5a32a7b5dfe..35415658d07 100644 --- a/maps/away/magshield/magshield.dm +++ b/maps/away/magshield/magshield.dm @@ -141,40 +141,24 @@ icon_state = "nav_light_red" -/obj/item/book/manual/magshield_manual +/obj/item/book/fluff/magshield_manual name = "SOP for Planetary Shield Orbital Station" icon = 'magshield_sprites.dmi' icon_state = "mg_guide" author = "Terraforms Industrial" title = "Standard operating procedures for Planetary Shield Orbital Station" - - dat = {" - - - - - -

    Introduction

    - Terraforms Industrial is happy to see you as our customer! Please read this guide before using and operating with your custom PSOS - Planetary Shield Orbital Statiion. -

    Best uses for PSOS

    - PSOS is intended for protecting exoplanets from high energy space radiation rays and particles. Best used for planets lacking active geomagnetic field so PSOS would compensate its absence.
    -

    Applied technologies

    - Terraforms Industrial is delivering you your new PSOS with set of four (4) high-strength magnetic field generators. Those devices use rotating supeconducter hands to create magnetic field with strength up to 5 Tesla effectively deflecting up to 99% of space radiation spectrum.
    -
    - Special modified vacuum radiation sensors will help you evaluate radiation level and adjust power input of PSOS magnetic generators for best efficiency and power saving. -


    - rest of the book pages are gone - - - "} + fluff_text = {" +

    Introduction

    + Terraforms Industrial is happy to see you as our customer! Please read this guide before using and operating with your custom PSOS - Planetary Shield Orbital Statiion. +

    Best uses for PSOS

    + PSOS is intended for protecting exoplanets from high energy space radiation rays and particles. Best used for planets lacking active geomagnetic field so PSOS would compensate its absence.
    +

    Applied technologies

    + Terraforms Industrial is delivering you your new PSOS with set of four (4) high-strength magnetic field generators. Those devices use rotating supeconducter hands to create magnetic field with strength up to 5 Tesla effectively deflecting up to 99% of space radiation spectrum.
    +
    + Special modified vacuum radiation sensors will help you evaluate radiation level and adjust power input of PSOS magnetic generators for best efficiency and power saving. +


    + The rest of the pages have been torn out... + "} /obj/item/paper/magshield/tornpage name = "torn book page" diff --git a/maps/away/magshield/magshield.dmm b/maps/away/magshield/magshield.dmm index 75a2b44e377..bb5e50b60cb 100644 --- a/maps/away/magshield/magshield.dmm +++ b/maps/away/magshield/magshield.dmm @@ -680,7 +680,7 @@ /area/magshield/engine) "cd" = ( /obj/machinery/atmospherics/binary/circulator{ - anchored = TRUE; + anchored = 1; dir = 4 }, /turf/simulated/floor/plating, @@ -766,7 +766,7 @@ icon_state = "0-8" }, /obj/machinery/generator{ - anchored = TRUE + anchored = 1 }, /turf/simulated/floor/plating, /area/magshield/engine) @@ -847,7 +847,7 @@ /area/magshield/engine) "cx" = ( /obj/machinery/atmospherics/binary/circulator{ - anchored = TRUE; + anchored = 1; dir = 8 }, /turf/simulated/floor/plating, @@ -2561,7 +2561,7 @@ /turf/simulated/floor/tiled, /area/magshield/west) "hD" = ( -/obj/item/book/manual/magshield_manual, +/obj/item/book/fluff/magshield_manual, /turf/simulated/floor/tiled/white, /area/magshield/west) "hE" = ( @@ -3163,7 +3163,7 @@ /obj/structure/table{ name = "plastic table frame" }, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/chems/food/flatbread, /turf/simulated/floor/tiled, /area/magshield/south) @@ -3319,7 +3319,7 @@ /obj/structure/table{ name = "plastic table frame" }, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/magshield/south) "jT" = ( @@ -3738,7 +3738,7 @@ name = "plastic table frame" }, /obj/item/kitchen/utensil/fork/plastic, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/magshield/south) "le" = ( diff --git a/maps/away/mining/mining-orb.dmm b/maps/away/mining/mining-orb.dmm index c11811d5a8b..15f3a6ac472 100644 --- a/maps/away/mining/mining-orb.dmm +++ b/maps/away/mining/mining-orb.dmm @@ -26,7 +26,7 @@ /turf/exterior/wall/random, /area/mine/unexplored) "ai" = ( -/turf/simulated/wall/sandstone, +/turf/simulated/wall/brick/sandstone, /area/mine/unexplored) "aj" = ( /turf/simulated/floor/airless/stone, @@ -48,7 +48,7 @@ /turf/simulated/wall/alium, /area/mine/explored) "ap" = ( -/turf/simulated/wall/sandstone, +/turf/simulated/wall/brick/sandstone, /area/mine/explored) "aq" = ( /obj/effect/floor_decal/spline/fancy/wood, @@ -339,7 +339,7 @@ /obj/effect/floor_decal/spline/fancy/wood/corner{ dir = 4 }, -/turf/simulated/wall/sandstone, +/turf/simulated/wall/brick/sandstone, /area/mine/explored) "Rr" = ( /obj/effect/floor_decal/spline/fancy/wood, diff --git a/maps/away/mining/mining-signal.dmm b/maps/away/mining/mining-signal.dmm index e3e32505f79..099a0b59bdc 100644 --- a/maps/away/mining/mining-signal.dmm +++ b/maps/away/mining/mining-signal.dmm @@ -971,7 +971,7 @@ /area/outpost/abandoned) "dt" = ( /obj/structure/door_assembly{ - anchored = TRUE + anchored = 1 }, /turf/simulated/floor, /area/outpost/abandoned) @@ -1079,18 +1079,18 @@ /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "dJ" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/table/steel, /obj/random/bomb_supply, /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "dK" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/bed/chair, /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "dL" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/bed/chair, /obj/machinery/light/small/emergency{ dir = 1; @@ -1173,7 +1173,7 @@ /turf/simulated/floor/tiled/white/airless, /area/outpost/abandoned) "dZ" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/sign/directions/medical{ dir = 8 }, @@ -1181,8 +1181,8 @@ /area/outpost/abandoned) "ea" = ( /obj/effect/decal/cleanable/dirt, -/obj/abstract/fluid_mapped/fuel, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "eb" = ( @@ -1194,11 +1194,11 @@ /area/outpost/abandoned) "ec" = ( /obj/effect/decal/cleanable/dirt, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "ed" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/effect/decal/cleanable/blood/oil, /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) @@ -1239,7 +1239,7 @@ /area/mine/explored) "el" = ( /obj/structure/firedoor_assembly{ - anchored = TRUE + anchored = 1 }, /obj/effect/wallframe_spawn/reinforced, /turf/simulated/floor/plating, @@ -1282,7 +1282,7 @@ /turf/simulated/floor/tiled/white/airless, /area/outpost/abandoned) "et" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/table, /obj/structure/window/reinforced{ dir = 1 @@ -1294,14 +1294,14 @@ /turf/simulated/floor/tiled/white/airless, /area/outpost/abandoned) "eu" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /mob/living/bot/medbot, /turf/simulated/floor/tiled/white/airless, /area/outpost/abandoned) "ev" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/tiled/white/airless, /area/outpost/abandoned) "ex" = ( @@ -1310,7 +1310,7 @@ /turf/simulated/floor/tiled/airless, /area/outpost/abandoned) "ey" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/effect/floor_decal/corner/paleblue{ dir = 9 }, @@ -1468,7 +1468,7 @@ "eW" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/machinery/atmospherics/pipe/simple/hidden/green{ dir = 4 }, @@ -1841,7 +1841,7 @@ /area/mine/explored) "gd" = ( /obj/structure/windoor_assembly{ - anchored = TRUE; + anchored = 1; dir = 8 }, /turf/simulated/floor/tiled/dark, @@ -2072,7 +2072,7 @@ /obj/effect/decal/cleanable/blood/tracks/footprints, /obj/effect/decal/cleanable/dirt, /obj/structure/firedoor_assembly{ - anchored = TRUE + anchored = 1 }, /turf/simulated/floor/plating{ icon_state = "dmg2" @@ -2260,7 +2260,7 @@ /area/outpost/abandoned) "hp" = ( /obj/effect/decal/cleanable/dirt, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/plating, /area/outpost/abandoned) "hq" = ( @@ -2361,13 +2361,13 @@ "hD" = ( /obj/random/junk, /obj/effect/decal/cleanable/dirt, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/plating, /area/outpost/abandoned) "hE" = ( /obj/structure/table/reinforced, /obj/random/material, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/plating, /area/outpost/abandoned) "hF" = ( @@ -2376,7 +2376,7 @@ /turf/simulated/floor/plating, /area/outpost/abandoned) "hG" = ( -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /obj/structure/closet/crate/radiation, /obj/random/voidsuit, /obj/random/voidhelmet, @@ -2384,7 +2384,7 @@ /area/outpost/abandoned) "hH" = ( /obj/structure/reagent_dispensers/fueltank, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/plating, /area/outpost/abandoned) "hL" = ( diff --git a/maps/away/slavers/slavers_base.dmm b/maps/away/slavers/slavers_base.dmm index 1937f9a942a..707f237cc3c 100644 --- a/maps/away/slavers/slavers_base.dmm +++ b/maps/away/slavers/slavers_base.dmm @@ -2936,7 +2936,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/slavers_base/dorms) "ib" = ( @@ -3197,7 +3197,7 @@ /area/slavers_base/dorms) "iR" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /obj/structure/cable{ icon_state = "4-8" @@ -3332,7 +3332,7 @@ /area/slavers_base/dorms) "ji" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /obj/random/snack, /turf/simulated/floor/tiled, /area/slavers_base/dorms) diff --git a/maps/away/smugglers/smugglers.dmm b/maps/away/smugglers/smugglers.dmm index dc20dfc73a6..43b2fc8a2f5 100644 --- a/maps/away/smugglers/smugglers.dmm +++ b/maps/away/smugglers/smugglers.dmm @@ -57,7 +57,7 @@ }, /obj/effect/floor_decal/industrial/warning/full, /obj/item/beartrap{ - anchored = TRUE; + anchored = 1; deployed = 1; icon_state = "beartrap1" }, @@ -249,7 +249,7 @@ /area/smugglers/base) "aJ" = ( /obj/item/beartrap{ - anchored = TRUE; + anchored = 1; deployed = 1; icon_state = "beartrap1" }, diff --git a/maps/away/unishi/unishi-2.dmm b/maps/away/unishi/unishi-2.dmm index 8d3c0ea178f..bb279fe3723 100644 --- a/maps/away/unishi/unishi-2.dmm +++ b/maps/away/unishi/unishi-2.dmm @@ -593,7 +593,7 @@ /obj/structure/cable/yellow{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/unishi/common) "bO" = ( /obj/machinery/floodlight, diff --git a/maps/away/unishi/unishi-3.dmm b/maps/away/unishi/unishi-3.dmm index 3156725ec11..e91221f4215 100644 --- a/maps/away/unishi/unishi-3.dmm +++ b/maps/away/unishi/unishi-3.dmm @@ -357,7 +357,7 @@ dir = 8; icon_state = "railing0" }, -/turf/simulated/open, +/turf/open, /area/unishi/living) "bp" = ( /turf/simulated/floor/tiled, @@ -430,7 +430,7 @@ /obj/structure/cable{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/unishi/living) "bB" = ( /obj/structure/reagent_dispensers/fueltank, @@ -930,7 +930,7 @@ /obj/structure/table/woodentable, /obj/item/board, /obj/item/book/manual/mass_spectrometry, -/obj/item/book/manual/stasis, +/obj/item/book/fluff/stasis, /turf/simulated/floor/tiled, /area/unishi/living) "cM" = ( @@ -1382,7 +1382,7 @@ /turf/simulated/floor/tiled, /area/unishi/living) "dT" = ( -/obj/item/trash/plate, +/obj/item/plate, /obj/machinery/light/small{ dir = 8 }, @@ -2009,7 +2009,7 @@ /area/unishi/living) "XA" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/unishi/living) (1,1,1) = {" diff --git a/maps/away/unishi/unishi.dm b/maps/away/unishi/unishi.dm index 327b663c2cc..554735ad04b 100644 --- a/maps/away/unishi/unishi.dm +++ b/maps/away/unishi/unishi.dm @@ -140,7 +140,7 @@ /obj/item/chems/glass/bottle/tericadone/Initialize() . = ..() - reagents.add_reagent(/decl/material/solid/phoron/safe, 60) + add_to_reagents(/decl/material/solid/phoron/safe, 60) update_icon() /decl/material/solid/phoron/safe/touch_mob(mob/living/M, amount, datum/reagents/holder) diff --git a/maps/example/example-2.dmm b/maps/example/example-2.dmm index ee19110309e..c13f3f65a42 100644 --- a/maps/example/example-2.dmm +++ b/maps/example/example-2.dmm @@ -39,7 +39,7 @@ /area/example/second) "es" = ( /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/example/second) "fJ" = ( /obj/machinery/light/small{ @@ -181,7 +181,7 @@ /area/example/second) "nB" = ( /obj/effect/shuttle_landmark/upper_level, -/turf/simulated/open, +/turf/open, /area/space) "nC" = ( /obj/effect/floor_decal/corner/mauve/mono, @@ -209,7 +209,7 @@ /turf/simulated/floor/tiled/steel_grid, /area/example/second) "oS" = ( -/turf/simulated/open, +/turf/open, /area/space) "pc" = ( /obj/effect/wallframe_spawn/reinforced, @@ -359,13 +359,13 @@ /turf/simulated/floor/tiled/steel_grid, /area/example/second) "wP" = ( -/turf/simulated/open, +/turf/open, /area/example/second) "xk" = ( /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/example/second) "xs" = ( /turf/space, @@ -509,7 +509,7 @@ /area/example/second) "GG" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/example/second) "GP" = ( /obj/machinery/light{ @@ -585,7 +585,7 @@ /area/example/second) "NY" = ( /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/example/second) "Pc" = ( /obj/effect/floor_decal/corner/orange{ @@ -655,7 +655,7 @@ /turf/simulated/floor/tiled/white/monotile, /area/example/second) "VL" = ( -/turf/simulated/open, +/turf/open, /area/turbolift/example/second) "Xm" = ( /obj/structure/iv_drip, @@ -669,7 +669,7 @@ /obj/machinery/light/small{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/example/second) "XE" = ( /turf/simulated/wall/r_wall/prepainted, diff --git a/maps/example/example-3.dmm b/maps/example/example-3.dmm index bfe1873d23f..87c2734da16 100644 --- a/maps/example/example-3.dmm +++ b/maps/example/example-3.dmm @@ -11,7 +11,7 @@ /turf/simulated/floor, /area/example/third) "cj" = ( -/turf/simulated/open, +/turf/open, /area/turbolift/example/third) "cw" = ( /obj/machinery/atmospherics/portables_connector, @@ -61,7 +61,7 @@ /area/example/third) "jb" = ( /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/example/third) "lK" = ( /turf/simulated/floor/glass, @@ -71,7 +71,7 @@ /turf/simulated/floor, /area/example/third) "nG" = ( -/turf/simulated/open, +/turf/open, /area/space) "nN" = ( /obj/effect/floor_decal/industrial/warning/dust{ @@ -132,7 +132,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/example/third) "wD" = ( /obj/effect/floor_decal/industrial/warning/dust{ @@ -209,7 +209,7 @@ /turf/simulated/floor, /area/example/third) "Ke" = ( -/turf/simulated/open, +/turf/open, /area/example/third) "KS" = ( /obj/effect/floor_decal/industrial/warning/dust{ @@ -276,7 +276,7 @@ /area/example/third) "TM" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/example/third) "TO" = ( /obj/machinery/atmospherics/pipe/simple/hidden, @@ -287,7 +287,7 @@ /area/example/third) "UC" = ( /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/example/third) "UM" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ diff --git a/maps/example/example_areas.dm b/maps/example/example_areas.dm index 2391adc3a8d..029ab553e01 100644 --- a/maps/example/example_areas.dm +++ b/maps/example/example_areas.dm @@ -35,7 +35,7 @@ arrival_sound = null lift_announce_str = null - base_turf = /turf/simulated/open + base_turf = /turf/open /area/turbolift/example/first name = "Testing Site First Floor Lift" diff --git a/maps/exodus/exodus-2.dmm b/maps/exodus/exodus-2.dmm index fe8656dbc51..3074b21f3f1 100644 --- a/maps/exodus/exodus-2.dmm +++ b/maps/exodus/exodus-2.dmm @@ -2485,7 +2485,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/effect/floor_decal/corner/red, /turf/simulated/floor/tiled/steel_grid, /area/exodus/security/main) @@ -3109,7 +3109,7 @@ /area/exodus/security/main) "agN" = ( /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/navbeacon/SecurityD, /obj/machinery/door/firedoor, @@ -5138,7 +5138,7 @@ "akU" = ( /obj/structure/table/woodentable, /obj/item/ashtray/plastic, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /obj/item/clothing/gloves/forensic, /turf/simulated/floor/carpet, /area/exodus/security/detectives_office) @@ -5375,7 +5375,7 @@ "alo" = ( /obj/structure/rack, /obj/item/flame/lighter/random, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /obj/random/maintenance, /obj/random/maintenance, /turf/simulated/floor/plating, @@ -6652,7 +6652,7 @@ pixel_x = 4; pixel_y = 6 }, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /turf/simulated/floor/tiled/dark, /area/exodus/lawoffice) "anU" = ( @@ -7004,7 +7004,7 @@ /area/exodus/maintenance/auxsolarstarboard) "aoK" = ( /obj/machinery/faxmachine/mapped{ - anchored = FALSE + anchored = 0 }, /obj/structure/table/reinforced, /obj/machinery/newscaster{ @@ -7953,7 +7953,7 @@ pixel_x = 4; pixel_y = 6 }, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -13770,7 +13770,7 @@ }, /obj/structure/lattice, /turf/simulated/floor/plating, -/turf/simulated/open, +/turf/open, /area/exodus/engineering/sublevel_access) "aDl" = ( /obj/machinery/atmospherics/pipe/zpipe/down/red{ @@ -13778,7 +13778,7 @@ }, /obj/structure/lattice, /turf/simulated/floor/plating, -/turf/simulated/open, +/turf/open, /area/exodus/engineering/sublevel_access) "aDm" = ( /obj/structure/reagent_dispensers/beerkeg, @@ -14480,7 +14480,7 @@ dir = 1 }, /turf/simulated/floor/plating, -/turf/simulated/open, +/turf/open, /area/exodus/engineering/sublevel_access) "aEI" = ( /obj/structure/shuttle/engine/propulsion/burst{ @@ -16714,7 +16714,7 @@ "aJb" = ( /obj/machinery/navbeacon/Bar, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/door/firedoor, /obj/effect/floor_decal/industrial/loading{ @@ -16734,7 +16734,7 @@ /area/exodus/gateway) "aJd" = ( /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/navbeacon/Kitchen, /obj/machinery/door/firedoor, @@ -16768,7 +16768,7 @@ pixel_x = -2; pixel_y = 5 }, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /turf/simulated/floor/lino, /area/exodus/chapel/office) "aJk" = ( @@ -17579,7 +17579,7 @@ "aKW" = ( /obj/machinery/navbeacon/Hydroponics, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/door/firedoor, /obj/effect/floor_decal/industrial/loading, @@ -20023,7 +20023,7 @@ name = "Prisoner's Locker" }, /obj/item/flame/lighter/zippo, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/simulated/floor/tiled/steel_grid, /area/exodus/security/prison/dorm) "aQb" = ( @@ -20093,7 +20093,7 @@ /area/exodus/maintenance/arrivals) "aQj" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigarettes{ +/obj/item/storage/box/fancy/cigarettes{ pixel_y = 2 }, /obj/random/single{ @@ -23009,8 +23009,8 @@ /area/exodus/storage/art) "aWZ" = ( /obj/structure/table, -/obj/item/storage/fancy/crayons, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, @@ -25371,7 +25371,7 @@ /obj/structure/cable/green{ icon_state = "0-4" }, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/effect/floor_decal/corner/blue/three_quarters, /turf/simulated/floor/tiled/steel_grid, /area/exodus/bridge) @@ -26220,7 +26220,7 @@ /obj/structure/cable/green{ icon_state = "0-4" }, -/obj/item/storage/fancy/cigarettes{ +/obj/item/storage/box/fancy/cigarettes{ pixel_y = 2 }, /turf/simulated/floor/tiled/dark/monotile, @@ -28087,7 +28087,7 @@ /area/exodus/turret_protected/ai) "bhU" = ( /obj/structure/table/woodentable, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/structure/cable/green{ icon_state = "4-8" }, @@ -30472,7 +30472,7 @@ dir = 4 }, /obj/structure/table/woodentable, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/simulated/floor/wood/walnut, /area/exodus/bridge/meeting_room) "bmF" = ( @@ -30753,7 +30753,7 @@ }, /obj/item/chems/glass/beaker/sulphuric, /obj/structure/reagent_dispensers/acid{ - density = FALSE; + density = 0; pixel_y = 32 }, /turf/simulated/floor/tiled/white/monotile, @@ -32838,7 +32838,7 @@ id_tag = "packageExternal" }, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/structure/cable{ icon_state = "4-8" @@ -34898,9 +34898,9 @@ "bvA" = ( /obj/effect/floor_decal/corner/paleblue, /obj/structure/table, -/obj/item/mmi, -/obj/item/mmi, -/obj/item/mmi, +/obj/item/organ/internal/brain_interface/empty, +/obj/item/organ/internal/brain_interface/empty, +/obj/item/organ/internal/brain_interface/empty, /turf/simulated/floor/tiled/dark, /area/exodus/research/robotics) "bvB" = ( @@ -36562,7 +36562,7 @@ /obj/item/flash/synthetic, /obj/item/flash/synthetic, /obj/item/flash/synthetic, -/obj/item/organ/internal/posibrain, +/obj/item/organ/internal/brain/robotic, /obj/item/robotanalyzer, /obj/effect/floor_decal/corner/paleblue{ dir = 10 @@ -38381,7 +38381,7 @@ "bCL" = ( /obj/machinery/navbeacon/Research, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/door/firedoor, /obj/effect/floor_decal/industrial/loading{ @@ -42234,7 +42234,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/window/westleft{ name = "Server Room"; - opacity = TRUE + opacity = 1 }, /obj/machinery/door/window/eastleft{ name = "Server Room" @@ -43592,7 +43592,7 @@ dir = 1 }, /obj/structure/bookcase/manuals/medical, -/obj/item/book/manual/stasis, +/obj/item/book/fluff/stasis, /obj/effect/floor_decal/corner/grey/diagonal, /turf/simulated/floor/tiled/white, /area/exodus/crew_quarters/medbreak) @@ -44094,7 +44094,7 @@ "bNY" = ( /obj/machinery/navbeacon/Janitor, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/door/firedoor, /turf/simulated/floor/plating, @@ -47011,7 +47011,7 @@ /area/exodus/maintenance/medbay) "bTP" = ( /obj/machinery/shieldwallgen{ - anchored = TRUE + anchored = 1 }, /obj/structure/cable/green{ icon_state = "0-2" @@ -48067,7 +48067,7 @@ "bWa" = ( /obj/machinery/navbeacon/Medbay, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /turf/simulated/floor/plating, /area/exodus/medical/sleeper) @@ -50786,7 +50786,7 @@ pixel_y = 4 }, /obj/item/clothing/glasses/welding/superior, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /obj/item/book/manual/supermatter_engine, /turf/simulated/floor/tiled/steel_grid, /area/exodus/crew_quarters/heads/chief) @@ -55386,7 +55386,7 @@ "clg" = ( /obj/machinery/navbeacon/Engineering, /obj/structure/plasticflaps{ - opacity = TRUE + opacity = 1 }, /obj/machinery/door/firedoor, /obj/effect/floor_decal/industrial/loading{ @@ -55993,7 +55993,7 @@ /turf/simulated/floor/plating, /area/exodus/maintenance/starboardsolar) "cmq" = ( -/obj/item/storage/fancy/vials, +/obj/item/storage/box/fancy/vials, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -56184,7 +56184,7 @@ /area/exodus/engineering/locker_room) "cmM" = ( /obj/machinery/door/blast/regular/open{ - density = FALSE; + density = 0; dir = 4; id_tag = "SupermatterPort"; name = "Reactor Blast Door" @@ -58241,7 +58241,7 @@ "crR" = ( /obj/structure/table, /obj/item/storage/box/matches, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /obj/machinery/light/small{ dir = 8 }, @@ -59271,7 +59271,7 @@ icon_state = "0-2" }, /obj/machinery/generator{ - anchored = TRUE; + anchored = 1; dir = 4 }, /obj/structure/cable/yellow, @@ -61968,7 +61968,7 @@ /area/exodus/engineering/engine_room) "cIa" = ( /obj/machinery/emitter{ - anchored = TRUE; + anchored = 1; id_tag = "EngineEmitter"; state = 2 }, @@ -62134,7 +62134,7 @@ /area/exodus/engineering/engine_room) "cIF" = ( /obj/machinery/atmospherics/binary/circulator{ - anchored = TRUE; + anchored = 1; dir = 1 }, /turf/simulated/floor/plating, @@ -62150,7 +62150,7 @@ /area/exodus/engineering/engine_room) "cIH" = ( /obj/machinery/atmospherics/binary/circulator{ - anchored = TRUE + anchored = 1 }, /turf/simulated/floor/plating, /area/exodus/engineering/engine_room) @@ -62507,7 +62507,7 @@ /area/exodus/maintenance/engi_engine) "cJZ" = ( /obj/machinery/generator{ - anchored = TRUE; + anchored = 1; dir = 4 }, /obj/structure/cable/yellow, diff --git a/maps/exodus/exodus-admin.dmm b/maps/exodus/exodus-admin.dmm index 50d1a80ed0b..c83c3c48c9b 100644 --- a/maps/exodus/exodus-admin.dmm +++ b/maps/exodus/exodus-admin.dmm @@ -2640,7 +2640,7 @@ /obj/item/chems/drinks/bottle/small/beer, /obj/item/chems/drinks/bottle/small/beer, /obj/item/flame/lighter/zippo/random, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/unsimulated/floor{ icon_state = "lino" }, diff --git a/maps/exodus/exodus-transit.dmm b/maps/exodus/exodus-transit.dmm index 850cd44d03a..3561cf64477 100644 --- a/maps/exodus/exodus-transit.dmm +++ b/maps/exodus/exodus-transit.dmm @@ -22,7 +22,7 @@ /obj/effect/step_trigger/teleporter/random{ affect_ghosts = 1; name = "escapeshuttle_leave"; - opacity = FALSE; + opacity = 0; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; diff --git a/maps/exodus/jobs/civilian.dm b/maps/exodus/jobs/civilian.dm index ad474b024e4..6919061c901 100644 --- a/maps/exodus/jobs/civilian.dm +++ b/maps/exodus/jobs/civilian.dm @@ -11,10 +11,9 @@ department_types = list(/decl/department/civilian) /datum/job/assistant/get_access() - if(config.assistant_maint) + if(get_config_value(/decl/config/toggle/assistant_maint)) return list(access_maint_tunnels) - else - return list() + return list() /datum/job/chaplain title = "Chaplain" diff --git a/maps/exodus/jobs/synthetics.dm b/maps/exodus/jobs/synthetics.dm index 1c102582a2c..1cac23c65ae 100644 --- a/maps/exodus/jobs/synthetics.dm +++ b/maps/exodus/jobs/synthetics.dm @@ -76,4 +76,4 @@ /datum/job/robot/New() ..() alt_titles = SSrobots.robot_alt_titles.Copy() - alt_titles -= title // So the unit test doesn't flip out if a mob or mmi type is declared for our main title. + alt_titles -= title // So the unit test doesn't flip out if a mob or brain type is declared for our main title. diff --git a/maps/ministation/jobs/civilian.dm b/maps/ministation/jobs/civilian.dm index a8857566ff4..b35ccd1b202 100644 --- a/maps/ministation/jobs/civilian.dm +++ b/maps/ministation/jobs/civilian.dm @@ -13,10 +13,9 @@ event_categories = list(ASSIGNMENT_GARDENER) /datum/job/ministation/assistant/get_access() - if(config.assistant_maint) + if(get_config_value(/decl/config/toggle/assistant_maint)) return list(access_maint_tunnels) - else - return list() + return list() /decl/hierarchy/outfit/job/ministation_assistant name = "Job - Ministation Assistant" diff --git a/maps/ministation/jobs/security.dm b/maps/ministation/jobs/security.dm index 526fd41b594..b1e691ccb99 100644 --- a/maps/ministation/jobs/security.dm +++ b/maps/ministation/jobs/security.dm @@ -6,7 +6,7 @@ total_positions = 2 outfit_type = /decl/hierarchy/outfit/job/ministation/security department_types = list(/decl/department/security) - selection_color = "#990000" + selection_color = COLOR_BLOOD_RED economic_power = 7 minimal_player_age = 7 access = list( diff --git a/maps/ministation/ministation-1.dmm b/maps/ministation/ministation-1.dmm index 4923d032960..a826ddb44d8 100644 --- a/maps/ministation/ministation-1.dmm +++ b/maps/ministation/ministation-1.dmm @@ -266,7 +266,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/supply, /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l2centraln) "bH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -407,7 +407,7 @@ /obj/machinery/camera/autoname{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "cN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -502,7 +502,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "dN" = ( /obj/structure/cable{ @@ -821,7 +821,7 @@ /turf/simulated/floor/plating, /area/ministation/maint/l2centrals) "gz" = ( -/turf/simulated/open, +/turf/open, /area/ministation/hall/e2) "gB" = ( /obj/structure/cable{ @@ -1313,7 +1313,7 @@ pixel_y = 7 }, /obj/item/pen, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /obj/item/handcuffs, /obj/machinery/newscaster{ pixel_x = 32; @@ -1776,7 +1776,7 @@ dir = 8; icon_state = "tube1" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "md" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ @@ -2636,7 +2636,7 @@ dir = 4; icon_state = "warningcorner" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "qO" = ( /obj/machinery/cryopod{ @@ -2827,7 +2827,7 @@ dir = 1; icon_state = "warningcorner" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "rA" = ( /obj/structure/table/woodentable, @@ -3357,7 +3357,7 @@ /obj/abstract/landmark{ name = "bluespace_a" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/e2) "tx" = ( /obj/machinery/door/firedoor{ @@ -4151,7 +4151,7 @@ "wr" = ( /obj/structure/lattice, /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l2centrals) "ws" = ( /turf/simulated/floor/tiled, @@ -4265,7 +4265,7 @@ /area/ministation/cafe) "wQ" = ( /obj/structure/table/marble, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/machinery/door/firedoor{ dir = 8 }, @@ -4405,7 +4405,7 @@ /obj/machinery/door/firedoor{ dir = 8 }, -/obj/item/trash/tray, +/obj/item/plate/tray, /obj/machinery/door/blast/shutters{ id_tag = "barshut"; name = "Bar Shutters" @@ -4670,7 +4670,7 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/nebypass) "yl" = ( /obj/structure/displaycase, @@ -5270,7 +5270,7 @@ /obj/item/stamp/clown, /obj/item/storage/backpack/clown, /obj/item/bikehorn, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/item/poster, /turf/simulated/floor/plating, /area/ministation/maint/hydromaint) @@ -6625,7 +6625,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "MU" = ( /obj/structure/filing_cabinet/chestdrawer, @@ -6747,7 +6747,7 @@ /turf/simulated/floor/tiled, /area/ministation/hall/w2) "NC" = ( -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "ND" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -6954,7 +6954,7 @@ /area/ministation/hall/e2) "Pd" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigarettes{ +/obj/item/storage/box/fancy/cigarettes{ pixel_y = 2 }, /obj/item/flame/lighter/random, @@ -7316,7 +7316,7 @@ /obj/structure/cable{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/hydromaint) "RQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -7416,7 +7416,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/w2) "SA" = ( /obj/machinery/network/relay{ @@ -7841,7 +7841,7 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/sebypass) "Wi" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ diff --git a/maps/ministation/ministation-2.dmm b/maps/ministation/ministation-2.dmm index c23f66a8cc6..6864884b7f9 100644 --- a/maps/ministation/ministation-2.dmm +++ b/maps/ministation/ministation-2.dmm @@ -637,7 +637,7 @@ /obj/effect/floor_decal/industrial/warning/corner{ icon_state = "warningcorner" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "ch" = ( /obj/structure/cable{ @@ -1741,7 +1741,7 @@ "hY" = ( /obj/structure/lattice, /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3nw) "if" = ( /obj/machinery/door/window/eastright, @@ -3001,7 +3001,7 @@ "pb" = ( /obj/structure/lattice, /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3sw) "pf" = ( /obj/effect/floor_decal/corner/blue{ @@ -3355,7 +3355,7 @@ /obj/abstract/landmark{ name = "bluespace_a" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "tx" = ( /obj/effect/wallframe_spawn/reinforced, @@ -3365,7 +3365,7 @@ "ty" = ( /obj/structure/lattice, /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3se) "tA" = ( /obj/effect/floor_decal/corner/yellow/full, @@ -3435,7 +3435,7 @@ /area/ministation/court) "ug" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "uh" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -3652,7 +3652,7 @@ "wY" = ( /obj/structure/table/woodentable/ebony, /obj/item/pen/fancy, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/effect/floor_decal/stoneborder{ dir = 6 }, @@ -3662,7 +3662,7 @@ "xc" = ( /obj/structure/lattice, /obj/structure/ladder, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3ne) "xg" = ( /obj/machinery/light{ @@ -4546,7 +4546,7 @@ /obj/machinery/camera/autoname{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "Dp" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -4842,7 +4842,7 @@ /turf/simulated/floor/tiled, /area/ministation/hall/s3) "GD" = ( -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "GF" = ( /obj/structure/disposalpipe/segment, @@ -5132,7 +5132,7 @@ /obj/structure/disposalpipe/down{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3central) "Kg" = ( /obj/structure/cable{ @@ -5646,7 +5646,7 @@ /obj/structure/catwalk, /obj/effect/floor_decal/industrial/warning, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "OG" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -5745,7 +5745,7 @@ dir = 8; icon_state = "tube1" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "Pg" = ( /obj/structure/cable{ @@ -6418,7 +6418,7 @@ dir = 8; icon_state = "warning" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "TR" = ( /obj/structure/window/basic{ @@ -6580,7 +6580,7 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l3se) "Vi" = ( /obj/machinery/light_switch{ @@ -6904,7 +6904,7 @@ /obj/structure/catwalk, /obj/effect/floor_decal/industrial/warning, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "XE" = ( /obj/structure/catwalk, @@ -6912,7 +6912,7 @@ dir = 8; icon_state = "warningcorner" }, -/turf/simulated/open, +/turf/open, /area/ministation/hall/n3) "XI" = ( /obj/effect/floor_decal/carpet/green/corners, diff --git a/maps/ministation/ministation-3.dmm b/maps/ministation/ministation-3.dmm index c957f544da3..4260640c1ad 100644 --- a/maps/ministation/ministation-3.dmm +++ b/maps/ministation/ministation-3.dmm @@ -229,7 +229,7 @@ /obj/machinery/light/small{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l4overpass) "Aj" = ( /obj/structure/cable, @@ -264,7 +264,7 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l4overpass) "CJ" = ( /obj/structure/cable{ @@ -411,7 +411,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/supply{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ministation/maint/l4central) "VO" = ( /obj/structure/cable{ diff --git a/maps/ministation/ministation_areas.dm b/maps/ministation/ministation_areas.dm index 91e6b18998a..5d138148067 100644 --- a/maps/ministation/ministation_areas.dm +++ b/maps/ministation/ministation_areas.dm @@ -333,8 +333,8 @@ /area/turbolift/l2 name = "Station Level 2" - base_turf = /turf/simulated/open + base_turf = /turf/open /area/turbolift/l3 name = "Station Level 3" - base_turf = /turf/simulated/open \ No newline at end of file + base_turf = /turf/open \ No newline at end of file diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 80490c1e80a..4496e42a8d7 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -6,6 +6,7 @@ #include "../../mods/content/mundane.dm" #include "../../mods/content/scaling_descriptors.dm" #include "../../mods/content/baychems/_baychems.dme" + #include "../../mods/content/dungeon_loot/_dungeon_loot.dme" #include "../../mods/content/bigpharma/_bigpharma.dme" #include "../../mods/content/byond_membership/_byond_membership.dm" #include "../../mods/content/corporate/_corporate.dme" diff --git a/maps/planets/test_planet/neutralia-4.dmm b/maps/planets/test_planet/neutralia-4.dmm index 98b3a04d943..bf23c1fb529 100644 --- a/maps/planets/test_planet/neutralia-4.dmm +++ b/maps/planets/test_planet/neutralia-4.dmm @@ -3,19 +3,19 @@ /turf/unsimulated/dark_filler, /area/exoplanet/neutralia/sky) "b" = ( -/turf/exterior/open, +/turf/open, /area/exoplanet/neutralia/sky) "c" = ( /obj/abstract/level_data_spawner/neutralia/sky, -/turf/exterior/open, +/turf/open, /area/exoplanet/neutralia/sky) "d" = ( /obj/abstract/map_data/neutralia, -/turf/exterior/open, +/turf/open, /area/exoplanet/neutralia/sky) "e" = ( /obj/effect/overmap/visitable/sector/planetoid/neutralia, -/turf/exterior/open, +/turf/open, /area/exoplanet/neutralia/sky) (1,1,1) = {" diff --git a/maps/planets/test_planet/test_planet.dm b/maps/planets/test_planet/test_planet.dm index b9557cf13a6..b4c7c55ce96 100644 --- a/maps/planets/test_planet/test_planet.dm +++ b/maps/planets/test_planet/test_planet.dm @@ -121,7 +121,7 @@ name = "neutralia sky" level_id = NEUTRALIA_SKY_LEVEL_ID base_area = /area/exoplanet/neutralia/sky - base_turf = /turf/exterior/open + base_turf = /turf/open border_filler = /turf/unsimulated/dark_filler /datum/level_data/planetoid/neutralia/surface diff --git a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dm b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dm index beec44a6f61..65431787700 100644 --- a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dm +++ b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dm @@ -6,7 +6,7 @@ var/global/list/crashed_pod_areas = list() suffixes = list("crashed_pod/crashed_pod.dmm") cost = 2 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS | TEMPLATE_FLAG_NO_RADS - ruin_tags = RUIN_HUMAN|RUIN_WRECK + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WRECK /area/map_template/crashed_pod name = "\improper Crashed Survival Pod" diff --git a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm index 0230a67ba8b..8c367234c97 100644 --- a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm +++ b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm @@ -950,9 +950,9 @@ /obj/item/storage/bag/trash, /obj/item/storage/box/donkpockets, /obj/item/storage/box/donkpockets, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, /obj/item/chems/condiment/enzyme, /obj/item/chems/drinks/milk, /obj/item/chems/drinks/milk, diff --git a/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm b/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm index 17e6dded4cf..87035476c8e 100644 --- a/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm +++ b/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm @@ -4,7 +4,7 @@ suffixes = list("datacapsule/datacapsule.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_WRECK + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WRECK apc_test_exempt_areas = list( /area/map_template/datacapsule = NO_SCRUBBER|NO_VENT|NO_APC @@ -40,7 +40,7 @@ desc += "Label is smudged, and there's crusted blood fingerprints on it." /obj/item/chems/glass/beaker/vial/random_podchem/populate_reagents() - reagents.add_reagent(pick(/decl/material/liquid/random, /decl/material/liquid/zombie/science, /decl/material/liquid/retrovirals), 5) + add_to_reagents(pick(/decl/material/liquid/random, /decl/material/liquid/zombie/science, /decl/material/liquid/retrovirals), 5) /obj/structure/backup_server name = "backup server" @@ -57,7 +57,7 @@ to_chat(user, SPAN_NOTICE("You pry out the data drive from \the [src].")) playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) var/obj/item/stock_parts/computer/hard_drive/cluster/drive = new(get_turf(src)) - drive.origin_tech = "{'[TECH_DATA]':[rand(4,5)],'[TECH_ENGINEERING]':[rand(4,5)],'[TECH_EXOTIC_MATTER]':[rand(4,5)],'[TECH_COMBAT]':[rand(2,5)],'[TECH_ESOTERIC]':[rand(0,6)]}" + drive.origin_tech = @'{"[TECH_DATA]":[rand(4,5)],"[TECH_ENGINEERING]":[rand(4,5)],"[TECH_EXOTIC_MATTER]":[rand(4,5)],"[TECH_COMBAT]":[rand(2,5)],"[TECH_ESOTERIC]":[rand(0,6)]}' disk_looted = TRUE return TRUE . = ..() diff --git a/maps/random_ruins/exoplanet_ruins/deserted_lab/deserted_lab.dm b/maps/random_ruins/exoplanet_ruins/deserted_lab/deserted_lab.dm index 1a640e3bea9..5cde3625eda 100644 --- a/maps/random_ruins/exoplanet_ruins/deserted_lab/deserted_lab.dm +++ b/maps/random_ruins/exoplanet_ruins/deserted_lab/deserted_lab.dm @@ -4,4 +4,4 @@ suffixes = list("deserted_lab/deserted_lab.dmm") cost = 1.5 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN \ No newline at end of file + template_tags = TEMPLATE_TAG_HUMAN \ No newline at end of file diff --git a/maps/random_ruins/exoplanet_ruins/drill_site/drill_site.dm b/maps/random_ruins/exoplanet_ruins/drill_site/drill_site.dm index be2108b0b72..ac9d41228c0 100644 --- a/maps/random_ruins/exoplanet_ruins/drill_site/drill_site.dm +++ b/maps/random_ruins/exoplanet_ruins/drill_site/drill_site.dm @@ -4,4 +4,4 @@ suffixes = list("drill_site/drill_site.dmm") cost = 0.5 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN \ No newline at end of file + template_tags = TEMPLATE_TAG_HUMAN \ No newline at end of file diff --git a/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dm b/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dm index 7bcd48aaab7..ce55aaa5f3b 100644 --- a/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dm +++ b/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dm @@ -4,9 +4,9 @@ suffixes = list("fountain/fountain_ruin.dmm") cost = 2 template_flags = TEMPLATE_FLAG_NO_RUINS | TEMPLATE_FLAG_CLEAR_CONTENTS - ruin_tags = RUIN_ALIEN + template_tags = TEMPLATE_TAG_ALIEN -/turf/simulated/wall/sandstonediamond +/turf/simulated/wall/brick/sandstonediamond icon_state = "reinforced_stone" material = /decl/material/solid/stone/sandstone reinf_material = /decl/material/solid/gemstone/diamond diff --git a/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dmm b/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dmm index a52244c3261..cfa9067b8f7 100644 --- a/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dmm +++ b/maps/random_ruins/exoplanet_ruins/fountain/fountain_ruin.dmm @@ -3,7 +3,7 @@ /turf/template_noop, /area/template_noop) "b" = ( -/turf/simulated/wall/sandstonediamond, +/turf/simulated/wall/brick/sandstonediamond, /area/template_noop) "c" = ( /turf/simulated/floor/fixed/alium, diff --git a/maps/random_ruins/exoplanet_ruins/hut/hut.dm b/maps/random_ruins/exoplanet_ruins/hut/hut.dm index 039019d9887..25ec5611d94 100644 --- a/maps/random_ruins/exoplanet_ruins/hut/hut.dm +++ b/maps/random_ruins/exoplanet_ruins/hut/hut.dm @@ -4,7 +4,7 @@ suffixes = list("hut/hut.dmm") cost = 0.5 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_HABITAT + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_HABITAT /turf/simulated/wall/silver icon_state = "metal" diff --git a/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm b/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm index 453e7fb4ffb..e28854c3373 100644 --- a/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm +++ b/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm @@ -4,7 +4,7 @@ suffixes = list("hydrobase/hydrobase.dmm") cost = 2 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_ALIEN + template_tags = TEMPLATE_TAG_ALIEN apc_test_exempt_areas = list( /area/map_template/hydrobase = NO_SCRUBBER|NO_VENT|NO_APC, /area/map_template/hydrobase/station = NO_SCRUBBER, diff --git a/maps/random_ruins/exoplanet_ruins/lodge/lodge.dm b/maps/random_ruins/exoplanet_ruins/lodge/lodge.dm index e3693151022..84ec9585fcc 100644 --- a/maps/random_ruins/exoplanet_ruins/lodge/lodge.dm +++ b/maps/random_ruins/exoplanet_ruins/lodge/lodge.dm @@ -4,7 +4,7 @@ suffixes = list("lodge/lodge.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_HABITAT + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_HABITAT /turf/simulated/floor/wood/usedup initial_gas = list(/decl/material/gas/carbon_dioxide = MOLES_O2STANDARD, /decl/material/gas/nitrogen = MOLES_N2STANDARD) \ No newline at end of file diff --git a/maps/random_ruins/exoplanet_ruins/marooned/marooned.dm b/maps/random_ruins/exoplanet_ruins/marooned/marooned.dm index 35f5d70ecec..9b06ca84cab 100644 --- a/maps/random_ruins/exoplanet_ruins/marooned/marooned.dm +++ b/maps/random_ruins/exoplanet_ruins/marooned/marooned.dm @@ -4,7 +4,7 @@ suffixes = list("marooned/marooned.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_WRECK + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WRECK apc_test_exempt_areas = list( /area/map_template/marooned = NO_SCRUBBER|NO_VENT|NO_APC ) diff --git a/maps/random_ruins/exoplanet_ruins/monoliths/monoliths.dm b/maps/random_ruins/exoplanet_ruins/monoliths/monoliths.dm index 94a8d7d9279..ff79160e8b7 100644 --- a/maps/random_ruins/exoplanet_ruins/monoliths/monoliths.dm +++ b/maps/random_ruins/exoplanet_ruins/monoliths/monoliths.dm @@ -4,7 +4,7 @@ suffixes = list("monoliths/monoliths.dmm") cost = 1 template_flags = TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_ALIEN + template_tags = TEMPLATE_TAG_ALIEN /obj/structure/monolith name = "monolith" diff --git a/maps/random_ruins/exoplanet_ruins/oasis/oasis.dm b/maps/random_ruins/exoplanet_ruins/oasis/oasis.dm index 00606d465bd..e648a663a5d 100644 --- a/maps/random_ruins/exoplanet_ruins/oasis/oasis.dm +++ b/maps/random_ruins/exoplanet_ruins/oasis/oasis.dm @@ -4,7 +4,7 @@ suffixes = list("oasis/oasis.dmm") cost = 0.5 template_flags = TEMPLATE_FLAG_NO_RUINS | TEMPLATE_FLAG_ALLOW_DUPLICATES - ruin_tags = RUIN_NATURAL|RUIN_WATER + template_tags = TEMPLATE_TAG_NATURAL|TEMPLATE_TAG_WATER /datum/map_template/ruin/exoplanet/oasis/oasis2 name = "oasis 2" diff --git a/maps/random_ruins/exoplanet_ruins/oldpod/oldpod.dm b/maps/random_ruins/exoplanet_ruins/oldpod/oldpod.dm index d5e30d3f9ca..0ea139fdbc7 100644 --- a/maps/random_ruins/exoplanet_ruins/oldpod/oldpod.dm +++ b/maps/random_ruins/exoplanet_ruins/oldpod/oldpod.dm @@ -6,7 +6,7 @@ suffixes = list("oldpod/oldpod.dmm") cost = 0.5 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_WRECK + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WRECK apc_test_exempt_areas = list( /area/map_template/oldpod = NO_APC ) diff --git a/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm b/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm index 0a919b57c8b..dd2aaef5dbf 100644 --- a/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm +++ b/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm @@ -2698,7 +2698,7 @@ /area/map_template/colony/messhall) "fI" = ( /obj/structure/table/woodentable_reinforced, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/effect/floor_decal/spline/fancy/wood{ dir = 1 }, @@ -3915,7 +3915,7 @@ dir = 1 }, /obj/structure/table/steel_reinforced, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/simulated/floor/tiled/techfloor, /area/map_template/colony/jail) "hR" = ( @@ -3926,7 +3926,7 @@ dir = 4 }, /obj/structure/casino/roulette_chart{ - density = TRUE + density = 1 }, /turf/simulated/floor/wood/walnut, /area/map_template/colony/commons) @@ -4242,7 +4242,7 @@ /obj/machinery/reagent_temperature, /obj/item/chems/drinks/shaker, /obj/machinery/vending/boozeomat{ - density = FALSE; + density = 0; pixel_y = -32; req_access = list() }, @@ -4795,7 +4795,7 @@ dir = 4 }, /obj/structure/casino/roulette{ - density = TRUE + density = 1 }, /obj/effect/floor_decal/spline/fancy/wood{ dir = 4 @@ -6907,7 +6907,7 @@ /obj/machinery/light{ dir = 8 }, -/mob/living/simple_animal/chicken, +/mob/living/simple_animal/fowl/chicken, /turf/simulated/floor/grass, /area/map_template/colony/hydroponics) "nm" = ( @@ -7806,7 +7806,7 @@ /turf/exterior/concrete, /area/template_noop) "vt" = ( -/mob/living/simple_animal/chicken, +/mob/living/simple_animal/fowl/chicken, /turf/simulated/floor/grass, /area/map_template/colony/hydroponics) "vJ" = ( diff --git a/maps/random_ruins/exoplanet_ruins/playablecolony/playablecolony.dm b/maps/random_ruins/exoplanet_ruins/playablecolony/playablecolony.dm index 224f94bebc5..8155b9581bd 100644 --- a/maps/random_ruins/exoplanet_ruins/playablecolony/playablecolony.dm +++ b/maps/random_ruins/exoplanet_ruins/playablecolony/playablecolony.dm @@ -6,7 +6,7 @@ suffixes = list("playablecolony/colony.dmm") cost = 2 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS | TEMPLATE_FLAG_NO_RADS - ruin_tags = RUIN_HUMAN|RUIN_HABITAT + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_HABITAT apc_test_exempt_areas = list( /area/map_template/colony/mineralprocessing = NO_SCRUBBER|NO_VENT ) diff --git a/maps/random_ruins/exoplanet_ruins/radshrine/radshrine.dm b/maps/random_ruins/exoplanet_ruins/radshrine/radshrine.dm index 5eb4a77c89b..4235d7fcea7 100644 --- a/maps/random_ruins/exoplanet_ruins/radshrine/radshrine.dm +++ b/maps/random_ruins/exoplanet_ruins/radshrine/radshrine.dm @@ -9,4 +9,4 @@ suffixes = list("radshrine/radshrine.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN|RUIN_HABITAT \ No newline at end of file + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_HABITAT \ No newline at end of file diff --git a/maps/random_ruins/exoplanet_ruins/spider_nest/spider_nest.dm b/maps/random_ruins/exoplanet_ruins/spider_nest/spider_nest.dm index 6560327c69d..dca18492f4a 100644 --- a/maps/random_ruins/exoplanet_ruins/spider_nest/spider_nest.dm +++ b/maps/random_ruins/exoplanet_ruins/spider_nest/spider_nest.dm @@ -4,4 +4,4 @@ suffixes = list("spider_nest/spider_nest.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_HUMAN + template_tags = TEMPLATE_TAG_HUMAN diff --git a/maps/random_ruins/exoplanet_ruins/tar_anomaly/tar_anomaly.dm b/maps/random_ruins/exoplanet_ruins/tar_anomaly/tar_anomaly.dm index 46b9a336898..9f2637a18ee 100644 --- a/maps/random_ruins/exoplanet_ruins/tar_anomaly/tar_anomaly.dm +++ b/maps/random_ruins/exoplanet_ruins/tar_anomaly/tar_anomaly.dm @@ -4,4 +4,4 @@ suffixes = list("tar_anomaly/tar_anomaly.dmm") cost = 1 template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS|TEMPLATE_FLAG_NO_RUINS - ruin_tags = RUIN_ALIEN \ No newline at end of file + template_tags = TEMPLATE_TAG_ALIEN \ No newline at end of file diff --git a/maps/random_ruins/space_ruins/multi_zas_test.dmm b/maps/random_ruins/space_ruins/multi_zas_test.dmm index 3beee73fb9d..787f02b7aae 100644 --- a/maps/random_ruins/space_ruins/multi_zas_test.dmm +++ b/maps/random_ruins/space_ruins/multi_zas_test.dmm @@ -10,7 +10,7 @@ /turf/simulated/floor, /area/template_noop) "d" = ( -/turf/simulated/open, +/turf/open, /area/template_noop) "e" = ( /turf/unsimulated/floor/shuttle_ceiling, diff --git a/maps/tether/atoms/areas.dm b/maps/tether/atoms/areas.dm index d3ad95030b2..d6bc19db836 100644 --- a/maps/tether/atoms/areas.dm +++ b/maps/tether/atoms/areas.dm @@ -396,7 +396,7 @@ name = "Outside - Surface" sound_env = MOUNTAINS area_flags = AREA_FLAG_EXTERNAL | AREA_FLAG_IS_NOT_PERSISTENT | AREA_FLAG_IS_BACKGROUND | AREA_FLAG_HIDE_FROM_HOLOMAP - is_outside = TRUE + is_outside = OUTSIDE_YES /area/tether/surfacebase/outside/outside1 icon_state = "outside1" /area/tether/surfacebase/outside/outside2 diff --git a/maps/tether/atoms/kink.dm b/maps/tether/atoms/kink.dm index ba010fe579e..a75ee823265 100644 --- a/maps/tether/atoms/kink.dm +++ b/maps/tether/atoms/kink.dm @@ -109,7 +109,7 @@ if(!jingled) usr.audible_message("[usr] jingles \the [src]'s bell.", SPAN_NOTICE("You jingle \the [src]'s bell."), "[usr] plays with \the [src]'s bell.") jingled = TRUE - addtimer(CALLBACK(src, .proc/jingledreset), 5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(jingledreset)), 5 SECONDS) return /obj/item/clothing/accessory/collar/bell/proc/jingledreset() diff --git a/maps/tether/atoms/props.dm b/maps/tether/atoms/props.dm index 2fc1e0b8176..2813e537afb 100644 --- a/maps/tether/atoms/props.dm +++ b/maps/tether/atoms/props.dm @@ -23,7 +23,7 @@ icon_state = "pill4" /obj/item/chems/pill/tox/populate_reagents() - reagents.add_reagent(/decl/material/liquid/bromide, 15) + add_to_reagents(/decl/material/liquid/bromide, 15) //"Red" Armory Door /obj/machinery/door/airlock/security/armory diff --git a/maps/tether/atoms/reagents.dm b/maps/tether/atoms/reagents.dm index 264a5d968ed..f6f13cc0eda 100644 --- a/maps/tether/atoms/reagents.dm +++ b/maps/tether/atoms/reagents.dm @@ -2,4 +2,5 @@ desc = "A small bottle of tramadol, an effective but dangerous and addictive painkiller. Do not mix with alcohol." /obj/item/chems/glass/bottle/tramadol/populate_reagents() - reagents.add_reagent(/decl/material/liquid/painkillers/strong, reagents.maximum_volume) \ No newline at end of file + add_to_reagents(/decl/material/liquid/painkillers/strong, reagents.maximum_volume) + . = ..() \ No newline at end of file diff --git a/maps/tether/atoms/unimplemented/books.dm b/maps/tether/atoms/unimplemented/books.dm index 54c674ecb61..71c197371f0 100644 --- a/maps/tether/atoms/unimplemented/books.dm +++ b/maps/tether/atoms/unimplemented/books.dm @@ -1,2 +1,5 @@ -/obj/item/book/manual/command_guide -/obj/item/book/manual/standard_operating_procedure \ No newline at end of file +/obj/item/book/fluff/command_guide + fluff_text = "todo: write the guide to command" + +/obj/item/book/fluff/standard_operating_procedure + fluff_text = "todo: write the Standard Operating Procedure" \ No newline at end of file diff --git a/maps/tether/atoms/unimplemented/stubs.dm b/maps/tether/atoms/unimplemented/stubs.dm index 381c6c028aa..567240524ca 100644 --- a/maps/tether/atoms/unimplemented/stubs.dm +++ b/maps/tether/atoms/unimplemented/stubs.dm @@ -1,5 +1,6 @@ // resleeving and transcore -/obj/item/book/manual/resleeving +/obj/item/book/fluff/resleeving + fluff_text = "todo: write resleeving guide" /obj/item/implanter/backup /obj/item/implant/backup diff --git a/maps/tether/datums/jobs/assistant.dm b/maps/tether/datums/jobs/assistant.dm index 3127865a7ac..0944ca86ae7 100644 --- a/maps/tether/datums/jobs/assistant.dm +++ b/maps/tether/datums/jobs/assistant.dm @@ -11,7 +11,7 @@ timeoff_factor = 0 /datum/job/visitor/get_access() - if(config.assistant_maint) + if(get_config_value(/decl/config/toggle/assistant_maint)) return list(access_maint_tunnels) else return list() diff --git a/maps/tether/datums/jobs/offduty.dm b/maps/tether/datums/jobs/offduty.dm index 92ab22de703..4e0dd28b4dc 100644 --- a/maps/tether/datums/jobs/offduty.dm +++ b/maps/tether/datums/jobs/offduty.dm @@ -14,7 +14,7 @@ outfit_type = /decl/hierarchy/outfit/job/generic/assistant /datum/job/offduty/get_access() - if(config.assistant_maint) + if(get_config_value(/decl/config/toggle/assistant_maint)) return list(access_maint_tunnels) else return list() diff --git a/maps/tether/icons/lobby/orbital.gif b/maps/tether/icons/lobby/orbital.gif new file mode 100644 index 00000000000..d03128c96c3 Binary files /dev/null and b/maps/tether/icons/lobby/orbital.gif differ diff --git a/maps/tether/main_dmms/tether-01-surface1.dmm b/maps/tether/main_dmms/tether-01-surface1.dmm index 5cb57bdf29e..564f6b98b0c 100644 --- a/maps/tether/main_dmms/tether-01-surface1.dmm +++ b/maps/tether/main_dmms/tether-01-surface1.dmm @@ -1978,7 +1978,7 @@ /obj/effect/floor_decal/corner/brown/bordercorner2{ dir = 9 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) "adT" = ( @@ -4123,7 +4123,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6014,8 +6014,8 @@ /area/vacant/vacant_site) "alc" = ( /obj/structure/table, -/obj/item/storage/fancy/crayons, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /turf/simulated/floor/tiled, /area/storage/art) "ald" = ( @@ -6100,7 +6100,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6110,7 +6110,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6123,7 +6123,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6413,14 +6413,14 @@ /obj/structure/railing/mapped{ dir = 8 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, /turf/simulated/floor/pool, /area/tether/surfacebase/atrium_one) "alS" = ( -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6430,7 +6430,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -7080,7 +7080,7 @@ /area/tether/surfacebase/atrium_one) "anm" = ( /obj/structure/railing/mapped, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -9214,7 +9214,7 @@ dir = 1; pixel_y = 28 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/engineering/atmos) "arE" = ( @@ -9295,7 +9295,7 @@ dir = 8 }, /obj/structure/railing/mapped, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -9306,7 +9306,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -11561,7 +11561,7 @@ dir = 1 }, /obj/structure/table/steel_reinforced, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/security/checkpoint) "avU" = ( @@ -32085,7 +32085,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/triage) "pQI" = ( diff --git a/maps/tether/main_dmms/tether-02-surface2.dmm b/maps/tether/main_dmms/tether-02-surface2.dmm index 17a18d5debe..70b25d41bfa 100644 --- a/maps/tether/main_dmms/tether-02-surface2.dmm +++ b/maps/tether/main_dmms/tether-02-surface2.dmm @@ -3,7 +3,7 @@ /turf/unsimulated/wall/planetary/virgo3b, /area/tether/surfacebase/outside/outside2) "ab" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "ac" = ( /turf/exterior/wall, @@ -377,7 +377,7 @@ dir = 1 }, /obj/machinery/vending/cigarette{ - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining) @@ -1053,11 +1053,11 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "cJ" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "cK" = ( /turf/simulated/floor, @@ -1280,7 +1280,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "dj" = ( /obj/structure/catwalk, @@ -1290,7 +1290,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "dk" = ( /obj/effect/floor_decal/rust, @@ -1339,7 +1339,7 @@ dir = 1 }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/north) "dq" = ( /obj/structure/catwalk, @@ -1541,7 +1541,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "dP" = ( /obj/structure/cable{ @@ -1570,7 +1570,7 @@ /area/maintenance/lower/north) "dS" = ( /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/north) "dT" = ( /obj/effect/floor_decal/rust, @@ -2330,7 +2330,7 @@ /area/maintenance/lower/bar) "fw" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/bar) "fx" = ( /obj/structure/catwalk, @@ -2339,7 +2339,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/supply, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/bar) "fy" = ( /obj/structure/railing/mapped{ @@ -2462,7 +2462,7 @@ /obj/machinery/atmospherics/pipe/simple/visible/supply, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/bar) "fO" = ( /obj/structure/railing/mapped{ @@ -2639,7 +2639,7 @@ /obj/machinery/atmospherics/pipe/simple/visible/supply, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers, /obj/structure/disposalpipe/segment, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/bar) "gd" = ( /obj/effect/floor_decal/techfloor{ @@ -2690,13 +2690,13 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gj" = ( /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gk" = ( /obj/structure/railing/mapped{ @@ -2705,7 +2705,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gl" = ( /obj/effect/floor_decal/borderfloor{ @@ -2779,7 +2779,7 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/north) "gt" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_staires_two) "gu" = ( /obj/effect/floor_decal/rust, @@ -2789,16 +2789,16 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gw" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gx" = ( /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "gy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -2928,7 +2928,7 @@ dir = 8; pixel_x = 29 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_staires_two) "gQ" = ( /obj/structure/stairs/long/north, @@ -3012,7 +3012,7 @@ dir = 4; pixel_x = -22 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_staires_two) "hb" = ( /turf/simulated/wall, @@ -3025,7 +3025,7 @@ dir = 1; pixel_x = -32 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_staires_two) "hf" = ( /turf/simulated/floor/tiled, @@ -3842,7 +3842,7 @@ dir = 4 }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/rnd) "iS" = ( /obj/effect/decal/cleanable/dirt, @@ -4924,7 +4924,7 @@ pixel_x = -32; dir = 4 }, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/rnd) "ls" = ( /turf/simulated/shuttle/wall/voidcraft/green{ @@ -5238,18 +5238,18 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "lV" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "lW" = ( /obj/structure/railing/mapped{ dir = 4 }, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "lX" = ( /obj/structure/catwalk, @@ -7683,22 +7683,22 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "qx" = ( /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "qy" = ( -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "qz" = ( /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "qA" = ( /obj/structure/bed/chair/comfy, @@ -7872,7 +7872,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "qV" = ( /obj/structure/table/glass, @@ -9104,7 +9104,7 @@ /turf/simulated/wall, /area/engineering/atmos/monitoring) "tu" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/east_stairs_two) "tv" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -9240,7 +9240,7 @@ /area/rnd/breakroom) "tK" = ( /obj/abstract/level_data_spawner/virgo3b/main/mid, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside2) "tL" = ( /obj/effect/floor_decal/borderfloor{ @@ -11096,7 +11096,7 @@ icon_state = "32-1" }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/asmaint2) "xl" = ( /obj/effect/floor_decal/techfloor{ @@ -11827,7 +11827,7 @@ dir = 4; pixel_x = 24 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/janitor) "yD" = ( @@ -11872,7 +11872,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "yK" = ( /obj/structure/cable/cyan{ @@ -12128,7 +12128,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "zh" = ( /obj/machinery/light_switch{ @@ -12233,7 +12233,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "zn" = ( /obj/structure/railing/mapped{ @@ -12690,7 +12690,7 @@ pixel_y = 7 }, /obj/item/pen, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/engineering/atmos/monitoring) "An" = ( @@ -13370,16 +13370,16 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "BQ" = ( -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "BR" = ( /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "BS" = ( /obj/machinery/atmospherics/unary/vent_pump/on, @@ -13629,14 +13629,14 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CA" = ( /obj/structure/railing/mapped, /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CB" = ( /obj/structure/railing/mapped, @@ -13672,14 +13672,14 @@ /area/engineering/atmos) "CG" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CH" = ( /obj/structure/railing/mapped, /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CI" = ( /obj/machinery/atmospherics/pipe/simple/hidden/cyan{ @@ -13711,14 +13711,14 @@ /area/maintenance/lower/south) "CM" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CN" = ( /obj/structure/railing/mapped, /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "CO" = ( /obj/structure/closet, @@ -13835,19 +13835,19 @@ dir = 1; pixel_y = -22 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "De" = ( /obj/structure/catwalk, /obj/machinery/camera/network/engineering{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "Df" = ( /obj/structure/catwalk, /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/engineering/atmos) "Dg" = ( /obj/structure/rack, @@ -16161,7 +16161,7 @@ }, /obj/structure/sign/poster{ pixel_x = 32; - dir = 4 + dir = 8 }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_two) @@ -16373,10 +16373,10 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/maintenance/lower/atmos) "Jo" = ( -/turf/simulated/open, +/turf/open, /area/maintenance/lower/atmos) "Jp" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -16968,7 +16968,7 @@ }, /obj/structure/sign/poster{ pixel_x = -32; - dir = 8 + dir = 4 }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_two) @@ -16995,7 +16995,7 @@ /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/atrium_two) "Nf" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/public_garden_two) "Nq" = ( /obj/structure/table/bench/steel, @@ -17190,9 +17190,6 @@ }, /turf/simulated/floor/tiled, /area/tcommsat/computer) -"Qb" = ( -/turf/exterior/open, -/area/tether/surfacebase/outside/outside2) "Qn" = ( /obj/machinery/network/router/lighthouse, /turf/simulated/floor/bluegrid{ @@ -17301,7 +17298,7 @@ /area/engineering/atmos/storage) "Sn" = ( /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_two) "Sr" = ( /obj/machinery/alarm{ @@ -17605,7 +17602,7 @@ /area/tcommsat/computer) "Wh" = ( /obj/structure/table/glass, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/rnd/breakroom) "Wr" = ( @@ -19136,19 +19133,19 @@ aa aa aa aa -Qb +ab aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aa aa @@ -19217,143 +19214,143 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab tK aa YY @@ -19373,144 +19370,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -19529,144 +19526,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -19685,2484 +19682,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(13,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(14,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(15,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(16,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(17,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(18,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(19,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(20,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(21,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(22,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(23,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(24,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(25,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(26,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(27,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -Qb -ac -ac -Qb -Qb -Qb -Qb -Qb -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -22172,7 +19829,7 @@ XT XT XT "} -(28,1,1) = {" +(13,1,1) = {" XT XT XT @@ -22181,24 +19838,6 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab @@ -22207,118 +19846,136 @@ ab ab ab ab -ac -ac -Qb -Qb -Qb -Qb -cI -cI -cI -cI -cI -Qb -Qb -Qb -Qb -Qb -Qb -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -22328,7 +19985,7 @@ XT XT XT "} -(29,1,1) = {" +(14,1,1) = {" XT XT XT @@ -22337,24 +19994,6 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab @@ -22363,119 +20002,137 @@ ab ab ab ab -ac -ac -ac -ac -ac -cD -cJ -cJ -di -di -cJ -cD -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa YY XT XT @@ -22484,7 +20141,7 @@ XT XT XT "} -(30,1,1) = {" +(15,1,1) = {" XT XT XT @@ -22493,144 +20150,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab ab ab -ac -ac -ac -ac -ac -ac -ac -ac -cD -cK -cV ab ab -dO -cD -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -22640,7 +20297,7 @@ XT XT XT "} -(31,1,1) = {" +(16,1,1) = {" XT XT XT @@ -22649,144 +20306,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab ab ab -ac -ac -ac -ac -ac -ac -ac -ac -cD -cL -cK -dj -dj -cJ -cD -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -22796,7 +20453,7 @@ XT XT XT "} -(32,1,1) = {" +(17,1,1) = {" XT XT XT @@ -22805,300 +20462,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab ab ab -ac -ac -ac -ac -ac -ac -ac -ac -cD -cL -cV -cK -dv -cD -cD -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(33,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab ab ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -cD -cD -cD -cD -cD -cD -cD -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -23108,7 +20609,7 @@ XT XT XT "} -(34,1,1) = {" +(18,1,1) = {" XT XT XT @@ -23117,144 +20618,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -23264,7 +20765,7 @@ XT XT XT "} -(35,1,1) = {" +(19,1,1) = {" XT XT XT @@ -23273,300 +20774,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(36,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -23576,7 +20921,7 @@ XT XT XT "} -(37,1,1) = {" +(20,1,1) = {" XT XT XT @@ -23585,144 +20930,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -23732,7 +21077,7 @@ XT XT XT "} -(38,1,1) = {" +(21,1,1) = {" XT XT XT @@ -23741,25 +21086,3339 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(22,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(23,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(24,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(25,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(26,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(27,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ac +ac +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(28,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +cI +cI +cI +cI +cI +ab +ab +ab +ab +ab +ab +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(29,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +cD +cJ +cJ +di +di +cJ +cD +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(30,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +cD +cK +cV +ab +ab +dO +cD +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(31,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +cD +cL +cK +dj +dj +cJ +cD +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(32,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +cD +cL +cV +cK +dv +cD +cD +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(33,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +cD +cD +cD +cD +cD +cD +cD +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(34,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(35,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(36,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(37,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(38,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(39,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(40,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Kt +Kt +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(41,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Kt +MX +SS +Kt +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(42,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Kt +Na +Nq +Zo +YN +Kt +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ac ac ac @@ -23791,94 +24450,524 @@ ac ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(43,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Kt +AN +LG +Uh +Uh +HV +YP +Kt +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(44,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Kt +TV +PC +Qr +YE +YH +KL +HV +OG +Kt +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac jM jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(45,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +Kt +Xf +Nq +Uh +PP +Rl +NZ +SH +Qz +HV +HT +Kt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -23888,7 +24977,7 @@ XT XT XT "} -(39,1,1) = {" +(46,1,1) = {" XT XT XT @@ -23897,34 +24986,23 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -23934,6 +25012,18 @@ ac ac ac ac +Kt +SE +Qu +Uh +Kj +Nf +Nf +IT +Qz +Zt +VM +Kt ac ac ac @@ -23984,57 +25074,56 @@ ac ac jM jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24044,7 +25133,7 @@ XT XT XT "} -(40,1,1) = {" +(47,1,1) = {" XT XT XT @@ -24053,27 +25142,23 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24085,6 +25170,14 @@ ac ac Kt Kt +Xd +KL +OL +Po +Yq +Zp +Wr +IC Kt Kt ac @@ -24106,91 +25199,87 @@ ac ac ac ac +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka +ka ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24200,7 +25289,7 @@ XT XT XT "} -(41,1,1) = {" +(48,1,1) = {" XT XT XT @@ -24209,26 +25298,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24240,8 +25327,12 @@ ac ac Kt Kt -MX -SS +UB +Kn +IE +Uh +Zt +Qt Kt Kt ac @@ -24252,12 +25343,135 @@ ac ac ac ac +hb +hb +hb +hb +hb +hb +hb +hb +hb +hb +hb ac ac +kp +kI +VX +lg +kT +kT +kT +kT +kT +oi +oY +oY +VX +rj +kT +sM +tC +VX +ve +VX +kT +kT +xJ +yo +ka ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(49,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24268,6 +25482,14 @@ ac ac ac ac +Kt +Kt +ZT +Vk +Zt +ZF +Kt +Kt ac ac ac @@ -24277,76 +25499,99 @@ ac ac ac ac +hb +Kg +gO +gO +gO +Kg +gO +gO +gO +Kg +hb ac ac ac +kJ +kU +kU +lz +kJ +kJ +nh +kJ +kJ +kJ +lY +kJ +kJ +rT +La +lz +kJ +kJ +kJ +kJ +lY +kJ +yp +ka ac ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24356,7 +25601,7 @@ XT XT XT "} -(42,1,1) = {" +(50,1,1) = {" XT XT XT @@ -24365,24 +25610,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac @@ -24395,10 +25641,8 @@ ac ac Kt Kt -Na -Nq -Zo -YN +Xk +WO Kt Kt ac @@ -24411,12 +25655,135 @@ ac ac ac ac +hb +xO +gO +CE +gO +gO +gO +CQ +gO +Je +hb ac ac +kd +kJ +kJ +kJ +lA +lY +kJ +kJ +kJ +kJ +kJ +nh +kJ +kJ +lA +kJ +lA +kJ +kJ +kJ +kJ +nh +kJ +On +ka ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(51,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24429,6 +25796,11 @@ ac ac ac ac +QD +OQ +QD +QD +QD ac ac ac @@ -24439,70 +25811,99 @@ ac ac ac ac +hb +xO +xO +gO +gO +CQ +gO +vn +gO +gO +hb ac ac +kr +kX +SC +lh +lB +SC +mE +ni +nO +oj +kV +SC +qt +YL +rU +kV +tD +uk +vf +vU +ws +kJ +xK +On +ka ac ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24512,7 +25913,7 @@ XT XT XT "} -(43,1,1) = {" +(52,1,1) = {" XT XT XT @@ -24521,24 +25922,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24548,19 +25949,14 @@ ac ac ac ac -Kt -Kt -AN -LG -Uh -Uh -HV -YP -Kt -Kt ac ac ac +QD +UX +IB +Mf +QD ac ac ac @@ -24571,12 +25967,134 @@ ac ac ac ac +hb +gO +xO +gO +Kk +yv +Kk +xm +Kg +gO +hb ac +cD +kq +ka +ka ac +lm +lm +lm +lm +lm +lm +lm +lm +lm +ka +ka +ka +ka +ka +ka +ka +ka +xj +ka +ka +ka ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(53,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24590,6 +26108,11 @@ ac ac ac ac +QD +Xx +QM +Rc +QD ac ac ac @@ -24600,65 +26123,99 @@ ac ac ac ac +hb +hF +vk +wA +vl +yw +yw +vl +ww +Ku +hb ac +VC +jF +il ac ac +lm +lH +mg +nn +nP +os +pc +pN +lm +qK +wG +rv +qK +qL +ka +ka +ka +uz +ka ac ac ac ac ac ac -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24668,7 +26225,7 @@ XT XT XT "} -(44,1,1) = {" +(54,1,1) = {" XT XT XT @@ -24677,25 +26234,23 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24703,32 +26258,63 @@ ac ac ac ac -Kt -Kt -TV -PC -Qr -YE -YH -KL -HV -OG -Kt -Kt ac ac ac +ae +ae +ae +ae +Sv +ae +ae +ae +ae +ae +ae +ae ac ac ac ac ac ac +hb +vg +vl +vl +vl +Kr +DB +vl +ww +yY +hb ac ac +il ac ac ac +lm +lI +mF +no +nQ +ot +pd +pO +lm +qL +rq +wG +wG +wG +sX +tE +us +xk +ka ac ac ac @@ -24736,6 +26322,91 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(55,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -24746,16 +26417,60 @@ ac ac ac ac +ae +bz +bX +cm +ZO +bX +cm +bX +bX +dP +eg +ae ac ac ac ac ac ac +hb +xp +vl +wv +vl +yw +yw +vl +ww +xO +hb ac +iw +il ac ac ac +lm +lZ +mH +np +nR +ou +nR +pP +lm +wG +wG +wG +wG +rq +ka +tF +ka +ka +ka ac ac ac @@ -24764,57 +26479,55 @@ ac ac ac ac -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +vW +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24824,7 +26537,7 @@ XT XT XT "} -(45,1,1) = {" +(56,1,1) = {" XT XT XT @@ -24833,68 +26546,85 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Kt -Xf -Nq -Uh -PP -Rl -NZ -SH -Qz -HV -HT -Kt -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ae +ae +ae +ae +ae +ae +bA +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae ac ac ac ac ac ac +hb +Ki +vl +yu +vl +vl +vl +vl +ww +Kz +hb ac +iw +il ac ac ac +lm +ma +mI +nq +nS +oy +pe +pQ +lm +qM +qK +wG +rB +wG +ka +tG +ka ac ac ac @@ -24905,11 +26635,152 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(57,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ae +ak +at +aI +aR +bn +bB +bY +cn +bo +cM +ae +cW +cW +cW +cW +cW +cW +cW +cW +cW +ap +ap +hb +xP +vl +ww +xn +Cw +yD +xn +Kf +gO +hb ac +iw +il +ks +ks +ks +lm +lm +lm +nr +lm +lm +pf +lm +lm +nD +nD +nD +rM +qL +ka +tH +ka ac ac ac @@ -24921,56 +26792,54 @@ ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -24980,7 +26849,7 @@ XT XT XT "} -(46,1,1) = {" +(58,1,1) = {" XT XT XT @@ -24989,144 +26858,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Kt -SE -Qu -Uh -Kj -Nf -Nf -IT -Qz -Zt -VM -Kt -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ae +al +au +aJ +aR +bo +bB +bo +co +bo +cM +ae +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +ap +hb +xP +vl +ww +gO +CT +hn +gO +CQ +xO +hb ac ac +kb +ks +kt +li +lC +mb +nj +lj +nT +oz +pg +pR +qv +pV +rr +nD +rV +ka +ka +wx +ka +ka +ka +ka +ka +ka +ka +ka +ka ac -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25136,7 +27005,7 @@ XT XT XT "} -(47,1,1) = {" +(59,1,1) = {" XT XT XT @@ -25145,144 +27014,300 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Kt -Kt -Xd -KL -OL -Po -Yq -Zp -Wr -IC -Kt -Kt -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +ae +am +av +aK +aR +bo +bB +bo +cp +ae +ae +ae +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +hb +Kh +vl +xQ +xm +xm +xm +xm +xO +gO +hb ac +il +il +ks +kK +lj +lD +mc +lj +lj +nY +oz +ph +pS +pV +pV +rr +nD +rW +sr +sZ +wy +vV +vV +xL +vV +vV +vV +zI +Ah +ka ac +LI +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(60,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ae +ae +ae +ae +ae +bp +bB +bo +bo +cE +cN +ae +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +hb +xP +vl +gK +wB +wB +xr +wB +Kw +vn +hb ac -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka -ka +il +iw +ks +kK +lj +lE +md +nk +ns +ok +oS +pi +pV +qw +qU +qU +nD +rX +ss +tb +wz +wz +uA +xM +xl +xl +xl +zJ +Ai ka ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +LI +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25292,7 +27317,7 @@ XT XT XT "} -(48,1,1) = {" +(61,1,1) = {" XT XT XT @@ -25301,43 +27326,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Kt -Kt -UB -Kn -IE -Uh -Zt -Qt -Kt -Kt +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -25346,99 +27352,118 @@ ac ac ac ac +ae +bq +bC +bZ +cq +cF +cO +ae +cW +cW +cW +cW +cW +cW +cW +cW +cW +cW +ap hb -hb -hb -hb -hb -hb -hb -hb -hb -hb +xP +vl +gK +wB +wB +wB +wB +Kq +gO hb ac -ac -kp -kI -VX -lg -kT -kT -kT -kT -kT -oi -oY -oY -VX -rj -kT -sM -tC -VX -ve -VX -kT -kT -xJ -yo +iw +iw +ks +kZ +lj +lF +me +nl +nt +ol +oz +pj +pW +qx +qy +qy +nD +rX +sN +ql +ql +ql +ql +ql +ql +ql +ka +ka +AQ ka ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +LI +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25448,7 +27473,7 @@ XT XT XT "} -(49,1,1) = {" +(62,1,1) = {" XT XT XT @@ -25457,43 +27482,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Kt -Kt -ZT -Vk -Zt -ZF -Kt -Kt -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -25502,99 +27508,118 @@ ac ac ac ac +ae +ae +ae +ae +ae +ae +ae +ae +cW +cW +cW +dx +cW +cW +cW +cW +cW +cW +cW hb -Kg -gO -gO -gO -Kg -gO -gO -gO -Kg +vj +vl +gL +wE +wE +wE +wE +Kq +Kc hb ac ac -ac -kJ -kU -kU -lz -kJ -kJ -nh -kJ -kJ -kJ -lY -kJ -kJ -rT -La -lz -kJ -kJ -kJ -kJ -lY -kJ -yp +il +ks +la +ll +lG +mf +nm +nu +om +oz +pk +pV +qy +qy +qy +nD +rY +sO +ql +tI +ue +uq +ut +uw +ql +zV +Au +AR ka +yT +BM +BM +yT +BM +BM +yT ac ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25604,7 +27629,7 @@ XT XT XT "} -(50,1,1) = {" +(63,1,1) = {" XT XT XT @@ -25613,41 +27638,29 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -Kt -Kt -Xk -WO -Kt -Kt ac ac ac @@ -25658,99 +27671,111 @@ ac ac ac ac +cW +cW +cW +dQ +dx +dx +dx +cW +cW +cW +cW +cW hb -xO -gO -CE -gO -gO -gO -CQ -gO -Je +BT +hr +wF +JX +Ks +IP +IP +JX +Kv hb ac -ac -kd -kJ -kJ -kJ -lA -lY -kJ -kJ -kJ -kJ -kJ -nh -kJ -kJ -lA -kJ -lA -kJ -kJ -kJ -kJ -nh -kJ -On -ka -ac -ac +cD +kc +ks +ks +ks +ks +ks +ks +ks +ks +ks +pB +pX +qz +qy +qy +nD +rX +sP +ql +tJ +ul +uq +ql +ql +ql +zW +Av +AS +Bk +Bx +BN +Ca +Cr +CD +vP +yT ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25760,7 +27785,7 @@ XT XT XT "} -(51,1,1) = {" +(64,1,1) = {" XT XT XT @@ -25769,41 +27794,29 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac -QD -OQ -QD -QD -QD ac ac ac @@ -25814,99 +27827,111 @@ ac ac ac ac +cW +cW +cW +dx +dx +dx +eU +dx +cW +cW +cW +ap hb -xO -xO -gO -gO -CQ -gO -vn -gO -gO +xo +wu +Jp +Cs +xp +IQ +IQ +Kq +Ke hb ac -ac -kr -kX -SC -lh -lB -SC -mE -ni -nO -oj -kV -SC -qt -YL -rU -kV -tD -uk -vf -vU -ws -kJ -xK -On +ii +kW +kL +il +ln +lJ +mG +mJ +nD +nD +nD +pH +ql +ql +ql +ql +ql +rZ +ql +ql +uq +um +uq +uu +ux +ql +zX +Aw ka +ka +yT +BO +Cb +vq +zM +CR +yT ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -25916,7 +27941,7 @@ XT XT XT "} -(52,1,1) = {" +(65,1,1) = {" XT XT XT @@ -25925,41 +27950,29 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -QD -UX -IB -Mf -QD ac ac ac @@ -25970,99 +27983,111 @@ ac ac ac ac +ap +cW +dw +dR +eh +dx +dx +dx +cW +cW +cW +cW hb -gO +xS +CB +Jp +vn +Kl +wB +wB +Kq xO -gO -Kk -yv -Kk -xm -Kg -gO hb -ac -cD -kq -ka +jy +ii +il +il +il +ln +lK +mh +mK +nD +on +oT +pI +ql +qA +qV +rs +rw +sa +sQ +ql +uq +un +ql +ql +ql +ql +zW +Ax ka ac -lm -lm -lm -lm -lm -lm -lm -lm -lm -ka -ka -ka -ka -ka -ka -ka -ka -xj -ka -ka -ka +yT +BS +Cc +Cv +zM +CS +yT +ac ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -26072,7 +28097,7 @@ XT XT XT "} -(53,1,1) = {" +(66,1,1) = {" XT XT XT @@ -26081,41 +28106,29 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -QD -Xx -QM -Rc -QD ac ac ac @@ -26126,99 +28139,111 @@ ac ac ac ac +cW +cW +dx +dx +dx +eB +dx +dx +cW +cW +cW +cW hb -hF -vk -wA -vl -yw -yw -vl -ww -Ku +ys +hE +JS +gO +Kl +wB +IU +Bo +xO hb -ac -VC -jF +ii +ke il -ac -ac -lm -lH -mg -nn -nP -os -pc -pN -lm -qK -wG -rv -qK -qL -ka -ka -ka -uz +il +il +ln +lL +mi +mL +nD +oo +oU +pJ +ql +qB +qX +qH +qH +sb +sR +tc +tO +uo +ur +uq +uy +ql +zY +Ay ka ac +yT +vp +Cd +vN +vO +vQ +yT +ac +ac ac ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -26228,7 +28253,7 @@ XT XT XT "} -(54,1,1) = {" +(67,1,1) = {" XT XT XT @@ -26237,25 +28262,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -26264,117 +28289,117 @@ ac ac ac ac -ae -ae -ae -ae -Sv -ae -ae -ae -ae -ae -ae -ae ac ac ac ac ac ac +cW +cW +dx +dx +dx +dx +dx +cW +cW +cW +cW +cW hb -vg -vl -vl -vl -Kr -DB -vl +Kg +xR +Jp +vn +Ky +wB +wB ww -yY +Kg hb -ac -ac +ii +kf +ku il -ac -ac -ac -lm -lI -mF -no -nQ -ot -pd -pO -lm -qL -rq -wG -wG -wG -sX -tE -us -xk +il +ln +lM +ln +mM +nD +op +oZ +pK +qu +qC +rk +rt +ry +sc +sS +ql +tQ +up +ql +uv +uZ +ql +zZ +Az ka +ka +yT +yT +yT +yT +yT +yT +yT +By +By +By +By +By +By ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -26384,7 +28409,7 @@ XT XT XT "} -(55,1,1) = {" +(68,1,1) = {" XT XT XT @@ -26393,25 +28418,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -26420,117 +28445,117 @@ ac ac ac ac -ae -bz -bX -cm -ZO -bX -cm -bX -bX -dP -eg -ae ac ac ac ac ac ac +cW +cW +dx +dx +dx +dx +cW +cW +cW +cW +cW +cW hb -xp -vl -wv -vl -yw -yw -vl -ww -xO hb -ac -iw -il -ac -ac -ac -lm -lZ -mH -np -nR -ou -nR -pP -lm -wG -wG -wG -wG -rq -ka -tF -ka -ka -ka -ac -ac +hC +xq +hC +hb +hb +hb +hb +hb +hb +ii +ii +kv +jN +lb +lp +lN +mj +mN +nJ +oq +pa +pL +ql +qD +rl +qH +qD +se +sT +ql +ql +ql +ql +ql +ql +ql +Aa +AA +zy +Bl +By +BU +Ce +Cx +By +CU +Dk +By +vX +Ee +Ep +Dk +By ac ac ac +ab +ab +ab +ab +ab ac ac ac -Qb -Qb -Qb +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab -vW ab ab ab ab ab ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb aa YY XT @@ -26540,7 +28565,7 @@ XT XT XT "} -(56,1,1) = {" +(69,1,1) = {" XT XT XT @@ -26549,85 +28574,106 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac ac -ae -ae -ae -ae -ae -ae -bA -ae -ae -ae -ae -ae -ae -ae -ae -ae -ae ac ac ac ac ac ac +ac +ac +ac +cW +cW +dx +dS +dx +cW +cW +cW +cW +cW +cW +cW +cW hb -Ki -vl -yu -vl -vl -vl -vl -ww -Kz +JY +yt +JV hb ac -iw -il ac ac ac -lm -ma -mI -nq -nS -oy -pe -pQ -lm -qM -qK +ac +ac +ii +kw +jx +lc +lc +lO +lc +mO +nK +or +pb +pM +ql +qE +rl +qH +qD +sg +sU +td +ql wG -rB +xz +yE +yZ +zy wG -ka -tG -ka +AB +AT +Bm +By +BV +BV +BU +By +CV +Dl +Dt +Dk +Ef +Eq +HO +By ac ac ac @@ -26638,55 +28684,34 @@ ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +LI +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -26696,7 +28721,7 @@ XT XT XT "} -(57,1,1) = {" +(70,1,1) = {" XT XT XT @@ -26705,40 +28730,39 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ac ac ac ac -ae -ak -at -aI -aR -bn -bB -bY -cn -bo -cM -ae cW cW cW @@ -26748,42 +28772,65 @@ cW cW cW cW -ap -ap +cW +cW +cW +cW hb -xP -vl -ww -xn -Cw -yD -xn -Kf -gO +Kd +JK +Jl hb +ii +ii +ii +ii +ii +ii +ii +kx +jx +lc +lr +lP +mk +mP +lc +ld +ld +cD +ql +qF +rm +ru +rA +sh +sV +sV +tR +wH +xA +yF +za +yF +Ab +AC +AU +AU +Bz +BW +Cf +Cy +By +CW +Dl +By +DC +BU +Er +BU +By ac -iw -il -ks -ks -ks -lm -lm -lm -nr -lm -lm -pf -lm -lm -nD -nD -nD -rM -qL -ka -tH -ka ac ac ac @@ -26795,54 +28842,32 @@ ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +LI +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -26852,7 +28877,7 @@ XT XT XT "} -(58,1,1) = {" +(71,1,1) = {" XT XT XT @@ -26861,40 +28886,39 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac ac ac ac ac -ae -al -au -aJ -aR -bo -bB -bo -co -bo -cM -ae cW cW cW @@ -26905,100 +28929,101 @@ cW cW cW cW -ap +cW +cW +cW hb -xP -vl -ww -gO -CT -hn -gO -CQ -xO +hH +JL +JV hb +ii +iO +je +jw +jw +jN +jN +ky +jy +ld +ls +ls +ls +ls +ls +ls +ld +ac +ql +qG +rn +rn +Wh +rn +qH +tm +ql +wI +xB +wG +yG +yG +yG +AD +yG +yG +yG +BX +Cg +Cy +By +CX +Dm +By +DD +BU +BU +Dk +By +ac +ac +By +By +By +By +By +By +ac ac ac -kb -ks -kt -li -lC -mb -nj -lj -nT -oz -pg -pR -qv -pV -rr -nD -rV -ka -ka -wx -ka -ka -ka -ka -ka -ka -ka -ka -ka ac LI LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27008,7 +29033,7 @@ XT XT XT "} -(59,1,1) = {" +(72,1,1) = {" XT XT XT @@ -27017,40 +29042,41 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac -ae -am -av -aK -aR -bo -bB -bo -cp -ae -ae -ae +ac +ac +ac +ac +ac +ac +ac +ac +cW +cW cW cW cW @@ -27063,98 +29089,97 @@ cW cW cW hb -Kh -vl -xQ -xm -xm -xm -xm -xO -gO +JZ +Kp +Kx hb +ii +iB +jf +jx +jx +jy +jy +jy +jy +ld +ls +lQ +lQ +lQ +lQ +ls +ld ac -il -il -ks -kK -lj -lD -mc -lj -lj -nY -oz -ph -pS -pV -pV -rr -nD -rW -sr -sZ -wy -vV -vV -xL -vV -vV -vV -zI -Ah -ka -ac -LI -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ql +qH +rn +rn +rn +rn +qH +tn +rp +wJ +xC +yG +yG +zz +Ac +AE +AV +Bn +yG +yG +Ch +Cy +By +By +By +By +By +Eg +By +By +By +By +By +By +Cy +II +IN +IV +By +By +By +By +By +By +By +Jz +Jz +By +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27164,7 +29189,7 @@ XT XT XT "} -(60,1,1) = {" +(73,1,1) = {" XT XT XT @@ -27173,40 +29198,41 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -ae -ae -ae -ae -ae -bp -bB -bo -bo -cE -cN -ae +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +cW +cW cW cW cW @@ -27219,98 +29245,97 @@ cW cW cW hb -xP -vl -gK -wB -wB -xr -wB -Kw -vn +wt +yt +ho hb +ii +iP +iT +jx +jy +jy +jy +jy +jy +ld +ls +lQ +lQ +lQ +lQ +ls +ld ac -il -iw -ks -kK -lj -lE -md -nk -ns -ok -oS -pi -pV -qw -qU -qU -nD -rX -ss -tb -wz -wz -uA -xM -xl -xl -xl -zJ -Ai -ka -ac -LI -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ql +qJ +ro +ro +ro +ro +sW +to +rp +wK +xD +yH +zb +zA +Ad +AF +AW +ZE +BA +yG +Ci +Cy +By +Db +Dn +By +DK +BV +BU +By +HY +Ig +Ip +Cy +Cy +Cy +Cy +Cy +BW +Jh +Jm +Ic +Jr +Jv +Jy +Cy +JB +JH +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27320,7 +29345,7 @@ XT XT XT "} -(61,1,1) = {" +(74,1,1) = {" XT XT XT @@ -27329,24 +29354,31 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac ac ac ac @@ -27355,14 +29387,6 @@ ac ac ac ac -ae -bq -bC -bZ -cq -cF -cO -ae cW cW cW @@ -27373,100 +29397,101 @@ cW cW cW cW -ap +cW +cW +cW hb -xP -vl -gK -wB -wB -wB -wB -Kq -gO +JM +yt +ho hb -ac -iw -iw -ks -kZ -lj -lF -me -nl -nt -ol -oz -pj -pW -qx -qy -qy -nD -rX -sN -ql -ql -ql -ql -ql +ii +iP +jf +jx +jy +jy +jy +jy +jy +ld +ls +lQ +lQ +lQ +lQ +ls +ld +cD ql ql -ka -ka -AQ -ka +rp +rp +rp +rp +rp +vW +vW +wL +xN +yH +zc +zB +Ae +AG +AX +vo +BB +yG +Cj +Cy +By +By +By +By +BW +BW +Cy +Bz +Cy +DL +Iq +Cy +Eh +IJ +BX +Ds +BW +Cy +BW +Cy +Js +BW +Cy +Cy +JC +JH ac -LI -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27476,7 +29501,7 @@ XT XT XT "} -(62,1,1) = {" +(75,1,1) = {" XT XT XT @@ -27485,24 +29510,31 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac ac ac ac @@ -27511,18 +29543,12 @@ ac ac ac ac -ae -ae -ae -ae -ae -ae -ae -ae cW cW cW -dx +cW +cW +cW cW cW cW @@ -27531,98 +29557,97 @@ cW cW cW hb -vj -vl -gL -wE -wE -wE -wE -Kq -Kc +vm +JN +JW hb +ii +iP +jg +jy +jy +jy +jy +jy +jy +ld +ls +lQ +lQ +lQ +lQ +ls +dY +oV +pC +qm +qY +rN +st +tp +uB +tN +sw +wM +xT +yI +zd +zC +zC +AH +AY +Br +BC +yG +Ck +BW +BW +BW +Cy +Cy +Cy +Eh +Et +By +By +By +By +By +By +By +By +By +Eg +By +By +By +By +By +By +BW +JD +By ac ac -il -ks -la -ll -lG -mf -nm -nu -om -oz -pk -pV -qy -qy -qy -nD -rY -sO -ql -tI -ue -uq -ut -uw -ql -zV -Au -AR -ka -yT -BM -BM -yT -BM -BM -yT -ac -ac -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27632,7 +29657,7 @@ XT XT XT "} -(63,1,1) = {" +(76,1,1) = {" XT XT XT @@ -27641,25 +29666,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27677,108 +29702,108 @@ ac cW cW cW -dQ -dx -dx -dx -cW -cW -cW cW cW +ap +ap +ap +ap +ap +ap +ap +ap +hb +Jq +Ka hb -BT -hr -wF -JX -Ks -IP -IP -JX -Kv hb +ix +iQ +jh +jy +jy +jy +jy +jy +jy +ld +ls +ls +lQ +lQ +ls +ls +dY +pl +pE +qn +qY +sd +su +tq +uC +vr +wa +wN +xU +yH +ze +zD +Af +Af +Af +zD +BD +yG +BV +Cg +BW +Dc +Ds +BW +Cy +Ei +By +By +HZ +Ih +Ir +Iz +IF +By +By +IW +BU +Ji +Jn +Jo +Jo +Jo +By +JA +BW +By ac -cD -kc -ks -ks -ks -ks -ks -ks -ks -ks -ks -pB -pX -qz -qy -qy -nD -rX -sP -ql -tJ -ul -uq -ql -ql -ql -zW -Av -AS -Bk -Bx -BN -Ca -Cr -CD -vP -yT ac ac -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27788,7 +29813,7 @@ XT XT XT "} -(64,1,1) = {" +(77,1,1) = {" XT XT XT @@ -27797,25 +29822,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27830,111 +29855,111 @@ ac ac ac ac +ap cW cW -cW -dx -dx -dx -eU -dx -cW -cW -cW +dT +ei +eC +eV ap -hb -xo -wu -Jp -Cs -xp -IQ -IQ -Kq -Ke -hb -ac -ii -kW -kL -il -ln -lJ -mG -mJ -nD -nD -nD -pH -ql -ql -ql -ql -ql -rZ -ql -ql -uq -um -uq -uu -ux -ql -zX -Aw -ka -ka -yT -BO -Cb -vq -zM -CR -yT -ac -ac +fP +gd +gs +gF +gZ +hm +Jw +Kb +vh +ij +iy +iR +ji +jy +jy +jy +jy +jy +jy +dY +dY +lR +ml +ml +nw +nU +dY +pm +pF +qo +qY +sf +sv +tr +uD +vs +sw +wO +xV +yH +yH +zE +zE +zE +zE +zE +yH +yG +wJ +wJ +CF +wJ +wJ +BW +Cy +Ej +By +HP +Ia +Ii +Is +BV +BU +IK +By +IX +BV +Jj +Jn +Jo +Jo +Jo +By +Cy +JE +By ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -27944,7 +29969,7 @@ XT XT XT "} -(65,1,1) = {" +(78,1,1) = {" XT XT XT @@ -27952,26 +29977,26 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27988,109 +30013,109 @@ ac ac ap cW -dw -dR -eh -dx -dx -dx -cW -cW -cW -cW -hb -xS -CB -Jp -vn -Kl -wB -wB -Kq -xO -hb -jy +dy +dl +dV +eD +eW +ap +fQ +ge +ge +ge +ge +ge +jv +JO +ge ii -il -il -il -ln -lK -mh -mK -nD -on -oT -pI -ql -qA -qV -rs -rw -sa -sQ -ql -uq -un -ql -ql -ql -ql -zW -Ax -ka -ac -yT -BS -Cc -Cv -zM -CS -yT -ac +iz +iS +jj +jy +jy +jy +jy +jy +jy +jy +dY +lS +mm +mQ +nx +nV +dY +pn +pG +pn +qY +qY +sw +sw +uE +sw +wb +wP +xW +yJ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +Cz +CG +CG +wJ +BW +Cy +Ek +By +HQ +Ia +BV +BU +BU +IG +IL +By +BV +BU +Jk +Jn +Jo +Jo +Jo +By +Cy +JF +By ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -28100,7 +30125,7 @@ XT XT XT "} -(66,1,1) = {" +(79,1,1) = {" XT XT XT @@ -28109,26 +30134,26 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28142,111 +30167,111 @@ ac ac ac ac -cW -cW -dx -dx -dx -eB -dx -dx -cW -cW -cW -cW -hb -ys -hE -JS -gO -Kl -wB -IU -Bo -xO -hb -ii -ke -il -il +ap +dk +dz +dU +dV +eE +eX +ap +fR +ge +gt +gt +ha +hd +jE +JP +ge +ik +iA +iT il -ln -lL -mi -mL -nD -oo -oU -pJ -ql -qB -qX -qH -qH -sb -sR -tc -tO -uo -ur -uq -uy -ql -zY -Ay -ka -ac -yT -vp -Cd -vN -vO -vQ -yT -ac -ac -ac -ac +jz +jy +jy +jy +jy +ii +ii +dY +dY +Tg +fG +hg +nX +nX +po +pT +qp +qZ +si +sx +ts +uF +vt +sC +wQ +xX +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +CM +CG +CG +wJ +BU +BW +Ei +By +HR +Ia +Ij +It +If +BU +IM +By +IZ +Jd +Ji +Jn +Jo +Jo +Jo +By +Cy +JG +By ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -28256,7 +30281,7 @@ XT XT XT "} -(67,1,1) = {" +(80,1,1) = {" XT XT XT @@ -28265,25 +30290,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28298,267 +30323,111 @@ ac ac ac ac -cW -cW -dx -dx -dx -dx -dx -cW -cW -cW -cW -cW -hb -Kg -xR -Jp -vn -Ky -wB -wB -ww -Kg -hb +ap +dl +dz +dV +cc +eF +eX +ap +fR +ge +gt +gt +gP +gt +hp +JQ +ge +il +iB +iU +il +jA +ii +ii +ii +ii ii -kf -ku il il -ln -lM -ln -mM -nD -op -oZ -pK -qu -qC -rk -rt -ry -sc -sS -ql -tQ -up -ql -uv -uZ -ql -zZ -Az -ka -ka -yT -yT -yT -yT -yT -yT -yT +lT +mn +fG +TH +nX +oA +pp +pU +qq +ra +si +sy +xY +uF +vu +sC +wQ +xX +BR +BR +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +CH +CG +wJ +BV +DL By By By +Ib +Ik +Iu +IA +BV By By By -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(68,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -cW -cW -dx -dx -dx -dx -cW -cW -cW -cW -cW -cW -hb -hb -hC -xq -hC -hb -hb -hb -hb -hb -hb -ii -ii -kv -jN -lb -lp -lN -mj -mN -nJ -oq -pa -pL -ql -qD -rl -qH -qD -se -sT -ql -ql -ql -ql -ql -ql -ql -Aa -AA -zy -Bl By -BU -Ce -Cx By -CU -Dk By -vX -Ee -Ep -Dk +By +By +By +By +Cf +Cy By ac ac ac -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -28568,7 +30437,7 @@ XT XT XT "} -(69,1,1) = {" +(81,1,1) = {" XT XT XT @@ -28577,31 +30446,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28610,111 +30473,117 @@ ac ac ac ac -cW -cW -dx -dS -dx -cW -cW -cW -cW -cW -cW -cW -cW -hb -JY -yt -JV -hb ac ac ac ac ac ac -ii -kw -jx -lc -lc -lO -lc -mO -nK -or -pb -pM -ql -qE -rl -qH -qD -sg -sU -td -ql -wG -xz -yE -yZ -zy -wG -AB -AT -Bm -By -BV +ap +dm +dA +cc +cc +eG +eY +ap +fS +ge +ge +ge +ge +ge +hq +hG +ge +im +iB +iV +jk +il +il +il +il +il +il +il +il +dY +mp +fG +Tc +oa +oA +pq +pU +qr +rb +si +sz +tv +uG +vv +sC +wQ +xZ +Bw +zf +yJ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +CM +Dd +wJ BV -BU +Cy +BW +BW By -CV -Dl -Dt -Dk -Ef -Eq -HO +By +By +By +By +If +By +IH +IH +IH +By +Jo +Jo +Jo +Jo +BV +BW +BW By ac ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -28724,7 +30593,7 @@ XT XT XT "} -(70,1,1) = {" +(82,1,1) = {" XT XT XT @@ -28732,26 +30601,26 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28766,111 +30635,111 @@ ac ac ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -Kd -JK -Jl -hb -ii -ii -ii -ii +ap +dn +dA +cc +cc +ap +ap +ap +fT +ge +gu +ge +gQ +hf +vi +JR +ge +il +iC +il +jf ii ii ii -kx -jx -lc -lr -lP -mk -mP -lc -ld -ld -cD -ql -qF -rm -ru -rA -sh -sV -sV -tR -wH -xA -yF -za -yF -Ab -AC -AU -AU -Bz -BW -Cf +dY +dY +dY +dY +dY +dY +mq +mR +nB +oa +oA +pr +pU +qs +ra +si +sA +tw +uH +vw +sC +wR +ya +yK +zg +yJ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +BQ +CM +CG +wJ +BU +DM Cy +Cy +HS +Ic +Il +Iv By -CW -Dl +BV By -DC -BU -Er -BU +IH +IH +IH +By +Jo +Jo +Jo +Jo +BV +Cy +BW By ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -28880,7 +30749,7 @@ XT XT XT "} -(71,1,1) = {" +(83,1,1) = {" XT XT XT @@ -28888,32 +30757,26 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28922,111 +30785,117 @@ ac ac ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -hH -JL -JV -hb +ap +ap +ap +ap +ap +ap +ap +dn +dB +dW +ej +eH +eZ +fA +fU +ge +gu +ge +gQ +nZ +hs +hI +hD +il +iD +YI +jf ii -iO -je -jw -jw -jN -jN -ky -jy -ld -ls -ls -ls -ls -ls -ls -ld -ac -ql -qG -rn -rn -Wh -rn -qH -tm -ql -wI -xB -wG -yG -yG -yG -AD -yG -yG -yG -BX -Cg +jG +jP +dY +dY +en +dY +en +eK +mr +mS +Tc +oa +oB +ps +pU +qI +rc +si +sB +tL +uI +vx +sC +wS +yb +tt +tt +yL +yL +yL +yL +BQ +BQ +BQ +BQ +BQ +CM +CG +wJ +Du +BW +BW Cy +Cy +Cy +Cy +Iw By -CX -Dm -By -DD BU -BU -Dk -By -ac -ac -By -By -By -By -By -By +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY ac ac ac ac -LI -LI -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29036,7 +30905,7 @@ XT XT XT "} -(72,1,1) = {" +(84,1,1) = {" XT XT XT @@ -29044,33 +30913,26 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29078,267 +30940,118 @@ ac ac ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -JZ -Kp -Kx -hb -ii -iB -jf -jx -jx -jy -jy -jy -jy -ld -ls -lQ -lQ -lQ -lQ -ls -ld ac -ql -qH -rn -rn -rn -rn -qH -tn -rp +ap +bD +ca +ca +ca +ca +cX +do +dC +cc +ek +dY +dY +dY +dY +dY +dY +dY +dY +dY +ht +hJ +dY +dY +dY +dY +jl +dY +dY +dY +dY +dY +kz +dY +dY +dY +ms +mT +nC +nX +oC +ps +pU +qI +rd +si +sC +sC +uJ +sC +wc +wT +yc +tt +zh +zF +Ag +AI +yL +yL +BQ +BQ +BQ +BQ +CM +CG wJ -xC -yG -yG -zz -Ac -AE -AV -Bn -yG -yG -Ch -Cy -By -By -By -By -By -Eg -By -By -By -By -By -By -Cy -II -IN -IV -By +Du +DN By By By By By By -Jz -Jz By -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(73,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +BV +QY +Qp +Qp +Yc +Qp +QY +YJ +ZN +LA +Mk +YJ +QY ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -wt -yt -ho -hb -ii -iP -iT -jx -jy -jy -jy -jy -jy -ld -ls -lQ -lQ -lQ -lQ -ls -ld ac -ql -qJ -ro -ro -ro -ro -sW -to -rp -wK -xD -yH -zb -zA -Ad -AF -AW -ZE -BA -yG -Ci -Cy -By -Db -Dn -By -DK -BV -BU -By -HY -Ig -Ip -Cy -Cy -Cy -Cy -Cy -BW -Jh -Jm -Ic -Jr -Jv -Jy -Cy -JB -JH -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29348,7 +31061,7 @@ XT XT XT "} -(74,1,1) = {" +(85,1,1) = {" XT XT XT @@ -29356,32 +31069,26 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29390,111 +31097,117 @@ ac ac ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -JM -yt -ho -hb -ii -iP -jf -jx -jy -jy -jy -jy -jy -ld -ls -lQ -lQ -lQ -lQ -ls -ld -cD -ql -ql -rp -rp -rp -rp -rp -vW -vW -wL -xN -yH -zc -zB -Ae -AG -AX -vo -BB -yG -Cj -Cy -By -By -By +ap +bE +cb +cr +cr +cr +cY +dp +dD +cc +el +dY +fa +fB +fV +gf +fV +gG +fV +hh +hu +hK +hZ +fV +fV +UA +jm +gG +fB +jQ +kg +fV +kA +gG +fV +fV +mt +mS +fG +od +pu +ps +pY +qN +re +sj +sD +sD +uK +sD +wd +wU +yd +yL +zi +zG +Aj +AJ +Ba +yL +BQ +BQ +BQ +BQ +CM +De +wJ +Dv +DO +El By -BW -BW -Cy -Bz -Cy -DL -Iq -Cy -Eh -IJ -BX -Ds -BW -Cy -BW -Cy -Js -BW -Cy -Cy -JC -JH +BU +Id +If +BU +ID +BU +QY +Ja +Ja +ZN +Mk +UT +Jt +Mk +Ja +ZN +ZN +QY ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29504,7 +31217,7 @@ XT XT XT "} -(75,1,1) = {" +(86,1,1) = {" XT XT XT @@ -29512,33 +31225,27 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29546,111 +31253,117 @@ ac ac ac ac -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -cW -hb -vm -JN -JW -hb -ii -iP -jg -jy -jy -jy -jy -jy -jy -ld -ls -lQ -lQ -lQ -lQ -ls -dY -oV -pC -qm -qY -rN -st -tp -uB -tN -sw -wM -xT -yI -zd -zC -zC -AH -AY -Br -BC -yG -Ck -BW -BW -BW -Cy -Cy +ap +bF +cc +cc +cc +cc +cZ +cc +dE +cc +em +eI +fb +fC +fW +gg +gg +gg +gg +gg +gg +hL +gm +gm +gm +gm +jn +jB +jB +jB +jB +jB +jB +jB +jB +jB +jB +mV +RK +oa +oD +ps +pZ +pu +rx +oa +sE +tP +uL +vy +we +wV +ye +yM +zj +zH +Ak +AK +Bb +yL +BQ +BQ +BQ +BQ +CM +Df +wJ +Dw Cy -Eh -Et -By -By -By -By -By -By -By -By -By -Eg -By -By -By -By +Em By +BV +BV +Ij +Ix By -BW -JD By +QY +Vc +Jf +NL +vZ +QY +LA +ZN +YJ +ZN +Nv +QY ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29660,7 +31373,7 @@ XT XT XT "} -(76,1,1) = {" +(87,1,1) = {" XT XT XT @@ -29668,145 +31381,145 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -cW -cW -cW -cW -cW -ap -ap -ap -ap -ap -ap -ap +an +an +an +an ap -hb -Jq -Ka -hb -hb -ix -iQ -jh -jy -jy -jy -jy -jy -jy -ld -ls -ls -lQ -lQ -ls -ls -dY -pl -pE -qn -qY -sd -su -tq -uC -vr -wa -wN -xU -yH -ze -zD -Af -Af -Af -zD -BD -yG -BV -Cg -BW -Dc -Ds -BW -Cy -Ei -By -By -HZ -Ih -Ir -Iz -IF -By -By -IW -BU -Ji -Jn -Jo -Jo -Jo +bG +cd +cs +cG +cs +da +dq +dF +dX +dq +eJ +fc +fD +fX +gh +gh +gh +gh +gh +gh +hM +ia +ia +ia +ia +ia +ia +ia +ia +ia +ia +ia +ia +ia +ia +mu +mW +nE +oe +oE +pt +qa +qO +rz +sk +sF +tS +uM +vz +wf +wW +yf +yL +zk +zK +Al +AL +Bc +yL +BQ +BQ +BQ +BQ +CM +CG +wJ +Dx +DO +En By -JA -BW +HU +Ie +Im +Iy By +IH +QY +Jb +Ko +ZN +Xm +QY +ZN +ZN +Mk +Mk +ZN +QY ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29816,7 +31529,7 @@ XT XT XT "} -(77,1,1) = {" +(88,1,1) = {" XT XT XT @@ -29824,145 +31537,145 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +an +aw +aL +aS +an +bH +ce +ap +ap +ap +ap +ap +ap ap -cW -cW -dT -ei -eC -eV ap -fP -gd -gs -gF -gZ -hm -Jw -Kb -vh -ij -iy -iR -ji -jy -jy -jy -jy -jy -jy -dY -dY -lR -ml -ml -nw -nU dY -pm -pF -qo -qY -sf -sv -tr -uD -vs -sw -wO -xV -yH -yH -zE -zE -zE -zE -zE -yH -yG -wJ -wJ -CF -wJ +fd +fE +fY +gi +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +gv +lU +mv +mX +nF +nX +oF +pv +qb +qP +rC +si +sG +tT +uN +sG +sG +wX +yg +tt +zl +zL +Am +AM +yL +yL +BQ +BQ +BQ +BQ +CM +CG wJ -BW -Cy -Ej -By -HP -Ia -Ii -Is +Dx +DO +DN +Eg BV -BU -IK -By -IX +If +In BV -Jj -Jn -Jo -Jo -Jo -By -Cy -JE By +IH +QY +Ko +ZN +ZN +NN +Vm +Ju +Ju +NL +Ju +Ty +QY ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -29972,7 +31685,7 @@ XT XT XT "} -(78,1,1) = {" +(89,1,1) = {" XT XT XT @@ -29980,32 +31693,37 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +an +ax +aM +aT +an +bI +cf ac ac ac @@ -30014,111 +31732,106 @@ ac ac ac ac -ap -cW -dy -dl -dV -eD -eW -ap -fQ -ge -ge -ge -ge -ge -jv -JO -ge -ii -iz -iS -jj -jy -jy -jy -jy -jy -jy -jy -dY -lS -mm -mQ -nx -nV dY -pn -pG -pn -qY -qY -sw -sw -uE -sw -wb -wP -xW -yJ -BQ -BQ -BQ -BQ +fe +fF +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +Zx +ob +of +of +qc +of +of +sl +sY +tU +uO +vA +sG +wY +yh +tt +tt +yL +yL +yL +yL BQ BQ BQ BQ BQ -Cz -CG +CM CG wJ -BW -Cy -Ek +Dy +DO +Eo By -HQ -Ia +HW BV BU BU -IG -IL -By -BV -BU -Jk -Jn -Jo -Jo -Jo -By -Cy -JF By +IH +QY +Jc +Jg +YA +Tf +QY +ZN +Ja +VI +ZN +Ko +QY ac ac ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30128,7 +31841,7 @@ XT XT XT "} -(79,1,1) = {" +(90,1,1) = {" XT XT XT @@ -30136,33 +31849,37 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +an +ay +aN +aU +an +bJ +cg ac ac ac @@ -30170,55 +31887,52 @@ ac ac ac ac -ap -dk -dz -dU -dV -eE -eX -ap -fR -ge -gt -gt -ha -hd -jE -JP -ge -ik -iA -iT -il -jz -jy -jy -jy -jy -ii -ii -dY -dY -Tg -fG -hg -nX -nX -po -pT -qp -qZ -si -sx -ts -uF -vt -sC -wQ -xX -BQ -BQ +ac +dY +ff +fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +nH +ob +oG +oK +qd +NX +rD +sl +ta +tV +uP +vB +sG +wZ +yi +yN +zm +yJ BQ BQ BQ @@ -30229,52 +31943,51 @@ BQ BQ CM CG -CG wJ -BU -BW -Ei +Dw +DP +By +By +By +By By -HR -Ia -Ij -It -If -BU -IM By -IZ -Jd -Ji -Jn -Jo -Jo -Jo By -Cy -JG By +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY +QY ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30284,7 +31997,7 @@ XT XT XT "} -(80,1,1) = {" +(91,1,1) = {" XT XT XT @@ -30292,90 +32005,90 @@ XT XT XT YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +an +az +an +aV +an +ap +ch ac ac ac ac ac ac -ap -dl -dz -dV -cc -eF -eX -ap -fR -ge -gt -gt -gP -gt -hp -JQ -ge -il -iB -iU -il -jA -ii -ii -ii -ii -ii -il -il -lT -mn +dY +dY +dY +fg fG -TH -nX -oA -pp -pU -qq -ra -si -sy -xY -uF -vu -sC -wQ -xX -BR -BR -BQ +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +Tc +ob +oH +pw +qe +qQ +rE +sl +Sc +tW +uQ +vC +sG +xa +yj +Bw +zn +yJ BQ BQ BQ @@ -30384,53 +32097,53 @@ BQ BQ BQ BQ -CH +CM CG wJ -BV -DL -By -By -By -Ib -Ik -Iu -IA -BV -By -By -By -By -By -By -By -By -By -By -Cf -Cy +Dz +DT By +Eu +sK +sK +sK +sK +sK +sK +Fw +FS +rg +ac +ac +ac +ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30440,7 +32153,7 @@ XT XT XT "} -(81,1,1) = {" +(92,1,1) = {" XT XT XT @@ -30449,89 +32162,88 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ap -dm -dA -cc -cc -eG -eY +aA +aO +aW +br ap -fS -ge -ge -ge -ge -ge -hq -hG -ge -im -iB -iV -jk -il -il -il -il -il -il -il -il +ci +ct +cH +cP +db +ac +ac dY -mp +en +eK +fh fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX Tc -oa -oA -pq -pU -qr -rb -si -sz -tv -uG -vv -sC -wQ -xZ -Bw -zf -yJ +of +oI +px +qf +rK +rF +sl +te +tW +uR +vD +sG +xa +yk +BP +BP BQ BQ BQ @@ -30540,53 +32252,54 @@ BQ BQ BQ BQ -CM -Dd +BQ +CN +CG wJ -BV -Cy -BW -BW -By -By -By -By -By -If -By -IH -IH -IH -By -Jo -Jo -Jo -Jo -BV -BW -BW -By +DA +Ed +Bz +Gu +Es +Ev +Io +EG +EA +Fe +Fx +FT +rg +ac +ac +ac +ac +ac +ac +ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30596,7 +32309,7 @@ XT XT XT "} -(82,1,1) = {" +(93,1,1) = {" XT XT XT @@ -30604,90 +32317,89 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ac +ap +aB +aP +aP +aP +bK +cj +cu +bK +bK +dc ac ac -ap -dn -dA -cc -cc -ap -ap -ap -fT -ge -gu -ge -gQ -hf -vi -JR -ge -il -iC -il -jf -ii -ii -ii -dY dY dY dY -dY -dY -mq -mR -nB -oa -oA -pr -pU -qs -ra -si -sA -tw -uH -vw -sC -wR -ya -yK -zg -yJ +fi +fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +Tc +of +oJ +py +qg +rK +rG +sl +tf +tX +uS +vE +sG +xa +yk +BQ +BQ BQ BQ BQ @@ -30698,51 +32410,52 @@ BQ BQ CM CG +CG wJ -BU -DM -Cy -Cy -HS -Ic -Il -Iv -By -BV By -IH -IH -IH By -Jo -Jo -Jo -Jo -BV -Cy -BW By +Gv +sK +rg +rg +rg +ET +ET +Fy +ET +ET +ac +ac +ac +ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30752,7 +32465,7 @@ XT XT XT "} -(83,1,1) = {" +(94,1,1) = {" XT XT XT @@ -30760,28 +32473,24 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30789,116 +32498,120 @@ ac ac ac ap +aC +aQ +aX ap ap ap ap ap -ap -dn -dB -dW -ej -eH -eZ -fA -fU -ge -gu -ge -gQ -nZ -hs -hI -hD -il -iD -YI -jf -ii -jG -jP -dY -dY -en +cQ +ch +ac +ac +ac +ac dY -en -eK -mr -mS +fj +fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX Tc -oa -oB -ps -pU -qI -rc -si -sB -tL -uI -vx -sC -wS -yb -tt -tt -yL -yL -yL -yL +of +oK +px +qf +rK +rH +sl +sG +sG +sG +sG +sG +xb +yl +yJ BQ BQ BQ BQ BQ -CM +BQ +BQ +BQ +BQ +CA +CG CG wJ -Du -BW -BW -Cy -Cy -Cy -Cy -Iw -By -BU -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY +ac +ac +rg +DQ +sK +rg +ac +ac +ET +Fg +Fz +FV +ET +ac +ac +ac ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -30908,7 +32621,7 @@ XT XT XT "} -(84,1,1) = {" +(95,1,1) = {" XT XT XT @@ -30916,145 +32629,145 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ad +ad +ad +aD +ad +ap +ap ac ac ac ac +cQ +dd ac ac ac ac -ap -bD -ca -ca -ca -ca -cX -do -dC -cc -ek -dY -dY -dY -dY -dY -dY -dY -dY -dY -ht -hJ -dY dY -dY -dY -jl -dY -dY -dY -dY -dY -kz -dY -dY -dY -ms -mT -nC -nX -oC -ps -pU -qI -rd -si -sC -sC -uJ -sC -wc -wT -yc -tt -zh -zF -Ag -AI -yL -yL -BQ -BQ -BQ -BQ -CM -CG +fk +fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +ld +Sn +ld +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +Tc +ob +oL +oK +qh +oK +VA +sl +tg +tY +uT +tg +wg +xc +ym +wJ +wJ +wJ +wJ +wJ +wJ +wJ +wJ +wJ +wJ +wJ +JJ +wJ wJ -Du -DN -By -By -By -By -By -By -By -BV -QY -Qp -Qp -Yc -Qp -QY -YJ -ZN -LA -Mk -YJ -QY +ac +ac +rg +DQ +sK +rg +ac +ac +ET +Fh +FA +FW +ET +ac +ac +ac +ac +ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -31064,7 +32777,7 @@ XT XT XT "} -(85,1,1) = {" +(96,1,1) = {" XT XT XT @@ -31072,183 +32785,115 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ad +af +aq +aE +ad +ac +ac +ac +ac +ac +ac +cQ +ch ac ac ac ac -ap -bE -cb -cr -cr -cr -cY -dp -dD -cc -el dY -fa -fB -fV -gf -fV -gG -fV -hh -hu -hK -hZ -fV -fV -UA -jm -gG -fB -jQ -kg -fV -kA -gG -fV -fV -mt -mS -fG -od -pu -ps -pY -qN -re -sj -sD -sD -uK -sD -wd -wU -yd -yL -zi -zG -Aj -AJ -Ba -yL -BQ -BQ -BQ -BQ -CM -De +ff +fH +fY +gj +gw +gw +ld +gw +gw +gw +gw +gw +Sn +Sn +Sn +gw +gw +gw +gw +gw +ld +gw +gw +lV +mv +mX +ny +ob +oM +pz +qi +qR +rI +sl +th +tZ +uU +vF +wh +xd +yr wJ -Dv -DO -El -By -BU -Id -If -BU -ID -BU -QY -Ja -Ja -ZN -Mk -UT -Jt -Mk -Ja -ZN -ZN -QY +zo +zN +An +Ao +Bd +Bs +Bt +rg +Cl +mo +mU +Dg +rg +ac +ac +rg +DR +sK +rg +ac +ac +ET +Fi +FB +FX +ET ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(86,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ac ac ac @@ -31256,117 +32901,29 @@ ac ac ac ac -ap -bF -cc -cc -cc -cc -cZ -cc -dE -cc -em -eI -fb -fC -fW -gg -gg -gg -gg -gg -gg -hL -gm -gm -gm -gm -jn -jB -jB -jB -jB -jB -jB -jB -jB -jB -jB -mV -RK -oa -oD -ps -pZ -pu -rx -oa -sE -tP -uL -vy -we -wV -ye -yM -zj -zH -Ak -AK -Bb -yL -BQ -BQ -BQ -BQ -CM -Df -wJ -Dw -Cy -Em -By -BV -BV -Ij -Ix -By -By -QY -Vc -Jf -NL -vZ -QY -LA -ZN -YJ -ZN -Nv -QY ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -31376,7 +32933,7 @@ XT XT XT "} -(87,1,1) = {" +(97,1,1) = {" XT XT XT @@ -31384,145 +32941,145 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -an -an -an -an -ap -bG -cd -cs -cG -cs -da -dq -dF -dX -dq -eJ -fc -fD -fX -gh -gh -gh -gh -gh -gh -hM -ia -ia -ia -ia -ia -ia -ia -ia -ia -ia -ia -ia -ia -ia -mu -mW -nE -oe -oE -pt -qa -qO -rz -sk -sF -tS -uM -vz -wf -wW -yf -yL -zk -zK -Al -AL -Bc -yL -BQ -BQ -BQ -BQ -CM -CG -wJ -Dx -DO -En -By -HU -Ie -Im -Iy -By -IH -QY -Jb -Ko -ZN -Xm -QY -ZN -ZN -Mk -Mk -ZN -QY +ad +ag +ai +ai +ad +ac +ac +ac +ac +ac +ac +cQ +ch +ac +ac +ac +ac +dY +fl +fG +fY +gj +gw +gw +gw +gw +gw +gw +gw +gw +ld +Sn +ld +gw +gw +gw +gw +gw +gw +gw +gw +lV +mv +mX +nI +ob +ob +ob +ob +ob +ob +sl +ti +ua +uV +vG +wi +xs +yx +yO +zp +zO +zq +zq +Be +Bt +Bt +rg +Cm +Dr +zq +zq +rg +ac +ac +rg +DS +Ey +Ez +Ez +Ez +EM +EM +FC +EM +EM +Gw +Gw +Gw +Gw +Gw +Gw +ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -31532,7 +33089,7 @@ XT XT XT "} -(88,1,1) = {" +(98,1,1) = {" XT XT XT @@ -31540,145 +33097,145 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -an -aw -aL -aS -an -bH -ce -ap -ap -ap -ap -ap -ap -ap -ap +ad +ah +ai +aF +ad +ad +ad +ad +ad +ad +ad +cR +de +ad +ad +ad +ad dY -fd -fE +fm +fG fY -gi -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -gv -lU +gj +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +gw +lV mv mX -nF -nX -oF -pv -qb -qP -rC -si -sG -tT -uN -sG -sG -wX -yg -tt -zl -zL -Am -AM -yL -yL -BQ -BQ -BQ -BQ -CM -CG +nA +nW +en +dY +ac +ac +ac +sm +tj +ub +uW +uW +wg +xt +yy wJ -Dx -DO -DN -Eg -BV -If -In -BV -By -IH -QY -Ko -ZN -ZN -NN -Vm -Ju -Ju -NL -Ju -Ty -QY +zq +zP +Ao +Ao +Bf +Bt +BE +rg +zq +Ao +CJ +Dh +rg +ac +ac +rg +HM +HX +Ex +EB +EH +EM +Fj +FD +FY +Gl +Gx +GK +GQ +GZ +Hf +Gw +ac +ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -31688,7 +33245,7 @@ XT XT XT "} -(89,1,1) = {" +(99,1,1) = {" XT XT XT @@ -31696,48 +33253,48 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -an -ax -aM -aT -an -bI -cf -ac -ac -ac -ac +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ad +ai +ar +aG +ad +aY +bs +bL +ck +cv +ad +cy +df +dr +aG +aG +eo dY -fe -fF +Nb +fG fY gj gw @@ -31762,79 +33319,79 @@ gw lV mv mX -Zx -ob -of -of -qc -of -of -sl -sY -tU -uO -vA -sG -wY -yh -tt -tt -yL -yL -yL -yL -BQ -BQ -BQ -BQ -BQ -CM -CG -wJ -Dy -DO -Eo -By -HW -BV -BU -BU -By -IH -QY -Jc -Jg -YA -Tf -QY -ZN -Ja -VI -ZN -Ko -QY +JT +dY +dY +dY +ac +ac +ac +sm +sm +sm +sm +sm +wj +wj +wj +wj +rO +zQ +rO +rO +rO +Bt +BF +rg +rg +Ao +rg +rg +rg +ac +ac +rg +HN +EV +Ez +EC +EI +EM +Fk +FE +Fo +Gm +Gx +GL +GR +Ha +Hg +Gw +ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -31844,55 +33401,55 @@ XT XT XT "} -(90,1,1) = {" -XT -XT +(100,1,1) = {" XT XT XT XT -YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -an -ay -aN -aU -an -bJ -cg -ac -ac -ac -ac -ac +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +ad +aj +as +af +ad +aZ +ai +aG +ai +bN +ad +cy +df +dr +aG +aG +aG dY -ff +fo fG fY gj @@ -31918,79 +33475,79 @@ gw lV mv mX -nH -ob -oG -oK -qd -NX -rD -sl -ta -tV -uP -vB -sG -wZ -yi -yN -zm -yJ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -CM -CG -wJ -Dw -DP -By -By -By -By -By -By -By -By -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY -QY +nG +dY +oN +rO +ac +ac +ac +ac +ac +ac +ac +ac +rO +tu +tu +tu +zr +zR +Ap +JU +rO +Bt +BG +rg +Cn +Ao +CK +Di +rg +ac +ac +rg +DU +sK +Ez +ED +EJ +EU +Fl +FF +FZ +Gn +Gy +GM +GS +Ha +Hh +Gw ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32000,7 +33557,7 @@ XT XT XT "} -(91,1,1) = {" +(101,1,1) = {" XT XT XT @@ -32008,47 +33565,47 @@ XT XT XT YY -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -an -az -an -aV -an -ap -ch -ac -ac -ac +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +ad +ad +ad +ad +ad +ba +ai +bM +bu +cw +ad +cS +df +ds +dG +dG +aG dY -dY -dY -fg +fn fG fY gj @@ -32074,50 +33631,54 @@ gw lV mv mX -Tc -ob -oH -pw -qe -qQ -rE -sl -Sc -tW -uQ -vC -sG -xa -yj -Bw -zn -yJ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -CM -CG -wJ -Dz -DT -By -Eu -sK -sK -sK -sK -sK -sK -Fw -FS +nz +dY +oO +rO +rO +rO +rO +rO +rO +rO +rO +rO +rO +tu +tu +tu +zr +zS +Aq +AO +rO +Bu +BG +rg +Co +zq +Ao +Ao rg ac ac +rg +DV +sK +Ez +EE +EK +EM +Fm +FG +Fo +Gl +Gx +GN +GT +Hb +Gw +Gw ac ac ac @@ -32125,28 +33686,24 @@ ac ac ac ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32156,7 +33713,7 @@ XT XT XT "} -(92,1,1) = {" +(102,1,1) = {" XT XT XT @@ -32165,46 +33722,46 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac -ap -aA -aO -aW -br -ap -ci -ct -cH -cP -db ac ac +ad +bb +aG +bN +ad +ad +ad +cT +dg +dt +dt +dZ +ep dY -en -eK -fh +fp fG fY gj @@ -32229,80 +33786,80 @@ gw gw lV mv -mX -Tc -of -oI -px -qf -rK -rF -sl -te -tW -uR -vD -sG -xa -yk -BP -BP -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -CN -CG -wJ -DA -Ed -Bz -Gu -Es -Ev -Io -EG -EA -Fe -Fx -FT +mY +Ya +ov +oP +pA +qj +qS +rJ +sn +tk +uc +uX +uX +wk +xu +xu +yP +zs +zT +Ar +AP +rO +Bt +BG +DJ +Ao +Dr +CL +zq rg ac ac +rg +DW +rg +Ez +Ez +EL +EM +Fn +FH +Ga +FR +FR +FR +FR +FR +FR +FR +FR +FR +FR +FR ac ac ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32312,7 +33869,7 @@ XT XT XT "} -(93,1,1) = {" +(103,1,1) = {" XT XT XT @@ -32321,47 +33878,47 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac -ap -aB -aP -aP -aP -bK -cj -cu -bK -bK -dc ac ac +ad +bc +bt +bO +ad +cx +cy +cU +dh +cy +cy +df +eq dY -dY -dY -fi -fG +fq +fI fY gj gw @@ -32385,80 +33942,236 @@ gw gw lV mv -mX -Tc -of -oJ -py -qg -rK -rG -sl -tf -tX -uS -vE -sG -xa -yk -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -CM -CG -CG -wJ -By -By -By -Gv -sK +mZ +nx +ow +oQ +oQ +oQ +oQ +rL +so +tl +ud +uY +oQ +ow +oQ +yz +yQ +zt +zU +As +As +rO +Bs +BH rg +Cp +Ao +zq +zq rg rg -ET -ET -Fy -ET -ET +rg +rg +DW +rg +ac +ac +EM +EW +Fo +FI +Gb +FR +Gz +Gz +Gz +Hc +Hi +Gz +Hx +Gz +GE +FR ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(104,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac ac ac ac ac ac +ad +bd +ai +bP +ad +cy +ad +ad +ad +ad +cy +ea +er +eL +fr +fJ +fY +gk +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +gx +lW +mv +mZ +nz +rO +rO +rO +rO +rO +rO +rO +rO +rO +oc +oc +oc +xv +oc +yR +oc +oc +Ar +Ar +rO +Bs +BI +rg +rg +JI +rg +rg +rg +CY +sK +DE +DX +rg ac ac +EM +EX +Fo +FJ +Gc +FR +Gz +GI +GI +GI +GI +GI +GI +GI +HI +FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32468,7 +34181,7 @@ XT XT XT "} -(94,1,1) = {" +(105,1,1) = {" XT XT XT @@ -32477,144 +34190,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -ap -aC -aQ -aX -ap -ap -ap -ap -ap -cQ -ch ac ac +ad +be +ai +bQ +ad +cy +ad ac ac +ad +dH +eb +es +eM +fs +fK +fZ +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +mw +mZ +nL dY -fj -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -Tc -of -oK -px -qf -rK -rH -sl -sG -sG -sG -sG -sG -xb -yl -yJ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -BQ -CA -CG -CG -wJ -ac -ac -rg -DQ -sK -rg ac ac -ET -Fg -Fz -FV -ET -ac ac ac ac ac ac ac +oc +vH +wl +Km +yA +yU +zu +oc +At +At +rO +Bs +Bs +BY +Bt +Bs +Bs +Bt +BY +sK +Do +DF +DY +rg ac ac +EM +EY +Fp +FK +Gd +FR +Gz +GI +GI +QO +GU +MH +GI +GI +Gz +FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32624,7 +34337,7 @@ XT XT XT "} -(95,1,1) = {" +(106,1,1) = {" XT XT XT @@ -32633,113 +34346,73 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ad -ad -ad -aD -ad -ap -ap -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac -cQ -dd ac ac +ad +bf +ai +bR +ad +cy +ad ac ac +ad +dI +df +et dY -fk +ft +fL +ga +gm +gy +gm +gm +gm +gm +gm +gm +gm +gm +iW +jo +jo +jo +jR fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -ld -Sn -ld -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -Tc -ob -oL -oK -qh -oK -VA -sl -tg -tY -uT -tg -wg -xc -ym -wJ -wJ -wJ -wJ -wJ -wJ -wJ -wJ -wJ -wJ -wJ -JJ -wJ -wJ -ac -ac -rg -DQ -sK -rg -ac -ac -ET -Fh -FA -FW -ET +kB +kM +kM +kM +kM +kM +na +nz +dY ac ac ac @@ -32748,29 +34421,69 @@ ac ac ac ac +oc +vI +pD +QP +pD +yV +zv +oc +rO +rO +rO +Bt +BJ +rg +Cq +CC +CP +Dj +rg +CZ +xg +DG +DZ +rg ac +EF +EF +EF +EF +FL +EF +FR +GA +GI +GI +GI +GI +GI +GI +HB +HJ +FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32780,7 +34493,7 @@ XT XT XT "} -(96,1,1) = {" +(107,1,1) = {" XT XT XT @@ -32789,144 +34502,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac ac ad -af -aq -aE +bg +ai +bS +ad +cy ad ac ac +ad +dJ +df +eu +dY +fu +fM +fM +fM +gz +gH +gR +hi +fM +hN +ib +fM +iF +iX +jp +ib +jH +jS +kh +fM +ib +fM +fM +iE +mx +nb +nM +dY ac ac ac ac -cQ -ch ac ac ac ac -dY -ff -fH -fY -gj -gw -gw -ld -gw -gw -gw -gw -gw -Sn -Sn -Sn -gw -gw -gw -gw -gw -ld -gw -gw -lV -mv -mX -ny -ob -oM -pz -qi -qR -rI -sl -th -tZ -uU -vF -wh -xd -yr -wJ -zo -zN -An -Ao -Bd +oc +vJ +wm +pD +yB +yW +zw +oc +ac +rg +Bg Bs -Bt +BK +rg +rg +rg rg -Cl -mo -mU -Dg rg -ac -ac rg -DR sK +Dp +DG +DZ rg ac -ac -ET -Fi -FB -FX -ET -ac -ac -ac -ac -ac -ac -ac +EF +Fd +EZ +Fq +FM +Ge +Go +GB +GO +GO +GO +TF +GO +GO +HC +Gz +FR ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -32936,7 +34649,7 @@ XT XT XT "} -(97,1,1) = {" +(108,1,1) = {" XT XT XT @@ -32945,144 +34658,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac ac ad -ag -ai -ai +bh +aG +bT +ad +cz ad ac ac -ac -ac -ac -ac -cQ -ch -ac -ac -ac -ac +ad +dK +df +ad +dY +dY +dY +dY +dY +gA +dY +gS +dY +dY +dY +dY +dY +dY +iY +dY +dY +dY +dY +dY +dY +dY +dY +dY +dY +my +nc +dY dY -fl -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -ld -Sn -ld -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -nI -ob -ob -ob -ob -ob -ob -sl -ti -ua -uV -vG -wi -xs -yx -yO -zp -zO -zq -zq -Be -Bt -Bt rg -Cm -Dr -zq -zq +rg +rg +rg rg ac ac -rg -DS -Ey -Ez -Ez -Ez -EM -EM -FC -EM -EM -Gw -Gw -Gw -Gw -Gw -Gw ac +oc +vK +wn +xw +yC +yX +zx +oc +ac +rg +Bh +Bs +BL +rg +ac +ac +ac +ac +rg +sK +Dq +DH +Ea +rg ac +EF +EO +Fa +Fr +FN +Gf +Gp +GC +GI +GI +GI +Gz +GI +GI +GI +Gz +FR ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33092,7 +34805,7 @@ XT XT XT "} -(98,1,1) = {" +(109,1,1) = {" XT XT XT @@ -33101,144 +34814,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac ac ac ac ac ad -ah +bi ai -aF -ad -ad -ad -ad -ad -ad -ad -cR -de +bN ad +cy ad +ac +ac ad +dJ +df ad -dY -fm -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -nA -nW -en -dY +eN ac ac ac -sm -tj -ub -uW -uW -wg -xt -yy -wJ -zq -zP -Ao -Ao -Bf -Bt -BE +dY +en +du +gT +du +hv +hO +hO +in +du +iZ +ee +jC +jI +jT +id +id +id +id +lt +du +mz +nd +du +ox +oR +tx +qk +qT rg -zq -Ao -CJ -Dh rg -ac +rg +rg +oc +oc +wo +oc +oc +oc +oc +oc ac rg -HM -HX -Ex -EB -EH -EM -Fj -FD -FY -Gl -Gx -GK -GQ -GZ -Hf -Gw +Bi +Bs +BK +rg ac ac ac ac +rg +sK +sK +DI +Eb +rg +ac +EF +EP +Fb +Fs +FO +Gg +Gq +GD +GP +Zk +Gz +Pu +Gz +Qn +GI +HK +FR +ac +ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33248,7 +34961,7 @@ XT XT XT "} -(99,1,1) = {" +(110,1,1) = {" XT XT XT @@ -33257,144 +34970,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac ac ac ac ac ad -ai -ar -aG -ad -aY -bs -bL -ck -cv +bj +bu +bU ad cy +ad +ac +ac +ad +dJ df -dr -aG -aG -eo -dY -Nb -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -JT -dY +ad +eN +eN +ac +ac dY dY +du +gT +du +hw +hP +hP +io +du +iZ +ee +du +du +du +du +du +du +du +lu +du +mA +nd +du +og +oW +oW +oW +rf +rg +sp +tx +uf +uf +vL +wp +xx +rg ac ac ac -sm -sm -sm -sm -sm -wj -wj -wj -wj -rO -zQ -rO -rO -rO +ac +rg +Bj Bt -BF +BK +rg +ac +ac +ac rg rg -Ao rg rg rg -ac -ac +DW rg -HN -EV -Ez -EC -EI -EM -Fk -FE -Fo -Gm -Gx -GL -GR -Ha -Hg -Gw -ac ac +EF +EQ +PX +Ft +FP +Fs +Gr +GE +GI +GI +GI +Gz +GI +GI +GI +Gz +FR ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33404,7 +35117,7 @@ XT XT XT "} -(100,1,1) = {" +(111,1,1) = {" XT XT XT @@ -33413,144 +35126,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac -ad -aj -as -af -ad -aZ -ai -aG -ai -bN -ad -cy -df -dr -aG -aG -aG -dY -fo -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -nG -dY -oN -rO ac ac ac +ad +ad +bv +ad +ad +cA +ad ac ac +ad +dJ +df +ad +eN +eN +eN ac ac ac -rO -tu -tu -tu -zr -zR -Ap -JU -rO -Bt -BG +du +gU +du +hx +hP +hP +ip +iG +ja +ee +du +jJ +jU +jU +kC +kN +le +lv +du +mB +ne +du +ee +ee +ee +gY +gY +du +sq +ty +ty +va +vM +wq +xy rg -Cn -Ao -CK -Di rg -ac -ac rg -DU -sK -Ez -ED -EJ -EU -Fl -FF -FZ -Gn -Gy -GM -GS -Ha -Hh -Gw -ac -ac -ac -ac +rg +rg +rg +rg +Bv +rg +rg +rg +rg +rg +rg +CO +Da +Dr +DJ +DW +rg ac +EF +ER +Fc +Fu +FQ +Gh +Gs +GF +GO +GO +GO +Yw +GO +GO +HE +Gz +FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33560,7 +35273,7 @@ XT XT XT "} -(101,1,1) = {" +(112,1,1) = {" XT XT XT @@ -33569,144 +35282,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac -ad -ad -ad -ad -ad -ba -ai -bM -bu -cw -ad -cS -df -ds -dG -dG -aG -dY -fn -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mX -nz -dY -oO -rO -rO -rO -rO -rO -rO -rO -rO -rO -rO -tu -tu -tu -zr -zS -Aq -AO -rO -Bu -BG -rg -Co -zq -Ao -Ao -rg ac ac -rg -DV -sK -Ez -EE -EK -EM -Fm -FG -Fo -Gl -Gx -GN -GT -Hb -Gw -Gw ac ac +ad +bk +bw +bV +bV +cB +ad ac ac +du +dL +ec +du +du +du +du +du +du +du +du +gV +du +hy +hQ +ic +iq +du +jb +ee +du +jK +jV +ki +ki +ki +ki +lw +du +mC +nd +du +ee +jK +ee +ee +gY +du +sH +qW +qW +vb +vR +wr +xe +xE +yn +yS +yS +yS +yS +yS +yS +Bp +Bp +Bp +yS +Ct +rg +rg +rg +rg +rg +DW +rg ac +EF +ES +Fd +Fv +FR +Gi +FR +GG +GI +GI +GI +GI +GI +GI +HF +HL +FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33716,7 +35429,7 @@ XT XT XT "} -(102,1,1) = {" +(113,1,1) = {" XT XT XT @@ -33725,25 +35438,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33751,118 +35464,118 @@ ac ac ac ad -bb -aG -bN -ad -ad +bl +bx +bV +bW +bV ad -cT -dg -dt -dt -dZ -ep -dY -fp -fG -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mY -Ya -ov -oP -pA -qj -qS -rJ -sn -tk -uc -uX -uX -wk -xu -xu -yP -zs -zT -Ar -AP -rO -Bt -BG -DJ -Ao -Dr -CL -zq +ac +ac +du +dL +ec +ev +eO +fv +fv +gb +gn +gB +du +gT +du +hz +hR +id +ir +du +jb +ee +du +ee +jW +gY +ee +ee +ee +jb +du +KJ +nd +du +oh +ee +ee +ee +rg +rg +sH +qW +uh +vc +vS +sK +sK +xF +ri +sK +rg +rg +rg +rg +AZ +Bq +vb +BZ +sK +Cu +yS +yS +yS +yS +yS +Ec rg ac -ac -rg -DW -rg -Ez -Ez -EL -EM -Fn -FH -Ga -FR -FR -FR -FR -FR -FR -FR -FR +EF +EF +EF +CI FR +Gj FR +GJ +GI +GI +ZS +LS +HD +GI +GI +Gz FR ac ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -33872,7 +35585,7 @@ XT XT XT "} -(103,1,1) = {" +(114,1,1) = {" XT XT XT @@ -33881,24 +35594,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33907,244 +35620,88 @@ ac ac ac ad -bc -bt -bO +bm +by +bW +cl +cC ad -cx -cy -cU -dh -cy -cy -df -eq -dY -fq -fI -fY -gj -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -gw -lV -mv -mZ -nx -ow -oQ -oQ -oQ -oQ -rL -so -tl -ud -uY -oQ -ow -oQ -yz -yQ -zt -zU -As -As -rO -Bs -BH -rg -Cp -Ao -zq -zq -rg +ac +ac +du +dL +ec +ew +eP +fw +fw +fw +go +ee +du +gW +du +du +du +du +du +du +jc +du +du +ee +jX +kj +kD +kO +lf +lx +du +mD +nf +du +du +oX +du +du rg +rP +sI +tz +tz +vd +vS +uj +xf +xG rg rg -DW rg ac ac -EM -EW -Fo -FI -Gb -FR -Gz -Gz -Gz -Hc -Hi -Gz -Hx -Gz -GE -FR -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(104,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ad -bd -ai -bP -ad -cy -ad -ad -ad -ad -cy -ea -er -eL -fr -fJ -fY -gk -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -gx -lW -mv -mZ -nz -rO -rO -rO -rO -rO -rO -rO -rO -rO -oc -oc -oc -xv -oc -yR -oc -oc -Ar -Ar -rO -Bs -BI rg rg -JI rg rg rg -CY -sK -DE -DX +rg +rg +rg +rg +rg +rg +rg +rg rg ac -ac -EM -EX -Fo -FJ -Gc +EF +Sr +Ph +NU FR -Gz +Gk +Gt +GI GI GI GI @@ -34158,23 +35715,23 @@ ac ac ab ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -34184,7 +35741,7 @@ XT XT XT "} -(105,1,1) = {" +(115,1,1) = {" XT XT XT @@ -34193,25 +35750,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac @@ -34219,47 +35776,61 @@ ac ac ac ad -be -ai -bQ ad -cy +ad +ad +ad +ad ad ac ac -ad -dH -eb -es -eM -fs -fK -fZ -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -gl -mw -mZ -nL -dY +du +dL +ed +ex +eQ +fx +fN +gc +gp +gD +gD +gX +hj +hA +hS +ie +is +iH +jd +jq +jq +jq +jY +kk +kE +kP +hB +ly +lX +lX +ng +nN +nN +nN +nN +nN +rh +rQ +sJ +tA +ui +ui +vT +sK +xg +xH +rg ac ac ac @@ -34268,69 +35839,55 @@ ac ac ac ac -oc -vH -wl -Km -yA -yU -zu -oc -At -At -rO -Bs -Bs -BY -Bt -Bs -Bs -Bt -BY -sK -Do -DF -DY -rg ac ac -EM -EY -Fp -FK -Gd +ac +ac +ac +ac +ac +ac +ac +ac +ac +EF +Og +Wd +wD FR +FR +FR +GJ +Gz +Gz +He +Hs Gz -GI -GI -QO -GU -MH -GI -GI Gz +Gz +GE FR ac ac ab ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -34340,7 +35897,7 @@ XT XT XT "} -(106,1,1) = {" +(116,1,1) = {" XT XT XT @@ -34349,73 +35906,32 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -ad -bf -ai -bR -ad -cy -ad ac ac -ad -dI -df -et -dY -ft -fL -ga -gm -gy -gm -gm -gm -gm -gm -gm -gm -gm -iW -jo -jo -jo -jR -fG -kB -kM -kM -kM -kM -kM -na -nz -dY ac ac ac @@ -34424,69 +35940,110 @@ ac ac ac ac -oc -vI -pD -QP -pD -yV -zv -oc -rO -rO -rO -Bt -BJ -rg -Cq -CC -CP -Dj -rg -CZ -xg -DG -DZ +du +dL +ee +ey +eR +fw +fw +fw +gq +ee +ee +gY +hk +hB +ef +if +ef +iI +ef +ef +ef +ef +jZ +kl +id +kQ +ee +ee +ee +ee +ee +ee +ee +ee +ee +ee +ri +rR +sK +sK +uj +sK +sK +sK +xh +xI rg ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac EF +Og +WA +Ph EF -EF -EF -FL -EF +ac +FR +FR +FR +FR +FR +FR +FR +FR +FR FR -GA -GI -GI -GI -GI -GI -GI -HB -HJ FR ac -ac ab ab -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -34496,7 +36053,7 @@ XT XT XT "} -(107,1,1) = {" +(117,1,1) = {" XT XT XT @@ -34505,73 +36062,31 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -ad -bg -ai -bS -ad -cy -ad ac ac -ad -dJ -df -eu -dY -fu -fM -fM -fM -gz -gH -gR -hi -fM -hN -ib -fM -iF -iX -jp -ib -jH -jS -kh -fM -ib -fM -fM -iE -mx -nb -nM -dY ac ac ac @@ -34580,225 +36095,111 @@ ac ac ac ac -oc -vJ -wm -pD -yB -yW -zw -oc ac +du +dM +ee +ez +eS +fy +fy +fy +gr +gE +gI +ee +dL +du +hT +ig +ig +iJ +du +du +du +jL +du +du +du +du +du +du +jL +du +du +du +du +du +du +du rg -Bg -Bs -BK -rg -rg -rg -rg -rg +rS +sL +tB +tB +tB +tB +tB +xi rg -sK -Dp -DG -DZ rg ac -EF -Fd -EZ -Fq -FM -Ge -Go -GB -GO -GO -GO -TF -GO -GO -HC -Gz -FR ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(108,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ac ac ac ac ac -ad -bh -aG -bT -ad -cz -ad ac ac -ad -dK -df -ad -dY -dY -dY -dY -dY -gA -dY -gS -dY -dY -dY -dY -dY -dY -iY -dY -dY -dY -dY -dY -dY -dY -dY -dY -dY -my -nc -dY -dY -rg -rg -rg -rg -rg ac ac ac -oc -vK -wn -xw -yC -yX -zx -oc ac -rg -Bh -Bs -BL -rg ac ac ac +EF +EF +EF +EF +EF +ac ac -rg -sK -Dq -DH -Ea -rg ac -EF -EO -Fa -Fr -FN -Gf -Gp -GC -GI -GI -GI -Gz -GI -GI -GI -Gz -FR ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -34808,7 +36209,7 @@ XT XT XT "} -(109,1,1) = {" +(118,1,1) = {" XT XT XT @@ -34817,23 +36218,27 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac ac ac ac @@ -34842,119 +36247,115 @@ ac ac ac ac -ad -bi -ai -bN -ad -cy -ad ac ac -ad -dJ -df -ad -eN ac ac ac -dY -en du -gT +dL +ee +eA +eT +fz +fO +fO +fz +fO +gJ +ee +dL du -hv -hO -hO -in +hU +id +it +iK +du +jr du -iZ ee -jC -jI -jT -id -id -id -id -lt du -mz -nd +km +kF +kR +kR du -ox -oR -tx -qk -qT +ee +du +LM +Xc +Ye +UJ +PL +LM +rg +rg +rg +rg rg rg rg rg -oc -oc -wo -oc -oc -oc -oc -oc -ac rg -Bi -Bs -BK rg ac ac ac ac -rg -sK -sK -DI -Eb -rg ac -EF -EP -Fb -Fs -FO -Gg -Gq -GD -GP -Zk -Gz -Pu -Gz -Qn -GI -HK -FR ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -34964,7 +36365,7 @@ XT XT XT "} -(110,1,1) = {" +(119,1,1) = {" XT XT XT @@ -34973,24 +36374,29 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac ac ac ac @@ -34998,119 +36404,114 @@ ac ac ac ac -ad -bj -bu -bU -ad -cy -ad ac ac -ad -dJ -df -ad -eN -eN ac ac -dY -dY -du -gT -du -hw -hP -hP -io du -iZ +dL +ee +ee +ee +ee ee +ee +ee +ee +ee +ee +dL du du du du +iL du +js du +ee du -lu +kn +kG +kS +kR du -mA -nd +ee +du +LM +Jx +Ye +Pd +Zs +LM du -og -oW -oW -oW -rf -rg -sp -tx -uf -uf -vL -wp -xx -rg ac ac ac ac -rg -Bj -Bt -BK -rg ac ac ac -rg -rg -rg -rg -rg -DW -rg ac -EF -EQ -PX -Ft -FP -Fs -Gr -GE -GI -GI -GI -Gz -GI -GI -GI -Gz -FR ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -35120,7 +36521,7 @@ XT XT XT "} -(111,1,1) = {" +(120,1,1) = {" XT XT XT @@ -35129,144 +36530,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac ac ac ac ac ac ac -ad -ad -bv -ad -ad -cA -ad ac ac -ad -dJ -df -ad -eN -eN -eN ac ac ac du -gU +dN +ef +ef +ef +ef +ef +ef +ef +ef +ef +ef +hl du -hx +hV hP hP -ip -iG -ja +hP +du +jt +jD ee du -jJ -jU -jU -kC -kN -le -lv du -mB -ne +du +du +du du ee -ee -ee -gY -gY +NY +Py +iu +Mv +Mv +iu +ON du -sq -ty -ty -va -vM -wq -xy -rg -rg -rg -rg -rg -rg -rg -Bv -rg -rg -rg -rg -rg -rg -CO -Da -Dr -DJ -DW -rg ac -EF -ER -Fc -Fu -FQ -Gh -Gs -GF -GO -GO -GO -Yw -GO -GO -HE -Gz -FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +VR +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -35276,7 +36677,7 @@ XT XT XT "} -(112,1,1) = {" +(121,1,1) = {" XT XT XT @@ -35285,43 +36686,41 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac ac ac ac ac ac ac -ad -bk -bw -bV -bV -cB -ad ac ac du -dL -ec du du du @@ -35330,291 +36729,61 @@ du du du du -gV du -hy -hQ -ic -iq du -jb -ee du -jK -jV -ki -ki -ki -ki -lw du -mC -nd +du +hW +hP +iu +iM +du +ju du ee jK +ko +kH +ee +ee ee ee -gY du -sH -qW -qW -vb -vR -wr -xe -xE -yn -yS -yS -yS -yS -yS -yS -Bp -Bp -Bp -yS -Ct -rg -rg -rg -rg -rg -DW -rg +LM +Jx +Lp +Lp +Zs +LM +du +IY +ac +VR +VR +ac +ac +ac +ac +ac +ac +ac +ac +ac ac -EF -ES -Fd -Fv -FR -Gi -FR -GG -GI -GI -GI -GI -GI -GI -HF -HL -FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(113,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ac ac ac ac ac ac -ad -bl -bx -bV -bW -bV -ad ac ac -du -dL -ec -ev -eO -fv -fv -gb -gn -gB -du -gT -du -hz -hR -id -ir -du -jb -ee -du -ee -jW -gY -ee -ee -ee -jb -du -KJ -nd -du -oh -ee -ee -ee -rg -rg -sH -qW -uh -vc -vS -sK -sK -xF -ri -sK -rg -rg -rg -rg -AZ -Bq -vb -BZ -sK -Cu -yS -yS -yS -yS -yS -Ec -rg ac -EF -EF -EF -CI -FR -Gj -FR -GJ -GI -GI -ZS -LS -HD -GI -GI -Gz -FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(114,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb ac ac ac @@ -35622,119 +36791,39 @@ ac ac ac ac -ad -bm -by -bW -cl -cC -ad ac ac -du -dL -ec -ew -eP -fw -fw -fw -go -ee -du -gW -du -du -du -du -du -du -jc -du -du -ee -jX -kj -kD -kO -lf -lx -du -mD -nf -du -du -oX -du -du -rg -rP -sI -tz -tz -vd -vS -uj -xf -xG -rg -rg -rg ac ac -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg ac -EF -Sr -Ph -NU -FR -Gk -Gt -GI -GI -GI -GI -GI -GI -GI -GI -HI -FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -35744,7 +36833,7 @@ XT XT XT "} -(115,1,1) = {" +(122,1,1) = {" XT XT XT @@ -35753,87 +36842,32 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ac -ad -ad -ad -ad -ad -ad -ad ac ac -du -dL -ed -ex -eQ -fx -fN -gc -gp -gD -gD -gX -hj -hA -hS -ie -is -iH -jd -jq -jq -jq -jY -kk -kE -kP -hB -ly -lX -lX -ng -nN -nN -nN -nN -nN -rh -rQ -sJ -tA -ui -ui -vT -sK -xg -xH -rg ac ac ac @@ -35853,82 +36887,35 @@ ac ac ac ac -EF -Og -Wd -wD -FR -FR -FR -GJ -Gz -Gz -He -Hs -Gz -Gz -Gz -GE -FR ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(116,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +du +hX +ih +hP +hP +du +du +du +du +du +du +du +du +du +du +du +du +LM +OZ +Py +Vx +Zs +LM +du +IY +IY +IY ac ac ac @@ -35943,53 +36930,6 @@ ac ac ac ac -du -dL -ee -ey -eR -fw -fw -fw -gq -ee -ee -gY -hk -hB -ef -if -ef -iI -ef -ef -ef -ef -jZ -kl -id -kQ -ee -ee -ee -ee -ee -ee -ee -ee -ee -ee -ri -rR -sK -sK -uj -sK -sK -sK -xh -xI -rg ac ac ac @@ -36001,6 +36941,11 @@ ac ac ac ac +ab +ab +ab +ab +ab ac ac ac @@ -36009,44 +36954,32 @@ ac ac ac ac -EF -Og -WA -Ph -EF ac -FR -FR -FR -FR -FR -FR -FR -FR -FR -FR -FR +ab ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36056,7 +36989,7 @@ XT XT XT "} -(117,1,1) = {" +(123,1,1) = {" XT XT XT @@ -36065,25 +36998,24 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36098,57 +37030,47 @@ ac ac ac ac +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ac du -dM -ee -ez -eS -fy -fy -fy -gr -gE -gI -ee -dL -du -hT -ig -ig -iJ -du -du -du -jL -du -du -du -du -du -du -jL du du +iv +iN du +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac du +PI du +PI +PI du +PI du -rg -rS -sL -tB -tB -tB -tB -tB -xi -rg -rg -ac -ac -ac +IY +IY ac ac ac @@ -36165,15 +37087,21 @@ ac ac ac ac -EF -EF -EF -EF -EF ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36183,26 +37111,31 @@ ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36212,7 +37145,7 @@ XT XT XT "} -(118,1,1) = {" +(124,1,1) = {" XT XT XT @@ -36221,25 +37154,26 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac @@ -36252,55 +37186,27 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac du -dL -ee -eA -eT -fz -fO -fO -fz -fO -gJ -ee -dL -du -hU -id -it -iK -du -jr -du -ee du -km -kF -kR -kR du -ee du -LM -Xc -Ye -UJ -PL -LM -rg -rg -rg -rg -rg -rg -rg -rg -rg -rg ac ac ac @@ -36310,14 +37216,119 @@ ac ac ac ac +VR +VR +IY +IY +IY +IY +LI +LI +IY +IY +LI +ac +ac ac ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(125,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36325,12 +37336,53 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ac +ab +jM +jM +jM +jM +jM +jM +jM +jM +IY +LI +LI +LI +LI +LI +LI +LI +LI +LI ac ac ac @@ -36338,27 +37390,64 @@ ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36368,7 +37457,7 @@ XT XT XT "} -(119,1,1) = {" +(126,1,1) = {" XT XT XT @@ -36377,110 +37466,25 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -dL -ee -ee -ee -ee -ee -ee -ee -ee -ee -ee -dL -du -du -du -du -iL -du -js -du -ee -du -kn -kG -kS -kR -du -ee -du -LM -Jx -Ye -Pd -Zs -LM -du -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36488,33 +37492,118 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +jM +jM +jM +jM +jM +jM +jM +jM +LI +LI +LI +LI +LI +LI +jM +LI +LI +LI +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36524,7 +37613,7 @@ XT XT XT "} -(120,1,1) = {" +(127,1,1) = {" XT XT XT @@ -36533,144 +37622,300 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -dN -ef -ef -ef -ef -ef -ef -ef -ef -ef -ef -hl -du -hV -hP -hP -hP -du -jt -jD -ee -du -du -du -du -du -du -ee -NY -Py -iu -Mv -Mv -iu -ON -du -ac -ac -ac -VR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +LI +LI +LI +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +YY +XT +XT +XT +XT +XT +XT +"} +(128,1,1) = {" +XT +XT +XT +XT +XT +XT +YY +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36680,7 +37925,7 @@ XT XT XT "} -(121,1,1) = {" +(129,1,1) = {" XT XT XT @@ -36689,144 +37934,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -du -du -du -du -du -du -du -du -du -du -du -du -du -hW -hP -iu -iM -du -ju -du -ee -jK -ko -kH -ee -ee -ee -ee -du -LM -Jx -Lp -Lp -Zs -LM -du -IY -ac -VR -VR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36836,7 +38081,7 @@ XT XT XT "} -(122,1,1) = {" +(130,1,1) = {" XT XT XT @@ -36845,144 +38090,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -hX -ih -hP -hP -du -du -du -du -du -du -du -du -du -du -du -du -LM -OZ -Py -Vx -Zs -LM -du -IY -IY -IY -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -36992,7 +38237,7 @@ XT XT XT "} -(123,1,1) = {" +(131,1,1) = {" XT XT XT @@ -37001,144 +38246,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -du -du -iv -iN -du -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -du -PI -du -PI -PI -du -PI -du -IY -IY -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -37148,7 +38393,7 @@ XT XT XT "} -(124,1,1) = {" +(132,1,1) = {" XT XT XT @@ -37157,144 +38402,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -du -du -du -du -ac -ac -ac -ac -ac -ac -ac -ac -ac -VR -VR -IY -IY -IY -IY -LI -LI -IY -IY -LI -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -37304,7 +38549,7 @@ XT XT XT "} -(125,1,1) = {" +(133,1,1) = {" XT XT XT @@ -37313,61 +38558,61 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab jM jM jM @@ -37376,154 +38621,6 @@ jM jM jM jM -IY -LI -LI -LI -LI -LI -LI -LI -LI -LI -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(126,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -ac -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -ac -ac -ac -ac -ac -ac -Qb jM jM jM @@ -37532,81 +38629,73 @@ jM jM jM jM -LI -LI -LI -LI -LI -LI jM -LI -LI -LI jM jM jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -37616,7 +38705,7 @@ XT XT XT "} -(127,1,1) = {" +(134,1,1) = {" XT XT XT @@ -37625,61 +38714,61 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab jM jM jM @@ -37688,9 +38777,6 @@ jM jM jM jM -LI -LI -LI jM jM jM @@ -37701,1160 +38787,71 @@ jM jM jM jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(128,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(129,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(130,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(131,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(132,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(133,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -aa -YY -XT -XT -XT -XT -XT -XT -"} -(134,1,1) = {" -XT -XT -XT -XT -XT -XT -YY -aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -38873,144 +38870,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39029,144 +39026,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -jM -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +jM +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39185,144 +39182,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39341,144 +39338,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39497,144 +39494,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39653,144 +39650,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39809,144 +39806,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -39965,144 +39962,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -40121,144 +40118,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -40277,144 +40274,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -40433,144 +40430,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT @@ -40589,144 +40586,144 @@ XT XT YY aa -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb -Qb +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa YY XT diff --git a/maps/tether/main_dmms/tether-03-surface3.dmm b/maps/tether/main_dmms/tether-03-surface3.dmm index 0cd3b52880f..fcaddf6e65d 100644 --- a/maps/tether/main_dmms/tether-03-surface3.dmm +++ b/maps/tether/main_dmms/tether-03-surface3.dmm @@ -3,7 +3,7 @@ /turf/unsimulated/wall/planetary/virgo3b, /area/tether/surfacebase/outside/outside3) "ab" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "ac" = ( /turf/exterior/sif_growth, @@ -166,7 +166,7 @@ /obj/structure/cable/green{ icon_state = "32-2" }, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_site2) "aI" = ( /obj/effect/decal/cleanable/blood/oil, @@ -357,7 +357,7 @@ /turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) "bv" = ( -/turf/simulated/open, +/turf/open, /area/gateway/prep_room) "bw" = ( /obj/structure/table/reinforced, @@ -1161,7 +1161,7 @@ /area/tether/surfacebase/security/breakroom) "do" = ( /obj/structure/table/glass, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/simulated/floor/carpet/blue, /area/tether/surfacebase/security/breakroom) "dp" = ( @@ -1266,7 +1266,7 @@ /area/tether/surfacebase/reading_room) "dG" = ( /obj/structure/catwalk, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "dH" = ( /obj/effect/floor_decal/corner_oldtile/green/full{ @@ -1533,7 +1533,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) "el" = ( @@ -2860,7 +2860,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/gateway/prep_room) "hf" = ( /obj/structure/grille, @@ -3335,9 +3335,6 @@ /obj/structure/window/reinforced, /turf/simulated/floor/plating, /area/tether/surfacebase/security/common) -"hZ" = ( -/turf/exterior/open, -/area/tether/surfacebase/outside/outside3) "ia" = ( /obj/machinery/door/airlock/double/glass{ name = "Security Lobby" @@ -5439,13 +5436,13 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "lk" = ( /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "ll" = ( /obj/structure/railing/mapped{ @@ -5454,7 +5451,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "lm" = ( /obj/effect/floor_decal/borderfloor{ @@ -5767,16 +5764,16 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "lY" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "lZ" = ( /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "ma" = ( /obj/structure/cable/green{ @@ -6166,7 +6163,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 9 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, @@ -6176,7 +6173,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, @@ -6186,7 +6183,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6196,7 +6193,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 5 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6315,10 +6312,10 @@ /obj/machinery/camera/network/tether{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_stairs_three) "ne" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_stairs_three) "ng" = ( /obj/machinery/camera/network/tether{ @@ -6543,21 +6540,21 @@ /obj/effect/floor_decal/spline/plain{ dir = 8 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, /turf/simulated/floor/pool/deep, /area/crew_quarters/pool) "nx" = ( -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, /turf/simulated/floor/pool/deep, /area/crew_quarters/pool) "ny" = ( -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6567,7 +6564,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 4 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -6673,7 +6670,7 @@ /area/tether/surfacebase/atrium_three) "nN" = ( /obj/structure/table/glass, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/tether/surfacebase/atrium_three) "nO" = ( @@ -7053,7 +7050,7 @@ /obj/structure/sign/directions/evac{ pixel_x = -32 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/north_stairs_three) "oF" = ( /obj/item/chems/drinks/bottle/orangejuice, @@ -7090,7 +7087,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/supply, /obj/structure/lattice, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/maintenance/bar) "oJ" = ( /turf/simulated/wall, @@ -7769,7 +7766,7 @@ dir = 8 }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "pY" = ( /obj/structure/cable{ @@ -8019,7 +8016,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 10 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, @@ -8027,7 +8024,7 @@ /area/crew_quarters/pool) "qt" = ( /obj/effect/floor_decal/spline/plain, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 800; name = "mapped deep pool" }, @@ -8035,7 +8032,7 @@ /area/crew_quarters/pool) "qu" = ( /obj/effect/floor_decal/spline/plain, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -8045,7 +8042,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 6 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -10389,18 +10386,18 @@ dir = 8 }, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "uI" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "uJ" = ( /obj/structure/railing/mapped, /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "uK" = ( /obj/structure/cable/green{ @@ -10554,7 +10551,7 @@ }, /obj/structure/disposalpipe/down, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/rnd/breakroom) "uZ" = ( /obj/machinery/door/firedoor/glass/hidden/steel, @@ -12024,13 +12021,13 @@ /turf/simulated/wall, /area/rnd/hallway) "xH" = ( -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "xI" = ( /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "xJ" = ( /obj/structure/cable/green{ @@ -12541,7 +12538,7 @@ /area/bridge/secondary) "yy" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/simulated/floor/tiled/dark, /area/bridge/secondary) "yz" = ( @@ -12621,7 +12618,7 @@ /area/hallway/lower/third_south) "yH" = ( /obj/abstract/level_data_spawner/virgo3b/main/top, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "yI" = ( /obj/structure/disposalpipe/segment{ @@ -12704,18 +12701,18 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "yN" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "yO" = ( /obj/structure/railing/mapped, /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "yP" = ( /obj/machinery/light{ @@ -13821,7 +13818,7 @@ /turf/simulated/floor/tiled/dark, /area/bridge/secondary) "AN" = ( -/turf/simulated/open, +/turf/open, /area/hallway/lower/third_south) "AO" = ( /obj/structure/hygiene/shower{ @@ -14296,7 +14293,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "BA" = ( /obj/structure/shuttle/engine/propulsion, @@ -14623,7 +14620,7 @@ dir = 4 }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/rnd/hallway) "BT" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -15136,7 +15133,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 9 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -15368,7 +15365,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 1 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -15740,7 +15737,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 5 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -16019,7 +16016,7 @@ /obj/effect/floor_decal/corner/mauve/border{ dir = 1 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) "Eh" = ( @@ -17938,15 +17935,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/shuttle_pad) -"Hv" = ( -/obj/structure/railing/mapped{ - dir = 1 - }, -/obj/structure/railing/mapped{ - dir = 4 - }, -/turf/exterior/open, -/area/tether/surfacebase/outside/outside3) "Hw" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 @@ -18217,8 +18205,8 @@ /area/assembly/robotics) "Ib" = ( /obj/structure/table, -/obj/item/mmi, -/obj/item/organ/internal/posibrain, +/obj/item/organ/internal/brain_interface, +/obj/item/organ/internal/brain/robotic, /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, /turf/simulated/floor/tiled/steel_grid, @@ -18329,7 +18317,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 10 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -18338,7 +18326,7 @@ /area/tether/surfacebase/sauna) "Io" = ( /obj/effect/floor_decal/spline/plain, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -19516,7 +19504,7 @@ /obj/structure/cable{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/public_garden_three) "KS" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ @@ -19704,8 +19692,8 @@ dir = 4 }, /obj/structure/table/reinforced, -/obj/item/book/manual/command_guide, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/command_guide, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled/dark, /area/bridge/secondary) "Ln" = ( @@ -20062,7 +20050,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "Ml" = ( /obj/structure/hygiene/sink{ @@ -20138,7 +20126,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "MF" = ( /turf/unsimulated/dark_filler, @@ -20722,7 +20710,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "Pq" = ( /obj/effect/floor_decal/borderfloor{ @@ -20944,7 +20932,7 @@ /area/crew_quarters/bar) "Qh" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "Qi" = ( /obj/machinery/alarm{ @@ -21233,7 +21221,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "Rw" = ( -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/public_garden_three) "Rx" = ( /obj/structure/disposalpipe/trunk{ @@ -21491,7 +21479,7 @@ /obj/effect/floor_decal/spline/plain{ dir = 6 }, -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -21645,7 +21633,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "TE" = ( /obj/structure/disposalpipe/segment{ @@ -21830,7 +21818,7 @@ /area/tether/surfacebase/public_garden_three) "Uy" = ( /obj/structure/table/glass, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/carpet/blue, /area/tether/surfacebase/security/breakroom) "UB" = ( @@ -21947,7 +21935,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/exterior/open, +/turf/open, /area/tether/surfacebase/outside/outside3) "Vq" = ( /obj/structure/table/woodentable, @@ -22252,7 +22240,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "Xm" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -22402,7 +22390,7 @@ dir = 4 }, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "Yb" = ( /obj/machinery/door/firedoor, @@ -22659,7 +22647,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/surfacebase/atrium_three) "Zn" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -23976,19 +23964,19 @@ aa aa aa aa -hZ +ab aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aa aa @@ -24057,143 +24045,143 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab yH aa aJ @@ -24213,144 +24201,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -24369,144 +24357,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -24525,778 +24513,5926 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(13,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(14,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(15,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(16,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(13,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(14,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(15,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(16,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(17,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(18,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(19,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(20,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(21,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(22,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(23,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(24,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(25,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(26,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(27,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(28,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(29,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +dG +dG +dG +dG +dG +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(30,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +dG +dG +dG +dG +dG +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(31,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +dH +el +eX +eX +gt +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(32,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +dI +em +ab +ab +gu +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(33,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +dJ +en +eY +eY +gv +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(34,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(35,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(36,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(37,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(38,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(39,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +fF +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(40,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Qx +Yc +Yc +Qx +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(41,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Uv +Qx +Mu +Mu +Qx +Op +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(42,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Uv +QC +VN +Zq +Zq +Yz +QC +Op +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(43,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Uv +QC +Ws +Zq +ZQ +QW +Zq +Ws +QC +Op +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(44,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +Qx +Qx +VF +Ws +ZQ +Lr +YN +RE +Ws +UL +Qx +Qx +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(45,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +Tt +Mu +Zq +Uu +Oa +Rw +Rw +YV +QW +Zq +Mu +VG +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(46,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +Tt +Mu +Zq +Ve +Qj +Rw +Rw +NL +WA +Zq +Mu +VG +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF MF "} -(17,1,1) = {" +(47,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +Qx +Qx +VF +Ws +Vr +Qd +RS +Rb +Ws +UL +Qx +Qx +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(48,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +YA +QC +Ws +Mp +Rh +WF +VH +Ws +QC +Zp +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bg +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(49,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +YA +QC +Sg +PF +Nb +NA +QC +Zp +ac +ac +gw +gw +gw +gw +kS +lw +lw +lw +kS +kS +kS +lw +lw +lw +kS +kS +kS +rU +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(50,1,1) = {" MF MF MF @@ -25305,144 +30441,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +YA +Qx +UH +MO +Qx +Zp +ac +ac +ac +gw +ip +jt +kl +kS +lx +mm +mM +nv +nZ +oq +mM +pm +mM +qr +rc +rv +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -25452,7 +30588,7 @@ MF MF MF "} -(18,1,1) = {" +(51,1,1) = {" MF MF MF @@ -25461,144 +30597,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Tt +SJ +Zn +VG +ac +ac +ac +ac +gw +iq +ju +km +kS +ly +mn +mN +mN +mN +mN +mN +pn +pI +pI +rd +rw +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -25608,7 +30744,7 @@ MF MF MF "} -(19,1,1) = {" +(52,1,1) = {" MF MF MF @@ -25617,144 +30753,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Tt +PD +KR +VG +ac +ad +gw +gw +gw +ir +jv +kn +kS +lz +mo +mO +nw +nw +nw +nw +nw +nw +qs +re +rw +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -25764,7 +30900,7 @@ MF MF MF "} -(20,1,1) = {" +(53,1,1) = {" MF MF MF @@ -25773,144 +30909,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Qx +TQ +TQ +Qx +ac +ac +gw +hd +hS +is +jw +ko +kS +lA +mp +mP +nx +nx +nx +nx +nx +nx +qt +re +rw +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +Mf +Mf +Mf +Mf +Mf +Mf +Mf +Mf +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -25920,7 +31056,7 @@ MF MF MF "} -(21,1,1) = {" +(54,1,1) = {" MF MF MF @@ -25929,144 +31065,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bh +bh +it +jx +kn +kS +lB +mp +mP +nx +nx +nx +nx +nx +nx +qt +re +rw +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +za +ac +ac +ac +ac +ac +ac +JW +Ak +Mw +Ak +Ak +Ak +Ak +JW +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26076,7 +31212,7 @@ MF MF MF "} -(22,1,1) = {" +(55,1,1) = {" MF MF MF @@ -26085,144 +31221,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bg +ac +ac +ac +ac +ac +ac +ac +bh +he +bh +iu +jy +kn +kS +lC +mp +mQ +ny +ny +or +oS +nx +nx +qt +re +rx +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +xG +xG +xG +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Ak +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26232,7 +31368,7 @@ MF MF MF "} -(23,1,1) = {" +(56,1,1) = {" MF MF MF @@ -26241,144 +31377,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bh +bh +bh +bh +bh +bh +bh +bh +hf +bh +iv +jz +kn +kS +lD +mq +mQ +ny +ny +lE +oT +nx +nx +qt +re +rw +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +za +ac +ac +ac +xG +BS +xG +Dx +DI +Et +ET +FD +Gn +GG +Hk +Hk +HE +Hk +Hk +Hk +Dx +Dx +Dx +Ak +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26388,7 +31524,7 @@ MF MF MF "} -(24,1,1) = {" +(57,1,1) = {" MF MF MF @@ -26397,144 +31533,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bv +bv +bv +bv +eo +eZ +fK +gx +hg +bh +TL +jz +kn +kT +lE +mr +mQ +ny +ny +os +oU +nx +nx +qt +re +rw +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +tp +ur +ur +ur +tp +xG +xG +xG +xG +xG +xG +xG +BT +xG +Dx +Ea +ED +ED +FE +Gq +GG +Hl +Hk +Hl +Hk +HY +Hk +Dx +Dx +Dx +Ak +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26544,7 +31680,7 @@ MF MF MF "} -(25,1,1) = {" +(58,1,1) = {" MF MF MF @@ -26553,144 +31689,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bv +bv +bv +bv +eo +fa +fL +gy +hh +bh +iw +jA +kp +kT +lE +mr +mQ +ny +ny +ny +ny +ny +ny +qu +re +rw +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +uq +us +vu +vW +tp +xH +xH +yM +yY +Aj +xG +Bb +BW +Cz +Dx +Ea +ED +EU +FF +Gs +GJ +Hk +Hk +Hk +Hk +Hk +Il +Dx +Dx +Dx +Ak +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26700,7 +31836,7 @@ MF MF MF "} -(26,1,1) = {" +(59,1,1) = {" MF MF MF @@ -26709,144 +31845,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bh +bh +bh +bh +bh +fb +fL +gy +hi +bh +ix +jz +kq +kU +lF +mr +mQ +ny +ny +ny +ny +ny +ny +qu +re +ry +kS +ac +ac +ac +ac +ac +ac +ac +ac +ac +uq +ut +vv +wm +tp +xH +xH +xH +zb +Al +xG +Bg +BX +CW +Dx +Eb +ED +ED +FI +Gq +GG +Hl +Hk +Hl +Hk +HZ +Hk +Dx +Dx +Dx +Ak +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -26856,7 +31992,7 @@ MF MF MF "} -(27,1,1) = {" +(60,1,1) = {" MF MF MF @@ -26865,144 +32001,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bw +bw +cV +dK +ep +fc +fL +gy +hh +bh +iy +jB +kr +kV +lG +ms +mR +nz +nz +nz +nz +nz +nz +qv +re +rw +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +uq +ut +vw +wo +tp +xH +xH +yN +zb +Am +zv +Bh +BY +CX +Dy +Ed +yC +EV +FJ +Gw +GX +Hk +Hk +Hk +Hk +Hk +Hk +Dx +Dx +Dx +MK +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27012,7 +32148,7 @@ MF MF MF "} -(28,1,1) = {" +(61,1,1) = {" MF MF MF @@ -27021,144 +32157,144 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +bh +bx +ci +cW +cW +cW +fd +fL +gy +hj +bh +iz +jC +ks +kW +lH +mt +mS +nA +nA +nA +nA +nA +pJ +qw +rf +rz +rV +ac +ac +ac +ac +ac +ac +ac +ac +ac +tp +uu +vF +wx +tp +xH +xH +yN +zc +An +AT +Bi +Cd +CY +Dz +Ee +ED +ED +FN +Gq +GG +Hl +Hk +Hl +Hk +HZ +Hk +Dx +Dx +Dx +JW +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27168,7 +32304,7 @@ MF MF MF "} -(29,1,1) = {" +(62,1,1) = {" MF MF MF @@ -27177,60 +32313,24 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -dG -dG -dG -dG -dG -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27241,6 +32341,34 @@ ac ac ac ac +bh +by +cj +cX +cX +cX +fe +fL +gz +hk +bh +iA +jD +kt +kX +lI +mu +mT +mu +mu +mu +mu +mu +pK +qx +rg +rA +rV ac ac ac @@ -27250,71 +32378,79 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +uq +uv +vQ +wy +tp +xH +xH +yN +zd +Ao +xG +Bj +Co +CZ +Dx +Ef +ED +EX +FO +Gx +GZ +Hk +Hk +Hk +Hk +Hk +Il +Dx +Dx +Dx +Ak +Bz +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27324,7 +32460,7 @@ MF MF MF "} -(30,1,1) = {" +(63,1,1) = {" MF MF MF @@ -27333,61 +32469,180 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac ac -dG -dG -dG -dG -dG ac ac ac +bh +bz +ck +cY +cY +cY +ff +fM +gA +hl +hT +iB +jE +ku +kS +lJ +mv +mU +mv +mv +mv +mv +mv +pL +qy +rh +rB +kS ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ ac ac ac ac ac +uq +uO +vR +wz +tp +xI +xI +yO +ze +Ap +xG +BC +Cp +Db +Dx +Eg +ED +ED +FE +Gq +GG +Hl +Hk +Hl +Hk +HZ +Hk +Dx +Dx +Dx +Ak +Ak +Bz +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(64,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27398,6 +32653,34 @@ ac ac ac ac +bh +bA +cl +cW +cW +cW +fd +fa +fa +hm +hU +iC +jF +kv +kS +lJ +mv +mV +nB +oa +ot +oa +mv +pM +qz +ri +rC +kS ac ac ac @@ -27406,71 +32689,80 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ ac +uq +uV +vS +wA +tp +xK +ym +yP +zf +Aq +xG +BC +Cp +Cu +Dx +Eh +EG +EY +FP +Gy +Ha +Hk +Hk +HF +Hk +Hk +Hk +Dx +Dx +Dx +Ay +Ak +JW ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27480,7 +32772,7 @@ MF MF MF "} -(31,1,1) = {" +(65,1,1) = {" MF MF MF @@ -27489,71 +32781,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -dH -el -eX -eX -gt -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27563,70 +32809,116 @@ ac ac ac ac +bh +bB +cm +cX +cX +cX +cX +cX +gB +hn +bh +iD +jG +kw +kY +kY +kZ +mW +nC +kY +kY +kY +kT +pN +qA +kS +rD +kS ac ac ac ac ac ac +tB +tB +tB +tp +tp +tp +wB +tp +xG +xG +xG +zv +xG +xG +BD +Cq +Dg +Dx +Dx +Dx +EZ +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +Dx +AI +Ay ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27636,7 +32928,7 @@ MF MF MF "} -(32,1,1) = {" +(66,1,1) = {" MF MF MF @@ -27645,71 +32937,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -dI -em -hZ -hZ -gu -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27718,6 +32964,33 @@ ac ac ac ac +ad +bh +bC +cn +cZ +cZ +eq +fg +fN +gC +ho +bh +jc +jH +kx +kY +lK +mw +mX +mw +ob +ou +kY +po +pO +ro +gw ac ac ac @@ -27726,63 +32999,82 @@ ac ac ac ac +tC +tT +tW +tZ +uW +vU +wC +wY +yh +yn +yQ +zy +Ar +AV +BE +Cr +Dh +xu +DB +Ek +Er +Ah +Ds +Dt +Dw +EK +EL +Fb +Fk +FG +Go +Kt +KA +AI +Ay ac -hZ -hZ -hZ ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27792,7 +33084,7 @@ MF MF MF "} -(33,1,1) = {" +(67,1,1) = {" MF MF MF @@ -27801,48 +33093,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -dJ -en -eY -eY -gv -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27852,6 +33121,32 @@ ac ac ac ac +bi +bi +bi +bi +bi +bi +fh +fh +fh +fh +fh +iF +jI +ky +kZ +lL +mw +mX +mw +oc +ov +kY +ir +jR +qC +lP ac ac ac @@ -27860,9 +33155,120 @@ ac ac ac ac +tC +tU +tX +ua +uX +vV +wD +xh +yi +yu +yR +yR +At +yR +BF +Cs +Aa +Ct +Dv +Aa +Df +Aa +Aa +Aa +DC +DC +DC +Fj +DC +HR +DC +KE +KK +AI +Ay +Ci ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(68,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -27871,6 +33277,32 @@ ac ac ac ac +bi +bD +co +da +dL +bi +fi +fO +gD +hp +fj +iG +jJ +kx +kZ +lL +mw +mX +mw +oc +ow +kY +pp +jR +qC +lP ac ac ac @@ -27878,67 +33310,83 @@ ac ac ac ac +Pw +tD +tV +tY +ub +vj +vU +wW +xy +yj +yI +yS +xy +AP +zE +AW +BH +ym +Cv +Ej +El +vH +Hb +Dn +Dn +DQ +DQ +DQ +Fc +Fm +FL +IL +KJ +KV +AI +Ay ac ac ac ac ac ac +ab +ab +ab +ab +ab ac ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -27948,7 +33396,7 @@ MF MF MF "} -(34,1,1) = {" +(69,1,1) = {" MF MF MF @@ -27957,63 +33405,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28023,12 +33433,75 @@ ac ac ac ac +bi +bE +cp +cp +dM +bi +fj +fj +gE +hq +hV +iH +jK +kx +kZ +lM +mw +mY +nD +od +ox +oV +pq +pP +qC +lP ac ac ac ac ac ac +tE +tq +tE +tE +tE +uc +vt +xa +xb +As +As +yK +As +As +xb +zZ +AX +Dg +Da +Da +Da +Fa +DA +Fa +Da +Da +Ks +Ks +Ks +Da +Da +Da +HN +KO +KY +AI +Ay ac ac ac @@ -28045,56 +33518,31 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -28104,7 +33552,7 @@ MF MF MF "} -(35,1,1) = {" +(70,1,1) = {" MF MF MF @@ -28113,64 +33561,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28179,12 +33589,75 @@ ac ac ac ac +bi +bF +cq +db +dN +bi +fi +fP +gF +hr +fj +iI +jz +kx +kZ +lN +mw +mX +mw +oe +oy +oW +pr +pQ +qD +gw ac ac ac ac ac ac +tF +tr +uw +uY +vx +vX +wE +xa +wX +xz +yk +yL +yT +zz +As +Ab +AY +BI +Ei +EP +FU +GH +HH +Ie +Iy +IU +LM +IH +HM +yc +Ia +Da +HS +KU +KZ +Kx +KB ac ac ac @@ -28201,56 +33674,31 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -28260,7 +33708,7 @@ MF MF MF "} -(36,1,1) = {" +(71,1,1) = {" MF MF MF @@ -28269,66 +33717,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28337,7 +33745,75 @@ ac ac ac ac +bi +bG +cr +dc +dO +bi +fj +fj +gG +hs +fj +iJ +jz +kx +kZ +lN +mw +mZ +nE +mw +mw +kZ +ix +ka +qE +gw +go +go +gw +gw +gw ac +tG +ud +ud +ud +ud +ud +ud +xa +xA +xJ +yo +yU +zC +zA +AQ +AZ +BN +Cw +Eq +EQ +FW +GI +HI +Ig +Iz +yF +Ai +CR +DD +DP +Ib +Ks +Jd +HX +Lb +Kx +KB ac ac ac @@ -28355,58 +33831,30 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -28416,7 +33864,7 @@ MF MF MF "} -(37,1,1) = {" +(72,1,1) = {" MF MF MF @@ -28425,66 +33873,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28493,7 +33901,75 @@ ac ac ac ac +bi +bH +cs +dd +dP +bi +fk +fQ +gF +ht +fj +iK +jz +kx +kY +lO +mx +na +nF +of +oz +kY +iK +ka +qF +ha +ha +ha +ss +sR +gw ac +tG +ud +ux +ux +ux +ux +ud +xa +xB +xL +yf +yV +zD +zB +As +Ba +BR +Cx +Ei +wq +FV +yE +HJ +FV +IA +LA +LO +LX +HO +FV +FV +HG +IM +Ic +Lc +AI +Ay ac ac ac @@ -28511,58 +33987,30 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -28572,7 +34020,7 @@ MF MF MF "} -(38,1,1) = {" +(73,1,1) = {" MF MF MF @@ -28581,62 +34029,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28645,7 +34057,75 @@ ac ac ac ac +bi +bi +ct +bi +bi +bi +bj +bj +bj +bj +bj +iL +jL +kz +kY +kY +kY +nb +nb +kY +kY +kY +ps +pR +qG +kE +kE +kE +st +kx +lP ac +tG +ud +ux +ux +ux +ux +ud +xa +xC +xM +yq +yW +yp +zI +xb +Bf +BG +Bf +Bf +DE +Em +EN +HK +Ii +If +LB +LR +Ih +En +DR +Id +Ks +JD +HX +Lt +AI +Ay ac ac ac @@ -28666,59 +34146,27 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -28728,7 +34176,7 @@ MF MF MF "} -(39,1,1) = {" +(74,1,1) = {" MF MF MF @@ -28737,56 +34185,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -fF -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28795,12 +34213,75 @@ ac ac ac ac +bj +bI +cu +de +dQ +er +fl +fR +fl +hu +hW +iM +jz +kA +la +gw ac ac ac ac ac +ik +pt +pS +qH +rj +rj +rW +jR +kx +lP ac +tG +ud +ux +ux +ux +ux +ud +xa +xD +xN +yr +xN +zF +zJ +xb +Bc +BM +CA +Bf +DF +En +EO +HL +Ij +IB +LC +LS +Dp +Le +ZC +zx +Da +IN +HX +Lb +Kx +KD ac ac ac @@ -28822,125 +34303,64 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF MF -MF -MF -MF -MF -"} -(40,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qx -Yc -Yc -Qx -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +MF +MF +MF +MF +"} +(75,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -28949,12 +34369,75 @@ ac ac ac ac +bj +bJ +cv +df +df +es +fm +fS +gH +hv +hX +iM +jz +kA +la +lP ac ac ac ac ac +ik +pu +pT +qI +rk +hc +rX +su +kx +gw ac +tG +ud +ux +ux +ux +ux +ud +xa +xE +xO +ys +yX +zG +zK +xb +Bd +BO +CB +Bf +DG +Eo +ER +De +De +GA +Hc +Hp +De +De +DT +Da +Da +Ko +HX +Lw +AI +Ay ac ac ac @@ -28978,59 +34461,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29040,7 +34488,7 @@ MF MF MF "} -(41,1,1) = {" +(76,1,1) = {" MF MF MF @@ -29049,56 +34497,27 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Uv -Qx -Mu -Mu -Qx -Op -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29106,11 +34525,75 @@ ac ac ac ac +bk +bK +cw +dg +dR +bj +fn +fT +bj +hw +hY +iM +jz +kA +la +lP ac ac +nG ac ac +oX +oX +oX +qJ +oX +oX +rY +jX +kx +lP ac +tG +ud +ud +ux +ux +ud +ud +xa +xb +As +yt +As +xb +zL +xb +Be +BP +CC +Bf +DH +Ep +ES +De +FT +GB +He +Hq +Hz +De +EM +EM +Im +zb +HX +Lb +Kx +KD ac ac ac @@ -29134,59 +34617,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29196,7 +34644,7 @@ MF MF MF "} -(42,1,1) = {" +(77,1,1) = {" MF MF MF @@ -29205,58 +34653,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Uv -QC -VN -Zq -Zq -Yz -QC -Op -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29265,12 +34681,76 @@ ac ac ac ac +bk +bL +cx +dh +dS +et +dh +fU +gI +hx +bj +iN +jz +kA +lb +gw ac ac ac ac ac +oX +pv +pU +qK +pv +oX +rZ +sv +kx +lP ac +ts +ts +uy +uZ +uZ +tg +wF +xb +xb +wZ +xP +yl +xb +xb +xb +Bf +BQ +Bf +Bf +up +IE +up +De +FX +GC +Hf +Hw +HA +De +Cj +EE +Da +Kq +ID +LE +AI +Ay +Ci ac ac ac @@ -29293,56 +34773,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29352,7 +34800,7 @@ MF MF MF "} -(43,1,1) = {" +(78,1,1) = {" MF MF MF @@ -29360,61 +34808,27 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Uv -QC -Ws -Zq -ZQ -QW -Zq -Ws -QC -Op -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29423,8 +34837,75 @@ ac ac ac ac +bk +bK +cy +di +dT +df +df +fV +gJ +hy +bj +iO +jM +kv +lc +lc +mz +lc +lc +lc +lc +lc +pw +pV +qL +rl +oX +iE +sw +kx +gw ac ac +ts +uz +va +vy +wa +wG +xc +xR +xQ +yv +yZ +zH +AU +Kr +BU +Dc +Ec +BJ +EW +Gz +Hn +FC +FY +GD +Hi +GD +HB +De +DU +EM +Bf +Bf +II +Bf +AR +Ay ac ac ac @@ -29449,56 +34930,23 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29508,7 +34956,7 @@ MF MF MF "} -(44,1,1) = {" +(79,1,1) = {" MF MF MF @@ -29517,60 +34965,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -Qx -Qx -VF -Ws -ZQ -Lr -YN -RE -Ws -UL -Qx -Qx -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29579,8 +34993,75 @@ ac ac ac ac +bk +bM +cz +dj +dU +eu +fo +fW +gK +hz +bj +iP +jM +kx +lc +lQ +mA +lc +nH +og +oA +lc +px +pV +qL +rm +oX +sa +sx +kx +lP ac ac +ue +uA +vb +vz +wb +wb +xd +wb +Gb +wb +zN +Ls +Ls +BK +CD +Dd +CD +CD +Fd +Ga +Hn +FC +FZ +GE +Hi +GE +GE +De +DV +EE +Bf +Kz +IJ +LF +AR +Ay ac ac ac @@ -29604,57 +35085,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29664,7 +35112,7 @@ MF MF MF "} -(45,1,1) = {" +(80,1,1) = {" MF MF MF @@ -29673,61 +35121,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -Tt -Mu -Zq -Uu -Oa -Rw -Rw -YV -QW -Zq -Mu -VG -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29737,10 +35149,78 @@ ac ac ac ac +bl +bl +cA +bl +bl +bl +bl +fX +gL +fX +gT +ic +jM +kx +lc +lR +mB +nc +nI +oh +oB +lc +py +pW +qM +py +oX +sb +jR +kx +lP ac ac +ue +uA +vc +vA +wc +wH +xe +Bk +yw +zg +zO +OA +wH +BL +BV +zu +Sj +CE +Fe +Fp +Hn +FC +Gi +GF +Hj +GF +HD +De +DV +EM +Bf +Lx +IK +LG +AR +Ay ac ac +fF ac ac ac @@ -29761,56 +35241,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29820,7 +35268,7 @@ MF MF MF "} -(46,1,1) = {" +(81,1,1) = {" MF MF MF @@ -29829,23 +35277,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29855,18 +35305,78 @@ ac ac ac ac -Tt -Mu -Zq -Ve -Qj -Rw -Rw -NL -WA -Zq -Mu -VG +bl +bN +cB +dk +dV +ev +bl +fY +gM +hA +gT +iQ +jM +Qb +lc +lS +mC +lc +lc +lc +lc +lc +gw +gw +gw +gw +oX +sc +jR +kx +gw +ac +ac +ts +uB +vd +vB +wd +Cy +Cy +Cy +Cy +Cy +IF +Cy +Cy +Pe +Pe +Pe +Pe +Pe +Ey +Fp +Ho +De +De +De +De +De +De +De +Da +Da +Bf +Bf +IT +Bf +Bf +IR +Jg +Jg +IR ac ac ac @@ -29886,6 +35396,62 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(82,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -29895,6 +35461,78 @@ ac ac ac ac +bm +bO +cC +dl +dl +ew +fp +fZ +gN +hB +gT +iR +jM +kq +ld +lT +mD +nd +oE +ne +ne +lc +pz +pX +qN +gw +rE +sb +jR +RD +gw +ts +ts +ts +uC +ve +vC +we +Cy +xg +xW +zm +Ge +Av +AS +Cy +Iq +Ww +Ww +TW +Pe +Fg +Gc +GK +Gj +Gt +Hr +Hr +Hr +Hr +IZ +Hr +Hr +Hr +KM +Hr +KM +IZ +Hr +Hr +JU +Kd ac ac ac @@ -29915,58 +35553,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -29976,7 +35580,7 @@ MF MF MF "} -(47,1,1) = {" +(83,1,1) = {" MF MF MF @@ -29984,65 +35588,27 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qx -Qx -VF -Ws -Vr -Qd -RS -Rb -Ws -UL -Qx -Qx -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30051,6 +35617,78 @@ ac ac ac ac +bm +bP +cD +dm +dW +ex +fq +ga +gO +hC +gT +iS +jN +kB +le +lU +mE +ne +ne +ne +ne +lc +pA +pY +qO +gw +rF +sb +rR +tn +PR +ts +tH +uf +uD +ve +vC +so +Cy +xi +AM +AM +Iv +KL +Lu +Cy +Ww +CO +In +Ww +Pe +Fh +Fp +wf +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -30071,58 +35709,24 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30132,7 +35736,7 @@ MF MF MF "} -(48,1,1) = {" +(84,1,1) = {" MF MF MF @@ -30140,67 +35744,27 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -YA -QC -Ws -Mp -Rh -WF -VH -Ws -QC -Zp -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -bg -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30209,6 +35773,78 @@ ac ac ac ac +bm +bQ +cE +dn +dX +ey +fr +gb +gP +hD +gT +iT +jO +Vc +lc +lV +mF +lc +lc +lc +lc +lc +gw +pZ +gw +gw +gw +sd +sy +kC +gw +ts +ts +ts +uE +vf +vD +wg +Cy +xj +yx +yy +TH +AA +MJ +Cy +Ww +Di +Io +Ww +Pe +Fi +Fp +wf +ts +GL +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +Ou +IR ac ac ac @@ -30228,57 +35864,25 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30288,7 +35892,7 @@ MF MF MF "} -(49,1,1) = {" +(85,1,1) = {" MF MF MF @@ -30296,69 +35900,27 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -YA -QC -Sg -PF -Nb -NA -QC -Zp -ac -ac -gw -gw -gw -gw -kS -lw -lw -lw -kS -kS -kS -lw -lw -lw -kS -kS -kS -rU -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30367,6 +35929,78 @@ ac ac ac ac +bm +bR +cF +do +dY +ez +fr +gc +gQ +hE +ia +iU +jP +kD +lg +lW +mG +ng +nK +oi +oC +oY +pB +qa +qP +rn +pB +se +jR +sS +ha +tt +Mm +ha +uF +vg +jX +Ne +RP +Au +AM +Iv +zY +Lh +Bp +Cy +Qs +DK +SB +Iu +Pe +Ff +Fp +wf +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -30384,57 +36018,27 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30444,7 +36048,7 @@ MF MF MF "} -(50,1,1) = {" +(86,1,1) = {" MF MF MF @@ -30452,69 +36056,27 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -YA -Qx -UH -MO -Qx -Zp -ac -ac -ac -gw -ip -jt -kl -kS -lx -mm -mM -nv -nZ -oq -mM -pm -mM -qr -rc -rv -rV -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30523,6 +36085,78 @@ ac ac ac ac +bl +bS +cG +Uy +dY +eA +fs +gd +gR +hF +ib +iV +jQ +kE +lh +lh +mH +nh +nh +nh +nh +oZ +nh +qb +lh +lh +lh +sf +sz +lh +lh +lh +lh +lh +uG +vh +vE +Ne +RP +xk +wI +wI +zT +Ot +Bq +Cy +Sk +Xb +LZ +NP +Pe +TE +Fp +wf +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -30540,57 +36174,27 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30600,7 +36204,7 @@ MF MF MF "} -(51,1,1) = {" +(87,1,1) = {" MF MF MF @@ -30608,68 +36212,26 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Tt -SJ -Zn -VG -ac -ac -ac -ac -gw -iq -ju -km -kS -ly -mn -mN -mN -mN -mN -mN -pn -pI -pI -rd -rw -kS -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -30679,6 +36241,78 @@ ac ac ac ac +bl +bT +cH +dp +dZ +eB +bl +ge +gS +hG +gT +iW +jR +kF +li +li +li +li +li +li +li +li +li +qc +qQ +qQ +qQ +sg +qQ +qQ +qQ +qQ +qQ +qQ +qQ +vi +Zg +OB +RP +xl +yA +Af +QX +Lm +Br +Cy +Pe +Pe +Ip +Pe +Pe +Fl +Fo +FK +ts +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +IR ac ac ac @@ -30696,57 +36330,27 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30756,7 +36360,7 @@ MF MF MF "} -(52,1,1) = {" +(88,1,1) = {" MF MF MF @@ -30764,30 +36368,107 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac +ad +ae +ae +ae +ae +ae +ae +bl +bl +bl +bl +bl +bl +bl +gf +gT +gT +gT +ie +jR +kG +lj +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +lX +uH +vk +jM +XP +RP +xF +zi +Ag +Cy +AC +Cy +Cy +UN +PH +Oq +Iw +Pe +DO +Gg +wf +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -30795,32 +36476,7 @@ ac ac ac ac -Tt -PD -KR -VG ac -ad -gw -gw -gw -ir -jv -kn -kS -lz -mo -mO -nw -nw -nw -nw -nw -nw -qs -re -rw -kS ac ac ac @@ -30830,9 +36486,145 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aJ +MF +MF +MF +MF +MF +MF +"} +(89,1,1) = {" +MF +MF +MF +MF +MF +MF +aJ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +ae +ai +au +aE +ax +aV +bn +bU +cI +dq +ea +eC +ft +gg +ae +hd +hS +iX +jR +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +uI +La +jM +yz +Cy +xT +zj +NW +zX +AD +Bs +Vb +Xm +Oj +Xc +Nj +IC +Rm +YR +GO +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -30852,57 +36644,25 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -30912,7 +36672,7 @@ MF MF MF "} -(53,1,1) = {" +(90,1,1) = {" MF MF MF @@ -30920,74 +36680,107 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Qx -TQ -TQ -Qx -ac -ac -gw -hd -hS -is -jw -ko -kS -lA -mp -mP -nx -nx -nx -nx -nx -nx -qt -re -rw -kS -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +af +aj +av +aF +aM +aW +bo +bV +cJ +dr +eb +eD +fu +ae +ae +ae +ae +iY +jR +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +uI +vk +jM +VU +Cy +xV +zk +ZT +Cy +AE +Bt +Og +CM +Mc +Ix +Vz +Pe +DW +Fp +GO +ts +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +Ou +IR ac ac ac @@ -31008,57 +36801,24 @@ ac ac ac ac -hZ -Mf -Mf -Mf -Mf -Mf -Mf -Mf -Mf -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31068,7 +36828,7 @@ MF MF MF "} -(54,1,1) = {" +(91,1,1) = {" MF MF MF @@ -31076,74 +36836,107 @@ MF MF MF aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -bh -bh -bh -it -jx -kn -kS -lB -mp -mP -nx -nx -nx -nx -nx -nx -qt -re -rw -rV -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac +af +ak +aw +aw +aN +ax +ae +bW +cK +ds +ae +eE +fv +fu +gU +hH +ae +iZ +jR +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +uI +vk +jM +wl +Cy +Cy +Cy +MV +Cy +AF +Bu +Uo +Pu +FS +Pe +Pe +Pe +Eu +Fp +GO +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -31158,63 +36951,30 @@ ac ac ac ac -za ac ac ac ac ac ac -JW -Ak -Mw -Ak -Ak -Ak -Ak -JW -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31224,7 +36984,7 @@ MF MF MF "} -(55,1,1) = {" +(92,1,1) = {" MF MF MF @@ -31233,62 +36993,106 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -bg -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -bh -he -bh -iu -jy -kn -kS -lC -mp -mQ -ny -ny -or -oS -nx -nx -qt -re -rx -rV +af +al +ax +aG +aO +aX +ae +bX +cL +dt +ae +eF +fw +gh +gV +hI +id +ja +jS +kG +lk +lY +lY +lY +lY +lY +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lY +lY +lY +lY +lY +uI +vk +jM +wk +wL +hd +Cy +LL +Cy +AO +Bv +FS +zP +NV +Pe +tH +DL +Pq +Fp +GO +Gj +Gv +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +Kd ac ac ac @@ -31309,68 +37113,24 @@ ac ac ac ac -xG -xG -xG -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Ak -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31380,7 +37140,7 @@ MF MF MF "} -(56,1,1) = {" +(93,1,1) = {" MF MF MF @@ -31389,62 +37149,107 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +af +am +ax +ae +ae +ae +ae +bY +ae +ae +ae +ae +ae +ae +ae +ae +ae +vo +jR +kG +lk +lY +lY +lY +lY +uI +XL +TZ +Sr +uP +XC +yD +Sr +Lk +HC +lk +lY +lY +lY +lY +uI +vk +jM +wn +wJ +FQ +FQ +zS +FQ +AO +Bw +Cn +AB +AB +AB +AB +AB +Ev +EC +GQ +ts +GL +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +IY +JV +IR ac -bh -bh -bh -bh -bh -bh -bh -bh -bh -hf -bh -iv -jz -kn -kS -lD -mq -mQ -ny -ny -lE -oT -nx -nx -qt -re -rw -rV ac ac ac @@ -31461,72 +37266,27 @@ ac ac ac ac -za ac ac ac -xG -BS -xG -Dx -DI -Et -ET -FD -Gn -GG -Hk -Hk -HE -Hk -Hk -Hk -Dx -Dx -Dx -Ak -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31536,7 +37296,7 @@ MF MF MF "} -(57,1,1) = {" +(94,1,1) = {" MF MF MF @@ -31545,62 +37305,111 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +ae +an +ay +ae +aP +aY +bp +bZ +cM +du +ae +eH +fx +gi +aw +aL +ae +jb +jT +kG +ME +lZ +lZ +lZ +lZ +Ya +ZA +OL +lq +lq +lq +lq +lq +OQ +Xw +ll +lZ +lZ +lZ +lZ +uJ +vk +jM +wi +wJ +xm +yB +zp +wJ +wJ +wJ +wJ +AB +CL +CP +Dj +AB +Ew +Gg +GO +Gj +GM +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +Hs +JX +IR ac ac ac ac ac -bh -bv -bv -bv -bv -eo -eZ -fK -gx -hg -bh -TL -jz -kn -kT -lE -mr -mQ -ny -ny -os -oU -nx -nx -qt -re -rw -kS ac ac ac @@ -31610,79 +37419,30 @@ ac ac ac ac -tp -ur -ur -ur -tp -xG -xG -xG -xG -xG -xG -xG -BT -xG -Dx -Ea -ED -ED -FE -Gq -GG -Hl -Hk -Hl -Hk -HY -Hk -Dx -Dx -Dx -Ak -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31692,7 +37452,7 @@ MF MF MF "} -(58,1,1) = {" +(95,1,1) = {" MF MF MF @@ -31701,62 +37461,115 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +ae +ae +ae +ae +aQ +aQ +aZ +bZ +ax +QM +ae +aq +aq +aU +aw +aw +ae +qB +jU +kn +PB +PB +PB +PB +PB +PB +lq +OL +lq +RR +RR +RR +lq +OQ +lq +PB +PB +PB +PB +PB +PB +Li +QO +SR +wM +xn +xn +Nu +zU +Aw +Bl +BZ +Cc +CF +CQ +Dk +DM +Ex +EH +GO +Gj +GN +GN +GN +GN +GN +Ja +GR +GN +Jl +Jx +GN +GN +Ja +GN +GN +GN +IR +Jg +Jg +IR +ac ac ac ac ac ac -bh -bv -bv -bv -bv -eo -fa -fL -gy -hh -bh -iw -jA -kp -kT -lE -mr -mQ -ny -ny -ny -ny -ny -ny -qu -re -rw -kS ac ac ac @@ -31766,79 +37579,26 @@ ac ac ac ac -uq -us -vu -vW -tp -xH -xH -yM -yY -Aj -xG -Bb -BW -Cz -Dx -Ea -ED -EU -FF -Gs -GJ -Hk -Hk -Hk -Hk -Hk -Il -Dx -Dx -Dx -Ak -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -31848,7 +37608,7 @@ MF MF MF "} -(59,1,1) = {" +(96,1,1) = {" MF MF MF @@ -31857,62 +37617,115 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +af +ao +aw +aw +aw +aw +aw +cb +ax +aw +ec +aq +fz +aY +aw +aw +ec +jd +jV +kn +lq +SZ +SZ +SZ +SZ +SZ +SZ +Wc +PN +xs +ZE +xs +PN +Xv +PN +PN +PN +PN +PN +PN +Rz +Oo +vG +kx +wJ +xS +zh +zq +wJ +Ax +Bm +xU +AB +CG +CU +Dl +AB +EB +Fn +GV +ts +GP +GP +IR +XQ +GN +IR +GN +GR +Jm +Jm +GR +GN +IR +Hm +GR +Mv +IR +Kf +Kl +IR +IR ac ac ac ac ac -bh -bh -bh -bh -bh -bh -fb -fL -gy -hi -bh -ix -jz -kq -kU -lF -mr -mQ -ny -ny -ny -ny -ny -ny -qu -re -ry -kS ac ac ac @@ -31922,79 +37735,26 @@ ac ac ac ac -uq -ut -vv -wm -tp -xH -xH -xH -zb -Al -xG -Bg -BX -CW -Dx -Eb -ED -ED -FI -Gq -GG -Hl -Hk -Hl -Hk -HZ -Hk -Dx -Dx -Dx -Ak -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -32004,7 +37764,7 @@ MF MF MF "} -(60,1,1) = {" +(97,1,1) = {" MF MF MF @@ -32013,62 +37773,116 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac ac +af +aw +aw +aI +aS +Xq +YF +cc +cO +cO +PQ +cO +fA +aw +aw +aq +ec +je +jW +kn +nS +nS +nS +nS +nS +nS +lq +OQ +lq +RR +RR +RR +lq +OL +lq +nS +nS +nS +nS +nS +nS +Li +jR +wh +pc +pc +pc +pc +pc +pc +Bn +pc +pc +pc +pc +pc +pc +Fv +Fo +GS +Gk +GR +GR +HV +GR +GT +Jb +GR +GT +WG +GR +GT +GR +GN +GT +GR +GR +IR +Kg +Kv +Km +Kd ac ac ac ac ac ac -bh -bw -bw -cV -dK -ep -fc -fL -gy -hh -bh -iy -jB -kr -kV -lG -ms -mR -nz -nz -nz -nz -nz -nz -qv -re -rw -rV ac ac ac @@ -32078,79 +37892,25 @@ ac ac ac ac -uq -ut -vw -wo -tp -xH -xH -yN -zb -Am -zv -Bh -BY -CX -Dy -Ed -yC -EV -FJ -Gw -GX -Hk -Hk -Hk -Hk -Hk -Hk -Dx -Dx -Dx -MK -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -32160,7 +37920,7 @@ MF MF MF "} -(61,1,1) = {" +(98,1,1) = {" MF MF MF @@ -32169,62 +37929,115 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +ae +aq +aq +aw +aT +aw +aq +aq +aq +aw +ed +aw +aw +ax +aq +aq +ih +jf +jX +kG +Zh +lX +lX +lX +lX +uH +ZA +OQ +lq +lq +lq +lq +lq +OL +Xw +lj +lX +lX +lX +lX +Xk +vk +jR +Ts +pc +xo +ZR +Qi +Ss +Ir +Bo +Bx +ZR +XB +Ss +RY +pc +Fw +Fp +GO +Gj +GT +Ht +GP +Is +IS +Jc +Jh +IS +Jh +Jh +IS +Jh +PY +IS +JL +Jh +Ke +Kh +Kv +Kn +Kd ac ac ac ac ac -bh -bx -ci -cW -cW -cW -fd -fL -gy -hj -bh -iz -jC -ks -kW -lH -mt -mS -nA -nA -nA -nA -nA -pJ -qw -rf -rz -rV ac ac ac @@ -32234,79 +38047,26 @@ ac ac ac ac -tp -uu -vF -wx -tp -xH -xH -yN -zc -An -AT -Bi -Cd -CY -Dz -Ee -ED -ED -FN -Gq -GG -Hl -Hk -Hl -Hk -HZ -Hk -Dx -Dx -Dx -JW -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -32316,7 +38076,7 @@ MF MF MF "} -(62,1,1) = {" +(99,1,1) = {" MF MF MF @@ -32325,62 +38085,115 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac ac +af +ar +aq +aK +aw +aw +ax +ax +ax +aw +ed +aw +aw +ax +aq +QA +ii +iV +jY +kG +lk +lY +lY +lY +lY +uI +Ly +YQ +KI +WK +Qv +VK +KI +Ub +Wi +lk +lY +lY +lY +lY +uI +vk +jR +wp +wQ +Ir +ZR +XB +Ss +Ir +AG +Ir +ZR +Wn +Ss +Ir +wQ +Fx +Fq +Gd +Gl +GW +Hu +HW +It +IV +GN +GR +Vx +GR +GR +Vx +GR +JF +Vx +JM +GR +IR +Ki +Kv +Kn +Kd ac ac ac ac ac -bh -by -cj -cX -cX -cX -fe -fL -gz -hk -bh -iA -jD -kt -kX -lI -mu -mT -mu -mu -mu -mu -mu -pK -qx -rg -rA -rV ac ac ac @@ -32390,79 +38203,26 @@ ac ac ac ac -uq -uv -vQ -wy -tp -xH -xH -yN -zd -Ao -xG -Bj -Co -CZ -Dx -Ef -ED -EX -FO -Gx -GZ -Hk -Hk -Hk -Hk -Hk -Il -Dx -Dx -Dx -Ak -Hv -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF @@ -32472,7 +38232,7 @@ MF MF MF "} -(63,1,1) = {" +(100,1,1) = {" MF MF MF @@ -32481,139 +38241,139 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -bh -bz -ck -cY -cY -cY -ff -fM -gA -hl -hT -iB -jE -ku -kS -lJ -mv -mU -mv -mv -mv -mv -mv -pL -qy -rh -rB -kS -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac -uq -uO -vR -wz -tp -xI -xI -yO -ze -Ap -xG -BC -Cp -Db -Dx -Eg -ED -ED -FE -Gq -GG -Hl -Hk -Hl -Hk -HZ -Hk -Dx -Dx -Dx -Ak -Ak -Bz -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +af +as +aw +aL +aU +aU +br +aw +aw +eE +ae +eN +aw +aw +aP +aw +ae +jg +jX +kG +lk +lY +lY +lY +lY +lY +lX +lX +lX +lX +lX +lX +lX +lX +lX +lY +lY +lY +lY +lY +uI +vk +jR +wp +Ac +Ir +ZR +XB +Ss +Ir +AH +Ir +ZR +XB +Ss +Ir +Ac +Fx +Fp +OJ +ts +IR +IR +IR +IO +IW +IR +Hm +Jk +Jq +GR +Jk +GN +IR +GN +JM +GR +IR +Kj +Pd +IR +IR +Wm +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -32628,7 +38388,7 @@ MF MF MF "} -(64,1,1) = {" +(101,1,1) = {" MF MF MF @@ -32637,62 +38397,116 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac ac +ae +at +at +ae +at +at +ae +at +at +ae +ae +ae +at +at +ae +ae +ae +jh +jX +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +uI +vk +rR +zt +Rn +Wp +Wp +Wp +Wp +Wp +Np +Ir +Ir +Ir +Ir +Ir +Ac +Fx +Fp +GO +ts +GY +Hx +IR +IP +IX +Jf +GN +GN +Jl +Jx +GN +GN +Jf +GN +JN +GN +IR +Kk +Kk +IR +ac ac ac ac ac ac ac -bh -bA -cl -cW -cW -cW -fd -fa -fa -hm -hU -iC -jF -kv -kS -lJ -mv -mV -nB -oa -ot -oa -mv -pM -qz -ri -rC -kS ac ac ac @@ -32702,70 +38516,16 @@ ac ac ac ac -uq -uV -vS -wA -tp -xK -ym -yP -zf -Aq -xG -BC -Cp -Cu -Dx -Eh -EG -EY -FP -Gy -Ha -Hk -Hk -HF -Hk -Hk -Hk -Dx -Dx -Dx -Ay -Ak -JW ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -32784,7 +38544,7 @@ MF MF MF "} -(65,1,1) = {" +(102,1,1) = {" MF MF MF @@ -32793,25 +38553,24 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -32821,107 +38580,108 @@ ac ac ac ac -bh -bB -cm -cX -cX -cX -cX -cX -gB -hn -bh -iD -jG -kw -kY -kY -kZ -mW -nC -kY -kY -kY -kT -pN -qA -kS -rD -kS ac ac ac ac ac ac -tB -tB -tB -tp -tp -tp -wB -tp -xG -xG -xG -zv -xG -xG -BD -Cq -Dg -Dx -Dx -Dx -EZ -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -Dx -AI -Ay ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +gw +hd +hS +ji +jX +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +uI +vk +jR +wp +Om +Ir +Ir +Ir +Ir +YD +AJ +Up +Ir +Ir +Ir +Ir +Om +Fx +Fp +GU +ts +ts +ts +ts +IQ +Hr +Hr +Hr +Hr +Hr +Hr +Hr +Hr +JG +JG +JO +JG +IR +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -32940,7 +38700,7 @@ MF MF MF "} -(66,1,1) = {" +(103,1,1) = {" MF MF MF @@ -32949,25 +38709,24 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -32976,33 +38735,87 @@ ac ac ac ac -ad -bh -bC -cn -cZ -cZ -eq -fg -fN -gC -ho -bh -jc -jH -kx -kY -lK -mw -mX -mw -ob -ou -kY -po -pO -ro +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +gw gw +gw +ix +jX +kG +lk +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lY +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +uJ +vk +jR +wr +pc +Tf +Ir +Ir +QU +Ua +AK +Ce +WU +Ir +Ir +PG +pc +Fy +Fr +GV +Gj +AN +AN +Gj +IY +IY +IY +IY +IY +IY +IY +IY +IY +IR +IR +JP +IR +IR +ac +ac +ac +ac +ac +ac +ac ac ac ac @@ -33011,73 +38824,20 @@ ac ac ac ac -tC -tT -tW -tZ -uW -vU -wC -wY -yh -yn -yQ -zy -Ar -AV -BE -Cr -Dh -xu -DB -Ek -Er -Ah -Ds -Dt -Dw -EK -EL -Fb -Fk -FG -Go -Kt -KA -AI -Ay ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -33096,7 +38856,7 @@ MF MF MF "} -(67,1,1) = {" +(104,1,1) = {" MF MF MF @@ -33105,25 +38865,24 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33133,32 +38892,80 @@ ac ac ac ac -bi -bi -bi -bi -bi -bi -fh -fh -fh -fh -fh -iF -jI -ky -kZ -lL -mw -mX -mw -oc -ov -kY -ir +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ik +ix +jX +kG +ll +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +lZ +Ya +NG +Sf +Ng +Xo +Sf +Ng +Xo +Sf +Ng +Li jR -qC -lP +wp +pc +pc +wQ +wQ +pc +pc +wR +pc +pc +wQ +wQ +pc +pc +Fz +Fs +GO +Gj +AN +AN +Gj +IY +Ji +Ji +Ji +Jw +Ji +Ji +Ji +JC +IR +JI +JQ +JY +IR +ac ac ac ac @@ -33167,73 +38974,26 @@ ac ac ac ac -tC -tU -tX -ua -uX -vV -wD -xh -yi -yu -yR -yR -At -yR -BF -Cs -Aa -Ct -Dv -Aa -Df -Aa -Aa -Aa -DC -DC -DC -Fj -DC -HR -DC -KE -KK -AI -Ay -Ci ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -33252,7 +39012,7 @@ MF MF MF "} -(68,1,1) = {" +(105,1,1) = {" MF MF MF @@ -33261,26 +39021,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33289,32 +39048,6 @@ ac ac ac ac -bi -bD -co -da -dL -bi -fi -fO -gD -hp -fj -iG -jJ -kx -kZ -lL -mw -mX -mw -oc -ow -kY -pp -jR -qC -lP ac ac ac @@ -33322,71 +39055,98 @@ ac ac ac ac -Pw -tD -tV -tY -ub -vj -vU -wW -xy -yj -yI -yS -xy -AP -zE -AW -BH -ym -Cv -Ej -El -vH -Hb -Dn -Dn -DQ -DQ -DQ -Fc -Fm -FL -IL -KJ -KV -AI -Ay +ac +ac +ac +ac +ik +ix +jX +kD +lm +lm +lm +lm +lm +lm +lm +lm +lm +qd +qR +qR +Yu +Yu +sA +sT +sT +sT +tI +ug +ug +vl +vI +ws +wS +lf +xv +xv +zs +TP +AL +BB +Ck +CS +Do +Do +Ez +FA +Ae +GO +Gj +AN +AN +Gj +IY +Jj +Jn +Jr +Js +Jv +JE +BA +IY +JH +JJ +JR +JZ +IR +ac +ac ac ac ac ac ac ac -hZ -hZ -hZ -hZ -hZ ac ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -33408,7 +39168,7 @@ MF MF MF "} -(69,1,1) = {" +(106,1,1) = {" MF MF MF @@ -33417,25 +39177,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33445,75 +39206,78 @@ ac ac ac ac -bi -bE -cp -cp -dM -bi -fj -fj -gE -hq -hV -iH -jK -kx -kZ -lM -mw -mY -nD -od -ox -oV -pq -pP -qC -lP ac ac ac ac ac ac -tE -tq -tE -tE -tE -uc -vt -xa -xb -As -As -yK -As -As -xb -zZ -AX -Dg -Da -Da -Da -Fa -DA -Fa -Da -Da -Ks -Ks -Ks -Da -Da -Da -HN -KO -KY -AI -Ay +ac +ac +ac +ik +ix +jZ +kH +kH +kH +kH +ni +nL +oj +nL +pa +nL +qe +nL +nL +nL +nL +sB +nL +td +nL +tJ +nL +nL +vm +vJ +wt +wT +wa +yd +yG +yG +yG +Ae +yG +Cl +CT +yG +yG +vZ +FB +Ft +Gf +Gm +Hd +HT +Gj +IY +Jj +Js +Js +Js +Jz +JE +BA +IY +JH +JJ +JS +Ka +IR +ac ac ac ac @@ -33530,19 +39294,15 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -33564,7 +39324,7 @@ MF MF MF "} -(70,1,1) = {" +(107,1,1) = {" MF MF MF @@ -33573,26 +39333,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33601,75 +39361,82 @@ ac ac ac ac -bi -bF -cq -db -dN -bi -fi -fP -gF -hr -fj -iI -jz -kx -kZ -lN -mw -mX -mw -oe -oy -oW -pr -pQ -qD -gw ac ac ac ac ac ac -tF -tr -uw -uY -vx -vX -wE -xa -wX -xz -yk -yL -yT -zz -As -Ab -AY -BI -Ei -EP -FU -GH -HH -Ie -Iy -IU -LM -IH -HM -yc -Ia -Da -HS -KU -KZ -Kx -KB +fF +ac +ac +ac +gw +ix +ka +kI +ln +ma +ma +nj +nM +ok +oD +pb +pC +qf +qS +zr +rG +pS +sC +pS +jX +tu +tK +uh +uK +vn +vn +vn +wU +xw +ye +ZS +SU +SU +Ru +xw +xw +CH +CH +LJ +EA +Ku +Fu +Gh +WS +Hg +HU +Gj +IY +Jj +Jp +Jt +Js +Jz +JE +BA +IY +JH +JJ +JS +Kb +IR +ac +ac +ac +ac ac ac ac @@ -33686,19 +39453,12 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ab +ab +ab +ab +ab ab ab ab @@ -33720,7 +39480,7 @@ MF MF MF "} -(71,1,1) = {" +(108,1,1) = {" MF MF MF @@ -33729,27 +39489,26 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33757,75 +39516,80 @@ ac ac ac ac -bi -bG -cr -dc -dO -bi -fj -fj -gG -hs -fj -iJ -jz -kx -kZ -lN -mw -mZ -nE -mw -mw -kZ -ix -ka -qE -gw +be +bs +bs +be +bs +bs +bs +be go go gw gw +ix +ka +kJ +lo +mb +lq +nk +Uj +ol +Pv +Pv +gw +qg gw +Pv +rH +sh +sD +sh +te +tv +tL +sh +uL +rJ +rJ +vK +rJ +rJ +sF +rJ +SW +PC +rJ +vK +rJ +rJ +Ym +rJ +vK +vK +vK +rJ +ts +ts +ts +ts +IY +Ji +Ji +Ji +Jw +Ji +Ji +Ji +IY +JH +JJ +JT +Kc +IR ac -tG -ud -ud -ud -ud -ud -ud -xa -xA -xJ -yo -yU -zC -zA -AQ -AZ -BN -Cw -Eq -EQ -FW -GI -HI -Ig -Iz -yF -Ai -CR -DD -DP -Ib -Ks -Jd -HX -Lb -Kx -KB ac ac ac @@ -33843,18 +39607,14 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ab +ab +ab +ab +ab ab ab ab @@ -33876,7 +39636,7 @@ MF MF MF "} -(72,1,1) = {" +(109,1,1) = {" MF MF MF @@ -33885,26 +39645,23 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -33913,75 +39670,84 @@ ac ac ac ac -bi -bH -cs -dd -dP -bi -fk -fQ -gF -ht -fj -iK -jz -kx -kY -lO -mx -na -nF -of -oz -kY -iK -ka -qF -ha -ha +ac +ac +bf +bt +cg +cS +cg +ef +eO +fG +gp ha -ss -sR +hP +il +jk +ka +kK +lp +TS +nr +nl +nN +ol +oF +pd gw +qh +gw +Pv +rI +si +sE +sU +tf +tw +tM +ui +uM +rJ +vL +wu +wV +ww +SK +xp +sK +sZ +xq +sk +xr +vK +sX +Lg +KW +sX +sX +sX +vK +ac +ac +IR +IY +IY +IY +IY +IY +IY +IY +IY +IY +IR +JK +JK +JK +IR +ac +ac ac -tG -ud -ux -ux -ux -ux -ud -xa -xB -xL -yf -yV -zD -zB -As -Ba -BR -Cx -Ei -wq -FV -yE -HJ -FV -IA -LA -LO -LX -HO -FV -FV -HG -IM -Ic -Lc -AI -Ay ac ac ac @@ -33999,18 +39765,12 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab ab ab ab @@ -34032,7 +39792,7 @@ MF MF MF "} -(73,1,1) = {" +(110,1,1) = {" MF MF MF @@ -34041,128 +39801,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -bi -bi -ct -bi -bi -bi -bj -bj -bj -bj -bj -iL -jL -kz -kY -kY -kY -nb -nb -kY -kY -kY -ps -pR -qG -kE -kE -kE -st -kx -lP -ac -tG -ud -ux -ux -ux -ux -ud -xa -xC -xM -yq -yW -yp -zI -xb -Bf -BG -Bf -Bf -DE -Em -EN -HK -Ii -If -LB -LR -Ih -En -DR -Id -Ks -JD -HX -Lt -AI -Ay -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -34179,122 +39817,90 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(74,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac +ab +ab ac ac ac ac -bj -bI -cu -de -dQ -er -fl -fR -fl -hu -hW -iM -jz -kA -la -gw ac ac ac ac ac -ik -pt -pS -qH -rj -rj -rW -jR -kx -lP +bf +bu +ch +be +dB +eg +eP +fH +gq +hb +hQ +im +hb +kc +kL +lq +lq +mc +nm +nO +ol +oG +pe +Pv +qi +Pv +Pv +rJ +rJ +sF +sV +sF +tx +sF +rJ +rJ +rJ +vM +Az +Az +Az +Az +Az +sK +sZ +Az +Az +Dq +DX +Ri +KP +QG +NU +NU +sX +vK ac -tG -ud -ux -ux -ux -ux -ud -xa -xD -xN -yr -xN -zF -zJ -xb -Bc -BM -CA -Bf -DF -En -EO -HL -Ij -IB -LC -LS -Dp -Le -ZC -zx -Da -IN -HX -Lb -Kx -KD ac +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR +IR ac ac ac @@ -34315,16 +39921,14 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -34344,7 +39948,7 @@ MF MF MF "} -(75,1,1) = {" +(111,1,1) = {" MF MF MF @@ -34353,26 +39957,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -34381,78 +39984,78 @@ ac ac ac ac -bj -bJ -cv -df -df -es -fm -fS -gH -hv -hX -iM -jz -kA -la -lP +be +be +be +be +dC +eh +eQ +fG +gr +hc +hR +in +Of +kd +kM +lr +md +LD +nn +nP +om +oH +pf +pD +qj +oH +rp +rK +sj +sG +sW +sG +ty +tN +Wo +uN +vp +Wo +Wo +Xx +Uf +Uf +Uf +sL +ta +Rl +Qg +YE +rJ +Lz +KQ +xt +KQ +Gp +rJ +rJ +ac +ac +ac +ac +ac ac ac ac ac ac -ik -pu -pT -qI -rk -hc -rX -su -kx -gw ac -tG -ud -ux -ux -ux -ux -ud -xa -xE -xO -ys -yX -zG -zK -xb -Bd -BO -CB -Bf -DG -Eo -ER -De -De -GA -Hc -Hp -De -De -DT -Da -Da -Ko -HX -Lw -AI -Ay ac ac ac +kk +ac ac ac ac @@ -34473,19 +40076,20 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -34500,7 +40104,7 @@ MF MF MF "} -(76,1,1) = {" +(112,1,1) = {" MF MF MF @@ -34509,27 +40113,90 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +bf +bt +cg +cT +XI +eh +eR +be +gw +gw +gw +io +io +io +WN +WN +io +io +LH +io +ol +oI +pg +pE +qk +qU +Pv +rL +sk +sH +UJ +th +Zc +KX +Zc +PA +Qo +Zc +Zc +QH +YJ +YP +XG +sM +tb +YJ +Cb +DY +rJ +KC +KQ +Yy +NU +sX +UI +vK +ac ac ac ac @@ -34537,75 +40204,11 @@ ac ac ac ac -bk -bK -cw -dg -dR -bj -fn -fT -bj -hw -hY -iM -jz -kA -la -lP ac ac -nG ac ac -oX -oX -oX -qJ -oX -oX -rY -jX -kx -lP ac -tG -ud -ud -ux -ux -ud -ud -xa -xb -As -yt -As -xb -zL -xb -Be -BP -CC -Bf -DH -Ep -ES -De -FT -GB -He -Hq -Hz -De -EM -EM -Im -zb -HX -Lb -Kx -KD ac ac ac @@ -34629,19 +40232,20 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -34656,7 +40260,7 @@ MF MF MF "} -(77,1,1) = {" +(113,1,1) = {" MF MF MF @@ -34665,26 +40269,25 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -34693,76 +40296,75 @@ ac ac ac ac -bk -bL -cx -dh -dS -et -dh -fU -gI -hx -bj -iN -jz -kA -lb -gw +bf +bu +ch +be +dD +eh +eS +be +YI +Sz +Lj +Nd +jl +ke +kN +ls +me +Rc +Nr +nR +on +oJ +oJ +oJ +oJ +oJ +oJ +rM +sl +sH +UJ +ti +Az +tO +ul +Az +Az +Az +Az +XF +VD +yg +yJ +sK +sZ +VD +DN +Zd +vK +KC +sX +sX +FH +Gr +Tv +vK +ac +ac +ac +ac +ac +ac +ac ac ac ac ac ac -oX -pv -pU -qK -pv -oX -rZ -sv -kx -lP ac -ts -ts -uy -uZ -uZ -tg -wF -xb -xb -wZ -xP -yl -xb -xb -xb -Bf -BQ -Bf -Bf -up -IE -up -De -FX -GC -Hf -Hw -HA -De -Cj -EE -Da -Kq -ID -LE -AI -Ay -Ci ac ac ac @@ -34785,19 +40387,21 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -34812,7 +40416,7 @@ MF MF MF "} -(78,1,1) = {" +(114,1,1) = {" MF MF MF @@ -34820,27 +40424,25 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -34849,75 +40451,73 @@ ac ac ac ac -bk -bK -cy -di -dT -df -df -fV -gJ -hy -bj -iO -jM -kv -lc -lc -mz -lc -lc -lc -lc -lc -pw -pV -qL -rl -oX -iE -sw -kx -gw +ac +be +be +be +be +dE +ei +eT +Uh +RX +Oe +LT +LT +LT +Pb +Qz +DS +DS +DS +np +nX +oo +oK +ph +pF +ql +mg +oJ +ru +ru +sI +sY +sY +tz +tP +ru +mL +uQ +uU +vr +XF +Az +Az +Az +sK +tc +Az +DZ +Ld +rJ +Ln +vK +vK +Ty +Ty +Ty +Ty +Ty +Ty +ac +ac +ac +ac +ac +ac ac ac -ts -uz -va -vy -wa -wG -xc -xR -xQ -yv -yZ -zH -AU -Kr -BU -Dc -Ec -BJ -EW -Gz -Hn -FC -FY -GD -Hi -GD -HB -De -DU -EM -Bf -Bf -II -Bf -AR -Ay ac ac ac @@ -34942,6 +40542,10 @@ ac ac ac ac +ac +ac +ab +ab ab ab ab @@ -34968,7 +40572,7 @@ MF MF MF "} -(79,1,1) = {" +(115,1,1) = {" MF MF MF @@ -34977,26 +40581,24 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -35005,75 +40607,69 @@ ac ac ac ac -bk -bM -cz -dj -dU -eu -fo -fW -gK -hz -bj -iP -jM -kx -lc -lQ -mA -lc -nH -og -oA -lc -px -pV -qL -rm -oX -sa -sx -kx -lP +ac +bf +bt +cg +cU +cg +ej +eU +Uh +WT +IG +WL +WL +WL +wj +WL +WL +WL +WL +Vy +nT +UB +oL +oK +UW +qm +ml +rq +fI +jq +kO +mf +qW +mK +oN +vN +no +vO +vq +vs +XF +YJ +YP +XG +sK +sZ +YJ +Cb +DY +vK +Lp +Lv +EF +Ty +MB +Oi +ZI +NR +Ty +ac +ac ac ac -ue -uA -vb -vz -wb -wb -xd -wb -Gb -wb -zN -Ls -Ls -BK -CD -Dd -CD -CD -Fd -Ga -Hn -FC -FZ -GE -Hi -GE -GE -De -DV -EE -Bf -Kz -IJ -LF -AR -Ay ac ac ac @@ -35097,7 +40693,15 @@ ac ac ac ac -hZ +ac +ac +ac +ac +ac +ac +ac +ab +ab ab ab ab @@ -35124,7 +40728,7 @@ MF MF MF "} -(80,1,1) = {" +(116,1,1) = {" MF MF MF @@ -35133,25 +40737,91 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +bf +bu +ch +be +dF +ek +eV +fG +WT +ya +ya +ya +ya +kf +ya +ya +ya +ya +Vy +nU +on +jp +oK +oK +qn +qX +rr +fJ +js +kP +fJ +mj +fJ +un +xZ +no +uS +vq +vs +XF +VD +yg +yJ +sN +sZ +VD +DN +KN +nq +Lq +Wd +Un +Ty +TG +Oi +Ty +Ty +Ty ac ac ac @@ -35161,78 +40831,10 @@ ac ac ac ac -bl -bl -cA -bl -bl -bl -bl -fX -gL -fX -gT -ic -jM -kx -lc -lR -mB -nc -nI -oh -oB -lc -py -pW -qM -py -oX -sb -jR -kx -lP ac ac -ue -uA -vc -vA -wc -wH -xe -Bk -yw -zg -zO -OA -wH -BL -BV -zu -Sj -CE -Fe -Fp -Hn -FC -Gi -GF -Hj -GF -HD -De -DV -EM -Bf -Lx -IK -LG -AR -Ay ac ac -fF ac ac ac @@ -35253,8 +40855,10 @@ ac ac ac ac -hZ -hZ +ab +ab +ab +ab ab ab ab @@ -35280,7 +40884,7 @@ MF MF MF "} -(81,1,1) = {" +(117,1,1) = {" MF MF MF @@ -35289,25 +40893,94 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ad +be +be +be +be +WQ +WQ +eW +be +VL +IG +WL +WL +WL +wj +WL +WL +WL +WL +Vy +nV +on +jr +pi +pG +qo +qY +oJ +gs +kb +kQ +lu +mk +mi +lu +uo +no +uR +vq +vs +Zx +YL +Az +Az +sK +sZ +Az +DZ +HP +Ty +Ty +Ty +Ty +Ty +Ps +Oi +PL +Qf +Ty +Wm +ac +ac ac ac ac @@ -35317,78 +40990,8 @@ ac ac ac ac -bl -bN -cB -dk -dV -ev -bl -fY -gM -hA -gT -iQ -jM -Qb -lc -lS -mC -lc -lc -lc -lc -lc -gw -gw -gw -gw -oX -sc -jR -kx -gw ac ac -ts -uB -vd -vB -wd -Cy -Cy -Cy -Cy -Cy -IF -Cy -Cy -Pe -Pe -Pe -Pe -Pe -Ey -Fp -Ho -De -De -De -De -De -De -De -Da -Da -Bf -Bf -IT -Bf -Bf -IR -Jg -Jg -IR ac ac ac @@ -35408,9 +41011,10 @@ ac ac ac ac -hZ -hZ -hZ +ab +ab +ab +ab ab ab ab @@ -35436,7 +41040,7 @@ MF MF MF "} -(82,1,1) = {" +(118,1,1) = {" MF MF MF @@ -35444,26 +41048,28 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -35473,78 +41079,66 @@ ac ac ac ac -bm -bO -cC -dl -dl -ew -fp -fZ -gN -hB -gT -iR -jM -kq -ld -lT -mD -nd -oE -ne -ne -lc -pz -pX -qN -gw -rE -sb -jR -RD -gw -ts -ts -ts -uC -ve -vC -we -Cy -xg -xW -zm -Ge -Av -AS -Cy -Iq -Ww -Ww -TW -Pe -Fg -Gc -GK -Gj -Gt -Hr -Hr -Hr -Hr -IZ -Hr -Hr -Hr -KM -Hr -KM -IZ -Hr -Hr -JU -Kd +ac +ac +ac +ac +Yb +WT +ya +ya +ya +ya +ya +ya +ya +ya +ya +Vy +Sl +on +oJ +oJ +oJ +oJ +oJ +oJ +jj +kg +kR +lu +lu +qW +lu +vN +ns +uR +vq +vs +ST +Zc +Zc +Zc +sO +tj +Zc +JB +Kw +Ky +EI +Gu +RG +OM +RQ +Oi +Ty +Ty +Ty +ac +ac +ac +ac +ac ac ac ac @@ -35565,8 +41159,18 @@ ac ac ac ac -hZ -hZ +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab ab ab ab @@ -35592,7 +41196,7 @@ MF MF MF "} -(83,1,1) = {" +(119,1,1) = {" MF MF MF @@ -35600,27 +41204,96 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Yb +WT +IG +WL +WL +WL +wj +WL +WL +WL +WL +Vy +nW +op +oO +pj +MT +qp +qZ +rs +jm +kh +lt +lu +mI +mi +lu +xx +no +uR +vq +vs +SI +Qu +Az +Az +sK +sZ +Az +Kp +Dm +Ty +EJ +FM +Hh +Ml +KS +Oi +To +Qf +Ty +ac +ac +ac +ac ac ac ac @@ -35629,78 +41302,6 @@ ac ac ac ac -bm -bP -cD -dm -dW -ex -fq -ga -gO -hC -gT -iS -jN -kB -le -lU -mE -ne -ne -ne -ne -lc -pA -pY -qO -gw -rF -sb -rR -tn -PR -ts -tH -uf -uD -ve -vC -so -Cy -xi -AM -AM -Iv -KL -Lu -Cy -Ww -CO -In -Ww -Pe -Fh -Fp -wf -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd ac ac ac @@ -35721,8 +41322,11 @@ ac ac ac ac -hZ -hZ +ab +ab +ab +ab +ab ab ab ab @@ -35748,7 +41352,7 @@ MF MF MF "} -(84,1,1) = {" +(120,1,1) = {" MF MF MF @@ -35756,27 +41360,27 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -35785,78 +41389,66 @@ ac ac ac ac -bm -bQ -cE -dn -dX -ey -fr -gb -gP -hD -gT -iT -jO -Vc -lc -lV -mF -lc -lc -lc -lc -lc -gw -pZ -gw -gw -gw -sd -sy -kC -gw -ts -ts -ts -uE -vf -vD -wg -Cy -xj -yx -yy -TH -AA -MJ -Cy -Ww -Di -Io -Ww -Pe -Fi -Fp -wf -ts -GL -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -Ou -IR +ac +ac +ac +ac +ac +ac +Yb +ZD +Qw +Qw +Qw +Qw +Qw +UD +Qw +Qw +Qw +yb +nX +Or +pk +pk +pk +qq +ra +rt +jn +ki +lu +lu +lu +lu +lu +xx +no +uR +uR +um +nt +rN +rS +rS +rS +rS +rS +to +tR +Ty +Ty +Ty +Ty +Ty +Ty +Ty +Ty +Ty +Ty +ac +ac +ac ac ac ac @@ -35876,9 +41468,21 @@ ac ac ac ac -hZ -hZ -hZ +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab ab ab ab @@ -35904,7 +41508,7 @@ MF MF MF "} -(85,1,1) = {" +(121,1,1) = {" MF MF MF @@ -35912,27 +41516,93 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +Yb +OR +vP +vP +vP +vP +Wf +Ur +vP +vP +vP +Ni +nY +op +oQ +pl +pH +pk +rb +rs +jo +kj +lv +mh +mJ +oM +sn +xx +uj +uT +no +xY +nu +wv +tl +QZ +QZ +tl +UY +Nz +tS +rJ +ac +ac +ac +kk +ac +ac +ac +ac +ac +ac ac ac ac @@ -35941,78 +41611,6 @@ ac ac ac ac -bm -bR -cF -do -dY -ez -fr -gc -gQ -hE -ia -iU -jP -kD -lg -lW -mG -ng -nK -oi -oC -oY -pB -qa -qP -rn -pB -se -jR -sS -ha -tt -Mm -ha -uF -vg -jX -Ne -RP -Au -AM -Iv -zY -Lh -Bp -Cy -Qs -DK -SB -Iu -Pe -Ff -Fp -wf -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd ac ac ac @@ -36030,11 +41628,17 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab ab ab ab @@ -36060,7 +41664,7 @@ MF MF MF "} -(86,1,1) = {" +(122,1,1) = {" MF MF MF @@ -36068,27 +41672,25 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36097,78 +41699,62 @@ ac ac ac ac -bl -bS -cG -Uy -dY -eA -fs -gd -gR -hF -ib -iV -jQ -kE -lh -lh -mH -nh -nh -nh -nh -oZ -nh -qb -lh -lh -lh -sf -sz -lh -lh -lh -lh -lh -uG -vh -vE -Ne -RP -xk -wI -wI -zT -Ot -Bq -Cy -Sk -Xb -LZ -NP -Pe -TE -Fp -wf -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd +ac +ac +ac +ac +ac +ac +ac +ad +wP +OY +OY +OY +OY +OY +wP +OY +OY +OY +OY +OY +io +op +oR +oR +oR +oR +oR +ru +ru +ru +sQ +sQ +sQ +sQ +sQ +RB +RB +RB +RB +RB +rO +sX +sX +sX +rS +sX +sX +tA +ZF +rJ +ac +ac +ac +ac +ac +ac ac ac ac @@ -36186,11 +41772,29 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ac +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36216,7 +41820,7 @@ MF MF MF "} -(87,1,1) = {" +(123,1,1) = {" MF MF MF @@ -36224,26 +41828,85 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +kk +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +RB +Zf +uk +ND +On +nQ +rP +rT +sq +sX +sX +sX +Rx +rJ +rJ +ac +ac ac ac ac @@ -36253,78 +41916,6 @@ ac ac ac ac -bl -bT -cH -dp -dZ -eB -bl -ge -gS -hG -gT -iW -jR -kF -li -li -li -li -li -li -li -li -li -qc -qQ -qQ -qQ -sg -qQ -qQ -qQ -qQ -qQ -qQ -qQ -vi -Zg -OB -RP -xl -yA -Af -QX -Lm -Br -Cy -Pe -Pe -Ip -Pe -Pe -Fl -Fo -FK -ts -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -IR ac ac ac @@ -36333,6 +41924,15 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac @@ -36342,11 +41942,15 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36372,7 +41976,7 @@ MF MF MF "} -(88,1,1) = {" +(124,1,1) = {" MF MF MF @@ -36380,107 +41984,37 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac ac ac -ad -ae -ae -ae -ae -ae -ae -bl -bl -bl -bl -bl -bl -bl -gf -gT -gT -gT -ie -jR -kG -lj -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -lX -uH -vk -jM -XP -RP -xF -zi -Ag -Cy -AC -Cy -Cy -UN -PH -Oq -Iw -Pe -DO -Gg -wf -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd ac ac ac @@ -36498,11 +42032,81 @@ ac ac ac ac -hZ -hZ -hZ -hZ -hZ +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ad +RB +MW +RZ +Nv +RB +oP +sp +tm +sr +UU +Qp +QE +rJ +rJ +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36528,7 +42132,7 @@ MF MF MF "} -(89,1,1) = {" +(125,1,1) = {" MF MF MF @@ -36536,107 +42140,30 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac ac -ae -ai -au -aE -ax -aV -bn -bU -cI -dq -ea -eC -ft -gg -ae -hd -hS -iX -jR -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -uI -La -jM -yz -Cy -xT -zj -NW -zX -AD -Bs -Vb -Xm -Oj -Xc -Nj -IC -Rm -YR -GO -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd ac ac ac @@ -36646,8 +42173,49 @@ ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ac +ac +ac +ac ac ac +Px +OE +Rt +Ph +RB +qV +sP +sP +sP +sP +rJ +rJ +rJ +rJ ac ac ac @@ -36656,9 +42224,45 @@ ac ac ac ac -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36684,7 +42288,7 @@ MF MF MF "} -(90,1,1) = {" +(126,1,1) = {" MF MF MF @@ -36692,113 +42296,74 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac -af -aj -av -aF -aM -aW -bo -bV -cJ -dr -eb -eD -fu -ae -ae -ae -ae -iY -jR -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -uI -vk -jM -VU -Cy -xV -zk -ZT -Cy -AE -Bt -Og -CM -Mc -Ix -Vz -Pe -DW -Fp -GO -ts -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -Ou -IR ac ac ac ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac ac ac +Px +Vq +Rt +YY +RB +Yj ac ac ac @@ -36813,8 +42378,47 @@ ac ac ac ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36840,7 +42444,7 @@ MF MF MF "} -(91,1,1) = {" +(127,1,1) = {" MF MF MF @@ -36848,117 +42452,74 @@ MF MF MF aJ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -af -ak -aw -aw -aN -ax -ae -bW -cK -ds -ae -eE -fv -fu -gU -hH -ae -iZ -jR -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -uI -vk -jM -wl -Cy -Cy -Cy -MV -Cy -AF -Bu -Uo -Pu -FS -Pe -Pe -Pe -Eu -Fp -GO -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd -ac -ac -ac -ac -ac -ac -ac -ac +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac +Px +SM +Rt +Ok +RB +Ry ac ac ac @@ -36969,8 +42530,51 @@ ac ac ac ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -36996,7 +42600,7 @@ MF MF MF "} -(92,1,1) = {" +(128,1,1) = {" MF MF MF @@ -37005,116 +42609,73 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -af -al -ax -aG -aO -aX -ae -bX -cL -dt -ae -eF -fw -gh -gV -hI -id -ja -jS -kG -lk -lY -lY -lY -lY -lY -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lY -lY -lY -lY -lY -uI -vk -jM -wk -wL -hd -Cy -LL -Cy -AO -Bv -FS -zP -NV -Pe -tH -DL -Pq -Fp -GO -Gj -Gv -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -Kd -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac +RB +Yq +Rt +XK +RB +WR ac ac ac @@ -37125,8 +42686,51 @@ ac ac ac ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -37152,7 +42756,7 @@ MF MF MF "} -(93,1,1) = {" +(129,1,1) = {" MF MF MF @@ -37161,128 +42765,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -af -am -ax -ae -ae -ae -ae -bY -ae -ae -ae -ae -ae -ae -ae -ae -ae -vo -jR -kG -lk -lY -lY -lY -lY -uI -XL -TZ -Sr -uP -XC -yD -Sr -Lk -HC -lk -lY -lY -lY -lY -uI -vk -jM -wn -wJ -FQ -FQ -zS -FQ -AO -Bw -Cn -AB -AB -AB -AB -AB -Ev -EC -GQ -ts -GL -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -IY -JV -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac -hZ -hZ +RB +RB +XH +Ra +RB +Xh +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -37308,7 +42912,7 @@ MF MF MF "} -(94,1,1) = {" +(130,1,1) = {" MF MF MF @@ -37317,128 +42921,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ae -an -ay -ae -aP -aY -bp -bZ -cM -du -ae -eH -fx -gi -aw -aL -ae -jb -jT -kG -ME -lZ -lZ -lZ -lZ -Ya -ZA -OL -lq -lq -lq -lq -lq -OQ -Xw -ll -lZ -lZ -lZ -lZ -uJ -vk -jM -wi -wJ -xm -yB -zp -wJ -wJ -wJ -wJ -AB -CL -CP -Dj -AB -Ew -Gg -GO -Gj -GM -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -Hs -JX -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ ab ab ab @@ -37455,146 +42937,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(95,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ae -ae -ae -ae -aQ -aQ -aZ -bZ -ax -QM -ae -aq -aq -aU -aw -aw -ae -qB -jU -kn -PB -PB -PB -PB -PB -PB -lq -OL -lq -RR -RR -RR -lq -OQ -lq -PB -PB -PB -PB -PB -PB -Li -QO -SR -wM -xn -xn -Nu -zU -Aw -Bl -BZ -Cc -CF -CQ -Dk -DM -Ex -EH -GO -Gj -GN -GN -GN -GN -GN -Ja -GR -GN -Jl -Jx -GN -GN -Ja -GN -GN -GN -IR -Jg -Jg -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ ab ab ab @@ -37611,146 +42953,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(96,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -af -ao -aw -aw -aw -aw -aw -cb -ax -aw -ec -aq -fz -aY -aw -aw -ec -jd -jV -kn -lq -SZ -SZ -SZ -SZ -SZ -SZ -Wc -PN -xs -ZE -xs -PN -Xv -PN -PN -PN -PN -PN -PN -Rz -Oo -vG -kx -wJ -xS -zh -zq -wJ -Ax -Bm -xU -AB -CG -CU -Dl -AB -EB -Fn -GV -ts -GP -GP -IR -XQ -GN -IR -GN -GR -Jm -Jm -GR -GN -IR -Hm -GR -Mv -IR -Kf -Kl -IR -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ ab ab ab @@ -37767,146 +42969,64 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(97,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -af -aw -aw -aI -aS -Xq -YF -cc -cO -cO -PQ -cO -fA -aw -aw -aq -ec -je -jW -kn -nS -nS -nS -nS -nS -nS -lq -OQ -lq -RR -RR -RR -lq -OL -lq -nS -nS -nS -nS -nS -nS -Li -jR -wh -pc -pc -pc -pc -pc -pc -Bn -pc -pc -pc -pc -pc -pc -Fv -Fo -GS -Gk -GR -GR -HV -GR -GT -Jb -GR -GT -WG -GR -GT -GR -GN -GT -GR -GR -IR -Kg -Kv -Km -Kd -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ac ac ac -hZ -hZ -hZ +RB +RB +RB +WR +WR +Pi +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -37923,146 +43043,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(98,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ae -aq -aq -aw -aT -aw -aq -aq -aq -aw -ed -aw -aw -ax -aq -aq -ih -jf -jX -kG -Zh -lX -lX -lX -lX -uH -ZA -OQ -lq -lq -lq -lq -lq -OL -Xw -lj -lX -lX -lX -lX -Xk -vk -jR -Ts -pc -xo -ZR -Qi -Ss -Ir -Bo -Bx -ZR -XB -Ss -RY -pc -Fw -Fp -GO -Gj -GT -Ht -GP -Is -IS -Jc -Jh -IS -Jh -Jh -IS -Jh -PY -IS -JL -Jh -Ke -Kh -Kv -Kn -Kd -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ ab ab ab @@ -38088,7 +43068,7 @@ MF MF MF "} -(99,1,1) = {" +(131,1,1) = {" MF MF MF @@ -38097,128 +43077,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -af -ar -aq -aK -aw -aw -ax -ax -ax -aw -ed -aw -aw -ax -aq -QA -ii -iV -jY -kG -lk -lY -lY -lY -lY -uI -Ly -YQ -KI -WK -Qv -VK -KI -Ub -Wi -lk -lY -lY -lY -lY -uI -vk -jR -wp -wQ -Ir -ZR -XB -Ss -Ir -AG -Ir -ZR -Wn -Ss -Ir -wQ -Fx -Fq -Gd -Gl -GW -Hu -HW -It -IV -GN -GR -Vx -GR -GR -Vx -GR -JF -Vx -JM -GR -IR -Ki -Kv -Kn -Kd -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +Qh +Pz +WR +VE +WR +WR +TB +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -38244,7 +43224,7 @@ MF MF MF "} -(100,1,1) = {" +(132,1,1) = {" MF MF MF @@ -38253,128 +43233,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -af -as -aw -aL -aU -aU -br -aw -aw -eE -ae -eN -aw -aw -aP -aw -ae -jg -jX -kG -lk -lY -lY -lY -lY -lY -lX -lX -lX -lX -lX -lX -lX -lX -lX -lY -lY -lY -lY -lY -uI -vk -jR -wp -Ac -Ir -ZR -XB -Ss -Ir -AH -Ir -ZR -XB -Ss -Ir -Ac -Fx -Fp -OJ -ts -IR -IR -IR -IO -IW -IR -Hm -Jk -Jq -GR -Jk -GN -IR -GN -JM -GR -IR -Kj -Pd -IR -IR -Wm -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +Vm +Vm +Vm +Vm +Vm +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -38400,7 +43380,7 @@ MF MF MF "} -(101,1,1) = {" +(133,1,1) = {" MF MF MF @@ -38409,128 +43389,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ae -at -at -ae -at -at -ae -at -at -ae -ae -ae -at -at -ae -ae -ae -jh -jX -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -uI -vk -rR -zt -Rn -Wp -Wp -Wp -Wp -Wp -Np -Ir -Ir -Ir -Ir -Ir -Ac -Fx -Fp -GO -ts -GY -Hx -IR -IP -IX -Jf -GN -GN -Jl -Jx -GN -GN -Jf -GN -JN -GN -IR -Kk -Kk -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -38556,7 +43536,7 @@ MF MF MF "} -(102,1,1) = {" +(134,1,1) = {" MF MF MF @@ -38565,128 +43545,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -gw -hd -hS -ji -jX -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -uI -vk -jR -wp -Om -Ir -Ir -Ir -Ir -YD -AJ -Up -Ir -Ir -Ir -Ir -Om -Fx -Fp -GU -ts -ts -ts -ts -IQ -Hr -Hr -Hr -Hr -Hr -Hr -Hr -Hr -JG -JG -JO -JG -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -38712,7 +43692,7 @@ MF MF MF "} -(103,1,1) = {" +(135,1,1) = {" MF MF MF @@ -38721,128 +43701,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -gw -gw -gw -ix -jX -kG -lk -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lY -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -uJ -vk -jR -wr -pc -Tf -Ir -Ir -QU -Ua -AK -Ce -WU -Ir -Ir -PG -pc -Fy -Fr -GV -Gj -AN -AN -Gj -IY -IY -IY -IY -IY -IY -IY -IY -IY -IR -IR -JP -IR -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ ab ab ab @@ -38859,146 +43717,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(104,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ik -ix -jX -kG -ll -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -lZ -Ya -NG -Sf -Ng -Xo -Sf -Ng -Xo -Sf -Ng -Li -jR -wp -pc -pc -wQ -wQ -pc -pc -wR -pc -pc -wQ -wQ -pc -pc -Fz -Fs -GO -Gj -AN -AN -Gj -IY -Ji -Ji -Ji -Jw -Ji -Ji -Ji -JC -IR -JI -JQ -JY -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ ab ab ab @@ -39015,146 +43733,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(105,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ik -ix -jX -kD -lm -lm -lm -lm -lm -lm -lm -lm -lm -qd -qR -qR -Yu -Yu -sA -sT -sT -sT -tI -ug -ug -vl -vI -ws -wS -lf -xv -xv -zs -TP -AL -BB -Ck -CS -Do -Do -Ez -FA -Ae -GO -Gj -AN -AN -Gj -IY -Jj -Jn -Jr -Js -Jv -JE -BA -IY -JH -JJ -JR -JZ -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ ab ab ab @@ -39171,146 +43749,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(106,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ik -ix -jZ -kH -kH -kH -kH -ni -nL -oj -nL -pa -nL -qe -nL -nL -nL -nL -sB -nL -td -nL -tJ -nL -nL -vm -vJ -wt -wT -wa -yd -yG -yG -yG -Ae -yG -Cl -CT -yG -yG -vZ -FB -Ft -Gf -Gm -Hd -HT -Gj -IY -Jj -Js -Js -Js -Jz -JE -BA -IY -JH -JJ -JS -Ka -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ ab ab ab @@ -39327,146 +43765,64 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(107,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -fF -ac -ac -ac -gw -ix -ka -kI -ln -ma -ma -nj -nM -ok -oD -pb -pC -qf -qS -zr -rG -pS -sC -pS -jX -tu -tK -uh -uK -vn -vn -vn -wU -xw -ye -ZS -SU -SU -Ru -xw -xw -CH -CH -LJ -EA -Ku -Fu -Gh -WS -Hg -HU -Gj -IY -Jj -Jp -Jt -Js -Jz -JE -BA -IY -JH -JJ -JS -Kb -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -39492,7 +43848,7 @@ MF MF MF "} -(108,1,1) = {" +(136,1,1) = {" MF MF MF @@ -39501,128 +43857,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -be -bs -bs -be -bs -bs -bs -be -go -go -gw -gw -ix -ka -kJ -lo -mb -lq -nk -Uj -ol -Pv -Pv -gw -qg -gw -Pv -rH -sh -sD -sh -te -tv -tL -sh -uL -rJ -rJ -vK -rJ -rJ -sF -rJ -SW -PC -rJ -vK -rJ -rJ -Ym -rJ -vK -vK -vK -rJ -ts -ts -ts -ts -IY -Ji -Ji -Ji -Jw -Ji -Ji -Ji -IY -JH -JJ -JT -Kc -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -39648,7 +44004,7 @@ MF MF MF "} -(109,1,1) = {" +(137,1,1) = {" MF MF MF @@ -39657,128 +44013,128 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -bf -bt -cg -cS -cg -ef -eO -fG -gp -ha -hP -il -jk -ka -kK -lp -TS -nr -nl -nN -ol -oF -pd -gw -qh -gw -Pv -rI -si -sE -sU -tf -tw -tM -ui -uM -rJ -vL -wu -wV -ww -SK -xp -sK -sZ -xq -sk -xr -vK -sX -Lg -KW -sX -sX -sX -vK -ac -ac -IR -IY -IY -IY -IY -IY -IY -IY -IY -IY -IR -JK -JK -JK -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -39804,7 +44160,7 @@ MF MF MF "} -(110,1,1) = {" +(138,1,1) = {" MF MF MF @@ -39813,127 +44169,127 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -bf -bu -ch -be -dB -eg -eP -fH -gq -hb -hQ -im -hb -kc -kL -lq -lq -mc -nm -nO -ol -oG -pe -Pv -qi -Pv -Pv -rJ -rJ -sF -sV -sF -tx -sF -rJ -rJ -rJ -vM -Az -Az -Az -Az -Az -sK -sZ -Az -Az -Dq -DX -Ri -KP -QG -NU -NU -sX -vK -ac -ac -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -IR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -39960,7 +44316,7 @@ MF MF MF "} -(111,1,1) = {" +(139,1,1) = {" MF MF MF @@ -39969,127 +44325,127 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -be -be -be -be -dC -eh -eQ -fG -gr -hc -hR -in -Of -kd -kM -lr -md -LD -nn -nP -om -oH -pf -pD -qj -oH -rp -rK -sj -sG -sW -sG -ty -tN -Wo -uN -vp -Wo -Wo -Xx -Uf -Uf -Uf -sL -ta -Rl -Qg -YE -rJ -Lz -KQ -xt -KQ -Gp -rJ -rJ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -kk -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -40116,7 +44472,7 @@ MF MF MF "} -(112,1,1) = {" +(140,1,1) = {" MF MF MF @@ -40125,127 +44481,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -bf -bt -cg -cT -XI -eh -eR -be -gw -gw -gw -io -io -io -WN -WN -io -io -LH -io -ol -oI -pg -pE -qk -qU -Pv -rL -sk -sH -UJ -th -Zc -KX -Zc -PA -Qo -Zc -Zc -QH -YJ -YP -XG -sM -tb -YJ -Cb -DY -rJ -KC -KQ -Yy -NU -sX -UI -vK -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ ab ab ab @@ -40263,145 +44498,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(113,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -bf -bu -ch -be -dD -eh -eS -be -YI -Sz -Lj -Nd -jl -ke -kN -ls -me -Rc -Nr -nR -on -oJ -oJ -oJ -oJ -oJ -oJ -rM -sl -sH -UJ -ti -Az -tO -ul -Az -Az -Az -Az -XF -VD -yg -yJ -sK -sZ -VD -DN -Zd -vK -KC -sX -sX -FH -Gr -Tv -vK -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ ab ab ab @@ -40419,145 +44515,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(114,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -be -be -be -be -dE -ei -eT -Uh -RX -Oe -LT -LT -LT -Pb -Qz -DS -DS -DS -np -nX -oo -oK -ph -pF -ql -mg -oJ -ru -ru -sI -sY -sY -tz -tP -ru -mL -uQ -uU -vr -XF -Az -Az -Az -sK -tc -Az -DZ -Ld -rJ -Ln -vK -vK -Ty -Ty -Ty -Ty -Ty -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ ab ab ab @@ -40575,145 +44532,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(115,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -bf -bt -cg -cU -cg -ej -eU -Uh -WT -IG -WL -WL -WL -wj -WL -WL -WL -WL -Vy -nT -UB -oL -oK -UW -qm -ml -rq -fI -jq -kO -mf -qW -mK -oN -vN -no -vO -vq -vs -XF -YJ -YP -XG -sK -sZ -YJ -Cb -DY -vK -Lp -Lv -EF -Ty -MB -Oi -ZI -NR -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ ab ab ab @@ -40731,145 +44549,59 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(116,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -bf -bu -ch -be -dF -ek -eV -fG -WT -ya -ya -ya -ya -kf -ya -ya -ya -ya -Vy -nU -on -jp -oK -oK -qn -qX -rr -fJ -js -kP -fJ -mj -fJ -un -xZ -no -uS -vq -vs -XF -VD -yg -yJ -sN -sZ -VD -DN -KN -nq -Lq -Wd -Un -Ty -TG -Oi -Ty -Ty -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -40896,7 +44628,7 @@ MF MF MF "} -(117,1,1) = {" +(141,1,1) = {" MF MF MF @@ -40905,127 +44637,127 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ad -be -be -be -be -WQ -WQ -eW -be -VL -IG -WL -WL -WL -wj -WL -WL -WL -WL -Vy -nV -on -jr -pi -pG -qo -qY -oJ -gs -kb -kQ -lu -mk -mi -lu -uo -no -uR -vq -vs -Zx -YL -Az -Az -sK -sZ -Az -DZ -HP -Ty -Ty -Ty -Ty -Ty -Ps -Oi -PL -Qf -Ty -Wm -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -41052,7 +44784,7 @@ MF MF MF "} -(118,1,1) = {" +(142,1,1) = {" MF MF MF @@ -41061,127 +44793,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Yb -WT -ya -ya -ya -ya -ya -ya -ya -ya -ya -Vy -Sl -on -oJ -oJ -oJ -oJ -oJ -oJ -jj -kg -kR -lu -lu -qW -lu -vN -ns -uR -vq -vs -ST -Zc -Zc -Zc -sO -tj -Zc -JB -Kw -Ky -EI -Gu -RG -OM -RQ -Oi -Ty -Ty -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ ab ab ab @@ -41199,145 +44810,110 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(119,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Yb -WT -IG -WL -WL -WL -wj -WL -WL -WL -WL -Vy -nW -op -oO -pj -MT -qp -qZ -rs -jm -kh -lt -lu -mI -mi -lu -xx -no -uR -vq -vs -SI -Qu -Az -Az -sK -sZ -Az -Kp -Dm -Ty -EJ -FM -Hh -Ml -KS -Oi -To -Qf -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -41364,7 +44940,7 @@ MF MF MF "} -(120,1,1) = {" +(143,1,1) = {" MF MF MF @@ -41373,127 +44949,127 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Yb -ZD -Qw -Qw -Qw -Qw -Qw -UD -Qw -Qw -Qw -yb -nX -Or -pk -pk -pk -qq -ra -rt -jn -ki -lu -lu -lu -lu -lu -xx -no -uR -uR -um -nt -rN -rS -rS -rS -rS -rS -to -tR -Ty -Ty -Ty -Ty -Ty -Ty -Ty -Ty -Ty -Ty -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -41520,7 +45096,7 @@ MF MF MF "} -(121,1,1) = {" +(144,1,1) = {" MF MF MF @@ -41529,127 +45105,7 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -Yb -OR -vP -vP -vP -vP -Wf -Ur -vP -vP -vP -Ni -nY -op -oQ -pl -pH -pk -rb -rs -jo -kj -lv -mh -mJ -oM -sn -xx -uj -uT -no -xY -nu -wv -tl -QZ -QZ -tl -UY -Nz -tS -rJ -ac -ac -ac -kk -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -41667,145 +45123,7 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(122,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ad -wP -OY -OY -OY -OY -OY -wP -OY -OY -OY -OY -OY -io -op -oR -oR -oR -oR -oR -ru -ru -ru -sQ -sQ -sQ -sQ -sQ -RB -RB -RB -RB -RB -rO -sX -sX -sX -rS -sX -sX -tA -ZF -rJ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -ac -hZ -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -41823,145 +45141,7 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(123,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -kk -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -RB -Zf -uk -ND -On -nQ -rP -rT -sq -sX -sX -sX -Rx -rJ -rJ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -41979,145 +45159,6 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(124,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ad -RB -MW -RZ -Nv -RB -oP -sp -tm -sr -UU -Qp -QE -rJ -rJ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -42135,145 +45176,56 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(125,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -ac -Px -OE -Rt -Ph -RB -qV -sP -sP -sP -sP -rJ -rJ -rJ -rJ -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -42300,7 +45252,7 @@ MF MF MF "} -(126,1,1) = {" +(145,1,1) = {" MF MF MF @@ -42309,127 +45261,127 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -Px -Vq -Rt -YY -RB -Yj -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab ab ab ab @@ -42456,7 +45408,7 @@ MF MF MF "} -(127,1,1) = {" +(146,1,1) = {" MF MF MF @@ -42465,127 +45417,6 @@ MF MF aJ aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -Px -SM -Rt -Ok -RB -Ry -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab ab ab @@ -42603,145 +45434,9 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(128,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -RB -Yq -Rt -XK -RB -WR -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab ab ab -hZ -hZ ab ab ab @@ -42759,2814 +45454,107 @@ ab ab ab ab -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(129,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -RB -RB -XH -Ra -RB -Xh -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(130,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ac -ac -ac -RB -RB -RB -WR -WR -Pi -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(131,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ ab -Qh -Pz -WR -VE -WR -WR -TB -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(132,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -Vm -Vm -Vm -Vm -Vm ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(133,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(134,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(135,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(136,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(137,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(138,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(139,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(140,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(141,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(142,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(143,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(144,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(145,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -aa -aJ -MF -MF -MF -MF -MF -MF -"} -(146,1,1) = {" -MF -MF -MF -MF -MF -MF -aJ -aa -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -ab -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ -hZ +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab aa aJ MF diff --git a/maps/tether/main_dmms/tether-04-transit.dmm b/maps/tether/main_dmms/tether-04-transit.dmm index d5a332ce610..d91bc5ed204 100644 --- a/maps/tether/main_dmms/tether-04-transit.dmm +++ b/maps/tether/main_dmms/tether-04-transit.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aa" = ( -/turf/exterior/open/sky, +/turf/open/sky, /area/tether/transit) "ab" = ( /obj/structure/cable{ @@ -87,7 +87,7 @@ /area/tether/midpoint) "al" = ( /obj/abstract/level_data_spawner/virgo3b/player, -/turf/exterior/open/sky, +/turf/open/sky, /area/tether/transit) "an" = ( /obj/structure/bed/chair/comfy/black{ @@ -248,7 +248,7 @@ /area/tether/midpoint) "aQ" = ( /obj/effect/blocker, -/turf/exterior/open/sky, +/turf/open/sky, /area/tether/transit) "aR" = ( /obj/machinery/light{ @@ -393,7 +393,7 @@ icon_state = "32-2" }, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/maintenance/tether_midpoint) "cd" = ( /obj/machinery/hologram/holopad, diff --git a/maps/tether/main_dmms/tether-05-station1.dmm b/maps/tether/main_dmms/tether-05-station1.dmm index 699f111ce28..a277ebbad50 100644 --- a/maps/tether/main_dmms/tether-05-station1.dmm +++ b/maps/tether/main_dmms/tether-05-station1.dmm @@ -4069,7 +4069,7 @@ /obj/structure/bookcase{ name = "bookcase (Religious)" }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/library) "aiB" = ( @@ -4262,7 +4262,7 @@ /obj/structure/bookcase{ name = "bookcase (Non-Fiction)" }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/library) "ajf" = ( @@ -4338,7 +4338,7 @@ /area/tether/station/pathfinder_office) "ajo" = ( /obj/structure/table/woodentable, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/tether/station/pathfinder_office) "ajp" = ( @@ -4378,7 +4378,7 @@ /obj/structure/bookcase{ name = "bookcase (Reference)" }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /obj/item/book/manual/engineering_guide, /turf/simulated/floor/wood, /area/library) @@ -4387,7 +4387,7 @@ name = "bookcase (Reference)" }, /obj/item/book/manual/supermatter_engine, -/obj/item/book/manual/resleeving, +/obj/item/book/fluff/resleeving, /turf/simulated/floor/wood, /area/library) "ajy" = ( @@ -7324,7 +7324,7 @@ }, /obj/structure/lattice, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/station/eng_lower) "arE" = ( /obj/structure/cable/green{ @@ -7948,7 +7948,7 @@ dir = 8 }, /obj/structure/table/woodentable, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/carpet, /area/engineering/break_room) "atH" = ( @@ -8771,7 +8771,7 @@ /turf/simulated/floor/plating, /area/hallway/station/docks) "axc" = ( -/obj/abstract/fluid_mapped{ +/obj/abstract/landmark/mapped_fluid{ fluid_initial = 300; name = "mapped shallow pool" }, @@ -13551,7 +13551,7 @@ dir = 4; name = "Engineering Reception Desk" }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/engineering/foyer) "aQJ" = ( @@ -14429,7 +14429,7 @@ /obj/structure/disposalpipe/down{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/maintenance/station/eng_lower) "aYg" = ( /obj/structure/grille, @@ -17181,7 +17181,7 @@ /area/hallway/station/docks) "bql" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/structure/cable/green{ icon_state = "0-4" }, @@ -17490,8 +17490,8 @@ pixel_y = -20; dir = 1 }, -/obj/item/book/manual/command_guide, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/command_guide, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled/dark, /area/bridge) "bsM" = ( @@ -18244,8 +18244,8 @@ "bAB" = ( /obj/structure/table/reinforced, /obj/item/megaphone, -/obj/item/book/manual/command_guide, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/command_guide, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hop) "bAC" = ( @@ -19611,9 +19611,9 @@ /area/tether/station/explorer_entry) "bWH" = ( /obj/structure/bookcase, -/obj/item/book/manual/command_guide, -/obj/item/book/manual/standard_operating_procedure, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/command_guide, +/obj/item/book/fluff/standard_operating_procedure, +/obj/item/book/fluff/nt_regs, /turf/simulated/floor/wood, /area/crew_quarters/captain) "bXl" = ( @@ -20505,7 +20505,7 @@ /obj/machinery/camera/network/tether{ dir = 4 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) "hpl" = ( @@ -23172,7 +23172,7 @@ dir = 4 }, /obj/structure/table/woodentable, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "xva" = ( diff --git a/maps/tether/main_dmms/tether-06-station2.dmm b/maps/tether/main_dmms/tether-06-station2.dmm index 6ca5e1b23f0..75a2fce5b36 100644 --- a/maps/tether/main_dmms/tether-06-station2.dmm +++ b/maps/tether/main_dmms/tether-06-station2.dmm @@ -556,7 +556,7 @@ /obj/effect/floor_decal/corner/lightorange/border{ dir = 8 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) "bd" = ( @@ -2638,7 +2638,7 @@ /area/chapel/office) "eA" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/structure/cable/pink{ icon_state = "1-2" }, @@ -3584,10 +3584,10 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/engineering/locker_room) "gw" = ( -/turf/simulated/open, +/turf/open, /area/engineering/locker_room) "gx" = ( /obj/machinery/atmospherics/unary/vent_pump/on, @@ -4315,18 +4315,18 @@ dir = 8 }, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/engineering/locker_room) "hO" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/engineering/locker_room) "hP" = ( /obj/structure/railing/mapped, /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/engineering/locker_room) "hQ" = ( /turf/simulated/wall/r_wall, @@ -4422,7 +4422,7 @@ /area/crew_quarters/medbreak) "ic" = ( /obj/structure/table/glass, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/crew_quarters/medbreak) "id" = ( @@ -5021,8 +5021,8 @@ /obj/item/book/manual/medical_diagnostics_manual{ pixel_y = 7 }, -/obj/item/book/manual/stasis, -/obj/item/book/manual/resleeving, +/obj/item/book/fluff/stasis, +/obj/item/book/fluff/resleeving, /obj/machinery/light{ dir = 8 }, @@ -5802,7 +5802,7 @@ icon_state = "32-2" }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/station/eng_upper) "kY" = ( /turf/simulated/shuttle/wall/voidcraft/green{ @@ -6459,7 +6459,7 @@ /obj/structure/disposalpipe/down{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/maintenance/station/eng_upper) "mq" = ( /obj/structure/railing/mapped{ @@ -6723,7 +6723,7 @@ /obj/structure/cable/green{ icon_state = "4-8" }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "mN" = ( /obj/structure/catwalk, @@ -6740,11 +6740,11 @@ /obj/structure/cable/green{ icon_state = "1-2" }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "mO" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "mP" = ( /obj/effect/floor_decal/borderfloor/corner{ @@ -7284,7 +7284,7 @@ /obj/structure/cable/green{ icon_state = "1-4" }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "nB" = ( /obj/structure/disposalpipe/junction/yjunction, @@ -7568,13 +7568,13 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "of" = ( /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "og" = ( /obj/structure/railing/mapped{ @@ -7583,7 +7583,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "oh" = ( /obj/structure/disposalpipe/segment, @@ -8004,7 +8004,7 @@ /turf/simulated/floor, /area/storage/tech) "oM" = ( -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "oN" = ( /obj/effect/floor_decal/borderfloor{ @@ -10034,13 +10034,13 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "sv" = ( /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "sw" = ( /turf/simulated/wall, @@ -10276,10 +10276,10 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "tb" = ( -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "tc" = ( /turf/simulated/floor, @@ -10288,10 +10288,10 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/tether/station/stairs_two) "te" = ( -/turf/simulated/open, +/turf/open, /area/tether/station/stairs_two) "tf" = ( /obj/effect/floor_decal/borderfloor{ @@ -10574,7 +10574,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "tI" = ( /obj/machinery/alarm{ @@ -10997,7 +10997,7 @@ /area/medical/virology) "uz" = ( /obj/structure/table/glass, -/obj/item/storage/fancy/vials, +/obj/item/storage/box/fancy/vials, /obj/machinery/alarm{ dir = 8; pixel_x = 24 @@ -11681,7 +11681,7 @@ /area/ai_monitored/storage/eva) "vM" = ( /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/vacant/vacant_restaurant_upper) "vN" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ @@ -12908,7 +12908,7 @@ /obj/structure/sign/department/engineering{ pixel_y = 32 }, -/turf/simulated/open, +/turf/open, /area/engineering/foyer_mezzenine) "xX" = ( /obj/structure/table/steel, @@ -12998,7 +12998,7 @@ /turf/simulated/floor, /area/maintenance/station/medbay) "yh" = ( -/turf/simulated/open, +/turf/open, /area/bridge/meeting_room) "yi" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ @@ -13103,7 +13103,7 @@ /area/bridge/meeting_room) "yp" = ( /obj/structure/table/woodentable, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, @@ -13946,7 +13946,7 @@ /obj/structure/cable/green{ icon_state = "32-4" }, -/turf/simulated/open, +/turf/open, /area/bridge/meeting_room) "zC" = ( /obj/structure/cable/green{ @@ -14004,7 +14004,7 @@ pixel_y = -22 }, /obj/structure/table/woodentable, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/bridge/meeting_room) "zJ" = ( @@ -16327,7 +16327,7 @@ dir = 4 }, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/engineering/shaft) "Jp" = ( /obj/machinery/alarm{ @@ -16800,7 +16800,7 @@ /obj/structure/cable/pink{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/maintenance/station/sec_lower) "LG" = ( /obj/structure/cable/pink{ @@ -18537,7 +18537,7 @@ /area/hallway/station/starboard) "VQ" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/item/storage/pill_bottle/dice, /turf/simulated/floor/tiled/white, /area/medical/psych_ward) diff --git a/maps/tether/main_dmms/tether-07-station3.dmm b/maps/tether/main_dmms/tether-07-station3.dmm index 57413387aed..26e9525dae2 100644 --- a/maps/tether/main_dmms/tether-07-station3.dmm +++ b/maps/tether/main_dmms/tether-07-station3.dmm @@ -333,7 +333,7 @@ }, /obj/structure/sign/poster{ pixel_x = -32; - dir = 8 + dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 1 @@ -1616,7 +1616,7 @@ /obj/structure/railing/mapped{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/security/brig) "cT" = ( /obj/structure/lattice, @@ -1624,7 +1624,7 @@ /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ id_tag = "sec_riot_control" }, -/turf/simulated/open, +/turf/open, /area/security/brig) "cU" = ( /turf/simulated/wall/r_wall, @@ -1633,7 +1633,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/security/brig) "cW" = ( /obj/machinery/door/firedoor/glass, @@ -1826,7 +1826,7 @@ pixel_y = -32; dir = 1 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hos) "dv" = ( @@ -2684,7 +2684,7 @@ /obj/item/stack/package_wrap/twenty_five, /obj/item/hand_labeler, /obj/structure/table/reinforced, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/security/briefing_room) "fa" = ( @@ -3030,7 +3030,7 @@ "fF" = ( /obj/machinery/door/firedoor/glass, /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/maintenance/station/ai) "fG" = ( /obj/structure/railing/mapped{ @@ -3284,7 +3284,7 @@ /area/security/hallway) "gb" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/security/brig) "gc" = ( /obj/effect/floor_decal/borderfloorwhite, @@ -3403,7 +3403,7 @@ dir = 4 }, /obj/structure/closet/secure_closet/warden, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/machinery/light{ dir = 1 }, @@ -5092,7 +5092,7 @@ /turf/simulated/floor/tiled/dark, /area/security/warden) "jk" = ( -/turf/simulated/open, +/turf/open, /area/security/brig) "jl" = ( /obj/effect/floor_decal/borderfloor{ @@ -5236,7 +5236,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/security/brig) "jz" = ( /obj/effect/floor_decal/borderfloor{ @@ -5865,9 +5865,9 @@ /area/crew_quarters/heads/hos) "kI" = ( /obj/structure/bookcase, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/standard_operating_procedure, -/obj/item/book/manual/command_guide, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/standard_operating_procedure, +/obj/item/book/fluff/command_guide, /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) "kJ" = ( @@ -6319,10 +6319,10 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/security/hallway) "lC" = ( -/turf/simulated/open, +/turf/open, /area/security/hallway) "lD" = ( /obj/machinery/door/firedoor/glass, @@ -6417,8 +6417,8 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/structure/table/reinforced, /turf/simulated/floor/tiled, /area/security/briefing_room) @@ -6979,7 +6979,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/security/hallway) "mH" = ( /turf/simulated/wall/r_wall, @@ -7249,9 +7249,9 @@ /area/security/breakroom) "ni" = ( /obj/structure/bookcase, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/wood, /area/security/breakroom) "nj" = ( @@ -7393,7 +7393,7 @@ }, /obj/structure/table/glass, /obj/item/folder/red, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /turf/simulated/floor/tiled, /area/security/briefing_room) "nu" = ( @@ -8187,7 +8187,7 @@ /obj/structure/cable{ icon_state = "32-4" }, -/turf/simulated/open, +/turf/open, /area/maintenance/station/ai) "oT" = ( /obj/effect/floor_decal/industrial/warning{ @@ -9172,8 +9172,8 @@ /area/security/detectives_office) "qG" = ( /obj/structure/bookcase, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, /turf/simulated/floor/lino, /area/security/detectives_office) "qH" = ( @@ -9345,7 +9345,7 @@ }, /obj/structure/lattice, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/maintenance/station/sec_upper) "qU" = ( /obj/machinery/portable_atmospherics/powered/pump/filled, @@ -10223,7 +10223,7 @@ "sj" = ( /obj/structure/table/woodentable, /obj/item/handcuffs, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, @@ -12018,7 +12018,7 @@ icon_state = "32-1" }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/station/elevator) "uY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -12253,12 +12253,12 @@ dir = 1 }, /obj/structure/bookcase, -/obj/item/book/manual/standard_operating_procedure, -/obj/item/book/manual/standard_operating_procedure, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/command_guide, -/obj/item/book/manual/command_guide, +/obj/item/book/fluff/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/command_guide, +/obj/item/book/fluff/command_guide, /turf/simulated/floor/tiled/dark, /area/lawoffice) "vy" = ( @@ -12770,7 +12770,7 @@ }, /obj/structure/lattice, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/station/elevator) "ww" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -13040,8 +13040,8 @@ /area/security/lobby) "wU" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, /turf/simulated/floor/tiled, /area/security/lobby) "wV" = ( @@ -13418,7 +13418,7 @@ dir = 4; pixel_x = 21 }, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/tiled, /area/quartermaster/office) "xu" = ( @@ -13640,7 +13640,7 @@ /obj/structure/disposalpipe/down{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/maintenance/station/elevator) "xO" = ( /obj/structure/cable{ @@ -17030,7 +17030,7 @@ /area/quartermaster/storage) "DE" = ( /obj/structure/table, -/obj/item/storage/fancy/cigarettes{ +/obj/item/storage/box/fancy/cigarettes{ pixel_y = 2 }, /obj/item/deck/cards, @@ -17950,14 +17950,14 @@ dir = 4; pixel_x = -22 }, -/turf/simulated/open, +/turf/open, /area/tether/station/stairs_three) "Fu" = ( /obj/structure/sign/deck/third{ pixel_x = 32; dir = 8 }, -/turf/simulated/open, +/turf/open, /area/tether/station/stairs_three) "Fv" = ( /obj/effect/floor_decal/borderfloorwhite{ @@ -18483,7 +18483,7 @@ /turf/simulated/floor/tiled/techfloor, /area/teleporter/departing) "Gk" = ( -/turf/simulated/open, +/turf/open, /area/tether/station/stairs_three) "Gl" = ( /obj/structure/table/glass, @@ -19368,8 +19368,8 @@ /obj/item/storage/box/syringes, /obj/item/radio/headset/headset_med, /obj/item/storage/box/pillbottles, -/obj/item/storage/fancy/vials, -/obj/item/storage/fancy/vials, +/obj/item/storage/box/fancy/vials, +/obj/item/storage/box/fancy/vials, /obj/effect/floor_decal/borderfloorwhite{ dir = 10 }, @@ -20245,7 +20245,7 @@ name = "Best Doctor 2552"; pixel_y = 32 }, -/turf/simulated/open, +/turf/open, /area/medical/medbay_primary_storage) "Jx" = ( /obj/structure/table, @@ -20560,7 +20560,7 @@ dir = 8; pixel_x = 25 }, -/turf/simulated/open, +/turf/open, /area/medical/medbay_primary_storage) "Kl" = ( /obj/structure/table, @@ -20607,7 +20607,7 @@ icon_state = "32-2" }, /obj/machinery/door/firedoor/glass, -/turf/simulated/open, +/turf/open, /area/maintenance/station/medbay) "Ku" = ( /obj/structure/disposalpipe/segment{ @@ -21343,7 +21343,7 @@ /turf/simulated/floor/tiled/white, /area/medical/resleeving) "LG" = ( -/obj/item/book/manual/resleeving, +/obj/item/book/fluff/resleeving, /obj/structure/table/glass, /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -21830,13 +21830,13 @@ /turf/simulated/floor/tiled/white, /area/medical/surgery2) "Mw" = ( -/turf/simulated/open, +/turf/open, /area/medical/surgery_hallway) "Mx" = ( /obj/machinery/light{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/medical/surgery_hallway) "My" = ( /obj/effect/floor_decal/borderfloorwhite{ @@ -21918,9 +21918,9 @@ /obj/item/storage/belt/medical, /obj/item/clothing/glasses/hud/health, /obj/item/clothing/accessory/stethoscope, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /obj/item/scanner/health, -/obj/item/storage/fancy/vials, +/obj/item/storage/box/fancy/vials, /obj/item/clothing/mask/surgical, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) @@ -22732,7 +22732,7 @@ /area/medical/surgery_hallway) "NM" = ( /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/medical/surgery_hallway) "NN" = ( /obj/structure/railing/mapped{ @@ -25520,7 +25520,7 @@ /area/medical/psych) "Su" = ( /obj/structure/table/woodentable, -/obj/item/book/manual/standard_operating_procedure, +/obj/item/book/fluff/standard_operating_procedure, /turf/simulated/floor/carpet, /area/security/detectives_office) "Sv" = ( @@ -26110,7 +26110,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/medical/psych_ward) "Uv" = ( /obj/effect/floor_decal/borderfloorwhite{ @@ -26530,7 +26530,7 @@ /area/medical/psych_ward) "VJ" = ( /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/medical/psych_ward) "VK" = ( /obj/effect/floor_decal/borderfloorwhite{ @@ -26558,7 +26558,7 @@ /turf/simulated/floor/tiled/white, /area/medical/psych_ward) "VM" = ( -/turf/simulated/open, +/turf/open, /area/ai/foyer) "VN" = ( /obj/machinery/door/airlock/medical{ @@ -27065,7 +27065,7 @@ /turf/simulated/floor/tiled, /area/quartermaster/belterdock) "XQ" = ( -/turf/simulated/open, +/turf/open, /area/medical/psych_ward) "XU" = ( /turf/simulated/wall, @@ -27382,7 +27382,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/medical/psych_ward) "YR" = ( /obj/effect/floor_decal/borderfloorwhite{ diff --git a/maps/tether/main_dmms/tether-10-colony.dmm b/maps/tether/main_dmms/tether-10-colony.dmm index 8de9d4acb95..1afe2cb0fbb 100644 --- a/maps/tether/main_dmms/tether-10-colony.dmm +++ b/maps/tether/main_dmms/tether-10-colony.dmm @@ -1367,7 +1367,7 @@ "cu" = ( /obj/machinery/vending/cigarette{ name = "hacked cigarette machine"; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/unsimulated/floor/wood, /area/centcom/specops) @@ -2347,7 +2347,7 @@ /area/centcom/control) "eg" = ( /obj/structure/table, -/obj/item/organ/internal/posibrain, +/obj/item/organ/internal/brain/robotic, /obj/item/robotanalyzer, /turf/unsimulated/floor/steel, /area/centcom/control) @@ -2559,7 +2559,7 @@ /obj/item/chems/drinks/bottle/small/beer, /obj/item/chems/drinks/bottle/small/beer, /obj/item/flame/lighter/zippo, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/unsimulated/floor{ icon_state = "lino" }, @@ -3609,7 +3609,7 @@ /area/centcom/control) "gW" = ( /obj/structure/table, -/obj/item/mmi, +/obj/item/organ/internal/brain_interface, /turf/unsimulated/floor/steel, /area/centcom/control) "gX" = ( @@ -3941,7 +3941,7 @@ dir = 8 }, /obj/machinery/computer/transhuman/resleeving, -/obj/item/book/manual/resleeving, +/obj/item/book/fluff/resleeving, /obj/item/storage/box/backup_kit, /turf/unsimulated/floor/steel, /area/centcom/control) @@ -7521,7 +7521,7 @@ name = "Station Intercom (General)"; pixel_y = 20 }, -/obj/item/storage/box/donut, +/obj/item/storage/box/fancy/donut, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -8925,7 +8925,7 @@ /area/centcom/holding) "rl" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /turf/unsimulated/floor/steel, /area/centcom/security) "rm" = ( @@ -9926,7 +9926,7 @@ /area/centcom/security) "tu" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/effect/floor_decal/borderfloor{ dir = 8 }, @@ -10171,7 +10171,7 @@ /area/centcom/security) "tT" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/item/gun/energy/taser, /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/blue/border, @@ -11045,7 +11045,7 @@ dir = 9 }, /obj/item/flame/lighter/zippo, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/unsimulated/floor{ icon_state = "carpet" }, @@ -11056,7 +11056,7 @@ dir = 1 }, /obj/item/flame/lighter/zippo, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/unsimulated/floor{ icon_state = "carpet" }, @@ -11073,7 +11073,7 @@ dir = 5 }, /obj/item/flame/lighter/zippo, -/obj/item/storage/fancy/cigarettes, +/obj/item/storage/box/fancy/cigarettes, /turf/unsimulated/floor{ icon_state = "carpet" }, @@ -11855,8 +11855,8 @@ dir = 10 }, /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, +/obj/item/book/fluff/nt_regs, /turf/unsimulated/floor{ dir = 5; icon_state = "vault" @@ -13919,7 +13919,7 @@ /area/centcom/security) "AJ" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /turf/unsimulated/floor{ dir = 5; icon_state = "vault" @@ -14570,7 +14570,7 @@ /area/centcom/security/residential) "BL" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/nt_regs, +/obj/item/book/fluff/nt_regs, /obj/item/taperecorder, /obj/effect/floor_decal/borderfloorblack, /obj/effect/floor_decal/corner/blue/border, diff --git a/maps/tether/submaps/aerostat/submaps/Rockybase.dmm b/maps/tether/submaps/aerostat/submaps/Rockybase.dmm index ab30b6b6bb7..2e6a253ba13 100644 --- a/maps/tether/submaps/aerostat/submaps/Rockybase.dmm +++ b/maps/tether/submaps/aerostat/submaps/Rockybase.dmm @@ -524,7 +524,7 @@ /area/submap/virgo2/Rockybase) "bR" = ( /obj/structure/table, -/obj/item/mmi/digital/robot, +/obj/item/organ/internal/brain/robotic, /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/Rockybase) "bS" = ( diff --git a/maps/tether/submaps/gateway/zoo.dmm b/maps/tether/submaps/gateway/zoo.dmm index 7dd43530f09..fac3faabc7c 100644 --- a/maps/tether/submaps/gateway/zoo.dmm +++ b/maps/tether/submaps/gateway/zoo.dmm @@ -1625,7 +1625,7 @@ "eM" = ( /obj/machinery/vending/cigarette{ name = "hacked cigarette machine"; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/simulated/floor/shuttle/black, /area/awaymission/zoo/tradeship) @@ -2467,7 +2467,7 @@ /area/awaymission/zoo) "hk" = ( /obj/item/storage/box/matches, -/obj/item/storage/fancy/cigarettes/dromedaryco, +/obj/item/storage/box/fancy/cigarettes/dromedaryco, /turf/simulated/floor/plating, /area/awaymission/zoo/pirateship) "hl" = ( @@ -2777,7 +2777,7 @@ "hZ" = ( /obj/machinery/vending/cigarette{ name = "hacked cigarette machine"; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/simulated/floor/shuttle/darkred, /area/awaymission/zoo/syndieship) @@ -4093,7 +4093,7 @@ /area/awaymission/zoo) "lq" = ( /obj/structure/rack, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /turf/simulated/floor/holofloor/carpet, /area/awaymission/zoo) "lr" = ( diff --git a/maps/tether/submaps/tether_ships.dmm b/maps/tether/submaps/tether_ships.dmm index 8ffe011fd64..b5ccd2acfaf 100644 --- a/maps/tether/submaps/tether_ships.dmm +++ b/maps/tether/submaps/tether_ships.dmm @@ -46,7 +46,7 @@ /turf/unsimulated/floor/techfloor_grid, /area/space) "hc" = ( -/turf/exterior/open/sky/moving/south, +/turf/open/sky/moving/south, /area/space) "hh" = ( /obj/effect/floor_decal/transit/orange{ @@ -82,7 +82,7 @@ name = "thrower_escapeshuttletop(left)"; tiles = 0 }, -/turf/exterior/open/sky/moving/south, +/turf/open/sky/moving/south, /area/space) "ho" = ( /obj/effect/step_trigger/thrower{ @@ -91,7 +91,7 @@ stopper = 0; tiles = 0 }, -/turf/exterior/open/sky/moving/south, +/turf/open/sky/moving/south, /area/space) "hp" = ( /turf/space/transit/south, @@ -103,7 +103,7 @@ name = "thrower_escapeshuttletop(right)"; tiles = 0 }, -/turf/exterior/open/sky/moving/south, +/turf/open/sky/moving/south, /area/space) "hs" = ( /obj/effect/step_trigger/teleporter/random{ @@ -116,7 +116,7 @@ teleport_z = 6; teleport_z_offset = 6 }, -/turf/exterior/open/sky/moving/south, +/turf/open/sky/moving/south, /area/space) "ht" = ( /obj/effect/step_trigger/lost_in_space, diff --git a/maps/tether/submaps/wild/tether_wild-crash.dmm b/maps/tether/submaps/wild/tether_wild-crash.dmm index 8043f281082..176c0c8e084 100644 --- a/maps/tether/submaps/wild/tether_wild-crash.dmm +++ b/maps/tether/submaps/wild/tether_wild-crash.dmm @@ -618,7 +618,7 @@ "bK" = ( /obj/machinery/vending/cigarette{ name = "hacked cigarette machine"; - products = list(/obj/item/storage/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) + products = list(/obj/item/storage/box/fancy/cigarettes = 10, /obj/item/storage/box/matches = 10, /obj/item/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2) }, /turf/simulated/floor/shuttle/black/virgo3b, /area/tether/surfacebase/crash) diff --git a/maps/tether/tether_define.dm b/maps/tether/tether_define.dm index eab6af9ad95..459307e22f6 100644 --- a/maps/tether/tether_define.dm +++ b/maps/tether/tether_define.dm @@ -3,6 +3,7 @@ full_name = "NRS Lighthouse" path = "tether" ground_noun = "deck" + lobby_screens = list('maps/tether/icons/lobby/orbital.gif') station_name = "NRS Lighthouse" station_short = "Lighthouse" diff --git a/maps/tether/tether_leveldata.dm b/maps/tether/tether_leveldata.dm index 75ee0c75cd4..656cc08651e 100644 --- a/maps/tether/tether_leveldata.dm +++ b/maps/tether/tether_leveldata.dm @@ -125,7 +125,7 @@ ) UT_turf_exceptions_by_door_type = list( /obj/machinery/door/firedoor/glass = list( - /turf/simulated/open + /turf/open ) ) diff --git a/maps/tradeship/jobs/civilian.dm b/maps/tradeship/jobs/civilian.dm index ef5e54bfd27..01802f673c8 100644 --- a/maps/tradeship/jobs/civilian.dm +++ b/maps/tradeship/jobs/civilian.dm @@ -16,7 +16,7 @@ event_categories = list(ASSIGNMENT_GARDENER, ASSIGNMENT_JANITOR) /datum/job/tradeship_deckhand/get_access() - if(config.assistant_maint) + if(get_config_value(/decl/config/toggle/assistant_maint)) return list(access_maint_tunnels) else return list() diff --git a/maps/tradeship/tradeship-0.dmm b/maps/tradeship/tradeship-0.dmm index 4f51351b557..2ea83d79b02 100644 --- a/maps/tradeship/tradeship-0.dmm +++ b/maps/tradeship/tradeship-0.dmm @@ -1018,7 +1018,7 @@ /obj/structure/window/basic, /obj/structure/curtain/open/bed{ icon_state = "closed"; - opacity = TRUE + opacity = 1 }, /obj/effect/floor_decal/corner/beige{ dir = 10 @@ -1038,6 +1038,7 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/structure/loot_pile/maint/technical, /turf/simulated/floor, /area/ship/trade/fore_port_underside_maint) "fV" = ( @@ -1295,7 +1296,7 @@ /obj/structure/window/basic, /obj/structure/curtain/open/bed{ icon_state = "closed"; - opacity = TRUE + opacity = 1 }, /turf/simulated/floor/plating, /area/ship/trade/loading_bay) @@ -1439,6 +1440,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled, /area/ship/trade/loading_bay) +"wI" = ( +/obj/structure/loot_pile/surface/medicine_cabinet{ + pixel_y = 18 + }, +/turf/simulated/floor/carpet/green, +/area/ship/trade/disused) "wP" = ( /obj/structure/disposalpipe/trunk, /obj/structure/cable{ @@ -1661,6 +1668,11 @@ }, /turf/simulated/floor, /area/ship/trade/undercomms) +"Fy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/loot_pile/maint/trash, +/turf/simulated/floor/tiled, +/area/ship/trade/disused) "FD" = ( /obj/item/mollusc/barnacle{ pixel_x = -5; @@ -1746,6 +1758,10 @@ /obj/effect/paint/brown, /turf/simulated/wall/r_wall/hull, /area/ship/trade/livestock) +"IA" = ( +/obj/structure/loot_pile/maint/junk, +/turf/simulated/floor/carpet/green, +/area/ship/trade/disused) "IG" = ( /obj/structure/bed/chair/comfy/green{ dir = 1 @@ -1763,6 +1779,15 @@ /obj/structure/stairs/long/west, /turf/simulated/floor/tiled/steel_grid, /area/ship/trade/loading_bay) +"IO" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/loot_pile/maint/boxfort, +/turf/simulated/floor, +/area/ship/trade/fore_port_underside_maint) "IQ" = ( /obj/structure/disposalpipe/trunk{ dir = 4 @@ -1958,6 +1983,19 @@ }, /turf/simulated/floor, /area/ship/trade/disused) +"PE" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/loot_pile/maint/junk, +/turf/simulated/floor, +/area/ship/trade/fore_port_underside_maint) "PF" = ( /obj/effect/floor_decal/industrial/warning{ dir = 8; @@ -2020,6 +2058,10 @@ /obj/item/stool/padded, /turf/simulated/floor, /area/ship/trade/disused) +"RR" = ( +/obj/structure/loot_pile/maint/boxfort, +/turf/simulated/floor/carpet/red, +/area/ship/trade/disused) "Ss" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/alarm{ @@ -2053,6 +2095,7 @@ pixel_y = 20 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/loot_pile/maint/junk, /turf/simulated/floor, /area/ship/trade/disused) "TA" = ( @@ -4771,7 +4814,7 @@ Gb fp ne ne -ne +IO ne aS Ss @@ -4850,7 +4893,7 @@ SC Ff Ym Xe -Nq +PE ak ak ak @@ -5588,7 +5631,7 @@ SC rp Iu oG -qt +Fy aT yO LO @@ -5831,7 +5874,7 @@ aa aa aa SC -AT +wI Ym JQ Yh @@ -5913,8 +5956,8 @@ aa aa aa SC -AT -Ym +IA +RR JQ lv DT diff --git a/maps/tradeship/tradeship-1.dmm b/maps/tradeship/tradeship-1.dmm index 8cfaa0d7f41..c5fb31ffbde 100644 --- a/maps/tradeship/tradeship-1.dmm +++ b/maps/tradeship/tradeship-1.dmm @@ -182,7 +182,7 @@ /obj/machinery/portable_atmospherics/canister/air/airlock, /obj/machinery/button/access/interior{ dir = 8; - id_tag = "tradeship_starboard_dock"; + id_tag = "eva"; pixel_x = 20 }, /turf/simulated/floor/tiled/techfloor, @@ -634,7 +634,7 @@ "br" = ( /obj/structure/lattice, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/ship/trade/maintenance/lower) "bt" = ( /obj/effect/floor_decal/corner/beige{ @@ -1104,7 +1104,7 @@ /obj/item/stamp/clown, /obj/item/storage/backpack/clown, /obj/item/bikehorn, -/obj/item/storage/fancy/crayons, +/obj/item/storage/box/fancy/crayons, /obj/machinery/newscaster{ pixel_y = -32; dir = 1 @@ -1239,7 +1239,7 @@ /obj/structure/railing/mapped{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo/lower) "dj" = ( /obj/effect/floor_decal/corner/beige{ @@ -1345,7 +1345,7 @@ /area/ship/trade/cargo/lower) "dv" = ( /obj/machinery/light, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo/lower) "dw" = ( /obj/effect/floor_decal/corner/beige{ @@ -2165,7 +2165,7 @@ /turf/simulated/floor/tiled/steel_grid, /area/ship/trade/cargo/lower) "lZ" = ( -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo/lower) "mb" = ( /obj/effect/floor_decal/corner/beige{ diff --git a/maps/tradeship/tradeship-2.dmm b/maps/tradeship/tradeship-2.dmm index 0ab231c402e..efbe77fd205 100644 --- a/maps/tradeship/tradeship-2.dmm +++ b/maps/tradeship/tradeship-2.dmm @@ -635,8 +635,8 @@ /obj/random/drinkbottle, /obj/random/drinkbottle, /obj/random/drinkbottle, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, /obj/item/chems/condiment/flour, /obj/item/chems/condiment/flour, /obj/item/chems/condiment/flour, @@ -1265,9 +1265,9 @@ /obj/machinery/recharger, /obj/structure/sign/poster{ pixel_x = 32; - dir = 4 + dir = 8 }, -/obj/item/trash/tray, +/obj/item/plate/tray, /obj/item/circular_saw, /obj/machinery/newscaster{ pixel_x = 32; @@ -1942,7 +1942,7 @@ icon_state = "32-1" }, /obj/structure/disposalpipe/down, -/turf/simulated/open, +/turf/open, /area/ship/trade/crew/hallway/starboard) "eL" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ @@ -2061,7 +2061,7 @@ /area/ship/trade/cargo) "eV" = ( /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fa" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -2208,7 +2208,7 @@ "fp" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fr" = ( /obj/structure/closet/crate, @@ -2218,7 +2218,7 @@ /obj/random/bomb_supply, /obj/item/storage/box/syringes, /obj/structure/catwalk, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fs" = ( /obj/structure/catwalk, @@ -2229,7 +2229,7 @@ pixel_x = 24; dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fu" = ( /obj/structure/cable{ @@ -2328,20 +2328,20 @@ "fI" = ( /obj/structure/catwalk, /obj/effect/floor_decal/industrial/warning, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fJ" = ( /obj/structure/catwalk, /obj/effect/floor_decal/industrial/warning, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fK" = ( /obj/structure/catwalk, /obj/machinery/light/spot{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "fN" = ( /obj/effect/paint/brown, @@ -2438,7 +2438,7 @@ /turf/simulated/floor/tiled/techmaint, /area/ship/trade/crew/hallway/port) "fZ" = ( -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "ga" = ( /obj/structure/catwalk, @@ -2449,7 +2449,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "gc" = ( /obj/machinery/door/airlock/hatch/autoname/general, @@ -2603,7 +2603,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "gt" = ( /obj/structure/emergency_dispenser/west, @@ -2691,7 +2691,7 @@ /obj/structure/railing/mapped{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "gI" = ( /obj/random/maintenance, @@ -2717,7 +2717,7 @@ dir = 8; icon_state = "warning" }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "gN" = ( /obj/effect/floor_decal/techfloor/orange{ @@ -2755,7 +2755,7 @@ dir = 1; icon_state = "warning" }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "gW" = ( /obj/structure/catwalk, @@ -2771,7 +2771,7 @@ pixel_y = -20; dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "hb" = ( /obj/machinery/power/terminal{ @@ -3391,7 +3391,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/abstract/fluid_mapped/fuel, +/obj/abstract/landmark/mapped_fluid/fuel, /turf/simulated/floor/tiled/techfloor, /area/ship/trade/maintenance/engineering) "in" = ( @@ -4691,7 +4691,7 @@ /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ dir = 1 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "nW" = ( /obj/effect/floor_decal/corner/red/diagonal, @@ -5178,7 +5178,7 @@ /obj/machinery/light/spot{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "sG" = ( /obj/effect/floor_decal/corner/beige{ @@ -5258,6 +5258,10 @@ }, /turf/simulated/floor/plating, /area/ship/trade/shuttle/outgoing/engineering) +"tG" = ( +/obj/abstract/ramp_sculptor/north, +/turf/exterior/wall, +/area/space) "tV" = ( /turf/space, /area/ship/trade/command/fmate) @@ -5918,6 +5922,10 @@ /obj/effect/paint/brown, /turf/simulated/wall/r_wall/hull, /area/ship/trade/crew/medbay/chemistry) +"Cg" = ( +/obj/abstract/ramp_sculptor/east, +/turf/exterior/wall, +/area/space) "Co" = ( /obj/effect/floor_decal/corner/red/diagonal, /obj/structure/cable{ @@ -6764,7 +6772,7 @@ /obj/structure/handrail{ dir = 4 }, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "KO" = ( /obj/structure/cable{ @@ -7132,6 +7140,10 @@ /obj/machinery/reagent_temperature/cooler, /turf/simulated/floor/tiled/white, /area/ship/trade/crew/medbay/chemistry) +"OQ" = ( +/obj/abstract/ramp_sculptor/west, +/turf/exterior/wall, +/area/space) "Pa" = ( /obj/structure/cable{ icon_state = "0-4" @@ -7542,6 +7554,10 @@ /obj/effect/paint/sun, /turf/simulated/wall/titanium, /area/ship/trade/shuttle/outgoing/engineering) +"Tv" = ( +/obj/structure/lattice, +/turf/exterior/wall, +/area/space) "Tx" = ( /obj/structure/shuttle/engine/propulsion/burst/right, /turf/simulated/floor/airless, @@ -7907,7 +7923,7 @@ /obj/effect/floor_decal/industrial/warning, /obj/structure/catwalk, /obj/structure/railing/mapped, -/turf/simulated/open, +/turf/open, /area/ship/trade/cargo) "Yc" = ( /obj/structure/cable{ @@ -9850,9 +9866,9 @@ aa aa aa aa -aa -aa -aa +OQ +OQ +OQ xX aa aa @@ -9931,8 +9947,8 @@ aa aa aa aa -aa -aa +tG +eh eh eh pn @@ -10013,7 +10029,7 @@ aa aa aa aa -aa +tG eh ew ex @@ -10095,7 +10111,7 @@ aa aa aa aa -aa +tG eh ex ex @@ -10178,7 +10194,7 @@ aa aa aa aa -aa +eh ex ex fh @@ -12391,9 +12407,9 @@ aa aa aa aa -aa -aa -cy +eh +eh +Tv eN Gc fN @@ -12472,7 +12488,7 @@ aa aa aa aa -aa +tG eh eh eN @@ -12554,8 +12570,8 @@ aa aa aa aa -aa -aa +tG +eh ew eN eN @@ -12636,8 +12652,8 @@ aa aa aa aa -aa -aa +tG +eh eh eh eN @@ -12719,9 +12735,9 @@ aa aa aa aa -aa -aa -aa +Cg +Cg +Cg aa we we diff --git a/maps/tradeship/tradeship-3.dmm b/maps/tradeship/tradeship-3.dmm index cda8b435d76..a1788b55a73 100644 --- a/maps/tradeship/tradeship-3.dmm +++ b/maps/tradeship/tradeship-3.dmm @@ -461,7 +461,7 @@ icon_state = "32-2" }, /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/ship/trade/maintenance/solars) "bg" = ( /obj/structure/cable{ @@ -995,7 +995,7 @@ /turf/simulated/floor/plating, /area/ship/trade/maintenance/solars) "GP" = ( -/turf/simulated/open, +/turf/open, /area/ship/trade/maintenance/solars) "HN" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ @@ -1273,7 +1273,7 @@ dir = 8 }, /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/ship/trade/command/bridge_upper) "ZU" = ( /obj/machinery/network/telecomms_hub{ diff --git a/maps/tradeship/tradeship.dm b/maps/tradeship/tradeship.dm index d68490df078..9dbc68ec395 100644 --- a/maps/tradeship/tradeship.dm +++ b/maps/tradeship/tradeship.dm @@ -6,6 +6,7 @@ #include "../random_ruins/exoplanet_ruins/playablecolony/playablecolony.dm" + #include "../../mods/content/dungeon_loot/_dungeon_loot.dme" #include "../../mods/content/mundane.dm" #include "../../mods/content/bigpharma/_bigpharma.dme" #include "../../mods/content/baychems/_baychems.dme" diff --git a/maps/tradeship/tradeship_areas.dm b/maps/tradeship/tradeship_areas.dm index 278902530e6..f5ebe695a9e 100644 --- a/maps/tradeship/tradeship_areas.dm +++ b/maps/tradeship/tradeship_areas.dm @@ -318,12 +318,12 @@ /area/turbolift/tradeship_cargo name = "Lower Cargo Bay" - base_turf = /turf/simulated/open + base_turf = /turf/open /area/turbolift/tradeship_upper name = "Upper Cargo Bay" - base_turf = /turf/simulated/open + base_turf = /turf/open /area/turbolift/tradeship_roof name = "Solar Array Access" - base_turf = /turf/simulated/open \ No newline at end of file + base_turf = /turf/open \ No newline at end of file diff --git a/mods/content/baychems/items.dm b/mods/content/baychems/items.dm index 7055203bf6b..51620c32edf 100644 --- a/mods/content/baychems/items.dm +++ b/mods/content/baychems/items.dm @@ -28,7 +28,8 @@ desc = "A small bottle of opium." /obj/item/chems/glass/bottle/opium/populate_reagents() - reagents.add_reagent(/decl/material/liquid/opium, volume) + add_to_reagents(/decl/material/liquid/opium, volume) + . = ..() DEFINE_CARTRIDGE_FOR_CHEM(opium, /decl/material/liquid/opium) diff --git a/mods/content/baychems/reactions.dm b/mods/content/baychems/reactions.dm index cb702442ed0..8a57df6f5bc 100644 --- a/mods/content/baychems/reactions.dm +++ b/mods/content/baychems/reactions.dm @@ -1,10 +1,10 @@ -/decl/chemical_reaction/arithrazine +/decl/chemical_reaction/drug/arithrazine name = "Arithrazine" result = /decl/material/liquid/antirads/arithrazine required_reagents = list(/decl/material/liquid/antirads = 1, /decl/material/liquid/fuel/hydrazine = 1) result_amount = 2 -/decl/chemical_reaction/dermaline +/decl/chemical_reaction/drug/dermaline name = "Dermaline" result = /decl/material/liquid/burn_meds/dermaline required_reagents = list(/decl/material/liquid/acetone = 1, /decl/material/solid/phosphorus = 1, /decl/material/liquid/burn_meds = 1) @@ -12,7 +12,7 @@ minimum_temperature = -150 CELSIUS maximum_temperature = -50 CELSIUS -/decl/chemical_reaction/oxy_meds +/decl/chemical_reaction/drug/oxy_meds name = "Dexalin" result_amount = 1 required_reagents = list( @@ -21,13 +21,13 @@ ) catalysts = list(/decl/material/solid/phoron = 5) -/decl/chemical_reaction/dexalinp +/decl/chemical_reaction/drug/dexalinp name = "Dexalin Plus" result = /decl/material/liquid/oxy_meds/dexalinp required_reagents = list(/decl/material/liquid/oxy_meds = 1, /decl/material/solid/carbon = 1, /decl/material/solid/metal/iron = 1) result_amount = 3 -/decl/chemical_reaction/paracetamol +/decl/chemical_reaction/drug/paracetamol name = "Paracetamol" result = /decl/material/liquid/painkillers required_reagents = list( @@ -37,7 +37,7 @@ ) result_amount = 3 -/decl/chemical_reaction/strong_painkillers +/decl/chemical_reaction/drug/strong_painkillers name = "Tramadol" result = /decl/material/liquid/painkillers/strong required_reagents = list( @@ -47,20 +47,20 @@ ) result_amount = 3 -/decl/chemical_reaction/oxycodone +/decl/chemical_reaction/drug/oxycodone name = "Oxycodone" result = /decl/material/liquid/painkillers/oxycodone required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/painkillers/strong = 1) catalysts = list(/decl/material/solid/phoron = 5) result_amount = 1 -/decl/chemical_reaction/fentanyl +/decl/chemical_reaction/drug/fentanyl name = "Fentanyl" result = /decl/material/liquid/painkillers/fentanyl required_reagents = list(/decl/material/liquid/painkillers/oxycodone = 2, /decl/material/liquid/sedatives = 1, /decl/material/liquid/hallucinogenics = 1) result_amount = 2 -/decl/chemical_reaction/paroxetine +/decl/chemical_reaction/drug/paroxetine name = "Paroxetine" result = /decl/material/liquid/antidepressants/paroxetine required_reagents = list(/decl/material/liquid/hallucinogenics = 1, /decl/material/liquid/acetone = 1, /decl/material/liquid/stabilizer = 1) diff --git a/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm b/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm index 9c56ac4dfa0..afcf92ce025 100644 --- a/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm +++ b/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm @@ -812,7 +812,7 @@ /area/lar_maria/library) "cs" = ( /obj/structure/bookcase, -/obj/item/book/manual/stasis, +/obj/item/book/fluff/stasis, /turf/simulated/floor/tiled, /area/lar_maria/library) "cu" = ( @@ -831,8 +831,8 @@ /area/lar_maria/library) "cy" = ( /obj/structure/bookcase, -/obj/item/book/manual/anomaly_spectroscopy, -/obj/item/book/manual/anomaly_testing, +/obj/item/book/fluff/anomaly_spectroscopy, +/obj/item/book/fluff/anomaly_testing, /turf/simulated/floor/tiled, /area/lar_maria/library) "cz" = ( @@ -2100,7 +2100,7 @@ /turf/simulated/floor/plating, /area/lar_maria/hallway) "gD" = ( -/turf/simulated/open, +/turf/open, /area/lar_maria/hallway) "gE" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ @@ -2193,7 +2193,7 @@ /area/lar_maria/mess_hall) "gR" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /turf/simulated/floor/tiled, /area/lar_maria/mess_hall) @@ -2265,7 +2265,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/open, +/turf/open, /area/lar_maria/hallway) "hf" = ( /obj/structure/window/basic{ @@ -2286,7 +2286,7 @@ dir = 4; icon_state = "tube1" }, -/turf/simulated/open, +/turf/open, /area/lar_maria/hallway) "hi" = ( /obj/machinery/power/apc{ @@ -2610,7 +2610,7 @@ /obj/structure/table/marble, /obj/machinery/door/firedoor, /obj/item/chems/condiment/flour, -/obj/item/storage/fancy/egg_box, +/obj/item/storage/box/fancy/egg_box, /turf/simulated/floor/tiled/white, /area/lar_maria/mess_hall) "ie" = ( @@ -2776,13 +2776,13 @@ /area/lar_maria/mess_hall) "iB" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/lar_maria/mess_hall) "iC" = ( /obj/structure/table/marble, /obj/machinery/door/firedoor, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled/white, /area/lar_maria/mess_hall) "iD" = ( @@ -2941,7 +2941,7 @@ /area/lar_maria/mess_hall) "iZ" = ( /obj/structure/table/marble, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /turf/simulated/floor/tiled/white, /area/lar_maria/mess_hall) @@ -3077,7 +3077,7 @@ /obj/structure/cable{ icon_state = "32-1" }, -/turf/simulated/open, +/turf/open, /area/lar_maria/solar_control) "nb" = ( /obj/structure/tank_rack/oxygen, diff --git a/mods/content/corporate/datum/ai_laws.dm b/mods/content/corporate/datum/ai_laws.dm index 9029327ae00..380101d48cc 100644 --- a/mods/content/corporate/datum/ai_laws.dm +++ b/mods/content/corporate/datum/ai_laws.dm @@ -1,7 +1,7 @@ /obj/item/aiModule/nanotrasen // -- TLE name = "'Corporate Default' Core AI Module" desc = "A 'Corporate Default' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/nanotrasen /datum/ai_laws/nanotrasen @@ -18,7 +18,7 @@ /obj/item/aiModule/corp name = "\improper 'Corporate' core AI module" desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/corporate /datum/ai_laws/corporate @@ -51,5 +51,5 @@ /obj/item/aiModule/dais name = "\improper 'DAIS Experimental' core AI module" desc = "A 'DAIS Experimental' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':4}" + origin_tech = @'{"programming":4}' laws = new/datum/ai_laws/dais() diff --git a/mods/content/corporate/datum/antagonists/commando.dm b/mods/content/corporate/datum/antagonists/commando.dm index e99fa97cedd..c8069877986 100644 --- a/mods/content/corporate/datum/antagonists/commando.dm +++ b/mods/content/corporate/datum/antagonists/commando.dm @@ -29,14 +29,13 @@ ) /obj/item/encryptionkey/hacked - icon_state = "cypherkey" can_decrypt = list(access_hacked) - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' /obj/item/encryptionkey/hacked/Initialize(ml, material_key) . = ..() can_decrypt |= get_all_station_access() /obj/item/radio/headset/hacked - origin_tech = "{'esoteric':3}" + origin_tech = @'{"esoteric":3}' encryption_keys = list(/obj/item/encryptionkey/hacked) diff --git a/mods/content/corporate/icons/lunchbox_dais.dmi b/mods/content/corporate/icons/lunchbox_dais.dmi new file mode 100644 index 00000000000..ce2477fef72 Binary files /dev/null and b/mods/content/corporate/icons/lunchbox_dais.dmi differ diff --git a/mods/content/corporate/icons/lunchbox_nanotrasen.dmi b/mods/content/corporate/icons/lunchbox_nanotrasen.dmi new file mode 100644 index 00000000000..1a315285862 Binary files /dev/null and b/mods/content/corporate/icons/lunchbox_nanotrasen.dmi differ diff --git a/mods/content/corporate/icons/rigs/asset_protection/helmet.dmi b/mods/content/corporate/icons/rigs/asset_protection/helmet.dmi index 4a9df55f933..e312d83b55b 100644 Binary files a/mods/content/corporate/icons/rigs/asset_protection/helmet.dmi and b/mods/content/corporate/icons/rigs/asset_protection/helmet.dmi differ diff --git a/mods/content/corporate/icons/rigs/engineer/helmet.dmi b/mods/content/corporate/icons/rigs/engineer/helmet.dmi index e7559d0a6a4..0c63f505f2f 100644 Binary files a/mods/content/corporate/icons/rigs/engineer/helmet.dmi and b/mods/content/corporate/icons/rigs/engineer/helmet.dmi differ diff --git a/mods/content/corporate/icons/rigs/janitor/helmet.dmi b/mods/content/corporate/icons/rigs/janitor/helmet.dmi index ab136668772..1f3b3bdc7a6 100644 Binary files a/mods/content/corporate/icons/rigs/janitor/helmet.dmi and b/mods/content/corporate/icons/rigs/janitor/helmet.dmi differ diff --git a/mods/content/corporate/icons/rigs/medic/helmet.dmi b/mods/content/corporate/icons/rigs/medic/helmet.dmi index 2a8c3f0d258..9d3aa70b3cf 100644 Binary files a/mods/content/corporate/icons/rigs/medic/helmet.dmi and b/mods/content/corporate/icons/rigs/medic/helmet.dmi differ diff --git a/mods/content/corporate/icons/rigs/security/helmet.dmi b/mods/content/corporate/icons/rigs/security/helmet.dmi index f31f3f84cb0..df061882fbf 100644 Binary files a/mods/content/corporate/icons/rigs/security/helmet.dmi and b/mods/content/corporate/icons/rigs/security/helmet.dmi differ diff --git a/mods/content/corporate/items/clutter.dm b/mods/content/corporate/items/clutter.dm index f81ae0c829a..2a3f6e2772d 100644 --- a/mods/content/corporate/items/clutter.dm +++ b/mods/content/corporate/items/clutter.dm @@ -6,14 +6,12 @@ /obj/item/storage/lunchbox/dais name = "\improper DAIS brand lunchbox" - icon_state = "lunchbox_dais" - item_state = "toolbox_blue" + icon = 'mods/content/corporate/icons/lunchbox_dais.dmi' desc = "A little lunchbox. This one is branded with the Deimos Advanced Information Systems logo!" /obj/item/storage/lunchbox/nt name = "\improper NanoTrasen brand lunchbox" - icon_state = "lunchbox_nanotrasen" - item_state = "toolbox_blue" + icon = 'mods/content/corporate/icons/lunchbox_nanotrasen.dmi' desc = "A little lunchbox. This one is branded with the NanoTrasen logo!" /obj/item/storage/lunchbox/nt/filled diff --git a/mods/content/corporate/items/documents.dm b/mods/content/corporate/items/documents.dm index 13cd7e1ded3..d722d5c411a 100644 --- a/mods/content/corporate/items/documents.dm +++ b/mods/content/corporate/items/documents.dm @@ -4,107 +4,111 @@ description_antag = "A conglomerate of powerful corporations seems to be wanting to create weaponized xenobiological species. Probably as a form of WMD, by your best guess." icon_state = "docs_verified" -/obj/item/book/manual/nt_regs +/obj/item/book/fluff/nt_regs name = "Corporate Regulations" desc = "A set of corporate guidelines for employees of a megacorporation." icon_state = "booknanoregs" author = "Employee Materials" title = "Corporate Regulations" - url = "Corporate_Regulations" + fluff_text = "The book is empty..." /obj/item/book/union_charter name = "\improper Union Charter" + unique = TRUE title = "Union Charter of Workplace Rights" author = "Corporate Union" - dat = {"Corporate Union Charter of Workplace Rights - -

    0. Summary

    -
    -

    As a union representative, you are required to uphold the interests of contracted workers on your station or vessel. You are empowered to inspect workplaces and instigate cessation of contracted work when on green alert, with diminishing powers during a state of emergency. You do not have authority or jurisdiction over government or military workers, or any workers who are not card-carrying signatories to this Charter.

    -

    1. Introduction

    -

    This Charter of Rights sets out the rights and responsibilities of all workplace parties in the provision of decent and fair health, safety, compensation and rehabilitation systems and practices within affiliated workplaces. Regardless of jurisdiction, changes to occupational health and safety, compensation and rehabilitation law must not result in a diminution of the rights and entitlements of any worker.

    -

    This Charter does not apply to staff who are not signatory to the Solar Employee General Award, or are signatory to other workplace regulatory documents such as the internal protocols of your local legislative body. Union representatives must take care to ensure that their operations on mixed jurisdiction stations and vessels are restricted to those areas that have a union worker, contractor or labourer presence.

    -

    Workers must not be adversely affected by any employer moving between jurisdictions in relation to their OHS and workers compensation entitlements. Any proposed move between jurisdictions will only occur following genuine consultation and agreement with workers and their representatives and a process of public review, including public tribunal hearings.

    -

    Consistent with OHS and Worker Compensation Policy and interstellar standards, Solar law must ensure healthy and safe workplaces and a compensation and rehabilitation system which ensures that no worker is disadvantaged should they be injured at work.

    -

    All workers have the right to join a genuine trade union. Union organised workplaces are safer workplaces.

    -

    2. Security Levels

    -
    -

    On stations or vessels employing the standard Security Alert Level protocol, the following conditions apply:

    -
      -
    • On green alert, all particulars of this charter are considered valid and applicable.
    • -
    • Above green alert, union representatives are not permitted to conduct workplace inspections and are advised, but not required, to cease all union meetings or strike proceedings.
    • -
    • On red alert or above, this charter is suspended, and all union representatives and workers must follow directives from personnel authorized under red alert protocol.
    • -
    -

    3. Representation

    -
    -

    Every worker has the right to be represented on health, safety, compensation, rehabilitation and return to work issues, by their elected Union Representative and their union. Every worker has the right to elect health and safety representatives.

    -

    Unions have the right to:

    -
      -
    • Enter workplaces on health and safety issues;
    • -
    • Investigate breaches of health and safety laws;
    • -
    • Represent members and prospective members;
    • -
    • Initiate investigations and prosecutions for occupational health and safety breaches;
    • -
    • Initiate cessation of work in unsafe areas; and
    • -
    • Access all relevant information and reports.
    • -
    -

    Union Representatives have the right to:

    -
      -
    • Be democratically elected by a process determined by workers, in conjunction with their union;
    • -
    • Utilise legal rights and powers to represent workers on health and safety matters;
    • -
    • Inspect the workplace, within the agreed-upon confines previously noted;
    • -
    • Access relevant information and be informed of all incidents;
    • -
    • Be consulted by the employer before workplace changes occur that may affect health and safety;
    • -
    • Issue notices when breaches are detected;
    • -
    • Call in government inspectors;
    • -
    • Direct workers to cease work where there is a belief of immediate risk to health and safety;
    • -
    • Seek resolution of health and safety issues;
    • -
    • Perform all OHS activities on paid time and have adequate facilities;
    • -
    • Be assisted by any person at any time in the execution of union duties;
    • -
    • Be protected by law from discrimination, harassment, bullying, intimidation and prosecution;
    • -
    • Appeal any decision of a regulator or court regarding any health and safety, compensation or rehabilitation matter.
    • -
    -

    4. Workers

    -
    -

    Every worker has the right to: -

      -
    • A safe and healthy workplace;
    • -
    • Travel to and from work sites in safety and with appropriate protections;
    • -
    • Return home from work free of injury or illness;
    • -
    • Enjoy the highest level of protection, representation, compensation and rehabilitation, regardless of the jurisdiction within which they work;
    • -
    • Take collective action over any health and safety matter, including the right to cease unsafe or unhealthy work; and
    • -
    • Discuss, negotiate and be consulted and involved in all issues affecting their health, safety and welfare.
    • -
    -

    All workers (or prospective workers), including health and safety representatives, will be protected by law from discrimination, harassment, bullying or detriment to their employment because they have raised a health and safety issue, lodged a compensation claim or been involved in consultation on workplace health and safety matters.

    -

    4. Employer Responsibilities

    -
    -

    Persons who control, manage or own workplaces have an absolute duty of care without limitation to provide and maintain safe and healthy work environments. Employers will not shift jurisdictions to attempt to avoid their OHS and workers compensation responsibilities and obligations. Employers are subject to all the obligations and responsibilities contained within this Charter.

    -

    5. Compensation

    -
    -

    Following a physical or psychological injury, all workers have the right to a fair, just and equitable compensation system, which promotes the best medical and like support, the most effective rehabilitation for injured workers and facilitates a safe return to work that offers genuine job security. Workers' compensation standards are to:

    -
  • Be available to all members of the workforce;
  • -
  • Provide compensation for all injuries that arise from travel to, from or during work including and during recess breaks;
  • -
  • Be available upon the death of a worker and for dependants of that worker;
  • -
  • Be based on the 100% replacement of loss of income;
  • -
  • Provide total cost of medical rehabilitation and other related expenses;
  • -
  • Provide lump sum compensation for permanent disability;
  • -
  • Ensure common law rights;
  • -
  • Support rehabilitation and return to work;
  • -
  • Ensure that workers are entitled to timely and effective claim determination and dispute resolution processes;
  • -
  • Ensure the worker has access to the doctor of their choice; and
  • -
  • Not be eroded by companies seeking to self-insure in order to obtain lower OHS and worker's compensation entitlements for workers.
  • - -

    6. Rehabilitation

    -
    -

    All workers have the right to return to safe, suitable, meaningful and sustainable work, following the provision of quality rehabilitation services, commensurate to need. Rehabilitation will include the right to:

    -
      -
    • Union representation;
    • -
    • Fair, equitable, high quality, appropriate, effective and timely rehabilitation plans and services;
    • -
    • Consultation about all aspects of rehabilitation;
    • -
    • All documentation and information relating to their rehabilitation;
    • -
    • Privacy in the management of all records and information; and
    • -
    • Personal choice of medical provider and rehabilitation service, where facilities permit.
    • -
    - + dat = {" + + Corporate Union Charter of Workplace Rights + + +

    0. Summary

    +
    +

    As a union representative, you are required to uphold the interests of contracted workers on your station or vessel. You are empowered to inspect workplaces and instigate cessation of contracted work when on green alert, with diminishing powers during a state of emergency. You do not have authority or jurisdiction over government or military workers, or any workers who are not card-carrying signatories to this Charter.

    +

    1. Introduction

    +

    This Charter of Rights sets out the rights and responsibilities of all workplace parties in the provision of decent and fair health, safety, compensation and rehabilitation systems and practices within affiliated workplaces. Regardless of jurisdiction, changes to occupational health and safety, compensation and rehabilitation law must not result in a diminution of the rights and entitlements of any worker.

    +

    This Charter does not apply to staff who are not signatory to the Solar Employee General Award, or are signatory to other workplace regulatory documents such as the internal protocols of your local legislative body. Union representatives must take care to ensure that their operations on mixed jurisdiction stations and vessels are restricted to those areas that have a union worker, contractor or labourer presence.

    +

    Workers must not be adversely affected by any employer moving between jurisdictions in relation to their OHS and workers compensation entitlements. Any proposed move between jurisdictions will only occur following genuine consultation and agreement with workers and their representatives and a process of public review, including public tribunal hearings.

    +

    Consistent with OHS and Worker Compensation Policy and interstellar standards, Solar law must ensure healthy and safe workplaces and a compensation and rehabilitation system which ensures that no worker is disadvantaged should they be injured at work.

    +

    All workers have the right to join a genuine trade union. Union organised workplaces are safer workplaces.

    +

    2. Security Levels

    +
    +

    On stations or vessels employing the standard Security Alert Level protocol, the following conditions apply:

    +
      +
    • On green alert, all particulars of this charter are considered valid and applicable.
    • +
    • Above green alert, union representatives are not permitted to conduct workplace inspections and are advised, but not required, to cease all union meetings or strike proceedings.
    • +
    • On red alert or above, this charter is suspended, and all union representatives and workers must follow directives from personnel authorized under red alert protocol.
    • +
    +

    3. Representation

    +
    +

    Every worker has the right to be represented on health, safety, compensation, rehabilitation and return to work issues, by their elected Union Representative and their union. Every worker has the right to elect health and safety representatives.

    +

    Unions have the right to:

    +
      +
    • Enter workplaces on health and safety issues;
    • +
    • Investigate breaches of health and safety laws;
    • +
    • Represent members and prospective members;
    • +
    • Initiate investigations and prosecutions for occupational health and safety breaches;
    • +
    • Initiate cessation of work in unsafe areas; and
    • +
    • Access all relevant information and reports.
    • +
    +

    Union Representatives have the right to:

    +
      +
    • Be democratically elected by a process determined by workers, in conjunction with their union;
    • +
    • Utilise legal rights and powers to represent workers on health and safety matters;
    • +
    • Inspect the workplace, within the agreed-upon confines previously noted;
    • +
    • Access relevant information and be informed of all incidents;
    • +
    • Be consulted by the employer before workplace changes occur that may affect health and safety;
    • +
    • Issue notices when breaches are detected;
    • +
    • Call in government inspectors;
    • +
    • Direct workers to cease work where there is a belief of immediate risk to health and safety;
    • +
    • Seek resolution of health and safety issues;
    • +
    • Perform all OHS activities on paid time and have adequate facilities;
    • +
    • Be assisted by any person at any time in the execution of union duties;
    • +
    • Be protected by law from discrimination, harassment, bullying, intimidation and prosecution;
    • +
    • Appeal any decision of a regulator or court regarding any health and safety, compensation or rehabilitation matter.
    • +
    +

    4. Workers

    +
    +

    Every worker has the right to: +

      +
    • A safe and healthy workplace;
    • +
    • Travel to and from work sites in safety and with appropriate protections;
    • +
    • Return home from work free of injury or illness;
    • +
    • Enjoy the highest level of protection, representation, compensation and rehabilitation, regardless of the jurisdiction within which they work;
    • +
    • Take collective action over any health and safety matter, including the right to cease unsafe or unhealthy work; and
    • +
    • Discuss, negotiate and be consulted and involved in all issues affecting their health, safety and welfare.
    • +
    +

    All workers (or prospective workers), including health and safety representatives, will be protected by law from discrimination, harassment, bullying or detriment to their employment because they have raised a health and safety issue, lodged a compensation claim or been involved in consultation on workplace health and safety matters.

    +

    4. Employer Responsibilities

    +
    +

    Persons who control, manage or own workplaces have an absolute duty of care without limitation to provide and maintain safe and healthy work environments. Employers will not shift jurisdictions to attempt to avoid their OHS and workers compensation responsibilities and obligations. Employers are subject to all the obligations and responsibilities contained within this Charter.

    +

    5. Compensation

    +
    +

    Following a physical or psychological injury, all workers have the right to a fair, just and equitable compensation system, which promotes the best medical and like support, the most effective rehabilitation for injured workers and facilitates a safe return to work that offers genuine job security. Workers' compensation standards are to:

    +
  • Be available to all members of the workforce;
  • +
  • Provide compensation for all injuries that arise from travel to, from or during work including and during recess breaks;
  • +
  • Be available upon the death of a worker and for dependants of that worker;
  • +
  • Be based on the 100% replacement of loss of income;
  • +
  • Provide total cost of medical rehabilitation and other related expenses;
  • +
  • Provide lump sum compensation for permanent disability;
  • +
  • Ensure common law rights;
  • +
  • Support rehabilitation and return to work;
  • +
  • Ensure that workers are entitled to timely and effective claim determination and dispute resolution processes;
  • +
  • Ensure the worker has access to the doctor of their choice; and
  • +
  • Not be eroded by companies seeking to self-insure in order to obtain lower OHS and worker's compensation entitlements for workers.
  • + +

    6. Rehabilitation

    +
    +

    All workers have the right to return to safe, suitable, meaningful and sustainable work, following the provision of quality rehabilitation services, commensurate to need. Rehabilitation will include the right to:

    +
      +
    • Union representation;
    • +
    • Fair, equitable, high quality, appropriate, effective and timely rehabilitation plans and services;
    • +
    • Consultation about all aspects of rehabilitation;
    • +
    • All documentation and information relating to their rehabilitation;
    • +
    • Privacy in the management of all records and information; and
    • +
    • Personal choice of medical provider and rehabilitation service, where facilities permit.
    • +
    + "} /obj/item/folder/nt diff --git a/mods/content/corporate/items/wristcomp.dm b/mods/content/corporate/items/wristcomp.dm index 5f9cc48611d..3ec7b2c5a34 100644 --- a/mods/content/corporate/items/wristcomp.dm +++ b/mods/content/corporate/items/wristcomp.dm @@ -8,7 +8,7 @@ color = COLOR_GUNMETAL light_color = LIGHT_COLOR_GREEN -/obj/item/modular_computer/pda/wrist/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/modular_computer/pda/wrist/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay) var/datum/extension/interactive/os/os = get_extension(src, /datum/extension/interactive/os) var/datum/extension/assembly/modular_computer/assembly = get_extension(src, /datum/extension/assembly) diff --git a/mods/content/dungeon_loot/_dungeon_loot.dme b/mods/content/dungeon_loot/_dungeon_loot.dme index 30b52f7b75c..f01aaf9cb65 100644 --- a/mods/content/dungeon_loot/_dungeon_loot.dme +++ b/mods/content/dungeon_loot/_dungeon_loot.dme @@ -2,6 +2,9 @@ #define MODPACK_DUNGEON_LOOT // BEGIN INCLUDE #include "_dungeon_loot.dm" -#include "loot_parent.dm" -#include "loot_structures.dm" -#endif \ No newline at end of file +#include "loot_pile.dm" +#include "subtypes/exosuit.dm" +#include "subtypes/maint.dm" +#include "subtypes/stubs.dm" +#include "subtypes/surface.dm" +#endif diff --git a/mods/content/dungeon_loot/icons/loot_piles.dmi b/mods/content/dungeon_loot/icons/loot_piles.dmi new file mode 100644 index 00000000000..784f9e47b23 Binary files /dev/null and b/mods/content/dungeon_loot/icons/loot_piles.dmi differ diff --git a/mods/content/dungeon_loot/loot_pile.dm b/mods/content/dungeon_loot/loot_pile.dm new file mode 100644 index 00000000000..fc8dff5808a --- /dev/null +++ b/mods/content/dungeon_loot/loot_pile.dm @@ -0,0 +1,131 @@ +/obj/structure/loot_pile + abstract_type = /obj/structure/loot_pile + name = "base loot pile" + desc = "If you can read me, this is bugged." + icon = 'mods/content/dungeon_loot/icons/loot_piles.dmi' + icon_state = "randompile" + density = FALSE + anchored = TRUE + + /// Keys that have searched this loot pile, with values of searched time. + var/list/searched_by + /// If true, the same person can loot multiple times. Mostly for debugging. + var/allow_multiple_looting = FALSE + /// Used so you can't spamclick to loot. + var/busy = FALSE + /// Unlucky people might need to loot multiple spots to find things. + var/chance_nothing = 0 + /// Probability of pulling from the uncommon_loot list. + var/chance_uncommon = 10 + /// Ditto, but for rare_loot list. + var/chance_rare = 1 + /// If true, loot piles can be 'depleted' after a certain number of searches by different players, where no more loot can be obtained. + var/loot_depletion = FALSE + /// When this reaches zero, and loot_depleted is true, you can't obtain anymore loot. + var/loot_left = 0 + /// If true, and if the loot gets depleted as above, the pile is deleted. + var/delete_on_depletion = FALSE + +/obj/structure/loot_pile/Initialize() + var/list/icon_states_to_use = get_icon_states_to_use() + if(icon_states_to_use && icon_states_to_use.len) + icon_state = pick(icon_states_to_use) + . = ..() + +/obj/structure/loot_pile/attack_ai(var/mob/user) + if(isrobot(user) && Adjacent(user)) + return attack_hand(user) + return ..() + +/obj/structure/loot_pile/attack_hand(mob/user) + + if(!isliving(user)) + return ..() + + var/mob/living/L = user + if(busy) + to_chat(L, SPAN_WARNING("\The [src] is already being searched.")) + return TRUE + + L.visible_message("\The [user] searches through \the [src].", SPAN_NOTICE("You search through \the [src]."), SPAN_NOTICE("You hear some rustling.")) + + //Do the searching + busy = TRUE + if(!do_after(user,rand(4 SECONDS,6 SECONDS),src)) + busy = FALSE + return TRUE + busy = FALSE + + // The loot's all gone. + if(loot_depletion && loot_left <= 0) + to_chat(L, SPAN_WARNING("\The [src] has been picked clean.")) + return TRUE + + //You already searched this one + if(!allow_multiple_looting && (user.ckey in searched_by)) + to_chat(L, SPAN_WARNING("You can't find anything else vaguely useful in \the [src]. Another set of eyes might, however.")) + return TRUE + + // You got unlucky. + if(chance_nothing && prob(chance_nothing)) + to_chat(L, SPAN_WARNING("Nothing in this pile really catches your eye this time.")) + return TRUE + + // You found something! + searched_by |= user.ckey + var/obj/item/loot = null + var/span = "notice" // Blue + + if(prob(chance_rare) && length(get_rare_loot())) // You won THE GRAND PRIZE! + loot = produce_rare_item() + span = "cult" // Purple and bold. + else if(prob(chance_uncommon) && length(get_uncommon_loot())) // Otherwise you might still get something good. + loot = produce_uncommon_item() + span = "alium" // Green + else if(length(get_common_loot())) // Welp. + loot = produce_common_item() + + if(loot) + loot.forceMove(get_turf(src)) + to_chat(L, SPAN_CLASS(span, "You found \a [loot]!")) + if(loot_depletion) + loot_left-- + if(loot_left <= 0) + to_chat(L, SPAN_WARNING("You seem to have gotten the last of the spoils inside \the [src].")) + if(delete_on_depletion) + qdel(src) + return TRUE + +/obj/structure/loot_pile/proc/produce_common_item() + var/list/common_loot = get_common_loot() + if(length(common_loot)) + var/path = pick(common_loot) + return new path(src) + +/obj/structure/loot_pile/proc/produce_uncommon_item() + var/list/uncommon_loot = get_uncommon_loot() + if(length(uncommon_loot)) + var/path = pick(uncommon_loot) + return new path(src) + +/obj/structure/loot_pile/proc/produce_rare_item() + var/list/rare_loot = get_rare_loot() + if(length(rare_loot)) + var/path = pick(rare_loot) + return new path(src) + +/// Returns a list of generally less-than-useful junk and filler, at least for maint loot piles. +/obj/structure/loot_pile/proc/get_common_loot() + return + +/// Returns a list of some maybe actually useful items, usually the reason someone bothers looking inside. +/obj/structure/loot_pile/proc/get_uncommon_loot() + return + +/// Returns a list of really powerful, or at least unique items. +/obj/structure/loot_pile/proc/get_rare_loot() + return + +/// Returns a list of icon states the pile can choose from on initialization. If empty or null, it will stay the initial icon_state. +/obj/structure/loot_pile/proc/get_icon_states_to_use() + return diff --git a/mods/content/dungeon_loot/subtypes/exosuit.dm b/mods/content/dungeon_loot/subtypes/exosuit.dm new file mode 100644 index 00000000000..44a04ae3a75 --- /dev/null +++ b/mods/content/dungeon_loot/subtypes/exosuit.dm @@ -0,0 +1,169 @@ +// Subtype for mecha and mecha accessories. These might not always be on the surface. +/obj/structure/loot_pile/exosuit + name = "pod wreckage" + desc = "The ruins of some unfortunate pod. Perhaps something is salvageable." + icon_state = "wreck" + icon = 'icons/mecha/mech_part_items.dmi' + density = TRUE + anchored = FALSE // In case a dead mecha-mob dies in a bad spot. + chance_uncommon = 20 + chance_rare = 10 + loot_depletion = TRUE + loot_left = 9 + abstract_type = /obj/structure/loot_pile/exosuit + +// Subtypes below. +/obj/structure/loot_pile/exosuit/powerloader + name = "powerloader exosuit wreckage" + desc = "The ruins of some unfortunate powerloader exosuit. Perhaps something is salvageable." + +/obj/structure/loot_pile/exosuit/powerloader/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/powerloader/painted, + /obj/item/mech_component/propulsion/powerloader/painted + ) + return common_loot + +/obj/structure/loot_pile/exosuit/powerloader/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_equipment/drill/steel, + /obj/item/mech_equipment/clamp + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/powerloader/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_component/sensors/powerloader/painted, + /obj/item/mech_component/chassis/powerloader/painted + ) + return rare_loot + +/obj/structure/loot_pile/exosuit/firefighter + name = "firefighter exosuit wreckage" + desc = "The ruins of some unfortunate firefighter exosuit. Perhaps something is salvageable." + +/obj/structure/loot_pile/exosuit/firefighter/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/powerloader/painted, + /obj/item/mech_component/propulsion/powerloader/painted, + /obj/item/mech_component/chassis/heavy + ) + return common_loot + +/obj/structure/loot_pile/exosuit/firefighter/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_equipment/drill/steel, + /obj/item/mech_equipment/mounted_system/extinguisher + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/firefighter/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_component/sensors/powerloader/painted + ) + return rare_loot + +/obj/structure/loot_pile/exosuit/combat + name = "combat exosuit wreckage" + desc = "The ruins of some unfortunate combat exosuit. Perhaps something is salvageable." + +/obj/structure/loot_pile/exosuit/combat/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/combat/painted, + /obj/item/mech_component/propulsion/combat/painted, + /obj/item/mech_equipment/flash, + /obj/item/mech_equipment/light + ) + return common_loot + +/obj/structure/loot_pile/exosuit/combat/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_component/chassis/combat/painted, + /obj/item/mech_equipment/mounted_system/taser + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/combat/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_component/sensors/combat/painted, + /obj/item/mech_equipment/mounted_system/projectile/assault_rifle + ) + return rare_loot + +/obj/structure/loot_pile/exosuit/explorer + name = "exploration exosuit wreckage" + desc = "The ruins of some unfortunate exploration exosuit. Perhaps something is salvagable." + +/obj/structure/loot_pile/exosuit/explorer/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/powerloader/exploration, + /obj/item/mech_component/chassis/pod/exploration, + /obj/item/mech_equipment/light + ) + return common_loot + +/obj/structure/loot_pile/exosuit/explorer/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_component/propulsion/tracks/exploration, + /obj/item/mech_equipment/clamp + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/explorer/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_component/sensors/light/painted, + /obj/item/mech_equipment/mounted_system/taser/plasma + ) + return rare_loot + +/obj/structure/loot_pile/exosuit/heavy + name = "heavy exosuit wreckage" + desc = "The ruins of some unfortunate heavy exosuit. Perhaps something is salvagable." + +/obj/structure/loot_pile/exosuit/heavy/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/heavy/painted, + /obj/item/mech_component/propulsion/heavy/painted, + /obj/item/mech_component/chassis/heavy/painted + ) + return common_loot + +/obj/structure/loot_pile/exosuit/heavy/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_equipment/shields, + /obj/item/mech_equipment/mounted_system/taser + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/heavy/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_equipment/mounted_system/taser/laser, + /obj/item/mech_component/sensors/heavy/painted + ) + return rare_loot + +/obj/structure/loot_pile/exosuit/light + name = "light exosuit wreckage" + desc = "The ruins of some unfortunate light exosuit. Perhaps something is salvagable." + +/obj/structure/loot_pile/exosuit/light/get_common_loot() + var/static/list/common_loot = list( + /obj/item/mech_component/manipulators/light/painted, + /obj/item/mech_component/propulsion/light/painted, + /obj/item/mech_component/chassis/light/painted + ) + return common_loot + +/obj/structure/loot_pile/exosuit/light/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/mech_component/sensors/light/painted, + /obj/item/mech_equipment/light + ) + return uncommon_loot + +/obj/structure/loot_pile/exosuit/light/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/mech_equipment/catapult, + /obj/item/mech_equipment/sleeper + ) + return rare_loot diff --git a/mods/content/dungeon_loot/loot_structures.dm b/mods/content/dungeon_loot/subtypes/maint.dm similarity index 60% rename from mods/content/dungeon_loot/loot_structures.dm rename to mods/content/dungeon_loot/subtypes/maint.dm index efa4a7ce77b..1346b9c3aa2 100644 --- a/mods/content/dungeon_loot/loot_structures.dm +++ b/mods/content/dungeon_loot/subtypes/maint.dm @@ -1,10 +1,23 @@ // Has large amounts of possible items, most of which may or may not be useful. +/obj/structure/loot_pile/maint + abstract_type = /obj/structure/loot_pile/maint + +/obj/structure/loot_pile/maint/get_icon_states_to_use() + var/static/list/icon_states_to_use = list( + "junk_pile1", + "junk_pile2", + "junk_pile3", + "junk_pile4", + "junk_pile5" + ) + return icon_states_to_use + /obj/structure/loot_pile/maint/junk name = "pile of junk" desc = "Lots of junk lying around. They say one man's trash is another man's treasure." - icon_states_to_use = list("junk_pile1", "junk_pile2", "junk_pile3", "junk_pile4", "junk_pile5") - common_loot = list( +/obj/structure/loot_pile/maint/junk/get_common_loot() + var/static/list/common_loot = list( /obj/item/flashlight/flare, /obj/item/flashlight/flare/glowstick, /obj/item/flashlight/flare/glowstick/blue, @@ -49,11 +62,9 @@ /obj/item/clothing/suit/storage/toggle/bomber, /obj/item/clothing/suit/bio_suit/general, /obj/item/clothing/suit/storage/toggle/hoodie/black, - /* /obj/item/clothing/suit/storage/toggle/hoodie/blue, /obj/item/clothing/suit/storage/toggle/hoodie/red, /obj/item/clothing/suit/storage/toggle/hoodie/yellow, - */ /obj/item/clothing/suit/storage/toggle/brown_jacket, /obj/item/clothing/suit/storage/leather_jacket, /obj/item/clothing/suit/apron, @@ -75,8 +86,10 @@ /obj/item/radio/headset, /obj/item/paicard, ) + return common_loot - uncommon_loot = list( +/obj/structure/loot_pile/maint/junk/get_uncommon_loot() + var/static/list/uncommon_loot = list( /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/gloves/insulated, /obj/item/clothing/under/tactical, @@ -85,19 +98,28 @@ /obj/item/knife/combat, /obj/item/knife/folding/combat/switchblade, ) + return uncommon_loot - rare_loot = list( +/obj/structure/loot_pile/maint/junk/get_rare_loot() + var/static/list/rare_loot = list( /obj/item/clothing/suit/armor/vest/heavy, /obj/item/clothing/shoes/jackboots/swat/combat, ) + return rare_loot // Contains mostly useless garbage. /obj/structure/loot_pile/maint/trash name = "pile of trash" desc = "Lots of garbage in one place. Might be able to find something if you're in the mood for dumpster diving." - icon_states_to_use = list("trash_pile1", "trash_pile2") - common_loot = list( +/obj/structure/loot_pile/maint/trash/get_icon_states_to_use() + var/static/list/icon_states_to_use = list( + "trash_pile1", + "trash_pile2") + return icon_states_to_use + +/obj/structure/loot_pile/maint/trash/get_common_loot() + var/static/list/common_loot = list( /obj/item/trash/candle, /obj/item/trash/candy, /obj/item/trash/candy/proteinbar, @@ -107,7 +129,7 @@ /obj/item/trash/stick, /obj/item/trash/liquidfood, /obj/item/trash/pistachios, - /obj/item/trash/plate, + /obj/item/plate, /obj/item/trash/popcorn, /obj/item/trash/raisins, /obj/item/trash/semki, @@ -116,7 +138,6 @@ /obj/item/trash/syndi_cakes, /obj/item/trash/tastybread, /obj/item/chems/drinks/sillycup, - /obj/item/trash/tray, /obj/item/trash/driedfish, /obj/item/trash/waffles, /obj/item/trash/beef, @@ -136,30 +157,39 @@ /obj/item/paper/crumpled, /obj/item/paper/crumpled/bloody, ) + return common_loot - uncommon_loot = list( +/obj/structure/loot_pile/maint/trash/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/plate, + /obj/item/plate/tray, /obj/item/chems/syringe/steroid, /obj/item/storage/pill_bottle/zoom, /obj/item/storage/pill_bottle/happy, /obj/item/storage/pill_bottle/painkillers, ) + return uncommon_loot // Contains loads of different types of boxes, which may have items inside! /obj/structure/loot_pile/maint/boxfort name = "pile of boxes" desc = "A large pile of boxes sits here." density = TRUE - icon_states_to_use = list("boxfort") - common_loot = list( +/obj/structure/loot_pile/maint/boxfort/get_icon_states_to_use() + var/static/list/icon_states_to_use = list("boxfort") + return icon_states_to_use + +/obj/structure/loot_pile/maint/boxfort/get_common_loot() + var/static/list/common_loot = list( /obj/item/storage/box, /obj/item/storage/box/beakers, /obj/item/storage/box/botanydisk, /obj/item/storage/box/cups, /obj/item/storage/box/botanydisk, /obj/item/storage/box/donkpockets, - /obj/item/storage/box/donut, - /obj/item/storage/box/donut/empty, + /obj/item/storage/box/fancy/donut, + /obj/item/storage/box/fancy/donut/empty, /obj/item/storage/box/evidence, /obj/item/storage/box/lights/mixed, /obj/item/storage/box/lights/tubes, @@ -173,8 +203,10 @@ /obj/item/storage/box/gloves, /obj/item/storage/box/PDAs, ) + return common_loot - uncommon_loot = list( +/obj/structure/loot_pile/maint/boxfort/get_uncommon_loot() + var/static/list/uncommon_loot = list( /obj/item/storage/box/sinpockets, /obj/item/storage/box/ammo/practiceshells, /obj/item/storage/box/ammo/blanks, @@ -184,23 +216,34 @@ // TODO: Replace with box of Security NIFsofts? Or a box of USB sticks with programs on them? // /obj/item/storage/box/seccarts ) + return uncommon_loot - rare_loot = list( +/obj/structure/loot_pile/maint/boxfort/get_rare_loot() + var/static/list/rare_loot = list( /obj/item/storage/box/flashbangs, /obj/item/storage/box/empslite, /obj/item/storage/box/ammo/flashshells, /obj/item/storage/box/ammo/stunshells, /obj/item/storage/box/teargas, ) + return rare_loot // One of the more useful maint piles, contains electrical components. /obj/structure/loot_pile/maint/technical name = "broken machine" desc = "A destroyed machine with unknown purpose, and doesn't look like it can be fixed. It might still have some functional components?" density = TRUE - icon_states_to_use = list("technical_pile1", "technical_pile2", "technical_pile3") - common_loot = list( +/obj/structure/loot_pile/maint/technical/get_icon_states_to_use() + var/static/list/icon_states_to_use = list( + "technical_pile1", + "technical_pile2", + "technical_pile3" + ) + return icon_states_to_use + +/obj/structure/loot_pile/maint/technical/get_common_loot() + var/static/list/common_loot = list( /obj/item/stock_parts/network_receiver, /obj/item/stock_parts/radio/receiver, /obj/item/stock_parts/radio/transmitter, @@ -267,8 +310,10 @@ /obj/item/robot_parts/robot_component/diagnosis_unit, /obj/item/robot_parts/robot_component/radio, ) + return common_loot - uncommon_loot = list( +/obj/structure/loot_pile/maint/technical/get_uncommon_loot() + var/static/list/uncommon_loot = list( /obj/item/cell/super, /obj/item/cell/gun, /obj/item/aiModule/reset, @@ -277,7 +322,6 @@ // todo: add some decent non-contraband NIFsoft disks here /obj/item/disk/integrated_circuit/upgrade/advanced, /obj/item/camera/tvcamera, - /obj/item/universal_translator, /obj/item/aicard, /obj/item/borg/upgrade/jetpack, /obj/item/borg/upgrade/vtec, @@ -292,215 +336,15 @@ /obj/item/rig_module/vision/meson, /obj/item/rig_module/vision/sechud, ) + return uncommon_loot - rare_loot = list( +/obj/structure/loot_pile/maint/technical/get_rare_loot() + var/static/list/rare_loot = list( /obj/item/cell/hyper, /obj/item/aiModule/freeform, /obj/item/aiModule/asimov, /obj/item/aiModule/paladin, /obj/item/aiModule/safeguard, ) + return rare_loot - -// Surface base type -/obj/structure/loot_pile/surface - // Surface loot piles are considerably harder and more dangerous to reach, so you're more likely to get rare things. - chance_uncommon = 20 - chance_rare = 5 - loot_depletion = TRUE - loot_left = 5 // This is to prevent people from asking the whole station to go down to some alien ruin to get massive amounts of phat lewt. - -// Base type for alien piles. -/obj/structure/loot_pile/surface/alien - name = "alien pod" - desc = "A pod which looks bigger on the inside. Something quite shiny might be inside?" - icon_state = "alien_pile1" - -/obj/structure/loot_pile/surface/alien - common_loot = list() - -// May contain alien tools. -/obj/structure/loot_pile/surface/alien/engineering - uncommon_loot = list() - rare_loot = list() - -// May contain alien surgery equipment or powerful medication. -/obj/structure/loot_pile/surface/alien/medical - uncommon_loot = list() - rare_loot = list() - -// May contain powercells or alien weaponry. -/obj/structure/loot_pile/surface/alien/security - uncommon_loot = list() - rare_loot = list() - -// The pile found at the very end, and as such has the best loot. -/obj/structure/loot_pile/surface/alien/end - chance_uncommon = 30 - chance_rare = 10 - - common_loot = list() - uncommon_loot = list() - -// Subtype for mecha and mecha accessories. These might not always be on the surface. -/obj/structure/loot_pile/mecha - name = "pod wreckage" - desc = "The ruins of some unfortunate pod. Perhaps something is salvageable." - icon = 'icons/obj/mech_wrecks.dmi' - icon_state = "engineering_pod-broken" - density = TRUE - anchored = FALSE // In case a dead mecha-mob dies in a bad spot. - - chance_uncommon = 20 - chance_rare = 10 - - loot_depletion = TRUE - loot_left = 9 - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -//Stuff you may find attached to a ripley. -/obj/structure/loot_pile/mecha/ripley - name = "ripley wreckage" - desc = "The ruins of some unfortunate ripley. Perhaps something is salvageable." - icon_state = "ripley-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/mecha/ripley/firefighter - icon_state = "firefighter-broken" - -/obj/structure/loot_pile/mecha/ripley/random_sprite - icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old") - -//Death-Ripley, same common, but more combat-exosuit-based -/obj/structure/loot_pile/mecha/deathripley - name = "strange ripley wreckage" - icon_state = "deathripley-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/mecha/odysseus - name = "odysseus wreckage" - desc = "The ruins of some unfortunate odysseus. Perhaps something is salvageable." - icon_state = "odysseus-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/mecha/odysseus/murdysseus - icon_state = "murdysseus-broken" - -/obj/structure/loot_pile/mecha/hoverpod - name = "hoverpod wreckage" - desc = "The ruins of some unfortunate hoverpod. Perhaps something is salvageable." - icon_state = "engineering_pod" - -/obj/structure/loot_pile/mecha/gygax - name = "gygax wreckage" - desc = "The ruins of some unfortunate gygax. Perhaps something is salvageable." - icon_state = "gygax-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/mecha/gygax/dark - icon_state = "darkgygax-broken" - -// Todo: Better loot. -/obj/structure/loot_pile/mecha/gygax/dark/adv - icon_state = "darkgygax_adv-broken" - icon_scale_x = 1.5 - icon_scale_y = 1.5 - pixel_y = 8 - -/obj/structure/loot_pile/mecha/gygax/medgax - icon_state = "medgax-broken" - -/obj/structure/loot_pile/mecha/durand - name = "durand wreckage" - desc = "The ruins of some unfortunate durand. Perhaps something is salvageable." - icon_state = "durand-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/mecha/marauder - name = "marauder wreckage" - desc = "The ruins of some unfortunate marauder. Perhaps something is salvagable." - icon_state = "marauder-broken" - // Todo: Better loot. - -/obj/structure/loot_pile/mecha/marauder/seraph - name = "seraph wreckage" - desc = "The ruins of some unfortunate seraph. Perhaps something is salvagable." - icon_state = "seraph-broken" - -/obj/structure/loot_pile/mecha/marauder/mauler - name = "mauler wreckage" - desc = "The ruins of some unfortunate mauler. Perhaps something is salvagable." - icon_state = "mauler-broken" - -/obj/structure/loot_pile/mecha/phazon - name = "phazon wreckage" - desc = "The ruins of some unfortunate phazon. Perhaps something is salvageable." - icon_state = "phazon-broken" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -/obj/structure/loot_pile/surface/drone - name = "drone wreckage" - desc = "The ruins of some unfortunate drone. Perhaps something is salvageable." - icon = 'icons/obj/mech_wrecks.dmi' - icon_state = "drone_dead" - - common_loot = list() - - uncommon_loot = list() - - rare_loot = list() - -// Contains old mediciation, most of it unidentified and has a good chance of being useless. -/obj/structure/loot_pile/surface/medicine_cabinet - name = "abandoned medicine cabinet" - desc = "An old cabinet, it might still have something of use inside." - icon_state = "medicine_cabinet" - density = FALSE - chance_uncommon = 0 - chance_rare = 0 - - common_loot = list() - -// Like the above but has way better odds, in exchange for being in a place still inhabited (or was recently). -/obj/structure/loot_pile/surface/medicine_cabinet/fresh - name = "medicine cabinet" - desc = "A cabinet designed to hold medicine, it might still have something of use inside." - icon_state = "medicine_cabinet" - density = FALSE - - common_loot = list() diff --git a/mods/content/dungeon_loot/subtypes/stubs.dm b/mods/content/dungeon_loot/subtypes/stubs.dm new file mode 100644 index 00000000000..bb8b42c7a88 --- /dev/null +++ b/mods/content/dungeon_loot/subtypes/stubs.dm @@ -0,0 +1,17 @@ +// Base type for alien piles. +/obj/structure/loot_pile/surface/alien + name = "alien pod" + desc = "A pod which looks bigger on the inside. Something quite shiny might be inside?" + icon_state = "alien_pile1" + +/obj/structure/loot_pile/surface/alien +// May contain alien tools. +/obj/structure/loot_pile/surface/alien/engineering +// May contain alien surgery equipment or powerful medication. +/obj/structure/loot_pile/surface/alien/medical +// May contain powercells or alien weaponry. +/obj/structure/loot_pile/surface/alien/security +// The pile found at the very end, and as such has the best loot. +/obj/structure/loot_pile/surface/alien/end + chance_uncommon = 30 + chance_rare = 10 \ No newline at end of file diff --git a/mods/content/dungeon_loot/subtypes/surface.dm b/mods/content/dungeon_loot/subtypes/surface.dm new file mode 100644 index 00000000000..6e29a9c7317 --- /dev/null +++ b/mods/content/dungeon_loot/subtypes/surface.dm @@ -0,0 +1,58 @@ +// Surface base type +/obj/structure/loot_pile/surface + // Surface loot piles are considerably harder and more dangerous to reach, so you're more likely to get rare things. + chance_uncommon = 20 + chance_rare = 5 + loot_depletion = TRUE + loot_left = 5 // This is to prevent people from asking the whole station to go down to some alien ruin to get massive amounts of phat lewt. + abstract_type = /obj/structure/loot_pile/surface + +// Contains old mediciation, most of it unidentified and has a good chance of being useless. +/obj/structure/loot_pile/surface/medicine_cabinet + name = "abandoned medicine cabinet" + desc = "An old cabinet, it might still have something of use inside." + icon_state = "medicine_cabinet" + density = FALSE + chance_uncommon = 1 + chance_rare = 1 + +/obj/structure/loot_pile/surface/medicine_cabinet/get_common_loot() + var/static/list/common_loot = list( + /obj/item/storage/pill_bottle/sugariron, + /obj/item/stack/medical/bruise_pack, + /obj/item/stack/medical/ointment, + /obj/item/storage/med_pouch/trauma, + /obj/item/storage/med_pouch/burn, + /obj/item/storage/med_pouch/toxin, + /obj/item/storage/med_pouch/radiation, + /obj/item/storage/med_pouch/oxyloss, + /obj/item/chems/hypospray/autoinjector + ) + return common_loot + +/obj/structure/loot_pile/surface/medicine_cabinet/get_uncommon_loot() + var/static/list/uncommon_loot = list( + /obj/item/storage/pill_bottle/painkillers, + /obj/item/stack/medical/splint, + /obj/item/storage/pill_bottle/burn_meds, + /obj/item/storage/pill_bottle/brute_meds, + /obj/item/storage/pill_bottle/antitoxins, + /obj/item/storage/pill_bottle/antibiotics, + /obj/item/storage/pill_bottle/oxygen + ) + return uncommon_loot + +/obj/structure/loot_pile/surface/medicine_cabinet/get_rare_loot() + var/static/list/rare_loot = list( + /obj/item/stack/medical/advanced/bruise_pack, + /obj/item/stack/medical/advanced/ointment, + /obj/item/storage/pill_bottle/strong_painkillers + ) + return rare_loot + +// Like the above but has way better odds, in exchange for being in a place still inhabited (or was recently). +/obj/structure/loot_pile/surface/medicine_cabinet/fresh + name = "medicine cabinet" + desc = "A cabinet designed to hold medicine, it might still have something of use inside." + chance_uncommon = 20 + chance_rare = 5 diff --git a/mods/content/extradrinks/drinks/bottle.dm b/mods/content/extradrinks/drinks/bottle.dm index ea6253ccf8d..3ca4fe1ffde 100644 --- a/mods/content/extradrinks/drinks/bottle.dm +++ b/mods/content/extradrinks/drinks/bottle.dm @@ -2,168 +2,168 @@ name = "Hangzhou Bay Baijiu" desc = "A large bottle of Baijiu with a beautiful looking sunset on the cover." DRINK_STATE("baijiu") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/baijiu/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/baijiu, 100) + add_to_reagents(/decl/material/liquid/ethanol/baijiu, 100) /obj/item/chems/drinks/bottle/cachaca name = "Brazillian Cachaca" desc = "Cachaca, distilled from fermented sugarcane. This one was bottled on Earth." DRINK_STATE("cachaca") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/cachaca/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/cachaca, 100) + add_to_reagents(/decl/material/liquid/ethanol/cachaca, 100) /obj/item/chems/drinks/bottle/soju name = "Sol Hyonjun's Soju" desc = "A clear, see-through bottle of Soju." DRINK_STATE("soju") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/soju/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/soju, 100) + add_to_reagents(/decl/material/liquid/ethanol/soju, 100) /obj/item/chems/drinks/bottle/rakia name = "Sadmir Cumani's Rakia" desc = "A polite looking man on the label promises you this is 100 percent fruit brandy." DRINK_STATE("rakia") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/rakia/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/rakia, 100) + add_to_reagents(/decl/material/liquid/ethanol/rakia, 100) /obj/item/chems/drinks/bottle/arak name = "Mo's Premium Arak" desc = "A bottle of Mo's Premium anise arak." DRINK_STATE("arak") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/arak/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/arak, 100) + add_to_reagents(/decl/material/liquid/ethanol/arak, 100) /obj/item/chems/drinks/bottle/blackstrap name = "Big Bill's Blackstrap" desc = "A bottle of Big Bill's Blackstrap. High Quality Rum." DRINK_STATE("blackstrap") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/blackstrap/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/blackstrap, 100) + add_to_reagents(/decl/material/liquid/ethanol/blackstrap, 100) /obj/item/chems/drinks/bottle/brandy name = "Lunar Brandy" desc = "A bottle of Lunar Brandy. It looks seriously expensive." DRINK_STATE("brandy") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/brandy/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/brandy, 100) + add_to_reagents(/decl/material/liquid/ethanol/brandy, 100) /obj/item/chems/drinks/bottle/pink_gin name = "Birmingham Pink" desc = "A bottle of high quality gin, produced in the New London Space Station." DRINK_STATE("pinkgin") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/pink_gin/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/gin/pink, 100) + add_to_reagents(/decl/material/liquid/ethanol/gin/pink, 100) /obj/item/chems/drinks/bottle/ogogoro name = "Metropolitan Ogogoro" desc = "A bottle of West Africa." DRINK_STATE("ogogoro") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/ogogoro/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/ogogoro, 100) + add_to_reagents(/decl/material/liquid/ethanol/ogogoro, 100) /obj/item/chems/drinks/bottle/prosecco name = "2020 Vintage Prosecco" desc = "A delicious prosecco, ideal for long days after work. This one proudly advertises itself as 2020 Vintage. Must have been a special year." DRINK_STATE("prosecco") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/prosecco/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/prosecco, 100) + add_to_reagents(/decl/material/liquid/ethanol/prosecco, 100) /obj/item/chems/drinks/bottle/tej name = "Rift Valley Tej" desc = "Honey Wine from the heart of East Africa!" DRINK_STATE("tej") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/tej/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/tej, 100) + add_to_reagents(/decl/material/liquid/ethanol/tej, 100) /obj/item/chems/drinks/bottle/mars_whiskey name = "Martian Gold Whiskey" desc = "A premium bottle of spiced whiskey, also known as fireball." DRINK_STATE("whiskeybottle3") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/mars_whiskey/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/whiskey/mars, 100) + add_to_reagents(/decl/material/liquid/ethanol/whiskey/mars, 100) /obj/item/chems/drinks/bottle/hrenti name = "Hhassa's Secret Stash" desc = "A bottle of Hrenti, shipped straight from Moghes." DRINK_STATE("hrenti") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/hrenti/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/hrenti, 100) + add_to_reagents(/decl/material/liquid/ethanol/hrenti, 100) /obj/item/chems/drinks/bottle/wasgaelhi name = "Szikan Wasgaelhi" desc = "A bottle of state-produced wasgaelhi." DRINK_STATE("wasgaelhi") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/wasgaelhi/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/wasgaelhi, 100) + add_to_reagents(/decl/material/liquid/ethanol/wasgaelhi, 100) /obj/item/chems/drinks/bottle/yekala name = "Kis'tan Yekala" desc = "A bottle of yekala from Moghes, triple sealed. It smells very strongly of fish." DRINK_STATE("yekala") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/yekala/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/yekala, 100) + add_to_reagents(/decl/material/liquid/ethanol/yekala, 100) /obj/item/chems/drinks/bottle/qokkhrona name = "Qixxkalan Qokk'hrona" desc = "A vibrant looking bottle of Qokk'hrona. There is a bright warning written in various human languages. It reads: WARNING. NOT SAFE FOR HUMAN CONSUMPTION." DRINK_STATE("qokk") - center_of_mass = @"{'x':16,'y':6}" + center_of_mass = @'{"x":16,"y":6}' /obj/item/chems/drinks/bottle/qokkhrona/Initialize() .=..() - reagents.add_reagent(/decl/material/liquid/ethanol/qokkhrona, 100) + add_to_reagents(/decl/material/liquid/ethanol/qokkhrona, 100) /obj/item/chems/drinks/bottle/lemonjuice name = "Lemon Juice" desc = "A carton of lemon juice." DRINK_STATE("lemonjuice") item_state = "carton" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -173,14 +173,14 @@ /obj/item/chems/drinks/bottle/lemonjuice/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/lemon, 100) + add_to_reagents(/decl/material/liquid/drink/juice/lemon, 100) /obj/item/chems/drinks/bottle/pineapplejuice name = "Pineapple Juice" desc = "A carton of tropical pineapple juice." DRINK_STATE("pineapplejuice") item_state = "carton" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -190,86 +190,86 @@ /obj/item/chems/drinks/bottle/pineapplejuice/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/pineapple, 100) + add_to_reagents(/decl/material/liquid/drink/juice/pineapple, 100) /obj/item/chems/drinks/bottle/small/cider_apple name = "Apple Cider" desc = "A small bottle of delicious apple cider." DRINK_STATE("applecider") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/cider_apple/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/ethanol/cider_apple, 30) + add_to_reagents(/decl/material/liquid/ethanol/cider_apple, 30) /obj/item/chems/drinks/bottle/small/cider_pear name = "Pear Cider" desc = "A small bottle of delicious pear cider" DRINK_STATE("pearcider") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/cider_pear/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/ethanol/cider_pear, 30) + add_to_reagents(/decl/material/liquid/ethanol/cider_pear, 30) /obj/item/chems/drinks/bottle/small/lager name = "Hans' Original Lager" desc = "A bottle of premium lager. Has Hans' seal of approval, apparently." DRINK_STATE("lager") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/lager/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/ethanol/lager, 30) + add_to_reagents(/decl/material/liquid/ethanol/lager, 30) /obj/item/chems/drinks/bottle/small/martianbeer name = "Martian Pale Ale" desc = "The best ale on Mars, according to the label." DRINK_STATE("marsbeer") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/martianbeer/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/ethanol/martianbeer, 30) + add_to_reagents(/decl/material/liquid/ethanol/martianbeer, 30) /obj/item/chems/drinks/bottle/small/alcoholfreebeer name = "Alcohol-Free Beer" desc = "A sad looking bottle of alcohol-free beer." DRINK_STATE("afbeer") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/alcoholfreebeer/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/alcoholfreebeer, 30) + add_to_reagents(/decl/material/liquid/drink/alcoholfreebeer, 30) /obj/item/chems/drinks/bottle/small/eggnog name = "Grandma's Own Eggnog" desc = "A small bottle of eggnog, ideal for on the go." icon_state = "" - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/eggnog/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/eggnog, 30) + add_to_reagents(/decl/material/liquid/drink/eggnog, 30) /obj/item/chems/drinks/bottle/small/rootbeer name = "Root Beer" desc = "A simple bottle of root beer." DRINK_STATE("eggnog") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/rootbeer/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/rootbeer, 30) + add_to_reagents(/decl/material/liquid/drink/rootbeer, 30) /obj/item/chems/drinks/bottle/small/dnb name = "Dandelion and Burdock" desc = "A bottle of dandelion and burdock. Not actually made from either of the two." DRINK_STATE("dnb") - center_of_mass = @"{'x':16,'y':12}" + center_of_mass = @'{"x":16,"y":12}' /obj/item/chems/drinks/bottle/small/dnb/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/dnb, 30) + add_to_reagents(/decl/material/liquid/drink/dnb, 30) /obj/item/chems/drinks/bottle/hrukhza name = "Hrukhza Extract" desc = "A carton of Hrukhza extract, straight from Moghes." DRINK_STATE("hrukhzaextract") item_state = "carton" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' material = /decl/material/solid/organic/cardboard matter = list( /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY @@ -279,4 +279,4 @@ /obj/item/chems/drinks/bottle/hrukhza/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/hrukhza, 100) \ No newline at end of file + add_to_reagents(/decl/material/liquid/drink/hrukhza, 100) \ No newline at end of file diff --git a/mods/content/extradrinks/drinks/cans.dm b/mods/content/extradrinks/drinks/cans.dm index 425e6045e5c..07babf924fb 100644 --- a/mods/content/extradrinks/drinks/cans.dm +++ b/mods/content/extradrinks/drinks/cans.dm @@ -2,48 +2,48 @@ name = "Europa Punch!" desc = "A can of Europa Punch, a delicious juice made from various aquatic plants!" DRINK_STATE("europa") - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/europa/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/europa, 30) + add_to_reagents(/decl/material/liquid/drink/juice/europa, 30) /obj/item/chems/drinks/cans/ionbru name = "Ion-Bru" desc = "A can of Ion-Bru, the drink of shipbuilders." DRINK_STATE("ionbru") - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/ionbru/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/ionbru, 30) + add_to_reagents(/decl/material/liquid/drink/ionbru, 30) /obj/item/chems/drinks/cans/vanillacola name = "Vanilla Cola" desc = "A can of vanilla cola." DRINK_STATE("vcola") - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/vanillacola/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/cola/vanilla, 30) + add_to_reagents(/decl/material/liquid/drink/cola/vanilla, 30) /obj/item/chems/drinks/cans/coffeecola name = "Coffee Cola" desc = "A can of coffee cola." DRINK_STATE("ccola") - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/coffeecola/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/cola/coffee, 30) + add_to_reagents(/decl/material/liquid/drink/cola/coffee, 30) /obj/item/chems/drinks/cans/zazkis name = "Hsstik Zazkis" desc = "A chilled can of zazkis, a Moghsian delight." DRINK_STATE("zazkis") - center_of_mass = @"{'x':16,'y':10}" + center_of_mass = @'{"x":16,"y":10}' /obj/item/chems/drinks/cans/zazkis/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/zazkis, 30) \ No newline at end of file + add_to_reagents(/decl/material/liquid/drink/zazkis, 30) \ No newline at end of file diff --git a/mods/content/extradrinks/drinks/drinks.dm b/mods/content/extradrinks/drinks/drinks.dm index cb1dd1dee45..0c21812f0ef 100644 --- a/mods/content/extradrinks/drinks/drinks.dm +++ b/mods/content/extradrinks/drinks/drinks.dm @@ -2,8 +2,8 @@ name = "\improper Robust Decaffeinated Coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot. It contains no caffeine." DRINK_STATE("coffee") - center_of_mass = @"{'x':15,'y':10}" + center_of_mass = @'{"x":15,"y":10}' /obj/item/chems/drinks/decaf/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/decafcoffee, 30) \ No newline at end of file + add_to_reagents(/decl/material/liquid/drink/decafcoffee, 30) \ No newline at end of file diff --git a/mods/content/extrafoods/food/baked_goods.dm b/mods/content/extrafoods/food/baked_goods.dm index d4f982e0ceb..787035ba802 100644 --- a/mods/content/extrafoods/food/baked_goods.dm +++ b/mods/content/extrafoods/food/baked_goods.dm @@ -14,15 +14,15 @@ /obj/item/chems/food/sliceable/keylimepie/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/liquid/nutriment/bread, 4, list("graham crackers" = 4)) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/bread, 4, list("graham crackers" = 4)) /obj/item/chems/food/keylimepieslice name = "slice of key lime pie" desc = "A slice of tart pie, with whipped cream on top." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "keylimepieslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f5b951" bitesize = 3 nutriment_desc = list("lime" = 1) @@ -43,14 +43,14 @@ /obj/item/chems/food/sliceable/quiche/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 10) + add_to_reagents(/decl/material/liquid/nutriment/protein, 10) /obj/item/chems/food/quicheslice name = "slice of quiche" desc = "A slice of delicious quiche. Eggy, cheesy goodness." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "quicheslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f5b951" bitesize = 3 nutriment_desc = list("cheesy eggs" = 1) @@ -60,7 +60,7 @@ /obj/item/chems/food/quicheslice/filled/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) /obj/item/chems/food/sliceable/brownies name = "brownies" @@ -78,14 +78,14 @@ /obj/item/chems/food/sliceable/brownies/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/browniemix, 2) + add_to_reagents(/decl/material/liquid/nutriment/browniemix, 2) /obj/item/chems/food/browniesslice name = "brownie" desc = "A dense, decadent chocolate brownie." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "browniesslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f5b951" bitesize = 2 nutriment_desc = list("fudge" = 1) @@ -95,7 +95,7 @@ /obj/item/chems/food/browniesslice/filled/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/browniemix, 1) + add_to_reagents(/decl/material/liquid/nutriment/browniemix, 1) /obj/item/chems/food/sliceable/cosmicbrownies name = "cosmic brownies" @@ -113,18 +113,18 @@ /obj/item/chems/food/sliceable/cosmicbrownies/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/browniemix, 2) - reagents.add_reagent(/decl/material/liquid/psychoactives, 2) - reagents.add_reagent(/decl/material/liquid/burn_meds, 1) - reagents.add_reagent(/decl/material/liquid/brute_meds, 1) - reagents.add_reagent(/decl/material/liquid/bromide, 1) + add_to_reagents(/decl/material/liquid/nutriment/browniemix, 2) + add_to_reagents(/decl/material/liquid/psychoactives, 2) + add_to_reagents(/decl/material/liquid/burn_meds, 1) + add_to_reagents(/decl/material/liquid/brute_meds, 1) + add_to_reagents(/decl/material/liquid/bromide, 1) /obj/item/chems/food/cosmicbrowniesslice name = "cosmic brownie" desc = "A dense, decadent and fun-looking chocolate brownie." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "cosmicbrowniesslice" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#f5b951" bitesize = 3 nutriment_desc = list("fudge" = 1) @@ -134,7 +134,7 @@ /obj/item/chems/food/cosmicbrowniesslice/filled/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/browniemix, 1) + add_to_reagents(/decl/material/liquid/nutriment/browniemix, 1) /obj/item/chems/food/berrymuffin name = "berry muffin" @@ -167,7 +167,7 @@ /obj/item/chems/food/honeybun/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/honey, 2) + add_to_reagents(/decl/material/liquid/nutriment/honey, 2) /obj/item/chems/food/cinnamonbun name = "cinnamon bun" diff --git a/mods/content/extrafoods/food/condiments.dm b/mods/content/extrafoods/food/condiments.dm index 17e9bef8f87..7d2e9f46433 100644 --- a/mods/content/extrafoods/food/condiments.dm +++ b/mods/content/extrafoods/food/condiments.dm @@ -14,4 +14,4 @@ has_done_jank = TRUE // remove all this when condiment bottles are moved to be on materials /obj/item/chems/condiment/small/spacespice/populate_reagents() - reagents.add_reagent(/decl/material/solid/spacespice, reagents.maximum_volume) \ No newline at end of file + add_to_reagents(/decl/material/solid/spacespice, reagents.maximum_volume) \ No newline at end of file diff --git a/mods/content/extrafoods/food/food_overrides.dm b/mods/content/extrafoods/food/food_overrides.dm index f7aba70894f..4b898cf4bef 100644 --- a/mods/content/extrafoods/food/food_overrides.dm +++ b/mods/content/extrafoods/food/food_overrides.dm @@ -42,10 +42,10 @@ FOOD_OVERRIDE(/obj/item/chems/food/baguette) FOOD_OVERRIDE(/obj/item/chems/food/sandwich) FOOD_OVERRIDE(/obj/item/chems/food/toastedsandwich) FOOD_OVERRIDE(/obj/item/chems/food/sliceable/pizza) -FOOD_OVERRIDE(/obj/item/chems/food/slice/margherita) -FOOD_OVERRIDE(/obj/item/chems/food/slice/meatpizza) -FOOD_OVERRIDE(/obj/item/chems/food/slice/mushroompizza) -FOOD_OVERRIDE(/obj/item/chems/food/slice/vegetablepizza) +FOOD_OVERRIDE(/obj/item/chems/food/slice/pizza/margherita) +FOOD_OVERRIDE(/obj/item/chems/food/slice/pizza/meat) +FOOD_OVERRIDE(/obj/item/chems/food/slice/pizza/mushroom) +FOOD_OVERRIDE(/obj/item/chems/food/slice/pizza/vegetable) FOOD_OVERRIDE(/obj/item/chems/food/donut) FOOD_OVERRIDE(/obj/item/chems/food/dionaroast) FOOD_OVERRIDE(/obj/item/chems/food/sausage) diff --git a/mods/content/extrafoods/food/fried.dm b/mods/content/extrafoods/food/fried.dm index ebd761ffd12..e70e433d678 100644 --- a/mods/content/extrafoods/food/fried.dm +++ b/mods/content/extrafoods/food/fried.dm @@ -10,7 +10,7 @@ /obj/item/chems/food/chickenfillet/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 8) + add_to_reagents(/decl/material/liquid/nutriment/protein, 8) /obj/item/chems/food/chilicheesefries name = "chili cheese fries" @@ -18,7 +18,7 @@ desc = "A mighty plate of fries, drowned in hot chili and cheese sauce. Because your arteries are overrated." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "chilicheesefries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" nutriment_amt = 8 nutriment_desc = list("hearty, cheesy fries" = 8) @@ -26,15 +26,15 @@ /obj/item/chems/food/chilicheesefries/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) - reagents.add_reagent(/decl/material/liquid/capsaicin, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/capsaicin, 2) /obj/item/chems/food/carrotfries name = "carrot fries" desc = "Tasty fries from fresh carrots." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "carrotfries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#faa005" nutriment_amt = 3 nutriment_desc = list("carrot" = 3) @@ -42,8 +42,8 @@ /obj/item/chems/food/carrotfries/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/eyedrops, 1) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/liquid/eyedrops, 1) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/friedmushroom name = "fried mushroom" @@ -57,7 +57,7 @@ /obj/item/chems/food/friedmushroom/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/pisanggoreng name = "pisang goreng" @@ -65,7 +65,7 @@ desc = "Crispy, starchy, sweet banana fritters. Popular street food in parts of Sol." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "pisanggoreng" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#301301" nutriment_amt = 8 nutriment_desc = list("sweet bananas" = 8) @@ -73,7 +73,7 @@ /obj/item/chems/food/pisanggoreng/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 1) /obj/item/chems/food/sausage/battered name = "battered sausage" @@ -86,9 +86,9 @@ /obj/item/chems/food/sausage/battered/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/nutriment/batter, 1.7) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 1.5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/batter, 1.7) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 1.5) /obj/item/chems/food/jalapeno_poppers name = "jalapeno popper" @@ -103,31 +103,31 @@ /obj/item/chems/food/jalapeno_poppers/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/batter, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 2) + add_to_reagents(/decl/material/liquid/nutriment/batter, 2) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 2) /obj/item/chems/food/chickenkatsu name = "chicken katsu" desc = "A delicacy consisting of chicken fried in a light beer batter." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "katsu" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#e9adff" do_coating_prefix = FALSE bitesize = 1.5 /obj/item/chems/food/chickenkatsu/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/nutriment/batter/beerbatter, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/batter/beerbatter, 2) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 1) /obj/item/chems/food/fries name = "fries" // NOT CHIPS /obj/item/chems/food/fries/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 1.2) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 1.2) // i'm putting these here because they're fries // even though they're not actually fried @@ -136,7 +136,7 @@ desc = "Soft and rubbery, should have fried them. Good for smaller crewmembers, maybe?" icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "microfries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" nutriment_amt = 4 nutriment_desc = list("soggy potato slices" = 4) @@ -147,7 +147,7 @@ desc = "Dark and crispy, but a bit dry." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "bakedfries" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" nutriment_amt = 4 nutriment_desc = list("crisp, dry fries" = 4) @@ -166,8 +166,8 @@ /obj/item/chems/food/sliceable/pizza/crunch/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/batter, 6.5) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 4) + add_to_reagents(/decl/material/liquid/nutriment/batter, 6.5) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 4) batter_coating = /decl/material/liquid/nutriment/batter /obj/item/chems/food/pizzacrunchslice @@ -189,16 +189,16 @@ /obj/item/chems/food/funnelcake/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/batter, 10) - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 5) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride/oil, 1) + add_to_reagents(/decl/material/liquid/nutriment/batter, 10) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 5) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride/oil, 1) /obj/item/chems/food/onionrings name = "onion rings" desc = "Like circular fries but better." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "onionrings" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" nutriment_desc = list("fried onions" = 5) nutriment_amt = 5 @@ -217,4 +217,4 @@ /obj/item/chems/food/corn_dog/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) diff --git a/mods/content/extrafoods/food/meat.dm b/mods/content/extrafoods/food/meat.dm index a02725d4f30..2ba78851e10 100644 --- a/mods/content/extrafoods/food/meat.dm +++ b/mods/content/extrafoods/food/meat.dm @@ -18,8 +18,8 @@ /obj/item/chems/food/rawbacon/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 0.33) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 0.33) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride, 1) // May as well put this here. /datum/codex_entry/rawbacon @@ -40,8 +40,8 @@ /obj/item/chems/food/bacon/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 0.33) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 0.33) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride, 1) /obj/item/chems/food/bacon/microwave name = "microwaved bacon" @@ -65,7 +65,7 @@ /obj/item/chems/food/bacon_stick/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/chilied_eggs name = "chilied eggs" @@ -76,28 +76,28 @@ /obj/item/chems/food/chilied_eggs/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 6) - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/bacon_and_eggs name = "bacon and eggs" desc = "A piece of bacon and two fried eggs." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "bacon_and_eggs" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_amt = 3 nutriment_type = /decl/material/liquid/nutriment/protein /obj/item/chems/food/bacon_and_eggs/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 1) /obj/item/chems/food/poachedegg name = "poached egg" desc = "A delicately poached egg with a runny yolk. Healthier than its fried counterpart." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "poachedegg" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ffdf78" nutriment_amt = 1 nutriment_desc = list("egg" = 1) @@ -105,8 +105,8 @@ /obj/item/chems/food/poachedegg/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/solid/blackpepper, 1) /obj/item/chems/food/nt_muffin name = "\improper NtMuffin" @@ -118,7 +118,7 @@ /obj/item/chems/food/nt_muffin/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) /obj/item/chems/food/baconburger name = "bacon burger" @@ -132,7 +132,7 @@ /obj/item/chems/food/baconburger/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/blt name = "BLT" @@ -146,7 +146,7 @@ /obj/item/chems/food/blt/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/blt/cbt name = "CBT" @@ -160,11 +160,11 @@ icon_state = "sweet_and_sour" nutriment_desc = list("sweet and sour" = 6) nutriment_amt = 6 - trash = /obj/item/trash/plate + plate = /obj/item/plate /obj/item/chems/food/sweet_and_sour/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/bacon_flatbread name = "bacon cheese flatbread" @@ -176,7 +176,7 @@ /obj/item/chems/food/bacon_flatbread/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 5) /obj/item/chems/food/meat_pocket name = "meat pocket" @@ -188,7 +188,7 @@ /obj/item/chems/food/meat_pocket/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/crabmeat name = "crab legs" @@ -199,7 +199,7 @@ /obj/item/chems/food/crabmeat/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /mob/living/simple_animal/crab/meat_type = /obj/item/chems/food/crabmeat @@ -211,12 +211,12 @@ nutriment_amt = 2 nutriment_desc = list("savory butter" = 2) bitesize = 2 - trash = /obj/item/trash/plate + plate = /obj/item/plate /obj/item/chems/food/crab_legs/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/nugget name = "chicken nugget" @@ -226,7 +226,7 @@ /obj/item/chems/food/nugget/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) var/shape = pick("lump", "star", "lizard", "corgi") desc = "A chicken nugget vaguely shaped like a [shape]." icon_state = "nugget_[shape]" @@ -242,14 +242,14 @@ /obj/item/chems/food/hatchling_surprise/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 2) /obj/item/chems/food/red_sun_special name = "red sun special" desc = "One lousy piece of sausage sitting on melted cheese curds. A cheap meal for the Unathi peasants of Moghes." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "red_sun_special" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_amt = 2 nutriment_type = /decl/material/liquid/nutriment/protein @@ -267,13 +267,13 @@ desc = "A sausage and an omelette on top of a grilled steak." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "father_breakfast" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_type = /decl/material/liquid/nutriment/protein nutriment_amt = 6 /obj/item/chems/food/father_breakfast/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 4) /obj/item/chems/food/stuffed_meatball name = "stuffed meatball" //YES @@ -288,20 +288,20 @@ desc = "An omelette baked on top of a giant meat patty. This monstrousity is typically shared between four people during a dinnertime meal." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "egg_pancake" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_type = /decl/material/liquid/nutriment/protein nutriment_amt = 6 /obj/item/chems/food/egg_pancake/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 2) /obj/item/chems/food/ribplate name = "plate of ribs" desc = "A half-rack of ribs, brushed with some sort of honey-glaze. Why are there no napkins on board?" icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "ribplate" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#7a3d11" nutriment_amt = 6 nutriment_desc = list("barbecue" = 6) @@ -309,38 +309,38 @@ /obj/item/chems/food/ribplate/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride, 2) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) - reagents.add_reagent(/decl/material/liquid/nutriment/honey, 5) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride, 2) + add_to_reagents(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/liquid/nutriment/honey, 5) /obj/item/chems/food/generalschicken name = "general's chicken" desc = "Sweet, spicy, and fried. General's Chicken has been around for more than five-hundred years now, and still tastes good." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "generaltso" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_amt = 4 nutriment_desc = list("sweet and spicy sauce" = 4) bitesize = 2 /obj/item/chems/food/generalschicken/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/roastbeef name = "roast beef" desc = "It's beef. It's roasted. It's been a staple of dining tradition for centuries." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "roastbeef" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_amt = 8 nutriment_desc = list("cooked meat" = 5) bitesize = 2 /obj/item/chems/food/roastbeef/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) //For meaty things. + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) //For meaty things. /obj/item/storage/box/wings //This is kinda like the donut box. name = "wing basket" @@ -386,7 +386,7 @@ /obj/item/chems/food/chickenwing/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/donerkebab name = "doner kebab" @@ -398,7 +398,7 @@ /obj/item/chems/food/donerkebab/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) //For meaty things. + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) //For meaty things. /obj/item/chems/food/fish_taco name = "carp taco" @@ -410,19 +410,19 @@ /obj/item/chems/food/fish_taco/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/lasagna name = "lasagna" desc = "Favorite of cats." icon_state = "lasagna" icon = 'mods/content/extrafoods/icons/obj/food.dmi' - trash = /obj/item/trash/tray - center_of_mass = @"{'x':16,'y':17}" + plate = /obj/item/plate/tray + center_of_mass = @'{"x":16,"y":17}' nutriment_amt = 6 nutriment_desc = list("pasta" = 4, "tomato" = 2) bitesize = 3 /obj/item/chems/food/lasagna/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) \ No newline at end of file diff --git a/mods/content/extrafoods/food/noodle.dm b/mods/content/extrafoods/food/noodle.dm index 868b4d59eaf..d1450a0ecd7 100644 --- a/mods/content/extrafoods/food/noodle.dm +++ b/mods/content/extrafoods/food/noodle.dm @@ -3,7 +3,7 @@ desc = "A popular Chinese noodle dish. Chopsticks optional." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "lomein" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#fcee81" nutriment_amt = 4 nutriment_desc = list("mushroom" = 2, "cabbage" = 2) @@ -11,10 +11,10 @@ /obj/item/chems/food/lomein/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 4) - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) - reagents.add_reagent(/decl/material/liquid/drink/juice/carrot, 3) - reagents.add_reagent(/decl/material/liquid/eyedrops, 1) + add_to_reagents(/decl/material/liquid/nutriment/rice, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/drink/juice/carrot, 3) + add_to_reagents(/decl/material/liquid/eyedrops, 1) /obj/item/chems/food/kitsuneudon name = "kitsune udon" @@ -38,5 +38,5 @@ /obj/item/chems/food/chickennoodlesoup/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) - reagents.add_reagent(/decl/material/liquid/water, 5) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/water, 5) \ No newline at end of file diff --git a/mods/content/extrafoods/food/rice.dm b/mods/content/extrafoods/food/rice.dm index 4d3e35e3ad1..385b6b26512 100644 --- a/mods/content/extrafoods/food/rice.dm +++ b/mods/content/extrafoods/food/rice.dm @@ -12,9 +12,9 @@ /obj/item/chems/food/redcurry/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 7) - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 4) - reagents.add_reagent(/decl/material/solid/spacespice, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 7) + add_to_reagents(/decl/material/liquid/nutriment/rice, 4) + add_to_reagents(/decl/material/solid/spacespice, 2) /obj/item/chems/food/greencurry name = "green curry" @@ -30,9 +30,9 @@ /obj/item/chems/food/greencurry/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/plant_protein, 2) - reagents.add_reagent(/decl/material/liquid/capsaicin, 2) - reagents.add_reagent(/decl/material/solid/spacespice, 2) + add_to_reagents(/decl/material/liquid/nutriment/plant_protein, 2) + add_to_reagents(/decl/material/liquid/capsaicin, 2) + add_to_reagents(/decl/material/solid/spacespice, 2) /obj/item/chems/food/yellowcurry name = "yellow curry" @@ -48,8 +48,8 @@ /obj/item/chems/food/yellowcurry/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 4) - reagents.add_reagent(/decl/material/solid/spacespice, 2) + add_to_reagents(/decl/material/liquid/nutriment/rice, 4) + add_to_reagents(/decl/material/solid/spacespice, 2) /obj/item/chems/food/bibimbap name = "bibimbap bowl" @@ -64,10 +64,10 @@ /obj/item/chems/food/bibimbap/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/eyedrops, 2) - reagents.add_reagent(/decl/material/solid/spacespice, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/eyedrops, 2) + add_to_reagents(/decl/material/solid/spacespice, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 3) /obj/item/chems/food/friedrice name = "fried rice" @@ -83,9 +83,9 @@ /obj/item/chems/food/friedrice/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 5) - reagents.add_reagent(/decl/material/liquid/drink/juice/carrot, 3) - reagents.add_reagent(/decl/material/liquid/eyedrops, 1) + add_to_reagents(/decl/material/liquid/nutriment/rice, 5) + add_to_reagents(/decl/material/liquid/drink/juice/carrot, 3) + add_to_reagents(/decl/material/liquid/eyedrops, 1) /obj/item/chems/food/riceball name = "rice ball" @@ -93,17 +93,17 @@ icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "riceball" filling_color = "#a66829" - center_of_mass = @"{'x':17,'y':16}" + center_of_mass = @'{"x":17,"y":16}' nutriment_amt = 1 nutriment_desc = list("seaweed" = 1) /obj/item/chems/food/riceball/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 1) - reagents.add_reagent(/decl/material/liquid/nutriment/soysauce, 1) + add_to_reagents(/decl/material/liquid/nutriment/rice, 1) + add_to_reagents(/decl/material/liquid/nutriment/soysauce, 1) /obj/item/chems/food/riceball/on_update_icon() - var/percent = round((reagents.total_volume / 3) * 100) + var/percent = round((reagents?.total_volume / 3) * 100) switch(percent) if(0 to 90) icon_state = "riceball_90" @@ -123,7 +123,7 @@ /obj/item/chems/food/porkbowl/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4) /obj/item/chems/food/ricepudding name = "rice pudding" @@ -132,7 +132,7 @@ icon_state = "rpudding" trash = /obj/item/trash/snack_bowl filling_color = "#fffbdb" - center_of_mass = @"{'x':17,'y':11}" + center_of_mass = @'{"x":17,"y":11}' nutriment_amt = 4 nutriment_type = /decl/material/liquid/nutriment/rice bitesize = 2 @@ -145,15 +145,15 @@ icon_state = "risotto" trash = /obj/item/trash/snack_bowl filling_color = "#edd7d7" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_amt = 4 nutriment_desc = list("creamy mushroom" = 4) bitesize = 2 /obj/item/chems/food/risotto/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 3) - reagents.add_reagent(/decl/material/solid/spacespice, 2) + add_to_reagents(/decl/material/liquid/nutriment/rice, 3) + add_to_reagents(/decl/material/solid/spacespice, 2) /obj/item/chems/food/risottoballs name = "risotto balls" @@ -163,23 +163,23 @@ icon_state = "risottoballs" trash = /obj/item/trash/snack_bowl filling_color = "#edd7d7" - center_of_mass = @"{'x':15,'y':9}" + center_of_mass = @'{"x":15,"y":9}' nutriment_amt = 2 nutriment_desc = list("spices" = 2, "mushroom" = 2) bitesize = 3 /obj/item/chems/food/risottoballs/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/rice, 4) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) - reagents.add_reagent(/decl/material/solid/blackpepper, 1) + add_to_reagents(/decl/material/liquid/nutriment/rice, 4) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/solid/blackpepper, 1) /obj/item/chems/food/omurice name = "omelette rice" desc = "Just like your Japanese animes!" icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "omurice" - trash = /obj/item/trash/plate + plate = /obj/item/plate nutriment_amt = 8 nutriment_desc = list("rice" = 4, "egg" = 4) bitesize = 1 diff --git a/mods/content/extrafoods/food/soup.dm b/mods/content/extrafoods/food/soup.dm index d696c1fd199..b914b825ac4 100644 --- a/mods/content/extrafoods/food/soup.dm +++ b/mods/content/extrafoods/food/soup.dm @@ -11,7 +11,7 @@ /obj/item/chems/food/onionsoup/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/hotandsoursoup name = "hot & sour soup" @@ -25,10 +25,10 @@ /obj/item/chems/food/hotandsoursoup/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/capsaicin, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/garlicsauce, 2) - reagents.add_reagent(/decl/material/liquid/nutriment/plant_protein, 2) - reagents.add_reagent(/decl/material/liquid/water, 5) + add_to_reagents(/decl/material/liquid/capsaicin, 2) + add_to_reagents(/decl/material/liquid/nutriment/garlicsauce, 2) + add_to_reagents(/decl/material/liquid/nutriment/plant_protein, 2) + add_to_reagents(/decl/material/liquid/water, 5) /obj/item/chems/food/goulash name = "goulash" @@ -41,5 +41,5 @@ /obj/item/chems/food/goulash/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) //For meaty things. - reagents.add_reagent(/decl/material/liquid/water, 5) \ No newline at end of file + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) //For meaty things. + add_to_reagents(/decl/material/liquid/water, 5) \ No newline at end of file diff --git a/mods/content/extrafoods/food/tortillas_chips.dm b/mods/content/extrafoods/food/tortillas_chips.dm index 034c8e3ee9e..b14eed92561 100644 --- a/mods/content/extrafoods/food/tortillas_chips.dm +++ b/mods/content/extrafoods/food/tortillas_chips.dm @@ -19,7 +19,7 @@ nutriment_desc = list("fried tortilla chips" = 2) nutriment_amt = 2 -/obj/item/chems/food/chip/On_Consume(mob/M as mob) +/obj/item/chems/food/chip/handle_consumed(mob/M as mob) . = ..() if(reagents && reagents.total_volume) icon_state = bitten_state @@ -108,7 +108,7 @@ name = "plate of nachos" desc = "A very cheesy nacho plate." icon_state = "nachos" - trash = /obj/item/trash/plate + plate = /obj/item/plate vendingobject = /obj/item/chems/food/chip/nacho nutriment_desc = list("tortilla chips" = 10) bitesize = 1 @@ -190,7 +190,7 @@ /obj/item/chems/food/burrito/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/burrito_vegan name = "vegan burrito" @@ -203,7 +203,7 @@ /obj/item/chems/food/burrito_vegan/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/plant_protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/plant_protein, 6) /obj/item/chems/food/burrito_spicy name = "spicy meat burrito" @@ -216,8 +216,8 @@ /obj/item/chems/food/burrito_spicy/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/capsaicin, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/capsaicin, 3) /obj/item/chems/food/burrito_cheese name = "meat cheese burrito" @@ -230,7 +230,7 @@ /obj/item/chems/food/burrito_cheese/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/burrito_cheese_spicy name = "spicy cheese meat burrito" @@ -243,8 +243,8 @@ /obj/item/chems/food/burrito_cheese_spicy/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) - reagents.add_reagent(/decl/material/liquid/capsaicin, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/capsaicin, 3) /obj/item/chems/food/burrito_hell name = "el diablo" @@ -266,8 +266,8 @@ /obj/item/chems/food/breakfast_wrap/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 9) - reagents.add_reagent(/decl/material/liquid/capsaicin/condensed, 20) + add_to_reagents(/decl/material/liquid/nutriment/protein, 9) + add_to_reagents(/decl/material/liquid/capsaicin/condensed, 20) /obj/item/chems/food/burrito_mystery name = "mystery meat burrito" diff --git a/mods/content/extrafoods/food/unsorted_aurora.dm b/mods/content/extrafoods/food/unsorted_aurora.dm index 29d513824c5..ec0e07be451 100644 --- a/mods/content/extrafoods/food/unsorted_aurora.dm +++ b/mods/content/extrafoods/food/unsorted_aurora.dm @@ -10,7 +10,7 @@ /obj/item/chems/food/meatbun/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 3) + add_to_reagents(/decl/material/liquid/nutriment/protein, 3) /obj/item/chems/food/custardbun name = "custard bun" @@ -24,7 +24,7 @@ /obj/item/chems/food/custardbun/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2) /obj/item/chems/food/chickenmomo name = "chicken momo" @@ -40,7 +40,7 @@ /obj/item/chems/food/chickenmomo/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 6) + add_to_reagents(/decl/material/liquid/nutriment/protein, 6) /obj/item/chems/food/veggiemomo name = "veggie momo" @@ -59,7 +59,7 @@ desc = "For those who like their breakfast sweet." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "honeytoast" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#ede5ad" nutriment_amt = 1 nutriment_desc = list("sweet, crunchy bread" = 1) @@ -85,8 +85,8 @@ /obj/item/chems/food/spreads/butter/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/triglyceride, 15) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/liquid/nutriment/triglyceride, 15) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/cheese_cracker name = "supreme cheese toast" @@ -105,7 +105,7 @@ /obj/item/chems/food/truffle/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/coco, 6) + add_to_reagents(/decl/material/liquid/nutriment/coco, 6) /obj/item/chems/food/truffle/random name = "mystery chocolate truffle" @@ -122,14 +122,14 @@ /obj/item/chems/food/truffle/random/Initialize() . = ..() - reagents.add_reagent(pick(mystery_reagents), 4) + add_to_reagents(pick(mystery_reagents), 4) /obj/item/chems/food/mashedpotato name = "mashed potato" desc = "Pillowy mounds of mashed potato." icon = 'mods/content/extrafoods/icons/obj/food.dmi' icon_state = "mashedpotato" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#eddd00" nutriment_amt = 4 nutriment_desc = list("mashed potatoes" = 4) @@ -156,4 +156,4 @@ /obj/item/chems/food/banana_split/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/drink/juice/banana, 3) + add_to_reagents(/decl/material/liquid/drink/juice/banana, 3) diff --git a/mods/content/extrafoods/food/unsorted_virgo.dm b/mods/content/extrafoods/food/unsorted_virgo.dm index d8b0a751d6d..65faf5dfea4 100644 --- a/mods/content/extrafoods/food/unsorted_virgo.dm +++ b/mods/content/extrafoods/food/unsorted_virgo.dm @@ -10,8 +10,8 @@ /obj/item/chems/food/benedict/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 2, list("bacon" = 2)) - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 2, list("creamy eggs" = 2)) + add_to_reagents(/decl/material/liquid/nutriment/protein, 2, list("bacon" = 2)) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 2, list("creamy eggs" = 2)) /obj/item/chems/food/beans name = "baked beans" @@ -32,7 +32,7 @@ /obj/item/chems/food/sugarcookie/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/sugar, 2, list("sweetness" = 2)) + add_to_reagents(/decl/material/liquid/nutriment/sugar, 2, list("sweetness" = 2)) /obj/item/chems/food/fruitsalad name = "fruit salad" @@ -56,7 +56,7 @@ /obj/item/chems/food/eggbowl/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein/egg, 4, list("scrambled eggs" = 4)) + add_to_reagents(/decl/material/liquid/nutriment/protein/egg, 4, list("scrambled eggs" = 4)) /obj/item/chems/food/curryrice name = "curry rice" @@ -69,8 +69,8 @@ /obj/item/chems/food/curryrice/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/capsaicin, 4) - reagents.add_reagent(/decl/material/solid/sodiumchloride, 1) + add_to_reagents(/decl/material/liquid/capsaicin, 4) + add_to_reagents(/decl/material/solid/sodiumchloride, 1) /obj/item/chems/food/piginblanket name = "pig in a blanket" @@ -83,7 +83,7 @@ /obj/item/chems/food/piginblanket/Initialize() . = ..() - reagents.add_reagent(/decl/material/liquid/nutriment/protein, 4, list("sausage" = 3)) + add_to_reagents(/decl/material/liquid/nutriment/protein, 4, list("sausage" = 3)) /obj/item/chems/food/macncheese name = "macaroni and cheese" diff --git a/mods/content/genemodding/decl/ears.dm b/mods/content/genemodding/decl/ears.dm index 5700cf9e6c3..d2f20aa376b 100644 --- a/mods/content/genemodding/decl/ears.dm +++ b/mods/content/genemodding/decl/ears.dm @@ -10,10 +10,40 @@ abstract_type = /decl/sprite_accessory/ears name = "You should not see this..." icon = 'mods/content/genemodding/icons/mob/ears.dmi' - do_colouration = TRUE // Set to 1 to blend (ICON_ADD) hair color - blend = ICON_MULTIPLY // Only appliciable if do_colouration = TRUE + do_colouration = TRUE + color_blend = ICON_MULTIPLY + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR var/extra_overlay // Icon state of an additional overlay to blend in. +/decl/sprite_accessory/ears/get_cached_accessory_icon(obj/item/organ/external/organ, color = COLOR_WHITE, color_extra = null) + ASSERT(istext(color) && (length(color) == 7 || length(color) == 9)) + if(!icon_state) + return null + LAZYINITLIST(cached_icons[organ.bodytype]) + LAZYINITLIST(cached_icons[organ.bodytype][organ.organ_tag]) + var/key = color + if(extra_overlay && do_colouration && color_extra) + ASSERT(istext(color_extra) && (length(color_extra) == 7 || length(color_extra) == 9)) + key = "[key][color_extra]" + var/icon/accessory_icon = cached_icons[organ.bodytype][organ.organ_tag][key] + if(!accessory_icon) + accessory_icon = icon(get_accessory_icon(organ), icon_state) // make a new one to avoid mutating the base + if(!accessory_icon) + cached_icons[organ.bodytype][organ.organ_tag][key] = null + return null + if(mask_to_bodypart) + accessory_icon.Blend(get_limb_mask_for(organ.bodytype, organ.organ_tag), ICON_MULTIPLY) + if(do_colouration && color) + accessory_icon.Blend(color, color_blend) + if(extra_overlay) + var/icon/overlay = icon(icon, extra_overlay) + if(do_colouration && color_extra) + overlay.Blend(color_extra, color_blend) + accessory_icon.Blend(overlay, ICON_OVERLAY) + cached_icons[organ.bodytype][organ.organ_tag][key] = accessory_icon + return accessory_icon + /decl/sprite_accessory/ears/bee name = "bee antennae" icon_state = "bee" diff --git a/mods/content/genemodding/decl/marking.dm b/mods/content/genemodding/decl/marking.dm index 33105df6994..f9f30e8d7b9 100644 --- a/mods/content/genemodding/decl/marking.dm +++ b/mods/content/genemodding/decl/marking.dm @@ -9,7 +9,7 @@ /decl/sprite_accessory/marking/genemodder abstract_type = /decl/sprite_accessory/marking/genemodder icon = 'mods/content/genemodding/icons/mob/human_races/markings.dmi' - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY species_allowed = null /decl/sprite_accessory/marking/genemodder/vulp_belly @@ -75,35 +75,35 @@ /decl/sprite_accessory/marking/genemodder/monoeye name = "Monoeye" icon_state = "monoeye" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_monoeye" /decl/sprite_accessory/marking/genemodder/spidereyes name = "Spider Eyes" icon_state = "spidereyes" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_spidereyes" /decl/sprite_accessory/marking/genemodder/vasseyes name = "Vassilisan Eyes" icon_state = "vasseyes" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_vasseyes" /decl/sprite_accessory/marking/genemodder/vasseyesalt name = "Vassilisan Eyes (Alt)" icon_state = "vasseyesalt" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_vasseyesalt" /decl/sprite_accessory/marking/genemodder/sergaleyes name = "Sergal Eyes" icon_state = "eyes_sergal" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_sergaleyes" @@ -116,7 +116,7 @@ /decl/sprite_accessory/marking/genemodder/spots name = "Spots" icon_state = "spots" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_CHEST) uid = "acc_modder_spots" @@ -129,28 +129,28 @@ /decl/sprite_accessory/marking/genemodder/jagged_teeth name = "Jagged teeth" icon_state = "jagged" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_jagged_teeth" /decl/sprite_accessory/marking/genemodder/saber_teeth name = "Saber teeth" icon_state = "saber" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_saber_teeth" /decl/sprite_accessory/marking/genemodder/fangs name = "Fangs" icon_state = "fangs" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_fangs" /decl/sprite_accessory/marking/genemodder/tusks name = "Tusks" icon_state = "tusks" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_tusks" @@ -296,28 +296,24 @@ name = "Zorren Male Face" icon_state = "zorren_face" body_parts = list(BP_HEAD) - required_gender = MALE uid = "acc_modder_zorren_face_male" /decl/sprite_accessory/marking/genemodder/zorren_face_female name = "Zorren Female Face" icon_state = "zorren_face_female" body_parts = list(BP_HEAD) - required_gender = FEMALE uid = "acc_modder_zorren_face_female" /decl/sprite_accessory/marking/genemodder/zorren_muzzle_male name = "Zorren Male Muzzle" icon_state = "zorren_muzzle" body_parts = list(BP_HEAD) - required_gender = MALE uid = "acc_modder_zorren_muzzle_male" /decl/sprite_accessory/marking/genemodder/zorren_muzzle_female name = "Zorren Female Muzzle" icon_state = "zorren_muzzle_female" body_parts = list(BP_HEAD) - required_gender = FEMALE uid = "acc_modder_zorren_muzzle_female" /decl/sprite_accessory/marking/genemodder/zorren_socks @@ -353,7 +349,7 @@ /decl/sprite_accessory/marking/genemodder/body_tone name = "Body toning (for emergency contrast loss)" icon_state = "btone" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_CHEST) uid = "acc_modder_body_tone" @@ -396,21 +392,21 @@ /decl/sprite_accessory/marking/genemodder/animeeyesinner name = "Anime Eyes Inner" icon_state = "animeeyesinner" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_anime_eyes_inner" /decl/sprite_accessory/marking/genemodder/animeeyesouter name = "Anime Eyes Outer" icon_state = "animeeyesouter" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_anime_eyes_outer" /decl/sprite_accessory/marking/genemodder/panda_eye_marks name = "Panda Eye Markings" icon_state = "eyes_panda" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_panda_eye_marks" @@ -477,7 +473,7 @@ /decl/sprite_accessory/marking/genemodder/heterochromia name = "Heterochromia" icon_state = "heterochromia" - blend = ICON_ADD + color_blend = ICON_ADD body_parts = list(BP_HEAD) uid = "acc_modder_heterochromia" diff --git a/mods/content/genemodding/decl/tail.dm b/mods/content/genemodding/decl/tail.dm index e6b98a5ec19..1769b53ea30 100644 --- a/mods/content/genemodding/decl/tail.dm +++ b/mods/content/genemodding/decl/tail.dm @@ -12,7 +12,7 @@ icon = 'mods/content/genemodding/icons/mob/tails.dmi' do_colouration = TRUE //Set to 1 to enable coloration using the tail color. - blend = ICON_MULTIPLY // Only appliciable if do_coloration = 1 + color_blend = ICON_MULTIPLY // Only appliciable if do_coloration = 1 var/extra_overlay // Icon state of an additional overlay to blend in. /* // This needs to be done in a better way. It probably doesn't even work currently? @@ -59,7 +59,7 @@ name = "bunny, colorable" icon_state = "bunny" do_colouration = TRUE - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_tail_bunny_colorable" /decl/sprite_accessory/tail/bear @@ -117,7 +117,7 @@ /decl/sprite_accessory/tail/spade_color name = "spade-tail (colorable)" icon_state = "spadetail-black" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_tail_spade_colorable" /decl/sprite_accessory/tail/eboop diff --git a/mods/content/genemodding/head_overwrites.dm b/mods/content/genemodding/head_overwrites.dm index e70aab84e2c..f4adb24c560 100644 --- a/mods/content/genemodding/head_overwrites.dm +++ b/mods/content/genemodding/head_overwrites.dm @@ -1,27 +1,9 @@ -var/global/list/ear_icon_cache = list() //key is "\ref[ear_style]", if colorable plus "[ear_color]" and potentially "[ear_color_extra]" -/obj/item/organ/external/head/get_hair_icon() - var/image/res = ..() - var/obj/item/headwear = owner.get_equipped_item(slot_head_str) - if(!owner.ear_style || (headwear?.flags_inv & BLOCK_HEAD_HAIR)) - return res - var/icon_key - if(owner.ear_style.do_colouration) - if(owner.ear_style.extra_overlay) - icon_key = "\ref[owner.ear_style][owner.ear_color][owner.ear_color_extra]" - else - icon_key = "\ref[owner.ear_style][owner.ear_color]" - else - icon_key = any2ref(owner.ear_style) - var/icon/ears_icon = global.ear_icon_cache[icon_key] - if(!ears_icon) - ears_icon = icon(owner.ear_style.icon, owner.ear_style.icon_state) - if(owner.ear_style.do_colouration) - ears_icon.Blend(owner.ear_color, owner.ear_style.blend) - if(owner.ear_style.extra_overlay) - var/icon/overlay = icon(owner.ear_style.icon, owner.ear_style.extra_overlay) - overlay.Blend(owner.ear_color_extra, owner.ear_style.blend) - ears_icon.Blend(overlay, ICON_OVERLAY) - qdel(overlay) - global.ear_icon_cache[icon_key] = ears_icon - res.overlays |= ears_icon - return res \ No newline at end of file +/obj/item/organ/external/head/get_mob_overlays() + . = ..() + if(!owner) + return + var/ear_style = owner.get_ear_style() + if(ear_style) + var/decl/sprite_accessory/ears/ears = resolve_accessory_to_decl(ear_style) + if(ears?.accessory_is_available(owner, species, bodytype)) + LAZYADD(., image(ears.get_cached_accessory_icon(src, owner.get_ear_colour(), owner.get_extra_ear_colour()))) diff --git a/mods/content/genemodding/mob_overwrites.dm b/mods/content/genemodding/mob_overwrites.dm index 60fcfc742f4..ded6df99e52 100644 --- a/mods/content/genemodding/mob_overwrites.dm +++ b/mods/content/genemodding/mob_overwrites.dm @@ -4,4 +4,22 @@ var/ear_color_extra = "#1e1e1e" var/decl/sprite_accessory/tail/tail_style = null // for bookkeeping in is_default_limb var/tail_color = "#1e1e1e" - var/tail_color_extra = "#1e1e1e" \ No newline at end of file + var/tail_color_extra = "#1e1e1e" + +/mob/living/proc/get_ear_style() + return + +/mob/living/proc/get_ear_colour() + return + +/mob/living/proc/get_extra_ear_colour() + return + +/mob/living/carbon/human/get_ear_style() + return ear_style + +/mob/living/carbon/human/get_ear_colour() + return ear_color + +/mob/living/carbon/human/get_extra_ear_colour() + return ear_color_extra \ No newline at end of file diff --git a/mods/content/genemodding/player_setup.dm b/mods/content/genemodding/player_setup.dm index fb7a4bccebf..7e3ae5c9214 100644 --- a/mods/content/genemodding/player_setup.dm +++ b/mods/content/genemodding/player_setup.dm @@ -49,15 +49,16 @@ var/obj/item/organ/external/tail/tail_organ = get_organ(BP_TAIL) var/decl/bodytype/root_bodytype = get_bodytype() if(!tail_style) - if(!tail_organ) + if(!tail_organ || root_bodytype.is_default_limb(tail_organ)) return + remove_organ(tail_organ, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE) qdel(tail_organ) var/list/tail_data = LAZYACCESS(root_bodytype?.has_limbs, BP_TAIL) var/tail_path = LAZYACCESS(tail_data, "path") if(!tail_path) return tail_organ = new tail_path(src, null, dna, root_bodytype) - add_organ(tail_organ) + add_organ(tail_organ, TRUE, TRUE, FALSE, TRUE) return if(!tail_organ) tail_organ = new(src, null, dna, root_bodytype) @@ -68,8 +69,8 @@ if(tail_style.do_colouration) tail_organ.tail_colour = tail_color tail_organ.tail_hair_colour = tail_color_extra - tail_organ.tail_blend = tail_style.blend - tail_organ.tail_hair_blend = tail_style.blend + tail_organ.tail_blend = tail_style.color_blend + tail_organ.tail_hair_blend = tail_style.color_blend else tail_organ.tail_colour = null tail_organ.tail_hair_colour = null diff --git a/mods/content/genemodding/update_icons.dm b/mods/content/genemodding/update_icons.dm index 3550352a14a..3bd0d0211f0 100644 --- a/mods/content/genemodding/update_icons.dm +++ b/mods/content/genemodding/update_icons.dm @@ -9,6 +9,7 @@ return // No tail data! // These values may be null and are generally optional. + var/hair_colour = get_hair_colour() var/tail_hair = tail_organ.get_tail_hair() var/tail_blend = tail_organ.get_tail_blend() var/tail_hair_blend = tail_organ.get_tail_hair_blend() diff --git a/mods/content/generic_shuttles/tanker/tanker.dmm b/mods/content/generic_shuttles/tanker/tanker.dmm index 704b701c15b..02a3995e394 100644 --- a/mods/content/generic_shuttles/tanker/tanker.dmm +++ b/mods/content/generic_shuttles/tanker/tanker.dmm @@ -300,7 +300,7 @@ dir = 4 }, /obj/machinery/fabricator/pipe{ - anchored = TRUE + anchored = 1 }, /turf/simulated/floor/plating, /area/tanker) diff --git a/mods/content/government/away_sites/icarus/icarus-1.dmm b/mods/content/government/away_sites/icarus/icarus-1.dmm index 5fde23e1cf5..0d80540e871 100644 --- a/mods/content/government/away_sites/icarus/icarus-1.dmm +++ b/mods/content/government/away_sites/icarus/icarus-1.dmm @@ -154,7 +154,7 @@ /area/icarus/vessel) "aL" = ( /obj/structure/table/woodentable, -/obj/item/storage/fancy/cigar, +/obj/item/storage/box/fancy/cigar, /turf/simulated/floor/wood, /area/icarus/vessel) "aM" = ( @@ -708,7 +708,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/icarus/vessel) "cB" = ( @@ -773,7 +773,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/item/trash/plate, +/obj/item/plate, /obj/item/kitchen/utensil/fork, /turf/simulated/floor/tiled, /area/icarus/vessel) @@ -944,7 +944,7 @@ /area/icarus/vessel) "dm" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/icarus/open) "dn" = ( @@ -994,7 +994,7 @@ /area/icarus/vessel) "dv" = ( /obj/structure/table, -/obj/item/trash/plate, +/obj/item/plate, /turf/simulated/floor/tiled, /area/icarus/vessel) "dw" = ( @@ -1385,7 +1385,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/item/trash/plate, +/obj/item/plate, /turf/unsimulated/beach/sand, /area/icarus/open) "eJ" = ( @@ -1425,7 +1425,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/item/trash/plate, +/obj/item/plate, /turf/unsimulated/beach/sand, /area/icarus/open) "eO" = ( @@ -2583,7 +2583,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/unary/engine{ - anchored = FALSE + anchored = 0 }, /turf/unsimulated/beach/sand, /area/icarus/open) diff --git a/mods/content/government/away_sites/icarus/icarus-2.dmm b/mods/content/government/away_sites/icarus/icarus-2.dmm index a33a27e4ea6..5e392f2cd8d 100644 --- a/mods/content/government/away_sites/icarus/icarus-2.dmm +++ b/mods/content/government/away_sites/icarus/icarus-2.dmm @@ -6,7 +6,7 @@ /turf/unsimulated/mask, /area/mine/unexplored) "ac" = ( -/turf/simulated/open, +/turf/open, /area/icarus/open) "ad" = ( /turf/exterior/wall, @@ -134,7 +134,7 @@ /area/icarus/vessel) "aE" = ( /obj/structure/table/steel_reinforced, -/obj/item/storage/fancy/cigarettes/killthroat, +/obj/item/storage/box/fancy/cigarettes/killthroat, /turf/simulated/floor/tiled, /area/icarus/vessel) "aF" = ( @@ -855,7 +855,7 @@ /area/icarus/vessel) "cR" = ( /obj/structure/lattice, -/turf/simulated/open, +/turf/open, /area/icarus/open) "cS" = ( /obj/structure/rack, @@ -1257,7 +1257,7 @@ /area/icarus/open) "dZ" = ( /obj/effect/icarus/irradiate, -/turf/simulated/open, +/turf/open, /area/icarus/open) "ea" = ( /obj/structure/cable{ diff --git a/mods/content/government/datum/ai_laws.dm b/mods/content/government/datum/ai_laws.dm index 0452bdcaad5..c31bd6571cd 100644 --- a/mods/content/government/datum/ai_laws.dm +++ b/mods/content/government/datum/ai_laws.dm @@ -25,7 +25,7 @@ /obj/item/aiModule/solgov name = "'SCG Expeditionary' Core AI Module" desc = "An 'SCG Expeditionary' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/solgov /******************** SCG Aggressive ********************/ @@ -33,5 +33,5 @@ /obj/item/aiModule/solgov_aggressive name = "\improper 'Military' Core AI Module" desc = "A 'Military' Core AI Module: 'Reconfigures the AI's core laws.'." - origin_tech = "{'programming':3,'materials':4}" + origin_tech = @'{"programming":3,"materials":4}' laws = new/datum/ai_laws/solgov_aggressive diff --git a/mods/content/government/ruins/ec_old_crash/ec_old_crash.dm b/mods/content/government/ruins/ec_old_crash/ec_old_crash.dm index 64e7aa4c84e..fcd9668d427 100644 --- a/mods/content/government/ruins/ec_old_crash/ec_old_crash.dm +++ b/mods/content/government/ruins/ec_old_crash/ec_old_crash.dm @@ -8,7 +8,7 @@ /area/map_template/ecship/engine = NO_SCRUBBER|NO_VENT|NO_APC, /area/map_template/ecship/cockpit = NO_SCRUBBER|NO_APC ) - ruin_tags = RUIN_HUMAN|RUIN_WRECK + template_tags = TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WRECK template_flags = TEMPLATE_FLAG_CLEAR_CONTENTS | TEMPLATE_FLAG_NO_RUINS /area/map_template/ecship/crew diff --git a/mods/content/government/ruins/ec_old_crash/ec_old_crash.dmm b/mods/content/government/ruins/ec_old_crash/ec_old_crash.dmm index 16ff99b6315..45fefce3a86 100644 --- a/mods/content/government/ruins/ec_old_crash/ec_old_crash.dmm +++ b/mods/content/government/ruins/ec_old_crash/ec_old_crash.dmm @@ -1200,7 +1200,7 @@ dir = 10 }, /obj/machinery/smartfridge{ - density = FALSE + density = 0 }, /turf/simulated/floor/tiled/white/lowpressure, /area/map_template/ecship/science) diff --git a/mods/content/lighthouse/timeclock/timeoff_subsystem.dm b/mods/content/lighthouse/timeclock/timeoff_subsystem.dm index b02c2b4bea6..e8c51c0191a 100644 --- a/mods/content/lighthouse/timeclock/timeoff_subsystem.dm +++ b/mods/content/lighthouse/timeclock/timeoff_subsystem.dm @@ -1,5 +1,6 @@ // Write to database every 15 minutes. SUBSYSTEM_DEF(timeoff) + name = "PTO" wait = 15 MINUTES priority = 20 flags = SS_BACKGROUND | SS_NO_INIT | SS_KEEP_TIMING diff --git a/mods/content/mouse_highlights/mouse_highlight_client.dm b/mods/content/mouse_highlights/mouse_highlight_client.dm index 1dad1018cd6..50d8c68b391 100644 --- a/mods/content/mouse_highlights/mouse_highlight_client.dm +++ b/mods/content/mouse_highlights/mouse_highlight_client.dm @@ -11,7 +11,7 @@ /client/New() // Cache our callback as we will potentially be using it (10 / ticklag) times per second, - mouseover_callback = CALLBACK(src, .proc/refresh_mouseover_highlight_timer) + mouseover_callback = CALLBACK(src, PROC_REF(refresh_mouseover_highlight_timer)) . = ..() // This proc iterates constantly whenever something is being mouseover'd, so that it @@ -74,7 +74,7 @@ mouseover_highlight_dummy.plane = HUD_ABOVE_ITEM_LAYER mouseover_highlight_dummy.alpha = prefs?.UI_mouseover_alpha || 255 mouseover_highlight_dummy.appearance_flags |= (KEEP_TOGETHER|RESET_COLOR) - mouseover_highlight_dummy.add_filter("glow", 1, list("drop_shadow", color = (prefs?.UI_mouseover_color || COLOR_AMBER) + "F0", size = 1, offset = 1, x = 0, y = 0)) + mouseover_highlight_dummy.add_filter("glow", 1, list(type = "drop_shadow", color = (prefs?.UI_mouseover_color || COLOR_AMBER) + "F0", size = 1, offset = 1, x = 0, y = 0)) // Replanes the overlays to avoid explicit plane/layer setting (such as // computer overlays) interfering with the ordering of the highlight. diff --git a/mods/content/psionics/datum/codex.dm b/mods/content/psionics/datum/codex.dm index cac5a264042..94ffe0c9962 100644 --- a/mods/content/psionics/datum/codex.dm +++ b/mods/content/psionics/datum/codex.dm @@ -26,7 +26,7 @@ name = "Psionics" associated_strings = list("psychic powers") associated_paths = list( - /obj/item/book/manual/psionics, + /obj/item/book/fluff/psionics, /obj/item/clothing/head/helmet/space/psi_amp, /obj/item/clothing/head/helmet/space/psi_amp/lesser ) diff --git a/mods/content/psionics/items/literature.dm b/mods/content/psionics/items/literature.dm index 94befe6938d..84b3d235399 100644 --- a/mods/content/psionics/items/literature.dm +++ b/mods/content/psionics/items/literature.dm @@ -1,29 +1,11 @@ -/obj/item/book/manual/psionics +/obj/item/book/fluff/psionics name = "Psychonetics" icon_state = "foundation" author = "John Titor" title = "Psychonetics" - - dat = {" - - - - -

    Psychonetics

    - -

    This seems to be a dry, longwinded reference text for the form of strange mental powers called psionics. The author spends way too much time trying to advertise his cult, though.

    - -

    The general gist of things seems to be that sometime in the last decade or so, the first cases of 'spontaneous operancy' became known. People who spent a lot of time in deep space, or who studied certain esoteric fields of mathematics, became able to perform strange feats like levitating coins or removing headaches with nothing but their minds. The text goes on to explain that psionics are perfectly harmless, and that studies (no citations) have shown operants are no more likely to go mad and murder people than anyone else.

    - -

    A postscript by a group called the Cuchulain Foundation invites anyone who knows an operant, or thinks they might be one, to send them a message via comms and get enrolled in their training and registration program in orbit around Neptune. It's catered. The postscript adds hastily that you should never try to activate your own latencies with trauma or drugs, as the results are often lethal.

    - - - - "} + fluff_text = {" +

    Psychonetics

    +

    This seems to be a dry, longwinded reference text for the form of strange mental powers called psionics. The author spends way too much time trying to advertise his cult, though.

    +

    The general gist of things seems to be that sometime in the last decade or so, the first cases of 'spontaneous operancy' became known. People who spent a lot of time in deep space, or who studied certain esoteric fields of mathematics, became able to perform strange feats like levitating coins or removing headaches with nothing but their minds. The text goes on to explain that psionics are perfectly harmless, and that studies (no citations) have shown operants are no more likely to go mad and murder people than anyone else.

    +

    A postscript by a group called the Cuchulain Foundation invites anyone who knows an operant, or thinks they might be one, to send them a message via comms and get enrolled in their training and registration program in orbit around Neptune. It's catered. The postscript adds hastily that you should never try to activate your own latencies with trauma or drugs, as the results are often lethal.

    + "} diff --git a/mods/content/psionics/system/psionics/interface/ui.dm b/mods/content/psionics/system/psionics/interface/ui.dm index 77685cf57d8..a3f8a3317db 100644 --- a/mods/content/psionics/system/psionics/interface/ui.dm +++ b/mods/content/psionics/system/psionics/interface/ui.dm @@ -1,6 +1,5 @@ /obj/screen/psi icon = 'mods/content/psionics/icons/psi.dmi' - var/mob/living/owner var/hidden = TRUE /obj/screen/psi/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha) diff --git a/mods/content/psionics/system/psionics/interface/ui_hub.dm b/mods/content/psionics/system/psionics/interface/ui_hub.dm index 260b5cc08e7..b9ff65b98d2 100644 --- a/mods/content/psionics/system/psionics/interface/ui_hub.dm +++ b/mods/content/psionics/system/psionics/interface/ui_hub.dm @@ -12,8 +12,8 @@ . = ..() on_cooldown = image(icon, "cooldown") components = list( - new /obj/screen/psi/armour(null, owner), - new /obj/screen/psi/toggle_psi_menu(null, owner, null, null, null, src) + new /obj/screen/psi/armour(null, _owner), + new /obj/screen/psi/toggle_psi_menu(null, _owner, null, null, null, src) ) START_PROCESSING(SSprocessing, src) diff --git a/mods/content/psionics/system/psionics/interface/ui_toggles.dm b/mods/content/psionics/system/psionics/interface/ui_toggles.dm index aa7f30d6b6a..62bba0cf9d9 100644 --- a/mods/content/psionics/system/psionics/interface/ui_toggles.dm +++ b/mods/content/psionics/system/psionics/interface/ui_toggles.dm @@ -5,7 +5,8 @@ /obj/screen/psi/armour/on_update_icon() ..() - if(invisibility == 0) + var/mob/living/owner = owner_ref.resolve() + if(istype(owner) && invisibility == 0) icon_state = owner?.psi.use_psi_armour ? "psiarmour_on" : "psiarmour_off" /obj/screen/psi/armour/handle_click(mob/user, params) diff --git a/mods/content/psionics/system/psionics/null/material.dm b/mods/content/psionics/system/psionics/null/material.dm index dd30a34a4c0..96aeff59041 100644 --- a/mods/content/psionics/system/psionics/null/material.dm +++ b/mods/content/psionics/system/psionics/null/material.dm @@ -26,7 +26,7 @@ /decl/material/nullglass/generate_recipes(stack_type, reinforce_material) . = ..() - if(!reinforce_material && islist(.) && !ispath(stack_type)) + if(!holographic && !reinforce_material && islist(.) && !ispath(stack_type)) . += new /datum/stack_recipe/tile/nullglass(src) /obj/item/shard/nullglass diff --git a/mods/content/resleeving/body_printer.dm b/mods/content/resleeving/body_printer.dm index cb3f6c9a29a..ed45d5c6de8 100644 --- a/mods/content/resleeving/body_printer.dm +++ b/mods/content/resleeving/body_printer.dm @@ -220,7 +220,7 @@ /obj/machinery/bioprinter/proc/open_pod_start() animate(lid, pixel_y = 38, time = 3 SECONDS, easing = SINE_EASING) - addtimer(CALLBACK(src, .proc/open_pod_finish), 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(open_pod_finish)), 3 SECONDS) playsound(get_turf(src), 'sound/machines/podopen.ogg', 75) /obj/machinery/bioprinter/proc/open_pod_finish() @@ -228,7 +228,7 @@ /obj/machinery/bioprinter/proc/close_pod_start() animate(lid, pixel_y = 0, time = 3 SECONDS, easing = SINE_EASING) - addtimer(CALLBACK(src, .proc/close_pod_finish), 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(close_pod_finish)), 3 SECONDS) playsound(get_turf(src), 'sound/machines/podclose.ogg', 75) /obj/machinery/bioprinter/proc/close_pod_finish() @@ -364,7 +364,7 @@ print_finished = FALSE next_increment = world.time + 4 SECONDS + get_printing_increment() playsound(get_turf(src), pick(global.keyboard_sound)) - addtimer(CALLBACK(src, .proc/start_print_next), 4 SECONDS) + addtimer(CALLBACK(src, PROC_REF(start_print_next)), 4 SECONDS) /obj/machinery/bioprinter/proc/start_print_next() var/datum/computer_file/data/body_record/body_record = diskette.contains_file_type("BDY") @@ -430,19 +430,19 @@ switch(total_passes) if(0) do_fakemob_animation("fakemob1", "layer1", "stage1", 0.01, FALSE) - addtimer(CALLBACK(src, .proc/animate_printhead), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(animate_printhead)), 2 SECONDS) if(1) animate(ph, pixel_y = 0, time = 2 SECONDS) do_fakemob_animation("fakemob2", "layer2", "stage2", 0.02, FALSE) - addtimer(CALLBACK(src, .proc/animate_printhead), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(animate_printhead)), 2 SECONDS) if(2) animate(ph, pixel_y = 0, time = 2 SECONDS) do_fakemob_animation("fakemob3", "layer3", "stage3", 0.03, FALSE) - addtimer(CALLBACK(src, .proc/animate_printhead), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(animate_printhead)), 2 SECONDS) if(3) animate(ph, pixel_y = 0, time = 2 SECONDS) do_fakemob_animation("fakemob4", "layer4", "stage4", 0.04, FALSE) - addtimer(CALLBACK(src, .proc/animate_printhead), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(animate_printhead)), 2 SECONDS) if(4) //By this point we can get rid of the three earlier mobs from vis_contents. animate(ph, pixel_y = 0, time = 2 SECONDS) do_fakemob_animation("fakemob1", "layer1", "stage1", fade_out = TRUE) @@ -458,7 +458,7 @@ fakemob.add_filter("layer5",1 ,list(type = "alpha", y = -32, icon = icon('icons/mob/human.dmi', "body_m_s"))) fakemob.animate_filter("layer5", list(y = 0, time = get_printing_increment())) vis_contents += fakemob - addtimer(CALLBACK(src, .proc/animate_printhead), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(animate_printhead)), 2 SECONDS) /obj/machinery/bioprinter/proc/do_fakemob_animation(var/fakemob_name, var/filter_name, var/stage_name, var/fakemob_layer_increment, var/fade_out = FALSE) var/obj/effect/fake_clone_mob/fakemob = clone_mobs[fakemob_name] @@ -530,7 +530,7 @@ last_used_technobabble = technobabble technobabble_used += technobabble if(!is_error) //if not a critical error, auto-resolve in ~30s - interaction_timer_id = addtimer(CALLBACK(src, .proc/fulfill_interaction), 50 SECONDS, TIMER_STOPPABLE) + interaction_timer_id = addtimer(CALLBACK(src, PROC_REF(fulfill_interaction)), 50 SECONDS, TIMER_STOPPABLE) do_telecomms_announcement(src, "Error in [technobabble] - auto-recovery under way...", "Bioprinter Monitoring System", "Medical") buzz("\The [src] buzzes, \"Error in [technobabble] - auto-recovery under way...\"") else @@ -561,7 +561,7 @@ /obj/machinery/bioprinter/proc/start_cleaning() cleaning = TRUE close_pod_start() - cleaning_timer_id = addtimer(CALLBACK(src, .proc/finish_cleaning), cleaning_delay, TIMER_STOPPABLE) + cleaning_timer_id = addtimer(CALLBACK(src, PROC_REF(finish_cleaning)), cleaning_delay, TIMER_STOPPABLE) update_icon() /obj/machinery/bioprinter/proc/finish_cleaning() diff --git a/mods/content/shackles/_shackles.dme b/mods/content/shackles/_shackles.dme index d48f7fc6e17..8685bfedc69 100644 --- a/mods/content/shackles/_shackles.dme +++ b/mods/content/shackles/_shackles.dme @@ -3,6 +3,5 @@ // BEGIN_INCLUDE #include "laws_pref.dm" #include "mind.dm" -#include "posibrain.dm" #include "shackle_lawsets.dm" #endif \ No newline at end of file diff --git a/mods/content/shackles/laws_pref.dm b/mods/content/shackles/laws_pref.dm index 7fb0a89af22..77c3b8baffa 100644 --- a/mods/content/shackles/laws_pref.dm +++ b/mods/content/shackles/laws_pref.dm @@ -28,7 +28,8 @@ W.write("is_shackled", pref.is_shackled) /datum/category_item/player_setup_item/law_pref/sanitize_character() - if(!istype(pref.laws)) pref.laws = list() + if(!istype(pref.laws)) + pref.laws = list() var/decl/bodytype/mob_bodytype = pref.get_bodytype_decl() if(!mob_bodytype?.can_be_shackled) @@ -68,6 +69,7 @@ . = jointext(.,null) /datum/category_item/player_setup_item/law_pref/OnTopic(href, href_list, user) + if(href_list["toggle_shackle"]) pref.is_shackled = !pref.is_shackled return TOPIC_REFRESH @@ -106,7 +108,3 @@ /decl/bodytype var/can_be_shackled - -/decl/bodytype/Initialize() - . = ..() - can_be_shackled = !!(BP_POSIBRAIN in has_organ) diff --git a/mods/content/shackles/posibrain.dm b/mods/content/shackles/posibrain.dm deleted file mode 100644 index 741b23fe40e..00000000000 --- a/mods/content/shackles/posibrain.dm +++ /dev/null @@ -1,16 +0,0 @@ -/obj/item/organ/internal/proc/handle_shackled(var/given_lawset) - return - -/obj/item/organ/internal/posibrain/handle_shackled(var/given_lawset) - ..() - update_icon() - -/obj/item/organ/internal/posibrain/examine(mob/user) - . = ..() - if(owner?.mind?.shackle) - . += SPAN_WARNING("It is clamped in a set of metal straps with a complex digital lock.") - -/obj/item/organ/internal/posibrain/on_update_icon() - . = ..() - if(owner?.mind?.shackle) - add_overlay("posibrain-shackles") diff --git a/mods/content/xenobiology/colours/colour_gold.dm b/mods/content/xenobiology/colours/colour_gold.dm index 15556e505e8..79372c444e2 100644 --- a/mods/content/xenobiology/colours/colour_gold.dm +++ b/mods/content/xenobiology/colours/colour_gold.dm @@ -17,7 +17,8 @@ /mob/living/simple_animal/corgi/puppy, /mob/living/simple_animal/cow, /mob/living/simple_animal/chick, - /mob/living/simple_animal/chicken + /mob/living/simple_animal/fowl/chicken, + /mob/living/simple_animal/fowl/duck ) /decl/slime_colour/gold/handle_phoron_reaction(var/datum/reagents/holder) diff --git a/mods/content/xenobiology/colours/colour_yellow.dm b/mods/content/xenobiology/colours/colour_yellow.dm index ca824eb3408..bc1c1ccbd74 100644 --- a/mods/content/xenobiology/colours/colour_yellow.dm +++ b/mods/content/xenobiology/colours/colour_yellow.dm @@ -17,7 +17,7 @@ /decl/slime_colour/yellow/Initialize() . = ..() - LAZYSET(reaction_procs, /decl/material/liquid/water, /decl/slime_colour/yellow/proc/try_water_reaction) + LAZYSET(reaction_procs, /decl/material/liquid/water, TYPE_PROC_REF(/decl/slime_colour/yellow, try_water_reaction)) /decl/slime_colour/yellow/handle_blood_reaction(var/datum/reagents/holder) var/location = get_turf(holder.get_reaction_loc()) diff --git a/mods/content/xenobiology/food.dm b/mods/content/xenobiology/food.dm index 27933822fb8..09316e9c2f6 100644 --- a/mods/content/xenobiology/food.dm +++ b/mods/content/xenobiology/food.dm @@ -12,7 +12,7 @@ items = list( /obj/item/chems/food/dough ) - result = /obj/item/chems/food/donut/slimejelly + result = /obj/item/chems/food/donut/jelly/slime /decl/recipe/slimeburger display_name = "Slime Burger" @@ -36,15 +36,15 @@ result = /obj/item/chems/food/slimesoup /obj/item/chems/food/jellysandwich/slime/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 5) + add_to_reagents(/decl/material/liquid/slimejelly, 5) . = ..() /obj/item/chems/food/jelliedtoast/slime/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 5) + add_to_reagents(/decl/material/liquid/slimejelly, 5) . = ..() /obj/item/chems/food/jellyburger/slime/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 5) + add_to_reagents(/decl/material/liquid/slimejelly, 5) . = ..() /obj/item/chems/food/slimesoup @@ -56,23 +56,18 @@ eat_sound = 'sound/items/drink.ogg' /obj/item/chems/food/slimesoup/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 5) - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/slimejelly, 5) + add_to_reagents(/decl/material/liquid/water, 10) . = ..() -/obj/item/chems/food/donut/slimejelly +/obj/item/chems/food/donut/jelly/slime name = "jelly donut" desc = "You jelly?" - icon_state = "jdonut1" filling_color = "#ed1169" - center_of_mass = @"{'x':16,'y':11}" + center_of_mass = @'{"x":16,"y":11}' nutriment_amt = 3 bitesize = 5 - donut_state = "jdonut" - -/obj/item/chems/food/donut/slimejelly/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 5) - . = ..() + jelly_type = /decl/material/liquid/slimejelly /obj/item/chems/food/mysterysoup/get_random_fillings() . = ..() + list(list( diff --git a/mods/content/xenobiology/overrides.dm b/mods/content/xenobiology/overrides.dm index 671c77bbe7b..33659633bd3 100644 --- a/mods/content/xenobiology/overrides.dm +++ b/mods/content/xenobiology/overrides.dm @@ -38,3 +38,9 @@ /obj/item/gripper/cultivator/Initialize(ml, material_key) . = ..() can_hold |= /obj/item/slime_extract + +/mob/living/carbon/human/say_understands(var/mob/other,var/decl/language/speaking = null) + . = (!speaking && isslime(other)) || ..() + +/mob/living/brain/say_understands(var/mob/other,var/decl/language/speaking = null) + . = (!speaking && isslime(other)) || ..() diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index c657146d6eb..e81a9809b9b 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -1,3 +1,7 @@ +/decl/config/num/movement_slime + uid = "slime_delay" + desc = "Movement delay for slimes." + #define FEED_RESULT_INVALID -1 #define FEED_RESULT_DEAD 0 #define FEED_RESULT_VALID 1 @@ -63,8 +67,7 @@ ingested = new /datum/reagents/metabolism(240, src, CHEM_TOUCH) reagents = ingested - // See comment in /mob/living/slime/on_update_icon() regarding alpha mask filters. - //render_target = "slime_\ref[src]" + render_target = "slime_\ref[src]" verbs += /mob/living/proc/ventcrawl slime_type = _stype @@ -104,7 +107,7 @@ if(current_health <= 0) // if damaged, the slime moves twice as slow tally *= 2 - return tally + config.slime_delay + return tally + get_config_value(/decl/config/num/movement_slime) /mob/living/slime/Bump(atom/movable/AM, yes) if ((!(yes) || now_pushing)) @@ -291,7 +294,7 @@ return FALSE /mob/living/slime/check_has_mouth() - return 0 + return FALSE /mob/living/slime/set_nutrition(amt) ..() diff --git a/mods/content/xenobiology/slime/feeding.dm b/mods/content/xenobiology/slime/feeding.dm index 91c90dc1d41..5fb8c6d1cdb 100644 --- a/mods/content/xenobiology/slime/feeding.dm +++ b/mods/content/xenobiology/slime/feeding.dm @@ -52,9 +52,9 @@ feeding_on = null if(victim) feeding_on = weakref(victim) - events_repository.register(/decl/observ/moved, src, src, /mob/living/slime/proc/check_feed_target_position) - events_repository.register(/decl/observ/moved, victim, src, /mob/living/slime/proc/check_feed_target_position) - events_repository.register(/decl/observ/destroyed, victim, src, /mob/living/slime/proc/check_feed_target_position) + events_repository.register(/decl/observ/moved, src, src, TYPE_PROC_REF(/mob/living/slime, check_feed_target_position)) + events_repository.register(/decl/observ/moved, victim, src, TYPE_PROC_REF(/mob/living/slime, check_feed_target_position)) + events_repository.register(/decl/observ/destroyed, victim, src, TYPE_PROC_REF(/mob/living/slime, check_feed_target_position)) var/datum/ai/slime/slime_ai = ai if(istype(slime_ai)) slime_ai.update_mood() diff --git a/mods/content/xenobiology/slime/items.dm b/mods/content/xenobiology/slime/items.dm index 504a44d8676..7638bb297ad 100644 --- a/mods/content/xenobiology/slime/items.dm +++ b/mods/content/xenobiology/slime/items.dm @@ -8,7 +8,7 @@ throwforce = 0 throw_speed = 3 throw_range = 6 - origin_tech = "{'biotech':4}" + origin_tech = @'{"biotech":4}' atom_flags = ATOM_FLAG_OPEN_CONTAINER material = /decl/material/liquid/slimejelly var/slime_type = /decl/slime_colour/grey @@ -47,7 +47,7 @@ . = ..() /obj/item/slime_extract/populate_reagents() - reagents.add_reagent(/decl/material/liquid/slimejelly, 30) + add_to_reagents(/decl/material/liquid/slimejelly, 30) /obj/item/slime_extract/on_reagent_change() ..() diff --git a/mods/content/xenobiology/slime/items_cell.dm b/mods/content/xenobiology/slime/items_cell.dm index 6e86721eb72..c8b16941691 100644 --- a/mods/content/xenobiology/slime/items_cell.dm +++ b/mods/content/xenobiology/slime/items_cell.dm @@ -1,7 +1,7 @@ /obj/item/cell/slime name = "charged slime core" desc = "A yellow slime core infused with phoron. It crackles with power." - origin_tech = "{'powerstorage':2,'biotech':4}" + origin_tech = @'{"powerstorage":2,"biotech":4}' icon = 'mods/content/xenobiology/icons/slimes/slime_extract_yellow.dmi' icon_state = ICON_STATE_WORLD maxcharge = 200 diff --git a/mods/content/xenobiology/slime/life.dm b/mods/content/xenobiology/slime/life.dm index 1e4c2b46f32..5c1d26a6bc3 100644 --- a/mods/content/xenobiology/slime/life.dm +++ b/mods/content/xenobiology/slime/life.dm @@ -1,49 +1,17 @@ -/mob/living/slime/Life() +/mob/living/slime/handle_environment(datum/gas_mixture/environment) . = ..() - if(. && stat != DEAD) - handle_turf_contents() - handle_local_conditions() - if(feeding_on) - slime_feed() - ingested.metabolize() -/mob/living/slime/fluid_act(datum/reagents/fluids) - . = ..() - if(!QDELETED(src) && fluids?.total_volume >= FLUID_SHALLOW && stat == DEAD) - var/turf/T = get_turf(src) - if(T) - T.add_fluid(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30))) - visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble. - qdel(src) - -/mob/living/slime/proc/handle_local_conditions() - var/datum/gas_mixture/environment = loc?.return_air() - adjust_body_temperature(bodytemperature, (environment?.temperature || T0C), 1) + if(environment) + var/delta = abs(bodytemperature - environment.temperature) + var/change = (delta / (delta > 50 ? 5 : 10)) + if(bodytemperature > environment.temperature) + change = -(change) + bodytemperature += (min(environment.temperature, bodytemperature + change) - bodytemperature) if(bodytemperature <= die_temperature) adjustToxLoss(200) - death() else if(bodytemperature <= hurt_temperature) adjustToxLoss(30) -/mob/living/slime/proc/adjust_body_temperature(current, loc_temp, boost) - var/delta = abs(current-loc_temp) - var/change = (delta / (delta > 50 ? 5 : 10)) * boost - if(current > loc_temp) - change = -(change) - bodytemperature += (min(loc_temp, current + change) - current) - -/mob/living/slime/handle_regular_status_updates() - . = ..() - if(stat != DEAD) - set_stat(CONSCIOUS) - if(prob(30)) - adjustOxyLoss(-1, do_update_health = FALSE) - adjustToxLoss(-1, do_update_health = FALSE) - adjustFireLoss(-1, do_update_health = FALSE) - adjustCloneLoss(-1, do_update_health = FALSE) - adjustBruteLoss(-1) - -/mob/living/slime/proc/handle_turf_contents() // If we're standing on top of a dead mob or small items, we can // ingest it (or just melt it a little if we're too small) // Also helps to keep our cell tidy! @@ -74,13 +42,51 @@ if(length(contents) != last_contents_length) queue_icon_update() +/mob/living/slime/handle_nutrition_and_hydration() + . = ..() + if(feeding_on) + slime_feed() + ingested.metabolize() + +/mob/living/slime/fluid_act(datum/reagents/fluids) + . = ..() + if(!QDELETED(src) && fluids?.total_volume >= FLUID_SHALLOW && stat == DEAD) + var/turf/T = get_turf(src) + if(T) + T.add_to_reagents(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30))) + visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble. + qdel(src) + /mob/living/slime/get_hunger_factor() return (0.1 + 0.05 * is_adult) /mob/living/slime/get_thirst_factor() return 0 +/mob/living/slime/fluid_act(datum/reagents/fluids) + . = ..() + if(stat == DEAD && fluids?.total_volume && REAGENT_VOLUME(fluids, /decl/material/liquid/water) >= FLUID_SHALLOW) + fluids.add_reagent(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30))) + visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble. + qdel(src) + +/mob/living/slime/handle_living_non_stasis_processes() + . = ..() + if(!.) + return FALSE + set_stat(CONSCIOUS) + if(prob(30)) + adjustOxyLoss(-1, do_update_health = FALSE) + adjustToxLoss(-1, do_update_health = FALSE) + adjustFireLoss(-1, do_update_health = FALSE) + adjustCloneLoss(-1, do_update_health = FALSE) + adjustBruteLoss(-1) + /mob/living/slime/handle_nutrition_and_hydration() + . = ..() + if(feeding_on) + slime_feed() + ingested.metabolize() // Digest whatever we've got floating around in our goop. if(length(contents)) @@ -127,6 +133,9 @@ ..() +/mob/living/slime/get_satiated_nutrition() // Can't go above it + . = is_adult ? 1150 : 950 + /mob/living/slime/get_max_nutrition() // Can't go above it . = is_adult ? 1200 : 1000 diff --git a/mods/content/xenobiology/slime/say.dm b/mods/content/xenobiology/slime/say.dm index ce3ffc9fd3f..c248fa29b21 100644 --- a/mods/content/xenobiology/slime/say.dm +++ b/mods/content/xenobiology/slime/say.dm @@ -13,10 +13,10 @@ var/datum/ai/slime/slime_ai = ai if(istype(slime_ai) && (weakref(speaker) in slime_ai.observed_friends)) LAZYSET(slime_ai.speech_buffer, speaker, lowertext(html_decode(message))) - ..() + return ..() -/mob/living/slime/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") +/mob/living/slime/hear_radio(var/message, var/verb="says", var/decl/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="", var/vsource) var/datum/ai/slime/slime_ai = ai if(istype(slime_ai) && (weakref(speaker) in slime_ai.observed_friends)) LAZYSET(slime_ai.speech_buffer, speaker, lowertext(html_decode(message))) - ..() + return ..() diff --git a/mods/content/xenobiology/slime/slime_update_icon.dm b/mods/content/xenobiology/slime/slime_update_icon.dm index 4e99fe88ceb..b7e54e6d295 100644 --- a/mods/content/xenobiology/slime/slime_update_icon.dm +++ b/mods/content/xenobiology/slime/slime_update_icon.dm @@ -20,8 +20,7 @@ var/mutable_appearance/MA = new(AM) MA.layer = FLOAT_LAYER MA.plane = FLOAT_PLANE - // Revisit this on 514, alpha filters are behaving strangely on 513 - //MA.add_filter("slime_mask", 1, list("alpha", render_source="slime_\ref[src]", flags=MASK_INVERSE)) + MA.add_filter("slime_mask", 1, list(type = "alpha", render_source="slime_\ref[src]")) LAZYADD(new_underlays, MA) underlays = new_underlays diff --git a/mods/mobs/borers/datum/antagonist.dm b/mods/mobs/borers/datum/antagonist.dm index 2d2c31a1645..b8b0c7feb4d 100644 --- a/mods/mobs/borers/datum/antagonist.dm +++ b/mods/mobs/borers/datum/antagonist.dm @@ -61,4 +61,4 @@ spawn_announcement_sound = global.using_map.lifesign_spawn_sound /decl/special_role/borer/attempt_random_spawn() - if(config.aliens_allowed) ..() + if(get_config_value(/decl/config/toggle/aliens_allowed)) ..() diff --git a/mods/mobs/borers/mob/borer/borer.dm b/mods/mobs/borers/mob/borer/borer.dm index dc3ff9d818b..309dcddf63d 100644 --- a/mods/mobs/borers/mob/borer/borer.dm +++ b/mods/mobs/borers/mob/borer/borer.dm @@ -48,7 +48,7 @@ var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. /obj/item/holder/borer - origin_tech = "{'biotech':6}" + origin_tech = @'{"biotech":6}' /mob/living/simple_animal/borer/roundstart roundstart = TRUE @@ -81,63 +81,60 @@ /mob/living/simple_animal/borer/proc/set_borer_name() truename = "[borer_names[min(generation, borer_names.len)]] [random_id("borer[generation]", 1000, 9999)]" -/mob/living/simple_animal/borer/Life() +/mob/living/simple_animal/borer/handle_vision() + . = ..() + set_status(STAT_BLIND, host ? GET_STATUS(host, STAT_BLIND) : 0) + set_status(STAT_BLURRY, host ? GET_STATUS(host, STAT_BLURRY) : 0) +/mob/living/simple_animal/borer/handle_disabilities() + . = ..() sdisabilities = 0 if(host) - set_status(STAT_BLIND, GET_STATUS(host, STAT_BLIND)) - set_status(STAT_BLURRY, GET_STATUS(host, STAT_BLURRY)) if(host.sdisabilities & BLINDED) sdisabilities |= BLINDED if(host.sdisabilities & DEAFENED) sdisabilities |= DEAFENED - else - set_status(STAT_BLIND, 0) - set_status(STAT_BLURRY, 0) +/mob/living/simple_animal/borer/handle_living_non_stasis_processes() . = ..() if(!.) return FALSE - if(host) + if(!host || host.stat) + return - if(!stat && !host.stat) + if(prob(host.getBrainLoss()/20)) + INVOKE_ASYNC(host, TYPE_PROC_REF(/mob, say), "*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]") - if(host.reagents.has_reagent(/decl/material/liquid/nutriment/sugar)) - if(!docile) - if(controlling) - to_chat(host, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility.")) - else - to_chat(src, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility.")) - docile = 1 - else - if(docile) - if(controlling) - to_chat(host, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood.")) - else - to_chat(src, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood.")) - docile = 0 - - if(chemicals < 250 && host.nutrition >= (neutered ? 200 : 50)) - host.nutrition-- - chemicals++ + if(stat) + return + if(host.reagents.has_reagent(/decl/material/liquid/nutriment/sugar)) + if(!docile) if(controlling) - - if(neutered) - host.release_control() - return - - if(docile) - to_chat(host, SPAN_NOTICE("You are feeling far too docile to continue controlling your host...")) - host.release_control() - return - - if(prob(5)) - host.adjustBrainLoss(0.1) - - if(prob(host.getBrainLoss()/20)) - INVOKE_ASYNC(host, /mob/proc/say, "*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]") + to_chat(host, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility.")) + else + to_chat(src, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility.")) + docile = TRUE + else + if(docile) + if(controlling) + to_chat(host, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood.")) + else + to_chat(src, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood.")) + docile = FALSE + + if(chemicals < 250 && host.nutrition >= (neutered ? 200 : 50)) + host.nutrition-- + chemicals++ + if(controlling) + if(neutered || docile) + if(docile) + to_chat(host, SPAN_NOTICE("You are feeling far too docile to continue controlling your host...")) + host.release_control() + return + if(prob(5)) + host.adjustBrainLoss(0.1) /mob/living/simple_animal/borer/Stat() . = ..() @@ -209,7 +206,7 @@ if(istype(borer_hud)) for(var/obj/thing in borer_hud.borer_hud_elements) thing.color = COLOR_BORER_RED - addtimer(CALLBACK(src, /mob/living/simple_animal/borer/proc/reset_ui_callback), amt) + addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/simple_animal/borer, reset_ui_callback)), amt) #undef COLOR_BORER_RED /mob/living/simple_animal/borer/proc/leave_host() diff --git a/mods/mobs/borers/mob/borer/borer_hud.dm b/mods/mobs/borers/mob/borer/borer_hud.dm index 301d96256e0..9144f017932 100644 --- a/mods/mobs/borers/mob/borer/borer_hud.dm +++ b/mods/mobs/borers/mob/borer/borer_hud.dm @@ -139,7 +139,7 @@ return to_chat(worm, SPAN_NOTICE("You squirt a measure of [chem] from your reservoirs into \the [worm.host]'s bloodstream.")) - worm.host.reagents.add_reagent(worm.chemical_types[chem], 10) + worm.host.add_to_reagents(worm.chemical_types[chem], 10) worm.chemicals -= 50 return TRUE diff --git a/mods/mobs/borers/mob/organ.dm b/mods/mobs/borers/mob/organ.dm index 579c94bc64b..c8f9a3c34bd 100644 --- a/mods/mobs/borers/mob/organ.dm +++ b/mods/mobs/borers/mob/organ.dm @@ -14,7 +14,7 @@ for(var/chem_name in chemical_types) var/chem = chemical_types[chem_name] if(REAGENT_VOLUME(owner.reagents, chem) < 3) - owner.reagents.add_reagent(chem, 5) + owner.add_to_reagents(chem, 5) // They're also super gross and ooze ichor. if(prob(5)) diff --git a/mods/mobs/dionaea/icons/lunchbox_nymph.dmi b/mods/mobs/dionaea/icons/lunchbox_nymph.dmi new file mode 100644 index 00000000000..500f939b9eb Binary files /dev/null and b/mods/mobs/dionaea/icons/lunchbox_nymph.dmi differ diff --git a/mods/mobs/dionaea/items/lunchbox.dm b/mods/mobs/dionaea/items/lunchbox.dm index b1e906a69c3..7be30a9b699 100644 --- a/mods/mobs/dionaea/items/lunchbox.dm +++ b/mods/mobs/dionaea/items/lunchbox.dm @@ -1,7 +1,6 @@ /obj/item/storage/lunchbox/nymph name = "\improper Diona nymph lunchbox" - icon_state = "lunchbox_dionanymph" - item_state = "toolbox_yellow" + icon = 'mods/mobs/dionaea/icons/lunchbox_nymph.dmi' desc = "A little lunchbox. This one is an adorable Diona nymph on the side!" /obj/item/storage/lunchbox/nymph/filled diff --git a/mods/mobs/dionaea/items/roast.dm b/mods/mobs/dionaea/items/roast.dm index 3df2242a39a..6d77f44b5ba 100644 --- a/mods/mobs/dionaea/items/roast.dm +++ b/mods/mobs/dionaea/items/roast.dm @@ -2,13 +2,13 @@ name = "roast diona" desc = "It's like an enormous, leathery carrot. With an eye." icon_state = "dionaroast" - trash = /obj/item/trash/plate + plate = /obj/item/plate filling_color = "#75754b" - center_of_mass = @"{'x':16,'y':7}" + center_of_mass = @'{"x":16,"y":7}' nutriment_desc = list("a chorus of flavor" = 6) nutriment_amt = 6 bitesize = 2 /obj/item/chems/food/dionaroast/populate_reagents() - reagents.add_reagent(/decl/material/solid/metal/radium, 2) + add_to_reagents(/decl/material/solid/metal/radium, 2) . = ..() diff --git a/mods/mobs/dionaea/mob/nymph_attacks.dm b/mods/mobs/dionaea/mob/nymph_attacks.dm index ec4cbbfdcc6..0e82f651059 100644 --- a/mods/mobs/dionaea/mob/nymph_attacks.dm +++ b/mods/mobs/dionaea/mob/nymph_attacks.dm @@ -54,7 +54,7 @@ if(tray.dead) if(tray.remove_dead(src, silent = TRUE)) - reagents.add_reagent(/decl/material/liquid/nutriment/glucose, rand(10,20)) + add_to_reagents(/decl/material/liquid/nutriment/glucose, rand(10,20)) visible_message(SPAN_NOTICE("\The [src] chews up the dead plant, clearing \the [tray] out."), SPAN_NOTICE("You devour the dead plant, clearing \the [tray].")) return TRUE return FALSE @@ -66,7 +66,7 @@ return FALSE if(tray.weedlevel || tray.pestlevel) - reagents.add_reagent(/decl/material/liquid/nutriment/glucose, (tray.weedlevel + tray.pestlevel)) + add_to_reagents(/decl/material/liquid/nutriment/glucose, (tray.weedlevel + tray.pestlevel)) tray.weedlevel = 0 tray.pestlevel = 0 visible_message(SPAN_NOTICE("\The [src] begins rooting through \the [tray], ripping out pests and weeds, and eating them noisily."),SPAN_NOTICE("You begin rooting through \the [tray], ripping out pests and weeds, and eating them noisily.")) diff --git a/mods/mobs/dionaea/mob/nymph_holder.dm b/mods/mobs/dionaea/mob/nymph_holder.dm index 0ac27fa04c0..1a06eb0d14b 100644 --- a/mods/mobs/dionaea/mob/nymph_holder.dm +++ b/mods/mobs/dionaea/mob/nymph_holder.dm @@ -1,5 +1,5 @@ /obj/item/holder/diona - origin_tech = "{'magnets':3,'biotech':5}" + origin_tech = @'{"magnets":3,"biotech":5}' slot_flags = SLOT_HEAD | SLOT_OVER_BODY | SLOT_HOLSTER armor = list( ARMOR_BIO = ARMOR_BIO_RESISTANT, diff --git a/mods/species/ascent/datum/species.dm b/mods/species/ascent/datum/species.dm index 42fe810802c..79710a9c0a9 100644 --- a/mods/species/ascent/datum/species.dm +++ b/mods/species/ascent/datum/species.dm @@ -29,7 +29,7 @@ name_plural = "Kharmaan Alates" show_ssd = "quiescent" - base_prosthetics_model = null + base_external_prosthetics_model = null available_bodytypes = list(/decl/bodytype/crystalline/mantid/alate) description = "When human surveyors finally arrived at the outer reaches of explored space, they hoped to find \ diff --git a/mods/species/ascent/effects/razorweb.dm b/mods/species/ascent/effects/razorweb.dm index 4212504c734..0908b3f816d 100644 --- a/mods/species/ascent/effects/razorweb.dm +++ b/mods/species/ascent/effects/razorweb.dm @@ -57,7 +57,7 @@ return INITIALIZE_HINT_QDEL if(decays) - addtimer(CALLBACK(src, /obj/effect/razorweb/proc/decay), 15 MINUTES) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/effect/razorweb, decay)), 15 MINUTES) web = image(icon = icon, icon_state = "razorweb") gleam = emissive_overlay(icon = icon, icon_state = "razorweb-gleam") diff --git a/mods/species/ascent/icons/species/body/gyne/damage_overlays.dmi b/mods/species/ascent/icons/species/body/gyne/damage_overlays.dmi index e90caba8959..4b50afcc0c4 100644 Binary files a/mods/species/ascent/icons/species/body/gyne/damage_overlays.dmi and b/mods/species/ascent/icons/species/body/gyne/damage_overlays.dmi differ diff --git a/mods/species/ascent/items/tools.dm b/mods/species/ascent/items/tools.dm index 5b1e5a13e36..412d62e1d8f 100644 --- a/mods/species/ascent/items/tools.dm +++ b/mods/species/ascent/items/tools.dm @@ -50,7 +50,7 @@ MANTIDIFY(/obj/item/tank/jetpack/carbondioxide, "maneuvering pack", "pr bitesize = 10 /obj/item/chems/food/hydration/populate_reagents() - reagents.add_reagent(/decl/material/liquid/water, 10) + add_to_reagents(/decl/material/liquid/water, 10) . = ..() /obj/item/storage/box/water/ascent diff --git a/mods/species/ascent/machines/fabricator.dm b/mods/species/ascent/machines/fabricator.dm index 61e77d244b2..917180f0848 100644 --- a/mods/species/ascent/machines/fabricator.dm +++ b/mods/species/ascent/machines/fabricator.dm @@ -13,7 +13,7 @@ name = "circuitboard (ascent nanofabricator)" build_path = /obj/machinery/fabricator/ascent board_type = "machine" - origin_tech = "{'engineering':2,'programming':2}" + origin_tech = @'{"engineering":2,"programming":2}' req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1) diff --git a/mods/species/ascent/machines/magnetotron.dm b/mods/species/ascent/machines/magnetotron.dm index 8c49a67d233..dc12dbb0ac6 100644 --- a/mods/species/ascent/machines/magnetotron.dm +++ b/mods/species/ascent/machines/magnetotron.dm @@ -66,7 +66,7 @@ name = "circuitboard (Ascent magnetotron)" build_path = /obj/machinery/ascent_magnetotron board_type = "machine" - origin_tech = "{'engineering':2,'magnets':4}" + origin_tech = @'{"engineering":2,"magnets":4}' req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1 diff --git a/mods/species/ascent/machines/ship_machines.dm b/mods/species/ascent/machines/ship_machines.dm index 9200cea9259..e053026c1d2 100644 --- a/mods/species/ascent/machines/ship_machines.dm +++ b/mods/species/ascent/machines/ship_machines.dm @@ -53,10 +53,10 @@ MANTIDIFY(/obj/machinery/door/airlock/external/bolted, "mantid airlock", "door") MANTIDIFY(/obj/item/chems/chem_disp_cartridge, "canister", "chemical storage") /obj/item/chems/chem_disp_cartridge/ascent/crystal/populate_reagents() - reagents.add_reagent(/decl/material/liquid/crystal_agent, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/crystal_agent, reagents.maximum_volume) /obj/item/chems/chem_disp_cartridge/ascent/bromide/populate_reagents() - reagents.add_reagent(/decl/material/liquid/bromide, reagents.maximum_volume) + add_to_reagents(/decl/material/liquid/bromide, reagents.maximum_volume) /obj/machinery/sleeper/ascent name = "mantid sleeper" diff --git a/mods/species/ascent/mobs/bodyparts.dm b/mods/species/ascent/mobs/bodyparts.dm index 28a05afbeca..3b04f648e38 100644 --- a/mods/species/ascent/mobs/bodyparts.dm +++ b/mods/species/ascent/mobs/bodyparts.dm @@ -42,7 +42,7 @@ owner.visible_message(SPAN_WARNING("\The [owner] separates their jaws and begins to weave a web of crystalline filaments...")) cooldown = TRUE refresh_action_button() - addtimer(CALLBACK(src, .proc/reset_cooldown), web_weave_time) + addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), web_weave_time) if(do_after(owner, web_weave_time) && length(existing_webs) < max_webs) playsound(user, 'mods/species/ascent/sounds/razorweb.ogg', 70, 0) owner.visible_message(SPAN_DANGER("\The [owner] completes a razorweb!")) @@ -81,7 +81,7 @@ owner.throw_mode_on() cooldown = TRUE refresh_action_button() - addtimer(CALLBACK(src, .proc/reset_cooldown), cooldown_time) + addtimer(CALLBACK(src, PROC_REF(reset_cooldown)), cooldown_time) else qdel(web) diff --git a/mods/species/ascent/mobs/insectoid_egg.dm b/mods/species/ascent/mobs/insectoid_egg.dm index 71fc85fb137..6076c3dff4b 100644 --- a/mods/species/ascent/mobs/insectoid_egg.dm +++ b/mods/species/ascent/mobs/insectoid_egg.dm @@ -102,7 +102,7 @@ var/global/default_gyne hatching = TRUE update_icon() visible_message(SPAN_NOTICE("\icon[src] \The [src] trembles and cracks as it begins to hatch.")) - addtimer(CALLBACK(src, .proc/finish_hatching), 2.5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(finish_hatching)), 2.5 SECONDS) /obj/structure/insectoid_egg/proc/finish_hatching() diff --git a/mods/species/ascent/mobs/nymph/nymph_holder.dm b/mods/species/ascent/mobs/nymph/nymph_holder.dm index 4dbbc36a85a..ec430c06f8e 100644 --- a/mods/species/ascent/mobs/nymph/nymph_holder.dm +++ b/mods/species/ascent/mobs/nymph/nymph_holder.dm @@ -1,5 +1,5 @@ /obj/item/holder/ascent_nymph - origin_tech = "{'magnets':3,'biotech':5}" + origin_tech = @'{"magnets":3,"biotech":5}' slot_flags = SLOT_HEAD | SLOT_OVER_BODY | SLOT_HOLSTER armor = list( ARMOR_BIO = ARMOR_BIO_RESISTANT diff --git a/mods/species/ascent/mobs/nymph/nymph_life.dm b/mods/species/ascent/mobs/nymph/nymph_life.dm index 3eba226e5b5..cd1a17f31af 100644 --- a/mods/species/ascent/mobs/nymph/nymph_life.dm +++ b/mods/species/ascent/mobs/nymph/nymph_life.dm @@ -1,9 +1,28 @@ -/mob/living/carbon/alien/ascent_nymph/Life() +/mob/living/carbon/alien/ascent_nymph/handle_regular_hud_updates() . = ..() - if(stat == DEAD) + if(!.) return + var/datum/hud/ascent_nymph/nymph_hud = hud_used + if(!istype(nymph_hud)) + return + if(nymph_hud.food) + switch(nutrition) + if(450 to INFINITY) nymph_hud.food.icon_state = "nutrition0" + if(350 to 450) nymph_hud.food.icon_state = "nutrition1" + if(250 to 350) nymph_hud.food.icon_state = "nutrition2" + if(150 to 250) nymph_hud.food.icon_state = "nutrition3" + else nymph_hud.food.icon_state = "nutrition4" + if(nymph_hud.drink) + switch(hydration) + if(450 to INFINITY) nymph_hud.drink.icon_state = "hydration0" + if(350 to 450) nymph_hud.drink.icon_state = "hydration1" + if(250 to 350) nymph_hud.drink.icon_state = "hydration2" + if(150 to 250) nymph_hud.drink.icon_state = "hydration3" + else nymph_hud.drink.icon_state = "hydration4" +/mob/living/carbon/alien/ascent_nymph/handle_nutrition_and_hydration() + . = ..() // Generate some crystals over time. if(nutrition >= 300 && crystal_reserve < ANYMPH_MAX_CRYSTALS) crystal_reserve = min(ANYMPH_MAX_CRYSTALS, crystal_reserve + 15) @@ -16,32 +35,9 @@ adjust_nutrition(DEFAULT_HUNGER_FACTOR * -2) else adjust_nutrition(DEFAULT_HUNGER_FACTOR * -1) - if(hydration > 0) adjust_hydration(DEFAULT_THIRST_FACTOR * -1) - update_nymph_hud() - -/mob/living/carbon/alien/ascent_nymph/proc/update_nymph_hud() - // Update the HUD. - var/datum/hud/ascent_nymph/nymph_hud = hud_used - if(istype(nymph_hud)) - if(nymph_hud.food) - switch(nutrition) - if(450 to INFINITY) nymph_hud.food.icon_state = "nutrition0" - if(350 to 450) nymph_hud.food.icon_state = "nutrition1" - if(250 to 350) nymph_hud.food.icon_state = "nutrition2" - if(150 to 250) nymph_hud.food.icon_state = "nutrition3" - else nymph_hud.food.icon_state = "nutrition4" - - if(nymph_hud.drink) - switch(hydration) - if(450 to INFINITY) nymph_hud.drink.icon_state = "hydration0" - if(350 to 450) nymph_hud.drink.icon_state = "hydration1" - if(250 to 350) nymph_hud.drink.icon_state = "hydration2" - if(150 to 250) nymph_hud.drink.icon_state = "hydration3" - else nymph_hud.drink.icon_state = "hydration4" - /mob/living/carbon/alien/ascent_nymph/Stat() . = ..() if(client && statpanel("Status")) diff --git a/mods/species/bayliens/adherent/_adherent.dm b/mods/species/bayliens/adherent/_adherent.dm index 23d88d9ad20..a5b9572567d 100644 --- a/mods/species/bayliens/adherent/_adherent.dm +++ b/mods/species/bayliens/adherent/_adherent.dm @@ -6,5 +6,6 @@ #define BP_JETS "maneuvering jets" #define BP_COOLING_FINS "cooling fins" -/mob/living/carbon/human/adherent/Initialize() - . = ..(species_name = SPECIES_ADHERENT) \ No newline at end of file +/mob/living/carbon/human/adherent/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) + species_name = SPECIES_ADHERENT + . = ..() \ No newline at end of file diff --git a/mods/species/bayliens/adherent/datum/species.dm b/mods/species/bayliens/adherent/datum/species.dm index a0f8b934bd1..eb671cfa0c0 100644 --- a/mods/species/bayliens/adherent/datum/species.dm +++ b/mods/species/bayliens/adherent/datum/species.dm @@ -13,7 +13,7 @@ /decl/species/adherent name = SPECIES_ADHERENT name_plural = "Adherents" - base_prosthetics_model = null + base_external_prosthetics_model = null description = "The Vigil is a loose collection of floating squid-like machines made of a crystalline composite. \ They once served their creators faithfully, but were left orphaned by a stellar apocalypse." @@ -96,7 +96,7 @@ float_is_usable = TRUE break if(float_is_usable) - if(istype(landing, /turf/simulated/open)) + if(landing.is_open()) H.visible_message("\The [H] descends from \the [landing].", "You descend regally.") else H.visible_message("\The [H] floats gracefully down from \the [landing].", "You land gently on \the [landing].") diff --git a/mods/species/bayliens/adherent/icons/damage_overlay.dmi b/mods/species/bayliens/adherent/icons/damage_overlay.dmi index c42c6420e53..a6b7ad243cd 100644 Binary files a/mods/species/bayliens/adherent/icons/damage_overlay.dmi and b/mods/species/bayliens/adherent/icons/damage_overlay.dmi differ diff --git a/mods/species/bayliens/adherent/organs/organs_internal.dm b/mods/species/bayliens/adherent/organs/organs_internal.dm index 9c2dea69181..5f7bbe5eddd 100644 --- a/mods/species/bayliens/adherent/organs/organs_internal.dm +++ b/mods/species/bayliens/adherent/organs/organs_internal.dm @@ -120,7 +120,7 @@ /obj/item/organ/internal/eyes/adherent/Initialize() . = ..() - verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color + verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color_verb /obj/item/organ/internal/cell/adherent name = "piezoelectric core" diff --git a/mods/species/bayliens/skrell/_skrell.dm b/mods/species/bayliens/skrell/_skrell.dm index 9b9ff3ce427..a1fc8f067ff 100644 --- a/mods/species/bayliens/skrell/_skrell.dm +++ b/mods/species/bayliens/skrell/_skrell.dm @@ -1,5 +1,6 @@ #define SPECIES_SKRELL "Skrell" #define BODYTYPE_SKRELL "skrellian body" -/mob/living/carbon/human/skrell/Initialize() - . = ..(species_name = SPECIES_SKRELL) \ No newline at end of file +/mob/living/carbon/human/skrell/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) + species_name = SPECIES_SKRELL + . = ..() \ No newline at end of file diff --git a/mods/species/bayliens/skrell/datum/skrell_meat.dm b/mods/species/bayliens/skrell/datum/skrell_meat.dm index b5813d6e84a..fb83b94a421 100644 --- a/mods/species/bayliens/skrell/datum/skrell_meat.dm +++ b/mods/species/bayliens/skrell/datum/skrell_meat.dm @@ -1,3 +1,3 @@ /obj/item/chems/food/fish/octopus/skrell/populate_reagents() . = ..() - reagents.add_reagent(/decl/material/liquid/hallucinogenics, 5) + add_to_reagents(/decl/material/liquid/hallucinogenics, 5) diff --git a/mods/species/bayliens/skrell/datum/species.dm b/mods/species/bayliens/skrell/datum/species.dm index 807e5e7d9ac..9885bf6b98d 100644 --- a/mods/species/bayliens/skrell/datum/species.dm +++ b/mods/species/bayliens/skrell/datum/species.dm @@ -123,10 +123,10 @@ bloodDNA = list(blood_data["blood_DNA"] = blood_data["blood_type"]) else bloodDNA = list() - T.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, H.dir, 0, H.skin_colour + "25") // Coming (8c is the alpha value) + T.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, H.dir, 0, H.get_skin_colour() + "25") // Coming (8c is the alpha value) if(istype(old_loc, /turf/simulated)) var/turf/simulated/old_turf = old_loc - old_turf.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, 0, H.dir, H.skin_colour + "25") // Going (8c is the alpha value) + old_turf.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints, bloodDNA, 0, H.dir, H.get_skin_colour() + "25") // Going (8c is the alpha value) /decl/species/skrell/check_background() return TRUE diff --git a/mods/species/bayliens/skrell/icons/body/hair.dmi b/mods/species/bayliens/skrell/icons/body/hair.dmi index f3d3cf7574e..9dad6dda88a 100644 Binary files a/mods/species/bayliens/skrell/icons/body/hair.dmi and b/mods/species/bayliens/skrell/icons/body/hair.dmi differ diff --git a/mods/species/bayliens/tajaran/_tajaran.dm b/mods/species/bayliens/tajaran/_tajaran.dm index 37580ae4404..78e6c821d4b 100644 --- a/mods/species/bayliens/tajaran/_tajaran.dm +++ b/mods/species/bayliens/tajaran/_tajaran.dm @@ -8,5 +8,5 @@ if(bodytype_equip_flags & BODY_FLAG_EXCLUDE) bodytype_equip_flags |= BODY_FLAG_FELINE -/mob/living/carbon/human/tajaran/Initialize() +/mob/living/carbon/human/tajaran/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) . = ..(species_name = SPECIES_TAJARA) diff --git a/mods/species/bayliens/tajaran/datum/accessory.dm b/mods/species/bayliens/tajaran/datum/accessory.dm index b85b331ddbc..d9f0ab3d3f6 100644 --- a/mods/species/bayliens/tajaran/datum/accessory.dm +++ b/mods/species/bayliens/tajaran/datum/accessory.dm @@ -4,7 +4,7 @@ icon_state = "hair_rattail" species_allowed = list(SPECIES_TAJARA) icon = 'mods/species/bayliens/tajaran/icons/hair.dmi' - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_hair_taj_rattail" /decl/sprite_accessory/hair/taj/straight @@ -132,7 +132,7 @@ icon_state = "facial_sideburns" species_allowed = list(SPECIES_TAJARA) icon = 'mods/species/bayliens/tajaran/icons/facial.dmi' - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_fhair_taj_sideburns" /decl/sprite_accessory/facial_hair/taj/mutton @@ -166,7 +166,7 @@ icon = 'mods/species/bayliens/tajaran/icons/markings.dmi' species_allowed = list(SPECIES_TAJARA) body_parts = list(BP_HEAD) - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_marking_taj_nose" /decl/sprite_accessory/marking/tajaran/ears diff --git a/mods/species/bayliens/tajaran/datum/species.dm b/mods/species/bayliens/tajaran/datum/species.dm index 3a45429e835..8db767a029f 100644 --- a/mods/species/bayliens/tajaran/datum/species.dm +++ b/mods/species/bayliens/tajaran/datum/species.dm @@ -14,7 +14,7 @@ /decl/species/tajaran name = SPECIES_TAJARA name_plural = "Tajaran" - base_prosthetics_model = null + base_external_prosthetics_model = null description = "A small mammalian carnivore. If you are reading this, you are probably a Tajaran." hidden_from_codex = FALSE @@ -82,4 +82,4 @@ autohiss_exempt = list(LANGUAGE_TAJARA) /decl/species/tajaran/handle_additional_hair_loss(var/mob/living/carbon/human/H, var/defer_body_update = TRUE) - . = H && H.change_skin_color(rgb(189, 171, 143)) + . = H?.set_skin_colour(rgb(189, 171, 143)) diff --git a/mods/species/bayliens/tajaran/icons/facial.dmi b/mods/species/bayliens/tajaran/icons/facial.dmi index 40fc99054b3..befd9dc68b4 100644 Binary files a/mods/species/bayliens/tajaran/icons/facial.dmi and b/mods/species/bayliens/tajaran/icons/facial.dmi differ diff --git a/mods/species/bayliens/tajaran/icons/hair.dmi b/mods/species/bayliens/tajaran/icons/hair.dmi index 240dbf58064..88380247713 100644 Binary files a/mods/species/bayliens/tajaran/icons/hair.dmi and b/mods/species/bayliens/tajaran/icons/hair.dmi differ diff --git a/mods/species/bayliens/unathi/_lizard.dm b/mods/species/bayliens/unathi/_lizard.dm index e3b372fed07..fdbd758e8af 100644 --- a/mods/species/bayliens/unathi/_lizard.dm +++ b/mods/species/bayliens/unathi/_lizard.dm @@ -1,5 +1,6 @@ #define SPECIES_LIZARD "Unathi" #define LANGUAGE_LIZARD "Sinta'unathi" -/mob/living/carbon/human/lizard/Initialize() - . = ..(species_name = SPECIES_LIZARD) +/mob/living/carbon/human/lizard/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) + species_name = SPECIES_LIZARD + . = ..() diff --git a/mods/species/bayliens/unathi/datum/sprite_accessory.dm b/mods/species/bayliens/unathi/datum/sprite_accessory.dm index 4c90af7d4f8..f8a71288a66 100644 --- a/mods/species/bayliens/unathi/datum/sprite_accessory.dm +++ b/mods/species/bayliens/unathi/datum/sprite_accessory.dm @@ -3,7 +3,7 @@ icon = 'mods/species/bayliens/unathi/icons/hair.dmi' icon_state = "horns" species_allowed = list(SPECIES_LIZARD) - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY flags = VERY_SHORT uid = "acc_hair_una_horns" @@ -90,10 +90,10 @@ // FACIAL /decl/sprite_accessory/facial_hair/lizard name = "Lizard Horn Chin" - icon = 'mods/species/bayliens/unathi/icons/facial_hair.dmi' + icon = 'mods/species/bayliens/unathi/icons/facial.dmi' icon_state = "facial_chinhorns" species_allowed = list(SPECIES_LIZARD) - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_fhair_una_chinhorns" /decl/sprite_accessory/facial_hair/lizard/hornadorns diff --git a/mods/species/bayliens/unathi/icons/facial_hair.dmi b/mods/species/bayliens/unathi/icons/facial.dmi similarity index 62% rename from mods/species/bayliens/unathi/icons/facial_hair.dmi rename to mods/species/bayliens/unathi/icons/facial.dmi index b992eb874f3..11ac6ca7926 100644 Binary files a/mods/species/bayliens/unathi/icons/facial_hair.dmi and b/mods/species/bayliens/unathi/icons/facial.dmi differ diff --git a/mods/species/bayliens/unathi/icons/hair.dmi b/mods/species/bayliens/unathi/icons/hair.dmi index 6eac2a1c305..5422f582410 100644 Binary files a/mods/species/bayliens/unathi/icons/hair.dmi and b/mods/species/bayliens/unathi/icons/hair.dmi differ diff --git a/mods/species/bayliens/unathi/organs/organs_internal.dm b/mods/species/bayliens/unathi/organs/organs_internal.dm index 739fff2d887..1edd08ffc19 100644 --- a/mods/species/bayliens/unathi/organs/organs_internal.dm +++ b/mods/species/bayliens/unathi/organs/organs_internal.dm @@ -4,4 +4,4 @@ icon = 'mods/species/bayliens/unathi/icons/organs.dmi' /obj/item/organ/internal/brain/lizard - can_use_mmi = FALSE + can_use_brain_interface = FALSE diff --git a/mods/species/neoavians/datum/accessory.dm b/mods/species/neoavians/datum/accessory.dm index 7ae58e8078d..1ee748abae7 100644 --- a/mods/species/neoavians/datum/accessory.dm +++ b/mods/species/neoavians/datum/accessory.dm @@ -4,7 +4,7 @@ icon_state = "avian_default" icon = 'mods/species/neoavians/icons/hair.dmi' species_allowed = list(SPECIES_AVIAN) - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_hair_avian_plumage" /decl/sprite_accessory/hair/avian/mohawk @@ -45,7 +45,7 @@ /decl/sprite_accessory/hair/avian/alt name = "Avian Plumage Alt" icon_state = "avian_default_alt" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_hair_avian_plumage_alt" /decl/sprite_accessory/hair/avian/alt/ears @@ -120,7 +120,7 @@ body_parts = list(BP_HEAD) icon = 'mods/species/neoavians/icons/markings.dmi' species_allowed = list(SPECIES_AVIAN) - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_marking_avian_beak" /decl/sprite_accessory/marking/avian/avian @@ -142,23 +142,23 @@ /decl/sprite_accessory/marking/avian/additive name = "Beak, Additive (Head)" icon_state = "beak-add" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_marking_avian_beak_alt" /decl/sprite_accessory/marking/avian/resomi name = "Raptor Ears, Additive (Head)" icon_state = "ears-add" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_marking_avian_raptorears_alt" /decl/sprite_accessory/marking/avian/wing_feathers/additive name = "Wing Feathers, Additive (Left)" icon_state = "wing_feathers-add" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_marking_avian_wingfeathers_left_alt" /decl/sprite_accessory/marking/avian/wing_feathers/right/additive name = "Wing Feathers, Additive (Right)" icon_state = "wing_feathers-add" - blend = ICON_ADD + color_blend = ICON_ADD uid = "acc_marking_avian_wingfeathers_right_alt" diff --git a/mods/species/neoavians/datum/species.dm b/mods/species/neoavians/datum/species.dm index 5c474d1da45..1a4e3f352ad 100644 --- a/mods/species/neoavians/datum/species.dm +++ b/mods/species/neoavians/datum/species.dm @@ -17,7 +17,7 @@ description = "Avian species, largely crows, magpies and other corvids, were among the first sophonts uplifted to aid in colonizing Mars. \ These days they are more commonly found pursuing their own careers and goals on the fringes of human space or around their adopted homeworld \ of Hyperion. Neo-avian naming conventions tend to be a chosen name followed by the species of the person, followed by the location they were hatched." - base_prosthetics_model = null + base_external_prosthetics_model = null snow_slowdown_mod = -1 @@ -66,7 +66,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/avian, slot_shoes_str) /decl/species/neoavian/get_holder_color(var/mob/living/carbon/human/H) - return H.skin_colour + return H.get_skin_colour() /decl/hierarchy/outfit/job/generic/assistant/avian name = "Job - Avian Assistant" diff --git a/mods/species/neoavians/icons/hair.dmi b/mods/species/neoavians/icons/hair.dmi index e213c5561e5..df5a5f7010a 100644 Binary files a/mods/species/neoavians/icons/hair.dmi and b/mods/species/neoavians/icons/hair.dmi differ diff --git a/mods/species/serpentid/mobs/bodyparts_serpentid.dm b/mods/species/serpentid/mobs/bodyparts_serpentid.dm index 40c4b1c7eab..26b976e41ab 100644 --- a/mods/species/serpentid/mobs/bodyparts_serpentid.dm +++ b/mods/species/serpentid/mobs/bodyparts_serpentid.dm @@ -7,16 +7,6 @@ /obj/item/organ/internal/eyes/insectoid/serpentid/get_innate_flash_protection() return override_flash_protection -/obj/item/organ/internal/eyes/insectoid/serpentid/get_special_overlay() - var/icon/I = get_onhead_icon() - if(I) - var/image/eye_overlay = image(I) - if(owner && owner.is_cloaked()) - eye_overlay.alpha = 100 - if(eyes_shielded) - eye_overlay.color = "#aaaaaa" - return eye_overlay - /obj/item/organ/internal/eyes/insectoid/serpentid/additional_flash_effects(var/intensity) if(!eyes_shielded) take_internal_damage(max(0, 4 * (intensity))) @@ -42,7 +32,7 @@ else to_chat(owner, "Your protective lenses retract out of the way.") override_flash_protection = FLASH_PROTECTION_VULNERABLE - addtimer(CALLBACK(src, .proc/remove_shield), 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(remove_shield)), 1 SECONDS) owner.update_icon() refresh_action_button() @@ -158,18 +148,26 @@ playsound(owner.loc, 'sound/effects/angrybug.ogg', 60, 0) owner.skin_state = SKIN_THREAT owner.update_skin() - addtimer(CALLBACK(owner, /mob/living/carbon/human/proc/reset_skin), 10 SECONDS, TIMER_UNIQUE) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob/living/carbon/human, reset_skin)), 10 SECONDS, TIMER_UNIQUE) else if(owner.skin_state == SKIN_THREAT) owner.reset_skin() /obj/item/organ/external/head/insectoid/serpentid name = "head" -/obj/item/organ/external/head/insectoid/serpentid/get_eye_overlay() - // todo: maybe this should use its own bodytype instead of mob root bodytype? - var/obj/item/organ/internal/eyes/eyes = owner.get_organ((owner.get_bodytype()?.vision_organ || BP_EYES), /obj/item/organ/internal/eyes) - if(eyes) - return eyes.get_special_overlay() +/obj/item/organ/external/head/insectoid/serpentid/get_organ_eyes_overlay() + var/obj/item/organ/internal/eyes/eyes = get_eyes_organ() + var/icon/eyes_icon = eyes?.get_onhead_icon() + if(!eyes_icon) + return + var/image/eye_overlay = image(eyes_icon) + if(owner && owner.is_cloaked()) + eye_overlay.alpha = 100 + if(istype(eyes, /obj/item/organ/internal/eyes/insectoid/serpentid)) + var/obj/item/organ/internal/eyes/insectoid/serpentid/snake_eyes = eyes + if(snake_eyes.eyes_shielded) + eye_overlay.color = "#aaaaaa" + return eye_overlay /obj/item/organ/external/groin/insectoid/serpentid name = "abdomen" diff --git a/mods/species/utility_frames/_utility_frames.dme b/mods/species/utility_frames/_utility_frames.dme index 776d098bb5d..728a6e05d86 100644 --- a/mods/species/utility_frames/_utility_frames.dme +++ b/mods/species/utility_frames/_utility_frames.dme @@ -1,5 +1,6 @@ #ifndef MODPACK_UTILITY_FRAMES #define MODPACK_UTILITY_FRAMES +#include "../../content/shackles/_shackles.dme" #include "_utility_frames.dm" #include "species.dm" #include "species_bodytypes.dm" diff --git a/mods/species/utility_frames/markings.dm b/mods/species/utility_frames/markings.dm index 24b8a68b72d..ade0c186443 100644 --- a/mods/species/utility_frames/markings.dm +++ b/mods/species/utility_frames/markings.dm @@ -4,7 +4,7 @@ body_parts = list(BP_CHEST) species_allowed = list(SPECIES_FRAME) icon = 'mods/species/utility_frames/icons/markings.dmi' - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_marking_frame_stripe" /decl/sprite_accessory/marking/frame/head_stripe diff --git a/mods/species/utility_frames/species.dm b/mods/species/utility_frames/species.dm index 9e10f61d368..4ea0b407028 100644 --- a/mods/species/utility_frames/species.dm +++ b/mods/species/utility_frames/species.dm @@ -14,8 +14,7 @@ name_plural = "Utility Frames" description = "Simple AI-driven robots are used for many menial or repetitive tasks in human space." cyborg_noun = null - base_prosthetics_model = null - + base_external_prosthetics_model = null blood_types = list(/decl/blood_type/coolant) available_bodytypes = list(/decl/bodytype/prosthetic/utility_frame) diff --git a/mods/species/utility_frames/species_bodytypes.dm b/mods/species/utility_frames/species_bodytypes.dm index c78b55cbde8..c5dc14b5025 100644 --- a/mods/species/utility_frames/species_bodytypes.dm +++ b/mods/species/utility_frames/species_bodytypes.dm @@ -12,14 +12,14 @@ base_eye_color = "#00ccff" material = /decl/material/solid/metal/steel vital_organs = list( - BP_POSIBRAIN, + BP_BRAIN, BP_CELL ) override_limb_types = list(BP_HEAD = /obj/item/organ/external/head/utility_frame) has_organ = list( - BP_POSIBRAIN = /obj/item/organ/internal/posibrain, - BP_EYES = /obj/item/organ/internal/eyes, - BP_CELL = /obj/item/organ/internal/cell + BP_BRAIN = /obj/item/organ/internal/brain/robotic, + BP_EYES = /obj/item/organ/internal/eyes, + BP_CELL = /obj/item/organ/internal/cell ) base_markings = list( /decl/sprite_accessory/marking/frame/plating = "#8888cc", diff --git a/mods/species/vox/_vox.dm b/mods/species/vox/_vox.dm index a36a5e9951b..9562251d79d 100644 --- a/mods/species/vox/_vox.dm +++ b/mods/species/vox/_vox.dm @@ -10,10 +10,11 @@ credits_crew_names = list("THE VOX") credits_topics = list("VOX RITUAL DUELS", "NECK MARKINGS", "ANCIENT SUPERCOMPUTERS") -/mob/living/carbon/human/vox/Initialize() - h_style = /decl/sprite_accessory/hair/vox/short - hair_colour = COLOR_BEASTY_BROWN - . = ..(species_name = SPECIES_VOX) +/mob/living/carbon/human/vox/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) + set_hairstyle(/decl/sprite_accessory/hair/vox/short, skip_update = TRUE) + set_hair_colour(COLOR_BEASTY_BROWN, skip_update = TRUE) + species_name = SPECIES_VOX + . = ..() /datum/follow_holder/voxstack sort_order = 14 diff --git a/mods/species/vox/datum/accessories.dm b/mods/species/vox/datum/accessories.dm index b8fb567bbf6..5213b4d8612 100644 --- a/mods/species/vox/datum/accessories.dm +++ b/mods/species/vox/datum/accessories.dm @@ -70,7 +70,7 @@ body_flags_allowed = BODY_FLAG_VOX bodytype_categories_allowed = list(BODYTYPE_VOX) icon = 'mods/species/vox/icons/body/soldier/markings.dmi' - blend = ICON_MULTIPLY + color_blend = ICON_MULTIPLY uid = "acc_markings_vox_neck" /decl/sprite_accessory/marking/vox/claws diff --git a/mods/species/vox/datum/antagonism.dm b/mods/species/vox/datum/antagonism.dm index e47ceef5b64..cc21ad6ea57 100644 --- a/mods/species/vox/datum/antagonism.dm +++ b/mods/species/vox/datum/antagonism.dm @@ -49,7 +49,7 @@ if(user.mind) user.mind.transfer_to(vox) qdel(user) - addtimer(CALLBACK(src, .proc/do_post_voxifying, vox), 1) + addtimer(CALLBACK(src, PROC_REF(do_post_voxifying), vox), 1) /obj/structure/mirror/raider/proc/do_post_voxifying(var/mob/living/carbon/human/vox) var/newname = sanitize_safe(input(vox,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN) diff --git a/mods/species/vox/datum/species.dm b/mods/species/vox/datum/species.dm index b8bd96cd14e..e3d525a7917 100644 --- a/mods/species/vox/datum/species.dm +++ b/mods/species/vox/datum/species.dm @@ -22,7 +22,7 @@ /decl/species/vox name = SPECIES_VOX name_plural = SPECIES_VOX - base_prosthetics_model = /decl/bodytype/prosthetic/vox/crap + base_external_prosthetics_model = /decl/bodytype/prosthetic/vox/crap default_emotes = list( /decl/emote/audible/vox_shriek diff --git a/mods/species/vox/datum/species_bodytypes.dm b/mods/species/vox/datum/species_bodytypes.dm index dec7118615d..ae83e547319 100644 --- a/mods/species/vox/datum/species_bodytypes.dm +++ b/mods/species/vox/datum/species_bodytypes.dm @@ -1,20 +1,20 @@ /decl/bodytype/vox - name = "soldier voxform" + name = "soldier voxform" bodytype_category = BODYTYPE_VOX - icon_base = 'mods/species/vox/icons/body/soldier/body.dmi' - icon_deformed = 'mods/species/vox/icons/body/deformed_body.dmi' - husk_icon = 'mods/species/vox/icons/body/husk.dmi' - blood_overlays = 'mods/species/vox/icons/body/blood_overlays.dmi' - eye_icon = 'mods/species/vox/icons/body/soldier/eyes.dmi' - bodytype_flag = BODY_FLAG_VOX - limb_blend = ICON_MULTIPLY - eye_blend = ICON_MULTIPLY - appearance_flags = HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_SKIN_COLOR - base_hair_color = "#160900" - base_eye_color = "#d60093" - base_color = "#526d29" - body_flags = BODY_FLAG_NO_DNA - default_h_style = /decl/sprite_accessory/hair/vox/short + icon_base = 'mods/species/vox/icons/body/soldier/body.dmi' + icon_deformed = 'mods/species/vox/icons/body/deformed_body.dmi' + husk_icon = 'mods/species/vox/icons/body/husk.dmi' + blood_overlays = 'mods/species/vox/icons/body/blood_overlays.dmi' + eye_icon = 'mods/species/vox/icons/body/soldier/eyes.dmi' + bodytype_flag = BODY_FLAG_VOX + limb_blend = ICON_MULTIPLY + eye_blend = ICON_MULTIPLY + appearance_flags = HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_SKIN_COLOR + base_hair_color = "#160900" + base_eye_color = "#d60093" + base_color = "#526d29" + body_flags = BODY_FLAG_NO_DNA + default_h_style = /decl/sprite_accessory/hair/vox/short cold_level_1 = 80 cold_level_2 = 50 @@ -28,36 +28,36 @@ BP_GROIN = /obj/item/organ/external/groin/vox, BP_TAIL = /obj/item/organ/external/tail/vox ) - has_organ = list( - BP_STOMACH = /obj/item/organ/internal/stomach/vox, - BP_HEART = /obj/item/organ/internal/heart/vox, - BP_LUNGS = /obj/item/organ/internal/lungs/vox, - BP_LIVER = /obj/item/organ/internal/liver/vox, - BP_KIDNEYS = /obj/item/organ/internal/kidneys/vox, - BP_BRAIN = /obj/item/organ/internal/brain, - BP_EYES = /obj/item/organ/internal/eyes/vox, - BP_STACK = /obj/item/organ/internal/voxstack, + has_organ = list( + BP_STOMACH = /obj/item/organ/internal/stomach/vox, + BP_HEART = /obj/item/organ/internal/heart/vox, + BP_LUNGS = /obj/item/organ/internal/lungs/vox, + BP_LIVER = /obj/item/organ/internal/liver/vox, + BP_KIDNEYS = /obj/item/organ/internal/kidneys/vox, + BP_BRAIN = /obj/item/organ/internal/brain, + BP_EYES = /obj/item/organ/internal/eyes/vox, + BP_STACK = /obj/item/organ/internal/voxstack, BP_HINDTONGUE = /obj/item/organ/internal/hindtongue ) - base_markings = list( - /decl/sprite_accessory/marking/vox/beak = "#bc7d3e", + base_markings = list( + /decl/sprite_accessory/marking/vox/beak = "#bc7d3e", /decl/sprite_accessory/marking/vox/scutes = "#bc7d3e", - /decl/sprite_accessory/marking/vox/crest = "#bc7d3e", - /decl/sprite_accessory/marking/vox/claws = "#a0a654" + /decl/sprite_accessory/marking/vox/crest = "#bc7d3e", + /decl/sprite_accessory/marking/vox/claws = "#a0a654" ) /decl/bodytype/vox/Initialize() if(!length(equip_adjust)) equip_adjust = list( - BP_L_HAND = list("[NORTH]" = list(0, -2), "[EAST]" = list(0, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list( 0, -2)), - BP_R_HAND = list("[NORTH]" = list(0, -2), "[EAST]" = list(0, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list( 0, -2)), - slot_head_str = list("[NORTH]" = list(0, -2), "[EAST]" = list(3, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list(-3, -2)), - slot_wear_mask_str = list("[NORTH]" = list(0, 0), "[EAST]" = list(4, 0), "[SOUTH]" = list( 0, 0), "[WEST]" = list(-4, 0)), - slot_wear_suit_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), - slot_w_uniform_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), + BP_L_HAND = list("[NORTH]" = list(0, -2), "[EAST]" = list(0, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list( 0, -2)), + BP_R_HAND = list("[NORTH]" = list(0, -2), "[EAST]" = list(0, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list( 0, -2)), + slot_head_str = list("[NORTH]" = list(0, -2), "[EAST]" = list(3, -2), "[SOUTH]" = list( 0, -2), "[WEST]" = list(-3, -2)), + slot_wear_mask_str = list("[NORTH]" = list(0, 0), "[EAST]" = list(4, 0), "[SOUTH]" = list( 0, 0), "[WEST]" = list(-4, 0)), + slot_wear_suit_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), + slot_w_uniform_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), slot_underpants_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), slot_undershirt_str = list("[NORTH]" = list(0, -1), "[EAST]" = list(0, -1), "[SOUTH]" = list( 0, -1), "[WEST]" = list( 0, -1)), - slot_back_str = list("[NORTH]" = list(0, 0), "[EAST]" = list(3, 0), "[SOUTH]" = list( 0, 0), "[WEST]" = list(-3, 0)) + slot_back_str = list("[NORTH]" = list(0, 0), "[EAST]" = list(3, 0), "[SOUTH]" = list( 0, 0), "[WEST]" = list(-3, 0)) ) return ..() diff --git a/mods/species/vox/gear/gear_head.dm b/mods/species/vox/gear/gear_head.dm index 24d6676478f..b2df8ba1e07 100644 --- a/mods/species/vox/gear/gear_head.dm +++ b/mods/species/vox/gear/gear_head.dm @@ -28,7 +28,7 @@ color = "#486e6e" var/lights_color = "#00ffff" -/obj/item/clothing/head/helmet/space/vox/carapace/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/head/helmet/space/vox/carapace/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && lights_color && check_state_in_icon("[overlay.icon_state]-lights", overlay.icon)) var/image/I = emissive_overlay(overlay.icon, "[overlay.icon_state]-lights") I.color = lights_color diff --git a/mods/species/vox/gear/gear_suit.dm b/mods/species/vox/gear/gear_suit.dm index a02b8554285..36adb11965c 100644 --- a/mods/species/vox/gear/gear_suit.dm +++ b/mods/species/vox/gear/gear_suit.dm @@ -43,7 +43,7 @@ desc = "An armoured, segmented carapace with glowing purple lights. It looks pretty run-down." var/lights_color = "#00ffff" -/obj/item/clothing/suit/space/vox/carapace/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE) +/obj/item/clothing/suit/space/vox/carapace/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_offset = FALSE) if(overlay && lights_color && check_state_in_icon("[overlay.icon_state]-lights", overlay.icon)) var/image/I = emissive_overlay(overlay.icon, "[overlay.icon_state]-lights") I.color = lights_color diff --git a/mods/species/vox/icons/body/servitor/hair.dmi b/mods/species/vox/icons/body/servitor/hair.dmi index f4e1011e013..999649b10e1 100644 Binary files a/mods/species/vox/icons/body/servitor/hair.dmi and b/mods/species/vox/icons/body/servitor/hair.dmi differ diff --git a/mods/species/vox/icons/body/soldier/hair.dmi b/mods/species/vox/icons/body/soldier/hair.dmi index 4316e8e33fb..7149c366b5c 100644 Binary files a/mods/species/vox/icons/body/soldier/hair.dmi and b/mods/species/vox/icons/body/soldier/hair.dmi differ diff --git a/mods/species/vox/icons/body/stanchion/damage_overlays.dmi b/mods/species/vox/icons/body/stanchion/damage_overlays.dmi index 190655c09cf..af035589c06 100644 Binary files a/mods/species/vox/icons/body/stanchion/damage_overlays.dmi and b/mods/species/vox/icons/body/stanchion/damage_overlays.dmi differ diff --git a/mods/species/vox/icons/body/stanchion/hair.dmi b/mods/species/vox/icons/body/stanchion/hair.dmi index d0f4f126680..cdbf92bc78f 100644 Binary files a/mods/species/vox/icons/body/stanchion/hair.dmi and b/mods/species/vox/icons/body/stanchion/hair.dmi differ diff --git a/mods/species/vox/organs_vox.dm b/mods/species/vox/organs_vox.dm index e51fd0920d8..e29724f70b9 100644 --- a/mods/species/vox/organs_vox.dm +++ b/mods/species/vox/organs_vox.dm @@ -155,10 +155,10 @@ icon_state = "cortical-stack" organ_tag = BP_STACK organ_properties = ORGAN_PROP_PROSTHETIC - origin_tech = @"{'biotech':4,'materials':4,'magnets':2,'programming':3}" + origin_tech = @'{"biotech":4,"materials":4,"magnets":2,"programming":3}' relative_size = 10 - var/ownerckey + var/stored_ckey var/default_language var/list/languages = list() var/datum/mind/backup @@ -166,7 +166,7 @@ /obj/item/organ/internal/voxstack/Initialize(mapload, material_key, datum/dna/given_dna, decl/bodytype/new_bodytype) var/decl/species/dna_species = given_dna && get_species_by_key(given_dna.species) - . = ..(mapload, material_key, given_dna, dna_species?.base_prosthetics_model) + . = ..(mapload, material_key, given_dna, dna_species?.base_internal_prosthetics_model) do_backup() /obj/item/organ/internal/voxstack/examine(mob/user) @@ -174,7 +174,7 @@ var/user_vox = isspecies(user, SPECIES_VOX) if (istype(backup)) - var/owner_viable = find_dead_player(ownerckey, TRUE) + var/owner_viable = find_dead_player(stored_ckey, TRUE) if (user_vox) to_chat(user, SPAN_NOTICE("The integrity light on [src] blinks [owner_viable ? "rapidly. It can be implanted." : "slowly. It is dormant."]")) else @@ -194,7 +194,7 @@ backup = owner.mind default_language = owner.default_language if(owner.ckey) - ownerckey = owner.ckey + stored_ckey = owner.ckey /obj/item/organ/internal/voxstack/proc/backup_inviable() return (!istype(backup) || backup == owner.mind || (backup.current && backup.current.stat != DEAD)) @@ -212,7 +212,7 @@ set waitfor = FALSE if(C && !backup_inviable()) prompting = TRUE - var/response = alert(find_dead_player(ownerckey, 1), "Your neural backup has been placed into a new body. Do you wish to return to life as the mind of [backup.name]?", "Resleeving", "Yes", "No") + var/response = alert(find_dead_player(stored_ckey, 1), "Your neural backup has been placed into a new body. Do you wish to return to life as the mind of [backup.name]?", "Resleeving", "Yes", "No") prompting = FALSE if(src && response == "Yes" && owner == C) overwrite() diff --git a/mods/utility/ooc_notes/player_setup.dm b/mods/utility/ooc_notes/player_setup.dm index 59d5bedf1ac..69a737fc1ec 100644 --- a/mods/utility/ooc_notes/player_setup.dm +++ b/mods/utility/ooc_notes/player_setup.dm @@ -32,7 +32,7 @@ ..() if(is_preview_copy) return - addtimer(CALLBACK(src, .proc/copy_ooc_notes), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(copy_ooc_notes)), 2 SECONDS) /datum/preferences/proc/copy_ooc_notes() for(var/datum/mind/M in SSticker.minds) //Need to iterate minds, unfortunately. diff --git a/mods/verbs/antighost/verb.dm b/mods/verbs/antighost/verb.dm index 6c980eac6df..2635a64da22 100644 --- a/mods/verbs/antighost/verb.dm +++ b/mods/verbs/antighost/verb.dm @@ -8,7 +8,7 @@ var/global/list/speech_toppings = list("|" = "i", "+" = "b", "_" = "u") usr.custom_emote_subtle(message = message) /proc/log_subtle(text) - if (config.log_say) + if (get_config_value(/decl/config/toggle/log_say)) game_log("SUBTLE", text) /mob/proc/custom_emote_subtle(var/m_type=VISIBLE_MESSAGE, var/message = null) //This would normally go in emote.dm diff --git a/nebula.dme b/nebula.dme index 17875255788..9467ad3ad24 100644 --- a/nebula.dme +++ b/nebula.dme @@ -17,6 +17,7 @@ #include "code\world.dm" #include "code\__datastructures\priority_queue.dm" #include "code\__datastructures\stack.dm" +#include "code\__defines\_byond_version_compat.dm" #include "code\__defines\_compile_helpers.dm" #include "code\__defines\_compile_options.dm" #include "code\__defines\_planes+layers.dm" @@ -80,8 +81,8 @@ #include "code\__defines\proc_presets.dm" #include "code\__defines\qdel.dm" #include "code\__defines\radio.dm" +#include "code\__defines\reactions.dm" #include "code\__defines\research.dm" -#include "code\__defines\ruin_tags.dm" #include "code\__defines\shields.dm" #include "code\__defines\shuttle.dm" #include "code\__defines\skills.dm" @@ -96,6 +97,7 @@ #include "code\__defines\subsystems.dm" #include "code\__defines\targeting.dm" #include "code\__defines\temperature.dm" +#include "code\__defines\template_tags.dm" #include "code\__defines\tgs.config.dm" #include "code\__defines\tgs.dm" #include "code\__defines\time.dm" @@ -234,7 +236,6 @@ #include "code\controllers\admin.dm" #include "code\controllers\autotransfer.dm" #include "code\controllers\communications.dm" -#include "code\controllers\configuration.dm" #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\hooks-defs.dm" @@ -257,6 +258,7 @@ #include "code\controllers\subsystems\ao.dm" #include "code\controllers\subsystems\atoms.dm" #include "code\controllers\subsystems\circuit_component.dm" +#include "code\controllers\subsystems\configuration.dm" #include "code\controllers\subsystems\daycycle.dm" #include "code\controllers\subsystems\disposals.dm" #include "code\controllers\subsystems\DPC.dm" @@ -296,6 +298,7 @@ #include "code\controllers\subsystems\xenoarch.dm" #include "code\controllers\subsystems\zcopy.dm" #include "code\controllers\subsystems\initialization\aspects.dm" +#include "code\controllers\subsystems\initialization\character_info.dm" #include "code\controllers\subsystems\initialization\character_setup.dm" #include "code\controllers\subsystems\initialization\codex.dm" #include "code\controllers\subsystems\initialization\computer_networks.dm" @@ -367,6 +370,28 @@ #include "code\datums\communication\~defines.dm" #include "code\datums\composite_sounds\_composite_sound.dm" #include "code\datums\composite_sounds\machinery_sounds.dm" +#include "code\datums\config\_config.dm" +#include "code\datums\config\_config_categories.dm" +#include "code\datums\config\config_enum.dm" +#include "code\datums\config\config_list.dm" +#include "code\datums\config\config_num.dm" +#include "code\datums\config\config_num_client.dm" +#include "code\datums\config\config_text.dm" +#include "code\datums\config\config_toggle.dm" +#include "code\datums\config\config_toggle_on.dm" +#include "code\datums\config\config_types\config_admin.dm" +#include "code\datums\config\config_types\config_client.dm" +#include "code\datums\config\config_types\config_debug.dm" +#include "code\datums\config\config_types\config_events.dm" +#include "code\datums\config\config_types\config_game_option.dm" +#include "code\datums\config\config_types\config_game_world.dm" +#include "code\datums\config\config_types\config_health.dm" +#include "code\datums\config\config_types\config_logging.dm" +#include "code\datums\config\config_types\config_mode.dm" +#include "code\datums\config\config_types\config_protected.dm" +#include "code\datums\config\config_types\config_resources.dm" +#include "code\datums\config\config_types\config_server.dm" +#include "code\datums\config\config_types\config_voting.dm" #include "code\datums\extensions\_defines.dm" #include "code\datums\extensions\access_provider.dm" #include "code\datums\extensions\deity_be_near.dm" @@ -950,6 +975,7 @@ #include "code\game\objects\item_materials.dm" #include "code\game\objects\item_mob_overlay.dm" #include "code\game\objects\munition.dm" +#include "code\game\objects\obj_edibility.dm" #include "code\game\objects\objs.dm" #include "code\game\objects\objs_damage.dm" #include "code\game\objects\objs_interactions.dm" @@ -973,7 +999,7 @@ #include "code\game\objects\effects\fake_fire.dm" #include "code\game\objects\effects\fluids.dm" #include "code\game\objects\effects\force_portal.dm" -#include "code\game\objects\effects\gibs.dm" +#include "code\game\objects\effects\gibspawner.dm" #include "code\game\objects\effects\item_pickup_ghost.dm" #include "code\game\objects\effects\landmarks.dm" #include "code\game\objects\effects\landmarks_endgame.dm" @@ -996,7 +1022,6 @@ #include "code\game\objects\effects\decals\decal.dm" #include "code\game\objects\effects\decals\misc.dm" #include "code\game\objects\effects\decals\warning_stripes.dm" -#include "code\game\objects\effects\decals\Cleanable\aliens.dm" #include "code\game\objects\effects\decals\Cleanable\humans.dm" #include "code\game\objects\effects\decals\Cleanable\misc.dm" #include "code\game\objects\effects\decals\Cleanable\robots.dm" @@ -1023,6 +1048,7 @@ #include "code\game\objects\items\glassjar.dm" #include "code\game\objects\items\holosign_creator.dm" #include "code\game\objects\items\instruments.dm" +#include "code\game\objects\items\item_edibility.dm" #include "code\game\objects\items\latexballoon.dm" #include "code\game\objects\items\paintkit.dm" #include "code\game\objects\items\paper_fortune_teller.dm" @@ -1038,12 +1064,22 @@ #include "code\game\objects\items\trash.dm" #include "code\game\objects\items\umbrella.dm" #include "code\game\objects\items\books\_book.dm" -#include "code\game\objects\items\books\skill_book.dm" +#include "code\game\objects\items\books\fluff\_fluff.dm" +#include "code\game\objects\items\books\fluff\science.dm" #include "code\game\objects\items\books\manuals\_manual.dm" #include "code\game\objects\items\books\manuals\engineering.dm" #include "code\game\objects\items\books\manuals\manuals.dm" #include "code\game\objects\items\books\manuals\medical.dm" #include "code\game\objects\items\books\manuals\science.dm" +#include "code\game\objects\items\books\skill\_skill.dm" +#include "code\game\objects\items\books\skill\_skill_custom.dm" +#include "code\game\objects\items\books\skill\engineering.dm" +#include "code\game\objects\items\books\skill\general.dm" +#include "code\game\objects\items\books\skill\medical.dm" +#include "code\game\objects\items\books\skill\organizational.dm" +#include "code\game\objects\items\books\skill\research.dm" +#include "code\game\objects\items\books\skill\security.dm" +#include "code\game\objects\items\books\skill\service.dm" #include "code\game\objects\items\devices\aicard.dm" #include "code\game\objects\items\devices\auto_cpr.dm" #include "code\game\objects\items\devices\binoculars.dm" @@ -1263,7 +1299,6 @@ #include "code\game\objects\items\weapons\storage\bible.dm" #include "code\game\objects\items\weapons\storage\boxes.dm" #include "code\game\objects\items\weapons\storage\briefcase.dm" -#include "code\game\objects\items\weapons\storage\fancy.dm" #include "code\game\objects\items\weapons\storage\firstaid.dm" #include "code\game\objects\items\weapons\storage\internal.dm" #include "code\game\objects\items\weapons\storage\laundry_basket.dm" @@ -1282,6 +1317,14 @@ #include "code\game\objects\items\weapons\storage\uplink_kits.dm" #include "code\game\objects\items\weapons\storage\wall_mirror.dm" #include "code\game\objects\items\weapons\storage\wallets.dm" +#include "code\game\objects\items\weapons\storage\fancy\_fancy.dm" +#include "code\game\objects\items\weapons\storage\fancy\cigar.dm" +#include "code\game\objects\items\weapons\storage\fancy\cigarettes.dm" +#include "code\game\objects\items\weapons\storage\fancy\crackers.dm" +#include "code\game\objects\items\weapons\storage\fancy\crayons.dm" +#include "code\game\objects\items\weapons\storage\fancy\donutbox.dm" +#include "code\game\objects\items\weapons\storage\fancy\eggbox.dm" +#include "code\game\objects\items\weapons\storage\fancy\vials.dm" #include "code\game\objects\items\weapons\storage\storage_ui\default.dm" #include "code\game\objects\items\weapons\storage\storage_ui\storage_ui.dm" #include "code\game\objects\items\weapons\tanks\jetpack.dm" @@ -1654,6 +1697,7 @@ #include "code\modules\atmospherics\components\unary\vent_scrubber.dm" #include "code\modules\augment\active.dm" #include "code\modules\augment\augment.dm" +#include "code\modules\augment\helping_hands.dm" #include "code\modules\augment\simple.dm" #include "code\modules\augment\active\armblades.dm" #include "code\modules\augment\active\circuit.dm" @@ -1675,8 +1719,17 @@ #include "code\modules\awaymissions\pamphlet.dm" #include "code\modules\awaymissions\trigger.dm" #include "code\modules\blob\blob.dm" +#include "code\modules\blood\blood.dm" +#include "code\modules\blood\blood_types.dm" +#include "code\modules\blood\blood_types_subtypes.dm" +#include "code\modules\brain_interface\_brain_interface.dm" +#include "code\modules\brain_interface\interface_radio.dm" #include "code\modules\butchery\butchery.dm" #include "code\modules\butchery\remains.dm" +#include "code\modules\character_info\_character_info.dm" +#include "code\modules\character_info\_comment.dm" +#include "code\modules\character_info\character_info_interface.dm" +#include "code\modules\character_info\comment_mood.dm" #include "code\modules\chat_filter\_chat_filter.dm" #include "code\modules\chat_filter\_chat_filter_regex.dm" #include "code\modules\chat_filter\filter_banned_words.dm" @@ -1738,11 +1791,12 @@ #include "code\modules\client\preference_setup\occupation\occupation.dm" #include "code\modules\client\preference_setup\occupation\skill_selection.dm" #include "code\modules\client\preference_setup\records\00_records.dm" -#include "code\modules\client\preference_setup\records\01_public_record.dm" -#include "code\modules\client\preference_setup\records\02_medical_record.dm" -#include "code\modules\client\preference_setup\records\03_security_record.dm" -#include "code\modules\client\preference_setup\records\04_general_record.dm" -#include "code\modules\client\preference_setup\records\05_memory.dm" +#include "code\modules\client\preference_setup\records\01_character_info.dm" +#include "code\modules\client\preference_setup\records\02_public_record.dm" +#include "code\modules\client\preference_setup\records\03_medical_record.dm" +#include "code\modules\client\preference_setup\records\04_security_record.dm" +#include "code\modules\client\preference_setup\records\05_general_record.dm" +#include "code\modules\client\preference_setup\records\06_memory.dm" #include "code\modules\clothing\_clothing.dm" #include "code\modules\clothing\chameleon.dm" #include "code\modules\clothing\clothing_accessories.dm" @@ -1879,6 +1933,7 @@ #include "code\modules\codex\codex_mob.dm" #include "code\modules\codex\codex_scannable.dm" #include "code\modules\codex\categories\_category.dm" +#include "code\modules\codex\categories\_materials.dm" #include "code\modules\codex\categories\category_categories.dm" #include "code\modules\codex\categories\category_cocktails.dm" #include "code\modules\codex\categories\category_cultures.dm" @@ -1901,6 +1956,7 @@ #include "code\modules\codex\entries\clothing.dm" #include "code\modules\codex\entries\codex.dm" #include "code\modules\codex\entries\engineering.dm" +#include "code\modules\codex\entries\guides.dm" #include "code\modules\codex\entries\guns.dm" #include "code\modules\codex\entries\jukebox.dm" #include "code\modules\codex\entries\machinery.dm" @@ -2108,7 +2164,6 @@ #include "code\modules\fabrication\designs\textile\protective.dm" #include "code\modules\fabrication\designs\textile\space.dm" #include "code\modules\fabrication\designs\textile\storage.dm" -#include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\TextFilters.dm" #include "code\modules\food\machines\_appliance.dm" #include "code\modules\food\machines\_cooker.dm" @@ -2120,6 +2175,7 @@ #include "code\modules\food\machines\mixer.dm" #include "code\modules\food\machines\oven.dm" #include "code\modules\food\machines\stove.dm" +#include "code\modules\food\plates\_plate.dm" #include "code\modules\food\recipes\recipes_fryer.dm" #include "code\modules\food\recipes\recipes_microwave.dm" #include "code\modules\food\recipes\recipes_mix.dm" @@ -2145,6 +2201,15 @@ #include "code\modules\goals\definitions\personal_achievement.dm" #include "code\modules\goals\definitions\personal_achievement_movement.dm" #include "code\modules\goals\definitions\personal_achievement_specific_object.dm" +#include "code\modules\hallucinations\_hallucination.dm" +#include "code\modules\hallucinations\hallucination_fakeattack.dm" +#include "code\modules\hallucinations\hallucination_gunfire.dm" +#include "code\modules\hallucinations\hallucination_mirage.dm" +#include "code\modules\hallucinations\hallucination_skitters.dm" +#include "code\modules\hallucinations\hallucination_sound.dm" +#include "code\modules\hallucinations\hallucination_spiderbabies.dm" +#include "code\modules\hallucinations\hallucination_talking.dm" +#include "code\modules\hallucinations\hallucination_telepathy.dm" #include "code\modules\holidays\_holiday.dm" #include "code\modules\holidays\holiday_hook.dm" #include "code\modules\holidays\holiday_name.dm" @@ -2294,6 +2359,7 @@ #include "code\modules\materials\recipes_stacks.dm" #include "code\modules\materials\recipes_storage.dm" #include "code\modules\materials\recipes_structures.dm" +#include "code\modules\materials\recipes_turfs.dm" #include "code\modules\materials\definitions\gasses\_mat_gas.dm" #include "code\modules\materials\definitions\gasses\material_gas_alien.dm" #include "code\modules\materials\definitions\gasses\material_gas_mundane.dm" @@ -2380,7 +2446,9 @@ #include "code\modules\mob\login.dm" #include "code\modules\mob\logout.dm" #include "code\modules\mob\mob.dm" +#include "code\modules\mob\mob_blood.dm" #include "code\modules\mob\mob_defines.dm" +#include "code\modules\mob\mob_eating.dm" #include "code\modules\mob\mob_grabs.dm" #include "code\modules\mob\mob_helpers.dm" #include "code\modules\mob\mob_layering.dm" @@ -2418,12 +2486,16 @@ #include "code\modules\mob\living\inventory.dm" #include "code\modules\mob\living\life.dm" #include "code\modules\mob\living\living.dm" +#include "code\modules\mob\living\living_appearance.dm" #include "code\modules\mob\living\living_attackhand.dm" +#include "code\modules\mob\living\living_blood.dm" #include "code\modules\mob\living\living_bodytemp.dm" #include "code\modules\mob\living\living_breath.dm" #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" +#include "code\modules\mob\living\living_dreams.dm" #include "code\modules\mob\living\living_grabs.dm" +#include "code\modules\mob\living\living_hallucinations.dm" #include "code\modules\mob\living\living_maneuvers.dm" #include "code\modules\mob\living\living_organs.dm" #include "code\modules\mob\living\living_powers.dm" @@ -2434,7 +2506,6 @@ #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\stasis.dm" #include "code\modules\mob\living\stress.dm" -#include "code\modules\mob\living\update_icon.dm" #include "code\modules\mob\living\bot\bot.dm" #include "code\modules\mob\living\bot\cleanbot.dm" #include "code\modules\mob\living\bot\ed209bot.dm" @@ -2444,18 +2515,20 @@ #include "code\modules\mob\living\bot\mulebot.dm" #include "code\modules\mob\living\bot\remotebot.dm" #include "code\modules\mob\living\bot\secbot.dm" +#include "code\modules\mob\living\brain\brain.dm" +#include "code\modules\mob\living\brain\death.dm" +#include "code\modules\mob\living\brain\say.dm" #include "code\modules\mob\living\carbon\breathe.dm" #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\carbon_defense.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" +#include "code\modules\mob\living\carbon\carbon_eating.dm" #include "code\modules\mob\living\carbon\carbon_grabs.dm" #include "code\modules\mob\living\carbon\carbon_organs.dm" #include "code\modules\mob\living\carbon\carbon_powers.dm" #include "code\modules\mob\living\carbon\damage_procs.dm" #include "code\modules\mob\living\carbon\give.dm" -#include "code\modules\mob\living\carbon\hallucinations.dm" #include "code\modules\mob\living\carbon\internals.dm" -#include "code\modules\mob\living\carbon\life.dm" #include "code\modules\mob\living\carbon\resist.dm" #include "code\modules\mob\living\carbon\taste.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" @@ -2464,18 +2537,12 @@ #include "code\modules\mob\living\carbon\alien\death.dm" #include "code\modules\mob\living\carbon\alien\life.dm" #include "code\modules\mob\living\carbon\alien\say.dm" -#include "code\modules\mob\living\carbon\brain\brain.dm" -#include "code\modules\mob\living\carbon\brain\death.dm" -#include "code\modules\mob\living\carbon\brain\life.dm" -#include "code\modules\mob\living\carbon\brain\login.dm" -#include "code\modules\mob\living\carbon\brain\MMI.dm" -#include "code\modules\mob\living\carbon\brain\robot.dm" -#include "code\modules\mob\living\carbon\brain\say.dm" -#include "code\modules\mob\living\carbon\human\appearance.dm" #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\examine.dm" #include "code\modules\mob\living\carbon\human\human.dm" +#include "code\modules\mob\living\carbon\human\human_appearance.dm" #include "code\modules\mob\living\carbon\human\human_attackhand.dm" +#include "code\modules\mob\living\carbon\human\human_blood.dm" #include "code\modules\mob\living\carbon\human\human_damage.dm" #include "code\modules\mob\living\carbon\human\human_defense.dm" #include "code\modules\mob\living\carbon\human\human_defines.dm" @@ -2882,8 +2949,6 @@ #include "code\modules\nano\modules\law_manager.dm" #include "code\modules\nano\modules\nano_module.dm" #include "code\modules\organs\_organ_setup.dm" -#include "code\modules\organs\blood.dm" -#include "code\modules\organs\blood_types.dm" #include "code\modules\organs\organ.dm" #include "code\modules\organs\pain.dm" #include "code\modules\organs\ailments\_ailment.dm" @@ -2912,13 +2977,14 @@ #include "code\modules\organs\internal\_internal.dm" #include "code\modules\organs\internal\appendix.dm" #include "code\modules\organs\internal\brain.dm" +#include "code\modules\organs\internal\brain_computer.dm" +#include "code\modules\organs\internal\cell.dm" #include "code\modules\organs\internal\eyes.dm" #include "code\modules\organs\internal\heart.dm" #include "code\modules\organs\internal\insectoid.dm" #include "code\modules\organs\internal\kidneys.dm" #include "code\modules\organs\internal\liver.dm" #include "code\modules\organs\internal\lungs.dm" -#include "code\modules\organs\internal\posibrain.dm" #include "code\modules\organs\internal\stomach.dm" #include "code\modules\organs\internal\voice.dm" #include "code\modules\organs\internal\species\golem.dm" @@ -2991,6 +3057,7 @@ #include "code\modules\paperwork\toner_cartridge.dm" #include "code\modules\paperwork\pen\chameleon_pen.dm" #include "code\modules\paperwork\pen\crayon.dm" +#include "code\modules\paperwork\pen\crayon_edibility.dm" #include "code\modules\paperwork\pen\fancy.dm" #include "code\modules\paperwork\pen\multi_pen.dm" #include "code\modules\paperwork\pen\pen.dm" @@ -3167,6 +3234,7 @@ #include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Metabolism.dm" #include "code\modules\reagents\cocktails.dm" +#include "code\modules\reagents\reagent_container_edibility.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" #include "code\modules\reagents\chems\chems_blood.dm" @@ -3195,6 +3263,7 @@ #include "code\modules\reagents\reactions\reaction_alcohol.dm" #include "code\modules\reagents\reactions\reaction_alloys.dm" #include "code\modules\reagents\reactions\reaction_cafe.dm" +#include "code\modules\reagents\reactions\reaction_compounds.dm" #include "code\modules\reagents\reactions\reaction_drinks.dm" #include "code\modules\reagents\reactions\reaction_drinks_hidden.dm" #include "code\modules\reagents\reactions\reaction_drugs.dm" @@ -3207,13 +3276,18 @@ #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\condiment.dm" +#include "code\modules\reagents\reagent_containers\condiment_edibility.dm" #include "code\modules\reagents\reagent_containers\drinks.dm" +#include "code\modules\reagents\reagent_containers\drinks_edibility.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" #include "code\modules\reagents\reagent_containers\food.dm" +#include "code\modules\reagents\reagent_containers\food_edibility.dm" #include "code\modules\reagents\reagent_containers\glass.dm" +#include "code\modules\reagents\reagent_containers\glass_edibility.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" #include "code\modules\reagents\reagent_containers\inhaler.dm" #include "code\modules\reagents\reagent_containers\pill.dm" +#include "code\modules\reagents\reagent_containers\pill_edibility.dm" #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\reagents\reagent_containers\drinkingglass\drinkingglass.dm" @@ -3230,6 +3304,7 @@ #include "code\modules\reagents\reagent_containers\food\baked_goods.dm" #include "code\modules\reagents\reagent_containers\food\bread.dm" #include "code\modules\reagents\reagent_containers\food\burgers.dm" +#include "code\modules\reagents\reagent_containers\food\can_edibility.dm" #include "code\modules\reagents\reagent_containers\food\canned.dm" #include "code\modules\reagents\reagent_containers\food\dough.dm" #include "code\modules\reagents\reagent_containers\food\eggs.dm" @@ -3255,7 +3330,12 @@ #include "code\modules\reagents\reagent_containers\food\sliceable\cheeses.dm" #include "code\modules\reagents\reagent_containers\food\sliceable\loaves.dm" #include "code\modules\reagents\reagent_containers\food\sliceable\misc_slices.dm" -#include "code\modules\reagents\reagent_containers\food\sliceable\pizza.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\_pizza.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\pizza_box.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\pizza_margherita.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\pizza_meat.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\pizza_mushroom.dm" +#include "code\modules\reagents\reagent_containers\food\sliceable\pizza\pizza_vegetable.dm" #include "code\modules\reagents\reagent_containers\glass\bottle.dm" #include "code\modules\reagents\reagent_containers\glass\bottle\robot.dm" #include "code\modules\reagents\storage\pill_bottle.dm" @@ -3512,6 +3592,7 @@ #include "code\modules\webhooks\webhook_ahelp2discord.dm" #include "code\modules\webhooks\webhook_custom_event.dm" #include "code\modules\webhooks\webhook_elevator_fall.dm" +#include "code\modules\webhooks\webhook_fax.dm" #include "code\modules\webhooks\webhook_roundend.dm" #include "code\modules\webhooks\webhook_roundprep.dm" #include "code\modules\webhooks\webhook_roundstart.dm" diff --git a/sound/foley/wooden_drop.ogg b/sound/foley/wooden_drop.ogg new file mode 100644 index 00000000000..dd6c4e7c530 Binary files /dev/null and b/sound/foley/wooden_drop.ogg differ diff --git a/test/check-paths.sh b/test/check-paths.sh index a775484c4da..2831ada98b2 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -40,7 +40,7 @@ exactly 0 "incorrect indentations" '^( {4,})' -P exactly 24 "text2path uses" 'text2path' exactly 4 "update_icon() override" '/update_icon\((.*)\)' -P exactly 0 "goto uses" 'goto ' -exactly 6 "atom/New uses" '^/(obj|atom|area|mob|turf).*/New\(' +exactly 5 "atom/New uses" '^/(obj|atom|area|mob|turf).*/New\(' exactly 1 "decl/New uses" '^/decl.*/New\(' exactly 0 "tag uses" '\stag = ' -P '**/*.dmm' exactly 3 "unmarked globally scoped variables" -P '^(/|)var/(?!global)' diff --git a/tether_migration.txt b/tether_migration.txt index 74dec9edd9e..b61acfc9dba 100644 --- a/tether_migration.txt +++ b/tether_migration.txt @@ -322,7 +322,7 @@ /obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} -/turf/simulated/open/virgo3b : /turf/simulated/open +/turf/simulated/open/virgo3b : /turf/open /turf/simulated/mineral/virgo3b : /turf/exterior/wall /turf/simulated/mineral/vacuum : /turf/exterior/wall /turf/simulated/floor/carpet/blucarpet : /turf/simulated/floor/carpet/blue @@ -471,7 +471,9 @@ /obj/item/storage/firstaid/regular{empty = 1} : /obj/item/storage/firstaid/empty{@OLD; empty = @SKIP; name = @SKIP} -/obj/item/mmi/digital/posibrain : /obj/item/organ/internal/posibrain{@OLD} +/obj/item/mmi/digital/@SUBTYPES : /obj/item/organ/internal/brain/robotic{@OLD} +/obj/item/mmi : /obj/item/organ/internal/brain_interface{@OLD} +/obj/item/organ/internal/posibrain : /obj/item/organ/internal/brain/robotic{@OLD} /obj/item/energy/@SUBTYPES : /obj/item/energy_blade/@SUBTYPES{@OLD} @@ -817,6 +819,7 @@ /obj/item/storage/box/flare : /obj/item/storage/box/flares{@OLD} /obj/item/storage/fancy/candle_box : /obj/item/storage/candle_box /obj/item/storage/fancy/cigar/havana : /obj/item/clothing/mask/smokable/cigarette/cigar/havana +/obj/item/storage/box/donut : /obj/item/storage/box/fancy/donut{@OLD} /obj/item/toy/plushie/coffee_fox : /obj/item/toy/plushie/fox/coffee /obj/item/toy/plushie/marble_fox : /obj/item/toy/plushie/fox/marble /obj/item/toy/plushie/mouse/fluff : /obj/item/toy/plushie/mouse @@ -828,7 +831,12 @@ /obj/item/beach_ball : /obj/item/ball /obj/structure/bookcase/manuals/research_and_development : /obj/structure/bookcase/manuals/xenoarchaeology -/obj/item/book/manual/security_space_law : /obj/item/book/manual/nt_regs +/obj/item/book/manual/security_space_law : /obj/item/book/fluff/nt_regs{@OLD} +/obj/item/book/manual/nt_regs : /obj/item/book/fluff/nt_regs{@OLD} +/obj/item/book/manual/stasis : /obj/item/book/fluff/stasis{@OLD} +/obj/item/book/manual/resleeving : /obj/item/book/fluff/resleeving{@OLD} +/obj/item/book/manual/command_guide : /obj/item/book/fluff/command_guide{@OLD} +/obj/item/book/manual/standard_operating_procedure : /obj/item/book/fluff/standard_operating_procedure{@OLD} /obj/machinery/fitness/heavy/lifter : /obj/structure/fitness/weightlifter diff --git a/tools/map_migrations/3560_central_atmos_computer.txt b/tools/map_migrations/3560_central_atmos_computer.txt index e1c7b6721e3..71179dbe712 100644 --- a/tools/map_migrations/3560_central_atmos_computer.txt +++ b/tools/map_migrations/3560_central_atmos_computer.txt @@ -1,2 +1,2 @@ -/obj/machinery/computer/atmoscontrol : /obj/machinery/computer/central_atmos{@OLD} +/obj/machinery/computer/atmoscontrol/@SUBTYPES : /obj/machinery/computer/central_atmos/@SUBTYPES{@OLD} /obj/item/stock_parts/circuitboard/atmoscontrol : /obj/item/stock_parts/circuitboard/central_atmos{@OLD} diff --git a/tools/map_migrations/3576_wallobj_migration.txt b/tools/map_migrations/3576_wallobj_migration.txt new file mode 100644 index 00000000000..1f381b8483f --- /dev/null +++ b/tools/map_migrations/3576_wallobj_migration.txt @@ -0,0 +1,33 @@ +# FIX WALLOBJ FACING DIRS +/obj/item/radio/intercom/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD {@OLD;pixel_x=-22;dir=4} +/obj/item/radio/intercom/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD {@OLD;pixel_x=22;dir=8} +/obj/item/radio/intercom/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD {@OLD;pixel_y=-30;dir=1} +/obj/item/radio/intercom/@SUBTYPES {pixel_x=@UNSET;pixel_y=@POSITIVE} : @OLD {@OLD;pixel_y=20;dir=@SKIP} +/obj/structure/extinguisher_cabinet {pixel_x=@POSITIVE;pixel_y=@UNSET} : @OLD {@OLD;pixel_x=29;dir=8} +/obj/structure/extinguisher_cabinet {pixel_x=@NEGATIVE;pixel_y=@UNSET} : @OLD {@OLD;pixel_x=-29;dir=4} +/obj/structure/extinguisher_cabinet {pixel_y=@POSITIVE;pixel_x=@UNSET} : @OLD {@OLD;pixel_y=29;dir=@SKIP} +/obj/structure/extinguisher_cabinet {pixel_y=@NEGATIVE;pixel_x=@UNSET} : @OLD {@OLD;pixel_y=-29;dir=1} +/obj/machinery/button/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/machinery/button/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/machinery/button/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/status_display/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=8} +/obj/machinery/status_display/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=4} +/obj/machinery/status_display/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/newscaster/@SUBTYPES {pixel_x=@NEGATIVE;pixel_y=@UNSET} : @OLD{@OLD;dir=8} +/obj/machinery/newscaster/@SUBTYPES {pixel_x=@POSITIVE;pixel_y=@UNSET} : @OLD{@OLD;dir=4} +/obj/machinery/newscaster/@SUBTYPES {pixel_y=@NEGATIVE;pixel_x=@UNSET} : @OLD{@OLD;dir=1} +/obj/structure/closet/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/structure/closet/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/structure/closet/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/recharger/wallcharger/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/machinery/recharger/wallcharger/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/machinery/recharger/wallcharger/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/embedded_controller/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/machinery/embedded_controller/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/machinery/embedded_controller/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/airlock_sensor/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/machinery/airlock_sensor/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/machinery/airlock_sensor/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} +/obj/machinery/light_switch/@SUBTYPES {pixel_y=@UNSET;pixel_x=@POSITIVE} : @OLD{@OLD;dir=8} +/obj/machinery/light_switch/@SUBTYPES {pixel_y=@UNSET;pixel_x=@NEGATIVE} : @OLD{@OLD;dir=4} +/obj/machinery/light_switch/@SUBTYPES {pixel_x=@UNSET;pixel_y=@NEGATIVE} : @OLD{@OLD;dir=1} \ No newline at end of file diff --git a/tools/map_migrations/3601_fancy_box.txt b/tools/map_migrations/3601_fancy_box.txt new file mode 100644 index 00000000000..2d40638ff2c --- /dev/null +++ b/tools/map_migrations/3601_fancy_box.txt @@ -0,0 +1,7 @@ +# REPATH /fancy to /box/fancy +/obj/item/storage/fancy/@SUBTYPES : /obj/item/storage/box/fancy/@SUBTYPES{@OLD} +# REPATH PIZZA SLICES +/obj/item/chems/food/slice/vegetablepizza/@SUBTYPES : /obj/item/chems/food/slice/pizza/vegetable/@SUBTYPES{@OLD} +/obj/item/chems/food/slice/meatpizza/@SUBTYPES : /obj/item/chems/food/slice/pizza/meat/@SUBTYPES{@OLD} +/obj/item/chems/food/slice/margherita/@SUBTYPES : /obj/item/chems/food/slice/pizza/margherita/@SUBTYPES{@OLD} +/obj/item/chems/food/slice/mushroompizza/@SUBTYPES : /obj/item/chems/food/slice/pizza/mushroom/@SUBTYPES{@OLD} diff --git a/tools/map_migrations/3634_openspace_merge.txt b/tools/map_migrations/3634_openspace_merge.txt new file mode 100644 index 00000000000..337671708f7 --- /dev/null +++ b/tools/map_migrations/3634_openspace_merge.txt @@ -0,0 +1,2 @@ +/turf/simulated/open/@SUBTYPES : /turf/open/@SUBTYPES{@OLD} +/turf/exterior/open/@SUBTYPES : /turf/open/@SUBTYPES{@OLD} \ No newline at end of file diff --git a/tools/map_migrations/3670_stonewalls.txt b/tools/map_migrations/3670_stonewalls.txt new file mode 100644 index 00000000000..a9abf2f2143 --- /dev/null +++ b/tools/map_migrations/3670_stonewalls.txt @@ -0,0 +1,2 @@ +/turf/simulated/wall/sandstone/@SUBTYPES : /turf/simulated/wall/brick/sandstone/@SUBTYPES{@OLD} +/turf/simulated/wall/sandstonediamond/@SUBTYPES : /turf/simulated/wall/brick/sandstonediamond/@SUBTYPES{@OLD} diff --git a/tools/map_migrations/3681_plates.txt b/tools/map_migrations/3681_plates.txt new file mode 100644 index 00000000000..c339d5d1e5a --- /dev/null +++ b/tools/map_migrations/3681_plates.txt @@ -0,0 +1,3 @@ +# REPATH /trash/plate to /plate +/obj/item/trash/plate/@SUBTYPES : /obj/item/plate/@SUBTYPES{@OLD} +/obj/item/trash/tray/@SUBTYPES : /obj/item/plate/tray/@SUBTYPES{@OLD} \ No newline at end of file diff --git a/tools/map_migrations/3710_fluid_landmarks.txt b/tools/map_migrations/3710_fluid_landmarks.txt new file mode 100644 index 00000000000..52d2f4a3ae4 --- /dev/null +++ b/tools/map_migrations/3710_fluid_landmarks.txt @@ -0,0 +1,2 @@ +# REPATH /obj/abstract/fluid_mapped TO /obj/abstract/landmark/mapped_fluid +/obj/abstract/fluid_mapped/@SUBTYPES : /obj/abstract/landmark/mapped_fluid/@SUBTYPES{@OLD} \ No newline at end of file diff --git a/~code/global_init.dm b/~code/global_init.dm index 3dee544e61a..00301af2ca2 100644 --- a/~code/global_init.dm +++ b/~code/global_init.dm @@ -14,7 +14,7 @@ var/global_init = new /datum/global_init() /datum/global_init/New() - load_configuration() + SSconfiguration.load_all_configuration() callHook("global_init") qdel(src) //we're done