From 0eb13d8f23d36756aad24cf7eabc58ad24dd4511 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 17:39:49 -0700
Subject: [PATCH 01/12] refactors guns a bit
---
.../mob/living/silicon/robot/robot_modules.dm | 2 +-
.../mob/living/simple_animal/hostile/mimic.dm | 7 +-
.../projectiles/ammunition/energy/plasma.dm | 2 +-
code/modules/projectiles/gun.dm | 58 +++++----
.../projectiles/guns/ballistic/automatic.dm | 21 ++--
code/modules/projectiles/guns/energy.dm | 115 +++++++++++++-----
code/modules/projectiles/guns/energy/laser.dm | 8 +-
.../projectiles/guns/energy/special.dm | 6 +-
.../modules/projectiles/guns/pumpenergy.dm | 28 ++---
9 files changed, 142 insertions(+), 105 deletions(-)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index a079a9985c..e304f13d1d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -191,7 +191,7 @@
else if(istype(I, /obj/item/gun/energy))
var/obj/item/gun/energy/EG = I
if(EG.cell?.charge < EG.cell.maxcharge)
- var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.select]
+ var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.current_firemode_index]
EG.cell.give(S.e_cost * coeff)
if(!EG.chambered)
EG.recharge_newshot(TRUE)
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index bbdd7ab4b0..5e159e8517 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -197,8 +197,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
return 0
return ..()
-
-
/mob/living/simple_animal/hostile/mimic/copy/ranged
var/obj/item/gun/TrueGun = null
var/obj/item/gun/magic/Zapstick
@@ -229,14 +227,13 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
casingtype = initial(M.ammo_type)
if(istype(G, /obj/item/gun/energy))
Zapgun = G
- var/selectfiresetting = Zapgun.select
- var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting]
+ var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[Zapgun.current_firemode_index]
projectiletype = initial(E.projectile_type)
/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target)
if(Zapgun)
if(Zapgun.cell)
- var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select]
+ var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.current_firemode_index]
if(Zapgun.cell.charge >= shot.e_cost)
Zapgun.cell.use(shot.e_cost)
Zapgun.update_icon()
diff --git a/code/modules/projectiles/ammunition/energy/plasma.dm b/code/modules/projectiles/ammunition/energy/plasma.dm
index 42b03e4245..c7e3820177 100644
--- a/code/modules/projectiles/ammunition/energy/plasma.dm
+++ b/code/modules/projectiles/ammunition/energy/plasma.dm
@@ -12,4 +12,4 @@
/obj/item/ammo_casing/energy/plasma/weak
projectile_type = /obj/item/projectile/plasma/weak
- e_cost = 100
\ No newline at end of file
+ e_cost = 100
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 531c6082b0..54f96c491c 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -28,10 +28,19 @@
trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
var/sawn_desc = null //description change if weapon is sawn-off
var/sawn_off = FALSE
- var/burst_size = 1 //how large a burst is
- var/fire_delay = 0 //rate of fire for burst firing and semi auto
- var/firing_burst = 0 //Prevent the weapon from firing again while already firing
- var/semicd = 0 //cooldown handler
+
+ /// Weapon is burst fire if this is above 1
+ var/burst_size = 1
+ /// The time between shots in burst.
+ var/burst_shot_delay = 3
+ /// The time between firing actions, this means between bursts if this is burst weapon.
+ var/fire_delay = 0
+ /// Last world.time this was fired
+ var/last_fire = 0
+ /// don't fire two bursts at the same time
+ var/firing_burst = FALSE
+ /// Used in gun-in-mouth execution/suicide and similar, while TRUE nothing should work on this like firing or modification and so on and so forth.
+ var/busy_action = FALSE
var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy
var/spread = 0 //Spread induced by the gun itself.
var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0.
@@ -110,7 +119,6 @@
to_chat(user, "*click*")
playsound(src, "gun_dry_fire", 30, 1)
-
/obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
if(recoil)
shake_camera(user, recoil + 1, recoil)
@@ -136,6 +144,9 @@
/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
+ process_afterattack(target, user, flag, params)
+
+/obj/item/gun/proc/process_afterattack(atom/target, mob/living/user, flag, params)
if(!target)
return
if(firing_burst)
@@ -162,7 +173,6 @@
handle_suicide(user, target, params)
return
-
//Exclude lasertag guns from the TRAIT_CLUMSY check.
if(clumsy_check)
if(istype(user))
@@ -194,8 +204,6 @@
process_fire(target, user, TRUE, params, null, bonus_spread)
-
-
/obj/item/gun/can_trigger_gun(mob/living/user)
. = ..()
if(!.)
@@ -220,6 +228,9 @@
/obj/item/gun/proc/recharge_newshot()
return
+/obj/item/gun/proc/on_cooldown()
+ return busy_action || firing_burst || (last_fire > world.time + fire_delay)
+
/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
if(!user || !firing_burst)
firing_burst = FALSE
@@ -260,14 +271,14 @@
/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
add_fingerprint(user)
- if(semicd)
+ if(on_cooldown())
return
var/sprd = 0
var/randomized_gun_spread = 0
var/rand_spr = rand()
if(spread)
- randomized_gun_spread = rand(0, spread)
+ randomized_gun_spread = rand(0, spread)
else if(burst_size > 1 && burst_spread)
randomized_gun_spread = rand(0, burst_spread)
if(HAS_TRAIT(user, TRAIT_POOR_AIM)) //nice shootin' tex
@@ -276,8 +287,12 @@
if(burst_size > 1)
firing_burst = TRUE
- for(var/i = 1 to burst_size)
- addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1))
+ process_burst(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, 1)
+ for(var/i in 2 to burst_size)
+ sleep(burst_shot_delay)
+ if(QDELETED(src))
+ break
+ process_burst(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i)
else
if(chambered)
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
@@ -294,8 +309,8 @@
return
process_chamber()
update_icon()
- semicd = TRUE
- addtimer(CALLBACK(src, .proc/reset_semicd), fire_delay)
+
+ last_fire = world.time
if(user)
user.update_inv_hands()
@@ -303,13 +318,6 @@
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
return TRUE
-/obj/item/gun/update_icon()
- ..()
-
-
-/obj/item/gun/proc/reset_semicd()
- semicd = FALSE
-
/obj/item/gun/attack(mob/M as mob, mob/user)
if(user.a_intent == INTENT_HARM) //Flogging
if(bayonet)
@@ -429,7 +437,7 @@
if(!ishuman(user) || !ishuman(target))
return
- if(semicd)
+ if(on_cooldown())
return
if(user == target)
@@ -439,7 +447,7 @@
target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \
"[user] points [src] at your head, ready to pull the trigger...")
- semicd = TRUE
+ busy_action = TRUE
if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
if(user)
@@ -447,10 +455,10 @@
user.visible_message("[user] decided not to shoot.")
else if(target && target.Adjacent(user))
target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!")
- semicd = FALSE
+ busy_action = FALSE
return
- semicd = FALSE
+ busy_action = FALSE
target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!")
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index bcb212a031..0ff0c79f1e 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -5,7 +5,7 @@
var/automatic_burst_overlay = TRUE
can_suppress = TRUE
burst_size = 3
- fire_delay = 2
+ burst_shot_delay = 2
actions_types = list(/datum/action/item_action/toggle_firemode)
/obj/item/gun/ballistic/automatic/proto
@@ -77,11 +77,9 @@
/obj/item/gun/ballistic/automatic/proc/enable_burst()
burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
/obj/item/gun/ballistic/automatic/proc/disable_burst()
burst_size = 1
- fire_delay = 0
/obj/item/gun/ballistic/automatic/can_shoot()
return get_ammo()
@@ -100,7 +98,7 @@
item_state = "c20r"
mag_type = /obj/item/ammo_box/magazine/smgm45
fire_sound = 'sound/weapons/gunshot_smg.ogg'
- fire_delay = 2
+ burst_shot_delay = 2
burst_size = 2
pin = /obj/item/firing_pin/implant/pindicate
can_bayonet = TRUE
@@ -130,7 +128,7 @@
mag_type = /obj/item/ammo_box/magazine/wt550m9
can_suppress = FALSE
burst_size = 2
- fire_delay = 1
+ burst_shot_delay = 1
can_bayonet = TRUE
knife_x_offset = 25
knife_y_offset = 12
@@ -165,7 +163,7 @@
can_suppress = FALSE
var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel
burst_size = 3
- fire_delay = 2
+ burst_shot_delay = 2
pin = /obj/item/firing_pin/implant/pindicate
/obj/item/gun/ballistic/automatic/m90/Initialize()
@@ -212,7 +210,6 @@
if(0)
select = 1
burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
to_chat(user, "You switch to [burst_size]-rnd burst.")
if(1)
select = 2
@@ -220,7 +217,6 @@
if(2)
select = 0
burst_size = 1
- fire_delay = 0
to_chat(user, "You switch to semi-auto.")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
update_icon()
@@ -237,7 +233,7 @@
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = FALSE
burst_size = 4
- fire_delay = 1
+ burst_shot_delay = 1
/obj/item/gun/ballistic/automatic/ar
name = "\improper NT-ARG 'Boarder'"
@@ -249,7 +245,7 @@
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = FALSE
burst_size = 3
- fire_delay = 1
+ burst_shot_delay = 1
// Bulldog shotgun //
@@ -264,7 +260,6 @@
fire_sound = 'sound/weapons/gunshot.ogg'
can_suppress = FALSE
burst_size = 1
- fire_delay = 0
pin = /obj/item/firing_pin/implant/pindicate
actions_types = list()
@@ -301,7 +296,7 @@
var/cover_open = FALSE
can_suppress = FALSE
burst_size = 3
- fire_delay = 1
+ burst_shot_delay = 1
spread = 7
pin = /obj/item/firing_pin/implant/pindicate
@@ -421,7 +416,7 @@
mag_type = /obj/item/ammo_box/magazine/recharge
fire_delay = 2
can_suppress = FALSE
- burst_size = 0
+ burst_size = 1
actions_types = list()
fire_sound = 'sound/weapons/laser.ogg'
casing_ejector = FALSE
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 1329e5418f..e77a52dfb3 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -1,3 +1,16 @@
+/*
+ * Energy guns that draw from a cell to fire.
+ *
+ * This is a bit weird but this is how it currently works:
+ * When switching shots, it clears the chamber, and loads the correct energy ammo casing if there is enough energy to fire it.
+ * If there's no projectile in the casing, it creates it now.
+ * Otherwise the chamber stays null.
+ * After firing, it actually deducts the energy and then clears the chamber and does the above again.
+ * It detects if a successful fire is done by checking if the chambered energy ammo casing still has its projectile intact.
+ *
+ * It might be good in the future to move away from ammo casinsgs and instead use a datum-firemode system, but that would make handling firing,
+ * which the casing does as of now, a little interesting to implement.
+ */
/obj/item/gun/energy
icon_state = "energy"
name = "energy gun"
@@ -8,7 +21,8 @@
var/cell_type = /obj/item/stock_parts/cell
var/modifystate = 0
var/list/ammo_type = list(/obj/item/ammo_casing/energy)
- var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
+ /// The index of the ammo_types/firemodes which we're using right now
+ var/current_firemode_index = 1
var/can_charge = 1 //Can it be charged in a recharger?
var/automatic_charge_overlays = TRUE //Do we handle overlays with base update_icon()?
var/charge_sections = 4
@@ -46,16 +60,6 @@
START_PROCESSING(SSobj, src)
update_icon()
-/obj/item/gun/energy/proc/update_ammo_types()
- var/obj/item/ammo_casing/energy/shot
- for (var/i = 1, i <= ammo_type.len, i++)
- var/shottype = ammo_type[i]
- shot = new shottype(src)
- ammo_type[i] = shot
- shot = ammo_type[select]
- fire_sound = shot.fire_sound
- fire_delay = shot.delay
-
/obj/item/gun/energy/Destroy()
QDEL_NULL(cell)
STOP_PROCESSING(SSobj, src)
@@ -81,13 +85,14 @@
recharge_newshot(TRUE)
update_icon()
-/obj/item/gun/energy/attack_self(mob/living/user as mob)
- if(ammo_type.len > 1)
+// ATTACK SELF IGNORING PARENT RETURN VALUE
+/obj/item/gun/energy/attack_self(mob/living/user)
+ . = ..()
+ if(can_select_fire(user))
select_fire(user)
- update_icon()
/obj/item/gun/energy/can_shoot()
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
return !QDELETED(cell) ? (cell.charge >= shot.e_cost) : FALSE
/obj/item/gun/energy/recharge_newshot(no_cyborg_drain)
@@ -97,11 +102,11 @@
if(iscyborg(loc))
var/mob/living/silicon/robot/R = loc
if(R.cell)
- var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index] //Necessary to find cost of shot
if(R.cell.use(shot.e_cost)) //Take power from the borg...
cell.give(shot.e_cost) //... to recharge the shot
if(!chambered)
- var/obj/item/ammo_casing/energy/AC = ammo_type[select]
+ var/obj/item/ammo_casing/energy/AC = ammo_type[current_firemode_index]
if(cell.charge >= AC.e_cost) //if there's enough power in the cell cell...
chambered = AC //...prepare a new shot based on the current ammo type selected
if(!chambered.BB)
@@ -124,19 +129,60 @@
process_chamber() // Ditto.
return ..()
-/obj/item/gun/energy/proc/select_fire(mob/living/user)
- select++
- if (select > ammo_type.len)
- select = 1
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
- fire_sound = shot.fire_sound
- fire_delay = shot.delay
- if (shot.select_name)
- to_chat(user, "[src] is now set to [shot.select_name].")
- chambered = null
- recharge_newshot(TRUE)
+// Firemodes/Ammotypes
+
+/obj/item/gun/energy/proc/update_ammo_types()
+ var/obj/item/ammo_casing/energy/C
+ for(var/i in 1 to length(ammo_type))
+ var/v = ammo_type[i]
+ if(istype(v, /obj/item/ammo_casing/energy)) //already set
+ continue
+ else
+ C = new v //if you put non energycasing/type stuff in here you deserve the runtime
+ ammo_type[i] = C
+ set_firemode_index(initial(current_firemode_index))
+
+/obj/item/gun/energy/proc/set_firemode_index(index, mob/user_for_feedback)
+ chambered = null //unchamber whatever we have chambered
+ if(index > length(ammo_type))
+ index = 1
+ else if(index < 1)
+ index = length(ammo_type)
+ var/obj/item/ammo_casing/energy/C = ammo_type[index] //energy weapons should not have no casings, if it does you deserve the runtime.
+ current_firemode_index = index
+ fire_sound = C.fire_sound
+ fire_delay = C.delay
+ if(user_for_feedback)
+ to_chat(user_for_feedback, "[src] is now set to [C.select_name || C].")
+ post_set_firemode()
update_icon(TRUE)
- return
+
+/obj/item/gun/energy/proc/post_set_firemode(recharge_newshot = TRUE)
+ if(recharge_newshot)
+ recharge_newshot(TRUE)
+
+/obj/item/gun/energy/proc/set_firemode_to_next(mob/user_for_feedback)
+ return set_firemode_index(current_firemode_index++, user_for_feedback)
+
+/obj/item/gun/energy/proc/set_firemode_to_prev(mob/user_for_feedback)
+ return set_firemode_index(current_firemode_index--, user_for_feedback)
+
+/obj/item/gun/energy/proc/get_firemode_index(casing_type)
+ var/obj/item/ammo_casing/energy/E = locate(casing_type) in ammo_type
+ if(E)
+ return ammo_type.Find(E)
+
+/obj/item/gun/energy/proc/set_firemode_to_type(casing_type)
+ var/index = get_firemode_index(casing_type)
+ if(index)
+ set_firemode_index(index)
+
+/// This is the proc used in general for when a user switches firemodes. Just goes to next firemode by default.
+/obj/item/gun/energy/proc/select_fire(mob/living/user)
+ return set_firemode_to_next(user)
+
+/obj/item/gun/energy/proc/can_select_fire(mob/living/user)
+ return TRUE
/obj/item/gun/energy/update_icon(force_update)
if(QDELETED(src))
@@ -156,7 +202,7 @@
if(!initial(item_state))
itemState = icon_state
if (modifystate)
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
add_overlay("[icon_state]_[shot.select_name]")
iconState += "_[shot.select_name]"
if(itemState)
@@ -175,6 +221,9 @@
if(itemState)
itemState += "[ratio]"
item_state = itemState
+ if(ismob(loc)) //forces inhands to update
+ var/mob/M = loc
+ M.update_inv_hands()
/obj/item/gun/energy/suicide_act(mob/living/user)
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
@@ -184,7 +233,7 @@
user.visible_message("[user] melts [user.p_their()] face off with [src]!")
playsound(loc, fire_sound, 50, 1, -1)
playsound(src, 'sound/weapons/dink.ogg', 30, 1)
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
cell.use(shot.e_cost)
update_icon()
return(FIRELOSS)
@@ -208,11 +257,11 @@
/obj/item/gun/energy/ignition_effect(atom/A, mob/living/user)
- if(!can_shoot() || !ammo_type[select])
+ if(!can_shoot() || !ammo_type[current_firemode_index])
shoot_with_empty_chamber()
. = ""
else
- var/obj/item/ammo_casing/energy/E = ammo_type[select]
+ var/obj/item/ammo_casing/energy/E = ammo_type[current_firemode_index]
var/obj/item/projectile/energy/BB = E.BB
if(!BB)
. = ""
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 1e1af62d5a..542794a281 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -189,7 +189,7 @@
if(!ishuman(user) || !ishuman(target))
return
- if(semicd)
+ if(on_cooldown())
return
if(user == target)
@@ -199,7 +199,7 @@
target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \
"[user] points [src] at your head, ready to pull the trigger...")
- semicd = TRUE
+ busy_action = TRUE
if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
if(user)
@@ -207,10 +207,10 @@
user.visible_message("[user] decided not to shoot.")
else if(target && target.Adjacent(user))
target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!")
- semicd = FALSE
+ busy_action = FALSE
return
- semicd = FALSE
+ busy_action = FALSE
target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!")
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index eeb272f8d9..c6a666e777 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -36,7 +36,7 @@
/obj/item/gun/energy/decloner/update_icon()
..()
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(!QDELETED(cell) && (cell.charge > shot.e_cost))
add_overlay("decloner_spin")
@@ -183,7 +183,7 @@
var/atmos_link = FALSE
/obj/item/gun/energy/wormhole_projector/update_icon()
- icon_state = "[initial(icon_state)][select]"
+ icon_state = "[initial(icon_state)][current_firemode_index]"
item_state = icon_state
/obj/item/gun/energy/wormhole_projector/update_ammo_types()
@@ -318,7 +318,7 @@
/obj/item/gun/energy/emitter/update_icon()
..()
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(!QDELETED(cell) && (cell.charge > shot.e_cost))
add_overlay("emitter_carbine_empty")
else
diff --git a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
index 47de736c3b..f7c0b343c3 100644
--- a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
+++ b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
@@ -46,34 +46,22 @@
cell.use(shot.e_cost)//... drain the cell cell
chambered = 0 //either way, released the prepared shot
-/obj/item/gun/energy/pumpaction/select_fire(mob/living/user) //makes it so that it doesn't rack itself when changing firing modes unless already racked
- select++
- if (select > ammo_type.len)
- select = 1
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
- fire_sound = shot.fire_sound
- fire_delay = shot.delay
- if (shot.select_name)
- to_chat(user, "[src] is now set to [shot.select_name].")
- if(chambered)
- chambered = 0
- recharge_newshot(1)
- update_icon()
- if(ismob(loc)) //forces inhands to update
- var/mob/M = loc
- M.update_inv_hands()
- return
+/obj/item/gun/energy/pumpaction/post_set_firemode()
+ var/has_shot = chambered
+ . = ..(recharge_newshot = FALSE)
+ if(has_shot)
+ recharge_newshot(TRUE)
/obj/item/gun/energy/pumpaction/update_icon() //adds racked indicators
..()
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(chambered)
add_overlay("[icon_state]_rack_[shot.select_name]")
else
add_overlay("[icon_state]_rack_empty")
/obj/item/gun/energy/pumpaction/proc/pump(mob/M) //pumping proc. Checks if the gun is empty and plays a different sound if it is.
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(cell.charge < shot.e_cost)
playsound(M, 'sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
else
@@ -102,7 +90,7 @@
/obj/item/gun/energy/pumpaction/worn_overlays(isinhands, icon_file, style_flags = NONE) //ammo counter for inhands
. = ..()
var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1)
- var/obj/item/ammo_casing/energy/shot = ammo_type[select]
+ var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(isinhands)
if(cell.charge < shot.e_cost)
var/mutable_appearance/ammo_inhand = mutable_appearance(icon_file, "[item_state]_empty")
From 7ae43a224943258a499e9e896cb64055373353ea Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 17:51:59 -0700
Subject: [PATCH 02/12] fix
---
code/modules/projectiles/gun.dm | 2 +-
code/modules/projectiles/guns/energy.dm | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 54f96c491c..bcf1df44bc 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -33,7 +33,7 @@
var/burst_size = 1
/// The time between shots in burst.
var/burst_shot_delay = 3
- /// The time between firing actions, this means between bursts if this is burst weapon.
+ /// The time between firing actions, this means between bursts if this is burst weapon. The reason this is 0 is because you are still, by default, limited by clickdelay.
var/fire_delay = 0
/// Last world.time this was fired
var/last_fire = 0
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index e77a52dfb3..b56664fe03 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -162,10 +162,10 @@
recharge_newshot(TRUE)
/obj/item/gun/energy/proc/set_firemode_to_next(mob/user_for_feedback)
- return set_firemode_index(current_firemode_index++, user_for_feedback)
+ return set_firemode_index(++current_firemode_index, user_for_feedback)
/obj/item/gun/energy/proc/set_firemode_to_prev(mob/user_for_feedback)
- return set_firemode_index(current_firemode_index--, user_for_feedback)
+ return set_firemode_index(--current_firemode_index, user_for_feedback)
/obj/item/gun/energy/proc/get_firemode_index(casing_type)
var/obj/item/ammo_casing/energy/E = locate(casing_type) in ammo_type
From 7d53d6e162556ac455df4cbe72ced3861a9a036b Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 20:24:02 -0700
Subject: [PATCH 03/12] s
---
code/__DEFINES/flags.dm | 11 ++--
code/__DEFINES/status_effects.dm | 4 +-
code/datums/status_effects/debuffs.dm | 40 +++++++++++----
.../projectiles/ammunition/energy/stun.dm | 2 +-
code/modules/projectiles/guns/energy.dm | 50 +++++++++++++++++--
code/modules/projectiles/guns/energy/stun.dm | 17 ++++++-
.../projectiles/projectile/energy/stun.dm | 12 ++++-
7 files changed, 111 insertions(+), 25 deletions(-)
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index a7d2670747..317066f673 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -56,11 +56,12 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
//Movement Types
-#define GROUND (1<<0)
-#define FLYING (1<<1)
-#define VENTCRAWLING (1<<2)
-#define FLOATING (1<<3)
-#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
+#define GROUND (1<<0)
+#define FLYING (1<<1)
+#define VENTCRAWLING (1<<2)
+#define FLOATING (1<<3)
+#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
+#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF (1<<0)
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 6d52f4640c..f42948f4ae 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -46,7 +46,9 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
-#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
+#define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down
+
+#define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 2e46046a7e..56fbc1659e 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -33,7 +33,6 @@
if(owner.getStaminaLoss())
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
-
//UNCONSCIOUS
/datum/status_effect/incapacitating/unconscious
id = "unconscious"
@@ -113,10 +112,16 @@
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
-/datum/status_effect/no_combat_mode/electrode
+/datum/status_effect/electrode
id = "tased"
+ var/slowdown = 1.5
+ var/slowdown_priority = 50 //to make sure the stronger effect overrides
+ var/affect_crawl = FALSE
+ var/nextmove_modifier = 1
+ var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
+ var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
-/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
+/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
@@ -124,20 +129,35 @@
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
- C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
+ C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affected_crawl? NONE : CRAWLING)
-/datum/status_effect/no_combat_mode/electrode/on_remove()
+/datum/status_effect/electrode/on_remove()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
- C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
+ C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]")
. = ..()
-/datum/status_effect/no_combat_mode/electrode/tick()
+/datum/status_effect/electrode/tick()
+ var/diff = world.time - last_tick
if(owner)
- owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
+ owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
+ last_tick = world.time
-/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
- return 2
+/datum/status_effect/electrode/no_combat_mode
+ id = "tased_strong"
+ slowdown = 8
+ slowdown_priority = 100
+ nextmove_modifier = 2
+
+/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
+ . = ..()
+ if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ if(C.combatmode)
+ C.toggle_combat_mode(TRUE)
+
+/datum/status_effect/electrode/no_combat_mode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
+ return nextmove_modifier
//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm
index 7c2b62c02c..f81064220f 100644
--- a/code/modules/projectiles/ammunition/energy/stun.dm
+++ b/code/modules/projectiles/ammunition/energy/stun.dm
@@ -27,4 +27,4 @@
click_cooldown_override = 3.5
/obj/item/ammo_casing/energy/disabler/secborg
- e_cost = 50
\ No newline at end of file
+ e_cost = 50
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index b56664fe03..d612383a95 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -20,7 +20,8 @@
var/obj/item/stock_parts/cell/cell //What type of power cell this uses
var/cell_type = /obj/item/stock_parts/cell
var/modifystate = 0
- var/list/ammo_type = list(/obj/item/ammo_casing/energy)
+ /// = TRUE/FALSE decides if the user can switch to it of their own accord
+ var/list/ammo_type = list(/obj/item/ammo_casing/energy = TRUE)
/// The index of the ammo_types/firemodes which we're using right now
var/current_firemode_index = 1
var/can_charge = 1 //Can it be charged in a recharger?
@@ -35,6 +36,9 @@
var/use_cyborg_cell = FALSE //whether the gun drains the cyborg user's cell instead, not to be confused with EGUN_SELFCHARGE_BORG
var/dead_cell = FALSE //set to true so the gun is given an empty cell
+ /// SET THIS TO TRUE IF YOU OVERRIDE altafterattack() or ANY right click action! If this is FALSE, the gun will show in examine its default right click behavior, which is to switch modes.
+ var/right_click_overridden = FALSE
+
/obj/item/gun/energy/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
@@ -65,6 +69,11 @@
STOP_PROCESSING(SSobj, src)
return ..()
+/obj/item/gun/energy/examine(mob/user)
+ . = ..()
+ if(!right_click_overridden)
+ . += "Right click in combat mode to switch modes."
+
/obj/item/gun/energy/process()
if(selfcharge && cell?.charge < cell.maxcharge)
charge_tick++
@@ -135,11 +144,13 @@
var/obj/item/ammo_casing/energy/C
for(var/i in 1 to length(ammo_type))
var/v = ammo_type[i]
+ var/user_can_select = ammo_type[v]
if(istype(v, /obj/item/ammo_casing/energy)) //already set
- continue
+ ammo_type[v] = isnull(user_can_select)? TRUE : user_can_select
else
C = new v //if you put non energycasing/type stuff in here you deserve the runtime
ammo_type[i] = C
+ ammo_type[C] = isnull(user_can_select)? TRUE : user_can_select
set_firemode_index(initial(current_firemode_index))
/obj/item/gun/energy/proc/set_firemode_index(index, mob/user_for_feedback)
@@ -179,11 +190,37 @@
/// This is the proc used in general for when a user switches firemodes. Just goes to next firemode by default.
/obj/item/gun/energy/proc/select_fire(mob/living/user)
- return set_firemode_to_next(user)
+ return user_set_firemode_to_next(user)
/obj/item/gun/energy/proc/can_select_fire(mob/living/user)
return TRUE
+#define INCREMENT_OR_WRAP(i) i = (i >= length(ammo_type))? 1 : (i + 1)
+#define DECREMENT_OR_WRAP(i) i = (i <= 1)? length(ammo_type) : (i - 1)
+#define IS_VALID_INDEX(i) (ammo_type[ammo_type[i]])
+/obj/item/gun/energy/proc/user_set_firemode_to_next(mob/user_for_feedback)
+ var/current_index = current_firemode_index
+ var/new_index = current_index
+ INCREMENT_OR_WRAP(new_index)
+ if(!IS_VALID_INDEX(new_index))
+ var/initial_index = new_index
+ while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
+ new_index = INCREMENT_OR_WRAP(new_index)
+ set_firemode_index(new_index, user_for_feedback)
+
+/obj/item/gun/energy/proc/user_set_firemode_to_next(mob/user_for_feedback)
+ var/current_index = current_firemode_index
+ var/new_index = current_index
+ DECREMENT_OR_WRAP(new_index)
+ if(!IS_VALID_INDEX(new_index))
+ var/initial_index = new_index
+ while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
+ new_index = DECREMENT_OR_WRAP(new_index)
+ set_firemode_index(new_index, user_for_feedback)
+#undef INCREMENT_OR_WRAP
+#undef DECREMENT_OR_WRAP
+#undef IS_VALID_INDEX
+
/obj/item/gun/energy/update_icon(force_update)
if(QDELETED(src))
return
@@ -255,7 +292,6 @@
STOP_PROCESSING(SSobj, src)
. = ..()
-
/obj/item/gun/energy/ignition_effect(atom/A, mob/living/user)
if(!can_shoot() || !ammo_type[current_firemode_index])
shoot_with_empty_chamber()
@@ -283,3 +319,9 @@
playsound(user, BB.hitsound, 50, 1)
cell.use(E.e_cost)
. = "[user] casually lights their [A.name] with [src]. Damn."
+
+/obj/item/gun/energy/altafterattack(atom/target, mob/user, proximity_flags, params)
+ if(!right_click_overridden)
+ select_fire(user)
+ return TRUE
+ return ..()
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 55d11c52d1..1b272bfbaa 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -18,10 +18,23 @@
/obj/item/gun/energy/e_gun/advtaser
name = "hybrid taser"
- desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
+ desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams. Right click in combat mode to fire a taser shot with a cooldown.""
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode = FALSE)
ammo_x_offset = 2
+ // Not enough guns have altfire systems like this yet for this to be a universal framework.
+ var/last_altfire = 0
+ var/altfire_delay = 40
+
+/obj/item/gun/energy/e_gun/advtaser/altafterattack(atom/target, mob/user, proximity_flag, params)
+ if(last_altfire > world.time + altfire_delay)
+ return FALSE
+ var/current_index = current_firemode_index
+ set_firemode_to_type(/obj/item/ammo_casing/energy/electrode)
+ process_afterattack(target, user, proximity_flag, params)
+ set_firemode_index(current_index)
+ last_altfire = world.time
+ return TRUE
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 88e70154d1..1addfa2001 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -14,6 +14,7 @@
muzzle_type = /obj/effect/projectile/muzzle/stun
impact_type = /obj/effect/projectile/impact/stun
var/tase_duration = 50
+ var/strong_tase = TRUE
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -26,10 +27,17 @@
C.IgniteMob()
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
- else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
- C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
+ else if(tase_duration && (C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
+ C.apply_status_effect(strong_tase? STATUS_EFFECT_TASED : STATUS_EFFECT_TASED_WEAK, tase_duration)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
do_sparks(1, TRUE, src)
..()
+
+/obj/item/projectile/energy/electrode/security
+ tase_duration = 20
+ knockdown = 0
+ knockdown_stamoverride = 5
+ knockdown_stam_max = 15
+ strong_tase = FALSE
From 57b977c2e51987848f5b6175c9054d74c0dd3b68 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 20:41:45 -0700
Subject: [PATCH 04/12] why
---
code/datums/status_effects/debuffs.dm | 2 +-
code/modules/mob/living/living.dm | 4 ++++
.../projectiles/ammunition/energy/stun.dm | 5 +++++
code/modules/projectiles/guns/energy.dm | 2 +-
.../projectiles/guns/energy/energy_gun.dm | 19 +++++++++++--------
code/modules/projectiles/guns/energy/stun.dm | 4 ++--
.../projectiles/projectile/energy/stun.dm | 5 +++++
7 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 56fbc1659e..86d7e43e1b 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -129,7 +129,7 @@
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
- C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affected_crawl? NONE : CRAWLING)
+ C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING)
/datum/status_effect/electrode/on_remove()
if(iscarbon(owner))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 90ada3d718..90eb17716e 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1087,6 +1087,10 @@
fall(forced = 1)
canmove = !(ko || recoveringstam || pinned || IsStun() || IsFrozen() || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) //Cit change - makes it plausible to move while resting, adds pinning and stamina crit
density = !lying
+ if(resting)
+ ENABLE_BITFIELD(movement_type, CRAWLING)
+ else
+ DISABLE_BITFIELD(movement_type, CRAWLING)
if(lying)
if(layer == initial(layer)) //to avoid special cases like hiding larvas.
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm
index f81064220f..2abc472138 100644
--- a/code/modules/projectiles/ammunition/energy/stun.dm
+++ b/code/modules/projectiles/ammunition/energy/stun.dm
@@ -5,6 +5,10 @@
e_cost = 200
harmful = FALSE
+/obj/item/ammo_casing/energy/electrode/security
+ projectile_type = /obj/item/projectile/energy/electrode/security
+ e_cost = 100
+
/obj/item/ammo_casing/energy/electrode/spec
e_cost = 100
@@ -13,6 +17,7 @@
e_cost = 100
/obj/item/ammo_casing/energy/electrode/hos
+ projectile_type = /obj/item/projectile/energy/electrode/security/hos
e_cost = 200
/obj/item/ammo_casing/energy/electrode/old
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index d612383a95..ae69c3993f 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -208,7 +208,7 @@
new_index = INCREMENT_OR_WRAP(new_index)
set_firemode_index(new_index, user_for_feedback)
-/obj/item/gun/energy/proc/user_set_firemode_to_next(mob/user_for_feedback)
+/obj/item/gun/energy/proc/user_set_firemode_to_prev(mob/user_for_feedback)
var/current_index = current_firemode_index
var/new_index = current_index
DECREMENT_OR_WRAP(new_index)
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index 163deae0ed..efe107a3f8 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -97,7 +97,7 @@
pin = null
can_charge = 0
ammo_x_offset = 1
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
selfcharge = EGUN_SELFCHARGE
var/fail_tick = 0
var/fail_chance = 0
@@ -113,18 +113,21 @@
..()
/obj/item/gun/energy/e_gun/nuclear/proc/failcheck()
- if(prob(fail_chance) && isliving(loc))
- var/mob/living/M = loc
+ if(prob(fail_chance))
switch(fail_tick)
if(0 to 200)
fail_tick += (2*(fail_chance))
- M.rad_act(400)
- to_chat(M, "Your [name] feels warmer.")
+ radiation_pulse(src, 50)
+ var/mob/M = (ismob(loc) && loc) || (ismob(loc.loc) && loc.loc) //thank you short circuiting. if you powergame and nest these guns deeply you get to suffer no-warning radiation death.
+ if(M)
+ to_chat(M, "Your [name] feels warmer.")
if(201 to INFINITY)
SSobj.processing.Remove(src)
- M.rad_act(800)
- crit_fail = 1
- to_chat(M, "Your [name]'s reactor overloads!")
+ radiation_pulse(src, 200)
+ crit_fail = TRUE
+ var/mob/M = (ismob(loc) && loc) || (ismob(loc.loc) && loc.loc)
+ if(M)
+ to_chat(M, "Your [name]'s reactor overloads!")
/obj/item/gun/energy/e_gun/nuclear/emp_act(severity)
. = ..()
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 1b272bfbaa..997930170a 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -18,9 +18,9 @@
/obj/item/gun/energy/e_gun/advtaser
name = "hybrid taser"
- desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams. Right click in combat mode to fire a taser shot with a cooldown.""
+ desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams. Right click in combat mode to fire a taser shot with a cooldown."
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode = FALSE)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode/security = FALSE)
ammo_x_offset = 2
// Not enough guns have altfire systems like this yet for this to be a universal framework.
var/last_altfire = 0
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 1addfa2001..5c4827d0a7 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -41,3 +41,8 @@
knockdown_stamoverride = 5
knockdown_stam_max = 15
strong_tase = FALSE
+
+/obj/item/projectile/energy/electrode/security/hos
+ knockdown = 100
+ knockdown_stamoverride = 30
+ knockdown_stam_max = null
From 9d047f07f862f111f2cd19ff4407a7856f9c11dc Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 21:08:47 -0700
Subject: [PATCH 05/12] separate this a bit
---
code/modules/projectiles/gun.dm | 97 ++++++++++----------
code/modules/projectiles/guns/energy.dm | 6 ++
code/modules/projectiles/guns/energy/stun.dm | 4 +-
3 files changed, 58 insertions(+), 49 deletions(-)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index bcf1df44bc..510fe0f3a6 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -37,8 +37,8 @@
var/fire_delay = 0
/// Last world.time this was fired
var/last_fire = 0
- /// don't fire two bursts at the same time
- var/firing_burst = FALSE
+ /// Currently firing, whether or not it's a burst or not.
+ var/firing = FALSE
/// Used in gun-in-mouth execution/suicide and similar, while TRUE nothing should work on this like firing or modification and so on and so forth.
var/busy_action = FALSE
var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy
@@ -124,7 +124,7 @@
shake_camera(user, recoil + 1, recoil)
if(isliving(user)) //CIT CHANGE - makes gun recoil cause staminaloss
- user.adjustStaminaLossBuffered(getstamcost(user)*(firing_burst && burst_size >= 2 ? 1/burst_size : 1)) //CIT CHANGE - ditto
+ user.adjustStaminaLossBuffered(getstamcost(user)*(firing && burst_size >= 2 ? 1/burst_size : 1)) //CIT CHANGE - ditto
if(suppressed)
playsound(user, fire_sound, 10, 1)
@@ -149,7 +149,7 @@
/obj/item/gun/proc/process_afterattack(atom/target, mob/living/user, flag, params)
if(!target)
return
- if(firing_burst)
+ if(firing)
return
if(flag) //It's adjacent, is the user, or is on the user's person
if(target in user.contents) //can't shoot stuff inside us.
@@ -229,51 +229,20 @@
return
/obj/item/gun/proc/on_cooldown()
- return busy_action || firing_burst || (last_fire > world.time + fire_delay)
-
-/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
- if(!user || !firing_burst)
- firing_burst = FALSE
- return FALSE
- if(!issilicon(user))
- if(iteration > 1 && !(user.is_holding(src))) //for burst firing
- firing_burst = FALSE
- return FALSE
- if(chambered && chambered.BB)
- if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
- if(chambered.harmful) // Is the bullet chambered harmful?
- to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone...")
- return
- if(randomspread)
- sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1)
- else //Smart spread
- sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1)
-
- if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
- shoot_with_empty_chamber(user)
- firing_burst = FALSE
- return FALSE
- else
- if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
- shoot_live_shot(user, 1, target, message)
- else
- shoot_live_shot(user, 0, target, message)
- if (iteration >= burst_size)
- firing_burst = FALSE
- else
- shoot_with_empty_chamber(user)
- firing_burst = FALSE
- return FALSE
- process_chamber()
- update_icon()
- return TRUE
+ return busy_action || firing || (last_fire > world.time + fire_delay)
/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
add_fingerprint(user)
if(on_cooldown())
return
+ firing = TRUE
+ . = do_fire(target, user, message, params, zone_override, bonus_spread)
+ firing = FALSE
+ last_fire = world.time
+/obj/item/gun/proc/do_fire(atom/target, mob/living/user, message = TRUE, params, zone_override = "", bonus_spread = 0)
+ set waitfor = FALSE
var/sprd = 0
var/randomized_gun_spread = 0
var/rand_spr = rand()
@@ -286,13 +255,12 @@
var/randomized_bonus_spread = rand(0, bonus_spread)
if(burst_size > 1)
- firing_burst = TRUE
- process_burst(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, 1)
+ do_burst_shot(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, 1)
for(var/i in 2 to burst_size)
sleep(burst_shot_delay)
if(QDELETED(src))
break
- process_burst(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i)
+ do_burst_shot(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i)
else
if(chambered)
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
@@ -310,14 +278,49 @@
process_chamber()
update_icon()
- last_fire = world.time
-
if(user)
user.update_inv_hands()
SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
return TRUE
+/obj/item/gun/proc/do_burst_shot(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
+ if(!user || !firing)
+ firing = FALSE
+ return FALSE
+ if(!issilicon(user))
+ if(iteration > 1 && !(user.is_holding(src))) //for burst firing
+ firing = FALSE
+ return FALSE
+ if(chambered && chambered.BB)
+ if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
+ if(chambered.harmful) // Is the bullet chambered harmful?
+ to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone...")
+ return
+ if(randomspread)
+ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1)
+ else //Smart spread
+ sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1)
+
+ if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
+ shoot_with_empty_chamber(user)
+ firing = FALSE
+ return FALSE
+ else
+ if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
+ shoot_live_shot(user, 1, target, message)
+ else
+ shoot_live_shot(user, 0, target, message)
+ if (iteration >= burst_size)
+ firing = FALSE
+ else
+ shoot_with_empty_chamber(user)
+ firing = FALSE
+ return FALSE
+ process_chamber()
+ update_icon()
+ return TRUE
+
/obj/item/gun/attack(mob/M as mob, mob/user)
if(user.a_intent == INTENT_HARM) //Flogging
if(bayonet)
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index ae69c3993f..6f46e976c3 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -206,6 +206,9 @@
var/initial_index = new_index
while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
new_index = INCREMENT_OR_WRAP(new_index)
+ if(initial_index == new_index) //cycled through without finding another
+ new_index = current_index
+
set_firemode_index(new_index, user_for_feedback)
/obj/item/gun/energy/proc/user_set_firemode_to_prev(mob/user_for_feedback)
@@ -216,6 +219,9 @@
var/initial_index = new_index
while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
new_index = DECREMENT_OR_WRAP(new_index)
+ if(initial_index == new_index) //cycled through without finding another
+ new_index = current_index
+
set_firemode_index(new_index, user_for_feedback)
#undef INCREMENT_OR_WRAP
#undef DECREMENT_OR_WRAP
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 997930170a..28b099e548 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -27,14 +27,14 @@
var/altfire_delay = 40
/obj/item/gun/energy/e_gun/advtaser/altafterattack(atom/target, mob/user, proximity_flag, params)
+ . = TRUE
if(last_altfire > world.time + altfire_delay)
- return FALSE
+ return
var/current_index = current_firemode_index
set_firemode_to_type(/obj/item/ammo_casing/energy/electrode)
process_afterattack(target, user, proximity_flag, params)
set_firemode_index(current_index)
last_altfire = world.time
- return TRUE
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
From 3ce1fe2585898ff4f3737836fc6703b791c145cb Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 22:26:43 -0700
Subject: [PATCH 06/12] changes
---
code/modules/projectiles/gun.dm | 7 ++++---
code/modules/projectiles/guns/energy.dm | 4 ++--
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 510fe0f3a6..8b28262dfe 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -241,6 +241,10 @@
firing = FALSE
last_fire = world.time
+ if(user)
+ user.update_inv_hands()
+ SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
+
/obj/item/gun/proc/do_fire(atom/target, mob/living/user, message = TRUE, params, zone_override = "", bonus_spread = 0)
set waitfor = FALSE
var/sprd = 0
@@ -278,9 +282,6 @@
process_chamber()
update_icon()
- if(user)
- user.update_inv_hands()
- SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
return TRUE
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 6f46e976c3..c96aa297ca 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -128,12 +128,12 @@
chambered = null //either way, released the prepared shot
recharge_newshot() //try to charge a new shot
-/obj/item/gun/energy/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
+/obj/item/gun/energy/do_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(!chambered && can_shoot())
process_chamber() // If the gun was drained and then recharged, load a new shot.
return ..()
-/obj/item/gun/energy/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
+/obj/item/gun/energy/do_burst_shot(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
if(!chambered && can_shoot())
process_chamber() // Ditto.
return ..()
From d89b8d95cfa2e79ec48a8efcff58046c3dba9b7b Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 22:44:51 -0700
Subject: [PATCH 07/12] BRAINLETMOMENT
---
code/modules/projectiles/gun.dm | 3 +--
code/modules/projectiles/guns/energy/stun.dm | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 8b28262dfe..7e125e9614 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -229,7 +229,7 @@
return
/obj/item/gun/proc/on_cooldown()
- return busy_action || firing || (last_fire > world.time + fire_delay)
+ return busy_action || firing || (last_fire + fire_delay > world.time)
/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
add_fingerprint(user)
@@ -246,7 +246,6 @@
SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
/obj/item/gun/proc/do_fire(atom/target, mob/living/user, message = TRUE, params, zone_override = "", bonus_spread = 0)
- set waitfor = FALSE
var/sprd = 0
var/randomized_gun_spread = 0
var/rand_spr = rand()
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 28b099e548..9b749bbead 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -28,7 +28,7 @@
/obj/item/gun/energy/e_gun/advtaser/altafterattack(atom/target, mob/user, proximity_flag, params)
. = TRUE
- if(last_altfire > world.time + altfire_delay)
+ if(last_altfire + altfire_delay > world.time)
return
var/current_index = current_firemode_index
set_firemode_to_type(/obj/item/ammo_casing/energy/electrode)
From 4c2b0a826a90662e6141a700fce122f93dc043fe Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Mon, 27 Jan 2020 23:26:24 -0700
Subject: [PATCH 08/12] WEW LAD
---
code/datums/status_effects/debuffs.dm | 1 +
code/modules/projectiles/projectile/energy/stun.dm | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 86d7e43e1b..7319945f49 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -125,6 +125,7 @@
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
+ last_tick = world.time
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 5c4827d0a7..ea7c013cbd 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -2,7 +2,7 @@
name = "electrode"
icon_state = "spark"
color = "#FFFF00"
- nodamage = 1
+ nodamage = TRUE
knockdown = 60
knockdown_stamoverride = 36
knockdown_stam_max = 50
@@ -38,8 +38,9 @@
/obj/item/projectile/energy/electrode/security
tase_duration = 20
knockdown = 0
- knockdown_stamoverride = 5
- knockdown_stam_max = 15
+ stamina = 5
+ knockdown_stamoverride = 0
+ knockdown_stam_max = 0
strong_tase = FALSE
/obj/item/projectile/energy/electrode/security/hos
From f430fbcbd620ed8f61f342d036fcef1eb4736da6 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Tue, 28 Jan 2020 17:48:56 -0700
Subject: [PATCH 09/12] doubles stutter
---
code/modules/projectiles/projectile/energy/stun.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index ea7c013cbd..929578df1e 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -6,7 +6,7 @@
knockdown = 60
knockdown_stamoverride = 36
knockdown_stam_max = 50
- stutter = 5
+ stutter = 10
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
range = 7
From 0612649eb7f7e55e66986b788345089d98ab510a Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Wed, 29 Jan 2020 20:50:06 -0700
Subject: [PATCH 10/12] Update stun.dm
---
code/modules/projectiles/guns/energy/stun.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 9b749bbead..d700db817c 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -24,7 +24,7 @@
ammo_x_offset = 2
// Not enough guns have altfire systems like this yet for this to be a universal framework.
var/last_altfire = 0
- var/altfire_delay = 40
+ var/altfire_delay = 15
/obj/item/gun/energy/e_gun/advtaser/altafterattack(atom/target, mob/user, proximity_flag, params)
. = TRUE
From 1a439b87588f81a7f14355a1569659dd608a01cd Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Wed, 29 Jan 2020 20:51:31 -0700
Subject: [PATCH 11/12] Update stun.dm
---
code/modules/projectiles/projectile/energy/stun.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 929578df1e..8852d754ce 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -38,7 +38,7 @@
/obj/item/projectile/energy/electrode/security
tase_duration = 20
knockdown = 0
- stamina = 5
+ stamina = 10
knockdown_stamoverride = 0
knockdown_stam_max = 0
strong_tase = FALSE
From 8db3fbdf880d1320585adfd1688adf1d0646bba7 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Tue, 4 Feb 2020 03:49:09 -0700
Subject: [PATCH 12/12] modularize out taser rework
---
code/__DEFINES/flags.dm | 11 +++--
code/__DEFINES/status_effects.dm | 4 +-
code/datums/status_effects/debuffs.dm | 41 +++++--------------
code/modules/mob/living/living.dm | 4 --
.../projectiles/ammunition/energy/stun.dm | 7 +---
.../projectiles/guns/energy/energy_gun.dm | 19 ++++-----
code/modules/projectiles/guns/energy/stun.dm | 17 +-------
.../projectiles/projectile/energy/stun.dm | 22 ++--------
8 files changed, 31 insertions(+), 94 deletions(-)
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 317066f673..a7d2670747 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -56,12 +56,11 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
//Movement Types
-#define GROUND (1<<0)
-#define FLYING (1<<1)
-#define VENTCRAWLING (1<<2)
-#define FLOATING (1<<3)
-#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
-#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
+#define GROUND (1<<0)
+#define FLYING (1<<1)
+#define VENTCRAWLING (1<<2)
+#define FLOATING (1<<3)
+#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF (1<<0)
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index f42948f4ae..6d52f4640c 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -46,9 +46,7 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
-#define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down
-
-#define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control
+#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 7319945f49..2e46046a7e 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -33,6 +33,7 @@
if(owner.getStaminaLoss())
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
+
//UNCONSCIOUS
/datum/status_effect/incapacitating/unconscious
id = "unconscious"
@@ -112,53 +113,31 @@
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
-/datum/status_effect/electrode
+/datum/status_effect/no_combat_mode/electrode
id = "tased"
- var/slowdown = 1.5
- var/slowdown_priority = 50 //to make sure the stronger effect overrides
- var/affect_crawl = FALSE
- var/nextmove_modifier = 1
- var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
- var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
-/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
+/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
- last_tick = world.time
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
- C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING)
+ C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
-/datum/status_effect/electrode/on_remove()
+/datum/status_effect/no_combat_mode/electrode/on_remove()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
- C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]")
+ C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
. = ..()
-/datum/status_effect/electrode/tick()
- var/diff = world.time - last_tick
+/datum/status_effect/no_combat_mode/electrode/tick()
if(owner)
- owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
- last_tick = world.time
+ owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
-/datum/status_effect/electrode/no_combat_mode
- id = "tased_strong"
- slowdown = 8
- slowdown_priority = 100
- nextmove_modifier = 2
-
-/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
- . = ..()
- if(iscarbon(owner))
- var/mob/living/carbon/C = owner
- if(C.combatmode)
- C.toggle_combat_mode(TRUE)
-
-/datum/status_effect/electrode/no_combat_mode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
- return nextmove_modifier
+/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
+ return 2
//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 90eb17716e..90ada3d718 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1087,10 +1087,6 @@
fall(forced = 1)
canmove = !(ko || recoveringstam || pinned || IsStun() || IsFrozen() || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) //Cit change - makes it plausible to move while resting, adds pinning and stamina crit
density = !lying
- if(resting)
- ENABLE_BITFIELD(movement_type, CRAWLING)
- else
- DISABLE_BITFIELD(movement_type, CRAWLING)
if(lying)
if(layer == initial(layer)) //to avoid special cases like hiding larvas.
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm
index 2abc472138..7c2b62c02c 100644
--- a/code/modules/projectiles/ammunition/energy/stun.dm
+++ b/code/modules/projectiles/ammunition/energy/stun.dm
@@ -5,10 +5,6 @@
e_cost = 200
harmful = FALSE
-/obj/item/ammo_casing/energy/electrode/security
- projectile_type = /obj/item/projectile/energy/electrode/security
- e_cost = 100
-
/obj/item/ammo_casing/energy/electrode/spec
e_cost = 100
@@ -17,7 +13,6 @@
e_cost = 100
/obj/item/ammo_casing/energy/electrode/hos
- projectile_type = /obj/item/projectile/energy/electrode/security/hos
e_cost = 200
/obj/item/ammo_casing/energy/electrode/old
@@ -32,4 +27,4 @@
click_cooldown_override = 3.5
/obj/item/ammo_casing/energy/disabler/secborg
- e_cost = 50
+ e_cost = 50
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index efe107a3f8..163deae0ed 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -97,7 +97,7 @@
pin = null
can_charge = 0
ammo_x_offset = 1
- ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
+ ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
selfcharge = EGUN_SELFCHARGE
var/fail_tick = 0
var/fail_chance = 0
@@ -113,21 +113,18 @@
..()
/obj/item/gun/energy/e_gun/nuclear/proc/failcheck()
- if(prob(fail_chance))
+ if(prob(fail_chance) && isliving(loc))
+ var/mob/living/M = loc
switch(fail_tick)
if(0 to 200)
fail_tick += (2*(fail_chance))
- radiation_pulse(src, 50)
- var/mob/M = (ismob(loc) && loc) || (ismob(loc.loc) && loc.loc) //thank you short circuiting. if you powergame and nest these guns deeply you get to suffer no-warning radiation death.
- if(M)
- to_chat(M, "Your [name] feels warmer.")
+ M.rad_act(400)
+ to_chat(M, "Your [name] feels warmer.")
if(201 to INFINITY)
SSobj.processing.Remove(src)
- radiation_pulse(src, 200)
- crit_fail = TRUE
- var/mob/M = (ismob(loc) && loc) || (ismob(loc.loc) && loc.loc)
- if(M)
- to_chat(M, "Your [name]'s reactor overloads!")
+ M.rad_act(800)
+ crit_fail = 1
+ to_chat(M, "Your [name]'s reactor overloads!")
/obj/item/gun/energy/e_gun/nuclear/emp_act(severity)
. = ..()
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index d700db817c..55d11c52d1 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -18,23 +18,10 @@
/obj/item/gun/energy/e_gun/advtaser
name = "hybrid taser"
- desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams. Right click in combat mode to fire a taser shot with a cooldown."
+ desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode/security = FALSE)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 2
- // Not enough guns have altfire systems like this yet for this to be a universal framework.
- var/last_altfire = 0
- var/altfire_delay = 15
-
-/obj/item/gun/energy/e_gun/advtaser/altafterattack(atom/target, mob/user, proximity_flag, params)
- . = TRUE
- if(last_altfire + altfire_delay > world.time)
- return
- var/current_index = current_firemode_index
- set_firemode_to_type(/obj/item/ammo_casing/energy/electrode)
- process_afterattack(target, user, proximity_flag, params)
- set_firemode_index(current_index)
- last_altfire = world.time
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 8852d754ce..88e70154d1 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -2,11 +2,11 @@
name = "electrode"
icon_state = "spark"
color = "#FFFF00"
- nodamage = TRUE
+ nodamage = 1
knockdown = 60
knockdown_stamoverride = 36
knockdown_stam_max = 50
- stutter = 10
+ stutter = 5
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
range = 7
@@ -14,7 +14,6 @@
muzzle_type = /obj/effect/projectile/muzzle/stun
impact_type = /obj/effect/projectile/impact/stun
var/tase_duration = 50
- var/strong_tase = TRUE
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -27,23 +26,10 @@
C.IgniteMob()
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
- else if(tase_duration && (C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
- C.apply_status_effect(strong_tase? STATUS_EFFECT_TASED : STATUS_EFFECT_TASED_WEAK, tase_duration)
+ else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
+ C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
do_sparks(1, TRUE, src)
..()
-
-/obj/item/projectile/energy/electrode/security
- tase_duration = 20
- knockdown = 0
- stamina = 10
- knockdown_stamoverride = 0
- knockdown_stam_max = 0
- strong_tase = FALSE
-
-/obj/item/projectile/energy/electrode/security/hos
- knockdown = 100
- knockdown_stamoverride = 30
- knockdown_stam_max = null