From 720e0feb950fa026c0d73ded95833028951684cd Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Sun, 7 Jan 2024 03:33:02 +0300 Subject: [PATCH 01/18] Cargo Update PR that contents majority of cargo codding. Edded: Blackmarket Some blackmarket stuff Bepis Survival pen Lava rods Tinker's gloves New types of Mosin boltaction Boxcutter Cargo gloves Cargo teleporter (high risk in future) Nerfed Nullcrate (will be nerfed) New bounties (will be nerfed) Cargo mech Edited: Warden gloves, but for now adminspawn only Crate with lasers moved to the armory list Specops crate get some loot in exchange for restrictions Some manitol overriding All works pretty fine though need some additional testing, The boomerangs are broken. --- code/__DEFINES/traits.dm | 3 + .../{dripstation_defines}/blackmarket.dm | 9 + code/__DEFINES/{dripstation_defines}/cargo.dm | 2 + .../dcs/signals/signals_transform.dm | 10 + .../{dripstation_defines}/directional.dm | 2 + code/controllers/subsystem/research.dm | 3 + code/datums/components/chasm.dm | 4 +- .../components/storage/concrete/pockets.dm | 4 +- code/game/atoms_movable.dm | 2 + code/game/gamemodes/dynamic/dynamic.dm | 2 +- code/game/machinery/recharger.dm | 1 + .../items/stacks/sheets/sheet_types.dm | 2 +- code/game/objects/items/stacks/stack.dm | 10 +- code/game/objects/items/storage/belt.dm | 1 + .../structures/crates_lockers/closets.dm | 6 + code/game/objects/structures/girders.dm | 11 +- code/game/turfs/simulated/chasm.dm | 5 +- code/modules/cargo/console.dm | 29 +- code/modules/cargo/order.dm | 2 +- code/modules/cargo/packs.dm | 4 +- .../mob/living/carbon/carbon_defense.dm | 4 +- code/modules/mob/living/living.dm | 1 + code/modules/research/rdconsole.dm | 3 + .../modules/research/techweb/_techweb_node.dm | 3 + code/modules/shuttle/supply.dm | 1 + .../code/controllers/subsystem/blackmarket.dm | 115 +++++++ .../code/datum/brain_damage/severe.dm | 31 ++ .../code/datum/component/transforming.dm | 258 ++++++++++++++ .../code/datum/reagent/baldium.dm | 16 + .../code/datum/reagent/chemoverride.dm | 40 +++ .../code/datum/reagent/leadacetate.dm | 16 + modular_dripstation/code/datum/strong_pull.dm | 47 +++ .../code/game/effects/effects_foam.dm | 30 ++ .../code/game/mecha/cargo_hauler.dm | 51 +++ .../objects/items/bepis_items/boomerang.dm | 34 ++ .../objects/items/bepis_items/eng_gloves.dm | 10 + .../objects/items/bepis_items/explorerpin.dm | 14 + .../objects/items/bepis_items/hypnochair.dm | 223 +++++++++++++ .../objects/items/bepis_items/lava_rods.dm | 84 +++++ .../objects/items/bepis_items/party_pod.dm | 309 +++++++++++++++++ .../objects/items/bepis_items/polycircuit.dm | 59 ++++ .../game/objects/items/bepis_items/rldmini.dm | 5 + .../objects/items/bepis_items/sprayoncan.dm | 48 +++ .../objects/items/bepis_items/survival_pen.dm | 21 ++ .../game/objects/items/blackmarketstuff.dm | 17 + .../game/objects/items/cargo_boxcutter.dm | 46 +++ .../code/game/objects/items/cargo_inducer.dm | 12 + .../game/objects/items/cargo_teleporter.dm | 315 ++++++++++++++++++ .../game/objects/items/clothing/gloves.dm | 67 ++++ .../objects/items/devices/PDA/PDA_types.dm | 2 + .../items/projectiles/guns/ballistic/rifle.dm | 30 ++ .../game/objects/items/tanks/watertank.dm | 6 + .../code/game/turfs/simulated/walls.dm | 2 + .../modules/antagonists/changeling/panacea.dm | 39 +++ .../antagonists/horror/horror_chemicals.dm | 4 + .../code/modules/bepis/all_nodes.dm | 51 +++ .../code/modules/bepis/bepis.dm | 294 ++++++++++++++++ .../code/modules/bepis/bepis_board.dm | 18 + .../code/modules/bepis/bepis_designs.dm | 66 ++++ .../code/modules/bepis/bepis_layout.dm | 27 ++ .../code/modules/bepis/bounty.dm | 5 + .../code/modules/bepis/designs.dm | 37 ++ .../modules/cargo/bounties/progression.dm | 15 + .../code/modules/cargo/bounties/syndicate.dm | 24 ++ .../code/modules/cargo/export_scaner.dm | 2 + .../code/modules/cargo/markets/_market.dm | 61 ++++ .../code/modules/cargo/markets/market_item.dm | 76 +++++ .../cargo/markets/market_items/clothing.dm | 80 +++++ .../cargo/markets/market_items/consumables.dm | 53 +++ .../cargo/markets/market_items/misc.dm | 78 +++++ .../cargo/markets/market_items/tools.dm | 82 +++++ .../cargo/markets/market_items/weapons.dm | 65 ++++ .../modules/cargo/markets/market_telepad.dm | 120 +++++++ .../modules/cargo/markets/market_uplink.dm | 171 ++++++++++ .../code/modules/cargo/packs.dm | 105 ++++++ .../code/modules/job/job_types/janitor.dm | 2 + .../modules/job/job_types/quartermaster.dm | 11 + .../icons/mob/clothing/belt.dmi | Bin 0 -> 333 bytes .../icons/mob/clothing/guns_on_back.dmi | Bin 0 -> 1869 bytes .../icons/mob/clothing/hands.dmi | Bin 0 -> 485 bytes .../inhands/equipment/boxcutter_lefthand.dmi | Bin 0 -> 406 bytes .../inhands/equipment/boxcutter_righthand.dmi | Bin 0 -> 381 bytes .../equipment/cargo_teleporter_lefthand.dmi | Bin 0 -> 603 bytes .../equipment/cargo_teleporter_righthand.dmi | Bin 0 -> 611 bytes .../icons/mob/inhands/guns_lefthand.dmi | Bin 0 -> 1227 bytes .../icons/mob/inhands/guns_righthand.dmi | Bin 0 -> 1274 bytes .../icons/mob/inhands/security_lefthand.dmi | Bin 0 -> 367 bytes .../icons/mob/inhands/security_righthand.dmi | Bin 0 -> 366 bytes .../icons/mob/mecha/cargo_hauler.dmi | Bin 0 -> 2244 bytes modular_dripstation/icons/obj/bepis/bepis.dmi | Bin 0 -> 4246 bytes .../icons/obj/blackmarket/blackmarket.dmi | Bin 0 -> 843 bytes .../icons/obj/blackmarket/module.dmi | Bin 0 -> 694 bytes .../icons/obj/blackmarket/telecoms.dmi | Bin 0 -> 2282 bytes modular_dripstation/icons/obj/bureaucracy.dmi | Bin 25971 -> 26512 bytes .../icons/obj/cargo/boxcutter.dmi | Bin 0 -> 432 bytes .../icons/obj/cargo/cargo_inducer.dmi | Bin 0 -> 620 bytes .../icons/obj/cargo/cargo_teleporter.dmi | Bin 0 -> 1435 bytes .../icons/obj/circuit_mess.dmi | Bin 0 -> 943 bytes .../icons/obj/clothing/gloves.dmi | Bin 0 -> 724 bytes .../icons/obj/clothing/shoes.dmi | Bin 0 -> 405 bytes modular_dripstation/icons/obj/device.dmi | Bin 8752 -> 9057 bytes modular_dripstation/icons/obj/hypnochair.dmi | Bin 0 -> 4140 bytes modular_dripstation/icons/obj/partypod.dmi | Bin 0 -> 15517 bytes .../icons/obj/weapons/48x32.dmi | Bin 0 -> 5261 bytes .../icons/obj/weapons/security.dmi | Bin 0 -> 2361 bytes modular_dripstation/includes.dm | 52 +++ .../sound/item/boxcutter_activate.ogg | Bin 0 -> 16979 bytes tgui/packages/tgui/interfaces/Bepis2.tsx | 129 +++++++ tgui/packages/tgui/interfaces/Party.js | 118 +++++++ yogstation.dme | 4 + 110 files changed, 3804 insertions(+), 17 deletions(-) create mode 100644 code/__DEFINES/{dripstation_defines}/blackmarket.dm create mode 100644 code/__DEFINES/{dripstation_defines}/cargo.dm create mode 100644 code/__DEFINES/{dripstation_defines}/dcs/signals/signals_transform.dm create mode 100644 code/__DEFINES/{dripstation_defines}/directional.dm create mode 100644 modular_dripstation/code/controllers/subsystem/blackmarket.dm create mode 100644 modular_dripstation/code/datum/brain_damage/severe.dm create mode 100644 modular_dripstation/code/datum/component/transforming.dm create mode 100644 modular_dripstation/code/datum/reagent/baldium.dm create mode 100644 modular_dripstation/code/datum/reagent/chemoverride.dm create mode 100644 modular_dripstation/code/datum/reagent/leadacetate.dm create mode 100644 modular_dripstation/code/datum/strong_pull.dm create mode 100644 modular_dripstation/code/game/effects/effects_foam.dm create mode 100644 modular_dripstation/code/game/mecha/cargo_hauler.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/boomerang.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/explorerpin.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/hypnochair.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/lava_rods.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/party_pod.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/polycircuit.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/rldmini.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/sprayoncan.dm create mode 100644 modular_dripstation/code/game/objects/items/bepis_items/survival_pen.dm create mode 100644 modular_dripstation/code/game/objects/items/blackmarketstuff.dm create mode 100644 modular_dripstation/code/game/objects/items/cargo_boxcutter.dm create mode 100644 modular_dripstation/code/game/objects/items/cargo_inducer.dm create mode 100644 modular_dripstation/code/game/objects/items/cargo_teleporter.dm create mode 100644 modular_dripstation/code/game/objects/items/clothing/gloves.dm create mode 100644 modular_dripstation/code/game/objects/items/devices/PDA/PDA_types.dm create mode 100644 modular_dripstation/code/game/objects/items/projectiles/guns/ballistic/rifle.dm create mode 100644 modular_dripstation/code/game/objects/items/tanks/watertank.dm create mode 100644 modular_dripstation/code/game/turfs/simulated/walls.dm create mode 100644 modular_dripstation/code/modules/antagonists/changeling/panacea.dm create mode 100644 modular_dripstation/code/modules/antagonists/horror/horror_chemicals.dm create mode 100644 modular_dripstation/code/modules/bepis/all_nodes.dm create mode 100644 modular_dripstation/code/modules/bepis/bepis.dm create mode 100644 modular_dripstation/code/modules/bepis/bepis_board.dm create mode 100644 modular_dripstation/code/modules/bepis/bepis_designs.dm create mode 100644 modular_dripstation/code/modules/bepis/bepis_layout.dm create mode 100644 modular_dripstation/code/modules/bepis/bounty.dm create mode 100644 modular_dripstation/code/modules/bepis/designs.dm create mode 100644 modular_dripstation/code/modules/cargo/bounties/progression.dm create mode 100644 modular_dripstation/code/modules/cargo/bounties/syndicate.dm create mode 100644 modular_dripstation/code/modules/cargo/export_scaner.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/_market.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_item.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_items/clothing.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_items/consumables.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_items/misc.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_items/tools.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_items/weapons.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_telepad.dm create mode 100644 modular_dripstation/code/modules/cargo/markets/market_uplink.dm create mode 100644 modular_dripstation/code/modules/cargo/packs.dm create mode 100644 modular_dripstation/code/modules/job/job_types/janitor.dm create mode 100644 modular_dripstation/code/modules/job/job_types/quartermaster.dm create mode 100644 modular_dripstation/icons/mob/clothing/belt.dmi create mode 100644 modular_dripstation/icons/mob/clothing/guns_on_back.dmi create mode 100644 modular_dripstation/icons/mob/clothing/hands.dmi create mode 100644 modular_dripstation/icons/mob/inhands/equipment/boxcutter_lefthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/equipment/boxcutter_righthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_lefthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_righthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/guns_lefthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/guns_righthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/security_lefthand.dmi create mode 100644 modular_dripstation/icons/mob/inhands/security_righthand.dmi create mode 100644 modular_dripstation/icons/mob/mecha/cargo_hauler.dmi create mode 100644 modular_dripstation/icons/obj/bepis/bepis.dmi create mode 100644 modular_dripstation/icons/obj/blackmarket/blackmarket.dmi create mode 100644 modular_dripstation/icons/obj/blackmarket/module.dmi create mode 100644 modular_dripstation/icons/obj/blackmarket/telecoms.dmi create mode 100644 modular_dripstation/icons/obj/cargo/boxcutter.dmi create mode 100644 modular_dripstation/icons/obj/cargo/cargo_inducer.dmi create mode 100644 modular_dripstation/icons/obj/cargo/cargo_teleporter.dmi create mode 100644 modular_dripstation/icons/obj/circuit_mess.dmi create mode 100644 modular_dripstation/icons/obj/clothing/gloves.dmi create mode 100644 modular_dripstation/icons/obj/clothing/shoes.dmi create mode 100644 modular_dripstation/icons/obj/hypnochair.dmi create mode 100644 modular_dripstation/icons/obj/partypod.dmi create mode 100644 modular_dripstation/icons/obj/weapons/48x32.dmi create mode 100644 modular_dripstation/icons/obj/weapons/security.dmi create mode 100644 modular_dripstation/sound/item/boxcutter_activate.ogg create mode 100644 tgui/packages/tgui/interfaces/Bepis2.tsx create mode 100644 tgui/packages/tgui/interfaces/Party.js diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 53fb59b1aa04..750687724e67 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -139,6 +139,7 @@ #define TRAIT_INCAPACITATED "incapacitated" #define HANDCUFFED_TRAIT "handcuffed" #define TRAIT_BLIND "blind" +#define HYPNOCHAIR_TRAIT "hypnochair" //dripstation edit #define TRAIT_ECHOLOCATION_RECEIVER "echolocation_receiver" #define TRAIT_MUTE "mute" #define TRAIT_EMOTEMUTE "emotemute" @@ -234,6 +235,7 @@ #define TRAIT_QUICK_CARRY "quick-carry" #define TRAIT_QUICKER_CARRY "quicker-carry" #define TRAIT_QUICKEST_CARRY "quickest-carry" +#define TRAIT_QUICK_BUILD "quick-build" //dripstation edit #define TRAIT_STRONG_GRIP "strong-grip" #define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech" #define TRAIT_UNSTABLE "unstable" @@ -333,6 +335,7 @@ #define TRAIT_ANXIOUS "anxious" #define TRAIT_SEE_REAGENTS "see_reagents" #define TRAIT_STARGAZED "stargazed" +#define TRAIT_TRANSFORM_ACTIVE "active_transform" //dripstation edit // common trait sources #define TRAIT_GENERIC "generic" diff --git a/code/__DEFINES/{dripstation_defines}/blackmarket.dm b/code/__DEFINES/{dripstation_defines}/blackmarket.dm new file mode 100644 index 000000000000..c5e199546f71 --- /dev/null +++ b/code/__DEFINES/{dripstation_defines}/blackmarket.dm @@ -0,0 +1,9 @@ + +// Shipping methods + +// The BEST way of shipping items: accurate, "undetectable" +#define SHIPPING_METHOD_LTSRBT "LTSRBT" +// Picks a random area to teleport the item to and gives you a minute to get there before it is sent. +#define SHIPPING_METHOD_TELEPORT "Teleport" +// Throws the item from somewhere at the station. +#define SHIPPING_METHOD_LAUNCH "Launch" \ No newline at end of file diff --git a/code/__DEFINES/{dripstation_defines}/cargo.dm b/code/__DEFINES/{dripstation_defines}/cargo.dm new file mode 100644 index 000000000000..b4c8b0c96256 --- /dev/null +++ b/code/__DEFINES/{dripstation_defines}/cargo.dm @@ -0,0 +1,2 @@ +/// Defining standart crate value for blackmarket, some events will change this shit some day +#define CARGO_CRATE_VALUE 200 diff --git a/code/__DEFINES/{dripstation_defines}/dcs/signals/signals_transform.dm b/code/__DEFINES/{dripstation_defines}/dcs/signals/signals_transform.dm new file mode 100644 index 000000000000..a520c050c73b --- /dev/null +++ b/code/__DEFINES/{dripstation_defines}/dcs/signals/signals_transform.dm @@ -0,0 +1,10 @@ +// /datum/component/transforming signals + +/// From /datum/component/transforming/proc/on_attack_self(obj/item/source, mob/user): (obj/item/source, mob/user, active) +#define COMSIG_TRANSFORMING_PRE_TRANSFORM "transforming_pre_transform" + /// Return COMPONENT_BLOCK_TRANSFORM to prevent the item from transforming. + #define COMPONENT_BLOCK_TRANSFORM (1<<0) +/// From /datum/component/transforming/proc/do_transform(obj/item/source, mob/user): (obj/item/source, mob/user, active) +#define COMSIG_TRANSFORMING_ON_TRANSFORM "transforming_on_transform" + /// Return COMPONENT_NO_DEFAULT_MESSAGE to prevent the transforming component from displaying the default transform message / sound. + #define COMPONENT_NO_DEFAULT_MESSAGE (1<<0) \ No newline at end of file diff --git a/code/__DEFINES/{dripstation_defines}/directional.dm b/code/__DEFINES/{dripstation_defines}/directional.dm new file mode 100644 index 000000000000..6574a46fb509 --- /dev/null +++ b/code/__DEFINES/{dripstation_defines}/directional.dm @@ -0,0 +1,2 @@ +/// Inverse direction, taking into account UP|DOWN if necessary. +#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) \ No newline at end of file diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 35c654a65f18..c35bdf33c806 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -27,6 +27,7 @@ SUBSYSTEM_DEF(research) var/list/techweb_categories = list() //category name = list(node.id = TRUE) var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount)) var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default. + var/list/techweb_nodes_experimental = list()//Node ids that are exclusive to the BEPIS. dripstation edit var/list/techweb_point_items = list( //path = list(point type = value) /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000) ) @@ -246,6 +247,8 @@ SUBSYSTEM_DEF(research) D.unlocked_by += node.id if(node.hidden) techweb_nodes_hidden[node.id] = TRUE + if(node.experimental) //dripstation edit + techweb_nodes_experimental[node.id] = TRUE //dripstation edit CHECK_TICK generate_techweb_unlock_linking() diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm index 90f85004ccdf..259289a1b70e 100644 --- a/code/datums/components/chasm.dm +++ b/code/datums/components/chasm.dm @@ -40,8 +40,8 @@ STOP_PROCESSING(SSobj, src) /datum/component/chasm/proc/is_safe() - //if anything matching this typecache is found in the chasm, we don't drop things - var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile)) + //if anything matching this typecache is found in the chasm, we don't drop things, dripstation edit + var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/lattice/lava, /obj/structure/stone_tile)) var/atom/parent = src.parent var/list/found_safeties = typecache_filter_list(parent.contents, chasm_safeties_typecache) diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm index 4e69c5f7a303..74b33246a7f4 100644 --- a/code/datums/components/storage/concrete/pockets.dm +++ b/code/datums/components/storage/concrete/pockets.dm @@ -44,7 +44,7 @@ /datum/component/storage/concrete/pockets/shoes/Initialize() . = ..() set_holdable(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, + /obj/item/kitchen/knife, /obj/item/boxcutter, /obj/item/switchblade, /obj/item/pen, //boxcutter dripstation edit /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, /obj/item/reagent_containers/autoinjector/medipen, /obj/item/reagent_containers/dropper, /obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini, @@ -56,7 +56,7 @@ /datum/component/storage/concrete/pockets/shoes/clown/Initialize() . = ..() set_holdable(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, + /obj/item/kitchen/knife, /obj/item/boxcutter, /obj/item/switchblade, /obj/item/pen, //boxcutter dripstation edit /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, /obj/item/reagent_containers/autoinjector/medipen, /obj/item/reagent_containers/dropper, /obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini, diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index caa5aa2f94d9..8ce03309ae53 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1000,6 +1000,8 @@ return FALSE if(force < (move_resist * MOVE_FORCE_PULL_RATIO)) return FALSE + if(SEND_SIGNAL(src, COMSIG_ATOM_CAN_BE_PULLED, user) & COMSIG_ATOM_CANT_PULL) + return FALSE return TRUE /// Called when mob changes from a standing position into a prone while lacking the ability to stand up at the moment. diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index d5dd024038f8..d7d8a672445d 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -79,7 +79,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop. var/antags_rolled = 0 /// CRATE DISCOUNT - var/discountedcrates = list( /datum/supply_pack/security/laser, + var/discountedcrates = list( /datum/supply_pack/security/armory/laser, //dripstation edit /datum/supply_pack/security/helmets, /datum/supply_pack/security/vending/security, /datum/supply_pack/service/party) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 6c393d6f367b..e5c37ee4594c 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -17,6 +17,7 @@ var/static/list/allowed_devices = typecacheof(list( /obj/item/gun/energy, + /obj/item/cargo_teleporter, //dripstation edit /obj/item/melee/baton, /obj/item/ammo_box/magazine/recharge, /obj/item/ammo_box/magazine/m308/laser, diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 53adc342c7a3..558a7ffd2248 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -57,7 +57,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \ new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \ null, \ - new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \ null, \ new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index c4b03c4c9928..0a1da50e1df4 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -456,9 +456,13 @@ var/on_floor = FALSE var/window_checks = FALSE var/placement_checks = FALSE + /// What trait, if any, boosts the construction speed of this item dripstation + var/trait_booster + /// How much the trait above, if supplied, boosts the construct speed of this item dripstation + var/trait_modifier = 1 -/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE ) - +/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, trait_booster, trait_modifier = 1) +//dripstation edit src.title = title src.result_type = result_type @@ -470,6 +474,8 @@ src.on_floor = on_floor src.window_checks = window_checks src.placement_checks = placement_checks + src.trait_booster = trait_booster //dripstation edit + src.trait_modifier = trait_modifier //dripstation edit /* * Recipe list datum */ diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index afbb8a4d8db1..ab39216115e8 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -78,6 +78,7 @@ /obj/item/shuttle_creator, //Yogs: Added this here cause I felt it fits /obj/item/barrier_taperoll/engineering, /obj/item/storage/bag/sheetsnatcher, + /obj/item/boxcutter, //dripstation edit /obj/item/holotool, )) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 75861b1dc5ee..b00566d22c3d 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -49,6 +49,8 @@ GLOBAL_LIST_EMPTY(lockers) var/door_anim_angle = 136 var/door_hinge_x = -6.5 var/door_anim_time = 2.5 // set to 0 to make the door not animate at all + /// true whenever someone with the strong pull component (or magnet modsuit module) is dragging this, preventing opening + var/strong_grab = FALSE /obj/structure/closet/Initialize(mapload) . = ..() @@ -165,6 +167,10 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/proc/can_open(mob/living/user) if(welded || locked) + to_chat(user, span_danger("[src] locked or welded to be opened.")) + return FALSE + if(strong_grab) + to_chat(user, span_danger("[pulledby] has an incredibly strong grip on [src], preventing it from opening.")) return FALSE var/turf/T = get_turf(src) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 2bf9e5eecb7e..fae4132b1a2e 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -10,6 +10,7 @@ max_integrity = 200 flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1 rad_insulation = RAD_VERY_LIGHT_INSULATION + var/next_beep = 0 //Prevents spamming of the construction sound, dripstation edit /obj/structure/girder/examine(mob/user) . = ..() @@ -27,6 +28,12 @@ . += span_notice("[src] is disassembled! You probably shouldn't be able to see this examine message.") /obj/structure/girder/attackby(obj/item/W, mob/user, params) + var/platingmodifier = 1 //dripstation edit start + if(HAS_TRAIT(user, TRAIT_QUICK_BUILD)) + platingmodifier = 0.7 + if(next_beep <= world.time) + next_beep = world.time + 10 + playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE) //dripstation edit end add_fingerprint(user) if(istype(W, /obj/item/gun/energy/plasmacutter)) @@ -55,7 +62,7 @@ to_chat(user, span_warning("You need at least two rods to create a false wall!")) return to_chat(user, span_notice("You start building a reinforced false wall...")) - if(do_after(user, 2 SECONDS, src)) + if(do_after(user, 20*platingmodifier, src)) //dripstation edit if(S.get_amount() < 2) return S.use(2) @@ -68,7 +75,7 @@ to_chat(user, span_warning("You need at least five rods to add plating!")) return to_chat(user, span_notice("You start adding plating...")) - if(do_after(user, 4 SECONDS, src)) + if(do_after(user, 40*platingmodifier, src)) //dripstation edit if(S.get_amount() < 5) return S.use(5) diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm index 482a7a9a7a7e..0b94df0abc73 100644 --- a/code/game/turfs/simulated/chasm.dm +++ b/code/game/turfs/simulated/chasm.dm @@ -57,7 +57,10 @@ to_chat(user, span_notice("You construct a lattice.")) playsound(src, 'sound/weapons/genhit.ogg', 50, 1) // Create a lattice, without reverting to our baseturf - new /obj/structure/lattice(src) + if(istype(R, /obj/item/stack/rods/lava)) //dripstation edit start + new /obj/structure/lattice/lava(src) + else + new /obj/structure/lattice(src) //dripstation edit end else to_chat(user, span_warning("You need one rod to build a lattice.")) return diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index a55fd9d6da86..66431f842b01 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -16,6 +16,7 @@ or homing beacons. Additionally, remove any privately ordered crates from the shuttle." var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible." var/self_paid = FALSE + req_access = list(ACCESS_CARGO) //dripstation edit /obj/machinery/computer/cargo/request name = "supply request console" @@ -25,6 +26,7 @@ requestonly = TRUE can_send = FALSE can_approve_requests = FALSE + req_access = list() //dripstation edit /obj/machinery/computer/cargo/Initialize(mapload) . = ..() @@ -50,6 +52,7 @@ obj_flags |= EMAGGED contraband = TRUE + do_sparks(8, FALSE, loc) //dripstation edit // This also permamently sets this on the circuit board var/obj/item/circuitboard/computer/cargo/board = circuit @@ -133,6 +136,9 @@ /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) if(..()) return + if(!allowed(usr) && can_approve_requests) + say("Access denied.") + return switch(action) if("send") if(!SSshuttle.supply.canMove()) @@ -148,7 +154,7 @@ investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO) else investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO) - say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.") + say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(10)] seconds.") SSshuttle.moveShuttle("supply", "supply_home", TRUE) . = TRUE if("loan") @@ -171,6 +177,12 @@ var/datum/supply_pack/pack = SSshuttle.supply_packs[id] if(!istype(pack)) return + if(pack.times_ordered >= pack.order_limit && pack.order_limit != -1) //If the crate has reached the limit, do not allow it to be ordered. + say("[pack.name] is out of stock and can no longer be ordered.") + return + if(pack.times_ordered_in_one_order >= pack.order_limit_in_one_order && pack.order_limit_in_one_order != -1) + say("[pack.name] is out of stock for now and can no longer be ordered in this package. Try again later.") + return if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.contraband && !contraband) || pack.DropPodOnly) return @@ -210,6 +222,8 @@ SSshuttle.requestlist += SO else SSshuttle.shoppinglist += SO + SO.pack.times_ordered += 1 + SO.pack.times_ordered_in_one_order += 1 if(self_paid) say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") . = TRUE @@ -218,17 +232,30 @@ for(var/datum/supply_order/SO in SSshuttle.shoppinglist) if(SO.id == id) SSshuttle.shoppinglist -= SO + SO.pack.times_ordered -= 1 + SO.pack.times_ordered_in_one_order -= 1 . = TRUE break if("clear") + for(var/datum/supply_order/SO in SSshuttle.shoppinglist) + SO.pack.times_ordered -= 1 + SO.pack.times_ordered_in_one_order = 0 SSshuttle.shoppinglist.Cut() . = TRUE if("approve") var/id = text2num(params["id"]) for(var/datum/supply_order/SO in SSshuttle.requestlist) if(SO.id == id) + if(SO.pack.times_ordered >= SO.pack.order_limit && SO.pack.order_limit != -1) //If the crate has reached the limit, do not allow it to be ordered. + say("[SO.pack.name] is out of stock and can no longer be ordered.") + return + if(SO.pack.times_ordered_in_one_order >= SO.pack.order_limit_in_one_order && SO.pack.order_limit_in_one_order != -1) + say("[SO.pack.name] is out of stock for now and can no longer be ordered in this package. Try again later.") + return SSshuttle.requestlist -= SO SSshuttle.shoppinglist += SO + SO.pack.times_ordered += 1 + SO.pack.times_ordered_in_one_order += 1 . = TRUE break if("deny") diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 6afc883649fe..72d87817bbda 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -108,7 +108,7 @@ if(paying_account) account_holder = paying_account.account_holder else - account_holder = "Cargo" + account_holder = "Cargo Budget" //dripstation edit var/obj/structure/closet/crate/C = pack.generate(A, paying_account) generateManifest(C, account_holder, pack) return C diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index aa2ef33a253c..91c2704f36a4 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -307,7 +307,7 @@ /obj/item/clothing/head/helmet/sec, /obj/item/clothing/head/helmet/sec) crate_name = "helmet crate" - +/* dripstation edit, removing lethals from sec access /datum/supply_pack/security/laser name = "Lasers Crate" desc = "Contains three lethal, high-energy laser guns. Requires Security access to open." @@ -316,7 +316,7 @@ /obj/item/gun/energy/laser, /obj/item/gun/energy/laser) crate_name = "laser crate" - +*/ /datum/supply_pack/security/secfiringpins name = "Mindshield Firing Pins Crate" desc = "Upgrade your arsenal with 10 mindshield firing pins. Requires Security access to open." diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index fadbd9a2d598..644a9f0e374b 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -1,7 +1,7 @@ /mob/living/carbon/get_eye_protection() . = ..() - if(HAS_TRAIT(src, TRAIT_BLIND)) - return INFINITY //Can't get flashed if you cant see + if(is_blind() && !HAS_TRAIT_FROM(src, TRAIT_BLIND, UNCONSCIOUS_TRAIT) && !HAS_TRAIT_FROM(src, TRAIT_BLIND, HYPNOCHAIR_TRAIT)) //dripstation edit + return INFINITY //For all my homies that can not see in the world var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES) if(!E) return INFINITY //Can't get flashed without eyes diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f9d4d573214a..2a90b6e5e912 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -262,6 +262,7 @@ pulling = AM AM.set_pulledby(src) + SEND_SIGNAL(src, COMSIG_LIVING_START_PULL, AM, state, force) //dripstation edit if(!supress_message) var/sound_to_play = 'sound/weapons/thudswoosh.ogg' if(ishuman(src)) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index f19753ed5eeb..b51b398de598 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -1090,6 +1090,9 @@ Nothing else in the console has ID requirements. stored_research.add_design(D, TRUE) else stored_research.add_design(d_disk.blueprints[n], TRUE) + + say("Uploading blueprints from disk.") //dripstation edit + d_disk.on_upload(stored_research) //dripstation edit updateUsrDialog() diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 5bf1cff4a57c..eff0c4a4dd9a 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -7,6 +7,7 @@ var/display_name = "Errored Node" var/description = "Why are you seeing this?" var/hidden = FALSE //Whether it starts off hidden. + var/experimental = FALSE //If the tech can be randomly generated by the BEPIS as a reward. MEant to be fully given in tech disks, not researched var/starting_node = FALSE //Whether it's available without any research. var/list/prereq_ids = list() var/list/design_ids = list() @@ -41,6 +42,7 @@ VARSET_TO_LIST(., id) VARSET_TO_LIST(., display_name) VARSET_TO_LIST(., hidden) + VARSET_TO_LIST(., experimental) VARSET_TO_LIST(., starting_node) VARSET_TO_LIST(., assoc_to_keys(prereq_ids)) VARSET_TO_LIST(., assoc_to_keys(design_ids)) @@ -56,6 +58,7 @@ VARSET_FROM_LIST(input, id) VARSET_FROM_LIST(input, display_name) VARSET_FROM_LIST(input, hidden) + VARSET_FROM_LIST(input, experimental) VARSET_FROM_LIST(input, starting_node) VARSET_FROM_LIST(input, prereq_ids) VARSET_FROM_LIST(input, design_ids) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index f4c18df95eb9..ffb00a55c4ef 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -122,6 +122,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( value += SO.pack.get_cost() SSshuttle.shoppinglist -= SO SSshuttle.orderhistory += SO + SO.pack.times_ordered_in_one_order = 0 //dripstation edit if(SO.pack.small_item) //small_item means it gets piled in the miscbox if(SO.paying_account) diff --git a/modular_dripstation/code/controllers/subsystem/blackmarket.dm b/modular_dripstation/code/controllers/subsystem/blackmarket.dm new file mode 100644 index 000000000000..357fa0df2915 --- /dev/null +++ b/modular_dripstation/code/controllers/subsystem/blackmarket.dm @@ -0,0 +1,115 @@ +SUBSYSTEM_DEF(blackmarket) + name = "Blackmarket" + flags = SS_BACKGROUND + init_order = INIT_ORDER_DEFAULT + + /// Descriptions for each shipping methods. + var/shipping_method_descriptions = list( + SHIPPING_METHOD_LAUNCH="Launches the item at the station from space, cheap but you might not receive your item at all.", + SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that receives items outside the station and then teleports them to the location of the uplink.", + SHIPPING_METHOD_TELEPORT="Teleports the item in a random area in the station, you get 60 seconds to get there first though." + ) + + /// List of all existing markets. + var/list/datum/market/markets = list() + /// List of existing ltsrbts. + var/list/obj/machinery/ltsrbt/telepads = list() + /// Currently queued purchases. + var/list/queued_purchases = list() + +/datum/controller/subsystem/blackmarket/Initialize() + for(var/market in subtypesof(/datum/market)) + markets[market] += new market + + for(var/item in subtypesof(/datum/market_item)) + var/datum/market_item/I = new item() + if(!I.item) + continue + + for(var/M in I.markets) + if(!markets[M]) + stack_trace("SSblackmarket: Item [I] available in market that does not exist.") + continue + markets[M].add_item(item) + qdel(I) + return SS_INIT_SUCCESS + +/datum/controller/subsystem/blackmarket/fire(resumed) + while(length(queued_purchases)) + var/datum/market_purchase/purchase = queued_purchases[1] + queued_purchases.Cut(1,2) + + // Uh oh, uplink is gone. We will just keep the money and you will not get your order. + if(!purchase.uplink || QDELETED(purchase.uplink)) + queued_purchases -= purchase + qdel(purchase) + continue + + switch(purchase.method) + // Find a ltsrbt pad and make it handle the shipping. + if(SHIPPING_METHOD_LTSRBT) + if(!telepads.len) + continue + // Prioritize pads that don't have a cooldown active. + var/free_pad_found = FALSE + for(var/obj/machinery/ltsrbt/pad in telepads) + if(pad.recharge_cooldown) + continue + pad.add_to_queue(purchase) + queued_purchases -= purchase + free_pad_found = TRUE + break + + if(free_pad_found) + continue + + var/obj/machinery/ltsrbt/pad = pick(telepads) + + to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting that the order is being processed by [pad].")) + + queued_purchases -= purchase + pad.add_to_queue(purchase) + // Get random area, throw it somewhere there. + if(SHIPPING_METHOD_TELEPORT) + var/turf/targetturf = get_safe_random_station_turf() + // This shouldn't happen. + if (!targetturf) + continue + + to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds.")) + + // do_teleport does not want to teleport items from nullspace, so it just forceMoves and does sparks. + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/controller/subsystem/blackmarket,fake_teleport), purchase.entry.spawn_item(), targetturf), 60 SECONDS) + queued_purchases -= purchase + qdel(purchase) + // Get the current location of the uplink if it exists, then throws the item from space at the station from a random direction. + if(SHIPPING_METHOD_LAUNCH) + var/startSide = pick(GLOB.cardinals) + var/turf/T = get_turf(purchase.uplink) + var/pickedloc = spaceDebrisStartLoc(startSide, T.z) + + var/atom/movable/item = purchase.entry.spawn_item(pickedloc) + item.throw_at(purchase.uplink, 3, 3, spin = FALSE) + + to_chat(recursive_loc_check(purchase.uplink.loc, /mob), span_notice("[purchase.uplink] flashes a message noting the order is being launched at the station from [dir2text(startSide)].")) + + queued_purchases -= purchase + qdel(purchase) + + if(MC_TICK_CHECK) + break + +/// Used to make a teleportation effect as do_teleport does not like moving items from nullspace. +/datum/controller/subsystem/blackmarket/proc/fake_teleport(atom/movable/item, turf/target) + item.forceMove(target) + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 1, target) + sparks.attach(item) + sparks.start() + +/// Used to add /datum/market_purchase to queued_purchases var. Returns TRUE when queued. +/datum/controller/subsystem/blackmarket/proc/queue_item(datum/market_purchase/P) + if(P.method == SHIPPING_METHOD_LTSRBT && !telepads.len) + return FALSE + queued_purchases += P + return TRUE diff --git a/modular_dripstation/code/datum/brain_damage/severe.dm b/modular_dripstation/code/datum/brain_damage/severe.dm new file mode 100644 index 000000000000..247ecd016360 --- /dev/null +++ b/modular_dripstation/code/datum/brain_damage/severe.dm @@ -0,0 +1,31 @@ +/datum/brain_trauma/severe/hypnotic_trigger + name = "Hypnotic Trigger" + desc = "Patient has a trigger phrase set in their subconscious that will trigger a suggestible trance-like state." + scan_desc = "oneiric feedback loop" + gain_text = span_warning("You feel odd, like you just forgot something important.") + lose_text = span_notice("You feel like a weight was lifted from your mind.") + random_gain = FALSE + var/trigger_phrase = "Nanotrasen" + +/datum/brain_trauma/severe/hypnotic_trigger/New(phrase) + ..() + if(phrase) + trigger_phrase = phrase + +/datum/brain_trauma/severe/hypnotic_trigger/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway + ..() + owner.remove_status_effect(/datum/status_effect/trance) + +/datum/brain_trauma/severe/hypnotic_trigger/handle_hearing(datum/source, list/hearing_args) + if(!owner.can_hear() || owner == hearing_args[HEARING_SPEAKER]) + return + + var/regex/reg = new("(\\b[REGEX_QUOTE(trigger_phrase)]\\b)","ig") + + if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg)) + addtimer(CALLBACK(src, PROC_REF(hypnotrigger)), 10) //to react AFTER the chat message + hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], span_hypnophrase("*********")) + +/datum/brain_trauma/severe/hypnotic_trigger/proc/hypnotrigger() + to_chat(owner, span_warning("The words trigger something deep within you, and you feel your consciousness slipping away...")) + owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE) \ No newline at end of file diff --git a/modular_dripstation/code/datum/component/transforming.dm b/modular_dripstation/code/datum/component/transforming.dm new file mode 100644 index 000000000000..3941d5eabe6c --- /dev/null +++ b/modular_dripstation/code/datum/component/transforming.dm @@ -0,0 +1,258 @@ +/* + * Transforming weapon component. For weapons that swap between states. + * For example: Energy swords, cleaving saws, switch blades. + * + * Used to easily make an item that can be attack_self'd to gain force or change mode. + * + * Only values passed on initialize will update when the item is activated (except the icon_state). + * The icon_state of the item will swap between "[icon_state]" and "[icon_state]_on". + */ +/datum/component/transforming + /// Whether the weapon is transformed + var/active = FALSE + /// Cooldown on transforming this item back and forth + var/transform_cooldown_time + /// Force of the weapon when active + var/force_on + /// Throwforce of the weapon when active + var/throwforce_on + /// Throw speed of the weapon when active + var/throw_speed_on + /// Weight class of the weapon when active + var/w_class_on + /// The sharpness of the weapon when active + var/sharpness_on + /// Hitsound played when active + var/hitsound_on + /// List of the original continuous attack verbs the item has. + var/list/attack_verb_off + /// List of simple attack verbs used when the weapon is enabled + var/list/attack_verb_on + /// Whether clumsy people need to succeed an RNG check to turn it on without hurting themselves + var/clumsy_check + /// If we get sharpened with a whetstone, save the bonus here for later use if we un/redeploy + var/sharpened_bonus = 0 + /// Dictate whether we change inhands or not + var/item_state_change = TRUE + /// Cooldown in between transforms + COOLDOWN_DECLARE(transform_cooldown) + +/datum/component/transforming/Initialize( + start_transformed = FALSE, + transform_cooldown_time = 0 SECONDS, + force_on = 0, + throwforce_on = 0, + throw_speed_on = 2, + sharpness_on = NONE, + hitsound_on = 'sound/weapons/blade1.ogg', + w_class_on = WEIGHT_CLASS_BULKY, + clumsy_check = TRUE, + list/attack_verb_on, + item_state_change = TRUE, +) + + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + + var/obj/item/item_parent = parent + + src.transform_cooldown_time = transform_cooldown_time + src.force_on = force_on + src.throwforce_on = throwforce_on + src.throw_speed_on = throw_speed_on + src.sharpness_on = sharpness_on + src.hitsound_on = hitsound_on + src.w_class_on = w_class_on + src.clumsy_check = clumsy_check + src.item_state_change = item_state_change + + if(attack_verb_on) + src.attack_verb_on = attack_verb_on + attack_verb_off = item_parent.attack_verb + + if(start_transformed) + toggle_active(parent) + +/datum/component/transforming/RegisterWithParent() + var/obj/item/item_parent = parent + + RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_attack_self)) + if(item_parent.sharpness || sharpness_on) + RegisterSignal(parent, COMSIG_ITEM_SHARPEN_ACT, PROC_REF(on_sharpen)) + + RegisterSignal(parent, COMSIG_DETECTIVE_SCANNED, PROC_REF(on_scan)) + +/datum/component/transforming/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_ITEM_ATTACK_SELF, COMSIG_ITEM_SHARPEN_ACT, COMSIG_DETECTIVE_SCANNED)) + +/datum/component/transforming/proc/on_scan(datum/source, mob/user, list/extra_data) + SIGNAL_HANDLER + LAZYADD(extra_data[DETSCAN_CATEGORY_NOTES], "Readings suggest some form of state changing.") + + +/* + * Called on [COMSIG_ITEM_ATTACK_SELF]. + * + * Check if we can transform our weapon, and if so, call [do_transform]. + * Sends signal [COMSIG_TRANSFORMING_PRE_TRANSFORM], and stops the transform action if it returns [COMPONENT_BLOCK_TRANSFORM]. + * And, if [do_transform] was successful, do a clumsy effect from [clumsy_transform_effect]. + * + * source - source of the signal, the item being transformed / parent + * user - the mob transforming the weapon + */ +/datum/component/transforming/proc/on_attack_self(obj/item/source, mob/user) + SIGNAL_HANDLER + + if(!COOLDOWN_FINISHED(src, transform_cooldown)) + to_chat(user, span_warning("Wait a bit before trying to use [source] again!")) + return + + if(SEND_SIGNAL(source, COMSIG_TRANSFORMING_PRE_TRANSFORM, user, active) & COMPONENT_BLOCK_TRANSFORM) + return + + if(do_transform(source, user)) + clumsy_transform_effect(user) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/* + * Transform the weapon into its alternate form, calling [toggle_active]. + * + * Sends signal [COMSIG_TRANSFORMING_ON_TRANSFORM], and calls [default_transform_message] if it does not return [COMPONENT_NO_DEFAULT_MESSAGE]. + * Also starts the [transform_cooldown] if we have a set [transform_cooldown_time]. + * + * source - the item being transformed / parent + * user - the mob transforming the item + * + * returns TRUE. + */ +/datum/component/transforming/proc/do_transform(obj/item/source, mob/user) + toggle_active(source) + if(!(SEND_SIGNAL(source, COMSIG_TRANSFORMING_ON_TRANSFORM, user, active) & COMPONENT_NO_DEFAULT_MESSAGE)) + default_transform_message(source, user) + + if(isnum(transform_cooldown_time)) + COOLDOWN_START(src, transform_cooldown, transform_cooldown_time) + if(user) + source.add_fingerprint(user) + return TRUE + +/* + * The default feedback message and sound effect for an item transforming. + * + * source - the item being transformed / parent + * user - the mob transforming the item + */ +/datum/component/transforming/proc/default_transform_message(obj/item/source, mob/user) + if(user) + source.balloon_alert(user, "[active ? "enabled" : "disabled"] [source]") + playsound(source, 'sound/weapons/batonextend.ogg', 50, TRUE) + +/* + * Toggle active between true and false, and call + * either set_active or set_inactive depending on whichever state is toggled. + * + * source - the item being transformed / parent + */ +/datum/component/transforming/proc/toggle_active(obj/item/source) + active = !active + if(active) + set_active(source) + else + set_inactive(source) + +/* + * Set our transformed item into its active state. + * Updates all the values that were passed from init and the icon_state. + * + * source - the item being transformed / parent + */ +/datum/component/transforming/proc/set_active(obj/item/source) + ADD_TRAIT(source, TRAIT_TRANSFORM_ACTIVE, REF(src)) + if(sharpness_on) + source.sharpness = sharpness_on + if(force_on) + source.force = force_on + (source.sharpness ? sharpened_bonus : 0) + if(throwforce_on) + source.throwforce = throwforce_on + (source.sharpness ? sharpened_bonus : 0) + if(throw_speed_on) + source.throw_speed = throw_speed_on + + if(LAZYLEN(attack_verb_on)) + source.attack_verb = attack_verb_on + + source.hitsound = hitsound_on + source.w_class = w_class_on + source.icon_state = "[source.icon_state]_on" + if(item_state_change && source.item_state) + source.item_state = "[source.item_state]_on" + source.update_icon() + +/* + * Set our transformed item into its inactive state. + * Updates all the values back to the item's initial values. + * + * source - the item being un-transformed / parent + */ +/datum/component/transforming/proc/set_inactive(obj/item/source) + REMOVE_TRAIT(source, TRAIT_TRANSFORM_ACTIVE, REF(src)) + if(sharpness_on) + source.sharpness = initial(source.sharpness) + if(force_on) + source.force = initial(source.force) + (source.sharpness ? sharpened_bonus : 0) + if(throwforce_on) + source.throwforce = initial(source.throwforce) + (source.sharpness ? sharpened_bonus : 0) + if(throw_speed_on) + source.throw_speed = initial(source.throw_speed) + + if(LAZYLEN(attack_verb_on)) + source.attack_verb = attack_verb_off + + source.hitsound = initial(source.hitsound) + source.w_class = initial(source.w_class) + source.icon_state = initial(source.icon_state) + source.item_state = initial(source.item_state) + +/* + * If [clumsy_check] is set to TRUE, attempt to cause a side effect for clumsy people activating this item. + * Called after the transform is done, meaning [active] var has already updated. + * + * user - the clumsy mob, transforming our item (parent) + * + * Returns TRUE if side effects happened, FALSE otherwise + */ +/datum/component/transforming/proc/clumsy_transform_effect(mob/living/user) + if(!clumsy_check) + return FALSE + + if(!user || !HAS_TRAIT(user, TRAIT_CLUMSY)) + return FALSE + + if(active && prob(50)) + var/hurt_self_verb = LAZYLEN(attack_verb_on) ? pick(attack_verb_on) : "hited" + user.visible_message( + span_warning("[user] triggers [parent] while holding it backwards and [hurt_self_verb] themself, like a doofus!"), + span_warning("You trigger [parent] while holding it backwards and [hurt_self_verb] yourself, like a doofus!"), + ) + user.take_bodypart_damage(10) + return TRUE + return FALSE + +/* + * Called on [COMSIG_ITEM_SHARPEN_ACT]. + * We need to track our sharpened bonus here, so we correctly apply and unapply it + * if our item's sharpness state changes from transforming. + * + * source - the item being sharpened / parent + * increment - the amount of force added + * max - the maximum force that the item can be adjusted to. + * + * Does not return naturally [COMPONENT_BLOCK_SHARPEN_APPLIED] as this is only to track our sharpened bonus between transformation. + */ +/datum/component/transforming/proc/on_sharpen(obj/item/source, increment, max) + SIGNAL_HANDLER + + if(sharpened_bonus) + return COMPONENT_BLOCK_SHARPEN_ALREADY + if(force_on + increment > max) + return COMPONENT_BLOCK_SHARPEN_MAXED + sharpened_bonus = increment diff --git a/modular_dripstation/code/datum/reagent/baldium.dm b/modular_dripstation/code/datum/reagent/baldium.dm new file mode 100644 index 000000000000..82a53e58bf36 --- /dev/null +++ b/modular_dripstation/code/datum/reagent/baldium.dm @@ -0,0 +1,16 @@ +/datum/reagent/baldium + name = "Baldium" + description = "A major cause of hair loss across the world." + reagent_state = LIQUID + color = "#ecb2cf" + taste_description = "bitterness" + +/datum/reagent/baldium/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE) + . = ..() + if(!(method & (TOUCH|VAPOR)) || !ishuman(L)) + return + + var/mob/living/carbon/human/baldtarget = L + to_chat(baldtarget, span_danger("Your hair is falling out in clumps!")) + baldtarget.facial_hair_style = "Shaved" + baldtarget.hair_style = "Bald" diff --git a/modular_dripstation/code/datum/reagent/chemoverride.dm b/modular_dripstation/code/datum/reagent/chemoverride.dm new file mode 100644 index 000000000000..31055843eb4f --- /dev/null +++ b/modular_dripstation/code/datum/reagent/chemoverride.dm @@ -0,0 +1,40 @@ +/datum/reagent/medicine/mannitol + name = "Mannitol" + description = "Efficiently restores brain damage. Requires very cold temperatures to properly metabolize." + color = "#DCDCFF" + metabolization_rate = 1.5 * REAGENTS_METABOLISM + +/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/M) + if(M.bodytemperature < T0C) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, (holder.has_reagent(/datum/reagent/drug/methamphetamine) ? 0 : -2)*REM) + . = 1 + else + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, (holder.has_reagent(/datum/reagent/drug/methamphetamine) ? 0 : -0.2)*REM) + metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5) + ..() + +/datum/reagent/medicine/mannitol/advanced + name = "Advanced mannitol" + description = "Efficiently restores brain damage. Really." + color = "#4CE8E2" + metabolization_rate = REAGENTS_METABOLISM + +/datum/reagent/medicine/mannitol/advanced/on_mob_life(mob/living/carbon/M) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, (holder.has_reagent(/datum/reagent/drug/methamphetamine) ? 0 : -2)*REM) + current_cycle++ + holder.remove_reagent(type, metabolization_rate / M.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism + +/datum/reagent/medicine/clonexadone + name = "Clonexadone" + description = "A chemical that derives from Cryoxadone. It specializes in healing clone damage, but nothing else. Requires very cold temperatures to properly metabolize, and metabolizes quicker than cryoxadone." + color = "#80BFFF" + taste_description = "muscle" + metabolization_rate = 1.5 * REAGENTS_METABOLISM + +/datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M) + if(M.bodytemperature < T0C && M.IsSleeping()) //yes you have to be in cryo shut up and drink your corn syrup + M.adjustCloneLoss(0.001 * (M.bodytemperature ** 2) - 100, 0) + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) + . = 1 + metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (M.bodytemperature ** 2) + 0.75) + ..() \ No newline at end of file diff --git a/modular_dripstation/code/datum/reagent/leadacetate.dm b/modular_dripstation/code/datum/reagent/leadacetate.dm new file mode 100644 index 000000000000..708ceb1c7d1e --- /dev/null +++ b/modular_dripstation/code/datum/reagent/leadacetate.dm @@ -0,0 +1,16 @@ +/datum/reagent/toxin/leadacetate + name = "Lead Acetate" + description = "Used hundreds of years ago as a sweetener, before it was realized that it's incredibly poisonous." + reagent_state = SOLID + color = "#2b2b2b" // rgb: 127, 132, 0 + toxpwr = 0.5 + taste_mult = 1.3 + taste_description = "sugary sweetness" + +/datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/affected_mob) + affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 SECONDS * REM) + affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 SECONDS * REM) + if(prob(5)) + to_chat(affected_mob, span_notice("Ah, what was that? You thought you heard something...")) + affected_mob.adjust_confusion(5 SECONDS) + return ..() \ No newline at end of file diff --git a/modular_dripstation/code/datum/strong_pull.dm b/modular_dripstation/code/datum/strong_pull.dm new file mode 100644 index 000000000000..8a6d851b7559 --- /dev/null +++ b/modular_dripstation/code/datum/strong_pull.dm @@ -0,0 +1,47 @@ +/* +This component attaches to mobs, and makes their pulls !strong! +Basically, the items they pull cannot be pulled (except by the puller) +*/ +/datum/component/strong_pull + var/atom/movable/strongpulling + +/datum/component/strong_pull/Initialize() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/strong_pull/Destroy(force, silent) + if(strongpulling) + lose_strong_grip() + return ..() + +/datum/component/strong_pull/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_LIVING_START_PULL, PROC_REF(on_pull)) + +/** + * Called when the parent grabs something, adds signals to the object to reject interactions + */ +/datum/component/strong_pull/proc/on_pull(datum/source, atom/movable/pulled, state, force) + SIGNAL_HANDLER + strongpulling = pulled + RegisterSignal(strongpulling, COMSIG_ATOM_NO_LONGER_PULLED, PROC_REF(on_no_longer_pulled)) + if(istype(strongpulling, /obj/structure/closet) && !istype(strongpulling, /obj/structure/closet/body_bag)) + var/obj/structure/closet/grabbed_closet = strongpulling + grabbed_closet.strong_grab = TRUE + +/** + * Unregisters signals and stops any buffs to pulling. + */ +/datum/component/strong_pull/proc/lose_strong_grip() + UnregisterSignal(strongpulling, list(COMSIG_ATOM_CAN_BE_PULLED, COMSIG_ATOM_NO_LONGER_PULLED)) + if(istype(strongpulling, /obj/structure/closet)) + var/obj/structure/closet/ungrabbed_closet = strongpulling + ungrabbed_closet.strong_grab = FALSE + strongpulling = null + +/** + * Called when the hooked object is no longer pulled and removes the strong grip. + */ +/datum/component/strong_pull/proc/on_no_longer_pulled(datum/source, atom/movable/last_puller) + SIGNAL_HANDLER + lose_strong_grip() \ No newline at end of file diff --git a/modular_dripstation/code/game/effects/effects_foam.dm b/modular_dripstation/code/game/effects/effects_foam.dm new file mode 100644 index 000000000000..44a0869d2d5f --- /dev/null +++ b/modular_dripstation/code/game/effects/effects_foam.dm @@ -0,0 +1,30 @@ +/obj/structure/foamedmetal/attackby(obj/item/W, mob/user, params) + ///A speed modifier for how fast the wall is build + var/platingmodifier = 1 + if(HAS_TRAIT(user, TRAIT_QUICK_BUILD)) + platingmodifier = 0.7 + if(next_beep <= world.time) + next_beep = world.time + 1 SECONDS + playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE) + add_fingerprint(user) + + if(!istype(W, /obj/item/stack/sheet)) + return ..() + + var/obj/item/stack/sheet/sheet_for_plating = W + if(istype(sheet_for_plating, /obj/item/stack/sheet/metal)) + if(sheet_for_plating.get_amount() < 2) + to_chat(user, span_warning("You need two sheets of iron to finish a wall on [src]!")) + return + to_chat(user, span_notice("You start adding plating to the foam structure...")) + if (do_after(user, 40 * platingmodifier, target = src)) + if(!sheet_for_plating.use(2)) + return + to_chat(user, span_notice("You add the plating.")) + var/turf/T = get_turf(src) + T.PlaceOnTop(/turf/closed/wall/metal_foam_base) + transfer_fingerprints_to(T) + qdel(src) + return + + add_hiddenprint(user) diff --git a/modular_dripstation/code/game/mecha/cargo_hauler.dm b/modular_dripstation/code/game/mecha/cargo_hauler.dm new file mode 100644 index 000000000000..c6a106c7b396 --- /dev/null +++ b/modular_dripstation/code/game/mecha/cargo_hauler.dm @@ -0,0 +1,51 @@ +GLOBAL_DATUM(cargo_ripley, /obj/mecha/working/ripley/cargo) + +/obj/mecha/working/ripley/cargo + desc = "An ailing, old, repurposed cargo hauler. Most of its equipment wires are frayed or missing and its frame is rusted. You should handle best queen carefully." + name = "\improper APLU \"Queen Bess II\"" + icon_state = "hauler" + silicon_icon_state = "hauler-empty" + icon = 'modular_dripstation/icons/mob/mecha/cargo_hauler.dmi' + fast_pressure_step_in = 1 //step_in while in low pressure conditions, fast as fuck boi + slow_pressure_step_in = 1.3 //step_in while in normal pressure conditions + step_in = 1.3 + max_equip = 5 //modified exoskeleton power drive + max_integrity = 150 //Lesser health then have normal RIPLEY mech, so it's harder to use as a weapon. + obj_integrity = 75 //Starting at low health + internals_req_access = list(ACCESS_CARGO, ACCESS_MECH_SCIENCE) //Giving access to cargotech & robo + +/obj/mecha/working/ripley/cargo/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "Mech`s power drive looks modified." + +/obj/mecha/working/ripley/cargo/attack_hand(mob/living/carbon/human/user, params) + . = ..() + if(user.a_intent == INTENT_DISARM) + user.say("All hail the queen!") + +/obj/mecha/working/ripley/cargo/Initialize(mapload) + . = ..() + if(cell) + cell.charge = FLOOR(cell.charge * 0.33, 1) //Starts at very low charge + + //Attach hydraulic clamp ONLY + var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new + HC.attach(src) + + take_damage(50, sound_effect=FALSE) //Low starting health + if(!GLOB.cargo_ripley && mapload) + GLOB.cargo_ripley = src + +/obj/mecha/working/ripley/cargo/Destroy() + if(GLOB.cargo_ripley == src) + GLOB.cargo_ripley = null + + return ..() + +/obj/structure/mecha_wreckage/ripley/cargo + name = "\improper APLU \"Queen Bess II\ wreckage" + desc = "Oh no, Bessy!" + icon_state = "hauler-broken" + icon = 'modular_dripstation/icons/mob/mecha/cargo_hauler.dmi' + orig_mecha = /obj/mecha/working/ripley/cargo \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/boomerang.dm b/modular_dripstation/code/game/objects/items/bepis_items/boomerang.dm new file mode 100644 index 000000000000..e515a2776e17 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/boomerang.dm @@ -0,0 +1,34 @@ +//bepis boomerang +/obj/item/melee/baton/boomerang + name = "\improper OZtek Boomerang" + desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!" + throw_speed = 2 + icon = 'modular_dripstation/icons/obj/weapons/security.dmi' + lefthand_file = 'modular_dripstation/icons/mob/inhands/security_lefthand.dmi' + righthand_file = 'modular_dripstation/icons/mob/inhands/security_righthand.dmi' + icon_state = "boomerang" + item_state = "boomerang" + force = 5 + throwforce = 5 + throw_range = 5 + hitcost = 2000 + throw_hit_chance = 99 //Have you prayed today? + custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 1000) + +/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(!status) + return ..() + var/caught = hit_atom.hitby(src, skipcatch = FALSE, hitpush = FALSE, throwingdatum = throwingdatum) + if(isliving(hit_atom) && !iscyborg(hit_atom) && !caught && prob(throw_hit_chance))//if they are a living creature and they didn't catch it + baton_stun(hit_atom, thrownby) + throw_at(thrownby, throw_range+3, throw_speed, null) + ..() + +/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, quickstart = TRUE) + if(iscarbon(thrower)) + var/mob/living/carbon/C = thrower + C.throw_mode_on() + ..() + +/obj/item/melee/baton/boomerang/loaded //Same as above, comes with a cell. + preload_cell_type = /obj/item/stock_parts/cell/high \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm new file mode 100644 index 000000000000..3a8a22099eb4 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm @@ -0,0 +1,10 @@ +/obj/item/clothing/gloves/tinkerer + name = "tinker's gloves" + desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn." + item_state = "orange" + icon_state = "clockwork_gauntlets" + siemens_coefficient = 0.8 + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50) + clothing_flags = list(TRAIT_QUICK_BUILD) + custom_materials = list(/datum/material/iron= 2000, /datum/material/silver= 1500, /datum/material/gold = 1000) + resistance_flags = NONE \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/explorerpin.dm b/modular_dripstation/code/game/objects/items/bepis_items/explorerpin.dm new file mode 100644 index 000000000000..f8b7870f8c3e --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/explorerpin.dm @@ -0,0 +1,14 @@ +// Explorer Firing Pin- Prevents use on station Z-Level, so it's justifiable to give Explorers guns that don't suck. +/obj/item/firing_pin/explorer + name = "outback firing pin" + desc = "A firing pin used by the austrailian defense force, retrofit to prevent weapon discharge on the station." + icon = 'modular_dripstation/icons/obj/device.dmi' + icon_state = "firing_pin_explorer" + fail_message = "Cannot fire while on station, mate!" + +// This checks that the user isn't on the station Z-level. +/obj/item/firing_pin/explorer/pin_auth(mob/living/user) + var/turf/station_check = get_turf(user) + if(!station_check || is_station_level(station_check.z)) + return FALSE + return TRUE \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/hypnochair.dm b/modular_dripstation/code/game/objects/items/bepis_items/hypnochair.dm new file mode 100644 index 000000000000..fea093548bfe --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/hypnochair.dm @@ -0,0 +1,223 @@ +/obj/item/circuitboard/machine/hypnochair + name = "Enhanced Interrogation Chamber" + build_path = /obj/machinery/hypnochair + icon_state = "security" + req_components = list( + /obj/item/stock_parts/micro_laser = 2, + /obj/item/stock_parts/scanning_module = 2 + ) + + +/obj/machinery/hypnochair + name = "enhanced interrogation chamber" + desc = "A device used to perform \"enhanced interrogation\" through invasive mental conditioning." + icon = 'modular_dripstation/icons/obj/hypnochair.dmi' + icon_state = "hypnochair" + base_icon_state = "hypnochair" + circuit = /obj/item/circuitboard/machine/hypnochair + density = TRUE + opacity = FALSE + + var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away + var/interrogating = FALSE ///Is the device currently interrogating someone? + var/start_time = 0 ///Time when the interrogation was started, to calculate effect in case of interruption + var/trigger_phrase = "" ///Trigger phrase to implant + var/timerid = 0 ///Timer ID for interrogations + var/message_cooldown = 0 ///Cooldown for breakout message + var/resisting = FALSE ///Yeah, shitcode my beloved + +/obj/machinery/hypnochair/Initialize(mapload) + . = ..() + open_machine() + update_icon() + +/obj/machinery/hypnochair/attackby(obj/item/I, mob/user, params) + if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I)) + update_icon() + return + if(default_pry_open(I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() + +/obj/machinery/hypnochair/ui_state(mob/user) + return GLOB.notcontained_state + +/obj/machinery/hypnochair/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "HypnoChair", name) + ui.open() + +/obj/machinery/hypnochair/ui_data() + var/list/data = list() + var/mob/living/mob_occupant = occupant + + data["occupied"] = mob_occupant ? 1 : 0 + data["open"] = state_open + data["interrogating"] = interrogating + + data["occupant"] = list() + if(mob_occupant) + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat + + data["trigger"] = trigger_phrase + + return data + +/obj/machinery/hypnochair/ui_act(action, params) + . = ..() + if(.) + return + + switch(action) + if("door") + if(state_open) + close_machine() + else + if(!interrogating) + open_machine() + . = TRUE + if("set_phrase") + set_phrase(params["phrase"]) + . = TRUE + if("interrogate") + if(!interrogating) + interrogate() + else + interrupt_interrogation() + . = TRUE + +/obj/machinery/hypnochair/proc/set_phrase(phrase) + trigger_phrase = phrase + +/obj/machinery/hypnochair/proc/interrogate() + if(!trigger_phrase) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE) + return + var/mob/living/carbon/C = occupant + if(!istype(C)) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE) + return + victim = C + if(C.get_eye_protection() <= 0) + to_chat(C, span_warning("Strobing coloured lights assault you relentlessly! You're losing your ability to think straight!")) + C.become_blind(HYPNOCHAIR_TRAIT) + ADD_TRAIT(C, TRAIT_DEAF, HYPNOCHAIR_TRAIT) + interrogating = TRUE + START_PROCESSING(SSobj, src) + start_time = world.time + update_icon() + timerid = addtimer(CALLBACK(src, PROC_REF(finish_interrogation)), 450, TIMER_STOPPABLE) + +/obj/machinery/hypnochair/process(delta_time) + var/mob/living/carbon/C = occupant + if(!istype(C) || C != victim) + interrupt_interrogation() + return + if(DT_PROB(5, delta_time) && !(C.get_eye_protection() > 0)) + to_chat(C, "[pick(\ + "...blue... red... green... blue, red, green, blueredgreen[span_small("blueredgreen")]",\ + "...pretty colors...",\ + "...you keep hearing words, but you can't seem to understand them...",\ + "...so peaceful...",\ + "...an annoying buzz in your ears..."\ + )]") + + use_power(active_power_usage * delta_time) + +/obj/machinery/hypnochair/proc/finish_interrogation() + interrogating = FALSE + STOP_PROCESSING(SSobj, src) + update_icon() + var/temp_trigger = trigger_phrase + trigger_phrase = "" //Erase evidence, in case the subject is able to look at the panel afterwards + audible_message(span_notice("[src] pings!")) + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + + if(QDELETED(victim) || victim != occupant) + victim = null + return + victim.cure_blind(HYPNOCHAIR_TRAIT) + REMOVE_TRAIT(victim, TRAIT_DEAF, HYPNOCHAIR_TRAIT) + if(!(victim.get_eye_protection() > 0)) + victim.cure_trauma_type(/datum/brain_trauma/severe/hypnotic_trigger, TRAUMA_RESILIENCE_SURGERY) + if(prob(90)) + victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_trigger(temp_trigger), TRAUMA_RESILIENCE_SURGERY) + else + victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_stupor(), TRAUMA_RESILIENCE_SURGERY) + victim = null + +/obj/machinery/hypnochair/proc/interrupt_interrogation() + deltimer(timerid) + interrogating = FALSE + STOP_PROCESSING(SSobj, src) + update_icon() + + if(QDELETED(victim)) + victim = null + return + victim.cure_blind(HYPNOCHAIR_TRAIT) + REMOVE_TRAIT(victim, TRAIT_DEAF, HYPNOCHAIR_TRAIT) + if(!(victim.get_eye_protection() > 0)) + var/time_diff = world.time - start_time + switch(time_diff) + if(0 to 100) + victim.adjust_confusion(10 SECONDS) + victim.set_dizzy_if_lower(100 SECONDS) + victim.blur_eyes(100) + if(101 to 200) + victim.adjust_confusion(15 SECONDS) + victim.set_dizzy_if_lower(200 SECONDS) + victim.blur_eyes(200) + if(prob(25)) + victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE) + if(201 to INFINITY) + victim.adjust_confusion(20 SECONDS) + victim.set_dizzy_if_lower(300 SECONDS) + victim.blur_eyes(300) + if(prob(65)) + victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE) + victim = null + +/obj/machinery/hypnochair/update_icon_state() + if((stat & MAINT) || panel_open) + icon_state = "[base_icon_state][state_open ? "_open" : null]"+"_maintenance" + else + icon_state = "[base_icon_state][state_open ? "_open" : null][occupant ? "_[interrogating ? "active" : "occupied"]" : null]" + return ..() + +/obj/machinery/hypnochair/update_icon() + . = ..() + update_icon_state() + +/obj/machinery/hypnochair/container_resist(mob/living/user) + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message(span_notice("You see [user] kicking against the door of [src]!"), \ + span_notice("You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)"), \ + span_hear("You hear a metallic creaking from [src].")) + if(do_after(user,(600), target = src)) + if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) + return + user.visible_message(span_warning("[user] successfully broke out of [src]!"), \ + span_notice("You successfully break out of [src]!")) + open_machine() + +/obj/machinery/hypnochair/relaymove(mob/living/user, direction) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, span_warning("[src]'s door won't budge!")) + if(resisting) + return + container_resist(user) + resisting = TRUE + + +/obj/machinery/hypnochair/MouseDrop_T(mob/target, mob/user) + if(HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) + return + + close_machine(target) \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/lava_rods.dm b/modular_dripstation/code/game/objects/items/bepis_items/lava_rods.dm new file mode 100644 index 000000000000..ad31ec9f5b7e --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/lava_rods.dm @@ -0,0 +1,84 @@ +/obj/item/stack/rods/lava + name = "heat resistant rod" + desc = "Treated, specialized iron rods. When exposed to the vaccum of space their coating breaks off, but they can hold up against the extreme heat of active lava." + singular_name = "heat resistant rod" + icon_state = "rods" + item_state = "rods" + color = "#5286b9ff" + flags_1 = CONDUCT_1 + w_class = WEIGHT_CLASS_NORMAL + materials = list(/datum/material/iron = 1000, /datum/material/plasma = 500, /datum/material/titanium = 2000) + max_amount = 30 + resistance_flags = FIRE_PROOF | LAVA_PROOF + merge_type = /obj/item/stack/rods/lava + +/obj/item/stack/rods/lava/thirty + amount = 30 + +/obj/structure/lattice/lava + name = "heatproof support lattice" + desc = "A specialized support beam for building across lava. Watch your step." + icon = 'icons/obj/smooth_structures/catwalk.dmi' + icon_state = "catwalk" + number_of_rods = 1 + color = "#5286b9ff" + obj_flags = CAN_BE_HIT + resistance_flags = FIRE_PROOF | LAVA_PROOF + +/obj/structure/lattice/lava/over + layer = CATWALK_LAYER + plane = GAME_PLANE + +/obj/structure/lattice/lava/deconstruction_hints(mob/user) + return span_notice("The rods look like they could be cut, but the heat treatment will shatter off. There's space for a tile.") + +/obj/structure/lattice/lava/attackby(obj/item/C, mob/user, params) + . = ..() + if(istype(C, /obj/item/stack/tile/plasteel)) + var/obj/item/stack/tile/plasteel/P = C + if(P.use(1)) + to_chat(user, span_notice("You construct a floor plating, as lava settles around the rods.")) + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /turf/open/floor/plating(locate(x, y, z)) + else + to_chat(user, span_warning("You need one floor tile to build atop [src].")) + return + +/turf/open/lava/attackby(obj/item/C, mob/user, params) + ..() + if(istype(C, /obj/item/stack/rods/lava)) + var/obj/item/stack/rods/lava/R = C + var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src) + if(H) + to_chat(user, span_warning("There is already a lattice here!")) + return + if(R.use(1)) + to_chat(user, span_notice("You construct a lattice.")) + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /obj/structure/lattice/lava(locate(x, y, z)) + else + to_chat(user, span_warning("You need one rod to build a heatproof lattice.")) + return + // Light a cigarette in the lava + if(istype(C, /obj/item/clothing/mask/cigarette)) + var/obj/item/clothing/mask/cigarette/ciggie = C + if(ciggie.lit) + to_chat(user, span_warning("The [ciggie.name] is already lit!")) + return TRUE + var/clumsy_modifier = HAS_TRAIT(user, TRAIT_CLUMSY) ? 2 : 1 + if(prob(25 * clumsy_modifier )) + ciggie.light(span_warning("[user] expertly dips \the [ciggie.name] into [src], along with the rest of [user.p_their()] arm. What a dumbass.")) + var/obj/item/bodypart/affecting = user.get_active_hand() + affecting?.receive_damage(burn = 90) + else + ciggie.light(span_rose("[user] expertly dips \the [ciggie.name] into [src], lighting it with the scorching heat of the planet. Witnessing such a feat is almost enough to make you cry.")) + return TRUE + +/turf/open/lava/is_safe() + //if anything matching this typecache is found in the lava, we don't burn things + var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/lattice/lava, /obj/structure/stone_tile)) + var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache) + for(var/obj/structure/stone_tile/S in found_safeties) + if(S.fallen) + LAZYREMOVE(found_safeties, S) + return LAZYLEN(found_safeties) \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/party_pod.dm b/modular_dripstation/code/game/objects/items/bepis_items/party_pod.dm new file mode 100644 index 000000000000..a35f01397169 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/party_pod.dm @@ -0,0 +1,309 @@ +/obj/item/circuitboard/machine/sleeper/party + name = "Party Pod" + build_path = /obj/machinery/party + +/obj/machinery/party + name = "party pod" + desc = "'Sleeper' units were once known for their healing properties, until a lengthy investigation revealed they were also dosing patients with deadly lead acetate. This appears to be one of those old 'sleeper' units repurposed as a 'Party Pod'. It’s probably not a good idea to use it." + icon_state = "partypod" + base_icon_state = "partypod" + icon = 'modular_dripstation/icons/obj/partypod.dmi' + circuit = /obj/item/circuitboard/machine/sleeper/party + + density = FALSE + state_open = TRUE + payment_department = ACCOUNT_MED + fair_market_price = 5 + + ///How much chems is allowed to be in a patient at once, before we force them to wait for the reagent to process. + var/efficiency = 1 + ///Whether the machine can be operated by the person inside of it. + var/controls_inside = TRUE + var/enter_message = "You're surrounded by some funky music inside the chamber. You zone out as you feel waves of krunk vibe within you." + var/min_health = -25 + ///List of currently available chems. + var/list/available_chems = list() + ///Used when emagged to scramble which chem is used, eg: mutadone -> morphine + var/list/chem_buttons + //Exclusively uses non-lethal, "fun" chems. At an obvious downside. + var/list/possible_chems = list( + list( + /datum/reagent/consumable/ethanol/beer, + /datum/reagent/consumable/laughter, + ), + list( + /datum/reagent/spraytan, + /datum/reagent/barbers_aid, + ), + list( + /datum/reagent/colorful_reagent, + /datum/reagent/hair_dye, + ), + list( + /datum/reagent/drug/space_drugs, + /datum/reagent/baldium, + ), + ) + ///Chemicals that need to have a touch or vapor reaction to be applied, not the standard chamber reaction. + var/spray_chems = list( + /datum/reagent/spraytan, + /datum/reagent/hair_dye, + /datum/reagent/baldium, + /datum/reagent/barbers_aid, + ) + +/obj/machinery/party/Initialize(mapload) + . = ..() + if(mapload) + LAZYREMOVE(component_parts, circuit) + QDEL_NULL(circuit) + occupant_typecache = GLOB.typecache_living + update_icon() + reset_chem_buttons() + +/obj/machinery/party/RefreshParts() + . = ..() + var/matterbin_rating + for(var/obj/item/stock_parts/matter_bin/matterbins in component_parts) + matterbin_rating += matterbins.rating + efficiency = initial(efficiency) * matterbin_rating + min_health = initial(min_health) * matterbin_rating + + available_chems.Cut() + for(var/obj/item/stock_parts/manipulator/servos in component_parts) + for(var/i in 1 to servos.rating) + available_chems |= possible_chems[i] + + reset_chem_buttons() + +/obj/machinery/party/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + + balloon_alert(user, "interface scrambled") + obj_flags |= EMAGGED + + var/list/av_chem = available_chems.Copy() + for(var/chem in av_chem) + chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct + return TRUE + +/obj/machinery/party/proc/inject_chem(chem, mob/user) + if(obj_flags & EMAGGED) + occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, 4) + else if (prob(20)) //You're injecting chemicals into yourself from a recalled, decrepit medical machine. What did you expect? + occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, rand(1,3)) + if(chem in spray_chems) + var/datum/reagents/holder = new() + holder.add_reagent(chem_buttons[chem], 10) //I hope this is the correct way to do this. + holder.trans_to(occupant, 10) //, methods = VAPOR untill proc trans_to remade + playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6) + if(user) + log_combat(user, occupant, "sprayed [chem] into", addition = "via [src]") + return TRUE + if((chem in available_chems) && chem_allowed(chem)) + occupant.reagents.add_reagent(chem_buttons[chem], 10) //emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU + if(user) + log_combat(user, occupant, "injected [chem] into", addition = "via [src]") + return TRUE + +/obj/machinery/party/proc/chem_allowed(chem) + var/mob/living/mob_occupant = occupant + if(!mob_occupant || !mob_occupant.reagents) + return + var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency + var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine + return amount && occ_health + +/obj/machinery/party/proc/reset_chem_buttons() + obj_flags &= ~EMAGGED + LAZYINITLIST(chem_buttons) + for(var/chem in available_chems) + chem_buttons[chem] = chem + + +/obj/machinery/party/update_icon() + icon_state = "[base_icon_state][state_open ? "-open" : null]" + return ..() + +/obj/machinery/party/proc/container_resist_act(mob/living/user) + visible_message(span_notice("[occupant] emerges from [src]!"), + span_notice("You climb out of [src]!")) + open_machine() + +/obj/machinery/party/Exited(atom/movable/gone, direction) + . = ..() + if (!state_open && gone == occupant) + container_resist_act(gone) + +/obj/machinery/party/relaymove(mob/living/user, direction) + if (!state_open) + container_resist_act(user) + +/obj/machinery/party/open_machine(drop = TRUE, density_to_set = FALSE) + if(!state_open && !panel_open) + flick("[initial(icon_state)]-anim", src) + return ..() + +/obj/machinery/party/close_machine(mob/user, density_to_set = TRUE) + if((isnull(user) || istype(user)) && state_open && !panel_open) + flick("[initial(icon_state)]-anim", src) + ..() + var/mob/living/mob_occupant = occupant + if(mob_occupant && mob_occupant.stat != DEAD) + to_chat(mob_occupant, "[enter_message]") + +/obj/machinery/party/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(!(stat & (NOPOWER|BROKEN|MAINT)) && occupant) + open_machine() + + +/obj/machinery/party/MouseDrop_T(mob/target, mob/user) + if(HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser()) + return + close_machine(target) + +/obj/machinery/party/screwdriver_act(mob/living/user, obj/item/I) + . = ..() + if(occupant) + to_chat(user, span_warning("[src] is currently occupied!")) + return TRUE + if(state_open) + to_chat(user, span_warning("[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!")) + return TRUE + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) + return TRUE + return FALSE + +/obj/machinery/party/wrench_act(mob/living/user, obj/item/I) + . = ..() + if(default_change_direction_wrench(user, I)) + return TRUE + return FALSE + +/obj/machinery/party/crowbar_act(mob/living/user, obj/item/I) + . = ..() + if(default_pry_open(I)) + return TRUE + if(default_deconstruction_crowbar(I)) + return TRUE + return FALSE + +/obj/machinery/party/default_pry_open(obj/item/I) //wew + . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR + if(.) + I.play_tool_sound(src, 50) + visible_message(span_notice("[usr] pries open [src]."), span_notice("You pry open [src].")) + open_machine() + +/obj/machinery/party/ui_state(mob/user) + if(!controls_inside) + return GLOB.notcontained_state + return GLOB.default_state + +/obj/machinery/party/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Party", name) + ui.open() + +/obj/machinery/party/AltClick(mob/user) + . = ..() + if(state_open) + close_machine() + else + open_machine() + +/obj/machinery/party/examine(mob/user) + . = ..() + . += span_notice("Alt-click [src] to [state_open ? "close" : "open"] it.") + +/obj/machinery/party/process() + ..() + use_power(idle_power_usage) + +/obj/machinery/party/nap_violation(mob/violator) + . = ..() + open_machine() + +/obj/machinery/party/ui_data() + var/list/data = list() + data["occupied"] = !!occupant + data["open"] = state_open + + data["chems"] = list() + for(var/chem in available_chems) + var/datum/reagent/R = GLOB.chemical_reagents_list[chem] + data["chems"] += list( + list( + "name" = R.name, + "id" = R.type, + "allowed" = chem_allowed(chem), + ), + ) + + data["occupant"] = list() + var/mob/living/mob_occupant = occupant + if(mob_occupant) + data["occupant"]["name"] = mob_occupant.name + switch(mob_occupant.stat) + if(CONSCIOUS) + data["occupant"]["stat"] = "Conscious" + data["occupant"]["statstate"] = "good" + if(SOFT_CRIT) + data["occupant"]["stat"] = "Conscious" + data["occupant"]["statstate"] = "average" + if(UNCONSCIOUS) + data["occupant"]["stat"] = "Unconscious" + data["occupant"]["statstate"] = "average" + if(DEAD) + data["occupant"]["stat"] = "Dead" + data["occupant"]["statstate"] = "bad" + data["occupant"]["health"] = mob_occupant.health + data["occupant"]["maxHealth"] = mob_occupant.maxHealth + data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD + data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss() + data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss() + data["occupant"]["toxLoss"] = mob_occupant.getToxLoss() + data["occupant"]["fireLoss"] = mob_occupant.getFireLoss() + data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss() + data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN) + data["occupant"]["reagents"] = list() + if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len) + for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) + data["occupant"]["reagents"] += list( + list( + "name" = R.name, + "volume" = R.volume, + ), + ) + + return data + +/obj/machinery/party/ui_act(action, params) + . = ..() + if(.) + return + + var/mob/living/mob_occupant = occupant + check_nap_violations() + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine() + . = TRUE + if("inject") + var/chem = text2path(params["chem"]) + if((stat & (NOPOWER|BROKEN|MAINT)) || !mob_occupant || isnull(chem)) + return + if(mob_occupant.health < min_health && !ispath(chem, /datum/reagent/medicine/epinephrine)) + return + if(inject_chem(chem, usr)) + . = TRUE + if((obj_flags & EMAGGED) && prob(5)) + to_chat(usr, span_warning("Chemical system re-route detected, results may not be as expected!")) \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/polycircuit.dm b/modular_dripstation/code/game/objects/items/bepis_items/polycircuit.dm new file mode 100644 index 000000000000..c10d74a8960a --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/polycircuit.dm @@ -0,0 +1,59 @@ +/obj/item/stack/circuit_stack + name = "polycircuit aggregate" + desc = "A dense, overdesigned cluster of electronics which attempted to function as a multipurpose circuit electronic. Circuits can be removed from it... if you don't bleed out in the process." + icon = 'modular_dripstation/icons/obj/circuit_mess.dmi' + icon_state = "circuit_mess" + item_state = "rods" + w_class = WEIGHT_CLASS_TINY + max_amount = 8 + merge_type = /obj/item/stack/circuit_stack + singular_name = "circuit aggregate" + var/circuit_type = /obj/item/electronics/airlock + var/chosen_circuit = "airlock" + +/obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it. + to_chat(user, span_warning("You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.")) + +/obj/item/stack/circuit_stack/attack_hand(mob/user, list/modifiers) + var/mob/living/carbon/human/H = user + if(user.get_inactive_held_item() != src) + return ..() + else + if(zero_amount()) + return + chosen_circuit = tgui_input_list(user, "Circuit to remove", "Circuit Removal", list("airlock","firelock","fire alarm","air alarm","APC"), chosen_circuit) + if(isnull(chosen_circuit)) + to_chat(user, span_notice("You wisely avoid putting your hands anywhere near [src].")) + return + if(zero_amount()) + return + if(loc != user) + return + switch(chosen_circuit) + if("airlock") + circuit_type = /obj/item/electronics/airlock + if("firelock") + circuit_type = /obj/item/electronics/firelock + if("fire alarm") + circuit_type = /obj/item/electronics/firealarm + if("air alarm") + circuit_type = /obj/item/electronics/airalarm + if("APC") + circuit_type = /obj/item/electronics/apc + to_chat(user, span_notice("You spot your circuit, and carefully attempt to remove it from [src], hold still!")) + if(do_after(user, 30, target = user)) + if(!src || QDELETED(src))//Sanity Check. + return + var/returned_circuit = new circuit_type(src) + user.put_in_hands(returned_circuit) + use(1) + if(!amount) + to_chat(user, span_notice("You navigate the sharp edges of circuitry and remove the last board.")) + else + to_chat(user, span_notice("You navigate the sharp edges of circuitry and remove a single board from [src]")) + else + H.apply_damage(15, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + to_chat(user, span_warning("You give yourself a wicked cut on [src]'s many sharp corners and edges!")) + +/obj/item/stack/circuit_stack/full + amount = 8 diff --git a/modular_dripstation/code/game/objects/items/bepis_items/rldmini.dm b/modular_dripstation/code/game/objects/items/bepis_items/rldmini.dm new file mode 100644 index 000000000000..c59ca00262d0 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/rldmini.dm @@ -0,0 +1,5 @@ +/obj/item/construction/rld/mini + name = "mini-rapid-light-device" + desc = "A device used to rapidly provide lighting sources to an area. Reload with iron, plasteel, glass or compressed matter cartridges." + matter = 100 + max_matter = 100 \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/sprayoncan.dm b/modular_dripstation/code/game/objects/items/bepis_items/sprayoncan.dm new file mode 100644 index 000000000000..71a5f8c01212 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/sprayoncan.dm @@ -0,0 +1,48 @@ +/obj/item/toy/sprayoncan + name = "spray-on insulation applicator" + desc = "What is the number one problem facing our station today?" + icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' + icon_state = "sprayoncan" + +/obj/item/toy/sprayoncan/afterattack(atom/target, mob/living/carbon/user, proximity) + if(iscarbon(target) && proximity) + var/mob/living/carbon/C = target + var/mob/living/carbon/U = user + var/obj/item/clothing/gloves/color/yellow/sprayon/spr = new(src) + var/success = C.equip_to_slot_or_del(spr, ITEM_SLOT_GLOVES) + if(success) + if(C == U) + C.visible_message(span_notice("[U] sprays their hands with glittery rubber!")) + else + C.visible_message(span_warning("[U] sprays glittery rubber on the hands of [C]!")) + else + C.visible_message(span_warning("The rubber fails to stick to [C]'s hands!")) + +/obj/item/clothing/gloves/color/yellow/sprayon + desc = "How're you gonna get 'em off, nerd?" + name = "spray-on insulated gloves" + icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' + icon_state = "sprayon" + item_state = "sprayon" + item_flags = DROPDEL + resistance_flags = ACID_PROOF + var/charges_remaining = 10 + +/obj/item/clothing/gloves/color/yellow/sprayon/Initialize(mapload) + .=..() + ADD_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT) + +/obj/item/clothing/gloves/color/yellow/sprayon/equipped(mob/user, slot) + . = ..() + RegisterSignal(user, COMSIG_LIVING_SHOCK_PREVENTED, PROC_REF(use_charge)) + RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(use_charge)) + +/obj/item/clothing/gloves/color/yellow/sprayon/proc/use_charge() + SIGNAL_HANDLER + + charges_remaining-- + if(charges_remaining <= 0) + var/turf/location = get_turf(src) + location.visible_message(span_warning("[src] crumble[p_s()] away into nothing.")) // just like my dreams after working with .dm + qdel(src) \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/bepis_items/survival_pen.dm b/modular_dripstation/code/game/objects/items/bepis_items/survival_pen.dm new file mode 100644 index 000000000000..9238fc9e9c76 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/bepis_items/survival_pen.dm @@ -0,0 +1,21 @@ +/obj/item/pen/fountain/survival + name = "survival pen" + desc = "The latest in portable survival technology, this pen was designed as a miniature hardlight shovel. Watchers find them very desirable for their diamond exterior." + icon = 'modular_dripstation/icons/obj/bureaucracy.dmi' + icon_state = "digging_pen" + item_state = "pen" + force = 8 //hard light beats hard, still weaker than the kitchen knife + throwforce = 0 //ineffective at long range + sharpness = SHARP_EDGED // Sharp shovel + resistance_flags = FIRE_PROOF //lavaland is dangerous + attack_verb = list("robusted", "slashed", "stabbed", "sliced", "thrashed", "whacked") + custom_materials = list(/datum/material/iron = 100, /datum/material/diamond = 200, /datum/material/titanium = 100) + pressure_resistance = 2 * ONE_ATMOSPHERE + grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1) + tool_behaviour = TOOL_MINING //For the classic "digging out of prison with a spoon but you're in space so this analogy doesn't work" situation. + toolspeed = 2 //You will never willingly choose to use one of these over a shovel. + hitsound = 'sound/weapons/blade1.ogg' + +/obj/item/pen/fountain/survival/Initialize() + . = ..() + AddComponent(/datum/component/butchering, 60, 100, 0, 'sound/weapons/blade1.ogg') //it's a strange hardlight tech \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/blackmarketstuff.dm b/modular_dripstation/code/game/objects/items/blackmarketstuff.dm new file mode 100644 index 000000000000..4d8f1de8d7bb --- /dev/null +++ b/modular_dripstation/code/game/objects/items/blackmarketstuff.dm @@ -0,0 +1,17 @@ +/obj/item/reagent_containers/glass/beaker/thermite + name = "thermite beaker" + desc = "Beaker with thermite. Danger, flammable." + list_reagents = list(/datum/reagent/thermite = 30) + +/obj/item/clothing/shoes/bhop/rocket + name = "rocket boots" + desc = "Very special boots with built-in rocket thrusters! SHAZBOT!" + icon_state = "rocketboots" + icon = 'modular_dripstation/icons/obj/clothing/shoes.dmi' + actions_types = list(/datum/action/cooldown/boost/brocket) + jumpdistance = 20 //great for throwing yourself into walls and people at high speeds + jumpspeed = 5 + +/datum/action/cooldown/boost/brocket + name = "Activate Rocket Boots" + desc = "Activates the boot's rocket propulsion system, allowing the user to hurl themselves great distances." \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/cargo_boxcutter.dm b/modular_dripstation/code/game/objects/items/cargo_boxcutter.dm new file mode 100644 index 000000000000..5b76290d89cc --- /dev/null +++ b/modular_dripstation/code/game/objects/items/cargo_boxcutter.dm @@ -0,0 +1,46 @@ +/obj/item/boxcutter + name = "boxcutter" + desc = "A tool for cutting boxes, or throats." + icon = 'modular_dripstation/icons/obj/cargo/boxcutter.dmi' + icon_state = "boxcutter" + item_state = "boxcutter" + lefthand_file = 'modular_dripstation/icons/mob/inhands/equipment/boxcutter_lefthand.dmi' + righthand_file = 'modular_dripstation/icons/mob/inhands/equipment/boxcutter_righthand.dmi' + attack_verb = list("proded", "poked") + w_class = WEIGHT_CLASS_SMALL + slot_flags = ITEM_SLOT_BELT + resistance_flags = FIRE_PROOF + force = 0 + bare_wound_bonus = 20 + /// Used on Initialize, how much time to cut cable restraints and zipties. + //var/snap_time_weak_handcuffs = 0 SECONDS + /// Used on Initialize, how much time to cut real handcuffs. Null means it can't. + //var/snap_time_strong_handcuffs = null + +/obj/item/boxcutter/Initialize(mapload) + . = ..() + AddComponent(/datum/component/butchering, 70, 100) + + AddComponent( \ + /datum/component/transforming, \ + force_on = 10, \ + throwforce_on = 4, \ + throw_speed_on = throw_speed, \ + sharpness_on = SHARP_EDGED, \ + hitsound_on = 'sound/weapons/bladeslice.ogg', \ + w_class_on = WEIGHT_CLASS_NORMAL, \ + attack_verb_on = list("cuted", "stabed", "slashed"), \ + ) + + RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) + +/obj/item/boxcutter/proc/on_transform(obj/item/source, mob/user, active) + SIGNAL_HANDLER + + playsound(src, 'modular_dripstation/sound/item/boxcutter_activate.ogg', 50) + //tool_behaviour = (active ? TOOL_KNIFE : NONE) + //if(active) + // AddElement(/datum/element/cuffsnapping, snap_time_weak_handcuffs, snap_time_strong_handcuffs) + //else + // RemoveElement(/datum/element/cuffsnapping, snap_time_weak_handcuffs, snap_time_strong_handcuffs) + //return COMPONENT_NO_DEFAULT_MESSAGE diff --git a/modular_dripstation/code/game/objects/items/cargo_inducer.dm b/modular_dripstation/code/game/objects/items/cargo_inducer.dm new file mode 100644 index 000000000000..b9b0eb579fbe --- /dev/null +++ b/modular_dripstation/code/game/objects/items/cargo_inducer.dm @@ -0,0 +1,12 @@ +/obj/item/inducer/cargo + name = "inducer" + icon_state = "inducer-cargo" + icon = 'modular_dripstation/icons/obj/cargo/cargo_inducer.dmi' + desc = "A tool for inductively charging internal power cells. This one has a cargo color scheme, and is less potent than its engineering counterpart." + cell_type = /obj/item/stock_parts/cell/high/empty + powertransfer = 500 + opened = TRUE + +/obj/item/inducer/cargo/Initialize() + . = ..() + update_icon() \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm new file mode 100644 index 000000000000..ade17c609529 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm @@ -0,0 +1,315 @@ +GLOBAL_LIST_EMPTY(cargo_marks) + +/obj/item/cargo_teleporter + name = "QM personal teleporter" + desc = "Specialised personal teleporter based on modern bluespace technology. This one issued to QM for moving crates, closets and none-living objects to previously marked locations." + icon = 'modular_dripstation/icons/obj/cargo/cargo_teleporter.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/belt.dmi' + lefthand_file = 'modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_lefthand.dmi' + righthand_file = 'modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_righthand.dmi' + icon_state = "cargo_tele" + item_state = "cargo_tele" + materials = list(MAT_METAL=10000) + slot_flags = ITEM_SLOT_BELT + cryo_preserve = TRUE + flags_1 = CONDUCT_1 + force = 10 + throwforce = 10 + throw_speed = 3 + throw_range = 5 + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + var/list/marker_children = list() //the list of markers spawned by this item + var/choice //storing marker of choice + var/cooldown_in_seconds = 16 SECONDS //cooldown, made for upgrades + var/emagged = FALSE //emagged? + var/emped = FALSE //emped? + verb_say = "beeps" + verb_exclaim = "blares" + var/obj/item/stock_parts/manipulator/manipulator = null + var/obj/item/stock_parts/cell/high/ctcell = null // Power cell (10000W) + var/chargecost = 1000 // How much energy tele use + var/static/list/high_risk_teleporting = typecacheof(list( + /obj/item/disk/nuclear, + /obj/item/gun/energy/laser/captain, + /obj/item/hand_tele, + /obj/item/clothing/accessory/medal/gold/captain, + /obj/item/melee/sabre, + /obj/item/clothing/gloves/krav_maga/sec, + /obj/item/gun/energy/e_gun/hos, + /obj/item/card/id/captains_spare, + /obj/item/tank/jetpack/oxygen/captain, + /obj/item/aicard, + /obj/item/hypospray/deluxe/cmo, + /obj/item/clothing/suit/armor/reactive/teleport, + /obj/item/clothing/suit/armor/laserproof, + /obj/item/blackbox, + /obj/item/holotool, + /obj/item/areaeditor/blueprints) + ) + var/static/list/blacklisted_turfs = typecacheof(list( + /turf/closed, + /turf/open/chasm, + /turf/open/lava)) + var/static/list/deathtrap_list = typecacheof(list( + /obj/machinery/power/supermatter_crystal, + /obj/machinery/conveyor, + /obj/machinery/recycler)) + + COOLDOWN_DECLARE(use_cooldown) + +/obj/item/cargo_teleporter/get_cell() + return ctcell + +/obj/item/cargo_teleporter/Initialize() + . = ..() + manipulator = new /obj/item/stock_parts/manipulator(src) + ctcell = new(src) + +/obj/item/cargo_teleporter/emp_act(severity) + emped = TRUE + SStgui.close_uis(src) //Close the UI control if it is open. I guess do not work, will work with ui refactor, if it will be made some day + switch(severity) + if(1) + ctcell.use(chargecost) + if(emagged) + emagged = FALSE + if(2) + ctcell.charge = 0 + if(emagged) + emagged = FALSE + if(prob(50)) + var/mob/living/carbon/human/user = src.loc + say("E:FATAL:PWR_BUS_OVERLOAD") + if(user.is_holding(src)) + if(user.dna && user.dna.species.id == "human") + say("E:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT") + to_chat(user, span_danger("An electromagnetic pulse disrupts your hacked teleporter and violently turns you into abomination.")) + to_chat(user, span_userdanger("You SEE THE LIGHT.")) + user.set_species(/datum/species/moth) + +/obj/item/cargo_teleporter/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + if(emagged) + . += "Warning: Safety protocols disabled." + if(!manipulator) + . += "The manipulator is missing." + else + . += "A tier [manipulator.rating] manipulator is installed. It is screwed in place." + . += "There are [round(ctcell.charge/chargecost)] charge\s left." + . += span_notice("Attack itself to set down the markers!") + . += span_notice("ALT-CLICK to change destination marker!") + +/obj/item/cargo_teleporter/Destroy() + if(length(marker_children)) + for(var/obj/effect/decal/cleanable/cargo_mark/destroy_children in marker_children) + destroy_children.parent_item = null + qdel(destroy_children) + QDEL_NULL(manipulator) + QDEL_NULL(ctcell) + return ..() + +/obj/item/cargo_teleporter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/stock_parts/manipulator)) + if(!manipulator) + if(!user.transferItemToLoc(W, src)) + return + manipulator = W + playsound(src, 'sound/machines/click.ogg', 25) + to_chat(user, span_notice("You install a [manipulator.name] in [src].")) + else + to_chat(user, span_notice("[src] already has a manipulator installed.")) + +/obj/item/cargo_teleporter/screwdriver_act(mob/living/user, obj/item/I) + if(manipulator) + I.play_tool_sound(src) + to_chat(user, span_notice("You remove the [manipulator.name] from \the [src].")) + manipulator.forceMove(drop_location()) + manipulator = null + +/obj/item/cargo_teleporter/emag_act(user) + if(!emagged) + emagged = TRUE + do_sparks(3, TRUE, src) + say("SAFETY PROTOCOLS OVERRIDE DETECTED!") + return + +/obj/item/cargo_teleporter/attack_self(mob/user, modifiers) + if(isnull(manipulator)) + say("\The [src] is missing it's manipulator, and cannot function.") + return + var/turf/current_location = get_turf(user)//What turf is the user on? + var/area/current_area = current_location.loc + if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf + say("\The [src] is malfunctioning.") + return + if(!is_station_level(current_location.z)) + var/lava_emag + if(emagged & is_mining_level(current_location.z)) + lava_emag = TRUE + if(!lava_emag) + say("Error 503. Marker location undefined. Bluespace signal is not tracing. Try again onboard.") + return + if(isspaceturf(current_location)) + say("You cannot place markers in space.") + return + if(is_type_in_typecache(current_location, blacklisted_turfs)) + say("You cannot place markers here.") + return + if(length(marker_children) >= manipulator.rating) + say("You may only have [manipulator.rating] spawned markers from [src].") + return + if(locate(/obj/effect/decal/cleanable/cargo_mark) in current_location) + say("There is already a marker here.") + return + var/obj/effect/decal/cleanable/cargo_mark/spawned_marker = new /obj/effect/decal/cleanable/cargo_mark(get_turf(src)) + to_chat(user, span_notice("You place a cargo marker below your feet.")) + playsound(src, 'sound/machines/click.ogg', 50) + spawned_marker.parent_item = src + marker_children += spawned_marker + +/obj/item/cargo_teleporter/AltClick(mob/user) + if(!user.is_holding(src)) + to_chat(user, span_notice("You should be able to press the change destination button to to interact with interface.")) + return + if(emped) + to_chat(user, "Teleporter restarts by itself!") + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, 3) + emped = FALSE + choice = null + return + makingchoice(user) + +/obj/item/cargo_teleporter/proc/makingchoice(mob/user) + choice = tgui_input_list(user, "Select which cargo mark to teleport the items to?", "Cargo Mark Selection", GLOB.cargo_marks) + if(!choice) + return ..() + + +/obj/item/cargo_teleporter/verb/remove_all_markers() + set name = "Cargo Tele: Remove All Markers" + set category = "Object" + + if(!usr.is_holding(src)) + return + if(length(marker_children)) + for(var/obj/effect/decal/cleanable/cargo_mark/destroy_children in marker_children) + qdel(destroy_children) + marker_children = list() + choice = null + playsound(src, 'sound/machines/click.ogg', 50) + to_chat(usr, span_notice("You destroyed all markers.")) + +/obj/item/cargo_teleporter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(!user.is_holding(src)) + to_chat(user, span_notice("You should be able to press the teleportation button to be able teleport something.")) + return ..() + if(isnull(manipulator)) + say("\The [src] is missing it's manipulator, and cannot function.") + return ..() + if(ctcell.charge < chargecost) + say("Unable to teleport, insufficient charge.") + return ..() + if(!emagged && !proximity_flag) + return ..() + if(emagged && (get_dist(user, target) > manipulator.rating)) + return ..() + if(target == src) + return ..() + if(!COOLDOWN_FINISHED(src, use_cooldown)) + say("\The [src] is still on cooldown.") + return + if(!choice) + return makingchoice(user) + var/turf/moving_turf = get_turf(choice) + var/turf/target_turf = get_turf(target) + var/area/current_area = target_turf.loc + if(current_area.noteleport)//If z level disables teleportation + say("\The [src] is malfunctioning.") + return + var/destination_incorrect = FALSE //prevent spamming on one turf and primitive deathraps + for(var/deathtrap_check in moving_turf.contents) //deathrap checking + if(emagged & is_type_in_typecache(deathtrap_check, deathtrap_list)) //preventing oneclick deathraps, say no to oneturf recycler bins + destination_incorrect = TRUE + continue + if(moving_turf == target_turf) //die spamm + destination_incorrect = TRUE + continue + if(destination_incorrect) //prevent oneturf sound spamming and primitive deathraps + say("Teleportation error detected. Destination incorrect.") + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + return ..() + var/dust = FALSE + for(var/check_content in target_turf.contents) + if(isobserver(check_content)) + continue + if(!ismovable(check_content)) + continue + if(is_type_in_typecache(check_content, high_risk_teleporting)) + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + continue + var/atom/movable/movable_content = check_content + if(isliving(movable_content) && !emagged) + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + continue + if(HAS_TRAIT(movable_content, TRAIT_NO_TELEPORT)) + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + continue + if(length(movable_content.get_all_contents_type(/mob/living)) && !emagged) + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + continue + if(length(typecache_filter_list(movable_content.get_all_contents_type(/obj/item), high_risk_teleporting))) + playsound(src, 'sound/machines/terminal_alert.ogg', 50) + continue + if(movable_content.anchored) + continue + if(length(movable_content.get_all_contents_type(/obj/item/cargo_teleporter))) + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, 1) + say("Teleportation error detected. Do not try teleport teleporter.") + continue + dust = TRUE + do_teleport(movable_content, moving_turf, asoundout = 'sound/magic/Disable_Tech.ogg') + if(dust) + new /obj/effect/decal/cleanable/ash(target_turf) + ctcell.use(chargecost) + say("Teleportation successful. [round(ctcell.charge/chargecost)] charge\s left.") + cooldown_in_seconds -= (manipulator.rating * 2) + COOLDOWN_START(src, use_cooldown, cooldown_in_seconds) + +/obj/effect/decal/cleanable/cargo_mark + name = "cargo mark" + desc = "A mark left behind by a cargo teleporter, which allows targeted teleportation. Can be removed by the cargo teleporter." + icon = 'modular_dripstation/icons/obj/cargo/cargo_teleporter.dmi' + icon_state = "marker" + ///the reference to the item that spawned the cargo mark + var/obj/item/cargo_teleporter/parent_item + + light_range = 3 + light_color = COLOR_VIVID_YELLOW + +/obj/effect/decal/cleanable/cargo_mark/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/cargo_teleporter)) + to_chat(user, span_notice("You remove [src] using [W].")) + playsound(src, 'sound/machines/click.ogg', 50) + if(parent_item.choice) + if(get_turf(parent_item.choice) == get_turf(src)) + parent_item.choice = null + qdel(src) + return + return ..() + +/obj/effect/decal/cleanable/cargo_mark/Destroy() + if(parent_item) + parent_item.marker_children -= src + if(parent_item.choice) + if(get_turf(parent_item.choice) == get_turf(src)) + parent_item.choice = null + GLOB.cargo_marks -= src + return ..() + +/obj/effect/decal/cleanable/cargo_mark/Initialize(mapload, list/datum/disease/diseases) + . = ..() + var/area/src_area = get_area(src) + name = "[src_area.name] ([rand(100000,999999)])" + GLOB.cargo_marks += src diff --git a/modular_dripstation/code/game/objects/items/clothing/gloves.dm b/modular_dripstation/code/game/objects/items/clothing/gloves.dm new file mode 100644 index 000000000000..340b34e28d56 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/clothing/gloves.dm @@ -0,0 +1,67 @@ +/obj/item/clothing/gloves/cargo_gauntlet + name = "\improper cargo gauntlets" + desc = "These rubberized gauntlets have high adhesion to the metal surface that allows you to drag crates and lockers with more confidence on them not getting nabbed from you." + icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' + siemens_coefficient = 0.6 // Some shock protected material anyway + icon_state = "cargogloves" + item_state = "cargogloves" + cold_protection = HANDS + heat_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + undyeable = TRUE + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) + var/datum/weakref/pull_component_weakref + +/obj/item/clothing/gloves/cargo_gauntlet/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_ITEM_EQUIPPED, PROC_REF(on_glove_equip)) + RegisterSignal(src, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_glove_unequip)) + +/// Called when the glove is equipped. Adds a component to the equipper and stores a weak reference to it. +/obj/item/clothing/gloves/cargo_gauntlet/proc/on_glove_equip(datum/source, mob/equipper, slot) + SIGNAL_HANDLER + + if(!(slot & ITEM_SLOT_GLOVES)) + return + + var/datum/component/strong_pull/pull_component = pull_component_weakref?.resolve() + if(pull_component) + stack_trace("Gloves already have a pull component associated with \[[pull_component.parent]\] when \[[equipper]\] is trying to equip them.") + QDEL_NULL(pull_component_weakref) + + to_chat(equipper, span_notice("You feel the gauntlets activate as soon as you fit them on, making your pulls stronger!")) + + pull_component_weakref = WEAKREF(equipper.AddComponent(/datum/component/strong_pull)) + +/* + * Called when the glove is unequipped. Deletes the component if one exists. + * + * No component being associated on equip is a valid state, as holding the gloves in your hands also counts + * as having them equipped, or even in pockets. They only give the component when they're worn on the hands. + */ +/obj/item/clothing/gloves/cargo_gauntlet/proc/on_glove_unequip(datum/source, force, atom/newloc, no_move, invdrop, silent) + SIGNAL_HANDLER + + var/datum/component/strong_pull/pull_component = pull_component_weakref?.resolve() + + if(!pull_component) + return + + to_chat(pull_component.parent, span_warning("You have lost the grip power of [src]!")) + + QDEL_NULL(pull_component_weakref) + + +/obj/item/clothing/gloves/krav_maga/sec + name = "krav maga gloves" + desc = "These gloves can teach you to perform Krav Maga using nanochips." + icon_state = "fightgloves" + item_state = "fightgloves" + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + cryo_preserve = TRUE \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/devices/PDA/PDA_types.dm b/modular_dripstation/code/game/objects/items/devices/PDA/PDA_types.dm new file mode 100644 index 000000000000..24a06170d713 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/devices/PDA/PDA_types.dm @@ -0,0 +1,2 @@ +/obj/item/pda/quartermaster + insert_type = /obj/item/pen/fountain/survival \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/projectiles/guns/ballistic/rifle.dm b/modular_dripstation/code/game/objects/items/projectiles/guns/ballistic/rifle.dm new file mode 100644 index 000000000000..2425712e6b78 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/projectiles/guns/ballistic/rifle.dm @@ -0,0 +1,30 @@ +/obj/item/gun/ballistic/rifle/boltaction/brand_new + desc = "A brand new Mosin Nagant issued by Nanotrasen for their interns. You would rather not to damage it." + icon_state = "mosinprime" + item_state = "mosinprime" + sawn_desc = "A sawn-off Brand New Nagant... Doing this was a sin, I hope you're happy. \ + You are now probably one of the few people in the universe to ever hold a \"Brand New Obrez\". \ + Even thinking about that name combination makes you ill." + icon = 'modular_dripstation/icons/obj/weapons/48x32.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/guns_on_back.dmi' + lefthand_file = 'modular_dripstation/icons/mob/inhands/guns_lefthand.dmi' + righthand_file = 'modular_dripstation/icons/mob/inhands/guns_righthand.dmi' + +/obj/item/gun/ballistic/rifle/boltaction/brand_new/sawoff(mob/user) + . = ..() + if(.) + name = "\improper Brand New Obrez" // wear it loud and proud + +/obj/item/gun/ballistic/rifle/boltaction/qmrifle + name = "\improper 'Forbidden' precision rifle" + desc = "Modernized boltaction rifle, the frame feels robust as cargotech liver. \ + This thing was probably built with a conversion kit from a shady NTnet site. \ +

