Skip to content

Commit

Permalink
Adds holo-targetting Vulture rounds (#5719)
Browse files Browse the repository at this point in the history
# About the pull request

Adds holo-targetting rounds for the Vulture. Their characteristics are:

- They deal SIGNIFICANTLY LESS damage, down from 400 to 60.
- They cannot penetrate walls nor mobs.
- They do not slow down mobs that are hit.
- When they hit a target, they will "mark them for death", inflicting a
holo stack value of 333. This means that they will take 33% more damage
from all sources. A balloon alert will be shown to all nearby mobs
indicating the mark, along with the holo-target aura itself.
- **They have IFF.**


![image](https://github.com/cmss13-devs/cmss13/assets/17518895/69fc22e2-316d-43b5-87fd-08e2a5e9ba2b)


The bullet increases the target's max capacity for holo stacks increases
by 233 (to 333 in total). Any holo-targetting rounds that hit the mob
will be able utilize this cap increase. The holo stacks will completely
deplete after 35-ish seconds from the initial impact. It takes 5 seconds
for the stack drain to begin, with every second passing after that
removing 10 stacks. Other holo-targetting rounds will not modify the
rate of stack depletion, keeping it at a firm 10 stacks per second. They
will, however, stop the drain for 5 seconds.


![image](https://github.com/cmss13-devs/cmss13/assets/17518895/ad85d159-344b-407a-8158-23eafbf0824a)


# Explain why it's good for the game

This gun is really fun for the users, encouraging a buddy system that I
feel the game desperately needs more of. I will admit that being hit
with 400 damage, 50 AP from 2 screens away is not engaging for the
opposing side, giving them no counterplay at all.

With these bullets, the Vulture can take a supporting role for the
marines instead of being an off-screen death cannon. 33% is a decent
damage increase, but it requires multiple marines around the target to
truly take advantage of it. Compared to the payoff that a regular
Vulture round gives, the lack of IFF for those bullets is
understandable. However, given that you NEED friendly troops to get any
use out of these rounds, I've given the rounds IFF (with Zonespace's
blessing) to broaden the areas and situations where it could get used.

The ammo is still limited as ever, so the sniper team will have to pick
their shots. Given how weak the rounds are in comparison to the standard
ones, they should rarely be able to snipe off targets on their own (in a
rare circumstance that they spot a half-crit xeno, an M4RA with a 4x
scope can finish them off just the same).

Is it weak? Too situational? Maybe, but the weapon is very interesting
mechanically and I would just like to see it in play a bit more.

The weapon is still ADMIN-ONLY. This will only give the admins a less
blunt variant of the Vulture if they choose to spawn in it.

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

How being hit feels:


https://github.com/cmss13-devs/cmss13/assets/17518895/a576629e-7961-4421-9932-d707e12477f1

General test:



https://github.com/cmss13-devs/cmss13/assets/17518895/e2fbb117-1cf9-4945-b87a-d63e68f62a10

Bonus damage testing. The M41A does a base damage of 44. A holo-stack of
333 will result in roughly 44 * 1.33 = 59 damage.


![image](https://github.com/cmss13-devs/cmss13/assets/17518895/d230fc11-34e6-468e-89c3-394696c9b3e1)


</details>


# Changelog
:cl:
add: The Vulture can now be loaded with holo-targetting rounds which
have severely hampered ballistic performance, but mark any target that
is hit, increasing their damage taken by 33% for a brief period of time.
/:cl:
  • Loading branch information
VileBeggar committed Feb 20, 2024
1 parent 7b58399 commit fe0134e
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 17 deletions.
9 changes: 7 additions & 2 deletions code/datums/ammo/bullet/rifle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@
/datum/ammo/bullet/rifle/holo_target
name = "holo-targeting rifle bullet"
damage = 30
/// inflicts this many holo stacks per bullet hit
var/holo_stacks = 10
/// modifies the default cap limit of 100 by this amount
var/bonus_damage_cap_increase = 0
/// multiplies the default drain of 5 holo stacks per second by this amount
var/stack_loss_multiplier = 1

/datum/ammo/bullet/rifle/holo_target/on_hit_mob(mob/M, obj/projectile/P)
/datum/ammo/bullet/rifle/holo_target/on_hit_mob(mob/hit_mob, obj/projectile/bullet)
. = ..()
M.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time)
hit_mob.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time, bonus_damage_cap_increase, stack_loss_multiplier)

/datum/ammo/bullet/rifle/holo_target/hunting
name = "holo-targeting hunting bullet"
Expand Down
22 changes: 22 additions & 0 deletions code/datums/ammo/bullet/sniper.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_penetrating/heavy)
))

