Files
Aurora.3/code/modules/projectiles/projectile/energy.dm
T
FenodyreeAvandGitHub e8944e087d Modular laser fixes and nerfs (#22147)
**Fixes the bugs found on the recent nations round.**

- Fixed firedelay doing nothing on modlasers with the shotgun lens. Also
fixed the existing laser shotgun as a side effect. Fixes #22141 and
Fixes #22137
- Fixes the shotgun lens not having any dispersion.
- Fixes bluespace capacitors not teleporting you on a failure.
- Fixes phoron capacitors not hurting the user when they explode.
- Fixes messages about malfunctions not displaying to the user.
- Fixes a bunch of bugs related to repairing components
- Stops components getting qdeled but leaving their references on all
other components, breaking them if reused.

**Nerfs a few of the most problematic things.**

- Cut the damage of the blaster projectile by 20% and reduced it's AP
from 60 to 35, also drops it's incendiary value to 1.
This projectile was FAR more powerful than any other, ignored all armour
and set the user on fire without a damage penalty.
With this change, lasers are now better on unarmoured targets, the
blaster is better on 40+ armour, so Heavy and Specialist Ablative.

- Added an immediate electric shock to the user (and anyone within one
tile if the capacitor is unstable enough).
The previous low level failures all irradiated the user. This did more
damage in the long term, but didn't affect the outcome of any fights and
was easy to negate with suits.
The tesla shock is obvious to everyone nearby, causes immediate pain and
the gun to be dropped if the capacitor is overcharged.
This makes minor failures a significant factor mid fight, especially on
powerful guns.

- Makes the phoron capacitor directly damage the hand holding it when it
explodes.
This capacitor can be built with phoron and uranium, which both spawn at
roundstart, though uranium isn't accessible.
It's therefore the most common capacitor, and the second most powerful.
This increases downside a lot, in addition to the explosion being fixed,
it will break the hand that fires it when it malfunctions.
If the capacitor is unstable, such as in a 60 damage monster, it will
gib the hand that fires it on malfunction.


**Tweaks, aimed at making the guns easier to understand, repair and
test**

- Adds a locker and boxes of modlaser parts. Not mapped in, but easy to
spawn for testing.
- Adds big red warning messages, visible to everyone nearby, explaining
what happened to the gun, who was holding it and how bad the malfunction
was.
- Made the lenses repairable with glass, or reinforced glass. The
nanopaste cost of a repair was more than 50x the cost of just printing a
new lens.
2026-04-07 20:08:41 +00:00

212 lines
5.1 KiB
Plaintext

/obj/projectile/energy
name = "energy"
icon_state = "spark"
damage = 0
damage_type = DAMAGE_BURN
check_armor = ENERGY
/// Releases a burst of light on impact or after travelling a distance.
/obj/projectile/energy/flash
name = "chemical shell"
icon_state = "bullet"
damage = 5
agony = 10
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
var/flash_range = 0
var/brightness = 7
var/light_duration = 5
/obj/projectile/energy/flash/on_hit(atom/target, blocked, def_zone)
. = ..()
var/turf/T = flash_range ? src.loc : get_turf(target)
if(!istype(T))
return
//blind adjacent people
for(var/mob/living/M in viewers(T, flash_range))
if(M.flash_act(ignore_inherent = TRUE))
M.confused = rand(5, 15)
//snap pop
playsound(src, 'sound/effects/snap.ogg', 50, 1)
src.visible_message(SPAN_WARNING("\The [src] explodes in a bright flash!"))
new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows
single_spark(T)
new /obj/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration)
/// blinds people like the flash round, but can also be used for temporary illumination
/obj/projectile/energy/flash/flare
damage = 10
flash_range = 1
brightness = 9 //similar to a flare
light_duration = 200
/obj/projectile/energy/electrode
name = "electrode"
icon_state = "spark"
damage = 2 //Flavor.
damage_type = DAMAGE_BURN
agony = 40
eyeblur = 1
//Damage will be handled on the MOB side, to prevent window shattering.
/obj/projectile/energy/electrode/stunshot
name = "stunshot"
damage = 5
agony = 80
/obj/projectile/energy/declone
name = "decloner beam"
icon_state = "declone"
damage = 20
damage_type = DAMAGE_CLONE
irradiate = 40
/obj/projectile/energy/dart
name = "dart"
icon_state = "toxin"
damage = 5
damage_type = DAMAGE_TOXIN
weaken = 5
/obj/projectile/energy/bolt
name = "bolt"
icon_state = "cbbolt"
damage = 1
damage_type = DAMAGE_BURN
agony = 45
stutter = 10
/obj/projectile/energy/bolt/large
name = "largebolt"
damage = 2
damage_type = DAMAGE_BURN
agony = 60
/obj/projectile/energy/neurotoxin
name = "neuro"
icon_state = "neurotoxin"
damage = 5
damage_type = DAMAGE_TOXIN
weaken = 5
/obj/projectile/energy/phoron
name = "phoron bolt"
icon_state = "energy"
irradiate = 20
/obj/projectile/energy/bfg
name = "distortion"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bfg"
check_armor = BOMB
damage = 60
damage_type = DAMAGE_BRUTE
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSRAILING
range = 100
embed = 0
speed = 8
light_range = 4
light_color = "#b5ff5b"
/obj/projectile/energy/bfg/on_hit(atom/target, blocked, def_zone)
if(ismob(target))
var/mob/M = target
M.gib()
explosion(target, -1, 0, 5)
. = ..()
/obj/projectile/energy/bfg/New()
var/matrix/M = matrix()
M.Scale(2)
src.transform = M
..()
// /obj/projectile/energy/bfg/after_move()
// for(var/a in range(1, src))
// if(isliving(a) && a != firer)
// var/mob/living/M = a
// if(M.stat == DEAD)
// M.gib()
// else
// M.apply_damage(60, DAMAGE_BRUTE, BP_HEAD)
// playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
// else if(isturf(a) || isobj(a))
// var/atom/A = a
// if(!A.density)
// continue
// A.ex_act(2)
// playsound(src, 'sound/magic/LightningShock.ogg', 75, 1)
/obj/projectile/energy/gravitydisabler
name = "gravity disabler"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bluespace"
damage = 0
damage_type = DAMAGE_BRUTE
pass_flags = PASSTABLE | PASSGRILLE | PASSRAILING
range = 10
embed = 0
speed = 1
light_range = 4
light_color = "#b5ff5b"
/obj/projectile/energy/gravitydisabler/on_hit(atom/target, blocked, def_zone)
. = ..()
var/area/A = get_area(target)
if(A && A.has_gravity())
A.gravitychange(FALSE)
addtimer(CALLBACK(src, PROC_REF(turnongravity)), 150)
if(istype(target, /obj/machinery/gravity_generator/main))
var/obj/machinery/gravity_generator/main/T = target
T.eshutoff()
/obj/projectile/energy/gravitydisabler/proc/turnongravity(var/area/A)
A.gravitychange(TRUE)
/obj/projectile/energy/blaster
name = "blaster bolt"
icon_state = "laser"
damage = 30
check_armor = LASER
damage_type = DAMAGE_BURN
damage_flags = DAMAGE_FLAG_LASER
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSRAILING
muzzle_type = /obj/effect/projectile/muzzle/bolt
impact_effect_type = /obj/effect/temp_visual/blaster_effect
/obj/projectile/energy/blaster/skrell // for nralakk fed consular pistol
damage = 30
armor_penetration = 5
pass_flags = PASSTABLE | PASSRAILING
/obj/projectile/energy/blaster/heavy
damage = 35
armor_penetration = 10
/obj/projectile/energy/blaster/incendiary
icon_state = "laser"
damage = 35
armor_penetration = 60
incinerate = 2
/obj/projectile/energy/blaster/incendiary/light
icon_state = "laser"
damage = 30
armor_penetration = 35
incinerate = 1
/obj/projectile/energy/disruptorskrell // for nralakk fed consular pistol
name = "disruptor bolt"
icon_state = "bluelaser"
damage = 1
agony = 45
speed = 0.4
damage_type = DAMAGE_BURN
eyeblur = 1
pass_flags = PASSTABLE | PASSRAILING
muzzle_type = /obj/effect/projectile/muzzle/bolt