Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sound/items/weapons/attributions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
rust_sower_armbomb.ogg - EnterTheJake
rust_sower_explode.ogg - EnterTheJake
}

laser.ogg and laser2.ogg are e-fire.ogg and heavy_laser.ogg from Shiptest (https://github.com/shiptest-ss13/Shiptest), CC BY-SA 3.0.
Binary file modified sound/items/weapons/laser.ogg
Binary file not shown.
Binary file modified sound/items/weapons/laser2.ogg
Binary file not shown.
1 change: 1 addition & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -6925,6 +6925,7 @@
#include "voidcrew\edits\modules\power\supermatter_anomalies.dm"
#include "voidcrew\edits\modules\power\turbine\turbine.dm"
#include "voidcrew\edits\modules\projectiles\boxes_magazines\_box_magazine.dm"
#include "voidcrew\edits\modules\projectiles\projectile\beams.dm"
#include "voidcrew\edits\modules\research\designs.dm"
#include "voidcrew\edits\modules\research\designs\comp_board_designs.dm"
#include "voidcrew\edits\modules\research\designs\machine_designs.dm"
Expand Down
55 changes: 55 additions & 0 deletions voidcrew/edits/modules/projectiles/projectile/beams.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Voidcrew: the standard laser family is hitscan. A laser lands the moment it is fired and leaves
// tg's beam tracer along its path, instead of flying as a bolt. Same damage as upstream; the instant
// hit is the change. Reflection, blocking, glass and every on-hit signal run exactly as for a bolt,
// because tg's hitscan walks the same per-tile movement and hit code (projectile.dm process_hitscan).
//
// Stays a travelling bolt: disablers and other stun beams, X-ray, pulse, emitters, the ship defense
// turret, lasertag, CTF, mech lasers (below) and the two lasers whose look is the projectile itself.

/obj/projectile/beam/laser
hitscan = TRUE

/// Its ball grows as it flies (reduce_range), which a hitscan beam never shows.
/obj/projectile/beam/laser/accelerator
hitscan = FALSE

/// Genetics laser eyes keep their own eye-beam sprite.
/obj/projectile/beam/laser/laser_eyes
hitscan = FALSE

// Lasers outside /beam/laser that laser guns and turrets fire. Upstream gives them no tracer.

/// Laser scattershot and scatter laser shells.
/obj/projectile/beam/scatter
hitscan = TRUE
tracer_type = /obj/effect/projectile/tracer/laser
muzzle_type = /obj/effect/projectile/muzzle/laser
impact_type = /obj/effect/projectile/impact/laser

/// Laser gatling and some turrets.
/obj/projectile/beam/weak
hitscan = TRUE
tracer_type = /obj/effect/projectile/tracer/laser
muzzle_type = /obj/effect/projectile/muzzle/laser
impact_type = /obj/effect/projectile/impact/laser

/// Practice laser guns.
/obj/projectile/beam/practice
hitscan = TRUE
tracer_type = /obj/effect/projectile/tracer/laser
muzzle_type = /obj/effect/projectile/muzzle/laser
impact_type = /obj/effect/projectile/impact/laser

// Mech lasers stay bolts: exosuit weapons are balanced on their own, apart from hand guns.

/obj/projectile/beam/laser/mech
hitscan = FALSE

/obj/projectile/beam/laser/heavylaser/mech
hitscan = FALSE

/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
projectile = /obj/projectile/beam/laser/mech

/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
projectile = /obj/projectile/beam/laser/heavylaser/mech
1 change: 1 addition & 0 deletions voidcrew/modules/unit_tests/_unit_tests.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
#include "voidcrew_gene_injector_loot.dm"
#include "voidcrew_helm_access.dm"
#include "voidcrew_helpers.dm"
#include "voidcrew_hitscan_lasers.dm"
#include "voidcrew_hull_containment.dm"
#include "voidcrew_hull_survey.dm"
#include "voidcrew_launch_access.dm"
Expand Down
57 changes: 57 additions & 0 deletions voidcrew/modules/unit_tests/voidcrew_hitscan_lasers.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/// Standard lasers are hitscan with a visible tracer; the beams we chose to keep as bolts are not.
/datum/unit_test/voidcrew_hitscan_lasers/Run()
var/list/obj/projectile/hitscan_types = list(
/obj/projectile/beam/laser,
/obj/projectile/beam/laser/carbine,
/obj/projectile/beam/laser/carbine/cybersun,
/obj/projectile/beam/laser/hellfire,
/obj/projectile/beam/laser/heavylaser,
/obj/projectile/beam/laser/musket,
/obj/projectile/beam/laser/outpost,
/obj/projectile/beam/scatter,
/obj/projectile/beam/weak/penetrator,
/obj/projectile/beam/practice,
)
for(var/obj/projectile/laser_type as anything in hitscan_types)
TEST_ASSERT(initial(laser_type.hitscan), "[laser_type] is not hitscan")
TEST_ASSERT_NOTNULL(initial(laser_type.tracer_type), "[laser_type] is hitscan with no tracer, so its beam is invisible")

var/list/obj/projectile/bolt_types = list(
/obj/projectile/beam/disabler,
/obj/projectile/beam/xray,
/obj/projectile/beam/pulse,
/obj/projectile/beam/emitter,
/obj/projectile/beam/ship_defense,
/obj/projectile/beam/laser/accelerator,
/obj/projectile/beam/laser/laser_eyes,
/obj/projectile/beam/laser/mech,
/obj/projectile/beam/laser/heavylaser/mech,
)
for(var/obj/projectile/bolt_type as anything in bolt_types)
TEST_ASSERT(!initial(bolt_type.hitscan), "[bolt_type] became hitscan")

var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/mech_laser = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
TEST_ASSERT_EQUAL(initial(mech_laser.projectile), /obj/projectile/beam/laser/mech, "The mech laser fires a hitscan laser")

/// A hitscan laser fired at someone three tiles away lands, from a bare projectile and from a trigger pull.
/// The beam finishes on the firing tick unless the tick is overrun, which it always is in a test, so wait for it.
/datum/unit_test/voidcrew_hitscan_laser_lands/Run()
var/mob/living/carbon/human/consistent/shooter = allocate(/mob/living/carbon/human/consistent, run_loc_floor_bottom_left)
var/turf/target_turf = locate(run_loc_floor_bottom_left.x + 3, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)
var/mob/living/carbon/human/consistent/target = allocate(/mob/living/carbon/human/consistent, target_turf)

var/obj/projectile/beam/laser/beam = new(run_loc_floor_bottom_left)
beam.aim_projectile(target, shooter)
beam.firer = shooter
beam.fire()
UNTIL(QDELETED(beam))
TEST_ASSERT(target.getFireLoss() > 0, "A hitscan laser fired at a target three tiles away missed")

var/before = target.getFireLoss()
var/obj/item/gun/energy/laser/rifle = allocate(/obj/item/gun/energy/laser)
TEST_ASSERT(shooter.put_in_active_hand(rifle), "The shooter could not hold the laser rifle")
var/charge_before = rifle.cell.charge
rifle.fire_gun(target, shooter, FALSE)
TEST_ASSERT(rifle.cell.charge < charge_before, "The laser rifle did not fire")
sleep(1 SECONDS)
TEST_ASSERT(target.getFireLoss() > before, "A laser rifle shot three tiles away missed")
Loading