mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-19 11:58:39 +01:00
debef28eef
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>
171 lines
6.2 KiB
Plaintext
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
|