/datum/ammo/bullet/sniper/anti_materiel/vulture/holo_target
name = "holo-targeting anti-materiel sniper bullet"
damage = 60 // it's a big bullet but its purpose is to support marines, not to kill enemies by itself
/// inflicts this many holo stacks per bullet hit
var/holo_stacks = 333
/// modifies the default cap limit of 100 by this amount
var/bonus_damage_cap_increase = 233
/// multiplies the default drain of 5 holo stacks per second by this amount
var/stack_loss_multiplier = 2

/datum/ammo/bullet/sniper/anti_materiel/vulture/holo_target/on_hit_mob(mob/hit_mob, obj/projectile/bullet)
hit_mob.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time, bonus_damage_cap_increase, stack_loss_multiplier)
playsound(hit_mob, 'sound/weapons/gun_vulture_mark.ogg', 40)
to_chat(hit_mob, isxeno(hit_mob) ? SPAN_XENOHIGHDANGER("It feels as if we were MARKED FOR DEATH!") : SPAN_HIGHDANGER("It feels as if you were MARKED FOR DEATH!"))
hit_mob.balloon_alert_to_viewers("marked for death!")

// the effect should be limited to one target, with IFF to compensate how hard it will be to hit these shots
/datum/ammo/bullet/sniper/anti_materiel/vulture/holo_target/set_bullet_traits()
LAZYADD(traits_to_give, list(
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff)
))

/datum/ammo/bullet/sniper/elite
name = "supersonic sniper bullet"

Expand Down
10 changes: 7 additions & 3 deletions code/datums/ammo/bullet/special_ammo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@
/datum/ammo/bullet/smartgun/holo_target //Royal marines smartgun bullet has only diff between regular ammo is this one does holostacks
name = "holo-targeting smartgun bullet"
damage = 30
///Stuff for the HRP holotargetting stacks
/// inflicts this many holo stacks per bullet hit
var/holo_stacks = 15
/// modifies the default cap limit of 100 by this amount
var/bonus_damage_cap_increase = 0
/// multiplies the default drain of 5 holo stacks per second by this amount
var/stack_loss_multiplier = 1

/datum/ammo/bullet/smartgun/holo_target/on_hit_mob(mob/M, obj/projectile/P)
/datum/ammo/bullet/smartgun/holo_target/on_hit_mob(mob/hit_mob, obj/projectile/bullet)
. = ..()
M.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time)
hit_mob.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time, bonus_damage_cap_increase, stack_loss_multiplier)

/datum/ammo/bullet/smartgun/holo_target/ap
name = "armor-piercing smartgun bullet"
Expand Down
13 changes: 10 additions & 3 deletions code/datums/ammo/shrapnel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,17 @@
shrapnel_chance = 0
shell_speed = AMMO_SPEED_TIER_3//she fast af boi
penetration = ARMOR_PENETRATION_TIER_5

/datum/ammo/bullet/shrapnel/hornet_rounds/on_hit_mob(mob/M, obj/projectile/P)
/// inflicts this many holo stacks per bullet hit
var/holo_stacks = 10
/// modifies the default cap limit of 100 by this amount
var/bonus_damage_cap_increase = 0
/// multiplies the default drain of 5 holo stacks per second by this amount
var/stack_loss_multiplier = 1

/datum/ammo/bullet/shrapnel/hornet_rounds/on_hit_mob(mob/hit_mob, obj/projectile/bullet)
. = ..()
M.AddComponent(/datum/component/bonus_damage_stack, 10, world.time)
hit_mob.AddComponent(/datum/component/bonus_damage_stack, holo_stacks, world.time, bonus_damage_cap_increase, stack_loss_multiplier)


