Skip to content

Commit

Permalink
Vehicle autofire (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
Doubleumc committed Feb 5, 2024
1 parent c69bc19 commit 0857c77
Show file tree
Hide file tree
Showing 21 changed files with 550 additions and 571 deletions.
441 changes: 288 additions & 153 deletions code/modules/vehicles/hardpoints/hardpoint.dm

Large diffs are not rendered by default.

24 changes: 18 additions & 6 deletions code/modules/vehicles/hardpoints/holder/holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,21 @@
for(var/obj/item/hardpoint/H in hardpoints)
H.take_damage(damage)

/obj/item/hardpoint/holder/on_install(obj/vehicle/multitile/V)
for(var/obj/item/hardpoint/HP in hardpoints)
HP.owner = V
return
/obj/item/hardpoint/holder/on_install(obj/vehicle/multitile/vehicle)
..()
if(!vehicle) //in loose holder
return
for(var/obj/item/hardpoint/hardpoint in hardpoints)
hardpoint.owner = vehicle
hardpoint.on_install(vehicle)

/obj/item/hardpoint/holder/on_uninstall(obj/vehicle/multitile/vehicle)
if(!vehicle) //in loose holder
return
for(var/obj/item/hardpoint/hardpoint in hardpoints)
hardpoint.on_uninstall(vehicle)
hardpoint.owner = null
..()

/obj/item/hardpoint/holder/proc/can_install(obj/item/hardpoint/H)
// Can only have 1 hardpoint of each slot type
Expand Down Expand Up @@ -121,16 +132,17 @@
H.forceMove(src)
LAZYADD(hardpoints, H)

H.on_install(owner)
H.rotate(turning_angle(H.dir, dir))

/obj/item/hardpoint/holder/proc/remove_hardpoint(obj/item/hardpoint/H, turf/uninstall_to)
if(!hardpoints)
return
hardpoints -= H
H.forceMove(uninstall_to ? uninstall_to : get_turf(src))

H.on_uninstall(owner)
H.reset_rotation()

hardpoints -= H
H.owner = null

if(H.health <= 0)
Expand Down
46 changes: 18 additions & 28 deletions code/modules/vehicles/hardpoints/holder/tank_turret.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
density = TRUE //come on, it's huge

activatable = TRUE
cooldown = 150
accuracy = 0.8

ammo = new /obj/item/ammo_magazine/hardpoint/turret_smoke
max_clips = 2
Expand Down Expand Up @@ -60,6 +58,15 @@
// Used during the windup
var/rotating = FALSE

scatter = 4
gun_firemode = GUN_FIREMODE_BURSTFIRE
gun_firemode_list = list(
GUN_FIREMODE_BURSTFIRE,
)
burst_amount = 2
burst_delay = 1.0 SECONDS
extra_delay = 13.0 SECONDS

/obj/item/hardpoint/holder/tank_turret/update_icon()
var/broken = (health <= 0)
icon_state = "tank_turret_[broken]"
Expand Down Expand Up @@ -182,12 +189,7 @@
user.client.pixel_x = -1 * AM.view_tile_offset * 32
user.client.pixel_y = 0

/obj/item/hardpoint/holder/tank_turret/fire(mob/user, atom/A)
if(ammo.current_rounds <= 0)
return

next_use = world.time + cooldown

/obj/item/hardpoint/holder/tank_turret/try_fire(atom/target, mob/living/user, params)
var/turf/L
var/turf/R
switch(owner.dir)
Expand All @@ -204,26 +206,14 @@
L = locate(owner.x - 4, owner.y + 2, owner.z)
R = locate(owner.x - 4, owner.y - 2, owner.z)

if(LAZYLEN(activation_sounds))
playsound(get_turf(src), pick(activation_sounds), 60, 1)
fire_projectile(user, L)
if(shots_fired)
target = R
else
target = L

sleep(10)
return ..()

if(LAZYLEN(activation_sounds))
playsound(get_turf(src), pick(activation_sounds), 60, 1)
fire_projectile(user, R)

to_chat(user, SPAN_WARNING("Smoke Screen uses left: <b>[SPAN_HELPFUL(ammo ? ammo.current_rounds / 2 : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds / 2 : 0)]</b> | Mags: <b>[SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]</b>"))

/obj/item/hardpoint/holder/tank_turret/fire_projectile(mob/user, atom/A)
set waitfor = 0

var/turf/origin_turf = get_turf(src)
origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z)
/obj/item/hardpoint/holder/tank_turret/get_origin_turf()
var/origin_turf = ..()
origin_turf = get_step(get_step(origin_turf, owner.dir), owner.dir) //this should get us tile in front of tank to prevent grenade being stuck under us.

var/obj/projectile/P = generate_bullet(user, origin_turf)
SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER])
P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, get_dist(origin_turf, A) + 1, P.ammo.shell_speed)
ammo.current_rounds--
return origin_turf
9 changes: 7 additions & 2 deletions code/modules/vehicles/hardpoints/primary/autocannon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
activation_sounds = list('sound/weapons/vehicles/autocannon_fire.ogg')

