Skip to content

Commit

Permalink
Vehicle projectile origin adjustment (#6245)
Browse files Browse the repository at this point in the history
# About the pull request

Vehicle projectiles now start on the vehicle and travel outward, without
hitting the vehicle. As a side effect, `Adjacent()` checks now accept a
list of objects to ignore.

Origins are adjusted to the point visually closest to the hardpoint's
sprite. For most hardpoints this is the center of the vehicle, with the
only exceptions being the APC weapons (all along different edges) and
the secondary flamer (flame origin is walked until not on the vehicle).

Since projectiles now must travel farther to reach the front of the
vehicle, some shorter ranged ammos are adjusted to compensate.

The hardpoint check `clear_los()` is removed since now all origins are
inside the vehicle's bounds.

Removed redundant call to `display_ammo()` when firing secondary flamer.

<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

# Explain why it's good for the game

Projectiles originating from the tile in front of a vehicle make it
extremely hard or even impossible to engage targets adjacent to it. With
this change the projectile, and resulting cone of fire, starts where you
would expect it to.
# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# Changelog
:cl:
qol: vehicle weapon projectiles start from the weapon
/:cl:
  • Loading branch information
Doubleumc committed May 25, 2024
1 parent 3e41177 commit 3624cdc
Show file tree
Hide file tree
Showing 22 changed files with 53 additions and 129 deletions.
15 changes: 9 additions & 6 deletions code/_onclick/adjacent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
* Passing through in this case ignores anything with the throwpass flag, such as tables, racks, and morgue trays.
*/
/turf/Adjacent(atom/neighbor, atom/target = null)
/turf/Adjacent(atom/neighbor, atom/target = null, list/ignore_list)
var/turf/T0 = get_turf(neighbor)
if(T0 == src)
return TRUE
Expand All @@ -34,22 +34,22 @@

if(T0.x == x || T0.y == y)
// Check for border blockages
return T0.ClickCross(get_dir(T0,src), border_only = 1) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target)
return T0.ClickCross(get_dir(T0,src), border_only = 1, ignore_list = ignore_list) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, ignore_list = ignore_list)

// Not orthagonal
var/in_dir = get_dir(neighbor,src) // eg. northwest (1+8)
var/d1 = in_dir&(in_dir-1) // eg west (1+8)&(8) = 8
var/d2 = in_dir - d1 // eg north (1+8) - 8 = 1

for(var/d in list(d1,d2))
if(!T0.ClickCross(d, border_only = 1))
if(!T0.ClickCross(d, border_only = 1, ignore_list = ignore_list))
continue // could not leave T0 in that direction

var/turf/T1 = get_step(T0,d)
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0)|get_dir(T1,src), border_only = 0))
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0)|get_dir(T1,src), border_only = 0, ignore_list = ignore_list))
continue // couldn't enter or couldn't leave T1

if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target))
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, ignore_list = ignore_list))
continue // could not enter src

return TRUE // we don't care about our own density
Expand Down Expand Up @@ -131,8 +131,11 @@ Quick adjacency (to turf):
This is defined as any dense ON_BORDER object, or any dense object without throwpass.
The border_only flag allows you to not objects (for source and destination squares)
*/
/turf/proc/ClickCross(target_dir, border_only, target_atom = null)
/turf/proc/ClickCross(target_dir, border_only, target_atom = null, list/ignore_list)
for(var/obj/O in src)
if(O in ignore_list)
continue

if(!O.density || O == target_atom || O.throwpass)
continue // throwpass is used for anything you can click through

Expand Down
5 changes: 5 additions & 0 deletions code/datums/ammo/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
/datum/ammo/flamethrower/tank_flamer
flamer_reagent_id = "napalmx"

max_range = 8

/datum/ammo/flamethrower/sentry_flamer
flags_ammo_behavior = AMMO_IGNORE_ARMOR|AMMO_IGNORE_COVER|AMMO_FLAME
flamer_reagent_id = "napalmx"
Expand Down Expand Up @@ -267,6 +269,9 @@
nade_type = /obj/item/explosive/grenade/smokebomb
icon_state = "smoke_shell"

/datum/ammo/grenade_container/tank_glauncher
max_range = 8

