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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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 b26d6c443f2a9bb86af8e47c8c51ee35b6edcb34 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 29 Jan 2020 02:23:54 -0700 Subject: [PATCH 10/31] Update ticker.dm --- code/controllers/subsystem/ticker.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c9562bcfd1..41b199a1d0 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -363,7 +363,7 @@ SUBSYSTEM_DEF(ticker) var/turf/epi = bomb.loc qdel(bomb) if(epi) - explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE) + explosion(epi, 512, 0, 0, 0, TRUE, TRUE, 0, TRUE) /datum/controller/subsystem/ticker/proc/create_characters() for(var/mob/dead/new_player/player in GLOB.player_list) 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 11/31] 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 12/31] 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 13/31] 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 From ab06c23a2b52c9a9c10798907a75a0872d0c0135 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Wed, 5 Feb 2020 23:48:17 +0100 Subject: [PATCH 14/31] runtime is forever, errors are eternal. --- code/game/machinery/dance_machine.dm | 2 +- code/game/objects/effects/contraband.dm | 3 +- code/game/objects/effects/wanted_poster.dm | 1 + .../mob/living/carbon/carbon_defense.dm | 51 +++++++++---------- code/modules/mob/living/say.dm | 3 +- code/modules/surgery/organs/eyes.dm | 2 +- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index c6b4f2fcf5..6bedfb0a10 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -430,6 +430,6 @@ /obj/machinery/jukebox/disco/process() . = ..() if(active) - for(var/mob/M in rangers) + for(var/mob/living/M in rangers) if(prob(5+(allowed(M)*4)) && M.canmove) dance(M) diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index 6e8387c07b..eea3bace98 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -57,6 +57,7 @@ var/poster_item_name = "hypothetical poster" var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here." var/poster_item_icon_state = "rolled_poster" + var/poster_item_type = /obj/item/poster /obj/structure/sign/poster/Initialize() . = ..() @@ -114,7 +115,7 @@ /obj/structure/sign/poster/proc/roll_and_drop(loc) pixel_x = 0 pixel_y = 0 - var/obj/item/poster/P = new(loc, src) + var/obj/item/poster/P = new poster_item_type(loc, src) forceMove(P) return P diff --git a/code/game/objects/effects/wanted_poster.dm b/code/game/objects/effects/wanted_poster.dm index 35d16070ff..2e3244b4b8 100644 --- a/code/game/objects/effects/wanted_poster.dm +++ b/code/game/objects/effects/wanted_poster.dm @@ -8,6 +8,7 @@ /obj/structure/sign/poster/wanted var/wanted_name + poster_item_type = /obj/item/poster/wanted /obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description) . = ..() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index bb4442559e..637178ffe6 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -274,7 +274,7 @@ return if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) - + var/friendly_check = FALSE if(lying) if(buckled) to_chat(M, "You need to unbuckle [src] first to do that!") @@ -289,39 +289,35 @@ playsound(src, 'sound/items/Nose_boop.ogg', 50, 0) else if(check_zone(M.zone_selected) == "head") - var/mob/living/carbon/human/H = src - var/datum/species/pref_species = H.dna.species + var/datum/species/S + if(ishuman(src)) + S = dna.species - M.visible_message("[M] gives [H] a pat on the head to make [p_them()] feel better!", \ - "You give [H] a pat on the head to make [p_them()] feel better!") + M.visible_message("[M] gives [src] a pat on the head to make [p_them()] feel better!", \ + "You give [src] a pat on the head to make [p_them()] feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat) - if(HAS_TRAIT(M, TRAIT_FRIENDLY)) - var/datum/component/mood/mood = M.GetComponent(/datum/component/mood) - if (mood.sanity >= SANITY_GREAT) - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M) - else if (mood.sanity >= SANITY_DISTURBED) - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M) - if(H.dna.species.can_wag_tail(H)) - if("tail_human" in pref_species.default_features) - if(H.dna.features["tail_human"] == "None") + friendly_check = TRUE + if(S?.can_wag_tail(src)) + if("tail_human" in S.default_features) + if(dna.features["tail_human"] == "None") return else - if(!H.dna.species.is_wagging_tail()) - H.emote("wag") + if(!dna.species.is_wagging_tail()) + emote("wag") - if("tail_lizard" in pref_species.default_features) - if(H.dna.features["tail_lizard"] == "None") + if("tail_lizard" in S.default_features) + if(dna.features["tail_lizard"] == "None") return else - if(!H.dna.species.is_wagging_tail()) - H.emote("wag") + if(!dna.species.is_wagging_tail()) + emote("wag") - if("mam_tail" in pref_species.default_features) - if(H.dna.features["mam_tail"] == "None") + if("mam_tail" in S.default_features) + if(dna.features["mam_tail"] == "None") return else - if(!H.dna.species.is_wagging_tail()) - H.emote("wag") + if(!dna.species.is_wagging_tail()) + emote("wag") else return @@ -335,8 +331,11 @@ M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \ "You hug [src] to make [p_them()] feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug) - if(HAS_TRAIT(M, TRAIT_FRIENDLY)) - var/datum/component/mood/mood = M.GetComponent(/datum/component/mood) + friendly_check = TRUE + + if(friendly_check && HAS_TRAIT(M, TRAIT_FRIENDLY)) + var/datum/component/mood/mood = M.GetComponent(/datum/component/mood) + if(mood) if (mood.sanity >= SANITY_GREAT) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M) else if (mood.sanity >= SANITY_DISTURBED) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index a12d468e24..0fb48f65b1 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -103,7 +103,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( else if(message_mode || saymode) message = copytext_char(message, 3) message = trim_left(message) - + if(!message) + return if(message_mode == MODE_ADMIN) if(client) client.cmd_admin_say(message) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index dfbf4ee21e..44e92e464b 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -51,7 +51,7 @@ clear_eye_trauma() . = ..() var/mob/living/carbon/C = . - if(C) + if(!QDELETED(C)) if(ishuman(C) && eye_color) var/mob/living/carbon/human/H = C H.eye_color = old_eye_color From 233ed5873f22c411c90dbaa23fd9bda984101ce5 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 6 Feb 2020 01:13:28 +0100 Subject: [PATCH 15/31] race conditions and turfs beings special. --- code/game/objects/items/implants/implant_explosive.dm | 5 +++-- code/game/turfs/simulated/walls.dm | 2 +- code/modules/projectiles/guns/energy.dm | 7 ++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index b93c9419a3..bf8d215a11 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -82,8 +82,9 @@ /obj/item/implant/explosive/proc/boom_goes_the_weasel() explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak) - imp_in?.gib(TRUE) - qdel(src) + if(!QDELETED(imp_in)) + imp_in.gib(TRUE) + qdel(src) /obj/item/implant/explosive/macro name = "macrobomb implant" diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 460c6a52c9..bd0b85a498 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -171,7 +171,7 @@ var/turf/T = user.loc //get user's location for delay checks //the istype cascade has been spread among various procs for easy overriding - if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || try_destroy(W, user, T)) + if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || (iswall(src) && try_destroy(W, user, T))) return return ..() diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3ca732eb0b..eeea961037 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -57,9 +57,10 @@ fire_delay = shot.delay /obj/item/gun/energy/Destroy() - QDEL_NULL(cell) - QDEL_LIST(ammo_type) - STOP_PROCESSING(SSobj, src) + if(flags_1 & INITIALIZED_1) + QDEL_NULL(cell) + QDEL_LIST(ammo_type) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/gun/energy/process() From a3e2ec372f5b95f893465d3ee2a72b8d98d259da Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 6 Feb 2020 01:40:14 +0100 Subject: [PATCH 16/31] Makes it compile also custom emote fix. --- code/game/say.dm | 2 +- code/game/turfs/simulated/walls.dm | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/say.dm b/code/game/say.dm index b275d8b69c..85ae9f0681 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/attach_spans(input, list/spans) var/customsayverb = findtext(input, "*") if(customsayverb) - input = capitalize(copytext(input, length(input[customsayverb]) + 1)) + input = capitalize(copytext(input, customsayverb + length(input[customsayverb]))) if(input) return "[message_spans_start(spans)][input]" else diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index bd0b85a498..d26a6efb02 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -171,7 +171,8 @@ var/turf/T = user.loc //get user's location for delay checks //the istype cascade has been spread among various procs for easy overriding - if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || (iswall(src) && try_destroy(W, user, T))) + var/srctype = type + if(try_clean(W, user, T) || try_wallmount(W, user, T) || try_decon(W, user, T) || (type == srctype && try_destroy(W, user, T))) return return ..() From 60b6d96f45d7eed2c69cda148e5b5df47e3b8947 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 6 Feb 2020 02:17:51 +0100 Subject: [PATCH 17/31] typecheck. --- .../mob/living/simple_animal/hostile/mining_mobs/basilisk.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 2fbcf376dd..ccd80573c0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -144,7 +144,7 @@ /obj/item/projectile/temp/basilisk/icewing/on_hit(atom/target, blocked = FALSE) . = ..() - if(.) + if(. && isliving(target)) var/mob/living/L = target L.apply_status_effect(/datum/status_effect/freon/watcher) From 639ec8066dfe7e487d9f6b8df32396479f97e9a1 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 6 Feb 2020 02:19:14 +0100 Subject: [PATCH 18/31] Another typecheck --- .../mob/living/simple_animal/hostile/mining_mobs/basilisk.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index ccd80573c0..91b76974b5 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -131,7 +131,7 @@ /obj/item/projectile/temp/basilisk/magmawing/on_hit(atom/target, blocked = FALSE) . = ..() - if(.) + if(. && isliving(target)) var/mob/living/L = target if (istype(L)) L.adjust_fire_stacks(0.1) From fd19eb7fa820b70b9ab2cd36393524a83e5b4edf Mon Sep 17 00:00:00 2001 From: KrabSpider <32101466+KrabSpider@users.noreply.github.com> Date: Thu, 6 Feb 2020 03:20:13 -0500 Subject: [PATCH 19/31] Update human_face.dmi --- icons/mob/human_face.dmi | Bin 145686 -> 145856 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 6e95eae9603367cee547662cb7b2df404fc828d8..d0bd3048083ed0af538921ffab75611034cfa3c8 100644 GIT binary patch delta 14741 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 delta 14562 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 From b4faac50a992b4d00837c698c47a2a9d112a167d Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 7 Feb 2020 04:41:16 -0800 Subject: [PATCH 20/31] yeah "null" is bad juju. why did i do that --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 821c819664..137220dfe9 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -41,7 +41,7 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset) // Forced threat level, setting this to zero or higher forces the roundstart threat to the value. GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) -GLOBAL_VAR_INIT(dynamic_storyteller_type, null) +GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) /datum/game_mode/dynamic name = "dynamic mode" From ea096a79eed0bb91c8405e8496af5450a2b9ff24 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 15:41:51 -0600 Subject: [PATCH 21/31] Automatic changelog generation for PR #10957 [ci skip] --- html/changelogs/AutoChangeLog-pr-10957.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10957.yml diff --git a/html/changelogs/AutoChangeLog-pr-10957.yml b/html/changelogs/AutoChangeLog-pr-10957.yml new file mode 100644 index 0000000000..b655b85fb9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10957.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - bugfix: "Dynamic now defaults to \"classic\" storyteller instead of just failing if the vote didn't choose a storyteller." From 6f3bec3ba337c4ab3e2d2c405c74a489a8b1db2e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 15:44:22 -0600 Subject: [PATCH 22/31] Automatic changelog generation for PR #10774 [ci skip] --- html/changelogs/AutoChangeLog-pr-10774.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10774.yml diff --git a/html/changelogs/AutoChangeLog-pr-10774.yml b/html/changelogs/AutoChangeLog-pr-10774.yml new file mode 100644 index 0000000000..f596bdcddb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10774.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - tweak: "nuke explosion is now full dev radius for anti lag purposes" From 1200628e3599a020c9ca4ad465b10ede0986a5c4 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 16:13:24 -0600 Subject: [PATCH 23/31] Automatic changelog generation for PR #10892 [ci skip] --- html/changelogs/AutoChangeLog-pr-10892.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10892.yml diff --git a/html/changelogs/AutoChangeLog-pr-10892.yml b/html/changelogs/AutoChangeLog-pr-10892.yml new file mode 100644 index 0000000000..88f12ef378 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10892.yml @@ -0,0 +1,5 @@ +author: "kevinz000" +delete-after: True +changes: + - refactor: "Guncode and energy guns have been refactored a bit." + - rscadd: "You can now combat mode ight click on an energy gun to attempt to switch firing modes. This only works on guns without right click functions overridden." From 853c66426b9a6f84c2cdd921dffdc185f8b830bd Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 16:23:59 -0600 Subject: [PATCH 24/31] Automatic changelog generation for PR #10935 [ci skip] --- html/changelogs/AutoChangeLog-pr-10935.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10935.yml diff --git a/html/changelogs/AutoChangeLog-pr-10935.yml b/html/changelogs/AutoChangeLog-pr-10935.yml new file mode 100644 index 0000000000..f35855854f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10935.yml @@ -0,0 +1,5 @@ +author: "KrabSpider" +delete-after: True +changes: + - imageadd: "The Van Dyke is no longer Fu Manchu." + - imagedel: "Gets rid of a Fu Manchu imitation." From 8c2019fcbf568d1c082e77d1ffafe36ea560e75d Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 7 Feb 2020 17:58:36 -0500 Subject: [PATCH 25/31] probably fixes plant disk techdisk --- code/modules/research/designs/misc_designs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 3867fa9f23..2bc56f2fbd 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -250,10 +250,10 @@ name = "Plant Data Disk" desc = "A disk for storing plant genetic data." id = "diskplantgene" - build_type = PROTOLATHE + build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL=200, MAT_GLASS=100) build_path = /obj/item/disk/plantgene - category = list("Electronics") + category = list("Electronics","Imported") departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/roastingstick From f4c148d44f6ed8662f997c1bc776217e223b2ff7 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 7 Feb 2020 22:58:47 -0500 Subject: [PATCH 26/31] Fix mining base having holes to space --- _maps/map_files/Mining/Lavaland.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index d4b09ac046..72f68910f7 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -75,7 +75,7 @@ /turf/closed/mineral/random/labormineral/volcanic, /area/lavaland/surface/outdoors) "aA" = ( -/turf/template_noop, +/turf/open/lava/smooth/lava_land_surface, /area/template_noop) "cu" = ( /obj/item/pickaxe, @@ -1181,7 +1181,7 @@ /area/lavaland/surface/outdoors) "ol" = ( /obj/effect/landmark/stationroom/lavaland/station, -/turf/template_noop, +/turf/open/lava/smooth/lava_land_surface, /area/template_noop) "Uq" = ( /obj/docking_port/stationary{ From c9852db0221830f96facee6e95083d9832f3ad1b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 22:06:25 -0600 Subject: [PATCH 27/31] Automatic changelog generation for PR #10966 [ci skip] --- html/changelogs/AutoChangeLog-pr-10966.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10966.yml diff --git a/html/changelogs/AutoChangeLog-pr-10966.yml b/html/changelogs/AutoChangeLog-pr-10966.yml new file mode 100644 index 0000000000..bdc78a2b01 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10966.yml @@ -0,0 +1,4 @@ +author: "r4d6" +delete-after: True +changes: + - bugfix: "Mining no longer lead to spess" From 72a285bb4ddeb22cb0606d80dc6f5435c009248f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 7 Feb 2020 22:12:22 -0600 Subject: [PATCH 28/31] Automatic changelog generation for PR #10960 [ci skip] --- html/changelogs/AutoChangeLog-pr-10960.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10960.yml diff --git a/html/changelogs/AutoChangeLog-pr-10960.yml b/html/changelogs/AutoChangeLog-pr-10960.yml new file mode 100644 index 0000000000..6033533590 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10960.yml @@ -0,0 +1,4 @@ +author: "kappa-sama" +delete-after: True +changes: + - bugfix: "the plant dudes can actually make plant disks now" From 611c8506394e97cb846bd9cb20495cbe8c88d12e Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 8 Feb 2020 00:31:46 -0800 Subject: [PATCH 29/31] all you need to understand is everything you know is wrong --- code/modules/antagonists/_common/antag_datum.dm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 0c05afb155..187ca66705 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -120,15 +120,16 @@ GLOBAL_LIST_EMPTY(antagonists) SEND_SIGNAL(owner.current, COMSIG_CLEAR_MOOD_EVENT, "antag_moodlet") /datum/antagonist/proc/remove_blacklisted_quirks() - var/mob/living/L = owner + var/mob/living/L = owner.current if(istype(L)) - var/list/cut = list() - cut = SSquirks.filter_quirks(L.roundstart_quirks,blacklisted_quirks) - for(var/q in cut) + var/list/my_quirks = L.client?.prefs.all_quirks.Copy() + SSquirks.filter_quirks(my_quirks,blacklisted_quirks) + for(var/q in L.roundstart_quirks) var/datum/quirk/Q = q - if(Q.antag_removal_text) - to_chat(L, "[Q.antag_removal_text]") - L.remove_quirk(Q.type) + if(!(SSquirks.quirk_name_by_path(Q.type) in my_quirks)) + if(initial(Q.antag_removal_text)) + to_chat(L, "[initial(Q.antag_removal_text)]") + L.remove_quirk(Q.type) //Returns the team antagonist belongs to if any. /datum/antagonist/proc/get_team() From 1f506e2f28eedc45392e4978d976135199ee839d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 8 Feb 2020 02:36:13 -0600 Subject: [PATCH 30/31] Automatic changelog generation for PR #10974 [ci skip] --- html/changelogs/AutoChangeLog-pr-10974.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10974.yml diff --git a/html/changelogs/AutoChangeLog-pr-10974.yml b/html/changelogs/AutoChangeLog-pr-10974.yml new file mode 100644 index 0000000000..7f668256b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10974.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - bugfix: "antag quirk blacklisting works now" From c665ed7e36b6a89888dffa2118c0219acfc73748 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 9 Feb 2020 00:05:17 +0100 Subject: [PATCH 31/31] Cecilia need helpies in maint, nya --- tools/travis/build_tgui.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/travis/build_tgui.sh diff --git a/tools/travis/build_tgui.sh b/tools/travis/build_tgui.sh old mode 100644 new mode 100755