health = 500
cooldown = 7
accuracy = 0.98
firing_arc = 60

origins = list(0, -3)
Expand All @@ -23,3 +21,10 @@
"4" = list(32, 0),
"8" = list(-32, 0)
)

scatter = 1
gun_firemode = GUN_FIREMODE_AUTOMATIC
gun_firemode_list = list(
GUN_FIREMODE_AUTOMATIC,
)
fire_delay = 0.7 SECONDS
29 changes: 7 additions & 22 deletions code/modules/vehicles/hardpoints/primary/dual_cannon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
damage_multiplier = 0.2

health = 500
cooldown = 7
accuracy = 0.98
firing_arc = 60
var/burst_amount = 2

origins = list(0, -2)

Expand All @@ -35,27 +32,15 @@
"8" = list(14, 9)
)

scatter = 1
gun_firemode = GUN_FIREMODE_AUTOMATIC
gun_firemode_list = list(
GUN_FIREMODE_AUTOMATIC,
)
fire_delay = 0.3 SECONDS

/obj/item/hardpoint/primary/dualcannon/set_bullet_traits()
..()
LAZYADD(traits_to_give, list(
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff)
))

/obj/item/hardpoint/primary/dualcannon/fire(mob/user, atom/A)
if(ammo.current_rounds <= 0)
return

next_use = world.time + cooldown * owner.misc_multipliers["cooldown"]

for(var/bullets_fired = 1, bullets_fired <= burst_amount, bullets_fired++)
var/atom/T = A
if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"]))
T = get_step(get_turf(A), pick(cardinal))
if(LAZYLEN(activation_sounds))
playsound(get_turf(src), pick(activation_sounds), 60, 1)
fire_projectile(user, T)
if(ammo.current_rounds <= 0)
break
if(bullets_fired < burst_amount) //we need to sleep only if there are more bullets to shoot in the burst
sleep(3)
to_chat(user, SPAN_WARNING("[src] Ammo: <b>[SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)]</b> | Mags: <b>[SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]</b>"))
37 changes: 9 additions & 28 deletions code/modules/vehicles/hardpoints/primary/flamer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
activation_sounds = list('sound/weapons/vehicles/flamethrower.ogg')

health = 400
cooldown = 20
accuracy = 0.75
firing_arc = 90

origins = list(0, -3)
Expand All @@ -26,36 +24,19 @@

use_muzzle_flash = FALSE

scatter = 5
fire_delay = 2.0 SECONDS

/obj/item/hardpoint/primary/flamer/set_bullet_traits()
..()
LAZYADD(traits_to_give, list(
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff)
))

/obj/item/hardpoint/primary/flamer/can_activate(mob/user, atom/A)
if(!..())
return FALSE

var/turf/origin_turf = get_turf(src)
origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z)
if(origin_turf == get_turf(A))
return FALSE

return TRUE

/obj/item/hardpoint/primary/flamer/fire_projectile(mob/user, atom/A)
set waitfor = 0

var/turf/origin_turf = get_turf(src)
origin_turf = locate(origin_turf.x + origins[1], origin_turf.y + origins[2], origin_turf.z)

var/range = get_dist(origin_turf, A) + 1

var/obj/projectile/P = generate_bullet(user, origin_turf)
SEND_SIGNAL(P, COMSIG_BULLET_USER_EFFECTS, owner.seats[VEHICLE_GUNNER])
P.fire_at(A, owner.seats[VEHICLE_GUNNER], src, range < P.ammo.max_range ? range : P.ammo.max_range, P.ammo.shell_speed)

if(use_muzzle_flash)
muzzle_flash(Get_Angle(owner, A))
/obj/item/hardpoint/primary/flamer/try_fire(target, user, params)
var/turf/origin_turf = get_origin_turf()
if(origin_turf == get_turf(target))
to_chat(user, SPAN_WARNING("The target is too close."))
return NONE

ammo.current_rounds--
return ..()
5 changes: 3 additions & 2 deletions code/modules/vehicles/hardpoints/primary/ltb.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
activation_sounds = list('sound/weapons/vehicles/cannon_fire1.ogg', 'sound/weapons/vehicles/cannon_fire2.ogg')

health = 500
cooldown = 200
accuracy = 0.97
firing_arc = 60

origins = list(0, -3)
Expand All @@ -30,3 +28,6 @@
"4" = list(89, -4),
"8" = list(-89, -4)
)

scatter = 2
fire_delay = 20.0 SECONDS
86 changes: 48 additions & 38 deletions code/modules/vehicles/hardpoints/primary/minigun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
disp_icon_state = "ltaaap_minigun"

health = 350
cooldown = 8
accuracy = 0.6
firing_arc = 90

