diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index b72bd9a9..e1d54064 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -44,6 +44,10 @@ #define EXAMINE_POSITION_BEFORE 2 //End positions #define COMPONENT_EXNAME_CHANGED 1 +#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" + #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1 + #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2 //from base of atom/update_icon(): () +#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays) #define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) #define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) #define COMPONENT_ATOM_BLOCK_EXIT 1 @@ -150,6 +154,7 @@ #define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) #define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) #define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () +#define COMSIG_BORG_SAFE_DECONSTRUCT "borg_safe_decon" //sent from borg mobs to itself, for tools to catch an upcoming destroy() due to safe decon (rather than detonation) // /mob/living/carbon signals #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) diff --git a/code/__DEFINES/spaceman_dmm.dm b/code/__DEFINES/spaceman_dmm.dm new file mode 100644 index 00000000..e590a30f --- /dev/null +++ b/code/__DEFINES/spaceman_dmm.dm @@ -0,0 +1,13 @@ +// Interfaces for the SpacemanDMM linter, define'd to nothing when the linter +// is not in use. + +// The SPACEMAN_DMM define is set by the linter and other tooling when it runs. +#ifdef SPACEMAN_DMM + #define RETURN_TYPE(X) set SpacemanDMM_return_type = X + #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X + #define UNLINT(X) SpacemanDMM_unlint(X) +#else + #define RETURN_TYPE(X) + #define SHOULD_CALL_PARENT(X) + #define UNLINT(X) X +#endif diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 09897e29..9e8756bb 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -24,7 +24,7 @@ var/list/add_overlays // a very temporary list of overlays to add var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays - + var/list/managed_overlays var/datum/proximity_monitor/proximity_monitor var/buckle_message_cooldown = 0 var/fingerprintslast @@ -255,6 +255,28 @@ /atom/proc/get_examine_string(mob/user, thats = FALSE) . = "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]" +/atom/proc/update_icon_state() + +/atom/proc/update_overlaysb() + SHOULD_CALL_PARENT(1) + . = list() + SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .) + +/atom/proc/update_iconb() + var/signalOut = SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON) + + if(!(signalOut & COMSIG_ATOM_NO_UPDATE_ICON_STATE)) + update_icon_state() + + if(!(signalOut & COMSIG_ATOM_NO_UPDATE_OVERLAYS)) + var/list/new_overlays = update_overlaysb() + if(managed_overlays) + cut_overlay(managed_overlays) + managed_overlays = null + if(length(new_overlays)) + managed_overlays = new_overlays + add_overlay(new_overlays) + /atom/proc/examine(mob/user) to_chat(user, get_examine_string(user, TRUE)) @@ -709,4 +731,4 @@ Proc for attack log creation, because really why not if(filter_data[name]) filter_data -= name update_filters() - return TRUE + return TRUE \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 3490cf22..2a8f0806 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -744,3 +744,204 @@ ..() hud = new /obj/item/clothing/glasses/hud/security(src) return + + +/********************************************************************** + Borg apparatus +***********************************************************************/ +//These are tools that can hold only specific items. For example, the mediborg gets one that can only hold beakers and bottles. + +/obj/item/borg/apparatus/ + name = "unknown storage apparatus" + desc = "This device seems nonfunctional." + icon = 'icons/mob/robot_items.dmi' + icon_state = "hugmodule" + var/obj/item/stored + var/list/storable = list() + +/obj/item/borg/apparatus/Initialize() + . = ..() + RegisterSignal(loc.loc, COMSIG_BORG_SAFE_DECONSTRUCT, .proc/safedecon) + +/obj/item/borg/apparatus/Destroy() + if(stored) + qdel(stored) + . = ..() + +///If we're safely deconstructed, we put the item neatly onto the ground, rather than deleting it. +/obj/item/borg/apparatus/proc/safedecon() + if(stored) + stored.forceMove(get_turf(src)) + stored = null + +/obj/item/borg/apparatus/Exited(atom/A) + if(A == stored) //sanity check + UnregisterSignal(stored, COMSIG_ATOM_UPDATE_ICON) + stored = null + update_icon() + . = ..() + +///A right-click verb, for those not using hotkey mode. +/obj/item/borg/apparatus/verb/verb_dropHeld() + set category = "Object" + set name = "Drop" + + if(usr != loc || !stored) + return + stored.forceMove(get_turf(usr)) + return + +/obj/item/borg/apparatus/attack_self(mob/living/silicon/robot/user) + if(!stored) + return ..() + if(user.client?.keys_held["Alt"]) + stored.forceMove(get_turf(user)) + return + stored.attack_self(user) + +/obj/item/borg/apparatus/pre_attack(atom/A, mob/living/user, params) + if(!stored) + var/itemcheck = FALSE + for(var/i in storable) + if(istype(A, i)) + itemcheck = TRUE + break + if(itemcheck) + var/obj/item/O = A + O.forceMove(src) + stored = O + RegisterSignal(stored, COMSIG_ATOM_UPDATE_ICON, /atom/.proc/update_iconb) + update_icon() + return + else + stored.melee_attack_chain(user, A, params) + return + . = ..() + +/obj/item/borg/apparatus/attackby(obj/item/W, mob/user, params) + if(stored) + W.melee_attack_chain(user, stored, params) + return + . = ..() + +///////////////// +//beaker holder// +///////////////// + +/obj/item/borg/apparatus/beaker + name = "beaker storage apparatus" + desc = "A special apparatus for carrying beakers without spilling the contents. Alt-Z or right-click to drop the beaker." + icon_state = "borg_beaker_apparatus" + storable = list(/obj/item/reagent_containers/glass/beaker, + /obj/item/reagent_containers/glass/bottle) + +/obj/item/borg/apparatus/beaker/Initialize() + . = ..() + stored = new /obj/item/reagent_containers/glass/beaker/large(src) + RegisterSignal(stored, COMSIG_ATOM_UPDATE_ICON, /atom/.proc/update_iconb) + update_icon() + +/obj/item/borg/apparatus/beaker/Destroy() + if(stored) + var/obj/item/reagent_containers/C = stored + C.SplashReagents(get_turf(src)) + qdel(stored) + . = ..() + +/obj/item/borg/apparatus/beaker/examine() + . = ..() + if(stored) + var/obj/item/reagent_containers/C = stored + . += "The apparatus currently has [C] secured, which contains:" + if(length(C.reagents.reagent_list)) + for(var/datum/reagent/R in C.reagents.reagent_list) + . += "[R.volume] units of [R.name]" + else + . += "Nothing." + +/obj/item/borg/apparatus/beaker/update_icon() + cut_overlays() + if(stored) + COMPILE_OVERLAYS(stored) + stored.pixel_x = 0 + stored.pixel_y = 0 + var/image/img = image("icon"=stored, "layer"=FLOAT_LAYER) + var/image/arm = image("icon"="borg_beaker_apparatus_arm", "layer"=FLOAT_LAYER) + if(istype(stored, /obj/item/reagent_containers/glass/beaker)) + arm.pixel_y = arm.pixel_y - 3 + img.plane = FLOAT_PLANE + add_overlay(img) + add_overlay(arm) + else + var/image/arm = image("icon"="borg_beaker_apparatus_arm", "layer"=FLOAT_LAYER) + arm.pixel_y = arm.pixel_y - 5 + add_overlay(arm) + +/obj/item/borg/apparatus/beaker/attack_self(mob/living/silicon/robot/user) + if(stored && !user.client?.keys_held["Alt"] && user.a_intent != "help") + var/obj/item/reagent_containers/C = stored + C.SplashReagents(get_turf(user)) + loc.visible_message("[user] spills the contents of the [C] all over the floor.") + return + . = ..() + +/obj/item/borg/apparatus/beaker/extra + name = "secondary beaker storage apparatus" + desc = "A supplementary beaker storage apparatus." + +/obj/item/borg/apparatus/beaker/service + name = "beverage storage apparatus" + desc = "A special apparatus for carrying drinks without spilling the contents. Alt-Z or right-click to drop the beaker." + icon_state = "borg_beaker_apparatus" + storable = list(/obj/item/reagent_containers/food/drinks/, + /obj/item/reagent_containers/food/condiment) + +/obj/item/borg/apparatus/beaker/service/Initialize() + . = ..() + stored = new /obj/item/reagent_containers/food/drinks/drinkingglass(src) + RegisterSignal(stored, COMSIG_ATOM_UPDATE_ICON, /atom/.proc/update_iconb) + update_icon() + +//////////////////// +//engi part holder// +//////////////////// + +/obj/item/borg/apparatus/circuit + name = "circuit manipulation apparatus" + desc = "A special apparatus for carrying and manipulating circuit boards. Alt-Z or right-click to drop the stored object." + icon_state = "borg_hardware_apparatus" + storable = list(/obj/item/circuitboard, + /obj/item/electronics) + +/obj/item/borg/apparatus/circuit/Initialize() + . = ..() + update_icon() + +/obj/item/borg/apparatus/circuit/update_icon() + cut_overlays() + if(stored) + COMPILE_OVERLAYS(stored) + stored.pixel_x = -3 + stored.pixel_y = 0 + var/image/arm + if(istype(stored, /obj/item/circuitboard)) + arm = image("icon"="borg_hardware_apparatus_arm1", "layer"=FLOAT_LAYER) + else + arm = image("icon"="borg_hardware_apparatus_arm2", "layer"=FLOAT_LAYER) + var/image/img = image("icon"=stored, "layer"=FLOAT_LAYER) + img.plane = FLOAT_PLANE + add_overlay(arm) + add_overlay(img) + else + var/image/arm = image("icon"="borg_hardware_apparatus_arm1", "layer"=FLOAT_LAYER) + add_overlay(arm) + +/obj/item/borg/apparatus/circuit/examine() + . = ..() + if(stored) + . += "The apparatus currently has [stored] secured." + +/obj/item/borg/apparatus/circuit/pre_attack(atom/A, mob/living/user, params) + . = ..() + if(istype(A, /obj/item/aiModule) && !stored) //If an admin wants a borg to upload laws, who am I to stop them? Otherwise, we can hint that it fails + to_chat(user, "This circuit board doesn't seem to have standard robot apparatus pin holes. You're unable to pick it up.") \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index d7dbcecd..7fcd7eff 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -514,7 +514,7 @@ /obj/item/robot_module/medical, /obj/item/robot_module/syndicate_medical, /obj/item/robot_module/medihound, - /obj/item/robot_module/borgi) + /obj/item/robot_module/borgi) /obj/item/borg/upgrade/advhealth/action(mob/living/silicon/robot/R, user = usr) . = ..() @@ -620,6 +620,32 @@ if (RPED) R.module.remove_module(RPED, TRUE) +/obj/item/borg/upgrade/circuit_app + name = "circuit manipulation apparatus" + desc = "An engineering cyborg upgrade allowing for manipulation of circuit boards." + icon_state = "cyborg_upgrade3" + require_module = TRUE + module_type = list(/obj/item/robot_module/engineering) + +/obj/item/borg/upgrade/circuit_app/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/borg/apparatus/circuit/C = locate() in R.module.modules + if(C) + to_chat(user, "This unit is already equipped with a circuit apparatus!") + return FALSE + + C = new(R.module) + R.module.basic_modules += C + R.module.add_module(C, FALSE, TRUE) + +/obj/item/borg/upgrade/circuit_app/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/borg/apparatus/circuit/C = locate() in R.module.modules + if (C) + R.module.remove_module(C, TRUE) + /obj/item/borg/upgrade/pinpointer name = "medical cyborg crew pinpointer" desc = "A crew pinpointer module for the medical cyborg." diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index b29749fc..cc5db37c 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -250,10 +250,12 @@ /obj/item/stack/rods/cyborg, /obj/item/stack/tile/plasteel/cyborg, /obj/item/extinguisher, + /obj/item/borg/apparatus/beaker/service, /obj/item/pickaxe, /obj/item/t_scanner/adv_mining_scanner, /obj/item/restraints/handcuffs/cable/zipties, /obj/item/soap/nanotrasen, + /obj/item/reagent_containers/rag, /obj/item/borg/cyborghug) emag_modules = list(/obj/item/melee/transforming/energy/sword/cyborg) ratvar_modules = list( @@ -269,6 +271,7 @@ /obj/item/assembly/flash/cyborg, /obj/item/healthanalyzer, /obj/item/reagent_containers/borghypo, + /obj/item/borg/apparatus/beaker, /obj/item/reagent_containers/glass/beaker/large, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, @@ -280,6 +283,9 @@ /obj/item/scalpel, /obj/item/circular_saw, /obj/item/extinguisher/mini, + /obj/item/soap/nanotrasen, + /obj/item/reagent_containers/rag, + /obj/item/crowbar/cyborg, /obj/item/roller/robo, /obj/item/borg/cyborghug/medical, /obj/item/stack/medical/gauze/cyborg, @@ -311,8 +317,11 @@ /obj/item/multitool/cyborg, /obj/item/t_scanner, /obj/item/analyzer, + /obj/item/borg/cyborghug, + /obj/item/reagent_containers/rag, /obj/item/geiger_counter/cyborg, /obj/item/assembly/signaler/cyborg, + /obj/item/holosign_creator/atmos, /obj/item/areaeditor/blueprints/cyborg, /obj/item/electroadaptive_pseudocircuit, /obj/item/stack/sheet/metal/cyborg, @@ -335,9 +344,15 @@ basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/restraints/handcuffs/cable/zipties, + /obj/item/holosign_creator/security, /obj/item/melee/baton/loaded, /obj/item/gun/energy/disabler/cyborg, + /obj/item/reagent_containers/spray/pepper, + /obj/item/reagent_containers/rag, /obj/item/clothing/mask/gas/sechailer/cyborg, + /obj/item/extinguisher/mini, + /obj/item/borg/cyborghug, + /obj/item/crowbar/cyborg, /obj/item/pinpointer/crew) emag_modules = list(/obj/item/gun/energy/laser/cyborg) ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, @@ -361,7 +376,9 @@ /obj/item/reagent_containers/borghypo/peace, /obj/item/holosign_creator/cyborg, /obj/item/borg/cyborghug/peacekeeper, - /obj/item/extinguisher, + /obj/item/extinguisher/mini, + /obj/item/reagent_containers/rag, + /obj/item/crowbar/cyborg, /obj/item/borg/projectile_dampen) emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked) ratvar_modules = list( @@ -385,7 +402,9 @@ /obj/item/crowbar/cyborg, /obj/item/stack/tile/plasteel/cyborg, /obj/item/soap/nanotrasen, + /obj/item/reagent_containers/rag, /obj/item/storage/bag/trash/cyborg, + /obj/item/borg/cyborghug, /obj/item/extinguisher/mini, /obj/item/mop/cyborg, /obj/item/lightreplacer/cyborg, @@ -434,7 +453,8 @@ /obj/item/bikehorn, /obj/item/bikehorn/airhorn, /obj/item/paint/anycolor, - /obj/item/soap/nanotrasen, + /obj/item/reagent_containers/rag, + /obj/item/cookiesynth, /obj/item/pneumatic_cannon/pie/selfcharge/cyborg, /obj/item/razor, //killbait material /obj/item/lipstick/purple, @@ -442,7 +462,10 @@ /obj/item/borg/cyborghug/peacekeeper, /obj/item/borg/lollipop/clown, /obj/item/picket_sign/cyborg, + /obj/item/reagent_containers/borghypo/borgshaker, /obj/item/reagent_containers/borghypo/clown, + /obj/item/borg/apparatus/beaker/service, + /obj/item/reagent_containers/glass/beaker/large, /obj/item/extinguisher/mini) emag_modules = list( /obj/item/reagent_containers/borghypo/clown/hacked, @@ -459,16 +482,20 @@ name = "Service" basic_modules = list( /obj/item/assembly/flash/cyborg, - /obj/item/reagent_containers/food/drinks/drinkingglass, + /obj/item/reagent_containers/glass/beaker/large, + /obj/item/borg/apparatus/beaker/service, /obj/item/reagent_containers/food/condiment/enzyme, /obj/item/pen, /obj/item/toy/crayon/spraycan/borg, /obj/item/extinguisher/mini, /obj/item/hand_labeler/borg, /obj/item/razor, + /obj/item/reagent_containers/rag, + /obj/item/crowbar/cyborg, /obj/item/instrument/violin, /obj/item/instrument/guitar, /obj/item/rsf/cyborg, + /obj/item/borg/cyborghug, /obj/item/reagent_containers/dropper, /obj/item/lighter, /obj/item/storage/bag/tray, @@ -496,7 +523,9 @@ /obj/item/pickaxe/drill/cyborg, /obj/item/shovel, /obj/item/crowbar/cyborg, + /obj/item/reagent_containers/rag, /obj/item/weldingtool/mini, + /obj/item/borg/cyborghug, /obj/item/extinguisher/mini, /obj/item/storage/bag/sheetsnatcher/borg, /obj/item/t_scanner/adv_mining_scanner, diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index e8c8bab0..841a8897 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -704,7 +704,7 @@ materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_SILVER=10000, MAT_GOLD=10000, MAT_TITANIUM=5000, MAT_DIAMOND=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") - + /datum/design/borg_upgrade_surgicalprocessor name = "Cyborg Upgrade (Surgical Processor)" id = "borg_upgrade_surgicalprocessor" @@ -759,6 +759,15 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") +/datum/design/borg_upgrade_circuit_app + name = "Cyborg Upgrade (Circuit Manipulator)" + id = "borg_upgrade_circuitapp" + build_type = MECHFAB + build_path = /obj/item/borg/upgrade/circuit_app + materials = list(MAT_METAL=2000, MAT_TITANIUM=500) + construction_time = 120 + category = list("Cyborg Upgrade Modules") + /datum/design/borg_upgrade_pinpointer name = "Cyborg Upgrade (Crew pinpointer)" id = "borg_upgrade_pinpointer" diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi index 862e1be3..a3b6237b 100644 Binary files a/icons/mob/robot_items.dmi and b/icons/mob/robot_items.dmi differ diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm index 8e922c35..b14176fa 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -37,6 +37,7 @@ /obj/item/clothing/mask/gas/sechailer/cyborg, /obj/item/soap/tongue, /obj/item/analyzer/nose, + /obj/item/holosign_creator/security, /obj/item/dogborg/sleeper/K9, /obj/item/gun/energy/disabler/cyborg, /obj/item/pinpointer/crew) @@ -88,9 +89,12 @@ /obj/item/healthanalyzer, /obj/item/dogborg/sleeper/medihound, /obj/item/roller/robo, + /obj/item/crowbar/cyborg, + /obj/item/borg/apparatus/beaker, /obj/item/reagent_containers/borghypo, /obj/item/twohanded/shockpaddles/cyborg/hound, /obj/item/stack/medical/gauze/cyborg, + /obj/item/reagent_containers/syringe, /obj/item/pinpointer/crew, /obj/item/sensor_device) emag_modules = list(/obj/item/dogborg/pounce) @@ -132,9 +136,13 @@ basic_modules = list( /obj/item/dogborg/jaws/small, /obj/item/analyzer/nose, + /obj/item/crowbar/cyborg, /obj/item/soap/tongue/scrubpup, + /obj/item/stack/tile/plasteel/cyborg, + /obj/item/storage/bag/trash/cyborg, /obj/item/lightreplacer/cyborg, /obj/item/extinguisher/mini, + /obj/item/holosign_creator, /obj/item/dogborg/sleeper/compactor) emag_modules = list(/obj/item/dogborg/pounce) ratvar_modules = list( @@ -168,7 +176,12 @@ /obj/item/storage/bag/borgdelivery, /obj/item/analyzer/nose, /obj/item/soap/tongue, + /obj/item/cookiesynth, + /obj/item/holosign_creator/cyborg, + /obj/item/crowbar/cyborg, + /obj/item/borg/projectile_dampen, /obj/item/healthanalyzer, + /obj/item/reagent_containers/borghypo/peace, /obj/item/extinguisher/mini, /obj/item/borg/cyborghug) emag_modules = list(/obj/item/dogborg/pounce) diff --git a/modular_citadel/icons/mob/robots.dmi b/modular_citadel/icons/mob/robots.dmi index ccb92f0c..924a3cba 100644 Binary files a/modular_citadel/icons/mob/robots.dmi and b/modular_citadel/icons/mob/robots.dmi differ