diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 1883df6e8e..5d35da5382 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -68,4 +68,6 @@
#define MOVESPEED_ID_SHOVE "SHOVE"
-#define MOVESPEED_ID_MKULTRA "MKULTRA"
\ No newline at end of file
+#define MOVESPEED_ID_MKULTRA "MKULTRA"
+
+#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
\ No newline at end of file
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index f42948f4ae..40d3550d1b 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -90,6 +90,9 @@
#define STATUS_EFFECT_NO_COMBAT_MODE /datum/status_effect/no_combat_mode //Wont allow combat mode and will disable it
#define STATUS_EFFECT_MESMERIZE /datum/status_effect/no_combat_mode/mesmerize //Just reskinned no_combat_mode
+
+#define STATUS_EFFECT_ELECTROSTAFF /datum/status_effect/electrostaff //slows down victim
+
/////////////
// NEUTRAL //
/////////////
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index c694f27d64..ae535b1db3 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -609,6 +609,19 @@
icon_state = "ichorial_stain"
alerttooltipstyle = "clockcult"
+/datum/status_effect/electrostaff
+ id = "electrostaff"
+ alert_type = null
+ status_type = STATUS_EFFECT_REPLACE
+
+/datum/status_effect/electrostaff/on_creation(mob/living/new_owner, set_duration)
+ if(isnum(set_duration))
+ duration = set_duration
+ . = ..()
+ owner.add_movespeed_modifier(MOVESPEED_ID_ELECTROSTAFF, multiplicative_slowdown = 1, movetypes = GROUND)
+
+/datum/status_effect/electrostaff/on_remove()
+ owner.remove_movespeed_modifier(MOVESPEED_ID_ELECTROSTAFF)
//GOLEM GANG
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 29921c4584..aa97aa821a 100755
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -16,6 +16,7 @@
/obj/item/melee/baton,
/obj/item/ammo_box/magazine/recharge,
/obj/item/modular_computer,
+ /obj/item/twohanded/electrostaff,
/obj/item/gun/ballistic/automatic/magrifle))
/obj/machinery/recharger/RefreshParts()
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index 0cd60804db..24cb265093 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -24,7 +24,7 @@
* Twohanded
*/
/obj/item/twohanded
- var/wielded = 0
+ var/wielded = FALSE
var/force_unwielded // default to null, the number force will be set to on unwield()
var/force_wielded // same as above but for wield()
var/wieldsound = null
@@ -1017,6 +1017,259 @@
user.client.pixel_x = 0
user.client.pixel_y = 0
+/obj/item/twohanded/electrostaff
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "electrostaff"
+ item_state = "electrostaff"
+ lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
+ name = "riot suppression electrostaff"
+ desc = "A large quarterstaff, with massive silver electrodes mounted at the end."
+ w_class = WEIGHT_CLASS_HUGE
+ slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
+ force_unwielded = 5
+ force_wielded = 10
+ throwforce = 15 //if you are a madman and finish someone off with this, power to you.
+ throw_speed = 1
+ item_flags = NO_MAT_REDEMPTION | SLOWS_WHILE_IN_HAND
+ block_chance = 30
+ attack_verb = list("struck", "beaten", "thwacked", "pulped")
+ total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on)
+ var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high
+ var/on = FALSE
+ var/can_block_projectiles = FALSE //can't block guns
+ var/lethal_cost = 400 //10000/400*20 = 500. decent enough?
+ var/lethal_damage = 20
+ var/lethal_stam_cost = 4
+ var/stun_cost = 333 //10000/333*25 = 750. stunbatons are at time of writing 10000/1000*49 = 490.
+ var/stun_status_effect = STATUS_EFFECT_ELECTROSTAFF //a small slowdown effect
+ var/stun_stamdmg = 40
+ var/stun_status_duration = 25
+ var/stun_stam_cost = 3.5
+
+/obj/item/twohanded/electrostaff/Initialize(mapload)
+ . = ..()
+ if(ispath(cell))
+ cell = new cell
+
+/obj/item/twohanded/electrostaff/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/twohanded/electrostaff/get_cell()
+ . = cell
+ if(iscyborg(loc))
+ var/mob/living/silicon/robot/R = loc
+ . = R.get_cell()
+
+/obj/item/twohanded/electrostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!on)
+ return FALSE
+ if((attack_type == PROJECTILE_ATTACK) && !can_block_projectiles)
+ return FALSE
+ return ..()
+
+/obj/item/twohanded/electrostaff/proc/min_hitcost()
+ return min(stun_cost, lethal_cost)
+
+/obj/item/twohanded/electrostaff/proc/turn_on(mob/user, silent = FALSE)
+ if(on)
+ return
+ if(!cell)
+ if(user)
+ to_chat(user, "[src] has no cell.")
+ return
+ if(cell.charge < min_hitcost())
+ if(user)
+ to_chat(user, "[src] is out of charge.")
+ return
+ on = TRUE
+ START_PROCESSING(SSobj, src)
+ if(user)
+ to_chat(user, "You turn [src] on.")
+ update_icon()
+ if(!silent)
+ playsound(src, "sparks", 75, 1, -1)
+
+/obj/item/twohanded/electrostaff/proc/turn_off(mob/user, silent = FALSE)
+ if(!on)
+ return
+ if(user)
+ to_chat(user, "You turn [src] off.")
+ on = FALSE
+ STOP_PROCESSING(SSobj, src)
+ update_icon()
+ if(!silent)
+ playsound(src, "sparks", 75, 1, -1)
+
+/obj/item/twohanded/electrostaff/proc/toggle(mob/user, silent = FALSE)
+ if(on)
+ turn_off(user, silent)
+ else
+ turn_on(user, silent)
+
+/obj/item/twohanded/electrostaff/wield(mob/user)
+ . = ..()
+ if(wielded)
+ turn_on(user)
+ add_fingerprint(user)
+
+/obj/item/twohanded/electrostaff/unwield(mob/user)
+ . = ..()
+ if(!wielded)
+ turn_off(user)
+ add_fingerprint(user)
+
+/obj/item/twohanded/electrostaff/update_icon()
+ . = ..()
+ if(!wielded)
+ icon_state = "electrostaff_3"
+ item_state = "electrostaff"
+ else
+ icon_state = item_state = (on? "electrostaff_1" : "electrostaff_3")
+ set_light(7, on? 1 : 0, LIGHT_COLOR_CYAN)
+
+/obj/item/twohanded/electrostaff/examine(mob/living/user)
+ . = ..()
+ if(cell)
+ . += "The cell charge is [round(cell.percent())]%."
+ else
+ . += "There is no cell installed!"
+
+/obj/item/twohanded/electrostaff/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/stock_parts/cell))
+ var/obj/item/stock_parts/cell/C = W
+ if(cell)
+ to_chat(user, "[src] already has a cell!")
+ else
+ if(C.maxcharge < min_hit_cost())
+ to_chat(user, "[src] requires a higher capacity cell.")
+ return
+ if(!user.transferItemToLoc(W, src))
+ return
+ cell = C
+ to_chat(user, "You install a cell in [src].")
+
+ else if(W.tool_behaviour == TOOL_SCREWDRIVER)
+ if(cell)
+ cell.update_icon()
+ cell.forceMove(get_turf(src))
+ cell = null
+ to_chat(user, "You remove the cell from [src].")
+ turn_off(user, TRUE)
+ else
+ return ..()
+
+/obj/item/twohanded/electrostaff/process()
+ deductcharge(50) //Wasteful!
+
+/obj/item/twohanded/electrostaff/proc/min_hit_cost()
+ return min(lethal_cost, stun_cost)
+
+/obj/item/twohanded/electrostaff/proc/deductcharge(amount)
+ var/obj/item/stock_parts/cell/C = get_cell()
+ if(!C)
+ turn_off()
+ return FALSE
+ C.use(min(amount, C.charge))
+ if(QDELETED(src))
+ return FALSE
+ if(C.charge < min_hit_cost())
+ turn_off()
+
+/obj/item/twohanded/electrostaff/attack(mob/living/target, mob/living/user)
+ if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes it impossible to baton in stamina softcrit
+ to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto
+ return //CIT CHANGE - ditto
+ if(on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
+ clowning_around(user) //ouch!
+ return
+ if(iscyborg(target))
+ ..()
+ return
+ if(target.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
+ playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
+ return FALSE
+ if(user.a_intent != INTENT_HARM)
+ if(stun_act(target, user))
+ user.do_attack_animation(target)
+ user.adjustStaminaLossBuffered(stun_stam_cost)
+ return
+ else if(!harm_act(target, user))
+ return ..() //if you can't fry them just beat them with it
+ else //we did harm act them
+ user.do_attack_animation(target)
+ user.adjustStaminaLossBuffered(lethal_stam_cost)
+
+/obj/item/twohanded/electrostaff/proc/stun_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE)
+ var/stunforce = stun_stamdmg
+ if(!no_charge_and_force)
+ if(!on)
+ target.visible_message("[user] has bapped [target] with [src]. Luckily it was off.", \
+ "[user] has bapped you with [src]. Luckily it was off")
+ turn_off() //if it wasn't already off
+ return FALSE
+ var/obj/item/stock_parts/cell/C = get_cell()
+ var/chargeleft = C.charge
+ deductcharge(stun_cost)
+ if(QDELETED(src) || QDELETED(C)) //boom
+ return FALSE
+ if(chargeleft < stun_cost)
+ stunforce *= round(chargeleft/stun_cost, 0.1)
+ target.adjustStaminaLoss(stunforce)
+ target.apply_effect(EFFECT_STUTTER, stunforce)
+ SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
+ if(user)
+ target.lastattacker = user.real_name
+ target.lastattackerckey = user.ckey
+ target.visible_message("[user] has shocked [target] with [src]!", \
+ "[user] has shocked you with [src]!")
+ log_combat(user, user, "stunned with an electrostaff")
+ playsound(src, 'sound/weapons/staff.ogg', 50, 1, -1)
+ target.apply_status_effect(stun_status_effect, stun_status_duration)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.forcesay(GLOB.hit_appends)
+ return TRUE
+
+/obj/item/twohanded/electrostaff/proc/harm_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE)
+ var/lethal_force = lethal_damage
+ if(!no_charge_and_force)
+ if(!on)
+ return FALSE //standard item attack
+ var/obj/item/stock_parts/cell/C = get_cell()
+ var/chargeleft = C.charge
+ deductcharge(lethal_cost)
+ if(QDELETED(src) || QDELETED(C)) //boom
+ return FALSE
+ if(chargeleft < stun_cost)
+ lethal_force *= round(chargeleft/lethal_cost, 0.1)
+ target.adjustFireLoss(lethal_force) //good against ointment spam
+ SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
+ if(user)
+ target.lastattacker = user.real_name
+ target.lastattackerckey = user.ckey
+ target.visible_message("[user] has seared [user] with [src]!", \
+ "[user] has seared you with [src]!")
+ log_combat(user, user, "burned with an electrostaff")
+ playsound(src, 'sound/weapons/sear.ogg', 50, 1, -1)
+ return TRUE
+
+/obj/item/twohanded/electrostaff/proc/clowning_around(mob/living/user)
+ user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \
+ "You accidentally hit yourself with [src]!")
+ SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
+ harm_act(user, user, TRUE)
+ stun_act(user, user, TRUE)
+ deductcharge(lethal_cost)
+
+/obj/item/twohanded/electrostaff/emp_act(severity)
+ . = ..()
+ if (!(. & EMP_PROTECT_SELF))
+ turn_off()
+ if(!iscyborg(loc))
+ deductcharge(1000 / severity, TRUE, FALSE)
+
/obj/item/twohanded/broom
name = "broom"
desc = "This is my BROOMSTICK! It can be used manually or braced with two hands to sweep items as you move. It has a telescopic handle for compact storage." //LIES
@@ -1078,4 +1331,4 @@
/obj/item/twohanded/broom/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) //bless you whoever fixes this copypasta
J.put_in_cart(src, user)
J.mybroom=src
- J.update_icon()
\ No newline at end of file
+ J.update_icon()
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 88c8d51479..bec1c893ae 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -265,12 +265,15 @@
new /obj/item/clothing/head/helmet/alt(src)
new /obj/item/clothing/mask/gas/sechailer(src)
new /obj/item/clothing/suit/armor/bulletproof(src)
+
/obj/structure/closet/secure_closet/lethalshots
- name = "shotgun lethal rounds"
+ name = "lethal ammunition and riot staves"
req_access = list(ACCESS_ARMORY)
icon_state = "tac"
/obj/structure/closet/secure_closet/lethalshots/PopulateContents()
..()
+ new /obj/item/twohanded/electrostaff(src)
+ new /obj/item/twohanded/electrostaff(src)
for(var/i in 1 to 3)
new /obj/item/storage/box/lethalshot(src)
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 7a28827903..1a2c0e189a 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/inhands/weapons/staves_lefthand.dmi b/icons/mob/inhands/weapons/staves_lefthand.dmi
index 8b96b84236..ca1694b1f1 100644
Binary files a/icons/mob/inhands/weapons/staves_lefthand.dmi and b/icons/mob/inhands/weapons/staves_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/staves_righthand.dmi b/icons/mob/inhands/weapons/staves_righthand.dmi
index 202bab9e21..4d366d950f 100644
Binary files a/icons/mob/inhands/weapons/staves_righthand.dmi and b/icons/mob/inhands/weapons/staves_righthand.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 30c43985fa..41f2693800 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 7058b9918b..bdad12b0b6 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/sound/weapons/staff.ogg b/sound/weapons/staff.ogg
new file mode 100644
index 0000000000..35b42dfd8d
Binary files /dev/null and b/sound/weapons/staff.ogg differ