[SR REPLACEMENT] Buffs/Reworks plasma marksman (#4572)

## About The Pull Request

Special thanks to offwrldr/Bangle for the unique sound effects of the
explosion.

<img width="1100" height="506" alt="plasma3"
src="https://github.com/user-attachments/assets/f7a30509-39a7-48ea-85e8-965e8c57cef1"
/>

MEET THE PLASMA MARKSMAN:
https://youtu.be/niNd51UAtBk

## Why It's Good For The Game

I will _**attempt**_ to write short instead of creating an essay here.


With the Murphy, the leeway for crew pistols lessened, and frankly my
core belief is that when something is added, it should add interesting
new gameplay elements, **things that are interesting to both fight with
and against**. Items that deviate from the regular gameplay loop of
shooting but in X manner and allow for expansion in the depth of combat
- and with all that in mind, our goal was to deliver on that. To **keep
the core of the weapon's mechanics, expand upon them and integrate it
with their faction's lore as a cherry on top.**


The plasma marksman (sharpshooter) is in an utterly horrid state. I
could go on to list how it's impossible to shoot someone walking away
from you in a straight line, how even if you hit them - your shots will
deal 3 damage per round on most antagonist armours, how it's huge clip
is an issue in the face of now-reduced HP values.

But it doesn't have to be that way. It wasn't just another military
weapon, it's part of a charming faction with their own gimmicks shown
through their equipment and a concept that just fits SS13 flavour-wise,
but not in gameplay.

The old weapon was capable of use almost exclusively on the defense, as
any gun would outperform it on the offense, and even when on it's home
turf - the weakness to armour wasn't helping it's case as "THE cheap
self-defense option for second amendment enjoyers".


### Why did we keep the magazine?
Magazine weapons have an element of pressure that needs a careful
balancing act to avoid becoming a plain spam weapon that loses it's
depth and becomes oppressive against targets due to the lack of need to
break in it's shooting and how easy it is to hoard ammo in a box. The
combination of consistency, wounds, a bag of holding full of rounds
(hyperbolically) and raw damage output are frankly "ass" to fight.

What makes this weapon different, however, is that the amount of rounds
isn't actually the true depth of the magazine. As an ingenious and
frankly wonderful suggester pitched, the gun's able to function normally
as it's projectile speed is high, however, careful dodging or misses
from the wielder are punished as the gun drops in reliability - it wears
down, and the consistent theme you will see across it, is "How Badly Do
You Want It?". The buffer is less of an issue on defense, where a
regular civilian would need it most, but while it ups the difficulty of
offensive kills and chasing after a target, say, an attacker, to finish
them off - it doesn't prevent it.

In this way, the gun is defense-biased, with a possibility for offensive
action that is dependant on how well can the user cater to their gun,
rather than having it mold to fit their needs exactly in every situation
ever. This will prevent it from becoming oppressive, it will make
split-second decisions all the more valuable, and lastly, players who
manage to plan ahead to lead fights to terrains where they know the
downsides aren't as prominent are rewarded with a much smaller penalty
to consistently landing shots, and so will those who use it in tandem
with tools to slow their opponents down.

### What is the point of the overclock mode?

The overclock mode is once again, a question, of How Badly Do You Want
it? There's two situations where it is primarily going to be used, one
is when you *need* to pick someone off, and one is when you know you
have no chance.

Let's start with the first:
Now, even preparation can go awry when your target rolls up in
freshly-bought armour, or they manage to escape your kill-room, or you
miss too many shots. This is where you can double down:

You gamble, that as you take 25 damage over the course of 10 seconds,
with the improved projectile speed and technically increased armour
penetration you will put the person you want dead into crit before your
gun explodes and people will hear the commotion. Whether it's worth it,
whether you believe yourself to be able to do it, or whether you have
the HP or escape routes to commit to this further is dependant on you
and you only.

In the second situation, meanwhile:
You risk going down earlier than you wish, but leaving a calling card of
where you've been, and now remember, whether people hear it and whether
people come is not guaranteed - and what's not guaranteed, is that by
injuring yourself and announcing that you're out of better options, the
assailant won't disengage, reset, and get you again. It's a careful game
of chicken and who managed to out-position who, as well as who can more
accurately gauge their own damage output versus what they risk taking by
comitting to a kill, or the overclock.

The practical example of the second situation is fighting a redsuit,
while the first would be attempting to use the gun to assasinate a
person (conveniently disposing of the murder weapon).


**That sounds like the old backup on the sechailer!**

A one time use, baitable, force-able by EMP, non-global and non-pinpoint
accurate backup. It's a conjunction of putting it in your hands and in
people's hands around, so no matter whether people show up or not - you
gave yourself at least a bit of advantage, and at least left a trail.

### Conclusions:
Merge my PR.

## Changelog
🆑
balance: The plasma marksman has been overhauled. It now comes with an
overcharge mode and progressive projectile speed.
/🆑

---------

Co-authored-by: xPokee <catmc8565@gmail.com>
This commit is contained in:
Ssalty
2025-11-11 19:19:02 +01:00
committed by GitHub
co-authored by xPokee
parent 3c07601fef
commit c3ed080466
7 changed files with 136 additions and 10 deletions
@@ -19,3 +19,8 @@
wound_bonus = -50 // However we do not very much against armor
pass_flags = PASSTABLE | PASSGRILLE // His ass does NOT pass through glass!
weak_against_armour = TRUE
/obj/projectile/beam/laser/plasma_glob/supercharged
name = "overcharged plasma globule"
icon_state = "plasma_glob_super"
weak_against_armour = FALSE
@@ -38,14 +38,15 @@
/obj/item/ammo_box/magazine/recharge/plasma_battery
name = "plasma power pack"
desc = "A rechargeable, detachable battery that serves as a power source for plasma projectors."
desc = "A detachable battery that serves as a power source for plasma projectors."
icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/szot_dynamica/ammo.dmi'
base_icon_state = "plasma_battery"
icon_state = "plasma_battery"
multiple_sprites = AMMO_BOX_FULL_EMPTY
ammo_type = /obj/item/ammo_casing/energy/laser/plasma_glob
ammo_type = list(/obj/item/ammo_casing/energy/laser/plasma_glob)
caliber = CALIBER_LASER
max_ammo = 15
var/overcharged = FALSE
/obj/item/ammo_box/magazine/recharge/plasma_battery/update_icon_state() // FUCK YOU /OBJ/ITEM/AMMO_BOX/MAGAZINE/RECHARGE
. = ..()
@@ -73,20 +73,30 @@
bolt_type = BOLT_TYPE_OPEN
fire_delay = 0.6 SECONDS
spread = 2.5
actions_types = list(/datum/action/item_action/activate_plasma_overclock)
var/current_projspeed_mod = 1.5 // default so the first shot always is at full, duh
var/overclocking = FALSE
var/self_destruct_timer
projectile_damage_multiplier = 3 // 30 damage a shot
projectile_wound_bonus = 10 // +55 of the base projectile, burn baby burn
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_MOVABLE_POST_THROW, PROC_REF(shakeit))
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/give_manufacturer_examine()
AddElement(/datum/element/manufacturer_examine, COMPANY_SZOT)
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/examine(mob/user)
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/examine(mob/user, overclocking)
. = ..()
if(overclocking)
. += span_notice("The weapon is glowing red and steaming!")
. += span_notice("You can <b>examine closer</b> to learn a little more about this weapon.")
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/examine_more(mob/user)
. = ..()
. += "The 'Gwiazda' is a further refinement of the 'Słońce' design. with improved \
energy cycling, magnetic launchers built to higher precision, and an overall more \
ergonomic design. While it still fails to perform against armor, the weapon is \
@@ -97,6 +107,107 @@
return .
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
. = ..()
if(overclocking && chambered)
chambered.projectile_type = /obj/projectile/beam/laser/plasma_glob/supercharged
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/update_projspeed(mob/user)
var/shots_in_mag = src.get_ammo()
if(overclocking)
projectile_speed_multiplier = 1.6
else if(shots_in_mag >= 13)
projectile_speed_multiplier = 1.5
else if(shots_in_mag >= 10 && shots_in_mag <= 12)
projectile_speed_multiplier = 1.3
else if(shots_in_mag >= 8 && shots_in_mag <= 9)
projectile_speed_multiplier = 1.2
else if(shots_in_mag >= 5 && shots_in_mag <= 7)
projectile_speed_multiplier = 1.1
else if(shots_in_mag >= 1 && shots_in_mag <= 4)
projectile_speed_multiplier = 1.0
else
projectile_speed_multiplier = 0.8
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/activate_oveclock(mob/user, current_proj_speed)
/datum/action/item_action/activate_plasma_overclock //Gotta be hud, its un-revertable. Imagine misclicking and blowing up your gun without knowing...
button_icon = 'icons/obj/weapons/guns/ammo.dmi'
button_icon_state = "9x19p"
name = "Overclock Plasma Charger"
check_flags = AB_CHECK_INCAPACITATED|AB_CHECK_CONSCIOUS
//Checks if we can overclock the gun, if so, starts the process
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/ui_action_click(mob/user, actiontype)
if(!istype(actiontype, /datum/action/item_action/activate_plasma_overclock))
return ..()
if(!overclocking)
overclocking = !overclocking
balloon_alert(user, "[overclocking ? "Plasma coils overheated, it's going to blow!" : "It's not shutting down!"]")
if(overclocking)
overclock(user)
playsound(src, 'sound/effects/magic/lightning_chargeup.ogg', 50)
update_item_action_buttons()
//Base overclock proc, changes our projectile for releasing the flare + explosion
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/overclock(mob/living/user, slot)
if(user)
START_PROCESSING(SSprocessing, src)
addtimer(CALLBACK(src, PROC_REF(audio_warning)), 7 SECONDS)
addtimer(CALLBACK(src, PROC_REF(kaboom)), 10 SECONDS)
shakeit()
add_shared_particles(/particles/smoke/steam)
/obj/item/ammo_casing/energy/laser/plasma_glob/ready_proj(atom/target, mob/living/user, quiet, zone_override, atom/fired_from)
var/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/gun = fired_from
if(istype(gun) && gun.overclocking)
loaded_projectile.name = "overcharged plasma globule"
loaded_projectile.icon_state = "plasma_glob_super"
loaded_projectile.weak_against_armour = FALSE
gun.update_projspeed(user)
. = ..()
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/shakeit()
SIGNAL_HANDLER
if(!overclocking)
return
spasm_animation()
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/kaboom(mob/living/user)
STOP_PROCESSING(SSprocessing, src)
var/turf/last_surprise = get_turf(src)
explosion(src, light_impact_range = 1, flame_range = 3, explosion_cause = src)
last_surprise.add_liquid(/datum/reagent/toxin/plasma, 3, no_react = FALSE, chem_temp = 300)
new /obj/effect/hotspot(last_surprise)
UnregisterSignal(src, COMSIG_MOVABLE_POST_THROW)
remove_shared_particles(/particles/bonfire)
qdel(src)
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/proc/audio_warning(mob/living/user)
playsound(src, 'modular_zubbers/sound/weapons/plasma_explosion.ogg', 100, FALSE, 20, , , , TRUE)
for(var/mob/living/carbon/M in orange(20, src))
if(!HAS_TRAIT(M, TRAIT_DEAF))
to_chat(M, span_warning("You hear a distant pulse of energy, as if a miniature reactor blasting out a shockwave from afar..."))
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/process(seconds_per_tick)
var/mob/living/carbon/wielder = ismob(loc) ? loc : null
var/obj/item/bodypart/affecting = wielder.get_bodypart("[(wielder.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(isnull(wielder))
return
if(isnull(affecting))
return
if(wielder.is_holding(src))
wielder.apply_damage(2.5, BURN, affecting)
to_chat(wielder, span_warning("[src] burns your hand, it's too hot!"))
/obj/item/gun/ballistic/automatic/pistol/plasma_marksman/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
if(prob(15 * severity))
overclock()
// A revolver, but it can hold shotgun shells
// Woe, buckshot be upon ye
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

@@ -49,6 +49,21 @@
/datum/supply_pack/goody/double_barrel
cost = PAYCHECK_COMMAND * 10 //1400 is too much considering the combat shotgun is 1500 for 1
/datum/supply_pack/goody/plasma_marksman
name = "Gwiazda Plasma Sharpshooters Single-pack"
desc = "Contains a Gwiazda Plasma Sharpshooter and one plasma battery free of additional charge."
contains = list(/obj/item/gun/ballistic/automatic/pistol/plasma_marksman = 1,
/obj/item/ammo_box/magazine/recharge/plasma_battery = 1)
access_view = ACCESS_WEAPONS
cost = PAYCHECK_COMMAND * 4
/datum/supply_pack/goody/plasma_marksman_ammo
name = "Plasma Battery Single-pack"
desc = "Contains a single plasma battery."
contains = list(/obj/item/ammo_box/magazine/recharge/plasma_battery = 1)
access_view = ACCESS_WEAPONS
cost = PAYCHECK_COMMAND * 1
/datum/supply_pack/goody/mars_single
special = FALSE
@@ -53,12 +53,6 @@
/obj/item/storage/backpack/duffelbag/deforest_medkit/stocked,
)
/datum/supply_pack/security/plasma_marksman
name = "Gwiazda Plasma Sharpshooter Single-Pack"
crate_name = "Gwiadza Plasma Sharpshooter Crate"
desc = "Contains a Gwiazda Plasma Sharpshooter and one plasma battery for it."
contains = list(/obj/item/gun/ballistic/automatic/pistol/plasma_marksman = 1,
/obj/item/ammo_box/magazine/recharge/plasma_battery = 1)
cost = CARGO_CRATE_VALUE * 10
access = ACCESS_SECURITY
Binary file not shown.