diff --git a/code/__DEFINES/nsv13.dm b/code/__DEFINES/nsv13.dm index c6fe54ceadb..3af5050427b 100644 --- a/code/__DEFINES/nsv13.dm +++ b/code/__DEFINES/nsv13.dm @@ -74,7 +74,8 @@ GLOBAL_DATUM_INIT(conquest_role_handler, /datum/conquest_role_handler, new) #define COMSIG_SHIP_BOARDED "ship_boarded" #define COMSIG_GLOB_CHECK_INTERDICT "check_interdict" //from interdiction component -#define BEING_INTERDICTED (1<<0) //returned on successful interdict +#define WEAK_INTERDICT (1<<0) //! Not a "true" interdiction in that it disrupts the drive field, relies on scrambling calculations and rendering a jump too dangerous to execute. +#define STRONG_INTERDICT (1<<1) //! The "true" interdiction, disrupts drive fields to the point any shift is impossible. //Gaming #define shares_overmap(A, B) (A.get_overmap() == B.get_overmap()) diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index fffc79fdbbe..a3f8402be7f 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -3,6 +3,9 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) #define KEYCARD_RED_ALERT "Red Alert" #define KEYCARD_EMERGENCY_MAINTENANCE_ACCESS "Emergency Maintenance Access" #define KEYCARD_BSA_UNLOCK "Bluespace Artillery Unlock" +//NSV13 +#define KEYCARD_FTL_SAFETY_OVERRIDE "FTL Safety Override" +//NSV13 end. /obj/machinery/keycard_auth name = "Keycard Authentication Device" @@ -52,6 +55,13 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) data["red_alert"] = (seclevel2num(get_security_level()) >= SEC_LEVEL_RED) ? 1 : 0 data["emergency_maint"] = GLOB.emergency_access data["bsa_unlock"] = GLOB.bsa_unlock + //NSV13 - emergency FTL + var/ftl_state = -1 // -1 = not overmap; 0 = Safe; 1 = Unsafe. + var/obj/structure/overmap/current_overmap = get_overmap() + if(current_overmap) + ftl_state = current_overmap.ftl_safety_override + data["ftl_safety_override"] = ftl_state + //NSV13 end return data /obj/machinery/keycard_auth/ui_status(mob/user) @@ -76,6 +86,12 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) . = TRUE if("auth_swipe") if(event_source) + //NSV13 - cross overmap safety even if the other things don't have it (we can have a subtype for syndi vessels that doesn't have the other options?). + var/overmap1 = event_source.get_overmap() + var/overmap2 = get_overmap() + if(overmap1 != overmap2) + return TRUE + //NSV13 end. event_source.trigger_event(usr) event_source = null . = TRUE @@ -83,6 +99,11 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) if(!event_source) sendEvent(KEYCARD_BSA_UNLOCK) . = TRUE + if("ftl_safety_override") + if(!event_source) + sendEvent(KEYCARD_FTL_SAFETY_OVERRIDE) + . = TRUE + /obj/machinery/keycard_auth/proc/sendEvent(event_type) triggerer = usr @@ -121,6 +142,8 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) make_maint_all_access() if(KEYCARD_BSA_UNLOCK) toggle_bluespace_artillery() + if(KEYCARD_FTL_SAFETY_OVERRIDE) + toggle_ftl_drive_safety(get_overmap()) GLOBAL_VAR_INIT(emergency_access, FALSE) /proc/make_maint_all_access() @@ -148,6 +171,18 @@ GLOBAL_VAR_INIT(emergency_access, FALSE) minor_announce("Bluespace Artillery firing protocols have been [GLOB.bsa_unlock? "unlocked" : "locked"]", "Weapons Systems Update:") SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("bluespace artillery", GLOB.bsa_unlock? "unlocked" : "locked")) +///NSV13 - toggles FTL safety mode of a passed vessel. +/proc/toggle_ftl_drive_safety(obj/structure/overmap/target) + if(QDELETED(target)) + return + target.ftl_safety_override = !target.ftl_safety_override + if(target.ftl_safety_override) //Safety disengaged. + target.relay('nsv13/sound/misc/triple_boop_alert.ogg',"

FTL Drive System Notice

FTL Drive Safeties disengaged. Drive reverting to manual control.
") + else //Safety reengaged. + target.relay('sound/misc/notice2.ogg', "

FTL Drive System Notice

