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