(probably) fixes some cyborg + window inventory bugs (#4310)

* start

* wild

* wacky

* e

* Update inventory.dm

Co-authored-by: VM_USER <VM_USER>
This commit is contained in:
silicons
2022-08-04 04:00:18 -07:00
committed by GitHub
parent 9371bec23b
commit f536422f68
11 changed files with 87 additions and 97 deletions

View File

@@ -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 ..()

View File

@@ -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"

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -546,6 +546,9 @@ var/list/name_to_material
var/window_count = 0
for (var/obj/structure/window/check_window in user.loc)
window_count++
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++

View File

@@ -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)

View File

@@ -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)
. += "<span class='notice'>\The [src] is holding \the [wrapped].</span>"
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, "<span class='danger'>You drop \the [wrapped].</span>")
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.force = 0
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
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)
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, "<span class='danger'>Your gripper cannot hold \the [target].</span>")
@@ -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("<span class='danger'>[user] removes the power cell from [A]!</span>", "You remove the power cell.")

View File

@@ -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

View File

@@ -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

View File

@@ -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