From 11318bfc3ccead4f6b98f8c158c06f8a2f6f5eb1 Mon Sep 17 00:00:00 2001
From: nemvar <47324920+nemvar@users.noreply.github.com>
Date: Fri, 16 Aug 2019 20:56:25 +0200
Subject: [PATCH] Arm implants now support more than two hands. (#45843)
* Adds multiple hand support to arm implants
* Kills those nasty static lists.
* Update inventory.dm
---
code/__DEFINES/inventory.dm | 4 ++
code/modules/flufftext/Hallucination.dm | 4 +-
code/modules/mob/inventory.dm | 42 +++++---------------
code/modules/mob/living/say.dm | 4 +-
code/modules/surgery/organs/augments_arms.dm | 35 ++++++++--------
5 files changed, 37 insertions(+), 52 deletions(-)
diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm
index 0e902ff1706..cd6ec711ce2 100644
--- a/code/__DEFINES/inventory.dm
+++ b/code/__DEFINES/inventory.dm
@@ -128,6 +128,10 @@
#define NECK (1<<11)
#define FULL_BODY (~0)
+//defines for the index of hands
+#define LEFT_HANDS 1
+#define RIGHT_HANDS 2
+
//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird
#define NO_FEMALE_UNIFORM 0
#define FEMALE_UNIFORM_FULL 1
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index c0196504e58..86eae47f8bf 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -429,11 +429,11 @@ GLOBAL_LIST_INIT(hallucination_list, list(
var/mob/living/carbon/human/H = pick(mob_pool)
feedback_details += " Mob: [H.real_name]"
- var/free_hand = H.get_empty_held_index_for_side(side = "left")
+ var/free_hand = H.get_empty_held_index_for_side(LEFT_HANDS)
if(free_hand)
side = "left"
else
- free_hand = H.get_empty_held_index_for_side(side = "right")
+ free_hand = H.get_empty_held_index_for_side(RIGHT_HANDS)
if(free_hand)
side = "right"
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 71f883131f1..5923179daec 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -51,46 +51,24 @@
//Finds the first available (null) index OR all available (null) indexes in held_items based on a side.
//Lefts: 1, 3, 5, 7...
//Rights:2, 4, 6, 8...
-/mob/proc/get_empty_held_index_for_side(side = "left", all = FALSE)
- var/start = 0
- var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE)
- var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent"
- if(lefts[side])
- start = 1
- else if(rights[side])
- start = 2
- if(!start)
- return FALSE
- var/list/empty_indexes
- for(var/i in start to held_items.len step 2)
+/mob/proc/get_empty_held_index_for_side(side = LEFT_HANDS, all = FALSE)
+ var/list/empty_indexes = all ? list() : null
+ for(var/i in (side == LEFT_HANDS) ? 1 : 2 to held_items.len step 2)
if(!held_items[i])
if(!all)
return i
- if(!empty_indexes)
- empty_indexes = list()
empty_indexes += i
return empty_indexes
//Same as the above, but returns the first or ALL held *ITEMS* for the side
-/mob/proc/get_held_items_for_side(side = "left", all = FALSE)
- var/start = 0
- var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE)
- var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent"
- if(lefts[side])
- start = 1
- else if(rights[side])
- start = 2
- if(!start)
- return FALSE
- var/list/holding_items
- for(var/i in start to held_items.len step 2)
+/mob/proc/get_held_items_for_side(side = LEFT_HANDS, all = FALSE)
+ var/list/holding_items = all ? list() : null
+ for(var/i in (side == LEFT_HANDS) ? 1 : 2 to held_items.len step 2)
var/obj/item/I = held_items[i]
if(I)
if(!all)
return I
- if(!holding_items)
- holding_items = list()
holding_items += I
return holding_items
@@ -193,11 +171,11 @@
//Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(obj/item/I)
- return put_in_hand(I, get_empty_held_index_for_side("l"))
+ return put_in_hand(I, get_empty_held_index_for_side(LEFT_HANDS))
//Puts the item into the first available right hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_r_hand(obj/item/I)
- return put_in_hand(I, get_empty_held_index_for_side("r"))
+ return put_in_hand(I, get_empty_held_index_for_side(RIGHT_HANDS))
/mob/proc/put_in_hand_check(obj/item/I)
return FALSE //nonliving mobs don't have hands
@@ -247,9 +225,9 @@
if(put_in_active_hand(I, forced))
return TRUE
- var/hand = get_empty_held_index_for_side("l")
+ var/hand = get_empty_held_index_for_side(LEFT_HANDS)
if(!hand)
- hand = get_empty_held_index_for_side("r")
+ hand = get_empty_held_index_for_side(RIGHT_HANDS)
if(hand)
if(put_in_hand(I, hand, forced))
return TRUE
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index cac59d006f3..536b11fbee6 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -370,12 +370,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(MODE_WHISPER)
return ITALICS
if(MODE_R_HAND)
- for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
+ for(var/obj/item/r_hand in get_held_items_for_side(RIGHT_HANDS, all = TRUE))
if (r_hand)
return r_hand.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
if(MODE_L_HAND)
- for(var/obj/item/l_hand in get_held_items_for_side("l", all = TRUE))
+ for(var/obj/item/l_hand in get_held_items_for_side(LEFT_HANDS, all = TRUE))
if (l_hand)
return l_hand.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index fb9b11174c9..359fa06b8e7 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -98,23 +98,26 @@
var/obj/item/assembly/flash/F = holder
F.set_light(7)
- var/obj/item/arm_item = owner.get_active_held_item()
-
- if(arm_item)
- if(!owner.dropItemToGround(arm_item))
- to_chat(owner, "Your [arm_item] interferes with [src]!")
+ var/side = zone == BODY_ZONE_R_ARM? "r" : "l"
+ var/hand = owner.get_empty_held_index_for_side(side)
+ if(hand)
+ owner.put_in_hand(holder, hand)
+ else
+ var/list/hand_items = owner.get_held_items_for_side(side, all = TRUE)
+ var/success = FALSE
+ var/list/failure_message = list()
+ for(var/i in 1 to hand_items.len) //Can't just use *in* here.
+ var/I = hand_items[i]
+ if(!owner.dropItemToGround(I))
+ failure_message += "Your [I] interferes with [src]!"
+ continue
+ to_chat(owner, "You drop [I] to activate [src]!")
+ success = owner.put_in_hand(holder, owner.get_empty_held_index_for_side(side))
+ break
+ if(!success)
+ for(var/i in failure_message)
+ to_chat(owner, i)
return
- else
- to_chat(owner, "You drop [arm_item] to activate [src]!")
-
- var/result = (zone == BODY_ZONE_R_ARM ? owner.put_in_r_hand(holder) : owner.put_in_l_hand(holder))
- if(!result)
- to_chat(owner, "Your [name] fails to activate!")
- return
-
- // Activate the hand that now holds our item.
- owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow
-
owner.visible_message("[owner] extends [holder] from [owner.p_their()] [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.",
"You extend [holder] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.",
"You hear a short mechanical noise.")