diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index e91643019e8..354e3771215 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -85,6 +85,7 @@ var/const/tk_maxrange = 15
//stops TK grabs being equipped anywhere but into hands
/obj/item/tk_grab/equipped(var/mob/user, var/slot)
+ ..()
if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
qdel(src)
return
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 055176246c1..a7de8f96572 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -71,6 +71,16 @@
// Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
var/list/sprite_sheets_obj = list()
+/obj/item/equipped()
+ ..()
+ var/mob/M = loc
+ if(!istype(M))
+ return
+ if(M.l_hand)
+ M.l_hand.update_held_icon()
+ if(M.r_hand)
+ M.r_hand.update_held_icon()
+
/obj/item/Destroy()
if(ismob(loc))
var/mob/m = loc
@@ -89,7 +99,7 @@
var/mob/M = src.loc
if(M.l_hand == src)
M.update_inv_l_hand()
- if(M.r_hand == src)
+ else if(M.r_hand == src)
M.update_inv_r_hand()
/obj/item/ex_act(severity)
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index 36a6d4f8055..b5b87674099 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -20,6 +20,7 @@
disrupt()
/obj/item/device/chameleon/equipped()
+ ..()
disrupt()
/obj/item/device/chameleon/attack_self()
diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm
index 2bc8830ad88..dbc519e117b 100644
--- a/code/game/objects/items/weapons/material/twohanded.dm
+++ b/code/game/objects/items/weapons/material/twohanded.dm
@@ -27,17 +27,19 @@
var/base_name
var/unwielded_force_divisor = 0.25
-/obj/item/weapon/material/twohanded/proc/unwield()
- wielded = 0
- force = force_unwielded
- name = "[base_name]"
- update_icon()
-
-/obj/item/weapon/material/twohanded/proc/wield()
- wielded = 1
- force = force_wielded
- name = "[base_name] (Wielded)"
+/obj/item/weapon/material/twohanded/update_held_icon()
+ var/mob/living/M = loc
+ if(istype(M) && !issmall(M) && ((M.r_hand == src && !M.l_hand) || (M.l_hand == src && !M.r_hand)))
+ wielded = 1
+ force = force_wielded
+ name = "[base_name] (Wielded)"
+ update_icon()
+ else
+ wielded = 0
+ force = force_unwielded
+ name = "[base_name]"
update_icon()
+ ..()
/obj/item/weapon/material/twohanded/update_force()
base_name = name
@@ -55,22 +57,6 @@
..()
update_icon()
-/obj/item/weapon/material/twohanded/mob_can_equip(M as mob, slot)
- //Cannot equip wielded items.
- if(wielded)
- M << "Unwield the [base_name] first!"
- return 0
-
- return ..()
-
-/obj/item/weapon/material/twohanded/dropped(mob/user as mob)
- //handles unwielding a twohanded weapon when dropped as well as clearing up the offhand
- if(user)
- var/obj/item/weapon/material/twohanded/O = user.get_inactive_hand()
- if(istype(O))
- O.unwield()
- return unwield()
-
//Allow a small chance of parrying melee attacks when wielded - maybe generalize this to other weapons someday
/obj/item/weapon/material/twohanded/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(wielded && default_parry_check(user, attacker, damage_source) && prob(15))
@@ -83,68 +69,6 @@
icon_state = "[base_icon][wielded]"
item_state = icon_state
-/obj/item/weapon/material/twohanded/pickup(mob/user)
- unwield()
-
-/obj/item/weapon/material/twohanded/attack_self(mob/user as mob)
-
- ..()
-
- if(istype(user, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
- if(issmall(H))
- user << "It's too heavy for you to wield fully."
- return
- else
- return
-
- if(wielded) //Trying to unwield it
- unwield()
- user << "You are now carrying the [name] with one hand."
- if (src.unwieldsound)
- playsound(src.loc, unwieldsound, 50, 1)
-
- var/obj/item/weapon/material/twohanded/offhand/O = user.get_inactive_hand()
- if(O && istype(O))
- O.unwield()
-
- else //Trying to wield it
- if(user.get_inactive_hand())
- user << "You need your other hand to be empty"
- return
- wield()
- user << "You grab the [base_name] with both hands."
- if (src.wieldsound)
- playsound(src.loc, wieldsound, 50, 1)
-
- var/obj/item/weapon/material/twohanded/offhand/O = new(user) ////Let's reserve his other hand~
- O.name = "[base_name] - offhand"
- O.desc = "Your second grip on the [base_name]."
- user.put_in_inactive_hand(O)
-
- if(istype(user,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
- H.update_inv_l_hand()
- H.update_inv_r_hand()
-
- return
-
-///////////OFFHAND///////////////
-/obj/item/weapon/material/twohanded/offhand
- w_class = 5
- icon_state = "offhand"
- name = "offhand"
- default_material = "placeholder"
-
-/obj/item/weapon/material/twohanded/offhand/unwield()
- qdel(src)
-
-/obj/item/weapon/material/twohanded/offhand/wield()
- qdel(src)
-
-/obj/item/weapon/material/twohanded/offhand/update_icon()
- return
-
/*
* Fireaxe
*/
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index c998ad1bd07..e4472e2450f 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -216,7 +216,7 @@ var/list/slot_equipment_priority = list( \
wear_mask = null
update_inv_wear_mask(0)
return
-
+
/mob/proc/isEquipped(obj/item/I)
if(!I)
return 0
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 50e04187662..1a2b89f0be3 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -140,12 +140,6 @@
return
/mob/living/carbon/swap_hand()
- var/obj/item/item_in_hand = src.get_active_hand()
- if(item_in_hand) //this segment checks if the item in your hand is twohanded.
- if(istype(item_in_hand,/obj/item/weapon/material/twohanded))
- if(item_in_hand:wielded == 1)
- usr << "Your other hand is too busy holding the [item_in_hand.name]"
- return
src.hand = !( src.hand )
if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
if(hand) //This being 1 means the left hand is in use
@@ -154,10 +148,6 @@
else
hud_used.l_hand_hud_object.icon_state = "l_hand_inactive"
hud_used.r_hand_hud_object.icon_state = "r_hand_active"
- /*if (!( src.hand ))
- src.hands.set_dir(NORTH)
- else
- src.hands.set_dir(SOUTH)*/
return
/mob/living/carbon/proc/activate_hand(var/selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 2f0160f35e6..7e1057d9d9e 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -171,9 +171,15 @@ This saves us from having to call add_fingerprint() any time something is put in
update_inv_legcuffed()
else if (W == r_hand)
r_hand = null
+ if(l_hand)
+ l_hand.update_held_icon()
+ update_inv_l_hand()
update_inv_r_hand()
else if (W == l_hand)
l_hand = null
+ if(r_hand)
+ r_hand.update_held_icon()
+ update_inv_l_hand()
update_inv_l_hand()
else
return 0
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
index af8b93e6206..0c4df2d22e5 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
@@ -70,6 +70,7 @@ var/const/MAX_ACTIVE_TIME = 400
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
+ ..()
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 168698385b7..1dce789df2f 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -64,6 +64,8 @@
var/list/burst_accuracy = list(0) //allows for different accuracies for each shot in a burst. Applied on top of accuracy
var/list/dispersion = list(0)
var/mode_name = null
+ var/requires_two_hands
+ var/wielded_icon = "gun_wielded"
var/next_fire_time = 0
@@ -87,17 +89,28 @@
if(isnull(scoped_accuracy))
scoped_accuracy = accuracy
+/obj/item/weapon/gun/update_held_icon()
+ if(requires_two_hands)
+ var/mob/living/M = loc
+ if(istype(M))
+ if((M.l_hand == src && !M.r_hand) || (M.r_hand == src && !M.l_hand))
+ item_state = wielded_icon
+ else
+ item_state = initial(item_state)
+ update_icon() // In case item_state is set somewhere else.
+ ..()
+
//Checks whether a given mob can use the gun
//Any checks that shouldn't result in handle_click_empty() being called if they fail should go here.
//Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there.
/obj/item/weapon/gun/proc/special_check(var/mob/user)
+
if(!istype(user, /mob/living))
return 0
if(!user.IsAdvancedToolUser())
return 0
var/mob/living/M = user
-
if(HULK in M.mutations)
M << "Your fingers are much too large for the trigger guard!"
return 0
@@ -161,6 +174,14 @@
user.setMoveCooldown(shoot_time) //no moving while shooting either
next_fire_time = world.time + shoot_time
+ var/held_acc_mod = 0
+ var/held_disp_mod = 0
+ if(requires_two_hands)
+ update_held_icon()
+ if((user.l_hand == src && user.r_hand) || (user.r_hand == src && user.l_hand))
+ held_acc_mod = -3
+ held_disp_mod = 3
+
//actually attempt to shoot
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
for(var/i in 1 to burst)
@@ -169,8 +190,8 @@
handle_click_empty(user)
break
- var/acc = burst_accuracy[min(i, burst_accuracy.len)]
- var/disp = dispersion[min(i, dispersion.len)]
+ var/acc = burst_accuracy[min(i, burst_accuracy.len)] + held_acc_mod
+ var/disp = dispersion[min(i, dispersion.len)] + held_disp_mod
process_accuracy(projectile, user, target, acc, disp)
if(pointblank)
diff --git a/html/changelogs/Zuhayr-twohands.yml b/html/changelogs/Zuhayr-twohands.yml
new file mode 100644
index 00000000000..011e0c18cc9
--- /dev/null
+++ b/html/changelogs/Zuhayr-twohands.yml
@@ -0,0 +1,5 @@
+author: Zuhayr
+delete-after: True
+changes:
+ - rscadd: "Added functionality for two-handed guns; these guns will give an accuracy penalty if fired without an empty offhand."
+ - rscadd: "Unified two-handed melee weapons with the above; while the offhand is empty, the weapon will count as wielded."
\ No newline at end of file
diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi
index 401e5eae6db..b4e58f68451 100644
Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ
diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi
index 7c2cc847163..0e8bb9118cc 100644
Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