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