diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 794c56691a6..2d1ed94cdb1 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -8,7 +8,6 @@ #define TOOL_ANALYZER "analyzer" #define TOOL_MINING "mining" #define TOOL_SHOVEL "shovel" -#define TOOL_DRAPES "surgicaldrapes" #define TOOL_RETRACTOR "retractor" #define TOOL_HEMOSTAT "hemostat" #define TOOL_CAUTERY "cautery" diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 9126b3a639b..708563cb751 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -199,6 +199,10 @@ return ..() +/obj/item/borg/cyborg_omnitool/get_all_tool_behaviours() + . = list() + for(var/obj/item/tool as anything in omni_toolkit) + . += initial(tool.tool_behaviour) ///The omnitool interacts with real world objects based on the state it has assumed /obj/item/borg/cyborg_omnitool/get_proxy_attacker_for(atom/target, mob/user) @@ -206,25 +210,25 @@ return src //first check if we have the tool - var/obj/item = atoms[reference] - if(!QDELETED(item)) - return item + var/obj/item/tool = atoms[reference] + if(!QDELETED(tool)) + return tool //else try to borrow an in-built tool from our other omnitool brothers to save & share memory & such var/mob/living/silicon/robot/borg = user for(var/obj/item/borg/cyborg_omnitool/omni_tool in borg.model.basic_modules) if(omni_tool == src) continue - item = omni_tool.atoms[reference] - if(!QDELETED(item)) - atoms[reference] = item - return item + tool = omni_tool.atoms[reference] + if(!QDELETED(tool)) + atoms[reference] = tool + return tool //if all else fails just make a new one from scratch - item = new reference(user) - ADD_TRAIT(item, TRAIT_NODROP, CYBORG_ITEM_TRAIT) - atoms[reference] = item - return item + tool = new reference(user) + ADD_TRAIT(tool, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + atoms[reference] = tool + return tool /obj/item/borg/cyborg_omnitool/attack_self(mob/user) //build the radial menu options @@ -236,9 +240,10 @@ var/toolkit_menu = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE) //set the reference & update icons - for(var/obj/item as anything in omni_toolkit) - if(initial(item.name) == toolkit_menu) - reference = item + for(var/obj/item/tool as anything in omni_toolkit) + if(initial(tool.name) == toolkit_menu) + reference = tool + tool_behaviour = initial(tool.tool_behaviour) update_appearance(UPDATE_ICON_STATE) playsound(src, 'sound/items/tools/change_jaws.ogg', 50, TRUE) break diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 9e126806651..50fe16dd435 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -129,7 +129,7 @@ item_module.forceMove(model) //Return item to configuration so it appears in its contents, so it can be taken out again. observer_screen_update(item_module, FALSE) - hud_used.update_robot_modules_display() + hud_used?.update_robot_modules_display() return TRUE /** diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 753979c3feb..2f14388fd49 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -316,7 +316,6 @@ attack_verb_continuous = list("slaps") attack_verb_simple = list("slap") interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY - tool_behaviour = TOOL_DRAPES /obj/item/surgical_drapes/Initialize(mapload) . = ..() diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 0b268b44166..26eda40f34d 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -210,6 +210,7 @@ #include "novaflower_burn.dm" #include "nuke_cinematic.dm" #include "objectives.dm" +#include "omnitools.dm" #include "operating_table.dm" #include "orderable_items.dm" #include "organ_bodypart_shuffle.dm" diff --git a/code/modules/unit_tests/omnitools.dm b/code/modules/unit_tests/omnitools.dm new file mode 100644 index 00000000000..700e0efd190 --- /dev/null +++ b/code/modules/unit_tests/omnitools.dm @@ -0,0 +1,64 @@ +/datum/unit_test/omnitools_engiboorg/Run() + var/mob/living/silicon/robot/borg = allocate(/mob/living/silicon/robot) + + //transform to engiborg + borg.model.transform_to(/obj/item/robot_model/engineering, forced = TRUE) + var/obj/item/borg/cyborg_omnitool/engineering/engi_tool = null + for(var/obj/item/borg/tool as anything in borg.model.modules) + if(istype(tool, /obj/item/borg/cyborg_omnitool/engineering)) + engi_tool = tool + break + borg.shown_robot_modules = TRUE //stops hud from updating which would runtime cause our mob does not have one + borg.equip_module_to_slot(engi_tool, 1) + borg.select_module(1) + var/obj/item/held_item = borg.get_active_held_item() + + //Tests for omnitool wrench + engi_tool.reference = engi_tool.omni_toolkit[1] + engi_tool.tool_behaviour = initial(engi_tool.reference.tool_behaviour) + var/obj/machinery/cell_charger/charger = allocate(/obj/machinery/cell_charger) + //Test 1: charger must be anchored + held_item.melee_attack_chain(borg, charger) + TEST_ASSERT(!charger.anchored, "Cell charger was not anchored by borg omnitool wrench!") + //Test 2: charger must be unanchored + held_item.melee_attack_chain(borg, charger) + TEST_ASSERT(charger.anchored, "Cell charger was not unanchored by borg omnitool wrench!") + + //Tests for omnitool wirecutter + engi_tool.reference = engi_tool.omni_toolkit[2] + engi_tool.tool_behaviour = initial(engi_tool.reference.tool_behaviour) + //Test 1: is holding wirecutters for wires + TEST_ASSERT(borg.is_holding_tool_quality(TOOL_WIRECUTTER), "Cannot find borg omnitool wirecutters in borgs hand!") + //Test 2: frame wires must be cut + var/obj/structure/frame/machine/test_frame = allocate(/obj/structure/frame/machine) + test_frame.state = FRAME_STATE_WIRED + held_item.melee_attack_chain(borg, test_frame) + TEST_ASSERT_EQUAL(test_frame.state, FRAME_STATE_EMPTY, "Machine frame's wires were not cut by the borg omnitool wirecutters!") + + //Test for omnitool screwdriver + engi_tool.reference = engi_tool.omni_toolkit[3] + engi_tool.tool_behaviour = initial(engi_tool.reference.tool_behaviour) + //Test 1: dissemble frame + held_item.melee_attack_chain(borg, test_frame) + TEST_ASSERT(QDELETED(test_frame), "Machine frame was not deconstructed by borg omnitool screwdriver!") + + //Test for borg omnitool crowbar + engi_tool.reference = engi_tool.omni_toolkit[4] + engi_tool.tool_behaviour = initial(engi_tool.reference.tool_behaviour) + var/obj/machinery/recharger/recharger = allocate(/obj/machinery/recharger) + recharger.panel_open = TRUE + //Test 1: should dissemble the charger + held_item.melee_attack_chain(borg, recharger) + TEST_ASSERT(QDELETED(recharger), "Recharger was not deconstructed by borg omnitool crowbar!") + + //Test for borg omnitool multitool + engi_tool.reference = engi_tool.omni_toolkit[5] + engi_tool.tool_behaviour = initial(engi_tool.reference.tool_behaviour) + var/obj/machinery/ore_silo/silo = allocate(/obj/machinery/ore_silo) + //Test 1: should store silo in buffer + held_item.melee_attack_chain(borg, silo) + var/obj/item/multitool/tool = held_item.get_proxy_attacker_for(silo, borg) + TEST_ASSERT(istype(tool), "Borg failed to switch internal tool to multitool") + TEST_ASSERT(istype(tool.buffer, /obj/machinery/ore_silo), "Borg omnitool multitool failed to log ore silo!") + + borg.unequip_module_from_slot(engi_tool, 1)