diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 2be5fc60c5c..a10e3398700 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -122,12 +122,13 @@ else if(istype(I,/obj/item/gripper)) //Behold, Grippers and their horribleness. If ..() is called by any computers' attackby() now or in the future, this should let grippers work with them appropriately. var/obj/item/gripper/B = I //B, for Borg. - if(!B.wrapped) + if(!B.get_item()) to_chat(user, "\The [B] is not holding anything.") return else - var/B_held = B.wrapped + var/B_held = B.get_item() to_chat(user, "You use \the [B] to use \the [B_held] with \the [src].") playsound(src, "keyboard", 100, 1, 0) + attackby(B.get_item(), user, params, attackchain_flags, damage_multiplier) return return ..() diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 6d50cb3ed76..c414289476f 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -1,4 +1,5 @@ /obj/machinery/computer/crew + name = "crew monitoring computer" desc = "Used to monitor active health sensors built into most of the crew's uniforms." icon_keyboard = "med_key" diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 9afb5fd9121..0a1393a13f2 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -357,6 +357,8 @@ merge(AM) /obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible + if(uses_charge) + return // how about no! if(QDELETED(S) || QDELETED(src) || (S == src)) //amusingly this can cause a stack to consume itself, let's not allow that. return var/transfer = get_amount() diff --git a/code/modules/economy/machines/mint.dm b/code/modules/economy/machines/mint.dm index 06fcd9af2ef..c212800ed00 100644 --- a/code/modules/economy/machines/mint.dm +++ b/code/modules/economy/machines/mint.dm @@ -441,12 +441,13 @@ else if(istype(O, /obj/item/gripper)) // Grippers. ~Mechoid. var/obj/item/gripper/B = O //B, for Borg. - if(!B.wrapped) + if(!B.get_item()) to_chat(user, "\The [B] is not holding anything.") return else - var/B_held = B.wrapped + var/B_held = B.get_item() to_chat(user, "You use \the [B] to put \the [B_held] into \the [src] slot.") + attackby(B_held, user) return else diff --git a/code/modules/food/kitchen/smartfridge.dm b/code/modules/food/kitchen/smartfridge.dm index 2b3c1645508..3700ed59086 100644 --- a/code/modules/food/kitchen/smartfridge.dm +++ b/code/modules/food/kitchen/smartfridge.dm @@ -283,12 +283,13 @@ else if(istype(O, /obj/item/gripper)) // Grippers. ~Mechoid. var/obj/item/gripper/B = O //B, for Borg. - if(!B.wrapped) + if(!B.get_item()) to_chat(user, "\The [B] is not holding anything.") return else - var/B_held = B.wrapped + var/B_held = B.get_item() to_chat(user, "You use \the [B] to put \the [B_held] into \the [src].") + attackby(B_held, user) return else diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 0be51833779..e6bab4d93b8 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -546,7 +546,10 @@ var/list/name_to_material var/window_count = 0 for (var/obj/structure/window/check_window in user.loc) window_count++ - possible_directions -= check_window.dir + if(check_window.is_fulltile()) + possible_directions -= GLOB.cardinal + else + possible_directions -= check_window.dir for (var/obj/structure/windoor_assembly/check_assembly in user.loc) window_count++ possible_directions -= check_assembly.dir diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 2af8626cf13..b2156ef023a 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -178,7 +178,7 @@ if (stat == 2 || (XRAY in src.mutations)) AddSightSelf(SEE_TURFS | SEE_MOBS | SEE_OBJS) SetSeeInDarkSelf(8) - SetSeeInvisibleSelf(SEE_INVISIBLE_LEVEL_TWO) + SetSeeInvisibleSelf(SEE_INVISIBLE_LEVEL_ONE) else if (stat != 2) RemoveSightSelf(SEE_TURFS | SEE_MOBS | SEE_OBJS) SetSeeInDarkSelf(2) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 55ad82c3f6d..4b6106a8f01 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -25,7 +25,8 @@ /obj/item/fuel_assembly/ ) - var/obj/item/wrapped = null // Item currently being held. + /// currently held item + VAR_PRIVATE/obj/item/wrapped var/force_holder = null // @@ -33,10 +34,47 @@ . = ..() if(wrapped) . += "\The [src] is holding \the [wrapped]." - wrapped.examine(user) + . += wrapped.examine(user) + +/obj/item/gripper/Destroy() + remove_item(drop_location()) + return ..() + +/obj/item/gripper/proc/insert_item(obj/item/I) + if(QDELETED(I)) + return + if(wrapped) + remove_item(drop_location()) + wrapped = I + I.forceMove(src) + RegisterSignal(I, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), .proc/unwrap_hook) + +/** + * newloc false to not move + */ +/obj/item/gripper/proc/remove_item(atom/newloc = FALSE) + if(!wrapped) + return + var/obj/item/old = wrapped + UnregisterSignal(wrapped, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + wrapped = null + switch(newloc) + if(null) + old.moveToNullspace() + if(FALSE) + else + old.forceMove(newloc) + +/obj/item/gripper/proc/unwrap_hook(datum/source) + ASSERT(isitem(source)) + ASSERT(source == wrapped) + remove_item(FALSE) + +/obj/item/gripper/proc/get_item() + return wrapped /obj/item/gripper/CtrlClick(mob/user) - drop_item() + remove_item() return /obj/item/gripper/omni @@ -246,102 +284,46 @@ /obj/item/gripper/attackby(var/obj/item/O, var/mob/user) if(wrapped) // We're interacting with the item inside. If you can hold a cup with 2 fingers and stick a straw in it, you could do that with a gripper and another robotic arm. - wrapped.loc = src.loc var/resolved = wrapped.attackby(O, user) - if(QDELETED(wrapped) || wrapped.loc != src.loc) //Juuuust in case. - wrapped = null if(!resolved && wrapped && O) O.afterattack(wrapped,user,1) - if(QDELETED(wrapped) || wrapped.loc != src.loc) // I don't know of a nicer way to do this. - wrapped = null - if(wrapped) - wrapped.loc = src return resolved return ..() /obj/item/gripper/verb/drop_item() - set name = "Drop Item" set desc = "Release an item from your magnetic gripper." set category = "Robot Commands" if(!wrapped) - //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z - for(var/obj/item/thing in src.contents) - thing.loc = get_turf(src) - return - - if(wrapped.loc != src) - wrapped = null return to_chat(src.loc, "You drop \the [wrapped].") - wrapped.forceMove(get_turf(src)) - wrapped = null - //update_icon() - -/obj/item/gripper/proc/drop_item_nm() - - if(!wrapped) - for(var/obj/item/thing in src.contents) - thing.loc = get_turf(src) - return - - if(wrapped.loc != src) - wrapped = null - return - - wrapped.forceMove(get_turf(src)) - wrapped = null - //update_icon() + remove_item(drop_location()) /obj/item/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack(). force_holder = wrapped.force - wrapped.force = 0.0 - if(QDELETED(wrapped) || wrapped.loc != src.loc) //qdel check here so it doesn't duplicate/spawn ghost items - wrapped = null - else - wrapped.loc = src.loc //To ensure checks pass. - wrapped.attack(M,user) - M.attackby(wrapped, user) //attackby reportedly gets procced by being clicked on, at least according to Anewbe. - if(QDELETED(wrapped) || wrapped.loc != src.loc) - wrapped = null - if(wrapped) //In the event nothing happened to wrapped, go back into the gripper. - wrapped.loc = src - return 1 + wrapped.force = 0 + wrapped.attack(M,user) + M.attackby(wrapped, user) //attackby reportedly gets procced by being clicked on, at least according to Anewbe. + return 1 return 0 /obj/item/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params) - if(!proximity) return // This will prevent them using guns at range but adminbuse can add them directly to modules, so eh. - //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z - if(!wrapped) - for(var/obj/item/thing in src.contents) - wrapped = thing - break if(wrapped) //Already have an item. - //Temporary put wrapped into user so target's attackby() checks pass. - wrapped.loc = user - //Pass the attack on to the target. This might delete/relocate wrapped. - var/resolved = target.attackby(wrapped,user) + var/resolved = target.attackby(wrapped, user) if(!resolved && wrapped && target) wrapped.afterattack(target,user,1) - //wrapped's force was set to zero. This resets it to the value it had before. if(wrapped) wrapped.force = force_holder force_holder = null - //If wrapped was neither deleted nor put into target, put it back into the gripper. - if(wrapped && user && (wrapped.loc == user)) - wrapped.loc = src - else - wrapped = null - return else if(istype(target,/obj/item)) //Check that we're not pocketing a mob. @@ -365,8 +347,7 @@ //We can grab the item, finally. if(grab) to_chat(user, "You collect \the [I].") - I.forceMove(src) - wrapped = I + insert_item(I) return else to_chat(user, "Your gripper cannot hold \the [target].") @@ -376,11 +357,9 @@ if(A.opened) if(A.cell) - wrapped = A.cell - + insert_item(A.cell) A.cell.add_fingerprint(user) A.cell.update_icon() - A.cell.forceMove(src) A.cell = null A.charging = 0 @@ -392,13 +371,10 @@ var/mob/living/silicon/robot/A = target if(A.opened) if(A.cell) - - wrapped = A.cell - + insert_item(A.cell) A.cell.add_fingerprint(user) A.cell.update_icon() A.updateicon() - A.cell.forceMove(src) A.cell = null user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index a0b7b868a39..290e0149af2 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -302,15 +302,16 @@ (istype(I.loc, /obj/item/gripper) && (require_active_module? is_holding(I.loc) : is_module_item(I.loc))) \ ) -/mob/living/silicon/robot/proc/unreference_from_gripper(obj/item/I) +/mob/living/silicon/robot/proc/unreference_from_gripper(obj/item/I, newloc) if(!istype(I.loc, /obj/item/gripper)) - return + return FALSE var/obj/item/gripper/G = I.loc if(!is_module_item(G)) - return - if(G.wrapped != I) - return - G.wrapped = null + return FALSE + if(G.get_item() != I) + return FALSE + G.remove_item(newloc) + return TRUE /mob/living/silicon/robot/temporarily_remove_from_inventory(obj/item/I, flags) if(!is_in_inventory(I)) @@ -318,27 +319,29 @@ . = considered_removable(I) if(!.) return - if(istype(I.loc, /obj/item/gripper)) - var/obj/item/gripper/G = I.loc - G.wrapped = null + if(is_in_gripper(I)) + return unreference_from_gripper(I, null) /mob/living/silicon/robot/transfer_item_to_loc(obj/item/I, newloc, flags) if(is_in_inventory(I) && considered_removable(I)) - unreference_from_gripper(I) + if(is_in_gripper(I)) + return unreference_from_gripper(I, newloc) I.forceMove(newloc) return TRUE return FALSE /mob/living/silicon/robot/transfer_item_to_nullspace(obj/item/I, flags) if(is_in_inventory(I) && considered_removable(I)) - unreference_from_gripper(I) + if(is_in_gripper(I)) + return unreference_from_gripper(I, null) I.moveToNullspace() return TRUE return FALSE /mob/living/silicon/robot/drop_item_to_ground(obj/item/I, flags) if(is_in_inventory(I) && considered_removable(I)) - unreference_from_gripper(I) + if(is_in_gripper(I)) + return unreference_from_gripper(I, drop_location()) I.forceMove(drop_location()) return TRUE return FALSE diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 1a484be7f6a..7c5c2047593 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -127,12 +127,13 @@ if(istype(O,/obj/item/gripper)) var/obj/item/gripper/B = O //B, for Borg. - if(!B.wrapped) + if(!B.get_item()) to_chat(user, "\The [B] is not holding anything.") return 0 else - var/B_held = B.wrapped + var/B_held = B.get_item() to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") + attackby(B_held, user) return 0 diff --git a/config/entries/dbconfig.txt b/config/entries/dbconfig.txt index eb2fc833790..6537f53b1cb 100644 --- a/config/entries/dbconfig.txt +++ b/config/entries/dbconfig.txt @@ -1,5 +1,6 @@ ## Enables SQL/database usage -SQL_ENABLED +## WARNING: A lot of the codebase requires SQL. Not using this is a terrible idea. +#SQL_ENABLED ## SQL address SQL_ADDRESS localhost