diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index ce716bcfe7b..9297735bcf5 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -155,32 +155,36 @@
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
else
- UnarmedAttack(A)
+ UnarmedAttack(A, 1)
return
else // non-adjacent click
if(W)
W.afterattack(A,src,0,params) // 0: not Adjacent
else
- if((LASER in mutations) && a_intent == "harm")
- LaserEyes(A) // moved into a proc below
- else if(TK in mutations)
- switch(get_dist(src,A))
- if(1 to 5) // not adjacent may mean blocked by window
- next_move += 2
- if(5 to 7)
- next_move += 5
- if(8 to 15)
- next_move += 10
- if(16 to 128)
- return
- A.attack_tk(src)
+ RangedAttack(A, params)
return
-// attack_hand, attack_paw, etc
-/mob/proc/UnarmedAttack(var/atom/A)
+// translates into attack_hand, attack_paw, etc. proximity_flag should NOT be true if you are not adjacent (telekinesis)
+/mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag)
return
+// unarmed and at range - laser eyes, telekinesis, and mob special abilities
+/mob/proc/RangedAttack(var/atom/A, var/params)
+ if((LASER in mutations) && a_intent == "harm")
+ LaserEyes(A) // moved into a proc below
+ else if(TK in mutations)
+ switch(get_dist(src,A))
+ if(1 to 5) // not adjacent may mean blocked by window
+ next_move += 2
+ if(5 to 7)
+ next_move += 5
+ if(8 to 15)
+ next_move += 10
+ if(16 to 128)
+ return
+ A.attack_tk(src)
+
// hand_h, hand_p, etc - these are almost entirely unused
/mob/proc/RestrainedClickOn(var/atom/A)
return
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 7f06ab0d186..8a8eb516580 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -1,6 +1,15 @@
// Humans
-/mob/living/carbon/human/UnarmedAttack(var/atom/A)
+/mob/living/carbon/human/UnarmedAttack(var/atom/A, var/proximity)
+ var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
+
+ // Special glove functions:
+ // If the gloves do anything, have them return 1 to stop
+ // normal attack_hand() here.
+
+ if(proximity && istype(G) && G.Touch(A,1))
+ return
+
A.attack_hand(src)
/atom/proc/attack_hand(mob/user as mob)
return
@@ -10,6 +19,26 @@
/atom/proc/hand_h(mob/user as mob) //human (hand) - restrained
return
+/mob/living/carbon/human/RangedAttack(var/atom/A)
+ var/obj/item/clothing/gloves/G = gloves
+ if((LASER in mutations) && a_intent == "harm")
+ LaserEyes(A) // moved into a proc below
+
+ else if(istype(G) && G.Touch(A,0)) // for magic gloves
+ return
+
+ else if(TK in mutations)
+ switch(get_dist(src,A))
+ if(1 to 5) // not adjacent may mean blocked by window
+ next_move += 2
+ if(5 to 7)
+ next_move += 5
+ if(8 to 15)
+ next_move += 10
+ if(16 to 128)
+ return
+ A.attack_tk(src)
+
// Animals & All Unspecified
/mob/living/UnarmedAttack(var/atom/A)
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index 247ebce905b..379a0c2e89a 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -53,7 +53,7 @@
layer = 20
var/last_throw = 0
- var/obj/focus = null
+ var/atom/movable/focus = null
var/mob/living/host = null
@@ -114,10 +114,8 @@
proc/focus_object(var/obj/target, var/mob/living/user)
if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
- if(target.anchored)
- target.attack_hand(user) // you can use shit now!
- return//No throwing anchored things
- if(!isturf(target.loc))
+ if(target.anchored || !isturf(target.loc))
+ del src
return
focus = target
update_icon()
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index b5157bd4fcd..7a9b02e5b6a 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -180,15 +180,6 @@
A.transfer_ai("INACTIVE","AICARD",src,user)
return
- attack_hand(var/mob/user as mob)
- if(ishuman(user))//Checks to see if they are ninja
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- if(user:wear_suit:s_control)
- user:wear_suit:transfer_ai("INACTIVE","NINJASUIT",src,user)
- else
- user << "\red ERROR: \black Remote access channel disabled."
- return
-
/*
This is a good place for AI-related object verbs so I'm sticking it here.
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index aa5d2b48d5b..4c382dce3a4 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -60,14 +60,6 @@
if(..())
return
- if(ishuman(user))//Checks to see if they are ninja
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- if(user:wear_suit:s_control)
- user:wear_suit.transfer_ai("AIFIXER","NINJASUIT",src,user)
- else
- user << "\red ERROR: \black Remote access channel disabled."
- return
-
user.set_machine(src)
var/dat = ""
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 8fe160b2827..8a088f3cb86 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -417,11 +417,6 @@
/obj/mecha/attack_hand(mob/user as mob)
src.log_message("Attack by hand/paw. Attacker - [user].",1)
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MECHA",src,user:wear_suit)
- return
-
if ((HULK in user.mutations) && !prob(src.deflect_chance))
src.take_damage(15)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 5bfd81a1c00..8dbbfada292 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -59,6 +59,10 @@ BLIND // can't see anything
..()
return
+// Called just before an attack_hand(), in mob/UnarmedAttack()
+/obj/item/clothing/gloves/proc/Touch(var/atom/A, var/proximity)
+ return 0 // return 1 to cancel attack_hand()
+
//Head
/obj/item/clothing/head
name = "head"
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index 7b0825f414d..b5845e7bfd2 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -1,14 +1,3 @@
-/obj/item/clothing/gloves/space_ninja
- desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
- name = "ninja gloves"
- icon_state = "s-ninja"
- item_state = "s-ninja"
- siemens_coefficient = 0
- var/draining = 0
- var/candrain = 0
- var/mindrain = 200
- var/maxdrain = 400
-
/obj/item/clothing/gloves/captain
desc = "Regal blue gloves, with a nice gold trim. Swanky."
name = "captain's gloves"
diff --git a/code/modules/clothing/gloves/ninja.dm b/code/modules/clothing/gloves/ninja.dm
new file mode 100644
index 00000000000..6abc883c417
--- /dev/null
+++ b/code/modules/clothing/gloves/ninja.dm
@@ -0,0 +1,110 @@
+/*
+ Dear ninja gloves
+
+ This isn't because I like you
+ this is because your father is a bastard
+
+ ...
+ I guess you're a little cool.
+ -Sayu
+*/
+
+/obj/item/clothing/gloves/space_ninja
+ desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
+ name = "ninja gloves"
+ icon_state = "s-ninja"
+ item_state = "s-ninja"
+ siemens_coefficient = 0
+ var/draining = 0
+ var/candrain = 0
+ var/mindrain = 200
+ var/maxdrain = 400
+
+/*
+ This runs the gamut of what ninja gloves can do
+ The other option would be a dedicated ninja touch bullshit proc on everything
+
+ For the drain proc, see events/ninja.dm
+*/
+/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity)
+ if(!candrain || draining) return 0
+
+ var/mob/living/carbon/human/H = loc
+ if(!istype(H)) return 0 // what
+ var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
+ if(!istype(suit)) return 0
+ if(isturf(A)) return 0
+
+ if(!proximity) // todo: you could add ninja stars or computer hacking here
+ return 0
+
+ // Move an AI into and out of things
+ if(istype(A,/mob/living/silicon/ai))
+ if(suit.s_control)
+ A.add_fingerprint(H)
+ suit.transfer_ai("AICORE", "NINJASUIT", A, H)
+ return 1
+ else
+ H << "\red ERROR: \black Remote access channel disabled."
+ return 0
+
+ if(istype(A,/obj/structure/AIcore/deactivated))
+ if(suit.s_control)
+ A.add_fingerprint(H)
+ suit.transfer_ai("INACTIVE","NINJASUIT",A, H)
+ return 1
+ else
+ H << "\red ERROR: \black Remote access channel disabled."
+ return 0
+ if(istype(A,/obj/machinery/computer/aifixer))
+ if(suit.s_control)
+ A.add_fingerprint(H)
+ suit.transfer_ai("AIFIXER","NINJASUIT",A, H)
+ return 1
+ else
+ H << "\red ERROR: \black Remote access channel disabled."
+ return 0
+
+ // steal energy from powered things
+ if(istype(A,/mob/living/silicon/robot))
+ A.add_fingerprint(H)
+ drain("CYBORG",A,suit)
+ return 1
+ if(istype(A,/obj/machinery/power/apc))
+ A.add_fingerprint(H)
+ drain("APC",A,suit)
+ return 1
+ if(istype(A,/obj/structure/cable))
+ A.add_fingerprint(H)
+ drain("WIRE",A,suit)
+ return 1
+ if(istype(A,/obj/structure/grille))
+ var/obj/structure/cable/C = locate() in A.loc
+ if(C)
+ drain("WIRE",C,suit)
+ return 1
+ if(istype(A,/obj/machinery/power/smes))
+ A.add_fingerprint(H)
+ drain("SMES",A,suit)
+ return 1
+ if(istype(A,/obj/mecha))
+ A.add_fingerprint(H)
+ drain("MECHA",A,suit)
+ return 1
+
+ // download research
+ if(istype(A,/obj/machinery/computer/rdconsole))
+ A.add_fingerprint(H)
+ drain("RESEARCH",A,suit)
+ return 1
+ if(istype(A,/obj/machinery/r_n_d/server))
+ A.add_fingerprint(H)
+ var/obj/machinery/r_n_d/server/S = A
+ if(S.disabled)
+ return 1
+ if(S.shocked)
+ S.shock(H,50)
+ return 1
+ drain("RESEARCH",A,suit)
+ return 1
+
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 4a1efcfe614..2201c22cda6 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -406,16 +406,6 @@ var/list/ai_list = list()
O.show_message(text("\red [] took a swipe at []!", M, src), 1)
return
-/mob/living/silicon/ai/attack_hand(mob/living/carbon/M as mob)
- if(ishuman(M))//Checks to see if they are ninja
- if(istype(M:gloves, /obj/item/clothing/gloves/space_ninja)&&M:gloves:candrain&&!M:gloves:draining)
- if(M:wear_suit:s_control)
- M:wear_suit:transfer_ai("AICORE", "NINJASUIT", src, M)
- else
- M << "\red ERROR: \black Remote access channel disabled."
- return
-
-
/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index e7fee9d1821..07aa7c7d67c 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -734,12 +734,6 @@
user.visible_message("[user] pets [src]!", \
"You pet [src]!")
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("CYBORG",src,user:wear_suit)
- return
-
-
/mob/living/silicon/robot/attack_paw(mob/user)
return attack_hand(user)
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 09ce2053a17..5f91e9df885 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -452,11 +452,6 @@
return
if(stat & (BROKEN|MAINT))
return
-
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("APC",src,user:wear_suit)
- return
// do APC interaction
user.set_machine(src)
src.interact(user)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 01a130b43be..0085de82d59 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -109,11 +109,6 @@
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
return powernet
-/obj/structure/cable/attack_hand(mob/user)
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("WIRE",src,user:wear_suit)
- return
/obj/structure/cable/attack_tk(mob/user)
return
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 055e62d9ca0..0d64b68dc9c 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -63,8 +63,11 @@
/obj/item/weapon/cell/attack_self(mob/user as mob)
src.add_fingerprint(user)
if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("CELL",src,user:wear_suit)
+ var/mob/living/carbon/human/H = user
+ var/obj/item/clothing/gloves/space_ninja/SNG = H.gloves
+ if(!istype(SNG) || !SNG.candrain || !SNG.draining) return
+
+ SNG.drain("CELL",src,H.wear_suit)
return
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index cbb9ccb90d1..e5f08b47f1e 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -168,11 +168,6 @@
/obj/machinery/power/smes/attack_hand(mob/user)
add_fingerprint(user)
if(stat & BROKEN) return
-
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("SMES",src,user:wear_suit)
- return
interact(user)
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 4da8960b080..1fd7235f7bb 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -545,11 +545,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(stat & (BROKEN|NOPOWER))
return
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("RESEARCH",src,user:wear_suit)
- return
-
user.set_machine(src)
var/dat = ""
files.RefreshResearch()
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 3e458226f1a..b56dcf8022d 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -154,19 +154,13 @@
del(src)
return 1
-/obj/machinery/r_n_d/server/attack_hand(mob/user as mob)
+/obj/machinery/r_n_d/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves.
if (disabled)
return
if (shocked)
shock(user,50)
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("RESEARCH",src,user:wear_suit)
return
-
-
-
/obj/machinery/r_n_d/server/centcom
name = "Centcom Central R&D Database"
server_id = -1
diff --git a/tgstation.dme b/tgstation.dme
index fad66a9cc54..64b10e41a95 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -713,6 +713,7 @@
#include "code\modules\clothing\gloves\boxing.dm"
#include "code\modules\clothing\gloves\color.dm"
#include "code\modules\clothing\gloves\miscellaneous.dm"
+#include "code\modules\clothing\gloves\ninja.dm"
#include "code\modules\clothing\head\collectable.dm"
#include "code\modules\clothing\head\hardhat.dm"
#include "code\modules\clothing\head\helmet.dm"