/datum/ammo/hugger_container
name = "hugger shell"
ping = null
Expand Down
2 changes: 2 additions & 0 deletions code/datums/ammo/rocket.dm
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@
return
return ..()

/datum/ammo/rocket/ap/tank_towlauncher
max_range = 8

/datum/ammo/rocket/ltb
name = "cannon round"
Expand Down
16 changes: 11 additions & 5 deletions code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@

if(F && !(projectile_flags & PROJECTILE_SHRAPNEL))
permutated |= F //Don't hit the shooter (firer)
else if (S && (projectile_flags & PROJECTILE_SHRAPNEL))
permutated |= S
if (S)
permutated |= get_atom_on_turf(S) //Don't hit the originating object

permutated |= src //Don't try to hit self.
shot_from = S
Expand Down Expand Up @@ -357,8 +357,14 @@
if((speed * world.tick_lag) >= get_dist(current_turf, target_turf))
SEND_SIGNAL(src, COMSIG_BULLET_TERMINAL)


var/list/ignore_list
var/obj/item/hardpoint/hardpoint = shot_from
if(istype(hardpoint))
LAZYOR(ignore_list, hardpoint.owner) //if fired from a vehicle, exclude the vehicle's body from the adjacency check

// Check we can reach the turf at all based on pathed grid
if(check_canhit(current_turf, next_turf))
if(check_canhit(current_turf, next_turf, ignore_list))
return TRUE

// Actually move
Expand Down Expand Up @@ -594,9 +600,9 @@
if(SEND_SIGNAL(src, COMSIG_BULLET_POST_HANDLE_MOB, L, .) & COMPONENT_BULLET_PASS_THROUGH)
return FALSE

