Files
Aurora.3/code/modules/events/comet_expulsion.dm
Fyni debef28eef Changes the Comet Expulsion sound effect to a voiced line (#21629)
See title.

Yes I feel a little dumb changing it and then changing it again but here
we are.

---------

Signed-off-by: Fyni <itsfyni@gmail.com>
2025-12-02 10:53:47 +00:00

171 lines
6.2 KiB
Plaintext

/// The minimum strength of a shield to reduce the explosion power of the comet expulsion
#define SHIELD_MINIMUM_STRENGTH_TO_REDUCE_EXPLOSION_POWER 5
/*###############################################
PROJECTILE OF THE COMET EXPULSION EVENT
###############################################*/
/obj/projectile/comet_expulsion
name = "Comet Expulsion"
icon = 'icons/obj/guns/ship/overmap_projectiles.dmi'
icon_state = "med_xray_salvo" //Eventually a spriter will make a sprite specific for this
speed = 1
pixel_speed_multiplier = 0.01
range = INFINITY
/obj/projectile/comet_expulsion/can_hit_target(atom/target, direct_target = FALSE, ignore_loc = FALSE, cross_failed = FALSE)
if(istype(get_turf(src), /turf/unsimulated/map/edge) && istype(target, /turf/unsimulated/map/edge))
return FALSE
if(!istype(target, /obj/effect/overmap/visitable))
return FALSE
return ..()
/obj/projectile/comet_expulsion/on_hit(atom/target, blocked, def_zone)
. = ..()
if(. != BULLET_ACT_HIT)
return
//If we hit the ship, spawn meteors for the various zlevels
if(target == original)
//The direction we are hitting the overmap object from, the true one
var/hit_direction = angle2dir(get_angle(src, target))
for(var/zlevel in SSmapping.levels_by_trait(ZTRAIT_STATION))
//Pick a cardinal direction to spawn the meteor from
var/meteor_source_dir = hit_direction
//If it's not a cardinal already, since the meteor code only supports cardinal directions, make it cardinal
switch(meteor_source_dir)
if(NORTHEAST)
meteor_source_dir = pick(EAST, NORTH)
if(NORTHWEST)
meteor_source_dir = pick(WEST, NORTH)
if(SOUTHEAST)
meteor_source_dir = pick(EAST, SOUTH)
if(SOUTHWEST)
meteor_source_dir = pick(WEST, SOUTH)
//Calculate how many meteors to spawn based on the direction of the hit
//getting hit broadside (cardinal direction) is worse than hitting it diagonally
var/meteors_to_spawn = 5
if(hit_direction in GLOB.cardinals)
meteors_to_spawn = 3
spawn_meteors(meteors_to_spawn, list(/obj/effect/meteor/comet_expulsion), meteor_source_dir, zlevel)
/*#############################################
METEORS OF THE COMET EXPULSION EVENT
#############################################*/
/obj/effect/meteor/comet_expulsion
heavy = TRUE
ignore_shield_destruction = TRUE
hitpwr = 3
/obj/effect/meteor/comet_expulsion/Collide(atom/A)
// Low chance that its a big boi
if(prob(3))
hitpwr = 5
//If there's shields and it's strong enough, the power of the explosion is reduced, but it won't stop it
if(istype(A, /obj/effect/energy_field))
var/obj/effect/energy_field/impacted_energy_field = A
if(impacted_energy_field.damage < 1)
hitpwr *= 0.5
qdel(impacted_energy_field)
. = ..()
/obj/effect/meteor/comet_expulsion/meteor_effect()
. = ..()
explosion(get_turf(src), ROUND_UP(hitpwr), ROUND_UP(hitpwr*1.2), ROUND_UP(hitpwr*1.4))
/*#############################
COMET EXPULSION EVENT
#############################*/
/datum/event/comet_expulsion
severity = EVENT_LEVEL_MAJOR
startWhen = 10
/// Number of meteors aimed directly at Horizon (few)
var/meteors_aimed = 0
/// Number of meteors traveling on random trajectories on the overmap (lots)
var/meteors_random = 0
/datum/event/comet_expulsion/setup()
if(!SSatlas.current_map.use_overmap)
qdel(src)
return
/datum/event/comet_expulsion/start()
. = ..()
var/list/possible_station_levels = SSmapping.levels_by_all_traits(list(ZTRAIT_STATION))
if(!length(possible_station_levels))
qdel(src)
return
var/obj/effect/overmap/visitable/target = GLOB.map_sectors["[pick(possible_station_levels)]"]
if(!istype(target))
log_and_message_admins("Comet Expulsion failed to find a viable overmap target.")
qdel(src)
return
/**
* These numbers may seem high, but the overmap is a Big Place. Meteors aimed at the Horizon will impact along its outer hull, if they manage to strike.
* Huddling crew in the Central Ring is the easiest way to keep them safe. The overwhelming majority of unaimed meteors will almost never come close; they
* just need to ensure there's stuff to dodge in most directions.
*/
meteors_aimed = (rand(2,5))
meteors_random = (rand(12,24))
// Rocks aimed directly at us.
for(var/x in 1 to meteors_aimed)
fire_comet(target, TRUE)
// Rocks flying around nearby to dodge.
for(var/y in 1 to meteors_random)
fire_comet(target)
log_and_message_admins("Comet Expulsion has spawned meteors: [meteors_aimed] aimed at Horizon, [meteors_random] traveling random directions")
/**
* Generate a meteor and fire it from the overmap edge in the general direction of, but not directly at, the Horizon.
*
* Parameter:
* * aimed - aim DIRECTLY at the horizon: guaranteed collision if no action is taken.
*/
/datum/event/comet_expulsion/proc/fire_comet(var/obj/effect/overmap/visitable/target, var/aimed = FALSE)
var/list/turf/unsimulated/map/edge/overmap_edges = list()
var/projectile_angle
for(var/turf/unsimulated/map/edge/E in block(locate(1,1,SSatlas.current_map.overmap_z), locate(SSatlas.current_map.overmap_size,SSatlas.current_map.overmap_size,SSatlas.current_map.overmap_z)))
overmap_edges += E
var/turf/unsimulated/map/edge/source = pick(overmap_edges)
if(!istype(source))
qdel(src)
return
var/obj/projectile/comet_expulsion/our_comet = new(source)
our_comet.preparePixelProjectile(target, source)
our_comet.original = target
// Get the angle to hit our target directly.
projectile_angle = get_angle(source, target)
// If we're not aiming, introduce random deviation.
if(!aimed)
var/random_deviation = rand(-75, 75)
projectile_angle = abs((projectile_angle + random_deviation) % 360)
our_comet.fire(projectile_angle)
/datum/event/comet_expulsion/announce()
command_announcement.Announce("Warning, long range field scanners have detected an unforeseen comet expulsion in collision route with [location_name()].\n\
All hands, assume defense condition, perform evasive maneuvers to avoid collision with the debris cloud. Damage control teams prepare to respond to breaches of the \
vessel perimeter.",
"[location_name()] Long Range Field Objects Sensor Array", new_sound = sound('sound/AI/comet_expulsion.ogg', volume = 50), zlevels = affecting_z)
#undef SHIELD_MINIMUM_STRENGTH_TO_REDUCE_EXPLOSION_POWER