FTL Drive Safeties restored.
") +//NSV13 end. + #undef KEYCARD_RED_ALERT #undef KEYCARD_EMERGENCY_MAINTENANCE_ACCESS #undef KEYCARD_BSA_UNLOCK +#undef KEYCARD_FTL_SAFETY_OVERRIDE diff --git a/nsv13.dme b/nsv13.dme index 2abd39ff698..5796f2e456d 100644 --- a/nsv13.dme +++ b/nsv13.dme @@ -4045,6 +4045,8 @@ #include "nsv13\code\modules\overmap\FTL\ftl_legacy.dm" #include "nsv13\code\modules\overmap\FTL\components\drive.dm" #include "nsv13\code\modules\overmap\FTL\components\drive_pylon.dm" +#include "nsv13\code\modules\overmap\FTL\ftl_jump_mishaps\jump_mishap_helpers.dm" +#include "nsv13\code\modules\overmap\FTL\ftl_jump_mishaps\phase_ghost.dm" #include "nsv13\code\modules\overmap\ship_areas\badmiral.dm" #include "nsv13\code\modules\overmap\types\miningships.dm" #include "nsv13\code\modules\overmap\types\nanotrasen.dm" diff --git a/nsv13/code/__DEFINES/overmap.dm b/nsv13/code/__DEFINES/overmap.dm index b76e8577e0f..5ef24bbf45e 100644 --- a/nsv13/code/__DEFINES/overmap.dm +++ b/nsv13/code/__DEFINES/overmap.dm @@ -120,5 +120,10 @@ GLOBAL_LIST_INIT(overmap_impact_sounds, list('nsv13/sound/effects/ship/freespace #define SHIELD_FORCE_DEFLECT 2 //!Shield absorbed hit and is redirecting projectile with slightly turned vector. #define SHIELD_FORCE_REFLECT 3 //!Shield absorbed hit and is redirecting projectile in reverse direction. +//Emergency FTL stuff. + +#define EMERGENCY_FTL_RANGE 120 //! Range of Emergency FTL jump (uncontrolled) +#define EMERGENCY_FTL_COOLDOWN 35 MINUTES //!Cooldown of FTL drives between emergency jumps. + //Interior instancing comsig, aka cursed things. #define COMSIG_INTERIOR_DONE_LOADING "interior_done_loading" diff --git a/nsv13/code/modules/overmap/FTL/components/drive.dm b/nsv13/code/modules/overmap/FTL/components/drive.dm index 513ffa698f0..f2cefcc6403 100644 --- a/nsv13/code/modules/overmap/FTL/components/drive.dm +++ b/nsv13/code/modules/overmap/FTL/components/drive.dm @@ -48,6 +48,9 @@ var/ftl_state = FTL_STATE_IDLE + ///world.time until which an user can confirm the emergency jump triggered by Nav. + var/await_emergency_ftl_confirm = 0 + /obj/machinery/computer/ship/ftl_core/Initialize(mapload) . = ..() add_overlay("screen") @@ -202,6 +205,16 @@ jump_speed_factor = 5 max_range = initial(max_range) * 3 +///Requests emergency FTL, needs manual confirm at the machine itself. +/obj/machinery/computer/ship/ftl_core/proc/request_emergency_ftl_confirm() + if(await_emergency_ftl_confirm - world.time > 0) + return + if(!linked.ftl_safety_override) + return + await_emergency_ftl_confirm = world.time + 15 SECONDS + say("Emergency FTL request signal received from Navigation system. Manual confirmation required.") + radio.talk_into(src, "Emergency FTL request signal received from Navigation system. Manual confirmation required.", radio_channel) + /* Preset classes of FTL drive with pre-programmed behaviours */ @@ -292,6 +305,22 @@ Preset classes of FTL drive with pre-programmed behaviours return auto_spool_enabled = !auto_spool_enabled . = TRUE + if("emergency_jump") + . = TRUE + if(!linked.ftl_safety_override) + return + if(world.time < linked.next_emergency_jump) + say("Failsafe Capacitor still recharging. Emergency transition unavailable.") + await_emergency_ftl_confirm = 0 + return + if(world.time > await_emergency_ftl_confirm) + return + if(progress / req_charge < 0.25) + say("FTL not sufficiently spooled for emergency transition. 25% of full charge required.") + await_emergency_ftl_confirm = 0 + return + await_emergency_ftl_confirm = 0 + linked.emergency_jump() /obj/machinery/computer/ship/ftl_core/ui_data(mob/user) var/list/data = list() @@ -317,14 +346,15 @@ Preset classes of FTL drive with pre-programmed behaviours data["pylons"] = all_pylon_info data["can_auto_spool"] = auto_spool_capable data["auto_spool_enabled"] = auto_spool_enabled + data["await_emergency_ftl_confirm"] = (await_emergency_ftl_confirm > world.time && linked.ftl_safety_override) return data -/obj/machinery/computer/ship/ftl_core/proc/jump(datum/star_system/target_system, force=FALSE) +/obj/machinery/computer/ship/ftl_core/proc/jump(datum/star_system/target_system, force=FALSE, misjump = FALSE) ftl_state = FTL_STATE_JUMPING if(!target_system) radio.talk_into(src, "ERROR. Specified star_system no longer exists.", radio_channel) return - linked.begin_jump(target_system, force) + linked.begin_jump(target_system, force, misjump) playsound(src, 'nsv13/sound/voice/ftl_start.wav', 100, FALSE) radio.talk_into(src, "Initiating FTL translation.", radio_channel) playsound(src, 'nsv13/sound/effects/ship/freespace2/computer/escape.wav', 100, 1) diff --git a/nsv13/code/modules/overmap/FTL/ftl_jump.dm b/nsv13/code/modules/overmap/FTL/ftl_jump.dm index bcdfc6b9120..2db3738de46 100644 --- a/nsv13/code/modules/overmap/FTL/ftl_jump.dm +++ b/nsv13/code/modules/overmap/FTL/ftl_jump.dm @@ -161,10 +161,10 @@ system_contents -= OM -/obj/structure/overmap/proc/begin_jump(datum/star_system/target_system, force=FALSE) +/obj/structure/overmap/proc/begin_jump(datum/star_system/target_system, force=FALSE, misjump = FALSE) relay(ftl_drive.ftl_start, channel = CHANNEL_IMPORTANT_SHIP_ALERT) desired_angle = 90 //90 degrees AKA face EAST to match the FTL parallax. - addtimer(CALLBACK(src, PROC_REF(jump_start), target_system, force), ftl_drive.ftl_startup_time) + addtimer(CALLBACK(src, PROC_REF(jump_start), target_system, force, misjump), ftl_drive.ftl_startup_time) /obj/structure/overmap/proc/force_return_jump() SIGNAL_HANDLER @@ -214,14 +214,16 @@ if(M && M.client && M.hud_used && length(M.client.parallax_layers)) M.hud_used.update_parallax(force=TRUE) -/obj/structure/overmap/proc/jump_start(datum/star_system/target_system, force=FALSE) +/obj/structure/overmap/proc/jump_start(datum/star_system/target_system, force=FALSE, misjump = FALSE) if(ftl_drive?.ftl_state != FTL_STATE_JUMPING) - if(force && ftl_drive) + if((force || misjump) && ftl_drive) ftl_drive.ftl_state = FTL_STATE_JUMPING else log_runtime("DEBUG: jump_start: aborted jump to [target_system], drive state = [ftl_drive?.ftl_state]") return - if((SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CHECK_INTERDICT, src) & BEING_INTERDICTED) && !force) // Override interdiction if the game is over + + var/interdict_return = SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CHECK_INTERDICT, src) + if(!force && ((interdict_return & STRONG_INTERDICT) || ((interdict_return & WEAK_INTERDICT) && !misjump))) // Override interdiction if the game is over, flying unsafe also bypasses non-fielddisruptive interdiction. ftl_drive.radio.talk_into(ftl_drive, "Warning. Local energy anomaly detected - calculated jump parameters invalid. Performing emergency reboot.", ftl_drive.radio_channel) relay('sound/magic/lightning_chargeup.ogg', channel=CHANNEL_IMPORTANT_SHIP_ALERT) ftl_drive.depower() @@ -242,6 +244,8 @@ if(drive_speed <= 0) //Assumption: If we got into this proc with speed 0, we want it to jump anyways, as it should be caught before otherwise. Using very slow speed in this case. drive_speed = 1 //Div-by-0s are not fun. var/speed = (curr.dist(target_system) / (drive_speed * 10)) //TODO: FTL drive speed upgrades. + if(misjump) + speed = max(speed, 3) SSstar_system.ships[src]["to_time"] = world.time + speed MINUTES SEND_SIGNAL(src, COMSIG_FTL_STATE_CHANGE) if(role == MAIN_OVERMAP) //Scuffed please fix @@ -255,9 +259,11 @@ SSstar_system.ships[src]["target_system"] = target_system SSstar_system.ships[src]["from_time"] = world.time SSstar_system.ships[src]["current_system"] = null - addtimer(CALLBACK(src, PROC_REF(jump_end), target_system), speed MINUTES) + addtimer(CALLBACK(src, PROC_REF(jump_end), target_system, misjump), speed MINUTES) ftl_drive.depower(ftl_drive.auto_spool_enabled) jump_handle_shake() + if(misjump) + on_misjump_start(target_system, (speed MINUTES)) force_parallax_update(TRUE) /obj/structure/overmap/proc/jump_handle_shake(ftl_start) @@ -286,7 +292,7 @@ shake_with_inertia(M, 4, 1, list(distance=nearestDistance, machine=nearestMachine)) -/obj/structure/overmap/proc/jump_end(datum/star_system/target_system) +/obj/structure/overmap/proc/jump_end(datum/star_system/target_system, misjump = FALSE) if(reserved_z) //Actual overmap parallax behaviour var/datum/space_level/SL = SSmapping.z_list[reserved_z] SL.set_parallax( (current_system != null) ? current_system.parallax_property : target_system.parallax_property, null) @@ -300,7 +306,15 @@ SSstar_system.ships[src]["from_time"] = 0 SSstar_system.ships[src]["to_time"] = 0 SEND_SIGNAL(src, COMSIG_FTL_STATE_CHANGE) - relay(ftl_drive.ftl_exit, "You feel the ship lurch to a halt", loop=FALSE, channel = CHANNEL_SHIP_ALERT) + if(!misjump) + relay(ftl_drive.ftl_exit, "You feel the ship lurch to a halt", loop=FALSE, channel = CHANNEL_SHIP_ALERT) + else + var/exit_sound = pick(list('nsv13/sound/effects/ship/misjump/misjump_exit_01.ogg', 'nsv13/sound/effects/ship/misjump/misjump_exit_02.ogg')) + relay(message = "You feel the ship violently leave drive space!") + for(var/mob/mob in mobs_in_ship) + if(!mob.client) + continue + mob.playsound_local(soundin = exit_sound, vol = 100, vary = FALSE) //Going for direct sound over relay because people should hear this, while system related sounds sometimes override relay. var/list/pulled = list() for(var/obj/structure/overmap/SOM as() in GLOB.overmap_objects) //Needs to go through global objects due to being in jumpspace not a system. @@ -317,9 +331,10 @@ SEND_SIGNAL(src, COMSIG_SHIP_ARRIVED) // Let missions know we have arrived in the system jump_handle_shake() + if(misjump) + on_misjump_end(target_system) force_parallax_update(FALSE) - /obj/item/ftl_slipstream_chip name = "Quantum slipstream field generation matrix (tier II)" desc = "An upgrade to the ship's FTL computer, allowing it to benefit from cutting edge calculation technologies to result in faster jump times by changing the way in which it allows the ship to incurse into bluespace." diff --git a/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/jump_mishap_helpers.dm b/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/jump_mishap_helpers.dm new file mode 100644 index 00000000000..4b2c1b837e2 --- /dev/null +++ b/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/jump_mishap_helpers.dm @@ -0,0 +1,326 @@ +///Has the ship begin an emergency jump. Very hazardous. +/obj/structure/overmap/proc/emergency_jump() + var/datum/star_system/target_system = current_system + var/list/viable_systems = SSstar_system.systems.Copy() + shuffle_inplace(viable_systems) + for(var/datum/star_system/potential_target as() in viable_systems) + if(current_system.dist(potential_target) > EMERGENCY_FTL_RANGE) + continue + if(potential_target.hidden) + continue + if(potential_target.sector != current_system.sector) + continue + target_system = potential_target + break + next_emergency_jump = world.time + EMERGENCY_FTL_COOLDOWN + ftl_drive.jump(target_system, misjump = TRUE) //Buckle up, here we go. + +///Called on jump start if the jump is a misjump. +/obj/structure/overmap/proc/on_misjump_start(datum/star_system/target_system, jump_length) + if(!occupying_levels || !linked_areas) + take_damage(0.4 * max_integrity, BRUTE, bypasses_shields = TRUE, sound_effect = FALSE) + return + else + take_damage((rand(5, 10) / 100) * max_integrity, BRUTE, bypasses_shields = TRUE, sound_effect = FALSE) + handle_concerning_noises(jump_length) + addtimer(CALLBACK(src, PROC_REF(fry_phasestate)), rand(35, 180) SECONDS) + disjoint_phasestate() + +///Called on jump end if the jump is a misjump. +/obj/structure/overmap/proc/on_misjump_end(datum/star_system/target_system) + if(!occupying_levels || !linked_areas) + take_damage(0.5 * max_integrity, BRUTE, bypasses_shields = TRUE, sound_effect = FALSE, nsv_damagesound = FALSE) + return + else + var/structure_stress = prob(25) ? 10 : rand(15,75) + var/structure_damage = (structure_stress / 100) * max_integrity + take_damage(structure_damage, BRUTE, bypasses_shields = TRUE, sound_effect = FALSE, nsv_damagesound = FALSE) + + var/fun_meteors = pick(0,0,0,0,1,2,2,3,4) + var/oops_asteroid_collision = 25 + for(var/obj/structure/overmap/asteroid/asteroid in target_system.system_contents) + oops_asteroid_collision += 5 + oops_asteroid_collision = CLAMP(oops_asteroid_collision, 25, 90) + fry_phasestate() + if(prob(oops_asteroid_collision)) + handle_asteroid_phase_collision() + if(fun_meteors > 0) + handle_meteor_launches(fun_meteors) + +///Provides occassional concerning noises while emergency jumping, also occasionally distorts the drive bubble, creating anomalies. +/obj/structure/overmap/proc/handle_concerning_noises(jump_length) + new /datum/misjump_noise_handler(src, jump_length) + +//Creates fun and engaging noises, self deletes shortly before jump end, or on end, or if the owner deletes. Also does some other stuff. +/datum/misjump_noise_handler + ///Linked overmap + var/obj/structure/overmap/linked + ///Next world.time or above to do things at + var/next_noise = 0 + ///Sounds to choose from + var/static/list/yowie_sounds = list('nsv13/sound/ambience/ship_damage/creak5.ogg' = 10, 'nsv13/sound/ambience/ship_damage/creak6.ogg' = 10, 'nsv13/sound/ambience/ship_damage/creak7.ogg' = 2) + ///The timer that tracks our time-based deletion + var/deletetimer + +/datum/misjump_noise_handler/New(obj/structure/overmap/linked_ship, jump_length) + . = ..() + if(!linked_ship) + log_runtime("A misjump noise handler was created without a linked ship :(") + linked = linked_ship + deletetimer = addtimer(CALLBACK(src, PROC_REF(on_timer_expire)), jump_length - (20 SECONDS), TIMER_STOPPABLE) + RegisterSignal(linked, COMSIG_PARENT_QDELETING, PROC_REF(cease_noise)) //If we are somehow faster than we expected. + RegisterSignal(linked, COMSIG_SHIP_ARRIVED, PROC_REF(cease_noise)) + START_PROCESSING(SSprocessing, src) + +///Handles deletion if our timer runs out. +/datum/misjump_noise_handler/proc/on_timer_expire() + deletetimer = null + qdel(src) + +///Handles deletion if one of our two signals gets triggered. +/datum/misjump_noise_handler/proc/cease_noise() + SIGNAL_HANDLER + qdel(src) + +/datum/misjump_noise_handler/Destroy(force, ...) + if(deletetimer) + deltimer(deletetimer) + deletetimer = null + UnregisterSignal(linked, COMSIG_PARENT_QDELETING) + UnregisterSignal(linked, COMSIG_SHIP_ARRIVED) + linked = null + STOP_PROCESSING(SSprocessing, src) + return ..() + +/datum/misjump_noise_handler/process(delta_time) + if(next_noise > world.time) + return + var/yowie_sound = pickweight(yowie_sounds) + linked.relay(yowie_sound) + if(prob(1)) + var/oops_reality_distortion = pick(/obj/effect/anomaly/stormdrive, /obj/effect/anomaly/stormdrive/sheer, /obj/effect/anomaly/bluespace) + var/list/possible_areas = linked.linked_areas.Copy() //we really should have a different space area for the NSV huh (and we even already have nearstation) + shuffle_inplace(possible_areas) + var/area/target_area + for(var/area/possible_area in possible_areas) + if(istype(possible_area, /area/space)) + continue + target_area = possible_area + break + var/turf/target_turf + for(var/turf/possible_target in target_area.contents) + target_turf = possible_target + break + if(target_turf) + new oops_reality_distortion(target_turf) + if(linked.reserved_z) + var/turf/hmmm = locate(rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE), rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE), linked.reserved_z) + if(hmmm) + new /obj/structure/overmap/ref_0x000000(hmmm, linked) + if(linked.structure_crit && prob(20)) //Bad times. + var/datum/space_level/picked_z = pick(linked.occupying_levels) + var/turf/explode_turf = locate(rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE), rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE), picked_z.z_value) + if(isturf(explode_turf) && !isspaceturf(explode_turf)) //If we roll space, you got lucky. + new /obj/effect/temp_visual/explosion_telegraph(explode_turf, 100 * round(((world.time - linked.structure_crit_init) / (1 MINUTES)) + 1)) + next_noise = world.time + 8 SECONDS + +///Launches a meteor from the front side somewhere towards the vessel. +/obj/structure/overmap/proc/handle_meteor_launches(fun_meteors = 0) + var/list/possible_areas = linked_areas.Copy() + for(var/i = 1; i <= fun_meteors; i++) + shuffle_inplace(possible_areas) + var/area/main_target_area + for(var/area/possible_area in possible_areas) + if(istype(possible_area, /area/space)) + continue + main_target_area = possible_area + break + var/turf/main_target_turf + for(var/turf/possible_target_turf in main_target_area.contents) + main_target_turf = possible_target_turf + break + if(!main_target_turf) //huh? + continue + var/turf/spawn_turf = locate(world.maxx - (TRANSITIONEDGE+1), main_target_turf.y, main_target_turf.z) + var/turf/real_target = locate((TRANSITIONEDGE+1), main_target_turf.y, main_target_turf.z) + if(!spawn_turf || !real_target) + continue + var/meteor_type = pickweight(GLOB.meteors_threatening) + new meteor_type(spawn_turf, real_target) + +// ~ +/obj/structure/overmap/ref_0x000000 + name = "??????" + max_integrity = 10000 + obj_integrity = 10000 + desc = null + alpha = 0 + layer = EFFECTS_LAYER + opacity = MOUSE_OPACITY_TRANSPARENT + invisibility = INVISIBILITY_MAXIMUM + resistance_flags = INDESTRUCTIBLE + destruction_effects = FALSE + ///Linked overmap + var/obj/structure/overmap/linked + brakes = FALSE + inertial_dampeners = FALSE + sensor_profile = 255 + +/obj/structure/overmap/ref_0x000000/handle_cloak(state) + return + +/obj/structure/overmap/ref_0x000000/take_damage(damage_amount, damage_type, damage_flag, sound_effect, bypasses_shields, nsv_damagesound) + return + +/obj/structure/overmap/ref_0x000000/bullet_act(obj/item/projectile/P) + return BULLET_ACT_FORCE_PIERCE + +/obj/structure/overmap/ref_0x000000/ex_act() + return + +/obj/structure/overmap/ref_0x000000/singularity_act() + return + +/obj/structure/overmap/ref_0x000000/apply_weapons() + return + +/obj/structure/overmap/ref_0x000000/is_sensor_visible(obj/structure/overmap/observer) + return SENSOR_VISIBILITY_VERYFAINT + +/obj/structure/overmap/ref_0x000000/Initialize(mapload, obj/structure/overmap/linked_ship) + . = ..() + linked = linked_ship + RegisterSignal(linked, COMSIG_SHIP_ARRIVED, PROC_REF(self_delete)) + velocity.a += (rand() - 0.5) * 2 + velocity.e += (rand() - 0.5) * 2 + QDEL_IN(src, rand(2,4) MINUTES) + +///Handles self deletion if signal is triggered +/obj/structure/overmap/ref_0x000000/proc/self_delete() + SIGNAL_HANDLER + qdel(src) + +/obj/structure/overmap/ref_0x000000/Destroy(force) + UnregisterSignal(linked, COMSIG_SHIP_ARRIVED) + linked = null + return ..() + +///Called if the ship decides to leave drive space in a very bad spot. +/obj/structure/overmap/proc/handle_asteroid_phase_collision() + if(!occupying_levels) + return + var/datum/space_level/target_z_level = pick(occupying_levels) + var/target_z = target_z_level.z_value + var/target_x = rand(40, world.maxx -40) + var/target_y = rand(40, world.maxy -40) + var/core_turf = locate(target_x, target_y, target_z) + var/list/potential_asteroids = flist("_maps/map_files/Mining/nsv13/asteroids/") + var/datum/map_template/asteroid_template = new /datum/map_template/asteroid("_maps/map_files/Mining/nsv13/asteroids/[pick(potential_asteroids)]", null, FALSE, list(/turf/closed/mineral/iron, /turf/closed/mineral/titanium, /turf/closed/mineral/plasma, /turf/closed/mineral/bscrystal)) + var/list/asteroidbounds = asteroid_template.load(core_turf, TRUE, TRUE) + var/turf/bound1 = locate(asteroidbounds[MAP_MINX], asteroidbounds[MAP_MINY], asteroidbounds[MAP_MINZ]) + var/turf/bound2 = locate(asteroidbounds[MAP_MAXX], asteroidbounds[MAP_MAXY], asteroidbounds[MAP_MAXZ]) + if(!bound1 || !bound2) + return + for(var/y_iter = bound1.y, y_iter <= bound2.y, y_iter++) + for(var/x_iter = bound1.x, x_iter <= bound2.x, x_iter++) + var/turf/squish = locate(x_iter, y_iter, target_z) + if(!isclosedturf(squish)) + continue + for(var/mob/living/squished in squish) + if(squished.client) + to_chat(squished, "You are suddenly crushed by something solid materializing in your own space!") + squished.gib() + +///Messes with turf spacetime in a certain area. +/obj/structure/overmap/proc/disjoint_phasestate() + for(var/mob/living/cloned in mobs_in_ship) + var/turf/target_turf = get_turf(cloned) + if(!target_turf) + continue + var/obj/effect/abstract/phase_ghost/ghost = new(target_turf) + ghost.set_up(cloned) + var/list/possible_areas = linked_areas.Copy() + shuffle_inplace(possible_areas) + var/area/target_area + for(var/area/possible_area in possible_areas) + if(istype(possible_area, /area/space)) + continue + target_area = possible_area + break + var/turf/target_turf + for(var/turf/possible_turf in target_area.contents) + target_turf = possible_turf //Why in the name of Ratvar is there no turf area list. + break + if(!target_turf) + return + var/list/turfs = spiral_range_turfs(12, target_turf) + if(!turfs.len) + return + var/list/turf_steps = list() + var/length = round(turfs.len * 0.5) + for(var/i in 1 to length) + turf_steps[pick_n_take(turfs)] = pick_n_take(turfs) + if(turfs.len > 0) + var/turf/loner = pick(turfs) + turf_steps[loner] = get_turf(pick(target_area.contents)) + + var/list/effects = list() + for(var/V in turf_steps) + var/turf/T0 = V + var/turf/T1 = turf_steps[V] + var/obj/effect/cross_action/spacetime_dist/STD0 = new /obj/effect/cross_action/spacetime_dist(T0) + var/obj/effect/cross_action/spacetime_dist/STD1 = new /obj/effect/cross_action/spacetime_dist(T1) + STD0.linked_dist = STD1 + STD0.add_overlay(T1.photograph()) + STD1.linked_dist = STD0 + STD1.add_overlay(T0.photograph()) + STD1.set_light(4, 30, "#c9fff5") + effects += STD0 + effects += STD1 + addtimer(CALLBACK(src, PROC_REF(clear_distortion), effects), rand(4,6) MINUTES) + +///Resets things after the timer expires +/obj/structure/overmap/proc/clear_distortion(list/effects) + for(var/effect in effects) + qdel(effect) + +///Causes permanent spatial displacement. +/obj/structure/overmap/proc/fry_phasestate() + var/num = rand(1,3) + var/list/possible_area_picks = linked_areas.Copy() //we really should have a different space area for the NSV huh (and we even already have nearstation) + shuffle_inplace(possible_area_picks) + for(var/area/possible_area in possible_area_picks) + if(istype(possible_area, /area/space)) + possible_area_picks -= possible_area + num = min(num, length(possible_area_picks)) + for(var/frycount = 1; frycount <= num; frycount++) + var/area/target_area = pick_n_take(possible_area_picks) + var/turf/target_turf = get_turf(pick(target_area.contents)) + if(!target_turf) + continue + var/list/to_scrungle = RANGE_TURFS(3, target_turf) + shuffle_inplace(to_scrungle) + for(var/i = 1; i <= length(to_scrungle)-1; i += 2) + ///Turf doing the swapping + var/turf/turf1 = to_scrungle[i] + ///Turf being swapped with. + var/turf/turf2 = to_scrungle[i+1] + ///Type of second turf. + var/turf2_type = turf2.type + ///Baseturfs of second turf. + var/list/turf2_originals + if(islist(turf2.baseturfs)) //Why can baseturfs both be a single non-list path or a list of them.. + turf2_originals = turf2.baseturfs.Copy() + else + turf2_originals = turf2.baseturfs + ///Contents of the second turf. + var/list/turf2_contents = turf2.contents.Copy() + if(islist(turf1.baseturfs)) + turf2.ChangeTurf(turf1.type, turf1.baseturfs.Copy(), CHANGETURF_INHERIT_AIR) + else + turf2.ChangeTurf(turf1.type, turf1.baseturfs, CHANGETURF_INHERIT_AIR) + for(var/atom/movable/thing in turf1) + thing.forceMove(turf2) + turf1.ChangeTurf(turf2_type, turf2_originals, CHANGETURF_INHERIT_AIR) + for(var/atom/movable/thing in turf2_contents) + thing.forceMove(turf1) diff --git a/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/phase_ghost.dm b/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/phase_ghost.dm new file mode 100644 index 00000000000..06f04a2fdad --- /dev/null +++ b/nsv13/code/modules/overmap/FTL/ftl_jump_mishaps/phase_ghost.dm @@ -0,0 +1,24 @@ +/obj/effect/abstract/phase_ghost + name = "?????" + alpha = 0 + invisibility = INVISIBILITY_MAXIMUM + resistance_flags = INDESTRUCTIBLE + +///Links the echo to a existing thing. +/obj/effect/abstract/phase_ghost/proc/set_up(mob/living/clone) + icon = clone.icon + icon_state = clone.icon_state + copy_overlays(clone, TRUE) + addtimer(CALLBACK(src, PROC_REF(appear)), rand(3, 6) MINUTES) + +///Makes the echo visible, and sets it to disappear later. +/obj/effect/abstract/phase_ghost/proc/appear() + invisibility = 0 + alpha = 100 + add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + QDEL_IN(src, rand(13, 20) MINUTES) + +/obj/effect/abstract/phase_ghost/Destroy(force) + icon = null + icon_state = null + return ..() diff --git a/nsv13/code/modules/overmap/FTL/ftl_legacy.dm b/nsv13/code/modules/overmap/FTL/ftl_legacy.dm index 0d48a618bbb..4e9fc054947 100644 --- a/nsv13/code/modules/overmap/FTL/ftl_legacy.dm +++ b/nsv13/code/modules/overmap/FTL/ftl_legacy.dm @@ -35,6 +35,9 @@ var/auto_spool_enabled = FALSE //For lazy admins var/lockout = FALSE //Used for our end round shenanigains + ///world.time until which an user can confirm the emergency jump triggered by Nav. + var/await_emergency_ftl_confirm = 0 + /obj/machinery/computer/ship/ftl_computer/attackby(obj/item/I, mob/user) //Allows you to upgrade dradis consoles to show asteroids, as well as revealing more valuable ones. . = ..() if(istype(I, /obj/item/ftl_slipstream_chip)) @@ -212,6 +215,22 @@ A way for syndies to track where the player ship is going in advance, so they ca jump(S) check_active(FALSE) break + if("emergency_jump") + . = TRUE + if(!linked.ftl_safety_override) + return + if(world.time > await_emergency_ftl_confirm) + return + if(world.time < linked.next_emergency_jump) + say("Failsafe Capacitor still recharging. Emergency transition unavailable.") + await_emergency_ftl_confirm = 0 + return + if(progress / spoolup_time < 0.25) + say("FTL not sufficiently spooled for emergency transition. 25% of full charge required.") + await_emergency_ftl_confirm = 0 + return + await_emergency_ftl_confirm = 0 + linked.emergency_jump() /obj/machinery/computer/ship/ftl_computer/ui_data(mob/user) var/list/data = list() @@ -232,6 +251,7 @@ A way for syndies to track where the player ship is going in advance, so they ca for(var/datum/star_system/S in SSstar_system.systems) if(S.visitable && S != linked.current_system) data["systems"] += list(list("name" = S.name, "distance" = "2 minutes")) + data["await_emergency_ftl_confirm"] = (await_emergency_ftl_confirm > world.time && linked.ftl_safety_override) return data /obj/machinery/computer/ship/ftl_computer/proc/check_active(state) @@ -242,11 +262,11 @@ A way for syndies to track where the player ship is going in advance, so they ca depower() STOP_PROCESSING(SSmachines, src) -/obj/machinery/computer/ship/ftl_computer/proc/jump(datum/star_system/target_system, force=FALSE) +/obj/machinery/computer/ship/ftl_computer/proc/jump(datum/star_system/target_system, force=FALSE, misjump = FALSE) if(!target_system) radio.talk_into(src, "ERROR. Specified star_system no longer exists.", radio_channel) return - linked?.begin_jump(target_system, force) + linked?.begin_jump(target_system, force, misjump) playsound(src, 'nsv13/sound/voice/ftl_start.wav', 100, FALSE) radio.talk_into(src, "Initiating FTL translation.", radio_channel) playsound(src, 'nsv13/sound/effects/ship/freespace2/computer/escape.wav', 100, 1) @@ -310,9 +330,22 @@ A way for syndies to track where the player ship is going in advance, so they ca if(auto_spool_enabled) active = TRUE spoolup() - START_PROCESSING(SSmachines, src) + if(!(datum_flags & DF_ISPROCESSING)) + START_PROCESSING(SSmachines, src) + else if(datum_flags & DF_ISPROCESSING) + STOP_PROCESSING(SSmachines, src) return TRUE return FALSE /obj/machinery/computer/ship/ftl_computer/proc/get_jump_speed() return jump_speed_factor + +///Requests emergency FTL, needs manual confirm at the machine itself. +/obj/machinery/computer/ship/ftl_computer/proc/request_emergency_ftl_confirm() + if(await_emergency_ftl_confirm - world.time > 0) + return + if(!linked.ftl_safety_override) + return + await_emergency_ftl_confirm = world.time + 15 SECONDS + say("Emergency FTL request signal received from Navigation system. Manual confirmation required.") + radio.talk_into(src, "Emergency FTL request signal received from Navigation system. Manual confirmation required.", radio_channel) diff --git a/nsv13/code/modules/overmap/ai-skynet.dm b/nsv13/code/modules/overmap/ai-skynet.dm index 650158d08c2..65ed142df1a 100644 --- a/nsv13/code/modules/overmap/ai-skynet.dm +++ b/nsv13/code/modules/overmap/ai-skynet.dm @@ -228,7 +228,8 @@ Adding tasks is easy! Just define a datum for it. if(world.time < last_encounter_time + combat_move_delay) //So that fleets don't leave mid combat. return FALSE - if(SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CHECK_INTERDICT, pick(all_ships)) & BEING_INTERDICTED) //Hypothesis: All ships within a fleet should have the same faction. + var/interdict_return = SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CHECK_INTERDICT, pick(all_ships)) //Hypothesis: All ships within a fleet should have the same faction. + if((interdict_return & (WEAK_INTERDICT|STRONG_INTERDICT))) return FALSE current_system.fleets -= src diff --git a/nsv13/code/modules/overmap/fighters/_fighters.dm b/nsv13/code/modules/overmap/fighters/_fighters.dm index b44e62bf267..5d120b5b21b 100644 --- a/nsv13/code/modules/overmap/fighters/_fighters.dm +++ b/nsv13/code/modules/overmap/fighters/_fighters.dm @@ -407,7 +407,7 @@ Been a mess since 2018, we'll fix it someday (probably) name = "Peregrine class attack fighter" desc = "A Peregrine class attack fighter, solgov's only premiere fighter, mounting minature capital grade phasers and a tiny shield generator." icon = 'nsv13/icons/overmap/new/solgov/playablefighter.dmi' - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 30, "bomb" = 30, "bio" = 100, "rad" = 90, "fire" = 90, "acid" = 80, "overmap_light" = 5, "overmap_medium" = 0, "overmap_heavy" = 10) + armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 30, "bomb" = 30, "bio" = 100, "rad" = 90, "fire" = 90, "acid" = 80, "overmap_light" = 5, "overmap_medium" = 0, "overmap_heavy" = 10) sprite_size = 32 damage_states = FALSE //temp max_integrity = 25 //shields. @@ -770,7 +770,7 @@ Been a mess since 2018, we'll fix it someday (probably) return ..() -/obj/structure/overmap/small_craft/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, bypasses_shields = FALSE) +/obj/structure/overmap/small_craft/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, bypasses_shields = FALSE, nsv_damagesound = TRUE) var/obj/item/fighter_component/armour_plating/A = loadout.get_slot(HARDPOINT_SLOT_ARMOUR) if(A && istype(A)) A.take_damage(damage_amount, damage_type, damage_flag, sound_effect) diff --git a/nsv13/code/modules/overmap/interdiction.dm b/nsv13/code/modules/overmap/interdiction.dm index 9a80525514f..f18e72ff062 100644 --- a/nsv13/code/modules/overmap/interdiction.dm +++ b/nsv13/code/modules/overmap/interdiction.dm @@ -19,7 +19,7 @@ Welcome to the gardens of kadesh. You shall never leave. if(owner.faction == interdicted.faction) return owner.on_interdict() - return BEING_INTERDICTED + return WEAK_INTERDICT /* diff --git a/nsv13/code/modules/overmap/overmap.dm b/nsv13/code/modules/overmap/overmap.dm index 2c5eba460a9..aad2662871a 100644 --- a/nsv13/code/modules/overmap/overmap.dm +++ b/nsv13/code/modules/overmap/overmap.dm @@ -28,6 +28,9 @@ var/overmap_deletion_traits = DAMAGE_DELETES_UNOCCUPIED | DAMAGE_STARTS_COUNTDOWN var/deletion_teleports_occupants = FALSE + ///Should sound be relayed & the destruction overlay be created on destruction? + var/destruction_effects = TRUE + var/sprite_size = 64 //Pixels. This represents 64x64 and allows for the bullets that you fire to align properly. var/area_type = null //Set the type of the desired area you want a ship to link to, assuming it's not the main player ship. var/impact_sound_cooldown = FALSE //Avoids infinite spamming of the ship taking damage. @@ -188,6 +191,11 @@ // It's terrible I know, but until we decide/are bothered enough to throw out the legacy drive (or subtype it), this'll have to do var/obj/machinery/computer/ship/ftl_core/ftl_drive + ///FTL safety state + var/ftl_safety_override = FALSE + ///FTL emergency jump cooldown; Only available once every 25 minutes. + var/next_emergency_jump = 0 + //Misc variables var/list/scanned = list() //list of scanned overmap anomalies var/reserved_z = 0 //The Z level we were spawned on, and thus inhabit. This can be changed if we "swap" positions with another ship. @@ -516,15 +524,17 @@ Proc to spool up a new Z-level for a player ship and assign it a treadmill. for(var/mob/living/M in operators) stop_piloting(M) GLOB.overmap_objects -= src - relay('nsv13/sound/effects/ship/damage/ship_explode.ogg') - relay_to_nearby('nsv13/sound/effects/ship/damage/disable.ogg') //Kaboom. - new /obj/effect/temp_visual/fading_overmap(get_turf(src), name, icon, icon_state) + if(destruction_effects) + relay('nsv13/sound/effects/ship/damage/ship_explode.ogg') + relay_to_nearby('nsv13/sound/effects/ship/damage/disable.ogg') //Kaboom. + new /obj/effect/temp_visual/fading_overmap(get_turf(src), name, icon, icon_state) for(var/obj/structure/overmap/OM in enemies) //If target's in enemies, return var/sound = pick('nsv13/sound/effects/computer/alarm.ogg','nsv13/sound/effects/computer/alarm_2.ogg') var/message = "ATTENTION: [src]'s reactor is going supercritical. Destruction imminent." OM?.tactical?.relay_sound(sound, message) OM.enemies -= src //Stops AI from spamming ships that are already dead - overmap_explode(linked_areas) + if(length(linked_areas)) + overmap_explode(linked_areas) if(role == MAIN_OVERMAP) priority_announce("WARNING: ([rand(10,100)]) Attempts to establish DRADIS uplink with [station_name()] have failed. Unable to ascertain operational status. Presumed status: TERMINATED","Central Intelligence Unit", 'nsv13/sound/effects/ship/reactor/explode.ogg') Cinematic(CINEMATIC_NSV_SHIP_KABOOM,world) @@ -839,9 +849,9 @@ Proc to spool up a new Z-level for a player ship and assign it a treadmill. progress = round(((progress / goal) * 100), 25)//Round it down to 20%. We now apply visual damage icon_state = "[initial(icon_state)]-[progress]" -/obj/structure/overmap/proc/relay(S, var/message=null, loop = FALSE, channel = null) //Sends a sound + text message to the crew of a ship +/obj/structure/overmap/proc/relay(S, var/message=null, loop = FALSE, channel = null) //Sends a sound and / or text message to the crew of a ship for(var/mob/M as() in mobs_in_ship) - if(M.can_hear()) + if(S && M.can_hear()) if(channel) //Doing this forbids overlapping of sounds SEND_SOUND(M, sound(S, repeat = loop, wait = 0, volume = 100, channel = channel)) else diff --git a/nsv13/code/modules/overmap/starmap.dm b/nsv13/code/modules/overmap/starmap.dm index 154f7ab7fe0..dc8d2787885 100644 --- a/nsv13/code/modules/overmap/starmap.dm +++ b/nsv13/code/modules/overmap/starmap.dm @@ -74,7 +74,13 @@ if(linked.ftl_drive.lockout) to_chat(usr, "[icon2html(src, viewers(src))] Unable to comply. Invalid authkey to unlock remove override code.") return - linked.ftl_drive.jump(selected_system) + if(linked.ftl_safety_override) + if(linked.next_emergency_jump > world.time) + say("Drive Emergency Capacitor is still recharging. Emergency jump unavailable.") + return TRUE + linked.ftl_drive.request_emergency_ftl_confirm() + else + linked.ftl_drive.jump(selected_system) . = TRUE if("cancel_jump") if(linked.ftl_drive.lockout) @@ -213,14 +219,15 @@ if(info["current_system"]) var/datum/star_system/curr = info["current_system"] data["star_dist"] = curr.dist(selected_system) - data["can_jump"] = current_system.dist(selected_system) < linked.ftl_drive?.max_range && linked.ftl_drive.ftl_state == FTL_STATE_READY && LAZYFIND(current_system.adjacency_list, selected_system.name) + data["can_jump"] = (current_system.dist(selected_system) < linked.ftl_drive?.max_range && linked.ftl_drive.ftl_state == FTL_STATE_READY && LAZYFIND(current_system.adjacency_list, selected_system.name)) || (linked.ftl_safety_override && linked.ftl_drive && linked.ftl_drive.ftl_state != FTL_STATE_JUMPING) if(return_jump_check(selected_system) && linked.ftl_drive.ftl_state == FTL_STATE_READY) data["can_jump"] = TRUE if(!can_control_ship) //For public consoles data["can_jump"] = FALSE data["can_cancel"] = FALSE + data["ftl_safety_override"] = linked?.ftl_safety_override data["screen"] = screen - data["can_cancel"] = linked?.ftl_drive?.ftl_state == FTL_STATE_JUMPING && linked?.ftl_drive?.can_cancel_jump + data["can_cancel"] = linked?.ftl_drive?.ftl_state == FTL_STATE_JUMPING && linked?.ftl_drive?.can_cancel_jump && !linked?.ftl_safety_override return data /obj/machinery/computer/ship/navigation/proc/is_in_range(datum/star_system/current_system, datum/star_system/system) diff --git a/nsv13/code/modules/overmap/weapons/damage.dm b/nsv13/code/modules/overmap/weapons/damage.dm index 09147b657e4..d1b75b92f79 100644 --- a/nsv13/code/modules/overmap/weapons/damage.dm +++ b/nsv13/code/modules/overmap/weapons/damage.dm @@ -75,7 +75,7 @@ Bullet reactions /obj/structure/overmap/small_craft/relay_damage(proj_type) return -/obj/structure/overmap/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, bypasses_shields = FALSE) +/obj/structure/overmap/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, bypasses_shields = FALSE, nsv_damagesound = TRUE) var/blocked = FALSE var/damage_sound = pick(GLOB.overmap_impact_sounds) if(!bypasses_shields && shields && shields.absorb_hit(damage_amount)) @@ -83,7 +83,7 @@ Bullet reactions damage_sound = pick('nsv13/sound/effects/ship/damage/shield_hit.ogg', 'nsv13/sound/effects/ship/damage/shield_hit2.ogg') if(!impact_sound_cooldown) add_overlay(new /obj/effect/temp_visual/overmap_shield_hit(get_turf(src), src)) - if(!impact_sound_cooldown && damage_sound) + if(nsv_damagesound && !impact_sound_cooldown && damage_sound) relay(damage_sound) if(damage_amount >= 15) //Flak begone shake_everyone(5) diff --git a/nsv13/sound/effects/ship/misjump/misjump_exit_01.ogg b/nsv13/sound/effects/ship/misjump/misjump_exit_01.ogg new file mode 100644 index 00000000000..051963221df Binary files /dev/null and b/nsv13/sound/effects/ship/misjump/misjump_exit_01.ogg differ diff --git a/nsv13/sound/effects/ship/misjump/misjump_exit_02.ogg b/nsv13/sound/effects/ship/misjump/misjump_exit_02.ogg new file mode 100644 index 00000000000..3945fe10d77 Binary files /dev/null and b/nsv13/sound/effects/ship/misjump/misjump_exit_02.ogg differ diff --git a/nsv13/sound/misc/triple_boop_alert.ogg b/nsv13/sound/misc/triple_boop_alert.ogg new file mode 100644 index 00000000000..d25bd7c77dd Binary files /dev/null and b/nsv13/sound/misc/triple_boop_alert.ogg differ diff --git a/tgui/packages/tgui/interfaces/FTLComputer.js b/tgui/packages/tgui/interfaces/FTLComputer.js index fe9c3699f0e..44e5fb35446 100644 --- a/tgui/packages/tgui/interfaces/FTLComputer.js +++ b/tgui/packages/tgui/interfaces/FTLComputer.js @@ -10,48 +10,63 @@ export const FTLComputer = (props, context) => { return ( -
-
- act('toggle_power')} /> + {(data.await_emergency_ftl_confirm && ( +
+
+
-
- + )) || ( +
+
+ act('toggle_power')} /> +
+
+ +
+
+ {Object.keys(data.tracking).map(key => { + let value = data.tracking[key]; + return ( + +
+
+
); + })} +
-
- {Object.keys(data.tracking).map(key => { - let value = data.tracking[key]; - return ( - -
-
-
); - })} -
-
+ )} ); diff --git a/tgui/packages/tgui/interfaces/FTLComputerModular.js b/tgui/packages/tgui/interfaces/FTLComputerModular.js index 56a6153648f..b6323dd6e16 100644 --- a/tgui/packages/tgui/interfaces/FTLComputerModular.js +++ b/tgui/packages/tgui/interfaces/FTLComputerModular.js @@ -8,88 +8,103 @@ export const FTLComputerModular = (props, context) => { return ( -
-
- - {Object.keys(data.pylons).map(key => { - let value = data.pylons[key]; - return ( - -
-
-
); - })} -
-
-
-
-
- +
+ + {Object.keys(data.pylons).map(key => { + let value = data.pylons[key]; + return ( + +
+
+
); + })} +
+
+
+
+
+ + }} /> +
-
+ )} ); diff --git a/tgui/packages/tgui/interfaces/KeycardAuth.js b/tgui/packages/tgui/interfaces/KeycardAuth.js index 3229bf2d077..1b646643265 100644 --- a/tgui/packages/tgui/interfaces/KeycardAuth.js +++ b/tgui/packages/tgui/interfaces/KeycardAuth.js @@ -7,7 +7,7 @@ export const KeycardAuth = (props, context) => { return ( + height={150}>
@@ -47,6 +47,12 @@ export const KeycardAuth = (props, context) => { fluid onClick={() => act('bsa_unlock')} content="Bluespace Artillery Unlock" /> + {data.ftl_safety_override >= 0 && ( +