/datum/ammo/bullet/shrapnel/incendiary
name = "flaming shrapnel"
Expand Down
34 changes: 25 additions & 9 deletions code/datums/components/bonus_damage_stack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@
var/bonus_damage_cap = 100
/// Last world.time that the afflicted was hit by a holo-targeting round.
var/last_stack
/// extra cap limit added by more powerful bullets
var/bonus_damage_cap_increase = 0
/// multiplies the BONUS_DAMAGE_STACK_LOSS_PER_SECOND calculation, modifying how fast we lose holo stacks
var/stack_loss_multiplier = 1

/datum/component/bonus_damage_stack/Initialize(bonus_damage_stacks, time)
/datum/component/bonus_damage_stack/Initialize(bonus_damage_stacks, time, bonus_damage_cap_increase, stack_loss_multiplier)
. = ..()
src.bonus_damage_stacks = bonus_damage_stacks
src.stack_loss_multiplier = stack_loss_multiplier
src.bonus_damage_cap = initial(bonus_damage_cap) + bonus_damage_cap_increase // this way it will never increase over the intended limit
if(!time)
time = world.time
src.last_stack = time

/datum/component/bonus_damage_stack/InheritComponent(datum/component/bonus_damage_stack/BDS, i_am_original, bonus_damage_stacks, time)
/datum/component/bonus_damage_stack/InheritComponent(datum/component/bonus_damage_stack/BDS, i_am_original, bonus_damage_stacks, time, bonus_damage_cap_increase, stack_loss_multiplier)
. = ..()
if(!BDS)
src.bonus_damage_stacks += bonus_damage_stacks
Expand All @@ -32,22 +38,32 @@
src.bonus_damage_stacks += BDS.bonus_damage_stacks
src.last_stack = BDS.last_stack

src.bonus_damage_stacks = min(src.bonus_damage_stacks, bonus_damage_cap)
// if a different type of holo targetting bullet hits a mob and has a bigger bonus cap, it will get applied.
if(src.bonus_damage_cap_increase < bonus_damage_cap_increase)
src.bonus_damage_cap_increase = bonus_damage_cap_increase
src.bonus_damage_cap = initial(bonus_damage_cap) + src.bonus_damage_cap_increase

// however, if it has a worse stack_loss_multiplier, it will get applied instead.
// this way, if a weapon is meant to have a big bonus cap but holo stacks that rapidly deplete, it will not be messed up by a weapon that a low stack_loss_multiplier.
if(src.stack_loss_multiplier < stack_loss_multiplier)
src.stack_loss_multiplier = stack_loss_multiplier

src.bonus_damage_stacks = min(src.bonus_damage_stacks, src.bonus_damage_cap)

/datum/component/bonus_damage_stack/process(delta_time)
if(last_stack + 5 SECONDS < world.time)
bonus_damage_stacks = bonus_damage_stacks - BONUS_DAMAGE_STACK_LOSS_PER_SECOND * delta_time
bonus_damage_stacks = bonus_damage_stacks - BONUS_DAMAGE_STACK_LOSS_PER_SECOND * stack_loss_multiplier * delta_time

if(bonus_damage_stacks <= 0)
qdel(src)

var/color = COLOR_BONUS_DAMAGE
var/intensity = bonus_damage_stacks / (bonus_damage_cap * 2)
color += num2text(BONUS_DAMAGE_MAX_ALPHA * intensity, 2, 16)

var/intensity = bonus_damage_stacks / (initial(bonus_damage_cap) * 2)
// if intensity is too high of a value, the hex code will become invalid
color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 1, 16)
if(parent)
var/atom/A = parent
A.add_filter("bonus_damage_stacks", 2, list("type" = "outline", "color" = color, "size" = 1))
A.add_filter("bonus_damage_stacks", 2, list("type" = "outline", "color" = color, "size" = 1 + clamp(intensity, 0, 1)))

/datum/component/bonus_damage_stack/RegisterWithParent()
START_PROCESSING(SSdcs, src)
Expand All @@ -67,7 +83,7 @@
SIGNAL_HANDLER
L += "Bonus Damage Taken: [bonus_damage_stacks * 0.1]%"