/obj/projectile/proc/check_canhit(turf/current_turf, turf/next_turf)
/obj/projectile/proc/check_canhit(turf/current_turf, turf/next_turf, list/ignore_list)
var/proj_dir = get_dir(current_turf, next_turf)
if((proj_dir & (proj_dir - 1)) && !current_turf.Adjacent(next_turf))
if((proj_dir & (proj_dir - 1)) && !current_turf.Adjacent(next_turf, ignore_list = ignore_list))
ammo.on_hit_turf(current_turf, src)
current_turf.bullet_act(src)
return TRUE
Expand Down
4 changes: 2 additions & 2 deletions code/modules/vehicles/apc/apc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(command_apc_list)
V.add_hardpoint(FPW)
FPW.dir = turn(V.dir, 90)
FPW.name = "Left "+ initial(FPW.name)
FPW.origins = list(2, 0)
FPW.origins = list(1, 0)
FPW.muzzle_flash_pos = list(
"1" = list(-18, 14),
"2" = list(18, -42),
Expand All @@ -191,7 +191,7 @@ GLOBAL_LIST_EMPTY(command_apc_list)
V.add_hardpoint(FPW)
FPW.dir = turn(V.dir, -90)
FPW.name = "Right "+ initial(FPW.name)
FPW.origins = list(-2, 0)
FPW.origins = list(-1, 0)
FPW.muzzle_flash_pos = list(
"1" = list(16, 14),
"2" = list(-18, -42),
Expand Down
43 changes: 0 additions & 43 deletions code/modules/vehicles/hardpoints/hardpoint.dm
Original file line number Diff line number Diff line change
Expand Up @@ -314,45 +314,6 @@

return data

/// Traces backwards from the gun origin to the vehicle to check for obstacles between the vehicle and the muzzle.
/obj/item/hardpoint/proc/clear_los()
if(origins[1] == 0 && origins[2] == 0) //skipping check for modules we don't need this
return TRUE

var/turf/muzzle_turf = get_origin_turf()

var/turf/checking_turf = muzzle_turf
while(!(owner in checking_turf))
// Dense turfs block LoS
if(checking_turf.density)
return FALSE

// Ensure that we can pass over all objects in the turf
for(var/obj/object in checking_turf)
// Since vehicles are multitile the
if(object == owner)
continue

// Non-dense objects are irrelevant
if(!object.density)
continue

// Make sure we can pass object from all directions
if(!HAS_FLAG(object.pass_flags.flags_can_pass_all, PASS_OVER_THROW_ITEM))
if(!HAS_FLAG(object.flags_atom, ON_BORDER))
return FALSE
//If we're behind the object, check the behind pass flags
else if(dir == object.dir && !HAS_FLAG(object.pass_flags.flags_can_pass_behind, PASS_OVER_THROW_ITEM))
return FALSE
//If we're in front, check front pass flags
else if(dir == turn(object.dir, 180) && !HAS_FLAG(object.pass_flags.flags_can_pass_front, PASS_OVER_THROW_ITEM))
return FALSE

// Trace back towards the vehicle
checking_turf = get_step(checking_turf, turn(dir,180))

return TRUE

//-----------------------------
//------INTERACTION PROCS----------
//-----------------------------
Expand Down Expand Up @@ -613,10 +574,6 @@
to_chat(user, SPAN_WARNING("<b>The target is not within your firing arc!</b>"))
return NONE

if(!clear_los())
to_chat(user, SPAN_WARNING("<b>The muzzle is obstructed!</b>"))
return NONE

return handle_fire(target, user, params)

/// Actually fires the gun, sets up the projectile and fires it.
Expand Down
2 changes: 1 addition & 1 deletion code/modules/vehicles/hardpoints/hardpoint_ammo/gl_ammo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
caliber = "grenade"
icon_state = "glauncher_2"
w_class = SIZE_LARGE
default_ammo = /datum/ammo/grenade_container
default_ammo = /datum/ammo/grenade_container/tank_glauncher
max_rounds = 10
gun_type = /obj/item/hardpoint/secondary/grenade_launcher

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
caliber = "rocket" //correlates to any rocket mags
icon_state = "quad_rocket"
w_class = SIZE_LARGE
default_ammo = /datum/ammo/rocket/ap
default_ammo = /datum/ammo/rocket/ap/tank_towlauncher
max_rounds = 5
gun_type = /obj/item/hardpoint/secondary/towlauncher
5 changes: 0 additions & 5 deletions code/modules/vehicles/hardpoints/holder/tank_turret.dm
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,3 @@
target = L

return ..()

/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.
return origin_turf
35 changes: 0 additions & 35 deletions code/modules/vehicles/hardpoints/primary/arc_sentry.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
)
burst_delay = 2
burst_amount = 3
projectile_type = /obj/projectile/arc_sentry

/// Potential targets the turret can shoot at
var/list/targets = list()
Expand Down Expand Up @@ -97,12 +96,6 @@

return try_fire(target, null, params)


/obj/item/hardpoint/primary/arc_sentry/generate_bullet(mob/user, turf/origin_turf)
var/obj/projectile/arc_sentry/made_projectile = ..()
made_projectile.permutated += owner
return made_projectile

/obj/item/hardpoint/primary/arc_sentry/start_fire(datum/source, atom/object, turf/location, control, params)
if(QDELETED(object))
return
Expand Down Expand Up @@ -199,31 +192,3 @@
return FALSE

return ..()

/obj/projectile/arc_sentry/Initialize(mapload, datum/cause_data/cause_data)
. = ..()
RegisterSignal(src, COMSIG_BULLET_POST_HANDLE_OBJ, PROC_REF(check_passthrough))

/obj/projectile/arc_sentry/check_canhit(turf/current_turf, turf/next_turf)
var/proj_dir = get_dir(current_turf, next_turf)
var/obj/item/hardpoint/arc_sentry = shot_from
if(!(arc_sentry.owner in current_turf) && !(arc_sentry.owner in next_turf) && (proj_dir & (proj_dir - 1)) && !current_turf.Adjacent(next_turf))
ammo.on_hit_turf(current_turf, src)
current_turf.bullet_act(src)
return TRUE

// Check for hits that would occur when moving to turf, such as a blocking cade
if(scan_a_turf(next_turf, proj_dir))
return TRUE

return FALSE

/obj/projectile/arc_sentry/proc/check_passthrough(datum/source, obj/hit_obj, bool)
SIGNAL_HANDLER

if(!istype(shot_from, /obj/item/hardpoint))
return

var/obj/item/hardpoint/sentry = shot_from
if(sentry.owner == hit_obj)
return COMPONENT_BULLET_PASS_THROUGH
2 changes: 0 additions & 2 deletions code/modules/vehicles/hardpoints/primary/autocannon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
health = 500
firing_arc = 60

origins = list(0, -3)

ammo = new /obj/item/ammo_magazine/hardpoint/ace_autocannon
max_clips = 2

Expand Down
2 changes: 1 addition & 1 deletion code/modules/vehicles/hardpoints/primary/dual_cannon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
health = 500
firing_arc = 60

origins = list(0, -2)
origins = list(0, 1)

ammo = new /obj/item/ammo_magazine/hardpoint/boyars_dualcannon
max_clips = 2
Expand Down
7 changes: 2 additions & 5 deletions code/modules/vehicles/hardpoints/primary/flamer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
health = 400
firing_arc = 90

origins = list(0, -3)

ammo = new /obj/item/ammo_magazine/hardpoint/primary_flamer
max_clips = 1

Expand All @@ -33,9 +31,8 @@
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_iff)
))

