diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md index de1166543f4..b205feae993 100644 --- a/ATTRIBUTIONS.md +++ b/ATTRIBUTIONS.md @@ -37,3 +37,10 @@ **License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=14935.0)
**Notes:** Permission to use assets also given in writing.
+
+**File:** `icons/mecha/fighters64x64.dmi`
+**Icon-States:** `gunpod`, derivs by VerySoft.
+**Creator:** Tartiflette & FlashFrozen
+**License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Patreon Post](https://www.patreon.com/posts/diable-avionics-44573931)
+**Notes:** Permission to use assets also given in writing.
diff --git a/code/__defines/color.dm b/code/__defines/color.dm index 36745128134..ecf01528aac 100644 --- a/code/__defines/color.dm +++ b/code/__defines/color.dm @@ -91,6 +91,7 @@ #define COLOR_DARK_TEAL "#2db5b5" #define COLOR_LIGHT_VIOLET "#e7bfff" #define COLOR_SAN_MARINO_BLUE "#4b75ab" +#define COLOR_OLIVE "#52613b" //VOREStation Addition #define PIPE_COLOR_GREY "#808080" #define PIPE_COLOR_RED "#ff0000" diff --git a/code/__defines/inventory_sizes.dm b/code/__defines/inventory_sizes.dm index 6fb72505d00..d6474a73998 100644 --- a/code/__defines/inventory_sizes.dm +++ b/code/__defines/inventory_sizes.dm @@ -22,4 +22,4 @@ // Container sizes. Note that different containers can hold a maximum ITEMSIZE. #define INVENTORY_STANDARD_SPACE ITEMSIZE_COST_NORMAL * 7 // 28 #define INVENTORY_DUFFLEBAG_SPACE ITEMSIZE_COST_NORMAL * 9 // 36 -#define INVENTORY_BOX_SPACE ITEMSIZE_COST_SMALL * 4 // 8 \ No newline at end of file +#define INVENTORY_BOX_SPACE ITEMSIZE_COST_SMALL * 7 // 14 diff --git a/code/__defines/map.dm b/code/__defines/map.dm index fce63b9955c..6ae9fd7c6f4 100644 --- a/code/__defines/map.dm +++ b/code/__defines/map.dm @@ -7,6 +7,7 @@ #define MAP_LEVEL_EMPTY 0x020 // Empty Z-levels that may be used for various things (currently used by bluespace jump) #define MAP_LEVEL_CONSOLES 0x040 // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset. #define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation. +#define MAP_LEVEL_PERSIST 0x100 // Z-levels where SSpersistence should persist between rounds // Misc map defines. #define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit \ No newline at end of file diff --git a/code/__defines/persistence.dm b/code/__defines/persistence.dm new file mode 100644 index 00000000000..1fde05bf22b --- /dev/null +++ b/code/__defines/persistence.dm @@ -0,0 +1 @@ +#define PERSISTENCE_VARIABLE_TOKEN_LENGTH -1 \ No newline at end of file diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index df78fd5df8f..44037305dda 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -188,4 +188,4 @@ #define ui_mech_deco1_f "WEST+2:-7, SOUTH+8" #define ui_mech_deco2_f "WEST+2:-7, SOUTH+9" -#define ui_crafting "EAST-4:22,SOUTH:5" \ No newline at end of file +#define ui_smallquad "EAST-4:22,SOUTH:5" \ No newline at end of file diff --git a/code/controllers/subsystems/persistence.dm b/code/controllers/subsystems/persistence.dm index 00c08363de3..1667aa83203 100644 --- a/code/controllers/subsystems/persistence.dm +++ b/code/controllers/subsystems/persistence.dm @@ -8,9 +8,11 @@ SUBSYSTEM_DEF(persistence) /datum/controller/subsystem/persistence/Initialize() . = ..() for(var/thing in subtypesof(/datum/persistent)) - var/datum/persistent/P = new thing - persistence_datums[thing] = P - P.Initialize() + var/datum/persistent/P = thing + if(initial(P.name)) + P = new P + persistence_datums[thing] = P + P.Initialize() /datum/controller/subsystem/persistence/Shutdown() for(var/thing in persistence_datums) @@ -30,8 +32,7 @@ SUBSYSTEM_DEF(persistence) if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT)) return -// if((!T.z in GLOB.using_map.station_levels) || !initialized) - if(!(T.z in using_map.station_levels)) + if(!(T.z in using_map.persist_levels)) return if(!tracking_values[track_type]) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 4ff5dadb7c0..9f39990afd9 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -504,4 +504,4 @@ name = "crafting menu" icon = 'icons/mob/screen/midnight.dmi' icon_state = "craft" - screen_loc = ui_crafting \ No newline at end of file + screen_loc = ui_smallquad \ No newline at end of file diff --git a/code/datums/vending/stored_item.dm b/code/datums/vending/stored_item.dm index 1f5d613b8a7..4b8606ff61e 100644 --- a/code/datums/vending/stored_item.dm +++ b/code/datums/vending/stored_item.dm @@ -46,10 +46,11 @@ /datum/stored_item/proc/add_product(var/atom/movable/product) if(product.type != item_path) - return 0 + return FALSE init_products() product.forceMove(stored) instances += product + return TRUE /datum/stored_item/proc/init_products() if(instances) @@ -57,4 +58,40 @@ instances = list() for(var/i = 1 to amount) var/new_product = new item_path(stored) - instances += new_product \ No newline at end of file + instances += new_product + + + +/datum/stored_item/stack/get_amount() + return amount + +/datum/stored_item/stack/add_product(var/atom/movable/product) + . = ..() + if(.) + var/obj/item/stack/S = product + if(istype(S)) + amount += S.amount + +/datum/stored_item/stack/get_product(var/product_location, var/count) + if(!LAZYLEN(instances)) + return null // Shouldn't happen, but will loudly complain if it breaks + + var/obj/item/stack/S = instances[1] + count = min(count, S.get_max_amount()) + src.amount -= count // We won't vend more than one full stack per call + + // Case 1: Draw the full amount from the first instance + if(count < S.get_amount()) + S = S.split(count) + + // Case 2: Amount at least one stack, or have to accumulate + else if(count >= S.get_amount()) + count -= S.get_amount() + instances -= S + for(var/obj/item/stack/T as anything in instances) + if(count <= 0) + break + count -= T.transfer_to(S, count) + + S.forceMove(product_location) + return S \ No newline at end of file diff --git a/code/game/mecha/combat/fighter.dm b/code/game/mecha/combat/fighter.dm index bf176f6a692..dcbe9f21ac3 100644 --- a/code/game/mecha/combat/fighter.dm +++ b/code/game/mecha/combat/fighter.dm @@ -16,6 +16,7 @@ dir_in = null //Don't reset direction when empty step_in = 2 //Fast + step_energy_drain = 0 //These should use fuel instead of energy health = 400 maxhealth = 400 @@ -38,6 +39,14 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/lightweight, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /obj/mecha/combat/fighter/Initialize() . = ..() ion_trail = new /datum/effect/effect/system/ion_trail_follow() diff --git a/code/game/mecha/combat/fighter_vr.dm b/code/game/mecha/combat/fighter_vr.dm deleted file mode 100644 index 4bc4782e9f8..00000000000 --- a/code/game/mecha/combat/fighter_vr.dm +++ /dev/null @@ -1,8 +0,0 @@ -/obj/mecha/combat/fighter - starting_components = list( - /obj/item/mecha_parts/component/hull/lightweight, - /obj/item/mecha_parts/component/actuator, - /obj/item/mecha_parts/component/armor, - /obj/item/mecha_parts/component/gas, - /obj/item/mecha_parts/component/electrical - ) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index cfcb2923ae8..525a65ffc80 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1450,16 +1450,28 @@ else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HURT) var/obj/item/weapon/weldingtool/WT = W + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] if (WT.remove_fuel(0,user)) if (hasInternalDamage(MECHA_INT_TANK_BREACH)) clearInternalDamage(MECHA_INT_TANK_BREACH) to_chat(user, "You repair the damaged gas tank.") else return - if(src.healthYou repair some damage to [src.name].") - src.health += min(10, initial(src.health)-src.health) - update_damage_alerts() + if((src.healthYou repair some damage to [src.name].") + src.health += min(10, initial(src.health)-src.health) + update_damage_alerts() + else if(HC.integrityYou repair some damage to [HC.name].") + HC.integrity += min(10, HC.max_integrity-HC.integrity) + update_damage_alerts() + else if(AC.integrityYou repair some damage to [AC.name].") + AC.integrity += min(10, AC.max_integrity-AC.integrity) + update_damage_alerts() + else to_chat(user, "The [src.name] is at full integrity") return diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index e3ae63cbad0..4d85b582fa3 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -2,8 +2,7 @@ var/list/beam_components = list() /datum/beam_components_cache/Destroy() - for(var/component in beam_components) - qdel(component) + QDEL_LIST_NULL(beam_components) return ..() /proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, datum/beam_components_cache/beam_components, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, instance_key) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported! diff --git a/code/game/objects/items/devices/radio/headset_vr.dm b/code/game/objects/items/devices/radio/headset_vr.dm index 8285fade758..1285ae0709a 100644 --- a/code/game/objects/items/devices/radio/headset_vr.dm +++ b/code/game/objects/items/devices/radio/headset_vr.dm @@ -81,13 +81,13 @@ /obj/item/device/radio/headset/pilot name = "pilot's headset" - desc = "A headset used by pilots, has access to the explorer channel." + desc = "A headset used by pilots." icon_state = "pilot_headset" adhoc_fallback = TRUE /obj/item/device/radio/headset/pilot/alt name = "pilot's bowman headset" - desc = "A bowman headset used by pilots, has access to the explorer channel." + desc = "A bowman headset used by pilots." icon_state = "pilot_headset_alt" /obj/item/device/radio/headset/explorer diff --git a/code/game/objects/items/weapons/id cards/id_stacks_vr.dm b/code/game/objects/items/weapons/id cards/id_stacks_vr.dm index 599fd9d5222..2bdd52bfa92 100644 --- a/code/game/objects/items/weapons/id cards/id_stacks_vr.dm +++ b/code/game/objects/items/weapons/id cards/id_stacks_vr.dm @@ -145,7 +145,7 @@ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-red") /obj/item/weapon/card/id/civilian/pilot - initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-darkgreen") + initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-olive") /obj/item/weapon/card/id/civilian/entertainer initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-brown") @@ -179,13 +179,13 @@ //Exploration /obj/item/weapon/card/id/exploration - initial_sprite_stack = list("base-stamp", "top-darkgreen", "stamp-n") + initial_sprite_stack = list("base-stamp", "top-olive", "stamp-n") /obj/item/weapon/card/id/exploration/fm - initial_sprite_stack = list("base-stamp", "top-darkgreen", "stamp-n", "stripe-medblu") + initial_sprite_stack = list("base-stamp", "top-olive", "stamp-n", "stripe-medblu") /obj/item/weapon/card/id/exploration/head - initial_sprite_stack = list("base-stamp-silver", "top-darkgreen", "stamp-n", "pips-white") + initial_sprite_stack = list("base-stamp-silver", "top-olive", "stamp-n", "pips-white") //Talon diff --git a/code/game/objects/structures/crates_lockers/_closets_appearance_definitions_vr.dm b/code/game/objects/structures/crates_lockers/_closets_appearance_definitions_vr.dm index 419b28e9c1a..46760952427 100644 --- a/code/game/objects/structures/crates_lockers/_closets_appearance_definitions_vr.dm +++ b/code/game/objects/structures/crates_lockers/_closets_appearance_definitions_vr.dm @@ -65,7 +65,7 @@ ) /decl/closet_appearance/secure_closet/expedition - color = COLOR_BRASS + color = COLOR_OLIVE decals = list( "lower_side_vent" ) @@ -84,15 +84,13 @@ /decl/closet_appearance/secure_closet/expedition/explorer extra_decals = list( - "stripe_vertical_left_full" = COLOR_PURPLE, - "stripe_vertical_right_full" = COLOR_PURPLE, - "exped" = COLOR_PURPLE + "stripe_vertical_mid_full" = COLOR_GRAY40, + "exped" = COLOR_GRAY40 ) /decl/closet_appearance/secure_closet/expedition/pathfinder extra_decals = list( - "stripe_vertical_left_full" = COLOR_PURPLE, - "stripe_vertical_mid_full" = COLOR_GRAY40, - "stripe_vertical_right_full" = COLOR_PURPLE, - "exped" = COLOR_GRAY40 + "stripe_vertical_left_full" = COLOR_GRAY20, + "stripe_vertical_right_full" = COLOR_GRAY20, + "exped" = COLOR_GRAY20 ) \ No newline at end of file diff --git a/code/game/world.dm b/code/game/world.dm index a51b7185de0..95d6ff18d72 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -111,8 +111,10 @@ var/world_topic_spam_protect_time = world.timeofday s["players"] = 0 s["stationtime"] = stationtime2text() s["roundduration"] = roundduration2text() + s["map"] = strip_improper(using_map.full_name) //Done to remove the non-UTF-8 text macros - if(input["status"] == "2") + if(input["status"] == "2") // Shiny new hip status. + var/active = 0 var/list/players = list() var/list/admins = list() @@ -122,15 +124,18 @@ var/world_topic_spam_protect_time = world.timeofday continue admins[C.key] = C.holder.rank players += C.key + if(istype(C.mob, /mob/living)) + active++ s["players"] = players.len s["playerlist"] = list2params(players) + s["active_players"] = active var/list/adm = get_admin_counts() var/list/presentmins = adm["present"] var/list/afkmins = adm["afk"] s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho s["adminlist"] = list2params(admins) - else + else // Legacy. var/n = 0 var/admins = 0 diff --git a/code/global_vr.dm b/code/global_vr.dm index 278df90f79a..f7ab6951cf0 100644 --- a/code/global_vr.dm +++ b/code/global_vr.dm @@ -5,6 +5,7 @@ robot_module_types += "Sci-borg" robot_module_types += "Pupdozer" robot_module_types += "Service-Hound" + robot_module_types += "BoozeHound" robot_module_types += "KMine" return 1 diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index b8a42321964..3f5e0b3344b 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -50,11 +50,11 @@ . += "tgui Window Mode: [(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]
" . += "tgui Window Placement: [(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]
" if(can_select_ooc_color(user)) - . += "OOC Color:�" + . += "OOC Color:" if(pref.ooccolor == initial(pref.ooccolor)) . += "Using Default
" else - . += "[pref.ooccolor] [color_square(hex = pref.ooccolor)]�reset
" + . += "[pref.ooccolor] [color_square(hex = pref.ooccolor)]reset
" /datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user) if(href_list["select_style"]) diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm index 7e21dd3ef8c..b006fc7a0d6 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -50,7 +50,7 @@ /datum/gear/accessory/holster display_name = "holster selection (Security, SM, HoP, Exploration)" - allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder","Talon Guard") + allowed_roles = list("Site Manager", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Field Medic","Explorer","Pathfinder","Talon Captain","Talon Guard") /datum/gear/accessory/brown_vest display_name = "webbing, brown (Eng, Sec, Med, Exploration, Miner)" diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm index 68699342a4b..9504678e06b 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm @@ -2,13 +2,20 @@ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") /datum/gear/eyes/meson - display_name = "Optical Meson Scanners (Engineering, Science)" + display_name = "Optical Meson Scanners (Eng, Sci, Explo)" allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician", "Scientist", "Research Director", "Explorer", "Pathfinder") /datum/gear/eyes/arglasses display_name = "AR glasses" path = /obj/item/clothing/glasses/omnihud +/datum/gear/eyes/arglasses/visor + display_name = "AR visor" + path = /obj/item/clothing/glasses/omnihud/visor + +/datum/gear/eyes/arglasses/visor/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) /datum/gear/eyes/arglassespres display_name = "AR glasses, prescription" path = /obj/item/clothing/glasses/omnihud/prescription @@ -48,7 +55,7 @@ path = /obj/item/clothing/glasses/fluff/science_proper /datum/gear/eyes/meson/retinal - display_name = "retinal projector, meson (Eng, Sci, Mining)" + display_name = "retinal projector, meson (Eng, Sci, Explo)" path = /obj/item/clothing/glasses/omnihud/eng/meson /datum/gear/eyes/security/secpatch diff --git a/code/modules/client/preference_setup/loadout/loadout_head_vr.dm b/code/modules/client/preference_setup/loadout/loadout_head_vr.dm index 2aebfd668f4..d7add786c52 100644 --- a/code/modules/client/preference_setup/loadout/loadout_head_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_head_vr.dm @@ -1,3 +1,8 @@ +/datum/gear/head/cap/med + display_name = "cap, medical (Medical)" + path = /obj/item/clothing/head/soft/med + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic","Field Medic") + /*/datum/gear/head/cap/sol display_name = "cap, sol" path = /obj/item/clothing/head/soft/sol*/ diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm index 554300d379a..66e93fbbf62 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm @@ -1,6 +1,3 @@ -/datum/gear/shoes/boots/winter/science - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Explorer", "Pathfinder") - /datum/gear/shoes/boots/winter/medical allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") diff --git a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm index e681401582d..25dc8d4511a 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm @@ -1,9 +1,6 @@ /datum/gear/suit/snowsuit/medical allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist", "Field Medic") -/datum/gear/suit/snowsuit/science - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Explorer", "Pathfinder") - /datum/gear/suit/labcoat_colorable display_name = "labcoat, colorable" path = /obj/item/clothing/suit/storage/toggle/labcoat @@ -49,7 +46,7 @@ /datum/gear/suit/roles/medical/ems_jacket display_name = "first responder jacket" path = /obj/item/clothing/suit/storage/toggle/fr_jacket - allowed_roles = list("Chief Medical Officer","Paramedic","Medical Doctor") + allowed_roles = list("Chief Medical Officer","Paramedic","Medical Doctor","Field Medic") //imo-superior 'martian' style jacket with the star-of-life design /datum/gear/suit/roles/medical/ems_jacket/alt @@ -60,7 +57,7 @@ /datum/gear/suit/roles/medical/paramedic_vest display_name = "paramedic vest" path = /obj/item/clothing/suit/storage/toggle/paramedic - allowed_roles = list("Chief Medical Officer","Paramedic","Medical Doctor") + allowed_roles = list("Chief Medical Officer","Paramedic","Medical Doctor","Field Medic") //greek thing /datum/gear/suit/chiton diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm index 6c8fc917641..1f169dbc70c 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm @@ -13,6 +13,10 @@ /datum/gear/uniform/job_turtle/science allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Xenobotanist") +/datum/gear/uniform/job_turtle/medical + display_name = "turtleneck, medical" + path = /obj/item/clothing/under/rank/medical/turtleneck + allowed_roles = list("Chief Medical Officer", "Paramedic", "Medical Doctor", "Psychiatrist", "Field Medic", "Chemist") //KHI Uniforms /datum/gear/uniform/job_khi/cmd @@ -38,7 +42,7 @@ /datum/gear/uniform/job_khi/sci display_name = "khi uniform, sci" path = /obj/item/clothing/under/rank/khi/sci - allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer") + allowed_roles = list("Research Director", "Scientist", "Roboticist", "Xenobiologist", "Xenobotanist") /datum/gear/uniform/job_khi/crg display_name = "khi uniform, cargo" @@ -58,7 +62,7 @@ /datum/gear/suit/job_fed/medsci display_name = "fed uniform, med/sci" path = /obj/item/clothing/suit/storage/fluff/fedcoat/fedblue - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist","Xenobotanist","Pathfinder","Explorer","Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist","Xenobotanist","Field Medic") /datum/gear/suit/job_fed/eng display_name = "fed uniform, eng" @@ -75,7 +79,7 @@ /datum/gear/uniform/job_trek/medsci/tos display_name = "TOS uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Field Medic") /datum/gear/uniform/job_trek/eng/tos display_name = "TOS uniform, eng/sec" @@ -91,7 +95,7 @@ /datum/gear/uniform/job_trek/medsci/tng display_name = "TNG uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/next - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Field Medic") /datum/gear/uniform/job_trek/eng/tng display_name = "TNG uniform, eng/sec" @@ -107,7 +111,7 @@ /datum/gear/uniform/job_trek/medsci/voy display_name = "VOY uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/voy - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Field Medic") /datum/gear/uniform/job_trek/eng/voy display_name = "VOY uniform, eng/sec" @@ -133,7 +137,7 @@ /datum/gear/uniform/job_trek/medsci/ds9 display_name = "DS9 uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/ds9 - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Field Medic") /datum/gear/uniform/job_trek/eng/ds9 display_name = "DS9 uniform, eng/sec" @@ -150,7 +154,7 @@ /datum/gear/uniform/job_trek/medsci/ent display_name = "ENT uniform, med/sci" path = /obj/item/clothing/under/rank/trek/medsci/ent - allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Pathfinder", "Explorer", "Field Medic") + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist", "Xenobiologist", "Xenobotanist", "Field Medic") /datum/gear/uniform/job_trek/eng/ent display_name = "ENT uniform, eng/sec" diff --git a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm index 36b3ead7a66..56218337e60 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm @@ -54,7 +54,7 @@ /datum/gear/utility/dufflebag/sci display_name = "science dufflebag" path = /obj/item/weapon/storage/backpack/dufflebag/sci - allowed_roles = list("Research Director","Scientist","Roboticist","Xenobiologist","Xenobotanist","Explorer","Pathfinder") + allowed_roles = list("Research Director","Scientist","Roboticist","Xenobiologist","Xenobotanist") /datum/gear/utility/ID display_name = "contractor identification card" diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 718b9e6908f..3487d0999c8 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -35,7 +35,7 @@ tgarscreen = null spawn(20 SECONDS) tgarscreen = disconnect_tgar - + //extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd if(icon_state == "glasses" || icon_state == "sun") if(prob(10)) @@ -113,6 +113,14 @@ /obj/item/clothing/glasses/omnihud/proc/ar_interact(var/mob/living/carbon/human/user) return 0 //The base models do nothing. +/obj/item/clothing/glasses/omnihud/visor + name = "AR visor" + desc = "The VZR-AR are a product based upon the classic AR Glasses, just more fashionable." + icon_override = 'icons/mob/eyes_vr.dmi' + icon = 'icons/mob/eyes_vr.dmi' + icon_state = "visor_CIV" + item_state = "visor_CIV" + /obj/item/clothing/glasses/omnihud/prescription name = "AR glasses (pr)" prescription = 1 diff --git a/code/modules/emotes/definitions/_mob.dm b/code/modules/emotes/definitions/_mob.dm index 8c10b4cde2f..46a2bf94da3 100644 --- a/code/modules/emotes/definitions/_mob.dm +++ b/code/modules/emotes/definitions/_mob.dm @@ -27,6 +27,7 @@ var/list/_default_mob_emotes = list( /mob var/list/usable_emotes + var/nextemote = 1 //VOREStation Add /mob/proc/update_emotes(var/skip_sort) usable_emotes = list() diff --git a/code/modules/emotes/definitions/audible_scream_vr.dm b/code/modules/emotes/definitions/audible_scream_vr.dm new file mode 100644 index 00000000000..7114d0eb662 --- /dev/null +++ b/code/modules/emotes/definitions/audible_scream_vr.dm @@ -0,0 +1,13 @@ +/decl/emote/audible/scream/get_emote_sound(var/atom/user) + var/mob/living/carbon/human/H = user + if(H.get_gender() == FEMALE) + return list( + "sound" = H.species.female_scream_sound, + "vol" = emote_volume + ) + else + return list( + "sound" = H.species.male_scream_sound, + "vol" = emote_volume + ) + return ..() diff --git a/code/modules/emotes/definitions/visible_animated.dm b/code/modules/emotes/definitions/visible_animated.dm index 2e035d289c7..c66fa789c17 100644 --- a/code/modules/emotes/definitions/visible_animated.dm +++ b/code/modules/emotes/definitions/visible_animated.dm @@ -27,7 +27,12 @@ /decl/emote/visible/flip/do_extra(mob/user) . = ..() - if(istype(user)) + // VOREStation Add - Fancy flips + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.handle_flip_vr() + // VOREStation Add End + else if(istype(user)) user.SpinAnimation(7,1) /decl/emote/visible/floorspin diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index 3e45f05091e..546ee4c7aec 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -1,4 +1,9 @@ /mob/proc/can_emote(var/emote_type) + //VOREStation Add + if(src.nextemote >= world.time) + return FALSE + src.nextemote = world.time + 12 + //VOREStation Add End return (stat == CONSCIOUS) /mob/living/can_emote(var/emote_type) diff --git a/code/modules/food/kitchen/smartfridge/drying_rack.dm b/code/modules/food/kitchen/smartfridge/drying_rack.dm new file mode 100644 index 00000000000..c0ceea5289c --- /dev/null +++ b/code/modules/food/kitchen/smartfridge/drying_rack.dm @@ -0,0 +1,71 @@ +/obj/machinery/smartfridge/drying_rack + name = "\improper Drying Rack" + desc = "A machine for drying plants." + wrenchable = 1 + icon_state = "drying_rack" + icon_base = "drying_rack" + +/obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/)) + var/obj/item/weapon/reagent_containers/food/snacks/S = O + if (S.dried_type) + return 1 + + if(istype(O, /obj/item/stack/wetleather)) + return 1 + + return 0 + +/obj/machinery/smartfridge/drying_rack/process() + ..() + if(stat & (BROKEN|NOPOWER)) + return + if(contents.len) + dry() + update_icon() + +/obj/machinery/smartfridge/drying_rack/update_icon() + var/not_working = stat & (BROKEN|NOPOWER) + var/hasItems + for(var/datum/stored_item/I in item_records) + if(I.get_amount()) + hasItems = 1 + break + if(hasItems) + if(not_working) + icon_state = "[icon_base]-plant-off" + else + icon_state = "[icon_base]-plant" + else + if(not_working) + icon_state = "[icon_base]-off" + else + icon_state = "[icon_base]" + +/obj/machinery/smartfridge/drying_rack/proc/dry() + for(var/datum/stored_item/I in item_records) + for(var/obj/item/weapon/reagent_containers/food/snacks/S in I.instances) + if(S.dry) continue + if(S.dried_type == S.type) + S.dry = 1 + S.name = "dried [S.name]" + S.color = "#AAAAAA" + I.instances -= S + S.forceMove(get_turf(src)) + else + var/D = S.dried_type + new D(get_turf(src)) + qdel(S) + return + + for(var/obj/item/stack/wetleather/WL in I.instances) + if(!WL.wetness) + if(WL.amount) + WL.forceMove(get_turf(src)) + WL.dry() + I.instances -= WL + break + + WL.wetness = max(0, WL.wetness - rand(1, 3)) + + return \ No newline at end of file diff --git a/code/modules/food/kitchen/smartfridge/engineering.dm b/code/modules/food/kitchen/smartfridge/engineering.dm new file mode 100644 index 00000000000..8141ca496df --- /dev/null +++ b/code/modules/food/kitchen/smartfridge/engineering.dm @@ -0,0 +1,32 @@ +/obj/machinery/smartfridge/sheets //Is this used anywhere? It's not secure. + name = "\improper Smart Sheet Storage" + desc = "A storage unit for metals." + icon_state = "fridge_dark" + icon_base = "fridge_dark" + icon_contents = "slime" + stored_datum_type = /datum/stored_item/stack + +/obj/machinery/smartfridge/sheets/persistent + persistent = /datum/persistent/storage/smartfridge/sheet_storage + +/obj/machinery/smartfridge/sheets/persistent_lossy + persistent = /datum/persistent/storage/smartfridge/sheet_storage/lossy + +/obj/machinery/smartfridge/sheets/accept_check(var/obj/item/O) + return istype(O, /obj/item/stack/material) + +/obj/machinery/smartfridge/sheets/vend(datum/stored_item/stack/I, var/count) + var/amount = I.get_amount() + if(amount < 1) + return + + while(count > 0) + var/obj/item/stack/S = I.get_product(get_turf(src), min(count, amount)) + count -= S.amount + SStgui.update_uis(src) + +/obj/machinery/smartfridge/sheets/find_record(var/obj/item/O) + for(var/datum/stored_item/stack/I as anything in item_records) + if(istype(O, I.item_path)) // Typecheck should evaluate material-specific subtype + return I + return null \ No newline at end of file diff --git a/code/modules/food/kitchen/smartfridge/hydroponics.dm b/code/modules/food/kitchen/smartfridge/hydroponics.dm new file mode 100644 index 00000000000..9b50136d796 --- /dev/null +++ b/code/modules/food/kitchen/smartfridge/hydroponics.dm @@ -0,0 +1,53 @@ +/obj/machinery/smartfridge/produce + name = "\improper Smart Produce Storage" + desc = "For storing all sorts of perishable foods!" + icon = 'icons/obj/vending.dmi' + icon_state = "fridge_food" + icon_base = "fridge_food" + icon_contents = "food" + +/obj/machinery/smartfridge/produce/persistent + persistent = /datum/persistent/storage/smartfridge/produce + +/obj/machinery/smartfridge/produce/persistent_lossy + persistent = /datum/persistent/storage/smartfridge/produce/lossy + +/obj/machinery/smartfridge/produce/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/)) + return TRUE + return FALSE + +/obj/machinery/smartfridge/drinks + name = "\improper Drink Showcase" + desc = "A refrigerated storage unit for tasty tasty alcohol." + icon_state = "fridge_drinks" + icon_base = "fridge_drinks" + icon_contents = "drink" + +/obj/machinery/smartfridge/drinks/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks) || istype(O,/obj/item/weapon/reagent_containers/food/condiment)) + return TRUE + return FALSE + +/obj/machinery/smartfridge/seeds + name = "\improper MegaSeed Servitor" + desc = "When you need seeds fast!" + icon_contents = "chem" + +/obj/machinery/smartfridge/seeds/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/seeds/)) + return 1 + return 0 + +/obj/machinery/smartfridge/secure/extract + name = "\improper Biological Sample Storage" + desc = "A refrigerated storage unit for xenobiological samples." + icon_contents = "slime" + req_access = list(access_research) + +/obj/machinery/smartfridge/secure/extract/accept_check(var/obj/item/O as obj) + if(istype(O, /obj/item/slime_extract)) + return TRUE + if(istype(O, /obj/item/slimepotion)) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/food/kitchen/smartfridge/medical.dm b/code/modules/food/kitchen/smartfridge/medical.dm new file mode 100644 index 00000000000..609f707a068 --- /dev/null +++ b/code/modules/food/kitchen/smartfridge/medical.dm @@ -0,0 +1,40 @@ +/obj/machinery/smartfridge/secure/medbay + name = "\improper Refrigerated Medicine Storage" + desc = "A refrigerated storage unit for storing medicine and chemicals." + req_one_access = list(access_medical,access_chemistry) + +/obj/machinery/smartfridge/secure/medbay/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/weapon/reagent_containers/glass/)) + return 1 + if(istype(O,/obj/item/weapon/storage/pill_bottle/)) + return 1 + if(istype(O,/obj/item/weapon/reagent_containers/pill/)) + return 1 + return 0 + +/obj/machinery/smartfridge/secure/virology + name = "\improper Refrigerated Virus Storage" + desc = "A refrigerated storage unit for storing viral material." + icon_contents = "drink" + req_access = list(access_virology) + +/obj/machinery/smartfridge/secure/virology/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/weapon/reagent_containers/glass/beaker/vial/)) + return 1 + if(istype(O,/obj/item/weapon/virusdish/)) + return 1 + return 0 + +/obj/machinery/smartfridge/chemistry //Is this used anywhere? It's not secure. + name = "\improper Smart Chemical Storage" + desc = "A refrigerated storage unit for medicine and chemical storage." + icon_contents = "chem" + +/obj/machinery/smartfridge/chemistry/accept_check(var/obj/item/O as obj) + if(istype(O,/obj/item/weapon/storage/pill_bottle) || istype(O,/obj/item/weapon/reagent_containers)) + return 1 + return 0 + +/obj/machinery/smartfridge/chemistry/virology //Same + name = "\improper Smart Virus Storage" + desc = "A refrigerated storage unit for volatile sample storage." \ No newline at end of file diff --git a/code/modules/food/kitchen/smartfridge.dm b/code/modules/food/kitchen/smartfridge/smartfridge.dm similarity index 53% rename from code/modules/food/kitchen/smartfridge.dm rename to code/modules/food/kitchen/smartfridge/smartfridge.dm index a6def6bd2b0..f43c9c49317 100644 --- a/code/modules/food/kitchen/smartfridge.dm +++ b/code/modules/food/kitchen/smartfridge/smartfridge.dm @@ -2,7 +2,7 @@ */ /obj/machinery/smartfridge name = "\improper SmartFridge" - desc = "For storing all sorts of perishable foods!" + desc = "For storing all sorts of things! This one doesn't accept any of them!" icon = 'icons/obj/vending.dmi' icon_state = "fridge_food" var/icon_base = "fridge_food" //Iconstate to base all the broken/deny/etc on @@ -13,10 +13,10 @@ idle_power_usage = 5 active_power_usage = 100 flags = NOREACT - var/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000. //VOREStation Edit - Non-global - //var/global/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000. + var/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000. //VOREStation Edit - Nonglobal so subtypes can override to lower values var/list/item_records = list() var/datum/stored_item/currently_vending = null //What we're putting out of the machine. + var/stored_datum_type = /datum/stored_item var/seconds_electrified = 0; var/shoot_inventory = 0 var/locked = 0 @@ -24,6 +24,7 @@ var/is_secure = 0 var/wrenchable = 0 var/datum/wires/smartfridge/wires = null + var/persistent = null // Path of persistence datum used to track contents /obj/machinery/smartfridge/secure is_secure = 1 @@ -31,8 +32,10 @@ icon_base = "fridge_sci" icon_contents = "chem" -/obj/machinery/smartfridge/New() - ..() +/obj/machinery/smartfridge/Initialize() + . = ..() + if(persistent) + SSpersistence.track_value(src, persistent) if(is_secure) wires = new/datum/wires/smartfridge/secure(src) else @@ -43,160 +46,13 @@ for(var/A in item_records) //Get rid of item records. qdel(A) wires = null + if(persistent) + SSpersistence.forget_value(src, persistent) return ..() /obj/machinery/smartfridge/proc/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/)) - return 1 - return 0 - -/obj/machinery/smartfridge/seeds - name = "\improper MegaSeed Servitor" - desc = "When you need seeds fast!" - icon_contents = "chem" - -/obj/machinery/smartfridge/seeds/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/seeds/)) - return 1 - return 0 - -/obj/machinery/smartfridge/secure/extract - name = "\improper Biological Sample Storage" - desc = "A refrigerated storage unit for xenobiological samples." - icon_contents = "slime" - req_access = list(access_research) - -/obj/machinery/smartfridge/secure/extract/accept_check(var/obj/item/O as obj) - if(istype(O, /obj/item/slime_extract)) - return TRUE - if(istype(O, /obj/item/slimepotion)) - return TRUE return FALSE -/obj/machinery/smartfridge/secure/medbay - name = "\improper Refrigerated Medicine Storage" - desc = "A refrigerated storage unit for storing medicine and chemicals." - req_one_access = list(access_medical,access_chemistry) - -/obj/machinery/smartfridge/secure/medbay/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/weapon/reagent_containers/glass/)) - return 1 - if(istype(O,/obj/item/weapon/storage/pill_bottle/)) - return 1 - if(istype(O,/obj/item/weapon/reagent_containers/pill/)) - return 1 - return 0 - -/obj/machinery/smartfridge/secure/virology - name = "\improper Refrigerated Virus Storage" - desc = "A refrigerated storage unit for storing viral material." - icon_contents = "drink" - req_access = list(access_virology) - -/obj/machinery/smartfridge/secure/virology/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/weapon/reagent_containers/glass/beaker/vial/)) - return 1 - if(istype(O,/obj/item/weapon/virusdish/)) - return 1 - return 0 - -/obj/machinery/smartfridge/chemistry //Is this used anywhere? It's not secure. - name = "\improper Smart Chemical Storage" - desc = "A refrigerated storage unit for medicine and chemical storage." - icon_contents = "chem" - -/obj/machinery/smartfridge/chemistry/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/weapon/storage/pill_bottle) || istype(O,/obj/item/weapon/reagent_containers)) - return 1 - return 0 - -/obj/machinery/smartfridge/chemistry/virology //Same - name = "\improper Smart Virus Storage" - desc = "A refrigerated storage unit for volatile sample storage." - -/obj/machinery/smartfridge/drinks - name = "\improper Drink Showcase" - desc = "A refrigerated storage unit for tasty tasty alcohol." - icon_state = "fridge_drinks" - icon_base = "fridge_drinks" - icon_contents = "drink" - -/obj/machinery/smartfridge/drinks/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks) || istype(O,/obj/item/weapon/reagent_containers/food/condiment)) - return 1 - -/obj/machinery/smartfridge/drying_rack - name = "\improper Drying Rack" - desc = "A machine for drying plants." - wrenchable = 1 - icon_state = "drying_rack" - icon_base = "drying_rack" - -/obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/)) - var/obj/item/weapon/reagent_containers/food/snacks/S = O - if (S.dried_type) - return 1 - - if(istype(O, /obj/item/stack/wetleather)) - return 1 - - return 0 - -/obj/machinery/smartfridge/drying_rack/process() - ..() - if(stat & (BROKEN|NOPOWER)) - return - if(contents.len) - dry() - update_icon() - -/obj/machinery/smartfridge/drying_rack/update_icon() - var/not_working = stat & (BROKEN|NOPOWER) - var/hasItems - for(var/datum/stored_item/I in item_records) - if(I.get_amount()) - hasItems = 1 - break - if(hasItems) - if(not_working) - icon_state = "[icon_base]-plant-off" - else - icon_state = "[icon_base]-plant" - else - if(not_working) - icon_state = "[icon_base]-off" - else - icon_state = "[icon_base]" - -/obj/machinery/smartfridge/drying_rack/proc/dry() - for(var/datum/stored_item/I in item_records) - for(var/obj/item/weapon/reagent_containers/food/snacks/S in I.instances) - if(S.dry) continue - if(S.dried_type == S.type) - S.dry = 1 - S.name = "dried [S.name]" - S.color = "#AAAAAA" - I.instances -= S - S.forceMove(get_turf(src)) - else - var/D = S.dried_type - new D(get_turf(src)) - qdel(S) - return - - for(var/obj/item/stack/wetleather/WL in I.instances) - if(!WL.wetness) - if(WL.amount) - WL.forceMove(get_turf(src)) - WL.dry() - I.instances -= WL - break - - WL.wetness = max(0, WL.wetness - rand(1, 3)) - - return - /obj/machinery/smartfridge/process() if(stat & (BROKEN|NOPOWER)) return @@ -229,7 +85,7 @@ is_off = "-off" // Fridge contents - if(contents) //VOREStation Edit - Some fridges do not have visible contents + if(contents) switch(contents.len) if(0) add_overlay("empty[is_off]") @@ -311,21 +167,28 @@ to_chat(user, "You short out the product lock on [src].") return 1 -/obj/machinery/smartfridge/proc/stock(obj/item/O) - var/hasRecord = FALSE //Check to see if this passes or not. - for(var/datum/stored_item/I in item_records) +/obj/machinery/smartfridge/proc/find_record(var/obj/item/O) + for(var/datum/stored_item/I as anything in item_records) if((O.type == I.item_path) && (O.name == I.item_name)) - I.add_product(O) - hasRecord = TRUE - break - if(!hasRecord) - var/datum/stored_item/item = new/datum/stored_item(src, O.type, O.name) - item.add_product(O) - item_records.Add(item) + return I + return null + +/obj/machinery/smartfridge/proc/stock(obj/item/O) + var/datum/stored_item/I = find_record(O) + if(!istype(I)) + I = new stored_datum_type(src, O.type, O.name) + item_records.Add(I) + I.add_product(O) SStgui.update_uis(src) -/obj/machinery/smartfridge/proc/vend(datum/stored_item/I) - I.get_product(get_turf(src)) +/obj/machinery/smartfridge/proc/vend(datum/stored_item/I, var/count) + var/amount = I.get_amount() + // Sanity check, there are probably ways to press the button when it shouldn't be possible. + if(amount <= 0) + return + + for(var/i = 1 to min(amount, count)) + I.get_product(get_turf(src)) SStgui.update_uis(src) /obj/machinery/smartfridge/attack_ai(mob/user as mob) @@ -376,16 +239,10 @@ return FALSE var/index = text2num(params["index"]) - var/datum/stored_item/I = item_records[index] - var/count = I.get_amount() - - // Sanity check, there are probably ways to press the button when it shouldn't be possible. - if(count > 0) - if((count - amount) < 0) - amount = count - for(var/i = 1 to amount) - vend(I) - + if(index < 1 || index > LAZYLEN(item_records)) + return TRUE + + vend(item_records[index], amount) return TRUE return FALSE @@ -393,7 +250,7 @@ var/obj/throw_item = null var/mob/living/target = locate() in view(7,src) if(!target) - return 0 + return FALSE for(var/datum/stored_item/I in item_records) throw_item = I.get_product(get_turf(src)) @@ -402,12 +259,12 @@ break if(!throw_item) - return 0 + return FALSE spawn(0) throw_item.throw_at(target,16,3,src) src.visible_message("[src] launches [throw_item.name] at [target.name]!") SStgui.update_uis(src) - return 1 + return TRUE /************************ * Secure SmartFridges diff --git a/code/modules/food/kitchen/smartfridge_vr.dm b/code/modules/food/kitchen/smartfridge/smartfridge_vr.dm similarity index 100% rename from code/modules/food/kitchen/smartfridge_vr.dm rename to code/modules/food/kitchen/smartfridge/smartfridge_vr.dm diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm index 2b8ce410635..1945db3e90a 100644 --- a/code/modules/mob/living/carbon/breathe.dm +++ b/code/modules/mob/living/carbon/breathe.dm @@ -17,7 +17,7 @@ if(losebreath>0) //Suffocating so do not take a breath AdjustLosebreath(-1) - if (prob(10)) //Gasp per 10 ticks? Sounds about right. + if (prob(10) && !isbelly(loc)) //Gasp per 10 ticks? Sounds about right. //VOREStation Add spawn emote("gasp") else //Okay, we can breathe, now check if we can get air diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index a705f034506..aba6241d652 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -124,6 +124,7 @@ var/list/_human_default_emotes = list( /decl/emote/audible/croak, /decl/emote/audible/gao, /decl/emote/audible/cackle, + /decl/emote/audible/squish, /decl/emote/visible/mlem, /decl/emote/visible/blep, diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index cdfef35b596..3ceea87f7b4 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -68,11 +68,12 @@ emp_act msg_admin_attack("[key_name(src)] was disarmed by a stun effect") drop_from_inventory(c_hand) - if (affected.robotic >= ORGAN_ROBOT) - custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [affected.name] malfunctioning!") - else - var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - custom_emote(VISIBLE_MESSAGE, "[affected.organ_can_feel_pain() ? "" : emote_scream] drops what they were holding in their [affected.name]!") + if(!isbelly(loc)) //VOREStation Add + if (affected.robotic >= ORGAN_ROBOT) + custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [affected.name] malfunctioning!") + else + var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") + custom_emote(VISIBLE_MESSAGE, "[affected.organ_can_feel_pain() ? "" : emote_scream] drops what they were holding in their [affected.name]!") ..(stun_amount, agony_amount, def_zone) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index f9c9bc831d1..4b94ff930a4 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -163,8 +163,9 @@ continue drop_from_inventory(r_hand) - var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - custom_emote(VISIBLE_MESSAGE, "[(can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") + if(!isbelly(loc)) //VOREStation Add + var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") + custom_emote(VISIBLE_MESSAGE, "[(can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") else if(E.is_malfunctioning()) switch(E.body_part) @@ -177,14 +178,15 @@ continue drop_from_inventory(r_hand) - custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [E.name] malfunctioning!") + if(!isbelly(loc)) //VOREStation Add + custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [E.name] malfunctioning!") - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src) - spark_system.attach(src) - spark_system.start() - spawn(10) - qdel(spark_system) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + spark_system.start() + spawn(10) + qdel(spark_system) //Handles chem traces /mob/living/carbon/human/proc/handle_trace_chems() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 767d68a56e7..dab0f0d18f6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1044,7 +1044,7 @@ if(client || sleeping > 3) AdjustSleeping(-1) throw_alert("asleep", /obj/screen/alert/asleep) - if( prob(2) && health && !hal_crit ) + if( prob(2) && health && !hal_crit && client ) spawn(0) emote("snore") //CONSCIOUS diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm index 15d5af23f24..a0fe3a017c4 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm @@ -439,3 +439,27 @@ T.apply_damage(20, HALLOSS,, armor_block, armor_soak) if(prob(75)) //75% chance to stun for 5 seconds, really only going to be 4 bcus click cooldown+animation. T.apply_effect(5, WEAKEN, armor_block) + + +/mob/living/silicon/robot/proc/reskin_booze() + set name = "Change Drink Color" + set category = "Robot Commands" + set desc = "Choose the color of drink displayed inside you." + + var/mob/M = usr + var/list/options = list() + options["Beer"] = "Beer Buddy" + options["Curacao"] = "Brilliant Blue" + options["Coffee"] = "Caffine Dispenser" + options["Space Mountain Wind"] = "Gamer Juice Maker" + options["Whiskey Soda"] = "Liqour Licker" + options["Grape Soda"] = "The Grapist" + options["Demon's Blood"] = "Vampire's Aid" + var/choice = input(M,"Choose your drink!") in options + if(src && choice && !M.stat && in_range(M,src)) + icontype = options[choice] + var/active_sound = 'sound/effects/bubbles.ogg' + playsound(src.loc, "[active_sound]", 100, 0, 4) + M << "Your Tank now displays [choice]. Drink up and enjoy!" + updateicon() + return 1 diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index cc5e4aaced7..7f6a4475b89 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -716,3 +716,10 @@ recycles = FALSE #undef SLEEPER_INJECT_COST + + +/obj/item/device/dogborg/sleeper/compactor/brewer + name = "Brew Belly" + desc = "A mounted drunk tank unit with fuel processor." + icon_state = "brewer" + injection_chems = null \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index cb7e7680070..4df9b63eee5 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -47,6 +47,7 @@ robot_modules["Sci-borg"] = /obj/item/weapon/robot_module/robot/science robot_modules["Pupdozer"] = /obj/item/weapon/robot_module/robot/engiedog robot_modules["Service-Hound"] = /obj/item/weapon/robot_module/robot/clerical/brodog + robot_modules["BoozeHound"] = /obj/item/weapon/robot_module/robot/booze robot_modules["KMine"] = /obj/item/weapon/robot_module/robot/kmine return 1 @@ -812,3 +813,75 @@ R.verbs -= /mob/living/proc/shred_limb R.verbs -= /mob/living/silicon/robot/proc/rest_style ..() + + +/obj/item/weapon/robot_module/robot/booze + name = "BoozeHound robot module" + channels = list("Service" = 1) + pto_type = PTO_CIVILIAN + can_be_pushed = 0 + sprites = list( + "Beer Buddy" = "boozeborg", + "Brilliant Blue" = "boozeborg(blue)", + "Caffine Dispenser" = "boozeborg(coffee)", + "Gamer Juice Maker" = "boozeborg(green)", + "Liqour Licker" = "boozeborg(orange)", + "The Grapist" = "boozeborg(purple)", + "Vampire's Aid" = "boozeborg(red)" + ) + +/obj/item/weapon/robot_module/robot/booze/New(var/mob/living/silicon/robot/R) + ..() + src.modules += new /obj/item/weapon/gripper/service(src) + //src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src) + //src.modules += new /obj/item/weapon/material/minihoe(src) + //src.modules += new /obj/item/device/analyzer/plant_analyzer(src) + //src.modules += new /obj/item/weapon/storage/bag/plants(src) + //src.modules += new /obj/item/weapon/robot_harvester(src) + src.modules += new /obj/item/weapon/material/knife(src) + src.modules += new /obj/item/weapon/material/kitchen/rollingpin(src) + src.modules += new /obj/item/device/multitool(src) //to freeze trays + src.modules += new /obj/item/weapon/dogborg/jaws/small(src) + src.modules += new /obj/item/weapon/tray/robotray + src.modules += new /obj/item/device/dogborg/boop_module(src) + src.modules += new /obj/item/device/dogborg/sleeper/compactor/brewer(src) + src.emag = new /obj/item/weapon/dogborg/pounce(src) + R.verbs += /mob/living/silicon/robot/proc/reskin_booze + + var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src) + M.stored_matter = 30 + src.modules += M + + src.modules += new /obj/item/weapon/reagent_containers/dropper/industrial(src) + + var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src) + L.lit = 1 + src.modules += L + + src.modules += new /obj/item/weapon/tray/robotray(src) + src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src) + src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) + + var/datum/reagents/N = new/datum/reagents(50) + src.emag.reagents = N + N.my_atom = src.emag + N.add_reagent("beer2", 50) + src.emag.name = "Mickey Finn's Special Brew" + R.icon = 'icons/mob/widerobot_colors_vr.dmi' + R.wideborg_dept = 'icons/mob/widerobot_colors_vr.dmi' + R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' + R.ui_style_vr = TRUE + R.pixel_x = -16 + R.old_x = -16 + R.default_pixel_x = -16 + R.dogborg = TRUE + R.wideborg = TRUE + R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + ..() + +/obj/item/weapon/robot_module/robot/booze/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) + var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules + E.reagents.add_reagent("enzyme", 2 * amount) + if(src.emag) + var/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/B = src.emag + B.reagents.add_reagent("beer2", 2 * amount) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm index 45ce8eb9ad5..a84177f29c1 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm @@ -47,9 +47,10 @@ attack_armor_pen = 25 pixel_x = -16 - pixel_y = -16 + pixel_y = 0 + default_pixel_x = -16 old_x = -16 - old_y = -16 + old_y = 0 /mob/living/simple_mob/animal/giant_spider/nurse/eggless/lay_eggs(turf/T) return FALSE diff --git a/code/modules/multiz/movement_vr.dm b/code/modules/multiz/movement_vr.dm index bbca4eef0d6..cba6ebb6c58 100644 --- a/code/modules/multiz/movement_vr.dm +++ b/code/modules/multiz/movement_vr.dm @@ -1,6 +1,6 @@ /mob/living/handle_fall(var/turf/landing) - var/mob/drop_mob = locate(/mob, landing) + var/mob/drop_mob = locate(/mob/living, landing) if(locate(/obj/structure/stairs) in landing) for(var/atom/A in landing) @@ -17,7 +17,7 @@ if(!O.CanFallThru(src, landing)) return 1 - if(drop_mob && !(drop_mob == src) && ismob(drop_mob) && isliving(drop_mob)) //Shitload of checks. This is because the game finds various ways to screw me over. + if(drop_mob && !(drop_mob == src)) //Shitload of checks. This is because the game finds various ways to screw me over. var/mob/living/drop_living = drop_mob if(drop_living.dropped_onto(src)) return @@ -105,4 +105,4 @@ if(direction == UP) //on a turf below, trying to enter return 0 if(direction == DOWN) //on a turf above, trying to enter - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm index 1fd3503d41c..aa2d1a99f59 100644 --- a/code/modules/nifsoft/nif.dm +++ b/code/modules/nifsoft/nif.dm @@ -102,9 +102,6 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable //Draw me yo. update_icon() - if(!our_statclick) - our_statclick = new(null, "Open", src) - //Destructor cleans up references /obj/item/device/nif/Destroy() human = null @@ -127,6 +124,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable human.nif = src stat = NIF_INSTALLING H.verbs |= /mob/living/carbon/human/proc/set_nif_examine + menu = H.AddComponent(/datum/component/nif_menu) if(starting_software) for(var/path in starting_software) new path(src) @@ -169,6 +167,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable stat = NIF_PREINSTALL vis_update() H.verbs -= /mob/living/carbon/human/proc/set_nif_examine + qdel_null(menu) H.nif = null human = null install_done = null diff --git a/code/modules/nifsoft/nif_statpanel.dm b/code/modules/nifsoft/nif_statpanel.dm deleted file mode 100644 index 00e928429fb..00000000000 --- a/code/modules/nifsoft/nif_statpanel.dm +++ /dev/null @@ -1,79 +0,0 @@ -/mob/living/carbon/human/Stat() - . = ..() - if(nif && statpanel("NIF")) - SetupNifStat() - -/mob/living/carbon/human/proc/SetupNifStat() - var/nif_status = "" - var/nif_percent = round((nif.durability/initial(nif.durability))*100) - switch(nif.stat) - if(NIF_WORKING) - if(nif_percent < 20) - nif_status = "Service Needed Soon" - else - nif_status = "Operating Normally" - if(NIF_POWFAIL) - nif_status = "Insufficient Energy!" - if(NIF_TEMPFAIL) - nif_status = "System Failure!" - if(NIF_INSTALLING) - nif_status = "Adapting To User" - else - nif_status = "Unknown - Error" - nif_status += " (Condition: [nif_percent]%)" - stat("NIF Status", nif_status) - stat("UI", nif.our_statclick) // TGUI Hook - - if(nif.stat == NIF_WORKING) - stat("- Modules -", "LMB: Toggle, Shift+LMB: Info/Uninstall") - for(var/nifsoft in nif.nifsofts) - if(!nifsoft) continue - var/datum/nifsoft/NS = nifsoft - var/obj/effect/nif_stat/stat_line = NS.stat_line - stat("[stat_line.nifsoft_name]",stat_line.atom_button_text()) - -/////////////////// -// Stat Line Object -/obj/effect/nif_stat - name = "" - var/nifsoft_name //Prevents deeper lookups, and the name won't change - var/datum/nifsoft/nifsoft //Reference to our nifsoft - var/toggleable = FALSE //Won't change, prevents looking it up deeper - -/obj/effect/nif_stat/New(var/datum/nifsoft/new_soft) - ..() - nifsoft = new_soft - nifsoft_name = new_soft.name - name = new_soft.name - -/obj/effect/nif_stat/Destroy() - nifsoft = null - return ..() - -/obj/effect/nif_stat/proc/atom_button_text() - name = nifsoft.stat_text() - return src - -/obj/effect/nif_stat/Click(var/location, var/control, var/params) - if(usr != nifsoft.nif.human) return - - var/list/clickprops = params2list(params) - var/opts = clickprops["shift"] - - if(opts) - var/choice = alert("Select an option","[nifsoft_name]","Display Info","Cancel","Uninstall") - switch(choice) - if("Display Info") - nifsoft.nif.notify("[nifsoft_name]: [nifsoft.desc] - It consumes [nifsoft.p_drain] energy units \ - while installed, and [nifsoft.a_drain] additionally while active. It is [nifsoft.illegal ? "NOT " : ""]\ - a legal software package. The MSRP of the package is [nifsoft.cost] Thalers. The difficulty to construct \ - the associated implant is Rating [nifsoft.wear].") - if("Uninstall") - var/confirm = alert("Really uninstall [nifsoft_name]?","Are you sure?","Cancel","Uninstall","Cancel") - if(confirm == "Uninstall") - nifsoft.uninstall() - else if(nifsoft.activates) - if(nifsoft.active) - nifsoft.deactivate() - else - nifsoft.activate() diff --git a/code/modules/nifsoft/nif_tgui.dm b/code/modules/nifsoft/nif_tgui.dm index 23d8102f793..b3d3aa00a7a 100644 --- a/code/modules/nifsoft/nif_tgui.dm +++ b/code/modules/nifsoft/nif_tgui.dm @@ -15,15 +15,75 @@ "retro", "syndicate" ) - var/tmp/obj/effect/statclick/nif_open/our_statclick var/tmp/last_notification + var/tmp/datum/component/nif_menu/menu /** - * Special stat button for the interface + * Small helper component to manage the HUD icon */ -/obj/effect/statclick/nif_open -/obj/effect/statclick/nif_open/Click(location, control, params) - var/obj/item/device/nif/N = target +/datum/component/nif_menu + var/obj/screen/nif/screen_icon + +/datum/component/nif_menu/Initialize() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + . = ..() + +/datum/component/nif_menu/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button) + var/mob/owner = parent + if(owner.client) + create_mob_button(parent) + +/datum/component/nif_menu/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN) + if(ismob(parent)) + var/mob/owner = parent + if(screen_icon) + owner?.client?.screen -= screen_icon + UnregisterSignal(screen_icon, COMSIG_CLICK) + qdel_null(screen_icon) + if(ishuman(parent)) + owner.verbs -= /mob/living/carbon/human/proc/nif_menu + + +/datum/component/nif_menu/proc/create_mob_button(mob/user) + var/datum/hud/HUD = user.hud_used + if(!screen_icon) + screen_icon = new() + screen_icon.icon = HUD.ui_style + HUD.other += screen_icon + user.client?.screen += screen_icon + + user.verbs |= /mob/living/carbon/human/proc/nif_menu + + RegisterSignal(screen_icon, COMSIG_CLICK, .proc/nif_menu_click) + +/datum/component/nif_menu/proc/nif_menu_click(atom/movable/screen/nif/image, location, control, params, user) + var/mob/living/carbon/human/H = user + if(istype(H) && H.nif) + INVOKE_ASYNC(H.nif, .proc/tgui_interact, user) + +/** + * Screen object for NIF menu access + */ +/obj/screen/nif + name = "nif menu" + icon = 'icons/mob/screen/midnight.dmi' + icon_state = "nif" + screen_loc = ui_smallquad + +/** + * Verb to open the interface + */ +/mob/living/carbon/human/proc/nif_menu() + set name = "NIF Menu" + set category = "IC" + set desc = "Open the NIF user interface." + + var/obj/item/device/nif/N = nif if(istype(N)) N.tgui_interact(usr) @@ -111,4 +171,4 @@ return TRUE if("dismissNotification") last_notification = null - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/nifsoft/nifsoft.dm b/code/modules/nifsoft/nifsoft.dm index ca1d0199a69..951e2932183 100644 --- a/code/modules/nifsoft/nifsoft.dm +++ b/code/modules/nifsoft/nifsoft.dm @@ -39,15 +39,11 @@ var/list/incompatible_with = null // List of NIFSofts that are disabled when this one is enabled - var/obj/effect/nif_stat/stat_line // The stat line in the statpanel for this NIFSoft - - //Constructor accepts the NIF it's being loaded into /datum/nifsoft/New(var/obj/item/device/nif/nif_load) ASSERT(nif_load) nif = nif_load - stat_line = new(src) if(!install(nif)) qdel(src) @@ -56,7 +52,6 @@ if(nif) uninstall() nif = null - QDEL_NULL(stat_line) return ..() //Called when the software is installed in the NIF @@ -138,7 +133,7 @@ /datum/nifsoft/proc/disk_install(var/mob/living/carbon/human/target,var/mob/living/carbon/human/user) return TRUE -//Stat-line clickable text +//Status text for menu /datum/nifsoft/proc/stat_text() if(activates) return "[active ? "Active" : "Disabled"]" diff --git a/code/modules/persistence/datum/datum_paper_sticky.dm b/code/modules/persistence/datum/datum_paper_sticky.dm deleted file mode 100644 index 1871eb4a037..00000000000 --- a/code/modules/persistence/datum/datum_paper_sticky.dm +++ /dev/null @@ -1,28 +0,0 @@ -/datum/persistent/paper/sticky - name = "stickynotes" - paper_type = /obj/item/weapon/paper/sticky - requires_noticeboard = FALSE - tokens_per_line = 10 - -/datum/persistent/paper/sticky/LabelTokens(var/list/tokens) - var/list/labelled_tokens = ..() - var/entries = LAZYLEN(labelled_tokens) - labelled_tokens["offset_x"] = tokens[entries+1] - labelled_tokens["offset_y"] = tokens[entries+2] - labelled_tokens["color"] = tokens[entries+3] - return labelled_tokens - -/datum/persistent/paper/sticky/CreateEntryInstance(var/turf/creating, var/list/tokens) - var/atom/paper = ..() - if(paper) - paper.pixel_x = text2num(tokens["offset_x"]) - paper.pixel_y = text2num(tokens["offset_y"]) - paper.color = tokens["color"] - return paper - -/datum/persistent/paper/sticky/CompileEntry(var/atom/entry, var/write_file) - . = ..() - var/obj/item/weapon/paper/sticky/paper = entry - LAZYADD(., "[paper.pixel_x]") - LAZYADD(., "[paper.pixel_y]") - LAZYADD(., "[paper.color]") \ No newline at end of file diff --git a/code/modules/persistence/datum/persistence_datum.dm b/code/modules/persistence/datum/persistence_datum.dm index e001e12e302..a52b57fb66c 100644 --- a/code/modules/persistence/datum/persistence_datum.dm +++ b/code/modules/persistence/datum/persistence_datum.dm @@ -3,15 +3,11 @@ // of persistent data like graffiti and round to round filth. /datum/persistent - var/name + var/name = null var/filename - var/tokens_per_line var/entries_expire_at // Set in rounds, this controls when the item is finally removed permanently regardless if cleaned or not. var/entries_decay_at // Set in rounds. This controls when item messages start getting scrambled. var/entry_decay_weight = 0.5 - var/file_entry_split_character = "\t" - var/file_entry_substitute_character = " " - var/file_line_split_character = "\n" var/has_admin_data /datum/persistent/New() @@ -20,63 +16,57 @@ /datum/persistent/proc/SetFilename() if(name) - filename = "data/persistent/[lowertext(using_map.name)]-[lowertext(name)].txt" + filename = "data/persistent/[lowertext(using_map.name)]-[lowertext(name)].json" if(!isnull(entries_decay_at) && !isnull(entries_expire_at)) entries_decay_at = round(entries_expire_at * entries_decay_at) -/datum/persistent/proc/LabelTokens(var/list/tokens) - var/list/labelled_tokens = list() - labelled_tokens["x"] = text2num(tokens[1]) - labelled_tokens["y"] = text2num(tokens[2]) - labelled_tokens["z"] = text2num(tokens[3]) - labelled_tokens["age"] = text2num(tokens[4]) - return labelled_tokens - -/datum/persistent/proc/GetValidTurf(var/turf/T, var/list/tokens) - if(T && CheckTurfContents(T, tokens)) +/datum/persistent/proc/GetValidTurf(var/turf/T, var/list/token) + if(T && CheckTurfContents(T, token)) return T -/datum/persistent/proc/CheckTurfContents(var/turf/T, var/list/tokens) +/datum/persistent/proc/CheckTurfContents(var/turf/T, var/list/token) return TRUE -/datum/persistent/proc/CheckTokenSanity(var/list/tokens) +/datum/persistent/proc/CheckTokenSanity(var/list/token) return ( \ - !isnull(tokens["x"]) && \ - !isnull(tokens["y"]) && \ - !isnull(tokens["z"]) && \ - !isnull(tokens["age"]) && \ - tokens["age"] <= entries_expire_at \ + !isnull(token["x"]) && \ + !isnull(token["y"]) && \ + !isnull(token["z"]) && \ + !isnull(token["age"]) && \ + token["age"] <= entries_expire_at \ ) -/datum/persistent/proc/CreateEntryInstance(var/turf/creating, var/list/tokens) +// Restores saved data to world +/datum/persistent/proc/CreateEntryInstance(var/turf/creating, var/list/token) return /datum/persistent/proc/ProcessAndApplyTokens(var/list/tokens) // If it's old enough we start to trim down any textual information and scramble strings. - if(tokens["message"] && !isnull(entries_decay_at) && !isnull(entry_decay_weight)) - var/_n = tokens["age"] - var/_message = tokens["message"] - if(_n >= entries_decay_at) - var/decayed_message = "" - for(var/i = 1 to length(_message)) - var/char = copytext(_message, i, i + 1) - if(prob(round(_n * entry_decay_weight))) - if(prob(99)) - decayed_message += pick(".",",","-","'","\\","/","\"",":",";") - else - decayed_message += char - _message = decayed_message - if(length(_message)) - tokens["message"] = _message - else - return + for(var/list/token in tokens) + if(token["message"] && !isnull(entries_decay_at) && !isnull(entry_decay_weight)) + var/_n = token["age"] + var/_message = token["message"] + if(_n >= entries_decay_at) + var/decayed_message = "" + for(var/i = 1 to length(_message)) + var/char = copytext(_message, i, i + 1) + if(prob(round(_n * entry_decay_weight))) + if(prob(99)) + decayed_message += pick(".",",","-","'","\\","/","\"",":",";") + else + decayed_message += char + _message = decayed_message + if(length(_message)) + token["message"] = _message + else + return - var/_z = tokens["z"] - if(_z in using_map.station_levels) - . = GetValidTurf(locate(tokens["x"], tokens["y"], _z), tokens) - if(.) - CreateEntryInstance(., tokens) + var/_z = token["z"] + if(_z in using_map.station_levels) + . = GetValidTurf(locate(token["x"], token["y"], _z), token) + if(.) + CreateEntryInstance(., token) /datum/persistent/proc/IsValidEntry(var/atom/entry) if(!istype(entry)) @@ -96,46 +86,46 @@ /datum/persistent/proc/CompileEntry(var/atom/entry) var/turf/T = get_turf(entry) - . = list( - T.x, - T.y, - T.z, - GetEntryAge(entry) + return list( + "x" = T.x, + "y" = T.y, + "z" = T.z, + "age" = GetEntryAge(entry) ) /datum/persistent/proc/Initialize() if(fexists(filename)) - for(var/entry_line in file2list(filename, file_line_split_character)) - if(!entry_line) - continue - var/list/tokens = splittext(entry_line, file_entry_split_character) - if(LAZYLEN(tokens) < tokens_per_line) - continue - tokens = LabelTokens(tokens) - if(!CheckTokenSanity(tokens)) - continue - ProcessAndApplyTokens(tokens) + var/list/tokens = json_decode(file2text(filename)) + for(var/list/token in tokens) + if(!CheckTokenSanity(token)) + tokens -= token + ProcessAndApplyTokens(tokens) /datum/persistent/proc/Shutdown() if(fexists(filename)) fdel(filename) - var/write_file = file(filename) + + var/list/to_store = list() for(var/thing in SSpersistence.tracking_values[type]) - if(IsValidEntry(thing)) - var/list/entry = CompileEntry(thing) - if(LAZYLEN(entry) == tokens_per_line) - for(var/i = 1 to LAZYLEN(entry)) - if(istext(entry[i])) - entry[i] = replacetext(entry[i], file_entry_split_character, file_entry_substitute_character) - to_file(write_file, jointext(entry, file_entry_split_character)) + if(!IsValidEntry(thing)) + continue + to_store[++to_store.len] = CompileEntry(thing) + + if(to_store.len) + to_file(file(filename), json_encode(to_store)) /datum/persistent/proc/RemoveValue(var/atom/value) qdel(value) /datum/persistent/proc/GetAdminSummary(var/mob/user, var/can_modify) + var/list/my_tracks = SSpersistence.tracking_values[type] + if(!my_tracks?.len) + return + . = list("[capitalize(name)]") . += "
" - for(var/thing in SSpersistence.tracking_values[type]) + + for(var/thing in my_tracks) . += "[GetAdminDataStringFor(thing, can_modify, user)]" . += "
" diff --git a/code/modules/persistence/datum/datum_filth.dm b/code/modules/persistence/effects/filth.dm similarity index 59% rename from code/modules/persistence/datum/datum_filth.dm rename to code/modules/persistence/effects/filth.dm index 10b304e18ee..166c374c02c 100644 --- a/code/modules/persistence/datum/datum_filth.dm +++ b/code/modules/persistence/effects/filth.dm @@ -1,26 +1,22 @@ /datum/persistent/filth name = "filth" - tokens_per_line = 5 entries_expire_at = 4 // 4 rounds, 24 hours. -/datum/persistent/filth/LabelTokens(var/list/tokens) - var/list/labelled_tokens = ..() - labelled_tokens["path"] = text2path(tokens[LAZYLEN(labelled_tokens)+1]) - return labelled_tokens - /datum/persistent/filth/IsValidEntry(var/atom/entry) . = ..() && entry.invisibility == 0 -/datum/persistent/filth/CheckTokenSanity(var/list/tokens) - return ..() && ispath(tokens["path"]) +/datum/persistent/filth/CheckTokenSanity(var/list/token) + // byond's json implementation is "questionable", and uses types as keys and values without quotes sometimes even though they aren't valid json + token["path"] = istext(token["path"]) ? text2path(token["path"]) : token["path"] + return ..() && ispath(token["path"]) -/datum/persistent/filth/CheckTurfContents(var/turf/T, var/list/tokens) - var/_path = tokens["path"] +/datum/persistent/filth/CheckTurfContents(var/turf/T, var/list/token) + var/_path = token["path"] return (locate(_path) in T) ? FALSE : TRUE -/datum/persistent/filth/CreateEntryInstance(var/turf/creating, var/list/tokens) - var/_path = tokens["path"] - new _path(creating, tokens["age"]+1) +/datum/persistent/filth/CreateEntryInstance(var/turf/creating, var/list/token) + var/_path = token["path"] + new _path(creating, token["age"]+1) /datum/persistent/filth/GetEntryAge(var/atom/entry) var/obj/effect/decal/cleanable/filth = entry @@ -32,4 +28,4 @@ /datum/persistent/filth/CompileEntry(var/atom/entry) . = ..() - LAZYADD(., "[GetEntryPath(entry)]") \ No newline at end of file + LAZYADDASSOC(., "path", "[GetEntryPath(entry)]") \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_graffiti.dm b/code/modules/persistence/effects/graffiti.dm similarity index 72% rename from code/modules/persistence/datum/datum_graffiti.dm rename to code/modules/persistence/effects/graffiti.dm index 6ca1bbf32f9..369f9156b49 100644 --- a/code/modules/persistence/datum/datum_graffiti.dm +++ b/code/modules/persistence/effects/graffiti.dm @@ -1,22 +1,14 @@ /datum/persistent/graffiti name = "graffiti" - tokens_per_line = 6 entries_expire_at = 4 // This previously was at 50 rounds??? Over 10 days. has_admin_data = TRUE -/datum/persistent/graffiti/LabelTokens(var/list/tokens) - var/list/labelled_tokens = ..() - var/entries = LAZYLEN(labelled_tokens) - labelled_tokens["author"] = tokens[entries+1] - labelled_tokens["message"] = tokens[entries+2] - return labelled_tokens - -/datum/persistent/graffiti/GetValidTurf(var/turf/T, var/list/tokens) +/datum/persistent/graffiti/GetValidTurf(var/turf/T, var/list/token) var/turf/checking_turf = ..() if(istype(checking_turf) && checking_turf.can_engrave()) return checking_turf -/datum/persistent/graffiti/CheckTurfContents(var/turf/T, var/list/tokens) +/datum/persistent/graffiti/CheckTurfContents(var/turf/T, var/list/token) var/too_much_graffiti = 0 for(var/obj/effect/decal/writing/W in .) too_much_graffiti++ @@ -24,8 +16,10 @@ return FALSE return TRUE -/datum/persistent/graffiti/CreateEntryInstance(var/turf/creating, var/list/tokens) - new /obj/effect/decal/writing(creating, tokens["age"]+1, tokens["message"], tokens["author"]) +/datum/persistent/graffiti/CreateEntryInstance(var/turf/creating, var/list/token) + var/obj/effect/decal/writing/inst = new /obj/effect/decal/writing(creating, token["age"]+1, token["message"], token["author"]) + if(token["icon_state"]) + inst.icon_state = token["icon_state"] /datum/persistent/graffiti/IsValidEntry(var/atom/entry) . = ..() @@ -40,8 +34,9 @@ /datum/persistent/graffiti/CompileEntry(var/atom/entry, var/write_file) . = ..() var/obj/effect/decal/writing/save_graffiti = entry - LAZYADD(., "[save_graffiti.author ? save_graffiti.author : "unknown"]") - LAZYADD(., "[save_graffiti.message]") + LAZYADDASSOC(., "author", "[save_graffiti.author ? save_graffiti.author : "unknown"]") + LAZYADDASSOC(., "message", "[save_graffiti.message]") + LAZYADDASSOC(., "icon_state", "[save_graffiti.icon_state]") /datum/persistent/graffiti/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) var/obj/effect/decal/writing/save_graffiti = thing diff --git a/code/modules/persistence/datum/datum_paper.dm b/code/modules/persistence/effects/paper.dm similarity index 74% rename from code/modules/persistence/datum/datum_paper.dm rename to code/modules/persistence/effects/paper.dm index fe2ef813681..95968274eba 100644 --- a/code/modules/persistence/datum/datum_paper.dm +++ b/code/modules/persistence/effects/paper.dm @@ -1,32 +1,24 @@ /datum/persistent/paper name = "paper" - tokens_per_line = 7 entries_expire_at = 50 has_admin_data = TRUE var/paper_type = /obj/item/weapon/paper var/requires_noticeboard = TRUE -/datum/persistent/paper/LabelTokens(var/list/tokens) - var/list/labelled_tokens = ..() - var/entries = LAZYLEN(labelled_tokens) - labelled_tokens["author"] = tokens[entries+1] - labelled_tokens["message"] = tokens[entries+2] - labelled_tokens["title"] = tokens[entries+3] - return labelled_tokens - -/datum/persistent/paper/CheckTurfContents(var/turf/T, var/list/tokens) +/datum/persistent/paper/CheckTurfContents(var/turf/T, var/list/token) if(requires_noticeboard && !(locate(/obj/structure/noticeboard) in T)) new /obj/structure/noticeboard(T) . = ..() -/datum/persistent/paper/CreateEntryInstance(var/turf/creating, var/list/tokens) +/datum/persistent/paper/CreateEntryInstance(var/turf/creating, var/list/token) var/obj/structure/noticeboard/board = locate() in creating if(requires_noticeboard && LAZYLEN(board.notices) >= board.max_notices) return var/obj/item/weapon/paper/paper = new paper_type(creating) - paper.info = tokens["message"] - paper.name = tokens["title"] - paper.last_modified_ckey = tokens["author"] + paper.info = token["message"] + paper.name = token["title"] + paper.last_modified_ckey = token["author"] + paper.age = token["age"]+1 if(requires_noticeboard) board.add_paper(paper) if(!paper.was_maploaded) // If we were created/loaded when the map was made, skip us! @@ -40,9 +32,9 @@ /datum/persistent/paper/CompileEntry(var/atom/entry, var/write_file) . = ..() var/obj/item/weapon/paper/paper = entry - LAZYADD(., "[paper.last_modified_ckey ? paper.last_modified_ckey : "unknown"]") - LAZYADD(., "[paper.info]") - LAZYADD(., "[paper.name]") + LAZYADDASSOC(., "author", "[paper.last_modified_ckey ? paper.last_modified_ckey : "unknown"]") + LAZYADDASSOC(., "message", "[paper.info]") + LAZYADDASSOC(., "name", "[paper.name]") /datum/persistent/paper/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) var/obj/item/weapon/paper/paper = thing diff --git a/code/modules/persistence/effects/paper_sticky.dm b/code/modules/persistence/effects/paper_sticky.dm new file mode 100644 index 00000000000..08fb9050093 --- /dev/null +++ b/code/modules/persistence/effects/paper_sticky.dm @@ -0,0 +1,23 @@ +/datum/persistent/paper/sticky + name = "stickynotes" + paper_type = /obj/item/weapon/paper/sticky + requires_noticeboard = FALSE + +/datum/persistent/paper/sticky/CreateEntryInstance(var/turf/creating, var/list/token) + var/atom/paper = ..() + if(paper) + if(prob(90)) + paper.pixel_x = token["offset_x"] + paper.pixel_y = token["offset_y"] + else + paper.pixel_x = rand(-5,5) + paper.pixel_y = rand(-5,5) + paper.color = token["color"] + return paper + +/datum/persistent/paper/sticky/CompileEntry(var/atom/entry, var/write_file) + . = ..() + var/obj/item/weapon/paper/sticky/paper = entry + LAZYADDASSOC(., "offset_x", paper.pixel_x) + LAZYADDASSOC(., "offset_y", paper.pixel_y) + LAZYADDASSOC(., "color", paper.color) \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_trash.dm b/code/modules/persistence/effects/trash.dm similarity index 100% rename from code/modules/persistence/datum/datum_trash.dm rename to code/modules/persistence/effects/trash.dm diff --git a/code/modules/persistence/persistence.dm b/code/modules/persistence/serialize.dm similarity index 100% rename from code/modules/persistence/persistence.dm rename to code/modules/persistence/serialize.dm diff --git a/code/modules/persistence/storage/smartfridge.dm b/code/modules/persistence/storage/smartfridge.dm new file mode 100644 index 00000000000..0584ab9e79e --- /dev/null +++ b/code/modules/persistence/storage/smartfridge.dm @@ -0,0 +1,97 @@ +/datum/persistent/storage/smartfridge/get_storage_list(var/obj/machinery/smartfridge/entry) + if(!istype(entry)) + return ..() + + . = list() + for(var/datum/stored_item/I in entry.item_records) + .[I.item_path] = I.get_amount() + +/datum/persistent/storage/smartfridge/CreateEntryInstance(var/turf/creating, var/list/token) + var/obj/machinery/smartfridge/S = find_specific_instance(creating) + var/list/L = generate_items(token["items"]) + for(var/atom/A in L) + if(S.accept_check(A)) + S.stock(A) + else + qdel(A) // Should clean this up here, it couldn't be stocked + + + + + +/datum/persistent/storage/smartfridge/sheet_storage + name = "sheet storage" + max_storage = 50 + store_per_type = TRUE + target_type = /obj/machinery/smartfridge/sheets + + var/stacks_go_missing = FALSE // Variable rate depletion of stacks inter-round + +/datum/persistent/storage/smartfridge/sheet_storage/lossy + name = "sheet storage lossy" + max_storage = 250 + stacks_go_missing = TRUE + +/datum/persistent/storage/smartfridge/sheet_storage/generate_items(var/list/L) + . = list() + for(var/obj/item/stack/material/S as anything in L) + var/real_path = istext(S) ? text2path(S) : S + if(!ispath(real_path, /obj/item/stack/material)) + log_debug("Warning: Sheet_storage persistent datum tried to create [S]") + continue + + // Skip entire stack if we hit the chance + if(prob(go_missing_chance)) + continue + + var/count = L[S] + + var/obj/item/stack/material/inst = real_path + var/max_amount = initial(inst.max_amount) + + // Delete some stacks if we want + if(stacks_go_missing) + var/fuzzy = rand(-5,5) + switch(count / max_amount) + if(0 to 1) + count -= 10+fuzzy // 1 stack or less, lose 10 + if(1 to 10) + count -= max_amount+fuzzy // 1 to 10 stacks, lose a stack + if(10 to INFINITY) + count -= max_amount*3+fuzzy // 10+ stacks, lose 3 stacks + if(count <= 0) + continue + + while(count > 0) + inst = new real_path + inst.amount = min(count, max_amount) + count -= inst.get_amount() + . += inst + + +/datum/persistent/storage/smartfridge/produce + name = "fruit storage" + max_storage = 50 + store_per_type = FALSE + target_type = /obj/machinery/smartfridge/produce + +/datum/persistent/storage/smartfridge/produce/lossy + name = "fruit storage lossy" + go_missing_chance = 12.5 // 10% loss between rounds + +/datum/persistent/storage/smartfridge/produce/create_item(var/seedtype) + return new /obj/item/weapon/reagent_containers/food/snacks/grown(null, seedtype) // Smartfridge will be stock()ed with it, loc is unimportant + +/datum/persistent/storage/smartfridge/produce/get_storage_list(var/obj/machinery/smartfridge/produce/entry) + if(!istype(entry)) + return ..() + + . = list() + for(var/datum/stored_item/I in entry.item_records) + if(prob(go_missing_chance)) + continue + if(LAZYLEN(I.instances)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = I.instances[1] + if(!istype(G)) + continue + .[G.plantname] = I.get_amount() // Store the seed type, because that's what's used to generate the fruit \ No newline at end of file diff --git a/code/modules/persistence/storage/storage.dm b/code/modules/persistence/storage/storage.dm new file mode 100644 index 00000000000..58b23a6ce94 --- /dev/null +++ b/code/modules/persistence/storage/storage.dm @@ -0,0 +1,74 @@ +/datum/persistent/storage + name = "storage" + entries_expire_at = 1 + has_admin_data = TRUE + + // Don't use these for storage persistence. If someone takes some sheets out and puts them back in mixed in with + // new sheets, how do you know the age of the stack? If you want sheets to 'decay', see go_missing_chance + entries_decay_at = 0 + entry_decay_weight = 0 + // // // // + + var/max_storage = 0 + var/store_per_type = FALSE // If true, will store up to max_storage for each type stored + var/target_type = null // Path of the thing that this expects to put stuff into + + var/go_missing_chance = 0 // Chance an item will fail to be spawned in from persistence and need to be restocked + +/datum/persistent/storage/SetFilename() + if(name) + filename = "data/persistent/storage/[lowertext(using_map.name)]-[lowertext(name)].json" + +/datum/persistent/storage/IsValidEntry(var/atom/entry) + return ..() && istype(entry, target_type) + +/datum/persistent/storage/CompileEntry(var/atom/entry) + . = ..() + var/stored = max_storage + var/list/item_list = get_storage_list(entry) + var/list/storage_list = list() + for(var/item in item_list) + storage_list[item] = min(stored, storage_list[item] + item_list[item]) // Can't store more than max_storage + + // stored gets reduced by qty stored, if greater than stored, + // previous assignment will handle overage, and we set to 0 + if(!store_per_type) + stored = max(stored - item_list[item], 0) + + LAZYADDASSOC(., "items", storage_list) + +// Usage: returns list with structure: +// list( +// [type1] = [stored_quantity], +// [type2] = [stored_quantity] +// ) +/datum/persistent/storage/proc/get_storage_list(var/atom/entry) + return list() // Subtypes define list structure + +/datum/persistent/storage/proc/find_specific_instance(var/turf/T) + return locate(target_type) in T + +/datum/persistent/storage/CheckTurfContents(var/turf/T, var/list/token) + return istype(find_specific_instance(T), target_type) + +/datum/persistent/storage/proc/generate_items(var/list/L) + . = list() + for(var/path in L) + // byond's json implementation is "questionable", and uses types as keys and values without quotes sometimes even though they aren't valid json + var/real_path = istext(path) ? text2path(path) : path + for(var/i in 1 to L[path]) + if(prob(go_missing_chance)) + continue + var/atom/A = create_item(real_path) + if(!QDELETED(A)) + . += A + +/datum/persistent/storage/proc/create_item(var/path) + return new path() + +/datum/persistent/storage/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) + var/atom/T = thing + if(!istype(T)) + return "" + else + . = "[T.name][T.x],[T.y],[T.z]" diff --git a/code/modules/reagents/reagents/dispenser.dm b/code/modules/reagents/reagents/dispenser.dm index 8d825ef91c7..6dd8a79285a 100644 --- a/code/modules/reagents/reagents/dispenser.dm +++ b/code/modules/reagents/reagents/dispenser.dm @@ -419,7 +419,7 @@ if(affecting.take_damage(0, removed * power * 0.1)) H.UpdateDamageIcon() if(prob(100 * removed / meltdose)) // Applies disfigurement - if (affecting.organ_can_feel_pain()) + if (affecting.organ_can_feel_pain() && !isbelly(H.loc)) //VOREStation Add H.emote("scream") H.status_flags |= DISFIGURED else diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index 3c56beda17a..8ff26d3d011 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -571,6 +571,7 @@ materials = list(DEFAULT_WALL_MATERIAL = 7500, "gold" = 750, "silver" = 1500, MAT_ALUMINIUM = 3750) build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid +/* These are way too OP to be buildable /datum/design/item/mecha/combat_shield name = "linear combat shield" desc = "Linear shield projector. Deploys a large, familiar, and rectangular shield in one direction at a time." @@ -586,6 +587,7 @@ req_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_ILLEGAL = 4) materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 3000, "phoron" = 5000, "glass" = 3750) build_path = /obj/item/mecha_parts/mecha_equipment/omni_shield +*/ /datum/design/item/mecha/crisis_drone name = "Crisis Drone" diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index 8444ddc1f86..359fc752e1b 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -38,6 +38,7 @@ killjaden - Protean ktccd - Diona liache - Black-Eyed Shadekin lizehrd - Xenochimera +lordlag - Black-Eyed Shadekin magpiemayhem - Vox marco_barko - Protean mewchild - Diona diff --git a/icons/mecha/fighters64x64.dmi b/icons/mecha/fighters64x64.dmi index 6025a94c864..4c9fd660bfa 100644 Binary files a/icons/mecha/fighters64x64.dmi and b/icons/mecha/fighters64x64.dmi differ diff --git a/icons/mob/dogborg_vr.dmi b/icons/mob/dogborg_vr.dmi index 0dc89d2b50a..30e0bb5e374 100644 Binary files a/icons/mob/dogborg_vr.dmi and b/icons/mob/dogborg_vr.dmi differ diff --git a/icons/mob/eyes_vr.dmi b/icons/mob/eyes_vr.dmi index 89805954f7a..f19fed9626a 100644 Binary files a/icons/mob/eyes_vr.dmi and b/icons/mob/eyes_vr.dmi differ diff --git a/icons/mob/screen/holo.dmi b/icons/mob/screen/holo.dmi index a0fff5d7819..8acd77b9b26 100644 Binary files a/icons/mob/screen/holo.dmi and b/icons/mob/screen/holo.dmi differ diff --git a/icons/mob/screen/midnight.dmi b/icons/mob/screen/midnight.dmi index b1f37cb2239..db6197abd9e 100644 Binary files a/icons/mob/screen/midnight.dmi and b/icons/mob/screen/midnight.dmi differ diff --git a/icons/mob/screen/minimalist.dmi b/icons/mob/screen/minimalist.dmi index a60c9b196ae..48ff4008640 100644 Binary files a/icons/mob/screen/minimalist.dmi and b/icons/mob/screen/minimalist.dmi differ diff --git a/icons/mob/screen/old-noborder.dmi b/icons/mob/screen/old-noborder.dmi index ddc72353ee3..b11c0b0d529 100644 Binary files a/icons/mob/screen/old-noborder.dmi and b/icons/mob/screen/old-noborder.dmi differ diff --git a/icons/mob/screen/old.dmi b/icons/mob/screen/old.dmi index f165b01b5bf..93d51e042a4 100644 Binary files a/icons/mob/screen/old.dmi and b/icons/mob/screen/old.dmi differ diff --git a/icons/mob/screen/orange.dmi b/icons/mob/screen/orange.dmi index d0b52d10d4a..c50d41b49b5 100644 Binary files a/icons/mob/screen/orange.dmi and b/icons/mob/screen/orange.dmi differ diff --git a/icons/mob/screen/white.dmi b/icons/mob/screen/white.dmi index 0a1a31bc31e..cf232ae5c36 100644 Binary files a/icons/mob/screen/white.dmi and b/icons/mob/screen/white.dmi differ diff --git a/icons/mob/screen1_robot_vr.dmi b/icons/mob/screen1_robot_vr.dmi index 162a3375090..33046af1959 100644 Binary files a/icons/mob/screen1_robot_vr.dmi and b/icons/mob/screen1_robot_vr.dmi differ diff --git a/icons/mob/widerobot_colors_vr.dmi b/icons/mob/widerobot_colors_vr.dmi new file mode 100644 index 00000000000..44295e3b891 Binary files /dev/null and b/icons/mob/widerobot_colors_vr.dmi differ diff --git a/icons/obj/card_new_vr.dmi b/icons/obj/card_new_vr.dmi index 20e3c855832..496b1fda27a 100644 Binary files a/icons/obj/card_new_vr.dmi and b/icons/obj/card_new_vr.dmi differ diff --git a/maps/expedition_vr/space/_debrisfield.dm b/maps/expedition_vr/space/_debrisfield.dm index f1b36da15ad..cf63350a596 100644 --- a/maps/expedition_vr/space/_debrisfield.dm +++ b/maps/expedition_vr/space/_debrisfield.dm @@ -184,10 +184,10 @@ shuttle_tag = "Debris Carrier" req_one_access = list() -/obj/mecha/combat/fighter/baron/loaded/busted +/obj/mecha/combat/fighter/baron/busted starting_components = list(/obj/item/mecha_parts/component/hull/lightweight,/obj/item/mecha_parts/component/actuator/hispeed,/obj/item/mecha_parts/component/armor,/obj/item/mecha_parts/component/gas,/obj/item/mecha_parts/component/electrical/high_current) -/obj/mecha/combat/fighter/baron/loaded/busted/Initialize() +/obj/mecha/combat/fighter/baron/busted/Initialize() . = ..() health = round(rand(50,120)) cell?.charge = 0 diff --git a/maps/offmap_vr/om_ships/shelter_6.dmm b/maps/offmap_vr/om_ships/shelter_6.dmm index 5918d23ad43..c7d3a9fec8b 100644 --- a/maps/offmap_vr/om_ships/shelter_6.dmm +++ b/maps/offmap_vr/om_ships/shelter_6.dmm @@ -1561,12 +1561,13 @@ /obj/machinery/mech_recharger{ icon = 'icons/turf/shuttle_alien_blue.dmi' }, -/obj/mecha/combat/fighter/baron{ +/obj/mecha/combat/fighter/baron/loaded{ ground_capable = 1; - health = 800; - internal_damage_threshold = 100; - maxhealth = 800; - name = "Panther" + health = 600; + maxhealth = 600; + name = "Duke"; + desc = "A heavily modified Baron-class fighter from the commonwealth. It has been retrofitted with heavier armor and additional maneuvering thrusters. Can be used in atmospheric operations."; + starting_components = list(/obj/item/mecha_parts/component/hull/lightweight,/obj/item/mecha_parts/component/actuator/hispeed,/obj/item/mecha_parts/component/armor/military,/obj/item/mecha_parts/component/gas/reinforced,/obj/item/mecha_parts/component/electrical) }, /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) diff --git a/maps/offmap_vr/talon/talon_v2.dmm b/maps/offmap_vr/talon/talon_v2.dmm index 53aa8895f59..1e00adc6a00 100644 --- a/maps/offmap_vr/talon/talon_v2.dmm +++ b/maps/offmap_vr/talon/talon_v2.dmm @@ -1679,6 +1679,18 @@ /obj/structure/closet/walllocker_double/hydrant/west, /turf/simulated/floor/tiled/techmaint, /area/talon_v2/secure_storage) +"fk" = ( +/obj/structure/railing/grey{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/smartfridge/sheets/persistent_lossy{ + layer = 3.3 + }, +/turf/simulated/floor/tiled/techfloor, +/area/talon_v2/refining) "fm" = ( /obj/machinery/door/airlock/glass_external{ req_one_access = list(301) @@ -8802,7 +8814,9 @@ /obj/structure/closet/walllocker/medical/north, /obj/item/weapon/storage/firstaid/regular, /obj/item/weapon/storage/firstaid/o2, -/obj/item/device/radio/off/talon, +/obj/item/device/radio/off{ + channels = list("Talon" = 1) + }, /turf/simulated/floor/wood, /area/talon_v2/crew_quarters/cap_room) "Fk" = ( @@ -11190,7 +11204,10 @@ pixel_y = 24 }, /obj/structure/table/rack/shelf/steel, -/obj/item/device/radio/off/talon, +/obj/item/device/radio/off{ + channels = list("Talon" = 1); + pixel_y = 6 + }, /turf/simulated/floor/tiled/techfloor, /area/talon_v2/armory) "Nw" = ( @@ -26588,7 +26605,7 @@ ca rj fW jS -tX +fk VS mQ ZR diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index c7f43260bad..c6767f4d7d3 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -66668,10 +66668,6 @@ /turf/simulated/floor/tiled, /area/quartermaster/foyer) "cvi" = ( -/obj/structure/bed/chair, -/obj/machinery/alarm{ - pixel_y = 22 - }, /obj/effect/floor_decal/borderfloor/corner{ dir = 1 }, @@ -70398,6 +70394,10 @@ /obj/effect/floor_decal/corner/brown/bordercorner2{ dir = 9 }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -22 + }, /turf/simulated/floor/tiled, /area/quartermaster/foyer) "cCs" = ( @@ -86952,9 +86952,9 @@ /turf/simulated/floor/plating, /area/maintenance/bar) "deS" = ( -/obj/machinery/smartfridge, /obj/structure/disposalpipe/segment, -/turf/simulated/wall/r_wall, +/obj/machinery/smartfridge/produce/persistent, +/turf/simulated/floor/plating, /area/hydroponics) "deT" = ( /turf/simulated/wall, @@ -114220,6 +114220,10 @@ }, /turf/simulated/floor/tiled, /area/hallway/primary/seconddeck/stairwell) +"xjf" = ( +/obj/machinery/smartfridge/sheets/persistent, +/turf/simulated/floor/plating, +/area/quartermaster/foyer) (1,1,1) = {" aaa @@ -201992,7 +201996,7 @@ cmS chE cpX crX -ctL +xjf cvi cxl cxl diff --git a/maps/submaps/admin_use_vr/kk_mercship.dmm b/maps/submaps/admin_use_vr/kk_mercship.dmm index 362023e72c4..c1d6949036c 100644 --- a/maps/submaps/admin_use_vr/kk_mercship.dmm +++ b/maps/submaps/admin_use_vr/kk_mercship.dmm @@ -4199,7 +4199,6 @@ "sM" = ( /obj/structure/table/rack, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, -/obj/item/mecha_parts/mecha_equipment/omni_shield, /obj/item/mecha_parts/mecha_equipment/repair_droid, /obj/machinery/firealarm/alarms_hidden{ pixel_y = 26 diff --git a/maps/submaps/pois_vr/debris_field/tinycarrier.dmm b/maps/submaps/pois_vr/debris_field/tinycarrier.dmm index 5be1f1456bb..908afdd05d1 100644 --- a/maps/submaps/pois_vr/debris_field/tinycarrier.dmm +++ b/maps/submaps/pois_vr/debris_field/tinycarrier.dmm @@ -1109,7 +1109,7 @@ /turf/simulated/floor/reinforced/airless, /area/submap/debrisfield/tinyshuttle/hangar) "bW" = ( -/obj/mecha/combat/fighter/baron/loaded/busted{ +/obj/mecha/combat/fighter/baron/busted{ dir = 8; dir_in = 8 }, diff --git a/maps/tether/submaps/_tether_submaps.dm b/maps/tether/submaps/_tether_submaps.dm index cbcc1b5c369..f1f848972c1 100644 --- a/maps/tether/submaps/_tether_submaps.dm +++ b/maps/tether/submaps/_tether_submaps.dm @@ -527,6 +527,6 @@ /datum/map_z_level/tether_lateload/talon_v2 name = "Talon" - flags = MAP_LEVEL_PLAYER + flags = MAP_LEVEL_PLAYER|MAP_LEVEL_PERSIST base_turf = /turf/space z = Z_LEVEL_OFFMAP1 \ No newline at end of file diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index 40b1869e5c4..dd0c6dd9ea1 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -18423,13 +18423,13 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "aDX" = ( -/obj/machinery/smartfridge, /obj/effect/floor_decal/borderfloor{ dir = 1 }, /obj/effect/floor_decal/corner/lime/border{ dir = 1 }, +/obj/machinery/smartfridge/produce/persistent_lossy, /turf/simulated/floor/tiled, /area/tether/surfacebase/botanystorage) "aDY" = ( diff --git a/maps/tether/tether-07-station3.dmm b/maps/tether/tether-07-station3.dmm index 9717e5f4f0e..af77aa1e468 100644 --- a/maps/tether/tether-07-station3.dmm +++ b/maps/tether/tether-07-station3.dmm @@ -19061,7 +19061,6 @@ /turf/simulated/floor, /area/maintenance/station/ai) "aSj" = ( -/obj/structure/closet/emcloset, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, @@ -19534,6 +19533,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, +/obj/structure/closet/emcloset, /turf/simulated/floor/tiled, /area/quartermaster/belterdock) "aTA" = ( @@ -23197,6 +23197,10 @@ }, /turf/simulated/floor/tiled/eris/dark/techfloor, /area/shuttle/medivac/engines) +"kPM" = ( +/obj/machinery/smartfridge/sheets/persistent_lossy, +/turf/simulated/wall, +/area/quartermaster/belterdock) "kPW" = ( /obj/machinery/door/blast/regular{ dir = 4; @@ -38467,7 +38471,7 @@ aHB aMz aBU aBU -aQG +kPM aSj aOu aOL diff --git a/maps/tether/tether_areas.dm b/maps/tether/tether_areas.dm index 71c93bb2894..16ca71ce364 100644 --- a/maps/tether/tether_areas.dm +++ b/maps/tether/tether_areas.dm @@ -698,6 +698,7 @@ name = "\improper South Maintenance" /area/maintenance/lower/trash_pit name = "\improper Trash Pit" + flags = RAD_SHIELDED|AREA_FLAG_IS_NOT_PERSISTENT /area/maintenance/lower/solars name = "\improper Solars Maintenance" /area/maintenance/lower/mining_eva diff --git a/maps/tether/tether_defines.dm b/maps/tether/tether_defines.dm index 58a05910ab3..caab265dfb6 100644 --- a/maps/tether/tether_defines.dm +++ b/maps/tether/tether_defines.dm @@ -299,14 +299,14 @@ // We have a bunch of stuff common to the station z levels /datum/map_z_level/tether/station - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_XENOARCH_EXEMPT + flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_XENOARCH_EXEMPT|MAP_LEVEL_PERSIST holomap_legend_x = 220 holomap_legend_y = 160 /datum/map_z_level/tether/station/surface_low z = Z_LEVEL_SURFACE_LOW name = "Surface 1" - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT + flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT|MAP_LEVEL_PERSIST base_turf = /turf/simulated/floor/outdoors/rocks/virgo3b holomap_offset_x = TETHER_HOLOMAP_MARGIN_X holomap_offset_y = TETHER_HOLOMAP_MARGIN_Y + TETHER_MAP_SIZE*0 @@ -314,7 +314,7 @@ /datum/map_z_level/tether/station/surface_mid z = Z_LEVEL_SURFACE_MID name = "Surface 2" - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT + flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT|MAP_LEVEL_PERSIST base_turf = /turf/simulated/open holomap_offset_x = TETHER_HOLOMAP_MARGIN_X holomap_offset_y = TETHER_HOLOMAP_MARGIN_Y + TETHER_MAP_SIZE*1 @@ -322,7 +322,7 @@ /datum/map_z_level/tether/station/surface_high z = Z_LEVEL_SURFACE_HIGH name = "Surface 3" - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT + flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES|MAP_LEVEL_SEALED|MAP_LEVEL_XENOARCH_EXEMPT|MAP_LEVEL_PERSIST base_turf = /turf/simulated/open holomap_offset_x = TETHER_HOLOMAP_MARGIN_X holomap_offset_y = TETHER_HOLOMAP_MARGIN_Y + TETHER_MAP_SIZE*2 @@ -359,11 +359,11 @@ /datum/map_z_level/tether/mine z = Z_LEVEL_SURFACE_MINE name = "Mining Outpost" - flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED + flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_PERSIST base_turf = /turf/simulated/floor/outdoors/rocks/virgo3b /datum/map_z_level/tether/solars z = Z_LEVEL_SOLARS name = "Solar Field" - flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED + flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_PERSIST base_turf = /turf/simulated/floor/outdoors/rocks/virgo3b diff --git a/maps/~map_system/maps.dm b/maps/~map_system/maps.dm index 07c72230261..b7a320a6bd7 100644 --- a/maps/~map_system/maps.dm +++ b/maps/~map_system/maps.dm @@ -33,6 +33,7 @@ var/list/all_maps = list() var/static/list/player_levels = list() // Z-levels a character can typically reach var/static/list/sealed_levels = list() // Z-levels that don't allow random transit at edge var/static/list/xenoarch_exempt_levels = list() //Z-levels exempt from xenoarch finds and digsites spawning. + var/static/list/persist_levels = list() // Z-levels where SSpersistence should persist between rounds. Defaults to station_levels if unset. var/static/list/empty_levels = null // Empty Z-levels that may be used for various things (currently used by bluespace jump) // End Static Lists @@ -135,8 +136,10 @@ var/list/all_maps = list() if(zlevel_datum_type) for(var/type in subtypesof(zlevel_datum_type)) new type(src) - if(!map_levels) + if(!map_levels?.len) map_levels = station_levels.Copy() + if(!persist_levels?.len) + persist_levels = station_levels.Copy() if(!allowed_jobs || !allowed_jobs.len) allowed_jobs = subtypesof(/datum/job) if(default_skybox) //Type was specified @@ -295,6 +298,7 @@ var/list/all_maps = list() if(flags & MAP_LEVEL_PLAYER) map.player_levels += z if(flags & MAP_LEVEL_SEALED) map.sealed_levels += z if(flags & MAP_LEVEL_XENOARCH_EXEMPT) map.xenoarch_exempt_levels += z + if(flags & MAP_LEVEL_PERSIST) map.persist_levels += z if(flags & MAP_LEVEL_EMPTY) if(!map.empty_levels) map.empty_levels = list() map.empty_levels += z diff --git a/vorestation.dme b/vorestation.dme index b883ec6234e..aa4ad30081a 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -975,7 +975,6 @@ #include "code\game\mecha\combat\combat.dm" #include "code\game\mecha\combat\durand.dm" #include "code\game\mecha\combat\fighter.dm" -#include "code\game\mecha\combat\fighter_vr.dm" #include "code\game\mecha\combat\gorilla.dm" #include "code\game\mecha\combat\gygax.dm" #include "code\game\mecha\combat\marauder.dm" @@ -2087,6 +2086,7 @@ #include "code\modules\emotes\definitions\audible_cough.dm" #include "code\modules\emotes\definitions\audible_furry_vr.dm" #include "code\modules\emotes\definitions\audible_scream.dm" +#include "code\modules\emotes\definitions\audible_scream_vr.dm" #include "code\modules\emotes\definitions\audible_slap.dm" #include "code\modules\emotes\definitions\audible_snap.dm" #include "code\modules\emotes\definitions\audible_sneeze.dm" @@ -2217,8 +2217,6 @@ #include "code\modules\food\kitchen\gibber.dm" #include "code\modules\food\kitchen\icecream.dm" #include "code\modules\food\kitchen\microwave.dm" -#include "code\modules\food\kitchen\smartfridge.dm" -#include "code\modules\food\kitchen\smartfridge_vr.dm" #include "code\modules\food\kitchen\cooking_machines\_appliance.dm" #include "code\modules\food\kitchen\cooking_machines\_cooker.dm" #include "code\modules\food\kitchen\cooking_machines\_cooker_output.dm" @@ -2229,6 +2227,12 @@ #include "code\modules\food\kitchen\cooking_machines\fryer.dm" #include "code\modules\food\kitchen\cooking_machines\grill.dm" #include "code\modules\food\kitchen\cooking_machines\oven.dm" +#include "code\modules\food\kitchen\smartfridge\drying_rack.dm" +#include "code\modules\food\kitchen\smartfridge\engineering.dm" +#include "code\modules\food\kitchen\smartfridge\hydroponics.dm" +#include "code\modules\food\kitchen\smartfridge\medical.dm" +#include "code\modules\food\kitchen\smartfridge\smartfridge.dm" +#include "code\modules\food\kitchen\smartfridge\smartfridge_vr.dm" #include "code\modules\gamemaster\defines.dm" #include "code\modules\gamemaster\event2\event.dm" #include "code\modules\gamemaster\event2\meta.dm" @@ -3157,7 +3161,6 @@ #include "code\modules\news\newspaper_layout.dm" #include "code\modules\nifsoft\nif.dm" #include "code\modules\nifsoft\nif_softshop.dm" -#include "code\modules\nifsoft\nif_statpanel.dm" #include "code\modules\nifsoft\nif_tgui.dm" #include "code\modules\nifsoft\nifsoft.dm" #include "code\modules\nifsoft\software\01_vision.dm" @@ -3282,13 +3285,15 @@ #include "code\modules\persistence\filth.dm" #include "code\modules\persistence\graffiti.dm" #include "code\modules\persistence\noticeboard.dm" -#include "code\modules\persistence\persistence.dm" -#include "code\modules\persistence\datum\datum_filth.dm" -#include "code\modules\persistence\datum\datum_graffiti.dm" -#include "code\modules\persistence\datum\datum_paper.dm" -#include "code\modules\persistence\datum\datum_paper_sticky.dm" -#include "code\modules\persistence\datum\datum_trash.dm" +#include "code\modules\persistence\serialize.dm" #include "code\modules\persistence\datum\persistence_datum.dm" +#include "code\modules\persistence\effects\filth.dm" +#include "code\modules\persistence\effects\graffiti.dm" +#include "code\modules\persistence\effects\paper.dm" +#include "code\modules\persistence\effects\paper_sticky.dm" +#include "code\modules\persistence\effects\trash.dm" +#include "code\modules\persistence\storage\smartfridge.dm" +#include "code\modules\persistence\storage\storage.dm" #include "code\modules\planet\planet.dm" #include "code\modules\planet\time.dm" #include "code\modules\planet\virgo3b_better_vr.dm"