origins = list(0, -3)
Expand All @@ -30,46 +28,58 @@
"8" = list(-77, 0)
)

//changed minigun mechanic so instead of having lowered cooldown with each shot it now has increased burst size.
//While it's still spammy, user doesn't have to click as fast as possible anymore and has margin of 2 seconds before minigun will start slowing down

var/chained_shots = 1 //how many quick succession shots we've fired, 1 by default
var/last_shot_time = 0 //when was last shot fired, after 3 seconds we stop barrel
var/list/chain_bursts = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4) //how many shots per click we do
scatter = 7
gun_firemode = GUN_FIREMODE_AUTOMATIC
gun_firemode_list = list(
GUN_FIREMODE_AUTOMATIC,
)
fire_delay = 0.8 SECONDS //base fire rate, modified by stage_delay_mult

activation_sounds = list('sound/weapons/gun_minigun.ogg')
/// Active firing time to reach max spin_stage.
var/spinup_time = 8 SECONDS
/// Grace period before losing spin_stage.
var/spindown_grace_time = 2 SECONDS
COOLDOWN_DECLARE(spindown_grace_cooldown)
/// Cooldown time to reach min spin_stage.
var/spindown_time = 3 SECONDS
/// Index of stage_rate.
var/spin_stage = 1
/// Shots fired per fire_delay at a particular spin_stage.
var/list/stage_rate = list(1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5)
/// Fire delay multiplier for current spin_stage.
var/stage_delay_mult = 1
/// When it was last fired, related to world.time.
var/last_fired = 0

/obj/item/hardpoint/primary/minigun/fire(mob/user, atom/A)
/obj/item/hardpoint/primary/minigun/set_fire_delay(value)
fire_delay = value
SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult)

var/S = 'sound/weapons/vehicles/minigun_stop.ogg'
//check how much time since last shot. 2 seconds are grace period before minigun starts to lose rotation momentum
var/t = world.time - last_shot_time - 2 SECONDS
t = round(t / 10)
if(t > 0)
chained_shots = max(chained_shots - t * 3, 1) //we lose 3 chained_shots per second
else
if(chained_shots < 11)
chained_shots++
S = 'sound/weapons/vehicles/minigun_loop.ogg'
/obj/item/hardpoint/primary/minigun/set_fire_cooldown()
calculate_stage_delay_mult() //needs to check grace_cooldown before refreshed
last_fired = world.time
COOLDOWN_START(src, spindown_grace_cooldown, spindown_grace_time)
COOLDOWN_START(src, fire_cooldown, fire_delay * stage_delay_mult)

if(chained_shots == 1)
playsound(get_turf(src), 'sound/weapons/vehicles/minigun_start.ogg', 40, 1)
/obj/item/hardpoint/primary/minigun/proc/calculate_stage_delay_mult()
var/stage_rate_len = stage_rate.len
var/delta_time = world.time - last_fired

next_use = world.time + cooldown * owner.misc_multipliers["cooldown"]

//how many rounds we will shoot in this burst
if(chained_shots > LAZYLEN(chain_bursts)) //5 shots at maximum rotation
t = 5
var/old_spin_stage = spin_stage
if(auto_firing || burst_firing) //spinup if continuing fire
var/delta_stage = delta_time * (stage_rate_len - 1)
spin_stage += delta_stage / spinup_time
else if(COOLDOWN_FINISHED(src, spindown_grace_cooldown)) //spindown if initiating fire after grace
var/delta_stage = (delta_time - spindown_grace_time) * (stage_rate_len - 1)
spin_stage -= delta_stage / spindown_time
else
t = LAZYACCESS(chain_bursts, chained_shots)
for(var/i = 1; i <= t; i++)
var/atom/T = A
if(!prob((accuracy * 100) / owner.misc_multipliers["accuracy"]))
T = get_step(get_turf(T), pick(cardinal))
fire_projectile(user, T)
if(ammo.current_rounds <= 0)
break
sleep(2)
to_chat(user, SPAN_WARNING("[src] Ammo: <b>[SPAN_HELPFUL(ammo ? ammo.current_rounds : 0)]/[SPAN_HELPFUL(ammo ? ammo.max_rounds : 0)]</b> | Mags: <b>[SPAN_HELPFUL(LAZYLEN(backup_clips))]/[SPAN_HELPFUL(max_clips)]</b>"))
return
spin_stage = Clamp(spin_stage, 1, stage_rate_len)

var/old_stage_rate = stage_rate[Floor(old_spin_stage)]
var/new_stage_rate = stage_rate[Floor(spin_stage)]

playsound(get_turf(src), S, 40, 1)
last_shot_time = world.time
if(old_stage_rate != new_stage_rate)
stage_delay_mult = 1 / new_stage_rate
SEND_SIGNAL(src, COMSIG_GUN_AUTOFIREDELAY_MODIFIED, fire_delay * stage_delay_mult)
Loading

0 comments on commit 0857c77

Please sign in to comment.