\ + BRAND NEW: Cannot be sawn off." + icon = 'modular_dripstation/icons/obj/weapons/48x32.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/guns_on_back.dmi' + lefthand_file = 'modular_dripstation/icons/mob/inhands/guns_lefthand.dmi' + righthand_file = 'modular_dripstation/icons/mob/inhands/guns_righthand.dmi' + icon_state = "mosintactical" + item_state = "mosintactical" + can_be_sawn_off = FALSE \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/tanks/watertank.dm b/modular_dripstation/code/game/objects/items/tanks/watertank.dm new file mode 100644 index 000000000000..394f296971e7 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/tanks/watertank.dm @@ -0,0 +1,6 @@ +/obj/item/reagent_containers/spray/mister/janitor + possible_transfer_amounts = list(5, 10) + +/obj/item/reagent_containers/spray/mister/janitor/attack_self(var/mob/user) + amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10) + to_chat(user, span_notice("You [amount_per_transfer_from_this == 10 ? "remove" : "affix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.")) \ No newline at end of file diff --git a/modular_dripstation/code/game/turfs/simulated/walls.dm b/modular_dripstation/code/game/turfs/simulated/walls.dm new file mode 100644 index 000000000000..50ce45791c7f --- /dev/null +++ b/modular_dripstation/code/game/turfs/simulated/walls.dm @@ -0,0 +1,2 @@ +/turf/closed/wall/metal_foam_base + girder_type = /obj/structure/foamedmetal \ No newline at end of file diff --git a/modular_dripstation/code/modules/antagonists/changeling/panacea.dm b/modular_dripstation/code/modules/antagonists/changeling/panacea.dm new file mode 100644 index 000000000000..4506cafa82f4 --- /dev/null +++ b/modular_dripstation/code/modules/antagonists/changeling/panacea.dm @@ -0,0 +1,39 @@ +/datum/action/changeling/panacea/sting_action(mob/user) + to_chat(user, span_notice("We cleanse impurities from our form.")) + var/mob/living/simple_animal/horror/H = user.has_horror_inside() + if(H) + H.leave_victim() + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.vomit(0) + to_chat(user, span_notice("A parasite exits our form.")) + ..() + var/list/bad_organs = list( + user.getorgan(/obj/item/organ/body_egg), + user.getorgan(/obj/item/organ/internal/shadowtumor), + user.getorgan(/obj/item/organ/zombie_infection)) + + for(var/o in bad_organs) + var/obj/item/organ/O = o + if(!istype(O)) + continue + + O.Remove(user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.vomit(0) + O.forceMove(get_turf(user)) + + user.reagents.add_reagent(/datum/reagent/medicine/mutadone, 10) + user.reagents.add_reagent(/datum/reagent/medicine/pen_acid, 20) + user.reagents.add_reagent(/datum/reagent/medicine/antihol, 10) + user.reagents.add_reagent(/datum/reagent/medicine/mannitol/advanced, 25) + + if(isliving(user)) + var/mob/living/L = user + for(var/thing in L.diseases) + var/datum/disease/D = thing + if(D.severity == DISEASE_SEVERITY_POSITIVE) + continue + D.cure() + return TRUE \ No newline at end of file diff --git a/modular_dripstation/code/modules/antagonists/horror/horror_chemicals.dm b/modular_dripstation/code/modules/antagonists/horror/horror_chemicals.dm new file mode 100644 index 000000000000..9de3b73ea26e --- /dev/null +++ b/modular_dripstation/code/modules/antagonists/horror/horror_chemicals.dm @@ -0,0 +1,4 @@ +/datum/horror_chem/mannitol + chemname = "mannitol" + R = /datum/reagent/medicine/mannitol/advanced + chem_desc = "Heals brain damage." \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/all_nodes.dm b/modular_dripstation/code/modules/bepis/all_nodes.dm new file mode 100644 index 000000000000..7fa470b206c1 --- /dev/null +++ b/modular_dripstation/code/modules/bepis/all_nodes.dm @@ -0,0 +1,51 @@ +////////////////////////B.E.P.I.S. Locked Techs//////////////////////// +/datum/techweb_node/light_apps + id = "light_apps" + display_name = "Illumination Applications" + description = "Applications of lighting and vision technology not originally thought to be commercially viable." + prereq_ids = list("base") + design_ids = list("bright_helmet", "rld_mini") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/spec_eng + id = "spec_eng" + display_name = "Specialized Engineering" + description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone." + prereq_ids = list("base") + design_ids = list("eng_gloves", "lava_rods") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/aus_security + id = "aus_security" + display_name = "Australicus Security Protocols" + description = "It is said that security in the Australicus sector is tight, so we took some pointers from their equipment. Thankfully, our sector lacks any signs of these, 'dropbears'." + prereq_ids = list("base") + design_ids = list("pin_explorer", "stun_boomerang") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/interrogation + id = "interrogation" + display_name = "Enhanced Interrogation Technology" + description = "By cross-referencing several declassified documents from past dictatorial regimes, we were able to develop an incredibly effective interrogation device. \ + Ethical concerns about loss of free will do not apply to criminals, according to galactic law." + prereq_ids = list("base") + design_ids = list("hypnochair") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) + hidden = TRUE + experimental = TRUE + +///datum/techweb_node/tackle_advanced +// id = "tackle_advanced" +// display_name = "Advanced Grapple Technology" +// description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \ +// will no longer be accepted in its academic journals." +// design_ids = list("tackle_dolphin", "tackle_rocket") +// research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) +// hidden = TRUE +// experimental = TRUE \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/bepis.dm b/modular_dripstation/code/modules/bepis/bepis.dm new file mode 100644 index 000000000000..796f2f02014b --- /dev/null +++ b/modular_dripstation/code/modules/bepis/bepis.dm @@ -0,0 +1,294 @@ +//This system is designed to act as an in-between for cargo and science, and the first major money sink in the game outside of just buying things from cargo (As of 10/9/19, anyway). + +//economics defined values, subject to change should anything be too high or low in practice. + +#define MACHINE_OPERATION 100000 +#define MACHINE_OVERLOAD 500000 +#define MAJOR_THRESHOLD (8*CARGO_CRATE_VALUE) +#define MINOR_THRESHOLD (4*CARGO_CRATE_VALUE) +#define STANDARD_DEVIATION (2*CARGO_CRATE_VALUE) +#define PART_CASH_OFFSET_AMOUNT (0.5*CARGO_CRATE_VALUE) + +/obj/machinery/rnd/bepis + name = "\improper B.E.P.I.S. Chamber" + desc = "A high fidelity testing device which unlocks the secrets of the known universe using the two most powerful substances available to man: excessive amounts of electricity and capital." + icon = 'modular_dripstation/icons/obj/bepis/bepis.dmi' + icon_state = "chamber" + base_icon_state = "chamber" + density = TRUE + layer = ABOVE_MOB_LAYER + circuit = /obj/item/circuitboard/machine/bepis + + ///How much cash the UI and machine are depositing at a time. + var/banking_amount = 100 + ///How much stored player cash exists within the machine. + var/banked_cash = 0 + ///Payer's bank account. + var/datum/bank_account/account + ///Name on the payer's bank account. + var/account_name + ///When the BEPIS fails to hand out any reward, the ERROR cause will be a randomly picked string displayed on the UI. + var/error_cause = null + + //Vars related to probability and chance of success for testing, using gaussian normal distribution. + ///How much cash you will need to obtain a Major Tech Disk reward. + var/major_threshold = MAJOR_THRESHOLD + ///How much cash you will need to obtain a minor invention reward. + var/minor_threshold = MINOR_THRESHOLD + ///The standard deviation of the BEPIS's gaussian normal distribution. + var/std = STANDARD_DEVIATION + + //Stock part variables + ///Multiplier that lowers how much the BEPIS' power costs are. Maximum of 1, upgraded to a minimum of 0.7. See RefreshParts. + var/power_saver = 1 + ///Variability on the money you actively spend on the BEPIS, with higher inaccuracy making the most change, good and bad to spent cash. + var/inaccuracy_percentage = 1.5 + ///How much "cash" is added to your inserted cash efforts for free. Based on manipulator stock part level. + var/positive_cash_offset = 0 + ///How much "cost" is removed from both the minor and major threshold costs. Based on laser stock part level. + var/negative_cash_offset = 0 + ///List of objects that constitute your minor rewards. All rewards are unique or rare outside of the BEPIS. + var/minor_rewards = list( + //To add a new minor reward, add it here. + /obj/item/stack/circuit_stack/full, + /obj/item/pen/fountain/survival, + /obj/item/circuitboard/machine/sleeper/party, + /obj/item/toy/sprayoncan, + ) + +/obj/machinery/rnd/bepis/attackby(obj/item/O, mob/user, params) + if(stat & (NOPOWER|BROKEN|MAINT)) + to_chat(user, span_notice("[src] can't accept money when it's not functioning.")) + return + if(istype(O, /obj/item/holochip) || istype(O, /obj/item/stack/spacecash)) + var/deposit_value = O.get_item_credit_value() + banked_cash += deposit_value + qdel(O) + say("Deposited [deposit_value] credits into storage.") + update_icon() + return + if(isidcard(O)) + var/obj/item/card/id/Card = O + if(Card.registered_account) + account = Card.registered_account + if(istype(Card, /obj/item/card/id/departmental_budget)) + var/obj/item/card/id/departmental_budget/DB = Card + account_name = DB.department_name + else + account_name = Card.registered_name + say("New account detected. Console Updated.") + else + say("No account detected on card. Aborting.") + return + return ..() + +/obj/machinery/rnd/bepis/screwdriver_act(mob/living/user, obj/item/tool) + return default_deconstruction_screwdriver(user, "chamber_open", "chamber", tool) + +/obj/machinery/rnd/bepis/RefreshParts() + . = ..() + var/C = 0 + var/M = 0 + var/L = 0 + var/S = 0 + for(var/obj/item/stock_parts/capacitor/capacitor in component_parts) + C += ((capacitor.rating - 1) * 0.1) + power_saver = 1 - C + for(var/obj/item/stock_parts/manipulator/manipulator in component_parts) + M += ((manipulator.rating - 1) * PART_CASH_OFFSET_AMOUNT) + positive_cash_offset = M + for(var/obj/item/stock_parts/micro_laser/Laser in component_parts) + L += ((Laser.rating - 1) * PART_CASH_OFFSET_AMOUNT) + negative_cash_offset = L + for(var/obj/item/stock_parts/scanning_module/scanning_module in component_parts) + S += ((scanning_module.rating - 1) * 0.25) + inaccuracy_percentage = (1.5 - S) + +/obj/machinery/rnd/bepis/update_icon() + if(panel_open == TRUE) + icon_state = "[base_icon_state]_open" + return ..() + if((use_power == ACTIVE_POWER_USE) && (banked_cash > 0) && !(stat & (NOPOWER|BROKEN|MAINT))) + icon_state = "[base_icon_state]_active_loaded" + return ..() + if (((use_power == IDLE_POWER_USE) && (banked_cash > 0)) || (banked_cash > 0) && (stat & (NOPOWER|BROKEN|MAINT))) + icon_state = "[base_icon_state]_loaded" + return ..() + if(use_power == ACTIVE_POWER_USE && !(stat & (NOPOWER|BROKEN|MAINT))) + icon_state = "[base_icon_state]_active" + return ..() + if(((use_power == IDLE_POWER_USE) && (banked_cash == 0)) || (stat & (NOPOWER|BROKEN|MAINT))) + icon_state = base_icon_state + return ..() + return ..() + +/obj/machinery/rnd/bepis/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Bepis_new", name) + ui.open() + RefreshParts() +// if(isliving(user)) +// var/mob/living/carbon/human/customer = user +// account = customer.get_bank_account() + +/obj/machinery/rnd/bepis/ui_data(mob/user) + var/list/data = list() + var/powered = FALSE + var/zvalue = ((banking_amount + banked_cash) - (major_threshold - positive_cash_offset - negative_cash_offset))/(std) + var/std_success = 0 + var/prob_success = 0 + //Admittedly this is messy, but not nearly as messy as the alternative, which is jury-rigging an entire Z-table into the code, or making an adaptive z-table. + var/z = abs(zvalue) + if(z > 0 && z <= 0.5) + std_success = 19.1 + else if(z > 0.5 && z <= 1.0) + std_success = 34.1 + else if(z > 1.0 && z <= 1.5) + std_success = 43.3 + else if(z > 1.5 && z <= 2.0) + std_success = 47.7 + else if(z > 2.0 && z <= 2.5) + std_success = 49.4 + else + std_success = 50 + if(zvalue > 0) + prob_success = 50 + std_success + else if(zvalue == 0) + prob_success = 50 + else + prob_success = 50 - std_success + + if(use_power == ACTIVE_POWER_USE) + powered = TRUE + data["account_owner"] = account_name + data["amount"] = banking_amount + data["stored_cash"] = account?.account_balance + data["mean_value"] = (major_threshold - positive_cash_offset - negative_cash_offset) + data["error_name"] = error_cause + data["power_saver"] = power_saver + data["accuracy_percentage"] = inaccuracy_percentage * 100 + data["positive_cash_offset"] = positive_cash_offset + data["negative_cash_offset"] = negative_cash_offset + data["manual_power"] = powered ? FALSE : TRUE + data["silicon_check"] = issilicon(user) + data["success_estimate"] = prob_success + return data + +/obj/machinery/rnd/bepis/ui_act(action,params) + . = ..() + if(.) + return + switch(action) + if("begin_experiment") + if(use_power == IDLE_POWER_USE) + return + depositcash() + if(banked_cash == 0) + say("Please select funds to deposit to begin testing.") + return + calcsuccess() + use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful. + use_power = IDLE_POWER_USE //Machine shuts off after use to prevent spam and look better visually. + update_icon() + if("amount") + var/input = text2num(params["amount"]) + if(input) + banking_amount = input + if("toggle_power") + if(use_power == ACTIVE_POWER_USE) + use_power = IDLE_POWER_USE + else + use_power = ACTIVE_POWER_USE + update_icon() + if("account_reset") + if(use_power == IDLE_POWER_USE) + return + account_name = "" + account = null + say("Account settings reset.") + . = TRUE + +/** + * Proc that handles the user's account to deposit credits for the BEPIS. + * Handles success and fail cases for transferring credits, then logs the transaction and uses small amounts of power. + **/ +/obj/machinery/rnd/bepis/proc/depositcash() + var/deposit_value = 0 + deposit_value = banking_amount + if(deposit_value == 0) + update_icon() + say("Attempting to deposit 0 credits. Aborting.") + return + deposit_value = clamp(round(deposit_value, 1), 1, 10000) + if(!account) + say("Cannot find user account. Please swipe a valid ID.") + return + if(!account.has_money(deposit_value)) + say("You do not possess enough credits.") + return + account.adjust_money(-deposit_value, "Vending: B.E.P.I.S. Chamber") //The money vanishes, not paid to any accounts. + SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) + log_message("[deposit_value] credits were inserted into [src] by [account.account_holder]", LOG_GAME) + banked_cash += deposit_value + use_power(1000 * power_saver) + return + +/** + * Proc used to determine the experiment math and results all in one. + * Uses banked_cash and stock part levels to determine minor, major, and real gauss values for the BEPIS to hold. + * If by the end real is larger than major, You get a tech disk. If all the disks are earned or you at least beat minor, you get a minor reward. + **/ + +/obj/machinery/rnd/bepis/proc/calcsuccess() + var/turf/dropturf = null + var/gauss_major = 0 + var/gauss_minor = 0 + var/gauss_real = 0 + + var/turf/open/floor/turfs = get_turf(src) + while(length(turfs)) + var/turf/T = pick_n_take(turfs) + if(T.is_blocked_turf()) + continue + else + dropturf = T + break + + if (!dropturf) + dropturf = drop_location() + gauss_major = (gaussian(major_threshold, std) - negative_cash_offset) //This is the randomized profit value that this experiment has to surpass to unlock a tech. + gauss_minor = (gaussian(minor_threshold, std) - negative_cash_offset) //And this is the threshold to instead get a minor prize. + gauss_real = (gaussian(banked_cash, std*inaccuracy_percentage) + positive_cash_offset) //this is the randomized profit value that your experiment expects to give. + say("Real: [gauss_real]. Minor: [gauss_minor]. Major: [gauss_major].") + flick("chamber_flash",src) + update_icon() + banked_cash = 0 + if((gauss_real >= gauss_major)) //Major Success. + if(SSresearch.techweb_nodes_experimental.len > 0) + say("Experiment concluded with major success. New technology node discovered on technology disc.") + new /obj/item/disk/design_disk/bepis/remove_tech(dropturf,1) + return + say("Expended all available experimental technology nodes. Resorting to minor rewards.") + if(gauss_real >= gauss_minor) //Minor Success. + var/reward = pick(minor_rewards) + new reward(dropturf) + say("Experiment concluded with partial success. Dispensing compiled research efforts.") + return + if(gauss_real <= -1) //Critical Failure + say("ERROR: CRITICAL MACHIME MALFUNCTI- ON. CURRENCY IS NOT CRASH. CANNOT COMPUTE COMMAND: 'make bucks'") //not a typo, for once. + new /mob/living/simple_animal/hostile/retaliate/frog(dropturf, 1) + use_power(MACHINE_OVERLOAD * power_saver) //To prevent gambling at low cost and also prevent spamming for infinite deer. + return + //Minor Failure + error_cause = pick("attempted to sell grey products to American dominated market.","attempted to sell gray products to British dominated market.","placed wild assumption that PDAs would go out of style.","simulated product #76 damaged brand reputation mortally.","simulated business model resembled 'pyramid scheme' by 98.7%.","product accidently granted override access to all station doors.") + say("Experiment concluded with zero product viability. Cause of error: [error_cause]") + return + + +#undef MACHINE_OPERATION +#undef MACHINE_OVERLOAD +#undef MAJOR_THRESHOLD +#undef MINOR_THRESHOLD +#undef STANDARD_DEVIATION +#undef PART_CASH_OFFSET_AMOUNT diff --git a/modular_dripstation/code/modules/bepis/bepis_board.dm b/modular_dripstation/code/modules/bepis/bepis_board.dm new file mode 100644 index 000000000000..0aa7b16b954f --- /dev/null +++ b/modular_dripstation/code/modules/bepis/bepis_board.dm @@ -0,0 +1,18 @@ +/datum/design/board/bepis + name = "B.E.P.I.S. Board" + desc = "The circuit board for a B.E.P.I.S." + id = "bepis" + build_path = /obj/item/circuitboard/machine/bepis + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_CARGO + +/obj/item/circuitboard/machine/bepis + name = "BEPIS Chamber" + icon_state = "supply" + build_path = /obj/machinery/rnd/bepis + req_components = list( + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/capacitor = 1, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/micro_laser = 1, + /obj/item/stock_parts/scanning_module = 1) \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/bepis_designs.dm b/modular_dripstation/code/modules/bepis/bepis_designs.dm new file mode 100644 index 000000000000..028eeb2d1a8f --- /dev/null +++ b/modular_dripstation/code/modules/bepis/bepis_designs.dm @@ -0,0 +1,66 @@ +/datum/design/bright_helmet + name = "Workplace-Ready Firefighter Helmet" + desc = "By applying state of the art lighting technology to a fire helmet with industry standard photo-chemical hardening methods, this hardhat will protect you from robust workplace hazards." + id = "bright_helmet" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 4000, /datum/material/glass = 1000, /datum/material/plastic = 3000, /datum/material/silver = 500) + build_path = /obj/item/clothing/head/hardhat/red/upgraded + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rld_mini + name = "Mini Rapid Light Device (MRLD)" + desc = "A tool that can deploy portable and standing lighting orbs and glowsticks." + id = "rld_mini" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 20000, /datum/material/glass = 10000, /datum/material/plastic = 8000, /datum/material/gold = 2000) + build_path = /obj/item/construction/rld/mini + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SERVICE + +/datum/design/eng_gloves + name = "Tinkers Gloves" + desc = "Overdesigned engineering gloves that have automated construction subroutines dialed in, allowing for faster construction while worn." + id = "eng_gloves" + build_type = PROTOLATHE + materials = list(/datum/material/iron= 2000, /datum/material/silver= 1500, /datum/material/gold = 1000) + build_path = /obj/item/clothing/gloves/tinkerer + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/lavarods + name = "Lava-Resistant Iron Rods" + id = "lava_rods" + build_type = PROTOLATHE + materials = list(/datum/material/iron= 1000, /datum/material/plasma= 500, /datum/material/titanium= 2000) + build_path = /obj/item/stack/rods/lava + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/pin_explorer + name = "Outback Firing Pin" + desc = "This firing pin only shoots while ya ain't on station, fair dinkum!" + id = "pin_explorer" + build_type = PROTOLATHE + materials = list(/datum/material/silver = 1000, /datum/material/gold = 1000, /datum/material/iron = 500) + build_path = /obj/item/firing_pin/explorer + category = list("Firing Pins") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/stun_boomerang + name = "OZtek Boomerang" + desc = "Uses reverse flow gravitodynamics to flip its personal gravity back to the thrower mid-flight. Also functions similar to a stun baton." + id = "stun_boomerang" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000) + build_path = /obj/item/melee/baton/boomerang + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/hypnochair + name = "Enhanced Interrogation Chamber Board" + desc = "Allows for the construction of circuit boards used to build an Enhanced Interrogation Chamber." + id = "hypnochair" + build_path = /obj/item/circuitboard/machine/hypnochair + category = list("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/bepis_layout.dm b/modular_dripstation/code/modules/bepis/bepis_layout.dm new file mode 100644 index 000000000000..5f49659f1a35 --- /dev/null +++ b/modular_dripstation/code/modules/bepis/bepis_layout.dm @@ -0,0 +1,27 @@ +/datum/techweb_node/light_apps + ui_x = 32 + ui_y = -576 + +/datum/techweb_node/spec_eng + ui_x = -32 + ui_y = -576 + +/datum/techweb_node/aus_security + ui_x = -96 + ui_y = -576 + +/datum/techweb_node/interrogation + ui_x = -160 + ui_y = -576 + +///datum/techweb_node/free_space1 +// ui_x = -252 +// ui_y = -576 + +///datum/techweb_node/free_space2 +// ui_x = -352 +// ui_y = -576 + +///datum/techweb_node/free_space3 +// ui_x = -448 +// ui_y = -576 \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/bounty.dm b/modular_dripstation/code/modules/bepis/bounty.dm new file mode 100644 index 000000000000..fec472a3659a --- /dev/null +++ b/modular_dripstation/code/modules/bepis/bounty.dm @@ -0,0 +1,5 @@ +/datum/bounty/item/science/bepis_disc + name = "Reformatted Tech Disk" + description = "It turns out the diskettes the BEPIS prints experimental nodes on are extremely space-efficient. Send us one of your spares when you're done with it." + reward = 10000 + wanted_types = list(/obj/item/disk/design_disk/bepis/remove_tech, /obj/item/disk/design_disk/bepis) \ No newline at end of file diff --git a/modular_dripstation/code/modules/bepis/designs.dm b/modular_dripstation/code/modules/bepis/designs.dm new file mode 100644 index 000000000000..13263134a24c --- /dev/null +++ b/modular_dripstation/code/modules/bepis/designs.dm @@ -0,0 +1,37 @@ +/obj/item/disk/design_disk/proc/on_upload(datum/techweb/stored_research) + return + +/obj/item/disk/design_disk/bepis + name = "Old experimental technology disk" + desc = "A disk containing some long-forgotten technology from a past age. You hope it still works after all these years. Upload the disk to an R&D Console to redeem the tech." + icon_state = "datadisk0" + max_blueprints = 0 + + ///The bepis node we have the design id's of + var/datum/techweb_node/bepis_node + +/obj/item/disk/design_disk/bepis/Initialize(mapload) + . = ..() + var/bepis_id = pick(SSresearch.techweb_nodes_experimental) + bepis_node = (SSresearch.techweb_node_by_id(bepis_id)) + + for(var/entry in bepis_node.design_ids) + var/datum/design/new_entry = SSresearch.techweb_design_by_id(entry) + blueprints += new_entry + +///Unhide and research our node so we show up in the R&D console. +/obj/item/disk/design_disk/bepis/on_upload(datum/techweb/stored_research) + stored_research.hidden_nodes -= bepis_node.id + stored_research.research_node(bepis_node, force = TRUE, auto_adjust_cost = FALSE) + +/** + * Subtype of Bepis tech disk + * Removes the tech disk that's held on it from the experimental node list, making them not show up in future disks. + */ +/obj/item/disk/design_disk/bepis/remove_tech + name = "Reformatted technology disk" + desc = "A disk containing a new, completed tech from the B.E.P.I.S. Upload the disk to an R&D Console to redeem the tech." + +/obj/item/disk/design_disk/bepis/remove_tech/Initialize(mapload) + . = ..() + SSresearch.techweb_nodes_experimental -= bepis_node.id \ No newline at end of file diff --git a/modular_dripstation/code/modules/cargo/bounties/progression.dm b/modular_dripstation/code/modules/cargo/bounties/progression.dm new file mode 100644 index 000000000000..085bd8b6f144 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/bounties/progression.dm @@ -0,0 +1,15 @@ +/datum/bounty/item/progression/mining_advanced/reward_string() + return "[reward] Credits and clearance to order high quality plasmacutters" + +/* +/datum/bounty/item/progression/drakeslayer + name = "Hardsuit Initiatives" + description = "Strange dragon-like fauna detected in the area. Provide us a few examples of scaly material from this creatures and we`ll pay in reward." + reward = 20000 + required_count = 10 + wanted_types = list(/obj/item/stack/sheet/animalhide/ashdrake, /obj/item/stack/sheet/animalhide/carpdragon) //let`s get down some lizards + unlocked_crates = list(/datum/supply_pack/clearance/heavymining) + +/datum/bounty/item/progression/drakeslayer/reward_string() + return "[reward] Credits and clearance to order high quality mining gear." +*/ \ No newline at end of file diff --git a/modular_dripstation/code/modules/cargo/bounties/syndicate.dm b/modular_dripstation/code/modules/cargo/bounties/syndicate.dm new file mode 100644 index 000000000000..0f07736f676f --- /dev/null +++ b/modular_dripstation/code/modules/cargo/bounties/syndicate.dm @@ -0,0 +1,24 @@ +/datum/bounty/item/syndicate/secbudget + name = "!&@#DEFENCE BUDGET CARD!#@*$" + description = "!&@#WE ARE INTERESTED IN CRYPTO CODES OF NANOTRASEN BUDGET CARDS. WE WANT SECS ONE. DO NOT FAIL US IN THIS TASK.#@*$" + wanted_types = list(/obj/item/card/id/departmental_budget/sec) + reward = 5 //you gotta take it from armory +/datum/bounty/item/syndicate/combatmagboots + name = "!&@#COMBAT MAGBOOTS!#@*$" + description = "!&@#WE'RE LOOKING FOR NANOTRASEN ADVANCED MAGNETIC TECHNOLOGY. PROVIDE US SOME EXAMPLES FROM STATIONBOARD SECURITY DEPARTMENT.#@*$" + wanted_types = list(/obj/item/clothing/shoes/magboots/security) + required_count = 3 + reward = 4 +/datum/bounty/item/syndicate/hoshardsuit + name = "!&@#HEAD OF SECURITY HARDSUIT!#@*$" + description = "!&@#SOME PARTS OF SECURITY PLATESHIELDING ARE EXPENSIVE ENOUGH TO BE SOLD TO SOME COLLECTORS. YOU KNOW WHAT TO DO.#@*$" + wanted_types = list(/obj/item/clothing/suit/space/hardsuit/security/hos) + reward = 6 //you gotta take down a HoS +/datum/bounty/item/syndicate/gygaxboards + name = "!&@#GYGAX EXOSUIT BOARDS!#@*$" + description = "!&@#AFTER A RECENT OPERATION, SEVERAL OF OUR DARK GYGAX UNITS HAVE BEEN LEFT INOPERABLE. SEND SOME REPLACEMENT BOARDS TO US FOR A REWARD#@*$" + wanted_types = list(/obj/item/circuitboard/mecha/gygax/peripherals,/obj/item/circuitboard/mecha/gygax/targeting,/obj/item/circuitboard/mecha/gygax/main) + reward = 3 + required_count = 10 +/datum/bounty/item/syndicate/phazon + reward = 14 //you need an anomaly core and robotics for this one broski, it's gotta be worth a lot \ No newline at end of file diff --git a/modular_dripstation/code/modules/cargo/export_scaner.dm b/modular_dripstation/code/modules/cargo/export_scaner.dm new file mode 100644 index 000000000000..0d792f291c4f --- /dev/null +++ b/modular_dripstation/code/modules/cargo/export_scaner.dm @@ -0,0 +1,2 @@ +/obj/item/export_scanner + slot_flags = ITEM_SLOT_BELT \ No newline at end of file diff --git a/modular_dripstation/code/modules/cargo/markets/_market.dm b/modular_dripstation/code/modules/cargo/markets/_market.dm new file mode 100644 index 000000000000..3c264289cd2b --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/_market.dm @@ -0,0 +1,61 @@ +/datum/market + /// Name for the market. + var/name = "huh?" + + /// Available shipping methods and prices, just leave the shipping method out that you don't want to have. + var/list/shipping + + // Automatic vars, do not touch these. + /// Items available from this market, populated by SSblackmarket on initialization. Automatically assigned, so don't manually adjust. + var/list/available_items = list() + /// Item categories available from this market, only items which are in these categories can be gotten from this market. Automatically assigned, so don't manually adjust. + var/list/categories = list() + +/// Adds item to the available items and add it's category if it is not in categories yet. +/datum/market/proc/add_item(datum/market_item/item) + if(!prob(initial(item.availability_prob))) + return FALSE + + if(ispath(item)) + item = new item() + + if(!(item.category in categories)) + categories += item.category + available_items[item.category] = list() + + available_items[item.category] += item + return TRUE + +/// Handles buying the item, this is mainly for future use and moving the code away from the uplink. +/datum/market/proc/purchase(item, category, method, obj/item/market_uplink/uplink, user) + if(!istype(uplink) || !(method in shipping)) + return FALSE + + for(var/datum/market_item/I in available_items[category]) + if(I.type != item) + continue + var/price = I.price + shipping[method] + + if(!uplink.current_user)///There is no ID card on the user, or the ID card has no account + to_chat(user, span_warning("The uplink sparks, as it can't identify an ID card with a bank account on you.")) + return FALSE + var/balance = uplink?.current_user.account_balance + + // I can't get the price of the item and shipping in a clean way to the UI, so I have to do this. + if(balance < price) + to_chat(user, span_warning("You don't have enough credits in [uplink] for [I] with [method] shipping.")) + return FALSE + + if(I.buy(uplink, user, method)) + uplink.current_user.adjust_money(-price, "Other: Third Party Transaction") + if(ismob(user)) + var/mob/m_user = user + m_user.playsound_local(get_turf(m_user), 'sound/machines/twobeep_high.ogg', 50, TRUE) + return TRUE + return FALSE + +/datum/market/blackmarket + name = "Black Market" + shipping = list(SHIPPING_METHOD_LTSRBT =50, + SHIPPING_METHOD_LAUNCH =10, + SHIPPING_METHOD_TELEPORT=75) diff --git a/modular_dripstation/code/modules/cargo/markets/market_item.dm b/modular_dripstation/code/modules/cargo/markets/market_item.dm new file mode 100644 index 000000000000..2113e1c846d5 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_item.dm @@ -0,0 +1,76 @@ +/datum/market_item + /// Name for the item entry used in the uplink. + var/name + /// Description for the item entry used in the uplink. + var/desc + /// The category this item belongs to, should be already declared in the market that this item is accessible in. + var/category + /// "/datum/market"s that this item should be in, used by SSblackmarket on init. + var/list/markets = list(/datum/market/blackmarket) + + /// Price for the item, if not set creates a price according to the *_min and *_max vars. + var/price + /// How many of this type of item is available, if not set creates a price according to the *_min and *_max vars. + var/stock + + /// Path to or the item itself what this entry is for, this should be set even if you override spawn_item to spawn your item. + var/item + + /// Minimum price for the item if generated randomly. + var/price_min = 0 + /// Maximum price for the item if generated randomly. + var/price_max = 0 + /// Minimum amount that there should be of this item in the market if generated randomly. This defaults to 1 as most items will have it as 1. + var/stock_min = 1 + /// Maximum amount that there should be of this item in the market if generated randomly. + var/stock_max = 0 + /// Probability for this item to be available. Used by SSblackmarket on init. + var/availability_prob = 0 + +/datum/market_item/New() + if(isnull(price)) + price = rand(price_min, price_max) + if(isnull(stock)) + stock = rand(stock_min, stock_max) + +/// Used for spawning the wanted item, override if you need to do something special with the item. +/datum/market_item/proc/spawn_item(loc) + return new item(loc) + +/// Buys the item and makes SSblackmarket handle it. +/datum/market_item/proc/buy(obj/item/market_uplink/uplink, mob/buyer, shipping_method) + // Sanity + if(!istype(uplink) || !istype(buyer)) + return FALSE + + // This shouldn't be able to happen unless there was some manipulation or admin fuckery. + if(!item || stock <= 0) + return FALSE + + // Alright, the item has been purchased. + var/datum/market_purchase/purchase = new(src, uplink, shipping_method) + + // SSblackmarket takes care of the shipping. + if(SSblackmarket.queue_item(purchase)) + stock-- + buyer.log_message("has succesfully purchased [name] using [shipping_method] for shipping.", LOG_GAME) + return TRUE + return FALSE + +// This exists because it is easier to keep track of all the vars this way. +/datum/market_purchase + /// The entry being purchased. + var/datum/market_item/entry + /// Instance of the item being sent. + var/item + /// The uplink where this purchase was done from. + var/obj/item/market_uplink/uplink + /// Shipping method used to buy this item. + var/method + +/datum/market_purchase/New(_entry, _uplink, _method) + entry = _entry + if(!ispath(entry.item)) + item = entry.item + uplink = _uplink + method = _method diff --git a/modular_dripstation/code/modules/cargo/markets/market_items/clothing.dm b/modular_dripstation/code/modules/cargo/markets/market_items/clothing.dm new file mode 100644 index 000000000000..42fd81856b51 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_items/clothing.dm @@ -0,0 +1,80 @@ +/datum/market_item/clothing + category = "Clothing" + +/datum/market_item/clothing/ninja_mask + name = "Space Ninja Mask" + desc = "Apart from being acid, lava, fireproof and being hard to take off someone it does nothing special on it's own." + item = /obj/item/clothing/mask/gas/space_ninja + + price_min = CARGO_CRATE_VALUE + price_max = CARGO_CRATE_VALUE * 2.5 + stock_max = 3 + availability_prob = 40 + +/datum/market_item/clothing/sunglasses + name = "Space Sunglasses" + desc = "Just cool sunglasses for all your needs." + item = /obj/item/clothing/glasses/sunglasses + + price_min = CARGO_CRATE_VALUE + price_max = CARGO_CRATE_VALUE * 2.5 + stock_max = 3 + availability_prob = 40 + +/datum/market_item/clothing/durathread_vest + name = "Durathread Vest" + desc = "Don't let them tell you this stuff is \"Like asbestos\" or \"Pulled from the market for safety concerns\". It could be the difference between a robusting and a retaliation." + item = /obj/item/clothing/suit/armor/vest/durathread + + price_min = CARGO_CRATE_VALUE + price_max = CARGO_CRATE_VALUE * 2 + stock_max = 4 + availability_prob = 50 + +/datum/market_item/clothing/durathread_helmet + name = "Durathread Helmet" + desc = "Customers ask why it's called a helmet when it's just made from armoured fabric and I always say the same thing: No refunds." + item = /obj/item/clothing/head/helmet/durathread + + price_min = CARGO_CRATE_VALUE * 0.5 + price_max = CARGO_CRATE_VALUE + stock_max = 4 + availability_prob = 50 + +/datum/market_item/clothing/full_spacesuit_set + name = "\improper Nanotrasen Branded Spacesuit Box" + desc = "A few boxes of \"Old Style\" space suits fell off the back of a space truck." + item = /obj/item/storage/box + + price_min = CARGO_CRATE_VALUE * 7.5 + price_max = CARGO_CRATE_VALUE * 20 + stock_max = 3 + availability_prob = 30 + +/datum/market_item/clothing/full_spacesuit_set/spawn_item(loc) + var/obj/item/storage/box/B = ..() + B.name = "Spacesuit Box" + B.desc = "It has an NT logo on it." + new /obj/item/clothing/suit/space(B) + new /obj/item/clothing/head/helmet/space(B) + return B + +/datum/market_item/clothing/chameleon_hat + name = "Chameleon Hat" + desc = "Pick any hat you want with this Handy device. Not Quality Tested." + item = /obj/item/clothing/head/chameleon/broken + + price_min = CARGO_CRATE_VALUE * 0.5 + price_max = CARGO_CRATE_VALUE + stock_max = 2 + availability_prob = 70 + +/datum/market_item/clothing/rocket_boots + name = "Rocket Boots" + desc = "We found a pair of jump boots and overclocked the hell out of them. No liability for grevious harm to or with a body." + item = /obj/item/clothing/shoes/bhop/rocket + + price_min = CARGO_CRATE_VALUE * 5 + price_max = CARGO_CRATE_VALUE * 15 + stock_max = 1 + availability_prob = 40 diff --git a/modular_dripstation/code/modules/cargo/markets/market_items/consumables.dm b/modular_dripstation/code/modules/cargo/markets/market_items/consumables.dm new file mode 100644 index 000000000000..e61c2bae1041 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_items/consumables.dm @@ -0,0 +1,53 @@ +/datum/market_item/consumable + category = "Consumables" + +/datum/market_item/consumable/donk_pocket_box + name = "Box of Donk Pockets" + desc = "A well packaged box containing the favourite snack of every spacefarer." + item = /obj/item/storage/box/donkpockets + + stock_min = 2 + stock_max = 5 + price_min = CARGO_CRATE_VALUE * 1.625 + price_max = CARGO_CRATE_VALUE * 2 + availability_prob = 80 + +/datum/market_item/consumable/suspicious_pills + name = "Bottle of Suspicious Pills" + desc = "A random cocktail of luxury drugs that are sure to put a smile on your face!" + item = /obj/item/storage/pill_bottle + + stock_min = 2 + stock_max = 3 + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 3.5 + availability_prob = 50 + +/datum/market_item/consumable/suspicious_pills/spawn_item(loc) + var/pillbottle = pick(list(/obj/item/storage/pill_bottle/zoom, + /obj/item/storage/pill_bottle/happy, + /obj/item/storage/pill_bottle/lsd, + /obj/item/storage/pill_bottle/aranesp, + /obj/item/storage/pill_bottle/stimulant)) + return new pillbottle(loc) + +/datum/market_item/consumable/floor_pill + name = "Strange Pill" + desc = "The Russian Roulette of the Maintenance Tunnels." + item = /obj/item/reagent_containers/pill/floorpill + + stock_min = 5 + stock_max = 35 + price_min = CARGO_CRATE_VALUE * 0.05 + price_max = CARGO_CRATE_VALUE * 0.3 + availability_prob = 50 + +/datum/market_item/consumable/pumpup + name = "Maintenance Pump-Up" + desc = "Resist any Baton stun with this handy device!" + item = /obj/item/reagent_containers/autoinjector/medipen/pumpup + + stock_max = 3 + price_min = CARGO_CRATE_VALUE * 0.25 + price_max = CARGO_CRATE_VALUE * 0.75 + availability_prob = 90 diff --git a/modular_dripstation/code/modules/cargo/markets/market_items/misc.dm b/modular_dripstation/code/modules/cargo/markets/market_items/misc.dm new file mode 100644 index 000000000000..70668d1c3b02 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_items/misc.dm @@ -0,0 +1,78 @@ +/datum/market_item/misc + category = "Miscellaneous" + +/datum/market_item/misc/Clear_PDA + name = "Clear PDA" + desc = "Show off your style with this limited edition clear PDA!." + item = /obj/item/modular_computer/tablet/pda/preset/basic + + price_min = CARGO_CRATE_VALUE * 1.25 + price_max = CARGO_CRATE_VALUE *3 + stock_max = 2 + availability_prob = 50 + +/datum/market_item/misc/jade_Lantern + name = "Jade Lantern" + desc = "Found in a box labeled 'Danger: Radioactive'. Probably safe." + item = /obj/item/flashlight/lantern/jade + + price_min = CARGO_CRATE_VALUE * 0.75 + price_max = CARGO_CRATE_VALUE * 2.5 + stock_max = 2 + availability_prob = 45 + +/datum/market_item/misc/cap_gun + name = "Cap Gun" + desc = "Prank your friends with this harmless gun! Harmlessness guranteed." + item = /obj/item/toy/gun + + price_min = CARGO_CRATE_VALUE * 0.25 + price_max = CARGO_CRATE_VALUE + stock_max = 6 + availability_prob = 80 + +/datum/market_item/misc/shoulder_holster + name = "Shoulder holster" + desc = "Yeehaw, hardboiled friends! This holster is the first step in your dream of becoming a detective and being allowed to shoot real guns!" + item = /obj/item/storage/belt/holster + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4 + stock_max = 8 + availability_prob = 70 + +/datum/market_item/misc/holywater + name = "Flask of holy water" + desc = "Father Lootius' own brand of ready-made holy water." + item = /obj/item/reagent_containers/food/drinks/bottle/holywater + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 3 + stock_max = 3 + availability_prob = 40 + +/datum/market_item/misc/holywater/spawn_item(loc) + if (prob(6.66)) + return new /obj/item/reagent_containers/glass/beaker/unholywater(loc) + return ..() + +/datum/market_item/misc/strange_seed + name = "Strange Seeds" + desc = "An Exotic Variety of seed that can contain anything from glow to acid." + item = /obj/item/seeds/random + + price_min = CARGO_CRATE_VALUE * 1.6 + price_max = CARGO_CRATE_VALUE * 1.8 + stock_min = 2 + stock_max = 5 + availability_prob = 50 + +/datum/market_item/misc/smugglers_satchel + name = "Smuggler's Satchel" + desc = "This easily hidden satchel can become a versatile tool to anybody with the desire to keep certain items out of sight and out of mind." + item = /obj/item/storage/backpack/satchel/flat/empty + + price_min = CARGO_CRATE_VALUE * 3.75 + price_max = CARGO_CRATE_VALUE * 5 + stock_max = 2 + availability_prob = 30 diff --git a/modular_dripstation/code/modules/cargo/markets/market_items/tools.dm b/modular_dripstation/code/modules/cargo/markets/market_items/tools.dm new file mode 100644 index 000000000000..27aa49dcc130 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_items/tools.dm @@ -0,0 +1,82 @@ +/datum/market_item/tool + category = "Tools" + +/datum/market_item/tool/caravan_wrench + name = "Experimental Wrench" + desc = "The extra fast and handy wrench you always wanted!" + item = /obj/item/wrench/caravan + stock = 1 + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4 + availability_prob = 20 + +/datum/market_item/tool/caravan_wirecutters + name = "Experimental Wirecutters" + desc = "The extra fast and handy wirecutters you always wanted!" + item = /obj/item/wirecutters/caravan + stock = 1 + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4 + availability_prob = 20 + +/datum/market_item/tool/caravan_screwdriver + name = "Experimental Screwdriver" + desc = "The extra fast and handy screwdriver you always wanted!" + item = /obj/item/screwdriver/caravan + stock = 1 + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4 + availability_prob = 20 + +/datum/market_item/tool/caravan_crowbar + name = "Experimental Crowbar" + desc = "The extra fast and handy crowbar you always wanted!" + item = /obj/item/crowbar/red/caravan + stock = 1 + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4 + availability_prob = 20 + +/datum/market_item/tool/binoculars + name = "Binoculars" + desc = "Increase your sight by 150% with this handy Tool!" + item = /obj/item/binoculars + stock = 1 + + price_min = CARGO_CRATE_VALUE * 2 + price_max = CARGO_CRATE_VALUE * 4.8 + availability_prob = 30 + +/datum/market_item/tool/riot_shield + name = "Riot Shield" + desc = "Protect yourself from an unexpected Riot at your local Police department!" + item = /obj/item/shield/riot + + price_min = CARGO_CRATE_VALUE * 2.25 + price_max = CARGO_CRATE_VALUE * 3.25 + stock_max = 2 + availability_prob = 50 + +/datum/market_item/tool/thermite_bottle + name = "Thermite Bottle" + desc = "30u of Thermite to assist in creating a quick access point or get away!" + item = /obj/item/reagent_containers/glass/beaker/thermite + + price_min = CARGO_CRATE_VALUE * 2.5 + price_max = CARGO_CRATE_VALUE * 7.5 + stock_max = 3 + availability_prob = 30 + +/datum/market_item/tool/science_goggles + name = "Science Goggles" + desc = "These glasses scan the contents of containers and projects their contents to the user in an easy to read format." + item = /obj/item/clothing/glasses/science + + price_min = CARGO_CRATE_VALUE * 0.75 + price_max = CARGO_CRATE_VALUE + stock_max = 3 + availability_prob = 50 diff --git a/modular_dripstation/code/modules/cargo/markets/market_items/weapons.dm b/modular_dripstation/code/modules/cargo/markets/market_items/weapons.dm new file mode 100644 index 000000000000..2cb48a45b5ee --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_items/weapons.dm @@ -0,0 +1,65 @@ +/datum/market_item/weapon + category = "Weapons" + +/datum/market_item/weapon/bear_trap + name = "Bear Trap" + desc = "Get the janitor back at his own game with this affordable prank kit." + item = /obj/item/restraints/legcuffs/beartrap + + price_min = CARGO_CRATE_VALUE * 1.5 + price_max = CARGO_CRATE_VALUE * 2.75 + stock_max = 3 + availability_prob = 50 + +/datum/market_item/weapon/shotgun_dart + name = "Shotgun Dart" + desc = "These handy darts can be filled up with any chemical and be shot with a shotgun! \ + Prank your friends by shooting them with laughter! \ + Not recommended for comercial use." + item = /obj/item/ammo_casing/shotgun/dart + + price_min = CARGO_CRATE_VALUE * 0.05 + price_max = CARGO_CRATE_VALUE * 0.25 + stock_min = 10 + stock_max = 60 + availability_prob = 40 + +/datum/market_item/weapon/bone_spear + name = "Bone Spear" + desc = "Authentic tribal spear, made from real bones! A steal at any price, especially if you're a caveman." + item = /obj/item/melee/spear/bonespear + + price_min = CARGO_CRATE_VALUE + price_max = CARGO_CRATE_VALUE * 1.5 + stock_max = 3 + availability_prob = 60 + +/datum/market_item/weapon/chainsaw + name = "Chainsaw" + desc = "A lumberjack's best friend, perfect for cutting trees or limbs efficiently." + item = /obj/item/melee/chainsaw + + price_min = CARGO_CRATE_VALUE * 1.75 + price_max = CARGO_CRATE_VALUE * 3 + stock_max = 1 + availability_prob = 35 + +/datum/market_item/weapon/switchblade + name = "Switchblade" + desc = "Tunnel Snakes rule!" + item = /obj/item/switchblade + + price_min = CARGO_CRATE_VALUE * 1.25 + price_max = CARGO_CRATE_VALUE * 1.75 + stock_max = 3 + availability_prob = 45 + +/datum/market_item/weapon/emp_grenade + name = "EMP Grenade" + desc = "Use this grenade for SHOCKING results!" + item = /obj/item/grenade/empgrenade + + price_min = CARGO_CRATE_VALUE * 0.5 + price_max = CARGO_CRATE_VALUE * 2 + stock_max = 2 + availability_prob = 50 diff --git a/modular_dripstation/code/modules/cargo/markets/market_telepad.dm b/modular_dripstation/code/modules/cargo/markets/market_telepad.dm new file mode 100644 index 000000000000..6b6dbab960c4 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_telepad.dm @@ -0,0 +1,120 @@ +/obj/item/circuitboard/machine/ltsrbt + name = "LTSRBT (Machine Board)" + icon_state = "bluespacearray" + icon = 'modular_dripstation/icons/obj/blackmarket/module.dmi' + build_path = /obj/machinery/ltsrbt + req_components = list( + /obj/item/stack/ore/bluespace_crystal = 2, + /obj/item/stock_parts/subspace/ansible = 1, + /obj/item/stock_parts/micro_laser = 1, + /obj/item/stock_parts/scanning_module = 2) + def_components = list(/obj/item/stack/ore/bluespace_crystal = /obj/item/stack/ore/bluespace_crystal/artificial) + +/obj/machinery/ltsrbt + name = "Long-To-Short-Range-Bluespace-Transceiver" + desc = "The LTSRBT is a compact teleportation machine for receiving and sending items outside the station and inside the station.\nUsing teleportation frequencies stolen from NT it is near undetectable.\nEssential for any illegal market operations on NT stations.\n" + icon = 'modular_dripstation/icons/obj/blackmarket/telecoms.dmi' + icon_state = "exonet_node" + circuit = /obj/item/circuitboard/machine/ltsrbt + density = TRUE + + use_power = IDLE_POWER_USE + idle_power_usage = 200 + active_power_usage = 250 + + /// Divider for power_usage_per_teleport. + var/power_efficiency = 1 + /// Power used per teleported which gets divided by power_efficiency. + var/power_usage_per_teleport = 10000 + /// The time it takes for the machine to recharge before being able to send or receive items. + var/recharge_time = 0 + /// Current recharge progress. + var/recharge_cooldown = 0 + /// Base recharge time in seconds which is used to get recharge_time. + var/base_recharge_time = 100 + /// Current /datum/market_purchase being received. + var/receiving + /// Current /datum/market_purchase being sent to the target uplink. + var/transmitting + /// Queue for purchases that the machine should receive and send. + var/list/datum/market_purchase/queue = list() + +/obj/machinery/ltsrbt/Initialize(mapload) + . = ..() + SSblackmarket.telepads += src + +/obj/machinery/ltsrbt/Destroy() + SSblackmarket.telepads -= src + // Bye bye orders. + if(SSblackmarket.telepads.len) + for(var/datum/market_purchase/P in queue) + SSblackmarket.queue_item(P) + . = ..() + +/obj/machinery/ltsrbt/RefreshParts() + . = ..() + recharge_time = base_recharge_time + // On tier 4 recharge_time should be 20 and by default it is 80 as scanning modules should be tier 1. + for(var/obj/item/stock_parts/scanning_module/scanning_module in component_parts) + recharge_time -= scanning_module.rating * 10 + recharge_cooldown = recharge_time + + power_efficiency = 0 + for(var/obj/item/stock_parts/micro_laser/laser in component_parts) + power_efficiency += laser.rating + // Shouldn't happen but you never know. + if(!power_efficiency) + power_efficiency = 1 + +/// Adds /datum/market_purchase to queue unless the machine is free, then it sets the purchase to be instantly received +/obj/machinery/ltsrbt/proc/add_to_queue(datum/market_purchase/purchase) + if(!recharge_cooldown && !receiving && !transmitting) + receiving = purchase + return + queue += purchase + +/obj/machinery/ltsrbt/process(seconds_per_tick) + if(stat & NOPOWER) + return + + if(recharge_cooldown > 0) + recharge_cooldown -= seconds_per_tick + return + + var/turf/T = get_turf(src) + if(receiving) + var/datum/market_purchase/P = receiving + + if(!P.item || ispath(P.item)) + P.item = P.entry.spawn_item(T) + else + var/atom/movable/M = P.item + M.forceMove(T) + + use_power(power_usage_per_teleport / power_efficiency) + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 1, get_turf(src)) + sparks.attach(P.item) + sparks.start() + + receiving = null + transmitting = P + + recharge_cooldown = recharge_time + return + else if(transmitting) + var/datum/market_purchase/P = transmitting + if(!P.item) + QDEL_NULL(transmitting) + if(!(P.item in T.contents)) + QDEL_NULL(transmitting) + return + do_teleport(P.item, get_turf(P.uplink)) + use_power(power_usage_per_teleport / power_efficiency) + QDEL_NULL(transmitting) + + recharge_cooldown = recharge_time + return + + if(queue.len) + receiving = pick_n_take(queue) diff --git a/modular_dripstation/code/modules/cargo/markets/market_uplink.dm b/modular_dripstation/code/modules/cargo/markets/market_uplink.dm new file mode 100644 index 000000000000..02a1ff7c877a --- /dev/null +++ b/modular_dripstation/code/modules/cargo/markets/market_uplink.dm @@ -0,0 +1,171 @@ +/obj/item/market_uplink + name = "\improper Market Uplink" + desc = "An market uplink. Usable with markets. You probably shouldn't have this!" + icon = 'modular_dripstation/icons/obj/blackmarket/blackmarket.dmi' + icon_state = "uplink" + + // UI variables. + /// What category is the current uplink viewing? + var/viewing_category + /// What market is currently being bought from by the uplink? + var/viewing_market + /// What item is the current uplink attempting to buy? + var/selected_item + /// Is the uplink in the process of buying the selected item? + var/buying + ///Reference to the currently logged in user's bank account. + var/datum/bank_account/current_user + /// List of typepaths for "/datum/market"s that this uplink can access. + var/list/accessible_markets = list(/datum/market/blackmarket) + +/obj/item/market_uplink/Initialize(mapload) + . = ..() + // We don't want to go through this at mapload because the SSblackmarket isn't initialized yet. + if(mapload) + return + + update_viewing_category() + +/// Simple internal proc for updating the viewing_category variable. +/obj/item/market_uplink/proc/update_viewing_category() + if(accessible_markets.len) + viewing_market = accessible_markets[1] + var/list/categories = SSblackmarket.markets[viewing_market].categories + if(categories?.len) + viewing_category = categories[1] + +/obj/item/market_uplink/ui_interact(mob/user, datum/tgui/ui) + if(!viewing_category) + update_viewing_category() + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BlackMarketUplink", name) + ui.open() + +/obj/item/market_uplink/ui_data(mob/user) + var/list/data = list() + var/datum/market/market = viewing_market ? SSblackmarket.markets[viewing_market] : null + var/obj/item/card/id/id_card + if(isliving(user)) + var/mob/living/livin = user + id_card = livin.get_idcard() + if(id_card?.registered_account) + current_user = id_card.registered_account + else + current_user = null + data["categories"] = market ? market.categories : null + data["delivery_methods"] = list() + if(market) + for(var/delivery in market.shipping) + data["delivery_methods"] += list(list("name" = delivery, "price" = market.shipping[delivery])) + data["money"] = "N/A cr" + if(current_user) + data["money"] = current_user.account_balance + data["buying"] = buying + data["items"] = list() + data["viewing_category"] = viewing_category + data["viewing_market"] = viewing_market + if(viewing_category && market) + if(market.available_items[viewing_category]) + for(var/datum/market_item/I in market.available_items[viewing_category]) + data["items"] += list(list( + "id" = I.type, + "name" = I.name, + "cost" = I.price, + "amount" = I.stock, + "desc" = I.desc || I.name + )) + return data + +/obj/item/market_uplink/ui_static_data(mob/user) + var/list/data = list() + data["delivery_method_description"] = SSblackmarket.shipping_method_descriptions + data["ltsrbt_built"] = SSblackmarket.telepads.len + data["markets"] = list() + for(var/M in accessible_markets) + var/datum/market/BM = SSblackmarket.markets[M] + data["markets"] += list(list( + "id" = M, + "name" = BM.name + )) + return data + +/obj/item/market_uplink/ui_act(action, params) + . = ..() + if(.) + return + switch(action) + if("set_category") + if(isnull(params["category"])) + return + if(isnull(viewing_market)) + return + if(!(params["category"] in SSblackmarket.markets[viewing_market].categories)) + return + viewing_category = params["category"] + . = TRUE + if("set_market") + if(isnull(params["market"])) + return + var/market = text2path(params["market"]) + if(!(market in accessible_markets)) + return + + viewing_market = market + + var/list/categories = SSblackmarket.markets[viewing_market].categories + if(categories?.len) + viewing_category = categories[1] + else + viewing_category = null + . = TRUE + if("select") + if(isnull(params["item"])) + return + var/item = text2path(params["item"]) + selected_item = item + buying = TRUE + . = TRUE + if("cancel") + selected_item = null + buying = FALSE + . = TRUE + if("buy") + if(isnull(params["method"])) + return + if(isnull(selected_item)) + buying = FALSE + return + var/datum/market/market = SSblackmarket.markets[viewing_market] + market.purchase(selected_item, viewing_category, params["method"], src, usr) + + buying = FALSE + selected_item = null + +/obj/item/market_uplink/blackmarket + name = "\improper Black Market Uplink" + desc = "An illegal black market uplink. If command wanted you to have these, they wouldn't have made it so hard to get one." + icon = 'modular_dripstation/icons/obj/blackmarket/blackmarket.dmi' + icon_state = "uplink" + //The original black market uplink + accessible_markets = list(/datum/market/blackmarket) + + +/datum/crafting_recipe/blackmarket_uplink + name = "Black Market Uplink" + result = /obj/item/market_uplink/blackmarket + time = 15 SECONDS + tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER, TOOL_MULTITOOL) + reqs = list( + /obj/item/stock_parts/micro_laser = 1, + /obj/item/assembly/signaler = 1, + /obj/item/stack/cable_coil = 15, + /obj/item/radio = 1, + /obj/item/analyzer = 1) + category = CAT_EQUIPMENT + +/datum/crafting_recipe/blackmarket_uplink/New() + ..() + blacklist |= typesof(/obj/item/radio/headset) // because we got shit like /obj/item/radio/off ... WHY!?! + blacklist |= typesof(/obj/item/radio/intercom) diff --git a/modular_dripstation/code/modules/cargo/packs.dm b/modular_dripstation/code/modules/cargo/packs.dm new file mode 100644 index 000000000000..4921dddcc3b7 --- /dev/null +++ b/modular_dripstation/code/modules/cargo/packs.dm @@ -0,0 +1,105 @@ +/datum/supply_pack + var/order_limit = -1 // The number of times one can order a cargo crate, before it becomes restricted. -1 for infinite + var/times_ordered = 0 // Number of times a crate has been ordered in a shift + var/order_limit_in_one_order = -1 // The number of times one can order a cargo crate, before it becomes restricted. -1 for infinite + var/times_ordered_in_one_order = 0 // Number of times a crate has been ordered in one package + +//specialops edit +/datum/supply_pack/emergency/specialops + desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, A \"SLEEPY PEN\" FULL OF NICE TOXINS AND YOUR NEW GEAR!#@*$" + cost = 6000 + order_limit = 2 + contains = list(/obj/item/storage/box/emps, + /obj/item/grenade/smokebomb, + /obj/item/grenade/smokebomb, + /obj/item/grenade/smokebomb, + /obj/item/pen/blue/sleepy, + /obj/item/grenade/chem_grenade/incendiary, + /obj/item/clothing/glasses/night, + /obj/item/storage/belt/holster/syndicate, + /obj/item/clothing/mask/gas/syndicate, + /obj/item/clothing/under/syndicate/combat, + /obj/item/clothing/shoes/combat) + crate_name = "crate" + crate_type = /obj/structure/closet/crate + +//telepad for black market +/datum/supply_pack/costumes_toys/blackmarket_telepad + name = "Black Market LTSRBT" + desc = "Need a faster and better way of transporting your illegal goods from and to the \ + station? Fear not, the Long-To-Short-Range-Bluespace-Transceiver (LTSRBT for short) \ + is here to help. Contains a LTSRBT circuit, two bluespace crystals, and one ansible." + cost = 26000 + contraband = TRUE + contains = list(/obj/item/circuitboard/machine/ltsrbt, + /obj/item/stack/ore/bluespace_crystal/artificial = 2, + /obj/item/stock_parts/subspace/ansible) + crate_name = "crate" + +//nullcrate check +/datum/supply_pack/emergency/nullcrate + name = "NULL_ENTRY" + desc = "(#@&^$THIS IS YOUR LOVELY PACKAGE THAT CONTAINS SOME RANDOM SYNDICATE STUFF. GIVE EM HELL, OPERATIVE@&!*()" + hidden = TRUE + order_limit_in_one_order = 2 + order_limit = 10 + cost = 12000 + crate_name = "crate" + crate_type = /obj/structure/closet/crate + contains = list() + +/datum/supply_pack/emergency/nullcrate/fill(obj/structure/closet/crate/C) + switch (rand(0,3)) + if(0) + new /obj/item/gun/ballistic/automatic/pistol(C) + new /obj/item/ammo_box/magazine/m10mm(C) + new /obj/item/ammo_box/magazine/m10mm(C) + if(1) + new /obj/item/gun/ballistic/rifle/boltaction(C) + new /obj/item/ammo_box/a762(C) + if(2) + new /obj/item/gun/ballistic/automatic/toy/pistol/riot(C) + new /obj/item/ammo_box/magazine/toy/pistol/riot(C) + new /obj/item/ammo_box/foambox/riot(C) + if(3) + new /obj/item/pen/red/edagger(C) + new /obj/item/grenade/plastic/c4(C) + for(var/i in 1 to 2) + //Gear + var/item = pick(/obj/item/clothing/shoes/magboots/syndie, + /obj/item/clothing/gloves/fingerless/bigboss, + /obj/item/storage/backpack/duffelbag/syndie, + /obj/item/storage/belt/chameleon/syndicate, + /obj/item/clothing/under/chameleon, + /obj/item/clothing/suit/chameleon, + /obj/item/flashlight/emp, + /obj/item/syndicateReverseCard, + /obj/item/camera_bug, + /obj/item/storage/toolbox/syndicate) + new item(C) + //Misk + item = pick(/obj/item/storage/box/syndie_kit/cutouts, + /obj/item/disk/nuclear/fake, + /obj/item/toy/plush/carpplushie/dehy_carp, + /obj/item/storage/pill_bottle/gummies/omnizine, + /obj/item/storage/pill_bottle/gummies/sleepy, + /obj/item/storage/fancy/cigarettes/cigpack_syndicate, + /obj/item/stack/tape/guerrilla, + /obj/item/soap/syndie, + /obj/item/flashlight/lantern/syndicate, + /obj/item/storage/box/syndie_kit/bugs, + /obj/item/computer_hardware/hard_drive/portable/syndicate/ntnet_dos, + /obj/item/storage/box/syndie_kit/throwing_weapons, + /obj/item/multitool/ai_detect, + /obj/item/stamp/syndiround, + /obj/item/suppressor) + new item(C) + +/datum/supply_pack/security/armory/laser //dripstation mooving lethals to the armory + name = "Lasers Crate" + desc = "Contains three lethal, high-energy laser guns. Requires Armory access to open." + cost = 2000 + contains = list(/obj/item/gun/energy/laser, + /obj/item/gun/energy/laser, + /obj/item/gun/energy/laser) + crate_name = "laser crate" \ No newline at end of file diff --git a/modular_dripstation/code/modules/job/job_types/janitor.dm b/modular_dripstation/code/modules/job/job_types/janitor.dm new file mode 100644 index 000000000000..2898e9b82a3d --- /dev/null +++ b/modular_dripstation/code/modules/job/job_types/janitor.dm @@ -0,0 +1,2 @@ +/datum/job/janitor + base_access = list(ACCESS_JANITOR, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM, ACCESS_MAILSORTING, ACCESS_RESEARCH, ACCESS_MEDICAL, ACCESS_CONSTRUCTION) \ No newline at end of file diff --git a/modular_dripstation/code/modules/job/job_types/quartermaster.dm b/modular_dripstation/code/modules/job/job_types/quartermaster.dm new file mode 100644 index 000000000000..9b0a1dc7ebdb --- /dev/null +++ b/modular_dripstation/code/modules/job/job_types/quartermaster.dm @@ -0,0 +1,11 @@ +/datum/job/qm + mail_goodies = list( + /obj/item/stack/sheet/mineral/gold = 10, + /obj/item/circuitboard/machine/emitter = 5, + /obj/item/survivalcapsule/luxuryelite = 3, + /obj/item/construction/rcd = 3, + /obj/item/circuitboard/machine/vending/donksofttoyvendor = 2 + ) + +/datum/outfit/job/quartermaster + backpack_contents = list(/obj/item/melee/classic_baton/telescopic = 1) \ No newline at end of file diff --git a/modular_dripstation/icons/mob/clothing/belt.dmi b/modular_dripstation/icons/mob/clothing/belt.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d2edeffb87536d7a16b6af92269f848faf6c7d1c GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^4M3d0!VDzUL(;2&lyrbki0gp^2P7pWjSLNe0-2ea z{{BZ_u2;9S+pDJLQ?)ht0Z^2&B*-tA!Qt7BG$5y{DkP%BCAB!YD6^m>Ge3`kp<+&O zSV2+g_bOeKtIW}B76iKS~Eyn4>G zjf-JbN^^&h7C(A~S|CwdS!0;gZQSF5#b|12T cG1z}+x;C5rW*^V_VxTPyp00i_>zopr0AzW8p8x;= literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/clothing/guns_on_back.dmi b/modular_dripstation/icons/mob/clothing/guns_on_back.dmi new file mode 100644 index 0000000000000000000000000000000000000000..0e88c3e92c8bffcd6b9954d8c8a621003e4228e1 GIT binary patch literal 1869 zcmV-T2eSByP)V=-0C=2r%D)POFc1geIrkJlbT9qmdP|9v4Ehd1)8?R2$sO(MJGd1(e(<%p z_m42b4}m_Zs;mnb-RVs3E3;)VZdY9rmQNeW=*T^5EJ?w* z{8WpR$rRuJc8h-W@I#;-jsGfLJ&6P}000JvNkl8g)}Od>dQh(OCR%Mk{W8HUD`;V`W6ytUh;_)0x>2ng$A-n zOSTZJ0bL|4j!hKWnvacWKW-n)-Hhw5J0Ev;?wI?7MR%8(bMF7lx%bZ8a~F_EBoc{4 zA{LEX>u99?0Cn3BJ4D(K(8jHGw%bs<5tO}n_@!rEwhtS(*3s^-zhrOe*-ICFybU`| zr2PQxJQ!JebL1HP>DSwq+dyh}VP``aqj$#P5i4@1~EPR00~XA+y#X; z+{W;!uMqfWh=-fY$T|ijG|iXLG)&Jvpn*5u1hCW)JN>BBg#A7m+OiqZBggRmzP((8 z7m8poDD2hWsua_cy**SVB>m!f{_fT?+Nu=O?$$EOTZdK006ocM(kEgNT9snD z^4DPW?l|{zTgm`Np)=uRZx6i?C)lEhHNCW>gXIj!H12dJob2tPY^LL+9jjQ?!Bz%j z8s~AYY=|zt9k>Jla4ra565mQMz%2k)9axPUePR0F+)dZTUu_m7B()nsZ}f#NWkYvs z83mT^a080s`uzqY?Dq-diy;DvLR*z$3OpCpDC{_q@LT{GX2ldye89s20K^s544w{v zL?V$$Boc{4B9TZW63G(WpR?<0=;MD_KYvSeJq3X8uKz6jLQF106rX zXBXl;KkR8^&f z5Of_sgL@Mb0G_ui6X61&r}uCt5{U#p?RY1h&Z5)OTu=3W=YxA{hy6b4f0bhHkq@`# zsHO8aREKDJMJZ})DggkSs;U400|P@sj|uv&lU@1okx9%9%ArJy}|oc`L3f3_NuO^kiJcTsj9;MD$Nw}U_k zp(Q0Hc)Rj-%uJ;)ySRY)`FUs-3dk%^Lvx8xh$=F-_b2on|0pef^5Gl^At)&+v2-r( z_W`l7A`Fk$;6j}6KJ_x(3IZX74h#$}o8hFM%v(O6r9s&3E`U+!fjQdMLE|Hn0FV~{ zS+_&2bU%QF0Ei+!qfkMJc6CtwOh=DZ@d3dfMHt2D?r1gf?P6({ByT5p;8YNt6yFip zU9i>ibdiX5bx^N71YCyMa&+FbG}qH;SBE7ZR8^(yuSok7Od&!gaX?Y1UQ9E`HZ?W5 z?!PTW2mr&Zn4T9O0KWNHtkhi-qDmwZi9{liNF)-8L?V&c$Iv2!zS2wdg$XbD3K(1y zF0Uv>TiYJoo0vdsY}9F=Y~dwefi}6yCT*hz!j(+j2lYVexW-5iA6X$SkaKvp_ z46)`iV0LiUwF1YQAA@T-*5JLZ2SdZf3V#G%#g|5>V*|%I6ng!`=ANBP&qSOfK z{b3vW=I5=~YZj8c8K7yJ@Avx}BKxRq0K047Y=jttPa*q7=P{JMrG$8n@gsg=c=eJCj^Ce;J*|cvC+fo_9St4Pj~) z)ZKSph(3Qcwub^(JoAd7J-Q-bCfTGZb>X3I!%X8tS2AM5Kcat^u zFwScj4#4`-QYZa*VKE$lr>T^aesIN0zDgt#i9{liyqNqCu8w2Mca?7Z00000NkvXX Hu0mjfy?tiM literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/clothing/hands.dmi b/modular_dripstation/icons/mob/clothing/hands.dmi new file mode 100644 index 0000000000000000000000000000000000000000..bd2cc81838c3a9ce28b52b61e845229416016352 GIT binary patch literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeE3?v1%WpM*3tpJ}8S0HU~Z*Oa3_!@pQ&klbQR0$X zoLrPyP?DLS$G}iACpfI2sPy}n;DV1|pJ;jOYMncCK6pc@!A0W-k95xaXr5#!>gnBK zVH{+9+1N{A&Z9|3CWR;juiUXfW22G1e`mL`>gE*^OM1JF*J>D=iykp^S>f%c<8|Ku z{7HRp-D69`A`f0Y&-#XgVbUXw@P!Y}GJvjl?CIhd649ERAi=sgLF9tCffjdzMxv`s zje>wtN`inxhCv}ipkABB4~4UOC!``SOFM*AYw_6$v`jTJU{Tm1m@rA1L0mq=jajk2 zw<*wo%k7}X0d9+MrQjJg3JESNc`ed?83H$_J$m45qHvXM&gz3)Y05bapTm`J9yoPC zpl=0GfgD4idZOB=bGH~4m7R4hv?$6gVDtGT)9^9B+4CJY571dXAd@{9CNRlLDqLra zIB+JEhlg7rMvtv6)VNTK?e+%l*uziW*8>L*)YY+^IHCUGgGE?AfPJp8{p$>Wc({iWy6S{DK)Ap4~_Ta!RT~B1&9Ri<65o3raHc z^B5Q^<^+co6qSDe5?t`{>k}<+U9EFx&IfM@HMnT};E~RGAI*~tMLoScER2JUFB^L) z%y~5F$fOX3U`@^aN;|hKQQ4|tXYb$HZLGR^g~XES-NtJ*49!K4m>pRpG2JVbHQZi& zgEfQAG|km*cbHZK?O*Ka;usRqnw%iPx;R0EhyOr_rb>g;LgrMSLN(_OPq!PU9F_?; zRx&M%5ZRcW;CozvOPgV0D&q}Pg94ERj;+jw)y#Zfd3b~kTr3t=i1aiC8gRKWiZv|V zb|5~ULp!1C;adGU8zc^|=mdKI;Vst0JZ#>2LJ#7 literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/equipment/boxcutter_righthand.dmi b/modular_dripstation/icons/mob/inhands/equipment/boxcutter_righthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d83a9f2fe652c1f1664677dbbca4b0dd4f61bf90 GIT binary patch literal 381 zcmV-@0fPRCP)kP@z*VptYXATM0d!JMQvg8b*k%9#0Caj( zSad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1Q30E$UOK~z|U?UykMfG`jQ?@$XnzaYLq@F7;d!^%31 z|F#NT!mUOtm7QwgRpQpo+2G*dSfY=23)E`+*oc*5Vs%}dJ4fA0}dY3N^u!*5g47nvHf zZT}>%Of9Dqkd(El@?`x9sNQsdDAmKgPNQiapQopJksMCU{0CNr8E3_CFS3}Kmyu-N zf+1W%i!Z2rtyGek*PP(PF1$?>$`3GrhZFXK&w!xigP2_qAV`zIF=} z00000mY^SKY}kIF)&6^rh+3x~Xix128twE0x;e8Su)^&J>_z&4HgG>M50_hgU_USq zmxF%bFz5#W0001f2>Jorh3yAy@4xqm$U6OiJ+&XOz0(i$_RM~u6K+4yU8Endf%}1Z pxZLUk`+<459P|T+K|cT=JOCax4-vSlWe)%V002ovPDHLkV1iLE{%HUJ literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_righthand.dmi b/modular_dripstation/icons/mob/inhands/equipment/cargo_teleporter_righthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..804322b94a34deaa4dcbb79bcddeb27850373a33 GIT binary patch literal 611 zcmV-p0-XJcP)I+*v zaZ?kQ5C8xG0QeV>tZKUO{_3Wh_I}|64<$O?lZ-^<*Dn=r-Z6}kMUrGjN`FQ~qjBf3 z1~4Xee>s_vnQS-PVcMs$1=^_$_}{jNb!p-t*3?rgO)xsS*b` z$@@}*MehHC*z=O=l}p`L;e4dXpWXv>Q~R9BdmxzS7I{QH#NO1O^4ub`!!0s9+#>VC zEfN3#0000K1b)DM8`}A5KcJV$qW1#}%MUF1{eYeseqh#b@B^0N2dwy1KM*Xkq#pS8KmEi|g x@u_|wSY$~*5H7N$A4o6q2>d`6;0M6(cmk~X4TTI~h(G`U002ovPDHLkV1jZ*0Gj{+ literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/guns_lefthand.dmi b/modular_dripstation/icons/mob/inhands/guns_lefthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..87d9332db0030b2e85567f3793f775f8bbb21740 GIT binary patch literal 1227 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGo4OJl#B`&GO$wiq3C7Jno3=9=> zN>A<_#7`kTM&3s_U&uy9imosAGYrJ-fwV-ztL{x zsx{macVGIv)83qFkQZKLc~bi}7IO2 zmHLChb^wWhviF{gPih zk6c=LBWY1@Y>Qu(!)%>0jiVbyn6@?x`m`-({m*c4WmJ3LHkU5f02wRE?1dJcP6zpp zX@+>kFBjod-Rb>qdcNMi^Rtia{!#tDc>nLaPw!S+RJX$`v`t&>IX<^}O?3emRl|TAFchYOWIsd1a-TtSw zTrlfdpM}z~!?7{1pZoQ_ih0Pq)92{=b8|aSCQZ5*pzyK++^IpB$>B!E` zUb3g`PuKf`duQvmSl6)R0Nn6>^jZ}Y9)@tVIJw)DTAd%Ae02*1nk9aZs@A7(9X5>9^pv-yDN zeyd|{zy8bKy}EJFjHeqX{+sqZqP*EJM}EEC+8K6duXN4Y|K`Y}@I^r-DIaG(`O9GO zDOUp$%A9BFy$xGkZ_KWoNo-17rp)@pIJ3_+pZ#&7`7Y~&E-^XlR*7fm)rPwqw-x-n z+x&lhNVz_{q;mFwlB@|;rRz67TH&she%lNf6SIB^>mDv=G(H!-dgi?v^Nh8bz+jb~ zH`S-6#@lcko5`)&@%;~v7|fslXUXKx@k^#G>OC**JNJln9`A|;TbBWazL?m$Y|EWo zwWR25-LoGjZ0lypEn556c6E%NdF-EU2cA4#5Y)xKsP@e=^Zjul-{1WfE%4#mA+fdU z^W8VEuXC4A4|7o6v#nXW-j&05HEV@tmUh+miznt5ERSR5d?x@3ff@V%PFlio-SN>= QVClr*>FVdQ&MBb@00Mp{2mk;8 literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/guns_righthand.dmi b/modular_dripstation/icons/mob/inhands/guns_righthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..be3e720e8a37794c470713ccc9b116084ecf726f GIT binary patch literal 1274 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGo4OJl#B`&GO$wiq3C7Jno3=9=> zN>A<_#7`kTM&3s_U&uy9imosAGYrJ-fwV-ztL{x zsx{macVGIv)83qFkQZKLc~bi}7IO2 z0g7B`tRg|5YLHS0fhxwNv!UM3Re^h zt#lqeRtR6?JK0;W{C>=@ntQrCpVZF(Ui`j#=bg_PK0Zu+dS4j&tdtmfI2e?f4sQ@P#*2>@ z2QPAUd@ZZo#uD9GyDV>Sz5n{_pZE2cU%UNuo&37XpVFp?8x_aA-%*xb*ITJ*e7w^5 zR!O{R_<@voe(|+}TH;0PRFo?$reEvmn3s0R=H~UsH?uUvi$b=zt+;8&Cu(r>`r+fr z!XbK3GX7Pn3jEGAJ=H41d$0b=7nZBZ|0-Rz#fwU8%r3^rU!CT9ujkY5s~->KT5r9z z`)Xl$bZdC6OhqEl%FDsqt+PJ8HM1?f{rPp|;@UU2o35Re_`hz?(xqFc9>}xY8W9zJ zu`c}HrCpMr-^{vDAiu3My7sPY$#v%J1V{CL3+-@nVJbLj|S(tc`+<2`&s0 zf(&jf4Wu!3Rc_VKo4;g|%(cUP!M-xw4%awZz8ctjs@}G%Pb=QNVsB00f|*AQTtkjr ztmwD2%(&b0(f74sW$3ct?vAbxXMPx*opqjRqTbG(u~#x?cLaH=ZT|PMH2lDRQ>MD- zJ;!=2{QKjVT$kVX^JcF127ifa?@QaZ+{`+D^-Ry^Y!<)&RZpXP8@4Sy`zpCAOw)C@ z_5GKp`?+d$Yk7~{{BNIVdnVoQ%cXPg{5R>Wu99hgs$a|0=a-SuR}<#)V1CEd)Bkcs z9ajowh+Joi+outrA)-|4bADTr!_|%z9OqTq_Wr8USSNp~{%7FAnMXd{m-!c@-L_@^ z4#DRyyX&)A%cEM#&*Q*>0CR#sS@SjWQjv_eE)-wnceq3W< T8hi#=m@#;|`njxgN@xNAS-C_< literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/security_lefthand.dmi b/modular_dripstation/icons/mob/inhands/security_lefthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b3f49af053ef8a930efca1608c69c0339960decf GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSJOMr-u0XmZfIZEa;eRNDXZ-C~ zKt5whkY6x^!?PP{Ku%s&NJNQCYH@N=WKhlO#F@nvH#g*lHV9hnrO5Ui%fwO9p? zGKwegW-|nGIM0Zim~>C$0GGr;m7qz9ISdm$Jln)|8m1^j@Hd>${t?o^y6k~qfV0v; z2WB57RY_I@Pp?Uhs-k^cRZqAv@XnNKSXNTX%=zq+7z4v;ZxJV-L!DoMPGsbP0 Hl+XkKV<&n> literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/mob/inhands/security_righthand.dmi b/modular_dripstation/icons/mob/inhands/security_righthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..65c48c22f7e67e6b386f93dea459abbac6211c5e GIT binary patch literal 366 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 VS$B!iv6cV;002ovPDHLkV1iSSZHoW^ literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/blackmarket/module.dmi b/modular_dripstation/icons/obj/blackmarket/module.dmi new file mode 100644 index 0000000000000000000000000000000000000000..ff9ce847d797d81115bd843a0fa47d4d14404086 GIT binary patch literal 694 zcmV;n0!jUeP)V=-0C=1w$FUBAFc1ddx%U)*%5G3tyO0vo0p8(+gEmnh*Q)XD9oW9FLf7BJ z2tNe+h~~6!aA+?znQxj)ghO*96D6&&oXLfYz`;JAZ^;Kw!m9kUWagw94p%aZ@=H!v z=tmDf1o{JQA06KRir;_$00H_*L_t(oh3%HHYTHm0hQC`f22l#yJQVr}rr;ri@uW#m zcW5vaG$}-63+@AS4c>}Oz0?pe4h0uP2jQV;=-@?k=vca$E&^jzj|Fv5t|KXKB?SpD zKFgJKe*W|69NmkA=XvZi9__XI0pI}e5CGdANAmh|avbe?UO9j?x9xFcS%%o9u`EL* zb(I1D{QlTZnO;tgBhyTGVVABF0LwDObztzXw=b(J4Pe{j=;qD$+}0M=B}3#L#nSAx zI_5es0QmX%0@DQFk2Ssz&(`nA>WXyYC{G|wY@5ik3?XOl`!MZyIKBE3gETJ~^fp53 z@_c2K9>Jiu5u?#vZZv{sliT9uN0193%|3sK`>pGGH0W)_wBG?h`O#s}+X!9PQ@WxM zrAFYoGaSd+w)g5Zq(4;va2zLw&}!TT**II?*VaCQr1|?sG2QjbDH3Livu#ojw` c0N6XgUy=0*ohk$XW&i*H07*qoM6N<$f^JkoPXGV_ literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/blackmarket/telecoms.dmi b/modular_dripstation/icons/obj/blackmarket/telecoms.dmi new file mode 100644 index 0000000000000000000000000000000000000000..fb0da921d9d4653ef5e0c46adef9aee7c3a2844d GIT binary patch literal 2282 zcmZvec{J327sqFsifogn;wPCbDTNtN_8&8nwPJ)P^HY&(Xps<^XvReGh#!*d8A*if z*=a0gjUiRM{pd;@OX^8tbI8G$j465+`GRtw{K?7l5W z1*f;?lCt-U5q8P?7lH3IJrOn#B8!cc3>Ri=^jKBaKPop9w78`$)BeUUf6U8O3B>0!dxMOb)KEm~+N$Pvo+~|pr zEFSi)if!YaPRUh8TMrDqt4|`voiv|1vvK$^2qeDK*5b4?K4bY+&z&((P-Li* zhGFEvpzdc&ea)p+&*#mdHD~K3E{7oHIjw4jk6!5gXN8KJ|rr}xQ10{20O`w z&y|+p&)GPEY_|Dp_7a}fwJ;@Q6?p6F;0H^mb5Sr;Klx@d#D#dt5f&d%S`|n{kf{ zmRNaEUscR_&A=ud9T)e?6C~T}`>F$VWp{{3G8?h6o_9L69WC=3)9g2QfpK0^u(1lw zAlc5fHea3Q7PviBtWva6_|v^;s%#^TiZyspcwlyM5-Ihkw~<|_Y&*JFDCrI{rg8*s z7<{Xq9fZ`83QXvpJQU&4T0ZG5A0e2~y>4oOnUNFhm`L};y}33lr$6C*5^qujm=8Dv z{vfIVTSTu$K;^3fpvgk7$@=D}yv0w1lEr}yD&>Pi2%N|;4&)C>RH^_oTx|KR#H9v@6n1K@&eM1fnk17x-l?RN( z)o}aefwdV@Z?9xhWH>m!zrI9g#hrA|$bdpN5m?Ftq`POk;S95Y%NDEtA8%DqrrZW~+ySgRpOi4zA^La4GHUS2=!!_w?W#rwTfzi=sz$#@;uozTf*Am~{@eK~) z=CLptd;BKCq9^Dz`9xvN#d_)P@;>j~==})oSnUumui?voHQ%Fznhzi8BgX>Fw2j|&#uC5AjjPgU~6E90yp2&? z3e`5>B_ZUn)bKNOmo5s3ZC_YJHRT@7Ci6;y{DOm@xfVsF<^Eh;lo;)owO^fh%3K~| zZ^Wf<(OiZQDA@ED|Nbw~dO3?MhOuV1dExgKUqdOk=R_QTdJpZRPX8ASKDMuUW6x-G z^wa^mOWW!zl5C!PLTO!{@vl=XQ!{Zv7pEPz##h8+8xP^bw}Q3S>WGxMi-mKw@AcAW zaFL}HD0t@cgd4dAVA$NxIWb760SwZ0cROgZ>h%Eu7F~#F8WM z7wVuXyKyV9BoF?GSdM!^XfcoUkjb%_9XY1SU?*oou@NZuBtnZJQ5Gi;IBtR;C$Ko4 zOR(Mzb_En00A$3Wc_d4#$G;FnIPz+GA`Nx|Dg3+&>0)*-!PIkNX59IxEN?XLNhV^AV2j{&|An#x)9t`!7NRK|wlEGn|OEn0{p1Viq3rbusx3K?GTcp?)_cNwCh zjtCqDOOUUK@BdG3#}>K&K_C;%R1VCK>^JK~Wi1j+zO&HUsVwjSNmS>|kj8B|Lb|H~ zSc3G5i#8Xg2zp$Fipmscf)6Z0JV)BE!;zziFoIdmKs#hu%()sW|Dv2pmsoYFgWAky zo57LB4u6zp%$sU|TLrqt;H4SS=mKbpo>5F_K$fE?JdV(0k?6;NLw)jYqTPuAoML(n ziUr&QIgF!zG;m+iAzdpo`72&C3E&@wIwN85->8N{rsuGw{fK$m-}C5Kqy!G}ltpL+>3xsSwadQA9g@L@4E$De*? zDlbJVQJE}Y@s*=@-r(69Td=?|WDvn5!6-jNQu{tRwgWe95IG z;T)U%x^L>wm-@`S$CIJHQ?DL@i3#Wzksf@l_;>dIy2(+%q;>0Y^j$8Nl3RDKu>}NU z`zCYb!xOy%cts5mq}Wfj9I9X2{JAm-2iDK<0yI>{FxeVzaHQolH_GJMh}akL5#m2= zb$Fydl*cgY9`JaZr`r#X3665!?$L#h&Ew~_B{&`eO^Ge Mmi89K=2yf14TW^2p8x;= literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/bureaucracy.dmi b/modular_dripstation/icons/obj/bureaucracy.dmi index d883cbecb41383bd6bca3ba8a8b2d87feceb595a..bda80eb870de406cdc354c6217d66c69266520ad 100644 GIT binary patch literal 26512 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 literal 25971 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¨?ELu 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 K<%{K>`TraCjM#4g diff --git a/modular_dripstation/icons/obj/cargo/boxcutter.dmi b/modular_dripstation/icons/obj/cargo/boxcutter.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4f1c3ec30f55ea9be8aac9b46bec84c5c3207b50 GIT binary patch literal 432 zcmV;h0Z;ykP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DJj1qxwNDtwMdDJGbOXA z7$|1Q#hF%=n41b=W2%hL&%>oyS;5uM1?&z0Eh;Ic3%ob200021NklLh zK|pkg`yVXv>pLiwh-!Ig>jWVp%>hki0{|cfKoh|7o}C0{g@c(76Hujsu|(><&-ux( zPzB)p1-pWu;KwV-Avy_4H7})*3m^yJRVZYhngGTa7J%C+r*>X*TQ##)myR@kXum(A aTC#5@5DB$mgcx=J0000vDXPegb0-072FX zIKs9q51)Mqgzrt+VTA2d0uX*W$_b#_6yQe+g>_v&CjeO2_kH)`Z>_SgZ|@&%!Wj%g zk#(Owo3f6gD2n?3e)<1T0AM%vM_>mtCzuV)-2z2X$Iusx%^3gU4HK6D0000V=-0C=2j%drZ=Fc1ddIrkJl?OMcG*IOh-GPJKC!JJL7wQvcFZ|~sX;`j|; zi_>uS6Wr+ODO&RO0OPpZlX>M>6Bzx0Op-jO`bDXs3K-2b=)7I3EYgsPSqm7J%uT~8 z1&p3dlqI~uu$}GfZ>~Y_qW_nr7Q^J=Mo%Az04mI9?Ze#w00hfPL_t(|ob8&=Z`))T z$G>4Ewo|qBn=OgGt)&N`asq>PY*baHZQ{}!R2&B4#sN(|AaUZfKY$w&(#i?`0#t3V zsRvLwgs4nt5rQo0IM8u%+O>V%77{y+We!b@+qKEt#&6;>e@^zBH~zjqp7-_R=Y4>X zkdTm&kdSAU2y4Z$(NV{H{~(`_q&3Yg`|#=}zWQ+h0PwI_WPWb9^?O*w-y9#u+UhDO zrP!bpX-#v^swxN}IFn4`h2dY3Nvi+=Q52mCP|1%(o?f`9C+)uv;fmIL1Y=(Tn=xHy@#589r4qnC=`cbnxn!_>M37O-;mWdc~#PG9h{eiR7#Jd2t$| zB)N5UU5}(S&B>(Gpp@d?&A$=7cE7D9aFBjHK7+x*N!+`e@w|*b`p1PE57M7y#{UD#`(dENTnul z_q%hhH~?Q}nnj-wk&8alpNT9xgb-Mk1>3e^Sr({aaPN30^jmI%4J^z0@48y`L;FbZ z(q|fgQ$0N>m&>qi8vqcC#Sn|d+IDhS;i=E$2__Q>_r6wd#9^$=jX2eX%f1Z`Z~dkN zFj{v+GU+r#N!nwEf*?RuRcC+w5572u-yS}~%G^lXgU|{6BRN8%B*CuLVApDZv-^Bi zRh>pdEYk!b1fPC01|knIceI=OEqBt!Cnq%wWHik!FBFR)vh3c!KfZ!n^8x@sQ50Bp zU%cU^9T(pEE&Tvd6rq<&d&Gg=4~{q??tL<0Bcq*n@7L?I)-JsDTP}gdH#H#yq%OEY zDfCha-f~ft+}{huB1)xF+q2&ZeI`#(*Y!v?mvi=)0dUJM^jpa0R=vOZMz{4tLPA19 zLjI=&@_o6Jzp>c3t{BU1d1;f$ZGkdSbFU?N*u8#!^vm(~TgMS^$4|0G+iWdN`QFIG zp2-{%<4t2`wic!qy=Lndl057Vg4YVz7F7r7zc$ZhogTLS17iW*g4qIi=LdLqd)|1p zPDFkHPXeDGz?;D22e3Lhe&E$=s=EJt{?EsMAs+t+@za1=slXd`yZQCT0q67n=L-4F zk;39a^a>()gi7U?j^zjN=1BPgiZX^&>JonVeh2{n{D4lt6csi$4JgVdkVFT)y;1kK z+1c5rI+>bYiky_r1B{N4ZQBrp$A}82x{@Ej6Q-^A$!Zq0oq~HlFGQm#m&?4{))7uj zegH2{M1BBI0-qnio517;c*9t{@oEJ=KY%w)-var3K4O`sJCn`M=VzuY=hnP|Y%T{y zQSkbV2~|~{pdVBQCO?2j7>q?L@c99}30!_aBPi;341XtoW3gf^bBj6pN+-kOfua+K p7E9lLw8xSIxkjJaqp^@K@Gp8|)dJEB*(d-2002ovPDHLkV1j4FwT=J) literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/circuit_mess.dmi b/modular_dripstation/icons/obj/circuit_mess.dmi new file mode 100644 index 0000000000000000000000000000000000000000..559e678066170639edf898da80d348dac09e155a GIT binary patch literal 943 zcmV;g15o^lP)HGylv0W@Z2YW&lP;Mlmrl92^_~N&x1#0GTtHsHmtF6&1A?7c(;ep`oDw6G`sw z?$XlI&?F?8000LE2XJt3CnqNW0GYP7w*LS#00930|1fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;Zh zDainGjE%TBGg33tGfE(w;*!LYR3K9+IkPCaG_xc=H?_D}iHkEOv#1y-Y{FSpk z$V=haJ;xD7hxbL4{L41gM=2r1yH*_^brJdrR>34Y1v92J{@Je z`V@n?$`5(Nq{%q~?#o)&*w2DsuJYc1Q>0vLs7LcWl&j*oXc~GnMOTpg%==Og<;wU; z#D-3$()oG02NPqb>N7_y=$B5{g;D!;?PvBl_TcZ+)<` z|NjH$2m6)%|7SWsnC|cQ`{n)rW}fuHDo^?#>4W(C;Cx=*|8M3=AKX_Td;u21(|iP1 RH!T1F002ovPDHLkV1k-~wPyeT literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/clothing/gloves.dmi b/modular_dripstation/icons/obj/clothing/gloves.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7c1387a99a070fa211b85eff5581bccf6bbe6d87 GIT binary patch literal 724 zcmV;_0xSKAP)XJ=>M-`}>jwx_43+j&k*}mZy%w@7yx6qbBD|RjmL3 z00DGTPE!Ct=GbNc004e^R9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5; z&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+Ik6}`KRqYEEVWpPi!&v& zs2C_}$i)dvs0iRg(BumaX~g|_3;40NBqW0BUH}=0_m0pc5XmqIBCn!IAd9DDFhdU$ zFS5Y*~MFURmciGV%QZs1c(svIJl1Y#fFVaKq)eq*(nKS3}*=~7!z1!9- zzTO{dhM_*}cRP-uK2SJgr69KbJH}JGe^*3ID%{2{J~mC=vacT z?YbL7aO=>(6MVagM-p(}g=2HMTo?j0oK74*{UdPrZ{!yms~*J7pL`eq0000fFDZ*Bkpc$`yKaB_9`^iy#0_2eo` zEh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBSC_gznwInG&zob}+ zi!&v&s2C_}$i0Al1VO$78K|BGrLj5^#+fM*UkK%v$t)Z?g+FIsE8cRN};#~7zK#ZTt~ILQTki`5Zn00000NkvXXu0mjfnuekf literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/device.dmi b/modular_dripstation/icons/obj/device.dmi index 122b6dd34d0217d3c9516d94defb079a49b9be8b..478c47aecb3a263cd44c642665b302b3b0b899dd 100644 GIT binary patch literal 9057 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 literal 8752 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 JGF_+0{{n*DBUk_c diff --git a/modular_dripstation/icons/obj/hypnochair.dmi b/modular_dripstation/icons/obj/hypnochair.dmi new file mode 100644 index 0000000000000000000000000000000000000000..c25e429c649b0756e0799b7b8821acbec3c48ba4 GIT binary patch literal 4140 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 literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/partypod.dmi b/modular_dripstation/icons/obj/partypod.dmi new file mode 100644 index 0000000000000000000000000000000000000000..cb6f2a6dc1c32c3d716c96007e89a639a06cc415 GIT binary patch literal 15517 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 Dd+Fye literal 0 HcmV?d00001 diff --git a/modular_dripstation/icons/obj/weapons/48x32.dmi b/modular_dripstation/icons/obj/weapons/48x32.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7b7ee4064aa2b764e21a16f6b1b34256c9b40ba4 GIT binary patch literal 5261 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 literal 0 HcmV?d00001 diff --git a/modular_dripstation/includes.dm b/modular_dripstation/includes.dm index 4f89d087214c..62b57a62f608 100644 --- a/modular_dripstation/includes.dm +++ b/modular_dripstation/includes.dm @@ -1,3 +1,55 @@ +#include "code\controllers\subsystem\blackmarket.dm" +#include "code\datum\brain_damage\severe.dm" +#include "code\datum\component\transforming.dm" +#include "code\datum\reagent\baldium.dm" +#include "code\datum\reagent\chemoverride.dm" +#include "code\datum\reagent\leadacetate.dm" +#include "code\datum\strong_pull.dm" +#include "code\game\effects\effects_foam.dm" +#include "code\game\mecha\cargo_hauler.dm" +#include "code\game\objects\items\bepis_items\boomerang.dm" +#include "code\game\objects\items\bepis_items\eng_gloves.dm" +#include "code\game\objects\items\bepis_items\explorerpin.dm" +#include "code\game\objects\items\bepis_items\hypnochair.dm" +#include "code\game\objects\items\bepis_items\lava_rods.dm" +#include "code\game\objects\items\bepis_items\party_pod.dm" +#include "code\game\objects\items\bepis_items\polycircuit.dm" +#include "code\game\objects\items\bepis_items\rldmini.dm" +#include "code\game\objects\items\bepis_items\sprayoncan.dm" +#include "code\game\objects\items\bepis_items\survival_pen.dm" +#include "code\game\objects\items\blackmarketstuff.dm" +#include "code\game\objects\items\cargo_boxcutter.dm" +#include "code\game\objects\items\cargo_inducer.dm" +#include "code\game\objects\items\cargo_teleporter.dm" +#include "code\game\objects\items\clothing\gloves.dm" +#include "code\game\objects\items\devices\PDA\PDA_types.dm" +#include "code\game\objects\items\projectiles\guns\ballistic\rifle.dm" +#include "code\game\objects\items\tanks\watertank.dm" +#include "code\game\turfs\simulated\walls.dm" +#include "code\modules\antagonists\changeling\panacea.dm" +#include "code\modules\antagonists\horror\horror_chemicals.dm" +#include "code\modules\bepis\all_nodes.dm" +#include "code\modules\bepis\bepis.dm" +#include "code\modules\bepis\bepis_board.dm" +#include "code\modules\bepis\bepis_designs.dm" +#include "code\modules\bepis\bepis_layout.dm" +#include "code\modules\bepis\bounty.dm" +#include "code\modules\bepis\designs.dm" +#include "code\modules\cargo\bounties\progression.dm" +#include "code\modules\cargo\bounties\syndicate.dm" +#include "code\modules\cargo\export_scaner.dm" +#include "code\modules\cargo\markets\_market.dm" +#include "code\modules\cargo\markets\market_item.dm" +#include "code\modules\cargo\markets\market_items\clothing.dm" +#include "code\modules\cargo\markets\market_items\consumables.dm" +#include "code\modules\cargo\markets\market_items\misc.dm" +#include "code\modules\cargo\markets\market_items\tools.dm" +#include "code\modules\cargo\markets\market_items\weapons.dm" +#include "code\modules\cargo\markets\market_telepad.dm" +#include "code\modules\cargo\markets\market_uplink.dm" +#include "code\modules\cargo\packs.dm" +#include "code\modules\job\job_types\janitor.dm" +#include "code\modules\job\job_types\quartermaster.dm" #include "code\modules\antagonists\cult\cult_items.dm" #include "code\modules\economy\pay_stand.dm" #include "code\modules\events\wizard\greentext.dm" diff --git a/modular_dripstation/sound/item/boxcutter_activate.ogg b/modular_dripstation/sound/item/boxcutter_activate.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6700c6d03fde23b8d57ef5e23923b239826fc646 GIT binary patch literal 16979 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 literal 0 HcmV?d00001 diff --git a/tgui/packages/tgui/interfaces/Bepis2.tsx b/tgui/packages/tgui/interfaces/Bepis2.tsx new file mode 100644 index 000000000000..f7b47098b10f --- /dev/null +++ b/tgui/packages/tgui/interfaces/Bepis2.tsx @@ -0,0 +1,129 @@ +import { BooleanLike } from 'common/react'; +import { useBackend } from '../backend'; +import { Box, Button, Grid, LabeledList, NumberInput, Section } from '../components'; +import { Window } from '../layouts'; + +type Data = { + amount: number; + account_owner: string; + manual_power: BooleanLike; + stored_cash: number; + accuracy_percentage: number; + positive_cash_offset: number; + negative_cash_offset: number; + silicon_check: BooleanLike; + success_estimate: number; + mean_value: number; + error_name: string; +}; + +const BEPIS_SLOGAN = `All you need to know about the B.E.P.I.S. and you! The +B.E.P.I.S. performs hundreds of tests a second using +electrical and financial resources to invent new products, +or discover new technologies otherwise overlooked for being +too risky or too niche to produce!`; + +export const Bepis_new = (props, context) => { + const { act, data } = useBackend(context); + const { + amount, + account_owner, + manual_power, + stored_cash, + accuracy_percentage, + positive_cash_offset, + negative_cash_offset, + silicon_check, + success_estimate, + mean_value, + error_name, + } = data; + + return ( + + +
+
act('toggle_power')} + /> + }> + {BEPIS_SLOGAN} +
+
act('account_reset')} + /> + }> + Console is currently being linked to {' '}{account_owner ? account_owner : 'no one'}`s account. +
+ + +
+ + + {stored_cash} + + + {accuracy_percentage}% + + + {positive_cash_offset} + + + {negative_cash_offset} + + + + act('amount', { + amount: value, + }) + } + /> + + +
+ +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/Party.js b/tgui/packages/tgui/interfaces/Party.js new file mode 100644 index 000000000000..7896471dfbac --- /dev/null +++ b/tgui/packages/tgui/interfaces/Party.js @@ -0,0 +1,118 @@ +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; + +const damageTypes = [ + { + label: 'Brute', + type: 'bruteLoss', + }, + { + label: 'Burn', + type: 'fireLoss', + }, + { + label: 'Toxin', + type: 'toxLoss', + }, + { + label: 'Oxygen', + type: 'oxyLoss', + }, +]; + +export const Party = (props, context) => { + const { act, data } = useBackend(context); + const { open, occupant = {}, occupied } = data; + const preSortChems = data.chems || []; + const chems = preSortChems.sort((a, b) => { + const descA = a.name.toLowerCase(); + const descB = b.name.toLowerCase(); + if (descA < descB) { + return -1; + } + if (descA > descB) { + return 1; + } + return 0; + }); + return ( + + +
+ {occupant.stat} + + ) + }> + {!!occupied && ( + <> + + + + {damageTypes.map((type) => ( + + + + ))} + + {occupant.cloneLoss ? 'Damaged' : 'Healthy'} + + + {occupant.brainLoss ? 'Abnormal' : 'Healthy'} + + + + )} +
+
act('door')} + /> + }> + {chems.map((chem) => ( +
+
+
+ ); +}; diff --git a/yogstation.dme b/yogstation.dme index c4ef764517ff..cab24911941d 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -176,6 +176,10 @@ #include "code\__DEFINES\dcs\signals\signals_mob\signals_silicon.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_simplemob.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_xenobiology.dm" +#include "code\__DEFINES\{dripstation_defines}\blackmarket.dm" +#include "code\__DEFINES\{dripstation_defines}\cargo.dm" +#include "code\__DEFINES\{dripstation_defines}\directional.dm" +#include "code\__DEFINES\{dripstation_defines}\dcs\signals\signals_transform.dm" #include "code\__DEFINES\{yogs_defines}\admin.dm" #include "code\__DEFINES\{yogs_defines}\antagonists.dm" #include "code\__DEFINES\{yogs_defines}\atmospherics.dm" From f56339d02987bf42646abcceac9b695e6e80cceb Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Wed, 10 Jan 2024 22:21:26 +0300 Subject: [PATCH 02/18] commenting code edits //dripstation edit --- code/game/atoms_movable.dm | 4 +-- .../structures/crates_lockers/closets.dm | 12 ++++---- code/modules/cargo/console.dm | 30 +++++++++---------- .../modules/research/techweb/_techweb_node.dm | 6 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 8ce03309ae53..31c9e7bbb5bd 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1000,8 +1000,8 @@ return FALSE if(force < (move_resist * MOVE_FORCE_PULL_RATIO)) return FALSE - if(SEND_SIGNAL(src, COMSIG_ATOM_CAN_BE_PULLED, user) & COMSIG_ATOM_CANT_PULL) - return FALSE + if(SEND_SIGNAL(src, COMSIG_ATOM_CAN_BE_PULLED, user) & COMSIG_ATOM_CANT_PULL) //dripstation edit + return FALSE //dripstation edit return TRUE /// Called when mob changes from a standing position into a prone while lacking the ability to stand up at the moment. diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index b00566d22c3d..c1c291ca49c5 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(lockers) var/door_hinge_x = -6.5 var/door_anim_time = 2.5 // set to 0 to make the door not animate at all /// true whenever someone with the strong pull component (or magnet modsuit module) is dragging this, preventing opening - var/strong_grab = FALSE + var/strong_grab = FALSE //dripstation edit /obj/structure/closet/Initialize(mapload) . = ..() @@ -167,11 +167,11 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/proc/can_open(mob/living/user) if(welded || locked) - to_chat(user, span_danger("[src] locked or welded to be opened.")) - return FALSE - if(strong_grab) - to_chat(user, span_danger("[pulledby] has an incredibly strong grip on [src], preventing it from opening.")) - return FALSE + to_chat(user, span_danger("[src] locked or welded to be opened.")) //dripstation edit + return FALSE //dripstation edit + if(strong_grab) //dripstation edit + to_chat(user, span_danger("[pulledby] has an incredibly strong grip on [src], preventing it from opening.")) //dripstation edit + return FALSE //dripstation edit var/turf/T = get_turf(src) for(var/mob/living/L in T) diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 66431f842b01..35c0f6a6e91c 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -136,9 +136,9 @@ /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) if(..()) return - if(!allowed(usr) && can_approve_requests) - say("Access denied.") - return + if(!allowed(usr) && can_approve_requests) //dripstation edit + say("Access denied.") //dripstation edit + return //dripstation edit switch(action) if("send") if(!SSshuttle.supply.canMove()) @@ -154,7 +154,7 @@ investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO) else investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO) - say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(10)] seconds.") + say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(10)] seconds.") //dripstation edit SSshuttle.moveShuttle("supply", "supply_home", TRUE) . = TRUE if("loan") @@ -222,8 +222,8 @@ SSshuttle.requestlist += SO else SSshuttle.shoppinglist += SO - SO.pack.times_ordered += 1 - SO.pack.times_ordered_in_one_order += 1 + SO.pack.times_ordered += 1 //dripstation edit + SO.pack.times_ordered_in_one_order += 1 //dripstation edit if(self_paid) say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") . = TRUE @@ -232,30 +232,30 @@ for(var/datum/supply_order/SO in SSshuttle.shoppinglist) if(SO.id == id) SSshuttle.shoppinglist -= SO - SO.pack.times_ordered -= 1 - SO.pack.times_ordered_in_one_order -= 1 + SO.pack.times_ordered -= 1 //dripstation edit + SO.pack.times_ordered_in_one_order -= 1 //dripstation edit . = TRUE break if("clear") - for(var/datum/supply_order/SO in SSshuttle.shoppinglist) - SO.pack.times_ordered -= 1 - SO.pack.times_ordered_in_one_order = 0 + for(var/datum/supply_order/SO in SSshuttle.shoppinglist) //dripstation edit + SO.pack.times_ordered -= 1 //dripstation edit + SO.pack.times_ordered_in_one_order = 0 //dripstation edit SSshuttle.shoppinglist.Cut() . = TRUE if("approve") var/id = text2num(params["id"]) for(var/datum/supply_order/SO in SSshuttle.requestlist) if(SO.id == id) - if(SO.pack.times_ordered >= SO.pack.order_limit && SO.pack.order_limit != -1) //If the crate has reached the limit, do not allow it to be ordered. + if(SO.pack.times_ordered >= SO.pack.order_limit && SO.pack.order_limit != -1) //If the crate has reached the limit, do not allow it to be ordered. dripstation edit start say("[SO.pack.name] is out of stock and can no longer be ordered.") return if(SO.pack.times_ordered_in_one_order >= SO.pack.order_limit_in_one_order && SO.pack.order_limit_in_one_order != -1) say("[SO.pack.name] is out of stock for now and can no longer be ordered in this package. Try again later.") - return + return //dripstation edit end SSshuttle.requestlist -= SO SSshuttle.shoppinglist += SO - SO.pack.times_ordered += 1 - SO.pack.times_ordered_in_one_order += 1 + SO.pack.times_ordered += 1 //dripstation edit + SO.pack.times_ordered_in_one_order += 1 //dripstation edit . = TRUE break if("deny") diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index eff0c4a4dd9a..23112ab60175 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -7,7 +7,7 @@ var/display_name = "Errored Node" var/description = "Why are you seeing this?" var/hidden = FALSE //Whether it starts off hidden. - var/experimental = FALSE //If the tech can be randomly generated by the BEPIS as a reward. MEant to be fully given in tech disks, not researched + var/experimental = FALSE //If the tech can be randomly generated by the BEPIS as a reward. MEant to be fully given in tech disks, not researched. dripstation edit var/starting_node = FALSE //Whether it's available without any research. var/list/prereq_ids = list() var/list/design_ids = list() @@ -42,7 +42,7 @@ VARSET_TO_LIST(., id) VARSET_TO_LIST(., display_name) VARSET_TO_LIST(., hidden) - VARSET_TO_LIST(., experimental) + VARSET_TO_LIST(., experimental) //dripstation edit VARSET_TO_LIST(., starting_node) VARSET_TO_LIST(., assoc_to_keys(prereq_ids)) VARSET_TO_LIST(., assoc_to_keys(design_ids)) @@ -58,7 +58,7 @@ VARSET_FROM_LIST(input, id) VARSET_FROM_LIST(input, display_name) VARSET_FROM_LIST(input, hidden) - VARSET_FROM_LIST(input, experimental) + VARSET_FROM_LIST(input, experimental) //dripstation edit VARSET_FROM_LIST(input, starting_node) VARSET_FROM_LIST(input, prereq_ids) VARSET_FROM_LIST(input, design_ids) From 5ff9ed97fd05a863cae68647c7560f7a35db03c3 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Fri, 12 Jan 2024 15:25:13 +0300 Subject: [PATCH 03/18] repairing commit --- .../game/objects/items/cargo_teleporter.dm | 2 +- modular_dripstation/icons/obj/device.dmi | Bin 11857 -> 12101 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm index ade17c609529..62f95b582654 100644 --- a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm +++ b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm @@ -184,7 +184,7 @@ GLOBAL_LIST_EMPTY(cargo_marks) /obj/item/cargo_teleporter/proc/makingchoice(mob/user) choice = tgui_input_list(user, "Select which cargo mark to teleport the items to?", "Cargo Mark Selection", GLOB.cargo_marks) if(!choice) - return ..() + return /obj/item/cargo_teleporter/verb/remove_all_markers() diff --git a/modular_dripstation/icons/obj/device.dmi b/modular_dripstation/icons/obj/device.dmi index c4093e118bf0373ea917ff4a93d63af6b0a66a19..1555a11664dee8dc72f43962be29db45e84a93a2 100644 GIT binary patch literal 12101 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 Ar2qf` literal 11857 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 From 5ee4673b03aabeadfc77e7aabea2e9134b7e2515 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Fri, 12 Jan 2024 15:47:59 +0300 Subject: [PATCH 04/18] upd --- code/modules/cargo/packs.dm | 2 +- .../code/game/objects/items/bepis_items/eng_gloves.dm | 3 +-- modular_dripstation/code/game/objects/items/clothing/gloves.dm | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 33490083d6a7..5ceca653bd5c 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -317,7 +317,7 @@ /obj/item/toy/crayon/white, /obj/item/clothing/head/fedora/det_hat) crate_name = "forensics crate" - +/* /datum/supply_pack/security/laser name = "Lasers Crate" desc = "Contains three lethal, high-energy laser guns. Requires Security access to open." diff --git a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm index 3a8a22099eb4..5cca3a23e831 100644 --- a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm +++ b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm @@ -3,8 +3,7 @@ desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn." item_state = "orange" icon_state = "clockwork_gauntlets" - siemens_coefficient = 0.8 - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 80) clothing_flags = list(TRAIT_QUICK_BUILD) custom_materials = list(/datum/material/iron= 2000, /datum/material/silver= 1500, /datum/material/gold = 1000) resistance_flags = NONE \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/clothing/gloves.dm b/modular_dripstation/code/game/objects/items/clothing/gloves.dm index 340b34e28d56..7c59113fcdc7 100644 --- a/modular_dripstation/code/game/objects/items/clothing/gloves.dm +++ b/modular_dripstation/code/game/objects/items/clothing/gloves.dm @@ -3,7 +3,6 @@ desc = "These rubberized gauntlets have high adhesion to the metal surface that allows you to drag crates and lockers with more confidence on them not getting nabbed from you." icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' - siemens_coefficient = 0.6 // Some shock protected material anyway icon_state = "cargogloves" item_state = "cargogloves" cold_protection = HANDS @@ -11,7 +10,7 @@ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT undyeable = TRUE - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50, ELECTRIC = 60) var/datum/weakref/pull_component_weakref /obj/item/clothing/gloves/cargo_gauntlet/Initialize(mapload) From 344a590102bb2e5ac7ae67b1f10843799d9c2469 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:35:47 +0300 Subject: [PATCH 05/18] upd2 --- .../game/objects/items/cargo_teleporter.dm | 41 +++++++++++-------- .../interfaces/{Bepis2.tsx => Bepis_new.tsx} | 0 2 files changed, 23 insertions(+), 18 deletions(-) rename tgui/packages/tgui/interfaces/{Bepis2.tsx => Bepis_new.tsx} (100%) diff --git a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm index 62f95b582654..d5d3c7bde96d 100644 --- a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm +++ b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm @@ -67,26 +67,27 @@ GLOBAL_LIST_EMPTY(cargo_marks) ctcell = new(src) /obj/item/cargo_teleporter/emp_act(severity) + if (. & EMP_PROTECT_SELF) + return emped = TRUE SStgui.close_uis(src) //Close the UI control if it is open. I guess do not work, will work with ui refactor, if it will be made some day - switch(severity) - if(1) - ctcell.use(chargecost) - if(emagged) - emagged = FALSE - if(2) - ctcell.charge = 0 - if(emagged) - emagged = FALSE - if(prob(50)) - var/mob/living/carbon/human/user = src.loc - say("E:FATAL:PWR_BUS_OVERLOAD") - if(user.is_holding(src)) - if(user.dna && user.dna.species.id == "human") - say("E:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT") - to_chat(user, span_danger("An electromagnetic pulse disrupts your hacked teleporter and violently turns you into abomination.")) - to_chat(user, span_userdanger("You SEE THE LIGHT.")) - user.set_species(/datum/species/moth) + if(severity > EMP_LIGHT) + ctcell.charge = 0 + if(emagged) + emagged = FALSE + if(prob(50)) + var/mob/living/carbon/human/user = src.loc + say("E:FATAL:PWR_BUS_OVERLOAD") + if(user.is_holding(src)) + if(user.dna && user.dna.species.id == "human") + say("E:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT") + to_chat(user, span_danger("An electromagnetic pulse disrupts your hacked teleporter and violently turns you into abomination.")) + to_chat(user, span_userdanger("You SEE THE LIGHT.")) + user.set_species(/datum/species/moth) + else + ctcell.use(chargecost) + if(emagged) + emagged = FALSE /obj/item/cargo_teleporter/examine(mob/user) . = ..() @@ -217,6 +218,10 @@ GLOBAL_LIST_EMPTY(cargo_marks) return ..() if(target == src) return ..() + if(emped) + say("\The [src] malfunctioning and needs to be restarted.") + to_chat(user, span_notice("AltClick on device to restart it.")) + return ..() if(!COOLDOWN_FINISHED(src, use_cooldown)) say("\The [src] is still on cooldown.") return diff --git a/tgui/packages/tgui/interfaces/Bepis2.tsx b/tgui/packages/tgui/interfaces/Bepis_new.tsx similarity index 100% rename from tgui/packages/tgui/interfaces/Bepis2.tsx rename to tgui/packages/tgui/interfaces/Bepis_new.tsx From 3816dfb400560407ad71455ba20fd7f02bac794a Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Fri, 12 Jan 2024 17:26:32 +0300 Subject: [PATCH 06/18] upd3 --- modular_dripstation/code/modules/bepis/bepis.dm | 2 +- tgui/packages/tgui/interfaces/Bepis.js | 2 +- tgui/packages/tgui/interfaces/{Bepis_new.tsx => Bepis.tsx} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename tgui/packages/tgui/interfaces/{Bepis_new.tsx => Bepis.tsx} (98%) diff --git a/modular_dripstation/code/modules/bepis/bepis.dm b/modular_dripstation/code/modules/bepis/bepis.dm index 796f2f02014b..360ddbee7d7a 100644 --- a/modular_dripstation/code/modules/bepis/bepis.dm +++ b/modular_dripstation/code/modules/bepis/bepis.dm @@ -125,7 +125,7 @@ /obj/machinery/rnd/bepis/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "Bepis_new", name) + ui = new(user, src, "Bepis", name) ui.open() RefreshParts() // if(isliving(user)) diff --git a/tgui/packages/tgui/interfaces/Bepis.js b/tgui/packages/tgui/interfaces/Bepis.js index 8315e4c935cd..60468e7aaf83 100644 --- a/tgui/packages/tgui/interfaces/Bepis.js +++ b/tgui/packages/tgui/interfaces/Bepis.js @@ -2,7 +2,7 @@ import { useBackend } from '../backend'; import { Box, Button, Grid, LabeledList, NumberInput, Section } from '../components'; import { Window } from '../layouts'; -export const Bepis = (props, context) => { +export const Bepis_old = (props, context) => { const { act, data } = useBackend(context); const { amount, diff --git a/tgui/packages/tgui/interfaces/Bepis_new.tsx b/tgui/packages/tgui/interfaces/Bepis.tsx similarity index 98% rename from tgui/packages/tgui/interfaces/Bepis_new.tsx rename to tgui/packages/tgui/interfaces/Bepis.tsx index f7b47098b10f..822a178e5b3a 100644 --- a/tgui/packages/tgui/interfaces/Bepis_new.tsx +++ b/tgui/packages/tgui/interfaces/Bepis.tsx @@ -23,7 +23,7 @@ electrical and financial resources to invent new products, or discover new technologies otherwise overlooked for being too risky or too niche to produce!`; -export const Bepis_new = (props, context) => { +export const Bepis = (props, context) => { const { act, data } = useBackend(context); const { amount, From 54d2078b79668afddae176d887b0118b6b5ceca7 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:40:56 +0300 Subject: [PATCH 07/18] Devices tweak Advance pinpointer adding Laser pointer faster recharge Teleporter dispel speed tweak --- .../objects/items/devices/advpinpointer.dm | 135 ++++++++++++++++++ .../objects/items/devices/laserpointer.dm | 3 + .../code/game/objects/items/teleportation.dm | 12 ++ modular_dripstation/includes.dm | 2 + 4 files changed, 152 insertions(+) create mode 100644 modular_dripstation/code/game/objects/items/devices/advpinpointer.dm create mode 100644 modular_dripstation/code/game/objects/items/devices/laserpointer.dm diff --git a/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm new file mode 100644 index 000000000000..abb8a975288a --- /dev/null +++ b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm @@ -0,0 +1,135 @@ +#define SETTING_DISK 0 +#define SETTING_OBJECT 1 +#define SETTING_PERSON 2 +GLOBAL_LIST_INIT(HIGHRISK, typecacheof(list(/obj/item/disk/nuclear, + /obj/item/gun/energy/laser/captain, + /obj/item/hand_tele, + /obj/item/clothing/accessory/medal/gold/captain, + /obj/item/melee/sabre, + /obj/item/gun/energy/e_gun/hos, + /obj/item/card/id/captains_spare, + /obj/item/tank/jetpack/oxygen/captain, + /obj/item/aicard, + /obj/item/hypospray/deluxe/cmo, + /obj/item/clothing/suit/armor/reactive/teleport, + /obj/item/clothing/suit/armor/laserproof, + /obj/item/blackbox, + /obj/item/holotool, + /obj/item/areaeditor/blueprints))) + ///obj/item/clothing/gloves/krav_maga/sec, + ///obj/item/cargo_teleporter, +/obj/item/pinpointer/adv + var/modelocked = FALSE // If true, user cannot change mode. + var/obj/item/highrisk_rem = null + var/remember_target = null + var/setting = SETTING_DISK + +/obj/item/pinpointer/adv/examine(mob/user) + . = ..() + var/msg = "Its tracking indicator reads " + if(is_syndicate(user)) + switch(setting) + if(SETTING_DISK) + msg += "\"nuclear_disk\"." + if(SETTING_OBJECT) + msg += "\"target\"." + if(SETTING_PERSON) + msg += "\"person\"." + else + msg = "Its tracking indicator is blank." + else + msg += "\"nuclear_disk\"." + . += msg + +/obj/item/pinpointer/adv/toggle_on() + active = !active + playsound(src, 'sound/items/screwdriver2.ogg', 50, 1) + if(active) + if(!is_syndicate(usr)) + setting = SETTING_DISK + START_PROCESSING(SSfastprocess, src) + else + target = null + highrisk_rem = null + remember_target = null + setting = SETTING_DISK + STOP_PROCESSING(SSfastprocess, src) + update_appearance(UPDATE_ICON) + +/obj/item/pinpointer/adv/scan_for_target() + target = null + switch(setting) + if(SETTING_DISK) + var/obj/item/disk/nuclear/N = locate() in GLOB.poi_list + target = N + if(SETTING_OBJECT) + if(!highrisk_rem) + setting = SETTING_DISK + playsound(src, 'sound/machines/triple_beep.ogg', 50, 1) + return + var/obj/item/H = highrisk_rem + target = H + if(SETTING_PERSON) + if(!remember_target) + setting = SETTING_DISK + playsound(src, 'sound/machines/triple_beep.ogg', 50, 1) + return + target = remember_target + ..() + +/obj/item/pinpointer/adv/AltClick(mob/user) + if(isliving(user)) + if(is_syndicate(user)) + var/mob/living/L = user + to_chat(L, span_danger("Your [name] beeps as it reconfigures it's tracking algorithms.")) + playsound(src, 'sound/machines/boop.ogg', 50, 1) + switch_mode_to() + else + setting = SETTING_DISK + +/obj/item/pinpointer/adv/proc/switch_mode_to(mob/user) + switch(alert("Please select the mode you want to put the pinpointer in.", "Pinpointer Mode Select", "Disk Recovery", "High Risk", "DNA RSS")) + if("Disk Recovery") + setting = SETTING_DISK + if("High Risk") + to_chat(user, "Where are you working?") + setting = SETTING_OBJECT + var/list/item_names[0] + var/list/item_paths[0] + for(var/objective in GLOB.HIGHRISK) + var/datum/objective_item/steal/T = objective + var/name = initial(T.name) + item_names += name + item_paths[name] = initial(T.targetitem) + var/targetitem = input("Select item to search for.", "Item Mode Select","") as null|anything in item_names + if(!targetitem) + return + var/list/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE) + to_chat(user, "You fucking work here?.") + for(var/obj/item/candidate in target_candidates) + if(!is_centcom_level((get_turf(candidate)).z)) + highrisk_rem = candidate + playsound(src, get_sfx("terminal_type"), 25, 1) + to_chat(user, "You set the pinpointer to locate [targetitem].") + return + if(!highrisk_rem) + to_chat(user, "Failed to locate [targetitem]!") + return + to_chat(user, "The fuck are you doing here?.") + + if("DNA RSS") + setting = SETTING_PERSON + var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "") + if(!DNAstring) + return + for(var/mob/living/carbon/C in GLOB.mob_list) + if(!C.dna) + continue + if(C.dna.unique_enzymes == DNAstring) + if(!is_centcom_level((get_turf(C)).z)) + remember_target = C + playsound(src, get_sfx("terminal_type"), 25, 1) + to_chat(user, "You set the pinpointer to locate somebody.") + else + playsound(src, 'sound/machines/triple_beep.ogg', 50, 1) + to_chat(user, "Malfunction detected.") diff --git a/modular_dripstation/code/game/objects/items/devices/laserpointer.dm b/modular_dripstation/code/game/objects/items/devices/laserpointer.dm new file mode 100644 index 000000000000..806e7a276612 --- /dev/null +++ b/modular_dripstation/code/game/objects/items/devices/laserpointer.dm @@ -0,0 +1,3 @@ +/obj/item/laser_pointer/RefreshParts() + ///The rate at which the laser regenerates charge. Clamped between 20 seconds and basically instantly just in case of weirdness. Knock off 5 seconds per diode rating + recharge_rate = clamp((20 SECONDS - (5 SECONDS * diode.rating)), 1, 20 SECONDS) \ No newline at end of file diff --git a/modular_dripstation/code/game/objects/items/teleportation.dm b/modular_dripstation/code/game/objects/items/teleportation.dm index 21423c5c0685..4c89e3968b4c 100644 --- a/modular_dripstation/code/game/objects/items/teleportation.dm +++ b/modular_dripstation/code/game/objects/items/teleportation.dm @@ -1,2 +1,14 @@ /obj/item/hand_tele icon = 'modular_dripstation/icons/obj/device.dmi' + +/obj/item/hand_tele/try_dispel_portal(atom/target, mob/user) + if(is_parent_of_portal(target)) //dispel me from this horrid realm + var/dispel_time = 2 - (manipulator.rating/2) + if(dispel_time == 0) + qdel(target) + to_chat(user, span_notice("You dispel [target] with \the [src]!")) + return + balloon_alert(user, "Dispelling portal...") + if(do_after(user, dispel_time SECONDS, target)) + qdel(target) + to_chat(user, span_notice("You dispel [target] with \the [src]!")) \ No newline at end of file diff --git a/modular_dripstation/includes.dm b/modular_dripstation/includes.dm index 6135890de8f6..dfba4de915f9 100644 --- a/modular_dripstation/includes.dm +++ b/modular_dripstation/includes.dm @@ -65,6 +65,8 @@ #include "code\game\objects\items\devices\radio\encryptionkey.dm" #include "code\game\objects\items\devices\radio\radio.dm" #include "code\game\objects\items\devices\powersink.dm" +#include "code\game\objects\items\devices\laserpointer.dm" +#include "code\game\objects\items\devices\advpinpointer.dm" #include "code\game\objects\items\stacks\cash.dm" #include "code\game\objects\items\implants\implant.dm" #include "code\game\objects\items\implants\implanter.dm" From b092a3c72a152eaa409dc93ece66af21fc43b4be Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:08:34 +0300 Subject: [PATCH 08/18] Update advpinpointer.dm --- .../code/game/objects/items/devices/advpinpointer.dm | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm index abb8a975288a..89d5131f3c95 100644 --- a/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm +++ b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm @@ -83,7 +83,7 @@ GLOBAL_LIST_INIT(HIGHRISK, typecacheof(list(/obj/item/disk/nuclear, var/mob/living/L = user to_chat(L, span_danger("Your [name] beeps as it reconfigures it's tracking algorithms.")) playsound(src, 'sound/machines/boop.ogg', 50, 1) - switch_mode_to() + switch_mode_to(user) else setting = SETTING_DISK @@ -92,20 +92,18 @@ GLOBAL_LIST_INIT(HIGHRISK, typecacheof(list(/obj/item/disk/nuclear, if("Disk Recovery") setting = SETTING_DISK if("High Risk") - to_chat(user, "Where are you working?") setting = SETTING_OBJECT var/list/item_names[0] var/list/item_paths[0] for(var/objective in GLOB.HIGHRISK) - var/datum/objective_item/steal/T = objective - var/name = initial(T.name) + var/obj/item/I = objective + var/name = initial(I.name) item_names += name - item_paths[name] = initial(T.targetitem) + item_paths[name] = objective var/targetitem = input("Select item to search for.", "Item Mode Select","") as null|anything in item_names if(!targetitem) return var/list/target_candidates = get_all_of_type(item_paths[targetitem], subtypes = TRUE) - to_chat(user, "You fucking work here?.") for(var/obj/item/candidate in target_candidates) if(!is_centcom_level((get_turf(candidate)).z)) highrisk_rem = candidate @@ -115,7 +113,6 @@ GLOBAL_LIST_INIT(HIGHRISK, typecacheof(list(/obj/item/disk/nuclear, if(!highrisk_rem) to_chat(user, "Failed to locate [targetitem]!") return - to_chat(user, "The fuck are you doing here?.") if("DNA RSS") setting = SETTING_PERSON From 7e95fa62f49ef491cbd60f7b89a07bfe6b63be72 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:36:47 +0300 Subject: [PATCH 09/18] Update advpinpointer.dm --- .../code/game/objects/items/devices/advpinpointer.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm index 89d5131f3c95..5e19b0c8efdb 100644 --- a/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm +++ b/modular_dripstation/code/game/objects/items/devices/advpinpointer.dm @@ -80,6 +80,9 @@ GLOBAL_LIST_INIT(HIGHRISK, typecacheof(list(/obj/item/disk/nuclear, /obj/item/pinpointer/adv/AltClick(mob/user) if(isliving(user)) if(is_syndicate(user)) + if(!user.is_holding(src)) + to_chat(user, span_notice("You should be able to press the change mode button to interact with interface.")) + return var/mob/living/L = user to_chat(L, span_danger("Your [name] beeps as it reconfigures it's tracking algorithms.")) playsound(src, 'sound/machines/boop.ogg', 50, 1) From 56e5d2b1447de1b83172b24533a2951ba4a40778 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:22:09 +0300 Subject: [PATCH 10/18] upd4 Fixing gloves --- .../objects/items/bepis_items/eng_gloves.dm | 4 +++- .../icons/mob/clothing/hands.dmi | Bin 485 -> 961 bytes .../icons/obj/clothing/gloves.dmi | Bin 724 -> 1123 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm index 5cca3a23e831..414e65a7336e 100644 --- a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm +++ b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm @@ -1,8 +1,10 @@ /obj/item/clothing/gloves/tinkerer name = "tinker's gloves" desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn." - item_state = "orange" + item_state = "clockwork_gauntlets" icon_state = "clockwork_gauntlets" + icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' + mob_overlay_icon = icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 80) clothing_flags = list(TRAIT_QUICK_BUILD) custom_materials = list(/datum/material/iron= 2000, /datum/material/silver= 1500, /datum/material/gold = 1000) diff --git a/modular_dripstation/icons/mob/clothing/hands.dmi b/modular_dripstation/icons/mob/clothing/hands.dmi index bd2cc81838c3a9ce28b52b61e845229416016352..c2f296c60b28f4f1fc3be164dcd12c5b53fecdff 100644 GIT binary patch delta 865 zcmaFLe2~4qGr-TCmrII^fq{Y7)59eQNG||k4rU;^M{v44kn#xd32_C|k`hvi3QG3& z_O>=Qp6>23(a}~`R+DQPE??l-wUlelEFOJ5LlqSjeSLjVQBf`~uAi-f(^Tc3`LP^y z&@koWjt~{{@$t#mkz@s$#aI&L7tG+m{_I8?kT-i`Mt;588Z&$Som+NTY}PTgv)yR2 zUPXN?OS_tawW_K5MxhfXml&P(Qdz_8#W#dANGICHwNCVEV_;xv@N{tushIP2*3F`3 z10L5#opXnTa@7C+x7SVF+^Z^WwdBG%Tm4=g&Xpp+3e-HAfVKfa$D}k(>8&z-%bPj< zjvqd>C)h=;{&(^+^R4AscE7pjoqKL*G2j1Q)5JZ&B2g1w`Wh$dYW%UT*m>_=a>4#s zeeTcBfz^I$zaMkooxLp6j;-?5{ew@6wm0pr?~S;ppOjGbc@8(k9tMVn{r-w`PMp8p z_~Ensat-cJpYQx>Un%9ax#5GEhS%$LQ{R7zzm@YqQ7)}s#qhr6s#&jIvM#FAE3jF- zLNfleVbHIK`W7esxfj)~(?503-neS3p8NN#uQj~~Uu(W@tt?;O^PxC)Vu!xRcf0sQ zHqA>bY{j2VUZ3_u!o+yr3f@n37N6VS70q05C-QSrRQ}5UvyOc_+xG3hrsKQsX5C+Q zZdQByP43%?L)GkyDjDjbE`D%%2VZ~lwDRm9`(ONtjO){kI{e@D*>1l6rAzMImHMY| zcfYVgXUd-Fga6OYh~FvH-&jd;f($)7Jit&)65cZR7vLrsxPcaTgGQpOOpStoQA&biL!e%p#SewEdMBhJE=xOvRBQ3s z3A9W#GGI~IA(${pnL%7W!;M+7zPBmRfXnTm#sO}NaHZfGH3|tXD|s!_eHj8br#*U5 z?`)!Qm2J-IgIsCKISik}m2Vz6bwHqR1yF??L!f%1+NX237#5YCbuF|g$}M2?`6Scu zF~8aK9XAiqT|FS9Js2i1$x13*XNx#+CX|PVTOdY{tu55JP>b#M2JYCyS%1vtuz4x( t>=Mp6BDY7X!r*TK!}_*BgEx!}>!tLv1!nc}qyjz6;OXk;vd$@?2>?yag?In} diff --git a/modular_dripstation/icons/obj/clothing/gloves.dmi b/modular_dripstation/icons/obj/clothing/gloves.dmi index 7c1387a99a070fa211b85eff5581bccf6bbe6d87..8ed1f72553f7e896d238f2510f9695d1f51feacb 100644 GIT binary patch delta 1113 zcmV-f1g87c1>*=xiBL{Q4GJ0x0000DNk~Le0001B0000$2m=5B0MhD$JOBUyfly3T zMZmzo*x1+^7#blUA`=r6XJ=>M-`_7TF&!NpwzjsXr>BuS8-Lq+4>2)WIyyT4%mDxY zGug+h|BeAVJZk^z%7Sl}r;ft!+%mDFCKVMG85tQbFE3aX5;YDB=1v44ARxg&DEWmE zmL(sBg*poW0004WQchCV=-0C=2@k3kB;Fc3x8 z$tgm+717qM8-Hn$F6rWyr`_X-Fm-9}7|?#pDukyO-jY;EpSQTzVu}V))n7@LSca z%|x!?)xaFG$NXhS%Po3X7@G~BtW`gD@1I{dQc2QMk$)sU0008!Nkln3fFsg;OH{oy2o-d`FV4Q;}ipB_Gcy}L;5u}+k{!X1br+;h_8lR~(v%!|;kpUX+FOM1?SDXF0oZ@5jBOkX8OM5mm>^sK7Qsyx zL6)VEY5VjN@P0Ua9NsN}(g@z3STb)*zds8|H6nvF%L3+Q3AvN~r9V~hK>+s_(I<|# zY^ja?z5ph$f10qh0SH5|0nROIOYk*FkT(sPAisNT{6z~$yKnmxjR1s{%9!%E@cD}- zy?>tY9+_tFBr(q{8v{5x0E956zC#kdUE*>b0FH;_@pIz3n;GHfkqFlXxO=b|V64fD z0bUs3xQmtp?DqTp6#+zeeZ8i?`Hyf-|25Y5{{vA7(4Xt*0&@ffP>f~F)QOKJssajk z2J6)?`e{NJSR>*Y3s8z{{WrZD*L8&_oqs_Cr$den)i|Y>lrg2}Se0K0HGY+LhStmK z%=&puZ;W0wP95tU>$0IjOPY=8CnU_cekzeLPQ9)jnJ&DHe*;5E>;bqNKXIP(nW>w<@< zYVJyxfO;M1&W>8F2 zMZmzo85kNNAR-eJ6E7|?9UUE!N*jMVIy(Q%0RR6pz`(%R*w|-hXW!r7wzjsXr>EO` z4>2)W*~hE@jsZG6YX9rXf^U|mj>7NUGO?p3=Sx+s00001bW%=J06^y0W&i*HetJ|` zbVOxyV{&P5bZKvH004NLQ&wwcnkQkwj?Bi>RtdDi1&`rBoN6k2qLedNFa-+WH3Vy6ECvB_v7d;m?}Xu3Pl4> z?swVI9#S)C;?j2y50ZaLkPA8Ll7KJ0fpj-ftK zID(wN3yy@J7=m-tG?z0+&|)}(Yuo;`S55^#DER6YJ|gH?g0Ahl8$)pG(7+RXyNO2< taNdPubGcj?0yLaX96tRcaQJWJ7aFS`#Lb_47ytkO07*qoM6LruV1j`FGLQfO From a2afe7f38c5e8de3a80216fb9aaa1a8216d87161 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:45:05 +0300 Subject: [PATCH 11/18] Uh --- .../code/game/objects/items/bepis_items/eng_gloves.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm index 414e65a7336e..bc8cb59bcc4c 100644 --- a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm +++ b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm @@ -4,7 +4,7 @@ item_state = "clockwork_gauntlets" icon_state = "clockwork_gauntlets" icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' - mob_overlay_icon = icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' + mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 80) clothing_flags = list(TRAIT_QUICK_BUILD) custom_materials = list(/datum/material/iron= 2000, /datum/material/silver= 1500, /datum/material/gold = 1000) From ecae8b1012c469f9b6542cfa3aed5f9433f38baf Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:54:58 +0300 Subject: [PATCH 12/18] I belive I fixed it --- .../code/game/objects/items/bepis_items/eng_gloves.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm index bc8cb59bcc4c..039bc412e114 100644 --- a/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm +++ b/modular_dripstation/code/game/objects/items/bepis_items/eng_gloves.dm @@ -1,8 +1,8 @@ /obj/item/clothing/gloves/tinkerer name = "tinker's gloves" desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn." - item_state = "clockwork_gauntlets" - icon_state = "clockwork_gauntlets" + item_state = "concussive_gauntlets" + icon_state = "concussive_gauntlets" icon = 'modular_dripstation/icons/obj/clothing/gloves.dmi' mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/hands.dmi' armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 70, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 80) From a81a4ffc8eb801c4e6c47d17fd7573efa2573f88 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:48:10 +0300 Subject: [PATCH 13/18] lints upd --- code/__HELPERS/unsorted.dm | 3 --- .../code/modules/bepis/all_nodes.dm | 20 +++++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index d346e7fae044..74ec550f4a37 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -41,9 +41,6 @@ else if(x<0) .+=360 -//Better performant than an artisanal proc and more reliable than Turn(). From TGMC. -#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) - //Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) /* diff --git a/modular_dripstation/code/modules/bepis/all_nodes.dm b/modular_dripstation/code/modules/bepis/all_nodes.dm index 7fa470b206c1..bb93c7073569 100644 --- a/modular_dripstation/code/modules/bepis/all_nodes.dm +++ b/modular_dripstation/code/modules/bepis/all_nodes.dm @@ -39,13 +39,13 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) hidden = TRUE experimental = TRUE - -///datum/techweb_node/tackle_advanced -// id = "tackle_advanced" -// display_name = "Advanced Grapple Technology" -// description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject \ -// will no longer be accepted in its academic journals." -// design_ids = list("tackle_dolphin", "tackle_rocket") -// research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) -// hidden = TRUE -// experimental = TRUE \ No newline at end of file +/* +/datum/techweb_node/tackle_advanced + id = "tackle_advanced" + display_name = "Advanced Grapple Technology" + description = "Nanotrasen would like to remind its researching staff that it is never acceptable to \"glomp\" your coworkers, and further \"scientific trials\" on the subject will no longer be accepted in its academic journals." + design_ids = list("tackle_dolphin", "tackle_rocket") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE +*/ \ No newline at end of file From 8703b9b74e89692e9ea03e9a3dee1f87ad9b2cf4 Mon Sep 17 00:00:00 2001 From: Blundir Date: Thu, 1 Feb 2024 16:52:32 +0200 Subject: [PATCH 14/18] maybe? --- .github/workflows/turdis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/turdis.yml b/.github/workflows/turdis.yml index dbde0b434455..46cf7a5ca194 100644 --- a/.github/workflows/turdis.yml +++ b/.github/workflows/turdis.yml @@ -99,7 +99,7 @@ jobs: - name: Find Maps id: map_finder run: | - echo "$(ls -mw0 _maps/*.json)" > maps_output.txt + echo "$(ls -mw0 _maps/yogstation.json)" > maps_output.txt sed -i -e s+_maps/+\"+g -e s+.json+\"+g maps_output.txt echo "Maps: $(cat maps_output.txt)" echo "maps={\"paths\":[$(cat maps_output.txt)]}" >> $GITHUB_OUTPUT From 83e0ee65f5ffffff41378d1229d62ccf822903bc Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:43:17 +0300 Subject: [PATCH 15/18] REVERSE_DIR Yogs updating --- code/__DEFINES/{dripstation_defines}/directional.dm | 2 -- code/__HELPERS/unsorted.dm | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 code/__DEFINES/{dripstation_defines}/directional.dm diff --git a/code/__DEFINES/{dripstation_defines}/directional.dm b/code/__DEFINES/{dripstation_defines}/directional.dm deleted file mode 100644 index 6574a46fb509..000000000000 --- a/code/__DEFINES/{dripstation_defines}/directional.dm +++ /dev/null @@ -1,2 +0,0 @@ -/// Inverse direction, taking into account UP|DOWN if necessary. -#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 74ec550f4a37..d346e7fae044 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -41,6 +41,9 @@ else if(x<0) .+=360 +//Better performant than an artisanal proc and more reliable than Turn(). From TGMC. +#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) + //Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) /* From 72d1d2ea9685d3fa0b5eaa3345b27094176fa0a9 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:09:34 +0300 Subject: [PATCH 16/18] define fix --- yogstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/yogstation.dme b/yogstation.dme index e7254bc8f483..916586a0e2e9 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -185,7 +185,6 @@ #include "code\__DEFINES\dcs\signals\signals_mob\signals_xenobiology.dm" #include "code\__DEFINES\{dripstation_defines}\blackmarket.dm" #include "code\__DEFINES\{dripstation_defines}\cargo.dm" -#include "code\__DEFINES\{dripstation_defines}\directional.dm" #include "code\__DEFINES\{dripstation_defines}\dcs\signals\signals_transform.dm" #include "code\__DEFINES\{yogs_defines}\admin.dm" #include "code\__DEFINES\{yogs_defines}\antagonists.dm" From 520e73f343d122e6989a7d965c7c9f3e622e25d8 Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:24:10 +0300 Subject: [PATCH 17/18] Mannitol patent received --- modular_dripstation/code/datum/reagent/chemoverride.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modular_dripstation/code/datum/reagent/chemoverride.dm b/modular_dripstation/code/datum/reagent/chemoverride.dm index 31055843eb4f..1e69ac66b919 100644 --- a/modular_dripstation/code/datum/reagent/chemoverride.dm +++ b/modular_dripstation/code/datum/reagent/chemoverride.dm @@ -1,6 +1,6 @@ /datum/reagent/medicine/mannitol - name = "Mannitol" - description = "Efficiently restores brain damage. Requires very cold temperatures to properly metabolize." + name = "Mannitolin" + description = "Generic drug that uses a patented active substance molecule to restore brain damage. Unfortunately it isn`t too effective and requires very cold temperatures to properly metabolize." color = "#DCDCFF" metabolization_rate = 1.5 * REAGENTS_METABOLISM @@ -14,8 +14,8 @@ ..() /datum/reagent/medicine/mannitol/advanced - name = "Advanced mannitol" - description = "Efficiently restores brain damage. Really." + name = "Mannitol" + description = "Efficiently restores brain damage. Brand patented." color = "#4CE8E2" metabolization_rate = REAGENTS_METABOLISM From 17dc3e73bce4479721b1ee200d5bb69674dace1b Mon Sep 17 00:00:00 2001 From: MrCastmer <125900379+MrCastmer@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:47:34 +0300 Subject: [PATCH 18/18] cargo handheld teleporter Rename --- modular_dripstation/code/game/objects/items/cargo_teleporter.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm index d5d3c7bde96d..91943a298afd 100644 --- a/modular_dripstation/code/game/objects/items/cargo_teleporter.dm +++ b/modular_dripstation/code/game/objects/items/cargo_teleporter.dm @@ -1,7 +1,7 @@ GLOBAL_LIST_EMPTY(cargo_marks) /obj/item/cargo_teleporter - name = "QM personal teleporter" + name = "cargo handheld teleporter" desc = "Specialised personal teleporter based on modern bluespace technology. This one issued to QM for moving crates, closets and none-living objects to previously marked locations." icon = 'modular_dripstation/icons/obj/cargo/cargo_teleporter.dmi' mob_overlay_icon = 'modular_dripstation/icons/mob/clothing/belt.dmi'