/obj/item/hardpoint/primary/flamer/try_fire(target, user, params)
var/turf/origin_turf = get_origin_turf()
if(origin_turf == get_turf(target))
/obj/item/hardpoint/primary/flamer/try_fire(atom/target, mob/living/user, params)
if(get_turf(target) in owner.locs)
to_chat(user, SPAN_WARNING("The target is too close."))
return NONE

Expand Down
2 changes: 0 additions & 2 deletions code/modules/vehicles/hardpoints/primary/ltb.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
health = 500
firing_arc = 60

origins = list(0, -3)

ammo = new /obj/item/ammo_magazine/hardpoint/ltb_cannon
max_clips = 3

Expand Down
2 changes: 0 additions & 2 deletions code/modules/vehicles/hardpoints/primary/minigun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
health = 350
firing_arc = 90

origins = list(0, -3)

ammo = new /obj/item/ammo_magazine/hardpoint/ltaaap_minigun
max_clips = 1

Expand Down
2 changes: 0 additions & 2 deletions code/modules/vehicles/hardpoints/secondary/cupola.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
health = 350
firing_arc = 120

origins = list(0, -2)

ammo = new /obj/item/ammo_magazine/hardpoint/m56_cupola
max_clips = 1

Expand Down
20 changes: 16 additions & 4 deletions code/modules/vehicles/hardpoints/secondary/flamer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
health = 300
firing_arc = 120

origins = list(0, -2)

ammo = new /obj/item/ammo_magazine/hardpoint/secondary_flamer
max_clips = 1

Expand All @@ -29,14 +27,28 @@
scatter = 6
fire_delay = 3.0 SECONDS

/obj/item/hardpoint/secondary/small_flamer/try_fire(atom/target, mob/living/user, params)
if(get_turf(target) in owner.locs)
to_chat(user, SPAN_WARNING("The target is too close."))
return NONE

return ..()

/obj/item/hardpoint/secondary/small_flamer/handle_fire(atom/target, mob/living/user, params)
var/turf/origin_turf = get_origin_turf()
//step forward along path so flame starts outside hull
var/list/turfs = get_line(get_origin_turf(), get_turf(target))
var/turf/origin_turf
for(var/turf/turf as anything in turfs)
if(turf in owner.locs)
continue
origin_turf = turf
break

var/distance = get_dist(origin_turf, get_turf(target))
var/fire_amount = min(ammo.current_rounds, distance+1, max_range)
ammo.current_rounds -= fire_amount

new /obj/flamer_fire(origin_turf, create_cause_data(initial(name), user), null, fire_amount, null, FLAMESHAPE_LINE, target, CALLBACK(src, PROC_REF(display_ammo), user))
new /obj/flamer_fire(origin_turf, create_cause_data(initial(name), user), null, fire_amount, null, FLAMESHAPE_LINE, target)

play_firing_sounds()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
health = 350
firing_arc = 120

origins = list(0, -2)
origins = list(0, -1)

ammo = new /obj/item/ammo_magazine/hardpoint/m56_cupola/frontal_cannon
max_clips = 1
Expand Down
Loading

0 comments on commit 3624cdc

Please sign in to comment.