From 9f01db07efafdc4ca0f8d5a40c456fdda0f97cb5 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:07:33 -0500 Subject: [PATCH] Rebalances the 3 least used non temp or illegal guns, + BSG (#27476) * guns * bsg fix, shield * lwap scoped always hits crawling mobs * decrease scope time * Apply suggestions from code review Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> --------- Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> --- code/__HELPERS/trait_helpers.dm | 1 + code/_globalvars/traits.dm | 2 + .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/mob/mob_movement.dm | 2 +- .../projectiles/ammunition/energy_lens.dm | 3 +- code/modules/projectiles/guns/energy/laser.dm | 8 +-- .../projectiles/guns/energy/special_eguns.dm | 8 +++ .../projectile/energy_projectiles.dm | 50 +++++++++++++------ code/modules/projectiles/projectile_base.dm | 3 ++ 9 files changed, 57 insertions(+), 22 deletions(-) diff --git a/code/__HELPERS/trait_helpers.dm b/code/__HELPERS/trait_helpers.dm index b8501ede03e..b8af1ffe715 100644 --- a/code/__HELPERS/trait_helpers.dm +++ b/code/__HELPERS/trait_helpers.dm @@ -237,6 +237,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NPC_ZOMBIE "npc_zombie" // A trait for checking if a zombie should act like an NPC and attack #define TRAIT_ABSTRACT_HANDS "abstract_hands" // Mobs with this trait can only pick up abstract items. #define TRAIT_LANGUAGE_LOCKED "language_locked" // cant add/remove languages until removed (excludes babel because fuck everything i guess) +#define TRAIT_BSG_IMMUNE "bsg_immune" // Granted by BSG when held, prevents BSG AOE from hitting you #define TRAIT_PLAYING_CARDS "playing_cards" #define TRAIT_EMP_IMMUNE "emp_immune" //The mob will take no damage from EMPs #define TRAIT_EMP_RESIST "emp_resist" //The mob will take less damage from EMPs diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 15b11466300..2b58a529175 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -103,7 +103,9 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_LANGUAGE_LOCKED" = TRAIT_LANGUAGE_LOCKED, "TRAIT_NON_INFECTIOUS_ZOMBIE" = TRAIT_NON_INFECTIOUS_ZOMBIE, "TRAIT_CANNOT_PULL" = TRAIT_CANNOT_PULL, + "TRAIT_BSG_IMMUNE" = TRAIT_BSG_IMMUNE, "TRAIT_FLYING" = TRAIT_FLYING + ), /datum/mind = list( diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index f44685b0337..f50496e4ff5 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -842,7 +842,7 @@ emp_act return TRUE /mob/living/carbon/human/projectile_hit_check(obj/item/projectile/P) - return (HAS_TRAIT(src, TRAIT_FLOORED) || HAS_TRAIT(src, TRAIT_NOKNOCKDOWNSLOWDOWN)) && !density // hit mobs that are intentionally lying down to prevent combat crawling. + return (HAS_TRAIT(src, TRAIT_FLOORED) || HAS_TRAIT(src, TRAIT_NOKNOCKDOWNSLOWDOWN)) && !density && !(P.always_hit_living_nondense && (stat != DEAD)) // hit mobs that are intentionally lying down to prevent combat crawling. /mob/living/carbon/human/canBeHandcuffed() return has_left_hand() || has_right_hand() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 32e73d7d1a4..dedebe6f549 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -21,7 +21,7 @@ return (!mover.density || !density || horizontal) /mob/proc/projectile_hit_check(obj/item/projectile/P) - return !density + return !(P.always_hit_living_nondense && (stat != DEAD)) && !density /client/verb/toggle_throw_mode() set hidden = 1 diff --git a/code/modules/projectiles/ammunition/energy_lens.dm b/code/modules/projectiles/ammunition/energy_lens.dm index 09ecd950aa9..e899f55e0f3 100644 --- a/code/modules/projectiles/ammunition/energy_lens.dm +++ b/code/modules/projectiles/ammunition/energy_lens.dm @@ -255,7 +255,6 @@ /obj/item/ammo_casing/energy/arc_revolver fire_sound = 'sound/magic/lightningbolt.ogg' //New sound - e_cost = 125 //8 shots? select_name = "lightning beam" //I guess muzzle_flash_color = LIGHT_COLOR_FADEDPURPLE // Depends on sprite projectile_type = /obj/item/projectile/energy/arc_revolver @@ -280,7 +279,7 @@ select_name = null //If the select name is null, it does not send a message of switching modes to the user, important on the pistol. /obj/item/ammo_casing/energy/charged_plasma - projectile_type = /obj/item/projectile/energy/charged_plasma + projectile_type = /obj/item/projectile/homing/charged_plasma e_cost = 0 //Charge is used when you charge the gun. Prevents issues. muzzle_flash_color = LIGHT_COLOR_FADEDPURPLE fire_sound = 'sound/weapons/marauder.ogg' //Should be different enough to get attention diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 07d38c92ee7..ac2269034d4 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -237,7 +237,7 @@ /obj/item/gun/energy/lwap/Initialize(mapload) . = ..() - AddComponent(/datum/component/scope, range_modifier = 2, time_to_scope = 3 SECONDS, flags = SCOPE_MOVEMENT_CANCELS | SCOPE_TURF_ONLY | SCOPE_NEED_ACTIVE_HAND) + AddComponent(/datum/component/scope, range_modifier = 2, time_to_scope = 2 SECONDS, flags = SCOPE_MOVEMENT_CANCELS | SCOPE_TURF_ONLY | SCOPE_NEED_ACTIVE_HAND) /obj/item/gun/energy/lwap/on_scope_success(mob/living/user) to_chat(user, "SCOPE_CREEPER_[rand(1, 9999)] Online.") @@ -258,7 +258,7 @@ muzzle_flash_strength = MUZZLE_FLASH_STRENGTH_STRONG select_name = null fire_sound = 'sound/weapons/marauder.ogg' - delay = 5 SECONDS + delay = 2 SECONDS /obj/item/ammo_casing/energy/laser/sniper/pierce projectile_type = /obj/item/projectile/beam/laser/sniper/pierce @@ -287,8 +287,10 @@ /obj/item/projectile/beam/laser/sniper/pierce forcedodge = 1 // Can pierce one non wall thing. speed = 0.5 + always_hit_living_nondense = TRUE //This means if you are scoped in sniping at crit xenomorphs or crit humans, you can always hit them even if you do not directly click on them /// Have we hit an r_wall? If we have, don't pierce it again so we don't become too effective on reinforced locations (AI sat) var/hit_a_r_wall = FALSE + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSGIRDER /obj/item/projectile/beam/laser/sniper/pierce/prehit(atom/target) if(istype(target, /turf/simulated/wall/r_wall)) @@ -296,7 +298,7 @@ hit_a_r_wall = TRUE if(!forcedodge) forcedodge++ - else if((isturf(target) || istype(target, /obj/structure/alien/resin)) && !forcedodge) + else if((isturf(target) || istype(target, /obj/structure/alien/resin) || istype(target, /obj/structure/spider)) && !forcedodge) forcedodge++ ..() diff --git a/code/modules/projectiles/guns/energy/special_eguns.dm b/code/modules/projectiles/guns/energy/special_eguns.dm index 27032627abe..46c042baf83 100644 --- a/code/modules/projectiles/guns/energy/special_eguns.dm +++ b/code/modules/projectiles/guns/energy/special_eguns.dm @@ -684,6 +684,14 @@ else return ..() +/obj/item/gun/energy/bsg/equipped(mob/user, slot, initial) + . = ..() + ADD_TRAIT(user, TRAIT_BSG_IMMUNE, "[UID(src)]") + +/obj/item/gun/energy/bsg/dropped(mob/user, silent) + . = ..() + REMOVE_TRAIT(user, TRAIT_BSG_IMMUNE, "[UID(src)]") + /obj/item/gun/energy/bsg/process_fire(atom/target, mob/living/user, message = TRUE, params, zone_override, bonus_spread = 0) if(!has_bluespace_crystal) to_chat(user, "[src] has no bluespace crystal to power it!") diff --git a/code/modules/projectiles/projectile/energy_projectiles.dm b/code/modules/projectiles/projectile/energy_projectiles.dm index 15fb2bbbd8d..844bf431d63 100644 --- a/code/modules/projectiles/projectile/energy_projectiles.dm +++ b/code/modules/projectiles/projectile/energy_projectiles.dm @@ -61,8 +61,9 @@ name = "orb of pure bluespace energy" icon_state = "bluespace" impact_effect_type = /obj/effect/temp_visual/bsg_kaboom - damage = 60 + damage = 90 damage_type = BURN + armour_penetration_flat = 50 range = 9 knockdown = 4 SECONDS //This is going to knock you off your feet eyeblur = 10 SECONDS @@ -79,7 +80,7 @@ /obj/item/projectile/energy/bsg/on_hit(atom/target) . = ..() - kaboom() + kaboom(target) qdel(src) /obj/item/projectile/energy/bsg/on_range() @@ -87,22 +88,22 @@ new /obj/effect/temp_visual/bsg_kaboom(loc) ..() -/obj/item/projectile/energy/bsg/proc/kaboom() +/obj/item/projectile/energy/bsg/proc/kaboom(atom/target) playsound(src, 'sound/weapons/bsg_explode.ogg', 75, TRUE) for(var/mob/living/M in hearers(7, src)) //No stuning people with thermals through a wall. + if(M == target) + continue var/floored = FALSE - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/gun/energy/bsg/N = locate() in H - if(N) - to_chat(H, "[N] deploys an energy shield to project you from [src]'s explosion.") - continue + if(HAS_TRAIT(M, TRAIT_BSG_IMMUNE)) + to_chat(M, "Your B.S.G deploys an energy shield to project you from [src]'s explosion.") + new /obj/effect/temp_visual/at_shield(get_turf(M), M) + continue var/distance = (1 + get_dist(M, src)) if(prob(min(400 / distance, 100))) //100% chance to hit with the blast up to 3 tiles, after that chance to hit is 80% at 4 tiles, 66.6% at 5, 57% at 6, and 50% at 7 - if(prob(min(150 / distance, 100)))//100% chance to upgraded to a stun as well at a direct hit, 75% at 1 tile, 50% at 2, 37.5% at 3, 30% at 4, 25% at 5, 21% at 6, and finaly 19% at 7. This is calculated after the first hit however. + if(prob(min(200 / distance, 100)))//100% chance to upgraded to a stun as well at a direct hit, 100% at 1 tile, 66% at 2, 50% at 3, 40% at 4, 33% at 5, 28.5% at 6, and finaly 25% at 7. This is calculated after the first hit however. floored = TRUE - M.apply_damage((rand(15, 30) * (1.1 - distance / 10)), BURN) //reduced by 10% per tile - add_attack_logs(src, M, "Hit heavily by [src]") + M.apply_damage((rand(60, 80) * (1.1 - distance / 10)), BURN) //reduced by 10% per tile + add_attack_logs(firer, M, "Hit heavily by [src]") if(floored) to_chat(M, "You see a flash of briliant blue light as [src] explodes, knocking you to the ground and burning you!") M.KnockDown(4 SECONDS) @@ -113,8 +114,10 @@ M.IgniteMob() else to_chat(M, "You feel the heat of the explosion of [src], but the blast mostly misses you.") - add_attack_logs(src, M, "Hit lightly by [src]") - M.apply_damage(rand(1, 5), BURN) + add_attack_logs(firer, M, "Hit lightly by [src]") + M.apply_damage(rand(20, 25), BURN) + if(ROLE_BLOB in M.faction) + M.apply_damage(rand(20, 25), BURN) //Ensures it clears all blob spores on the screen without fail. /obj/item/projectile/energy/weak_plasma name = "plasma bolt" @@ -122,14 +125,31 @@ damage = 12.5 damage_type = BURN -/obj/item/projectile/energy/charged_plasma +/obj/item/projectile/homing/charged_plasma name = "charged plasma bolt" icon_state = "plasma_heavy" damage = 45 damage_type = BURN + flag = "energy" armour_penetration_flat = 10 // It can have a little armor pen, as a treat. Bigger than it looks, energy armor is often low. shield_buster = TRUE reflectability = REFLECTABILITY_PHYSICAL //I will let eswords block it like a normal projectile, but it's not getting reflected, and eshields will take the hit hard. Carp still can reflect though, screw you. + var/reached_target = FALSE + +/obj/item/projectile/homing/charged_plasma/pixel_move(trajectory_multiplier) + homing_active = FALSE + if(isturf(original)) + return ..() //It gets weird if it is a turf. Turfs don't move anyway. + if(reached_target || get_turf(original) == get_turf(src)) + reached_target = TRUE + return ..() + var/fake_Angle = Angle + if(fake_Angle < 0) + fake_Angle += 360 + if(abs(get_angle(get_turf(src), original) - fake_Angle) > 45) + return ..() + homing_active = TRUE + ..() /obj/item/projectile/energy/arc_revolver name = "arc emitter" diff --git a/code/modules/projectiles/projectile_base.dm b/code/modules/projectiles/projectile_base.dm index f10e7ea0a22..0130b85e8ab 100644 --- a/code/modules/projectiles/projectile_base.dm +++ b/code/modules/projectiles/projectile_base.dm @@ -88,6 +88,9 @@ ///Has the projectile been fired? var/has_been_fired = FALSE + /// Does this projectile hit living non dense mobs? + var/always_hit_living_nondense = FALSE + //Hitscan var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored. var/list/beam_segments //assoc list of datum/point_precise or datum/point_precise/vector, start = end. Used for hitscan effect generation.