/datum/component/bonus_damage_stack/proc/get_bonus_damage(mob/M, list/damage_data) // 10% damage bonus at most
/datum/component/bonus_damage_stack/proc/get_bonus_damage(mob/M, list/damage_data) // 10% damage bonus in most instances
SIGNAL_HANDLER
damage_data["bonus_damage"] = damage_data["damage"] * (min(bonus_damage_stacks, bonus_damage_cap) / 1000)

Expand Down
24 changes: 24 additions & 0 deletions code/modules/cm_marines/equipment/guncases.dm
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,30 @@
new /obj/item/device/vulture_spotter_scope/skillless(src, WEAKREF(rifle))
new /obj/item/tool/screwdriver(src) // Spotter scope needs a screwdriver to disassemble

/obj/item/storage/box/guncase/vulture/holo_target
name = "\improper M707 holo-targetting anti-materiel rifle case"
desc = "A gun case containing the M707 \"Vulture\" anti-materiel rifle and its requisite spotting tools. This variant is pre-loaded with <b>IFF-CAPABLE</b> holo-targeting rounds."

/obj/item/storage/box/guncase/vulture/holo_target/fill_preset_inventory()
var/obj/item/weapon/gun/boltaction/vulture/holo_target/rifle = new(src)
new /obj/item/ammo_magazine/rifle/boltaction/vulture/holo_target(src)
new /obj/item/device/vulture_spotter_tripod(src)
new /obj/item/device/vulture_spotter_scope(src, WEAKREF(rifle))
new /obj/item/tool/screwdriver(src)
new /obj/item/pamphlet/trait/vulture(src)
new /obj/item/pamphlet/trait/vulture(src)

/obj/item/storage/box/guncase/vulture/holo_target/skillless
storage_slots = 5

/obj/item/storage/box/guncase/vulture/holo_target/skillless/fill_preset_inventory()
var/obj/item/weapon/gun/boltaction/vulture/holo_target/skillless/rifle = new(src)
new /obj/item/ammo_magazine/rifle/boltaction/vulture/holo_target(src)
new /obj/item/device/vulture_spotter_tripod(src)
new /obj/item/device/vulture_spotter_scope/skillless(src, WEAKREF(rifle))
new /obj/item/tool/screwdriver(src)


/obj/item/storage/box/guncase/xm51
name = "\improper XM51 breaching scattergun case"
desc = "A gun case containing the XM51 Breaching Scattergun. Comes with two spare magazines, two spare shell boxes, an optional stock and a belt to holster the weapon."
Expand Down
6 changes: 6 additions & 0 deletions code/modules/projectiles/guns/boltaction.dm
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,9 @@

/obj/item/weapon/gun/boltaction/vulture/skillless
bypass_trait = TRUE

/obj/item/weapon/gun/boltaction/vulture/holo_target
current_mag = /obj/item/ammo_magazine/rifle/boltaction/vulture/holo_target

/obj/item/weapon/gun/boltaction/vulture/holo_target/skillless
bypass_trait = TRUE
8 changes: 8 additions & 0 deletions code/modules/projectiles/magazines/rifles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,14 @@
max_rounds = 4
gun_type = /obj/item/weapon/gun/boltaction/vulture
w_class = SIZE_MEDIUM // maybe small? This shit's >4 inches long mind you
ammo_band_icon = "+vulture_band"
ammo_band_icon_empty = "+vulture_band_e"

/obj/item/ammo_magazine/rifle/boltaction/vulture/holo_target
name = "\improper M707 \"Vulture\" holo-target magazine (20x102mm)"
desc = "A magazine for the M707 \"Vulture\" anti-matieriel rifle. Contains up to 4 massively oversized <b>IFF-CAPABLE</b> holo-targeting rounds, which excel at marking heavy targets to be attacked by allied ground forces. The logistical requirements for such capabilities heavily hinder the performance and stopping power of this round."
default_ammo = /datum/ammo/bullet/sniper/anti_materiel/vulture/holo_target
ammo_band_color = AMMO_BAND_COLOR_HOLOTARGETING

//=ROYAL MARINES=\\
Expand Down
Binary file modified icons/obj/items/weapons/guns/ammo_by_faction/uscm.dmi
Binary file not shown.
Binary file added sound/weapons/gun_vulture_mark.ogg
Binary file not shown.

0 comments on commit fe0134e

Please sign in to comment.