diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 51833046098..f68957ddb55 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -8,8 +8,12 @@ var/global/datum/shuttle_controller/shuttle_controller /datum/shuttle_controller/proc/process() //process ferry shuttles - for (var/datum/shuttle/ferry/shuttle in process_shuttles) - if (shuttle.process_state || shuttle.always_process) + for (var/datum/shuttle/shuttle in process_shuttles) + if(istype(shuttle, /datum/shuttle/ferry)) + var/datum/shuttle/ferry/F = shuttle + if(F.process_state || F.always_process) + F.process() + else shuttle.process() diff --git a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm index be978e7ee44..d83602aa68b 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm @@ -25,5 +25,6 @@ /obj/effect/temporary_effect/darkness name = "darkness" time_to_die = 2 MINUTES - new_light_range = 6 - new_light_power = -20 \ No newline at end of file + invisibility = 101 + light_range = 6 + light_power = -20 \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/spells/spawner/destablize.dm b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm index 1f7df21125b..29381701ca5 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/destablize.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm @@ -26,13 +26,11 @@ /obj/effect/temporary_effect/destablize name = "destablizing disturbance" desc = "This can't be good..." - icon = 'icons/effects/effects.dmi' icon_state = "blueshatter" time_to_die = null - invisibility = 0 - new_light_range = 6 - new_light_power = 20 - new_light_color = "#C26DDE" + light_range = 6 + light_power = 20 + light_color = "#C26DDE" var/pulses_remaining = 40 // Lasts 20 seconds. var/instability_power = 5 var/instability_range = 6 diff --git a/code/game/gamemodes/technomancer/spells/spawner/fire_blast.dm b/code/game/gamemodes/technomancer/spells/spawner/fire_blast.dm index ff1a3f7644f..69444a4c7b1 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/fire_blast.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/fire_blast.dm @@ -22,13 +22,11 @@ /obj/effect/temporary_effect/fire_blast name = "fire blast" desc = "Run!" - icon = 'icons/effects/effects.dmi' icon_state = "at_shield1" time_to_die = 2.5 SECONDS // After which we go boom. - invisibility = 0 - new_light_range = 4 - new_light_power = 5 - new_light_color = "#FF6A00" + light_range = 4 + light_power = 5 + light_color = "#FF6A00" /obj/effect/temporary_effect/fire_blast/Destroy() explosion(get_turf(src), -1, 1, 2, 5, adminlog = 1) diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index df13fd2460f..5641df2f87b 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -28,13 +28,11 @@ /obj/effect/temporary_effect/pulsar name = "pulsar" desc = "Not a real pulsar, but still emits loads of EMP." - icon = 'icons/effects/effects.dmi' icon_state = "shield2" time_to_die = null - invisibility = 0 - new_light_range = 4 - new_light_power = 5 - new_light_color = "#2ECCFA" + light_range = 4 + light_power = 5 + light_color = "#2ECCFA" var/pulses_remaining = 3 /obj/effect/temporary_effect/pulsar/New() diff --git a/code/game/gamemodes/technomancer/spells/spawner/spawner.dm b/code/game/gamemodes/technomancer/spells/spawner/spawner.dm index 218c4467398..ba86e700bb9 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/spawner.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/spawner.dm @@ -6,22 +6,6 @@ aspect = null var/obj/effect/spawner_type = null -/obj/effect/temporary_effect - name = "self deleting effect" - desc = "How are you examining what which cannot be seen?" - invisibility = 101 - var/time_to_die = 10 SECONDS // Afer which, it will delete itself. - var/new_light_range = 6 - var/new_light_power = 6 - var/new_light_color = "#FFFFFF" - -/obj/effect/temporary_effect/New() - ..() - set_light(new_light_range, new_light_power, l_color = new_light_color) - if(time_to_die) - spawn(time_to_die) - qdel(src) - /obj/item/weapon/spell/spawner/on_ranged_cast(atom/hit_atom, mob/user) var/turf/T = get_turf(hit_atom) if(T) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 6cc507aeecc..48026296d77 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -7,6 +7,19 @@ density = 1 anchored = 0 +/obj/effect/temporary_effect + name = "self deleting effect" + desc = "How are you examining what which cannot be seen?" + icon = 'icons/effects/effects.dmi' + invisibility = 0 + var/time_to_die = 10 SECONDS // Afer which, it will delete itself. + +/obj/effect/temporary_effect/New() + ..() + if(time_to_die) + spawn(time_to_die) + qdel(src) + // Shown really briefly when attacking with axes. /obj/effect/temporary_effect/cleave_attack name = "cleaving attack" @@ -16,12 +29,19 @@ layer = 6 time_to_die = 6 alpha = 140 - invisibility = 0 mouse_opacity = 0 - new_light_range = 0 - new_light_power = 0 pixel_x = -32 pixel_y = -32 /obj/effect/temporary_effect/cleave_attack/initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself. animate(src, alpha = 0, time = time_to_die - 1) + +/obj/effect/temporary_effect/shuttle_landing + name = "shuttle landing" + desc = "You better move if you don't want to go splat!" + icon_state = "shuttle_warning_still" + time_to_die = 4.9 SECONDS + +/obj/effect/temporary_effect/shuttle_landing/initialize() + flick("shuttle_warning", src) // flick() forces the animation to always begin at the start. + ..() \ No newline at end of file diff --git a/code/modules/blob2/blobs/base_blob.dm b/code/modules/blob2/blobs/base_blob.dm index 01692144cfa..5bd83a0cee6 100644 --- a/code/modules/blob2/blobs/base_blob.dm +++ b/code/modules/blob2/blobs/base_blob.dm @@ -281,15 +281,11 @@ var/list/blobs = list() /obj/effect/temporary_effect/blob_attack name = "blob" desc = "The blob lashing out at something." - icon = 'icons/effects/effects.dmi' icon_state = "blob_attack" layer = 5.2 time_to_die = 6 alpha = 140 - invisibility = 0 mouse_opacity = 0 - new_light_range = 0 - new_light_power = 0 /obj/structure/grille/blob_act() qdel(src) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index d9dea08d99a..18795972d79 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -37,12 +37,20 @@ supply_controller.shuttle = null . = ..() +/datum/shuttle/proc/process() + return + /datum/shuttle/proc/init_docking_controllers() if(docking_controller_tag) docking_controller = locate(docking_controller_tag) if(!istype(docking_controller)) world << "warning: shuttle with docking tag [docking_controller_tag] could not find it's controller!" +// This creates a graphical warning to where the shuttle is about to land, in approximately five seconds. +/datum/shuttle/proc/create_warning_effect(area/landing_area) + for(var/turf/T in landing_area) + new /obj/effect/temporary_effect/shuttle_landing(T) // It'll delete itself when needed. + // Return false to abort a jump, before the 'warmup' phase. /datum/shuttle/proc/pre_warmup_checks() return TRUE @@ -70,6 +78,7 @@ spawn(warmup_time*10) make_sounds(origin, HYPERSPACE_WARMUP) + create_warning_effect(destination) sleep(5 SECONDS) // so the sound finishes. if(!post_warmup_checks()) @@ -102,6 +111,7 @@ spawn(warmup_time*10) make_sounds(departing, HYPERSPACE_WARMUP) + create_warning_effect(interim) // Really doubt someone is gonna get crushed in the interim area but for completeness's sake we'll make the warning. sleep(5 SECONDS) // so the sound finishes. if(!post_warmup_checks()) @@ -122,11 +132,16 @@ move(departing, interim, direction) var/last_progress_sound = 0 + var/made_warning = FALSE while (world.time < arrive_time) // Make the shuttle make sounds every four seconds, since the sound file is five seconds. if(last_progress_sound + 4 SECONDS < world.time) make_sounds(interim, HYPERSPACE_PROGRESS) last_progress_sound = world.time + + if(arrive_time - world.time <= 5 SECONDS && !made_warning) + made_warning = TRUE + create_warning_effect(destination) sleep(5) move(interim, destination, direction) diff --git a/code/modules/shuttles/shuttle_arrivals.dm b/code/modules/shuttles/shuttle_arrivals.dm index 7b8a6026c85..d0f71d54b16 100644 --- a/code/modules/shuttles/shuttle_arrivals.dm +++ b/code/modules/shuttles/shuttle_arrivals.dm @@ -57,9 +57,9 @@ ..() // Do everything else -/datum/shuttle/ferry/arrivals/proc/message_passengers(area/A, var/message) +/datum/shuttle/proc/message_passengers(area/A, var/message) for(var/mob/M in A) - to_chat(M, message) + M.show_message(message, 2) /* /datum/shuttle/ferry/arrivals/current_dock_target() diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm index c122da96f1f..f279ce5d343 100644 --- a/code/modules/shuttles/shuttle_ferry.dm +++ b/code/modules/shuttles/shuttle_ferry.dm @@ -76,7 +76,7 @@ Please ensure that long_jump() and short_jump() are only called from here. This applies to subtypes as well. Doing so will ensure that multiple jumps cannot be initiated in parallel. */ -/datum/shuttle/ferry/proc/process() +/datum/shuttle/ferry/process() switch(process_state) if (WAIT_LAUNCH) if (skip_docking_checks() || docking_controller.can_launch()) diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index 07ff4cbc936..8eee5be9b78 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -1,20 +1,32 @@ //This shuttle traverses a "web" of route_datums to have a wider range of places to go and make flying feel like movement is actually occuring. /datum/shuttle/web_shuttle flags = SHUTTLE_FLAGS_NONE + var/visible_name = null // The pretty name shown to people in announcements, since the regular name var is used internally for other things. var/cloaked = FALSE var/can_cloak = FALSE - var/cooldown = 5 SECONDS + var/cooldown = 0 var/last_move = 0 //the time at which we last moved var/area/current_area = null var/datum/shuttle_web_master/web_master = null var/web_master_type = null var/flight_time_modifier = 1.0 + var/autopilot = FALSE + var/can_autopilot = FALSE + var/autopilot_delay = 60 // How many ticks to not do anything when not following an autopath. Should equal two minutes. + var/autopilot_first_delay = null // If your want your shuttle to stay for a different amount of time for the first time, set this. + var/can_rename = TRUE // Lets the pilot rename the shuttle. Only available once. category = /datum/shuttle/web_shuttle /datum/shuttle/web_shuttle/New() current_area = locate(current_area) web_master = new web_master_type(src) build_destinations() + if(autopilot) + flags |= SHUTTLE_FLAGS_PROCESS + if(autopilot_first_delay) + autopilot_delay = autopilot_first_delay + if(!visible_name) + visible_name = name ..() /datum/shuttle/web_shuttle/Destroy() @@ -39,6 +51,78 @@ /datum/shuttle/web_shuttle/proc/build_destinations() return +/datum/shuttle/web_shuttle/process() + if(moving_status == SHUTTLE_IDLE) + if(web_master.autopath) // We're currently flying a path. + autopilot_say("Continuing route.") + web_master.process_autopath() + + else // Otherwise we are about to start one or just finished one. + if(autopilot_delay > 0) // Wait for awhile so people can get on and off. + if(docking_controller && !skip_docking_checks()) // Dock to the destination if possible. + var/docking_status = docking_controller.get_docking_status() + if(docking_status == "undocked") + dock() + autopilot_say("Docking.") + return + else if(docking_status == "docking") + return // Give it a few more ticks to finish docking. + + if(autopilot_delay % 10 == 0) // Every ten ticks. + var/seconds_left = autopilot_delay * 2 + if(seconds_left >= 60) // A minute + var/minutes_left = Floor(seconds_left / 60) + seconds_left = seconds_left % 60 + autopilot_say("Departing in [minutes_left] minute\s[seconds_left ? ", [seconds_left] seconds":""].") + else + autopilot_say("Departing in [seconds_left] seconds.") + autopilot_delay-- + + else // Time to go. + if(docking_controller && !skip_docking_checks()) // Undock if possible. + var/docking_status = docking_controller.get_docking_status() + if(docking_status == "docked") + undock() + autopilot_say("Undocking.") + return + else if(docking_status == "undocking") + return // Give it a few more ticks to finish undocking. + + autopilot_delay = initial(autopilot_delay) + autopilot_say("Taking off.") + web_master.process_autopath() + +/datum/shuttle/web_shuttle/proc/adjust_autopilot(on) + if(on) + if(autopilot) + return + autopilot = TRUE + autopilot_delay = initial(autopilot_delay) + shuttle_controller.process_shuttles += src + else + if(!autopilot) + return + autopilot = FALSE + shuttle_controller.process_shuttles -= src + +/datum/shuttle/web_shuttle/proc/autopilot_say(message) // Makes the autopilot 'talk' to the passengers. + var/padded_message = "shuttle autopilot states, \"[message]\"" + message_passengers(current_area, padded_message) + +/datum/shuttle/web_shuttle/proc/rename_shuttle(mob/user) + if(!can_rename) + to_chat(user, "You can't rename this vessel.") + return + var/new_name = input(user, "Please enter a new name for this vessel. Note that you can only set its name once, so choose wisely.", "Rename Shuttle", visible_name) as null|text + var/sanitized_name = sanitizeName(new_name, MAX_NAME_LEN, TRUE) + if(sanitized_name) + can_rename = FALSE + to_chat(user, "You've renamed the vessel to '[sanitized_name]'.") + message_admins("[key_name_admin(user)] renamed shuttle '[visible_name]' to '[sanitized_name]'.") + visible_name = sanitized_name + else + to_chat(user, "The name you supplied was invalid. Try another name.") + /obj/machinery/computer/shuttle_control/web name = "flight computer" icon_state = "flightcomp_center" @@ -174,13 +258,16 @@ "travel_progress" = between(0, percent_finished, 100), "time_left" = round( (total_time - elapsed_time) / 10), "can_cloak" = shuttle.can_cloak ? 1 : 0, - "cloaked" = shuttle.cloaked ? 1 : 0 + "cloaked" = shuttle.cloaked ? 1 : 0, + "can_autopilot" = shuttle.can_autopilot ? 1 : 0, + "autopilot" = shuttle.autopilot ? 1 : 0, + "can_rename" = shuttle.can_rename ? 1 : 0 ) ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) - ui = new(user, src, ui_key, "flight.tmpl", "[shuttle_tag] Flight Computer", 470, 500) + ui = new(user, src, ui_key, "flight.tmpl", "[shuttle.visible_name] Flight Computer", 470, 500) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) @@ -202,13 +289,22 @@ ui_interact(usr) if (WS.moving_status != SHUTTLE_IDLE) - usr << "[shuttle_tag] vessel is busy moving." + usr << "[WS.visible_name] is busy moving." return + if(href_list["rename_command"]) + WS.rename_shuttle(usr) + if(href_list["dock_command"]) + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return WS.dock() if(href_list["undock_command"]) + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return WS.undock() if(href_list["cloak_command"]) @@ -223,7 +319,17 @@ WS.cloaked = FALSE to_chat(usr, "Ship stealth systems have been deactivated. The station will be warned of our arrival.") + if(href_list["autopilot_on_command"]) + WS.adjust_autopilot(TRUE) + + if(href_list["autopilot_off_command"]) + WS.adjust_autopilot(FALSE) + if(href_list["traverse"]) + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return + if((WS.last_move + WS.cooldown) > world.time) usr << "The ship's drive is inoperable while the engines are charging." return @@ -245,7 +351,8 @@ return WS.web_master.future_destination = target_destination - to_chat(usr, "[shuttle_tag] flight computer received command.") + to_chat(usr, "[WS.visible_name] flight computer received command.") + WS.web_master.reset_autopath() // Deviating from the path will almost certainly confuse the autopilot, so lets just reset its memory. var/travel_time = new_route.travel_time * WS.flight_time_modifier diff --git a/code/modules/shuttles/web_datums.dm b/code/modules/shuttles/web_datums.dm index 17cd7257254..d30df26863b 100644 --- a/code/modules/shuttles/web_datums.dm +++ b/code/modules/shuttles/web_datums.dm @@ -1,4 +1,8 @@ -// This file actually has three seperate datums. +// This file actually has four seperate datums. + +/********** + * Routes * + **********/ // This is the first datum, and it connects shuttle_destinations together. /datum/shuttle_route @@ -39,6 +43,10 @@ return target.name +/**************** + * Destinations * + ****************/ + // This is the second datum, and contains information on all the potential destinations for a specific shuttle. /datum/shuttle_destination var/name = "a place" // Name of the destination, used for the flight computer. @@ -50,8 +58,8 @@ var/dock_target = null // The tag_id that the shuttle will use to try to dock to the destination, if able. var/announcer = null // The name of the 'announcer' that will say the arrival/departure messages. Defaults to the map's boss name if blank. - var/arrival_message = null // Message said if the ship enters this destination. Not announced if the ship is cloaked. - var/departure_message = null // Message said if the ship exits this destination. Not announced if the ship is cloaked. +// var/arrival_message = null // Message said if the ship enters this destination. Not announced if the ship is cloaked. +// var/departure_message = null // Message said if the ship exits this destination. Not announced if the ship is cloaked. // When this destination is instantiated, it will go and instantiate other destinations in this assoc list and build routes between them. // The list format is '/datum/shuttle_destination/subtype = 1 MINUTES' @@ -101,18 +109,23 @@ /datum/shuttle_destination/proc/exit(var/datum/shuttle_destination/new_destination) announce_departure() +/datum/shuttle_destination/proc/get_departure_message() + return null /datum/shuttle_destination/proc/announce_departure() - if(isnull(departure_message) || master.my_shuttle.cloaked) + if(isnull(get_departure_message()) || master.my_shuttle.cloaked) return - command_announcement.Announce(departure_message,(announcer ? announcer : "[using_map.boss_name]")) + command_announcement.Announce(get_departure_message(),(announcer ? announcer : "[using_map.boss_name]")) + +/datum/shuttle_destination/proc/get_arrival_message() + return null /datum/shuttle_destination/proc/announce_arrival() - if(isnull(arrival_message) || master.my_shuttle.cloaked) + if(isnull(get_arrival_message()) || master.my_shuttle.cloaked) return - command_announcement.Announce(arrival_message,(announcer ? announcer : "[using_map.boss_name]")) + command_announcement.Announce(get_arrival_message(),(announcer ? announcer : "[using_map.boss_name]")) /datum/shuttle_destination/proc/link_destinations(var/datum/shuttle_destination/other_place, var/area/interim_area, var/travel_time = 0) // First, check to make sure this doesn't cause a duplicate route. @@ -131,6 +144,17 @@ /datum/shuttle_destination/proc/flight_failure() return +// Returns a /datum/shuttle_route connecting this destination to origin, if one exists. +/datum/shuttle_destination/proc/get_route_to(origin_type) + for(var/datum/shuttle_route/R in routes) + if(R.start.type == origin_type || R.end.type == origin_type) + return R + return null + +/*************** + * Web Masters * + ***************/ + // This is the third and final datum, which coordinates with the shuttle datum to tell it where it is, where it can go, and how long it will take. // It is also responsible for instancing all the destinations it has control over, and linking them together. /datum/shuttle_web_master @@ -141,12 +165,17 @@ var/list/destinations = list() // List of currently instanced destinations. var/destination_class = null // Type to use in typesof(), to build destinations. + var/datum/shuttle_autopath/autopath = null // Datum used to direct an autopilot. + var/list/autopaths = list() // Potential autopaths the autopilot can use. The autopath's start var must equal current_destination to be viable. + var/autopath_class = null // Similar to destination_class, used for typesof(). + /datum/shuttle_web_master/New(var/new_shuttle, var/new_destination_class = null) my_shuttle = new_shuttle if(new_destination_class) destination_class = new_destination_class build_destinations() current_destination = get_destination_by_type(starting_destination) + build_autopaths() /datum/shuttle_web_master/Destroy() my_shuttle = null @@ -189,4 +218,84 @@ return current_destination /datum/shuttle_web_master/proc/get_destination_by_type(var/type_to_get) - return locate(type_to_get) in destinations \ No newline at end of file + return locate(type_to_get) in destinations + +// Autopilot stuff. +/datum/shuttle_web_master/proc/build_autopaths() + init_subtypes(autopath_class, autopaths) + for(var/datum/shuttle_autopath/P in autopaths) + P.master = src + +/datum/shuttle_web_master/proc/choose_path() + if(!autopaths.len) + return + for(var/datum/shuttle_autopath/path in autopaths) + if(path.start == current_destination.type) + autopath = path + break + +/datum/shuttle_web_master/proc/path_finished(datum/shuttle_autopath/path) + autopath = null + +/datum/shuttle_web_master/proc/walk_path(target_type) + var/datum/shuttle_route/R = current_destination.get_route_to(target_type) + if(!R) + return FALSE + future_destination = R.get_other_side(current_destination) + + var/travel_time = R.travel_time * my_shuttle.flight_time_modifier * 2 // Autopilot is less efficent than having someone flying manually. + if(R.interim && R.travel_time > 0) + my_shuttle.long_jump(my_shuttle.current_area, future_destination.my_area, R.interim, travel_time / 10) + else + my_shuttle.short_jump(my_shuttle.current_area, future_destination.my_area) + return TRUE // Note this will return before the shuttle actually arrives. + +/datum/shuttle_web_master/proc/process_autopath() + if(!autopath) // If we don't have a path, get one. + if(!autopaths.len) + return + choose_path() + + if(!autopath) // Still nothing, oh well. + return + + var/datum/shuttle_destination/target = autopath.get_next_node() + if(walk_path(target)) + autopath.walk_path() + +// Call this to reset everything related to autopiloting. +/datum/shuttle_web_master/proc/reset_autopath() + autopath = null + my_shuttle.autopilot = FALSE + + +/************* + * Autopaths * + *************/ + + +// Fourth datum, this one essentially acts as directions for an autopilot to go to the correct places. +/datum/shuttle_autopath + var/datum/shuttle_web_master/master = null + var/datum/shuttle_destination/start = null + var/list/path_nodes = list() + var/index = 1 + +/datum/shuttle_autopath/Destroy() + master = null + return ..() + +/datum/shuttle_autopath/proc/reset_path() + index = 1 + +/datum/shuttle_autopath/proc/get_next_node() + return path_nodes[index] + +/datum/shuttle_autopath/proc/walk_path() + index++ + if(index > path_nodes.len) + finish_path() + +/datum/shuttle_autopath/proc/finish_path() + reset_path() + master.path_finished(src) diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index b96d107773a..948a55d9f1e 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/maps/southern_cross/shuttles/crew_shuttles.dm b/maps/southern_cross/shuttles/crew_shuttles.dm index 698ed717a95..7b8970d16d1 100644 --- a/maps/southern_cross/shuttles/crew_shuttles.dm +++ b/maps/southern_cross/shuttles/crew_shuttles.dm @@ -10,11 +10,36 @@ current_area = /area/shuttle/shuttle1/start docking_controller_tag = "shuttle1_shuttle" web_master_type = /datum/shuttle_web_master/shuttle1 + autopilot = TRUE + can_autopilot = TRUE + autopilot_delay = 60 + autopilot_first_delay = 300 // Ten minutes at roundstart. Two minutes otherwise. /datum/shuttle_web_master/shuttle1 destination_class = /datum/shuttle_destination/shuttle1 + autopath_class = /datum/shuttle_autopath/shuttle1 starting_destination = /datum/shuttle_destination/shuttle1/root +/datum/shuttle_autopath/shuttle1/to_outpost + start = /datum/shuttle_destination/shuttle1/root + + path_nodes = list( + /datum/shuttle_destination/shuttle1/outside_SC, + /datum/shuttle_destination/shuttle1/sif_orbit, + /datum/shuttle_destination/shuttle1/sky, + /datum/shuttle_destination/shuttle1/main_base + ) + +/datum/shuttle_autopath/shuttle1/to_home + start = /datum/shuttle_destination/shuttle1/main_base + + path_nodes = list( + /datum/shuttle_destination/shuttle1/sky, + /datum/shuttle_destination/shuttle1/sif_orbit, + /datum/shuttle_destination/shuttle1/outside_SC, + /datum/shuttle_destination/shuttle1/root + ) + //Shuttle 2 /obj/machinery/computer/shuttle_control/web/shuttle2 @@ -27,11 +52,38 @@ current_area = /area/shuttle/shuttle2/start docking_controller_tag = "shuttle2_shuttle" web_master_type = /datum/shuttle_web_master/shuttle2 + autopilot = TRUE + can_autopilot = TRUE + autopilot_delay = 60 + autopilot_first_delay = 380 // Twelve and a half minutes at roundstart. Two minutes otherwise. This should leave when the first shuttle arrives at the outpost. /datum/shuttle_web_master/shuttle2 destination_class = /datum/shuttle_destination/shuttle2 + autopath_class = /datum/shuttle_autopath/shuttle2 starting_destination = /datum/shuttle_destination/shuttle2/root +/datum/shuttle_autopath/shuttle2/to_outpost + start = /datum/shuttle_destination/shuttle2/root + + path_nodes = list( + /datum/shuttle_destination/shuttle2/outside_SC, + /datum/shuttle_destination/shuttle2/sif_orbit, + /datum/shuttle_destination/shuttle2/sky, + /datum/shuttle_destination/shuttle2/main_base + ) + +/datum/shuttle_autopath/shuttle2/to_home + start = /datum/shuttle_destination/shuttle2/main_base + + path_nodes = list( + /datum/shuttle_destination/shuttle2/sky, + /datum/shuttle_destination/shuttle2/sif_orbit, + /datum/shuttle_destination/shuttle2/outside_SC, + /datum/shuttle_destination/shuttle2/root + ) + + + /datum/shuttle_destination/shuttle1/root name = "Southern Cross Hangar One" my_area = /area/shuttle/shuttle1/start @@ -39,13 +91,17 @@ dock_target = "hangar_1" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, shuttle one has arrived to Hangar One." - departure_message = "Attention, shuttle one has departed Hangar One." routes_to_make = list( /datum/shuttle_destination/shuttle1/outside_SC = 0, ) +/datum/shuttle_destination/shuttle1/root/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to Hangar One." + +/datum/shuttle_destination/shuttle1/root/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed Hangar One." + /datum/shuttle_destination/shuttle2/root name = "Southern Cross Hangar Two" my_area = /area/shuttle/shuttle2/start @@ -53,13 +109,17 @@ dock_target = "hangar_2" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, shuttle two has arrived to Hangar Two." - departure_message = "Attention, shuttle two has departed Hangar Two." routes_to_make = list( /datum/shuttle_destination/shuttle2/outside_SC = 0, ) +/datum/shuttle_destination/shuttle2/root/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to Hangar Two." + +/datum/shuttle_destination/shuttle2/root/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed Hangar Two." + /datum/shuttle_destination/shuttle1/outside_SC name = "Outside of NLS Southern Cross" @@ -67,7 +127,7 @@ preferred_interim_area = /area/shuttle/shuttle1/transit routes_to_make = list( - /datum/shuttle_destination/shuttle1/sif_orbit = 1 MINUTE, + /datum/shuttle_destination/shuttle1/sif_orbit = 30 SECONDS, /datum/shuttle_destination/shuttle1/docked_SC = 0 ) @@ -77,7 +137,7 @@ preferred_interim_area = /area/shuttle/shuttle2/transit routes_to_make = list( - /datum/shuttle_destination/shuttle2/sif_orbit = 1 MINUTE, + /datum/shuttle_destination/shuttle2/sif_orbit = 30 SECONDS, /datum/shuttle_destination/shuttle2/docked_SC = 0 ) @@ -89,8 +149,13 @@ dock_target = "shuttle1_dock_airlocksc" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, shuttle one has arrived to the Arrivals Dock." - departure_message = "Attention, shuttle one has departed the Arrivals Dock." + +/datum/shuttle_destination/shuttle1/docked_SC/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Arrivals Dock." + +/datum/shuttle_destination/shuttle1/docked_SC/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Arrivals Dock." + /datum/shuttle_destination/shuttle2/docked_SC name = "Southern Cross Docking Port" @@ -99,8 +164,12 @@ dock_target = "shuttle2_dock_airlocksc" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, shuttle two has arrived to the Arrivals Dock." - departure_message = "Attention, shuttle two has departed the Arrivals Dock." + +/datum/shuttle_destination/shuttle2/docked_SC/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Arrivals Dock." + +/datum/shuttle_destination/shuttle2/docked_SC/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Arrivals Dock." /datum/shuttle_destination/shuttle1/sif_orbit @@ -109,7 +178,7 @@ preferred_interim_area = /area/shuttle/shuttle1/transit routes_to_make = list( - /datum/shuttle_destination/shuttle1/sky = 1 MINUTE + /datum/shuttle_destination/shuttle1/sky = 30 SECONDS ) /datum/shuttle_destination/shuttle2/sif_orbit @@ -118,7 +187,7 @@ preferred_interim_area = /area/shuttle/shuttle2/transit routes_to_make = list( - /datum/shuttle_destination/shuttle2/sky = 1 MINUTE + /datum/shuttle_destination/shuttle2/sky = 30 SECONDS ) @@ -128,8 +197,8 @@ preferred_interim_area = /area/shuttle/shuttle1/sky_transit routes_to_make = list( - /datum/shuttle_destination/shuttle1/main_base = 30 SECONDS, - /datum/shuttle_destination/shuttle1/mining_base = 30 SECONDS + /datum/shuttle_destination/shuttle1/main_base = 15 SECONDS, + /datum/shuttle_destination/shuttle1/mining_base = 15 SECONDS ) /datum/shuttle_destination/shuttle2/sky @@ -138,8 +207,8 @@ preferred_interim_area = /area/shuttle/shuttle2/sky_transit routes_to_make = list( - /datum/shuttle_destination/shuttle2/main_base = 30 SECONDS, - /datum/shuttle_destination/shuttle2/mining_base = 30 SECONDS + /datum/shuttle_destination/shuttle2/main_base = 15 SECONDS, + /datum/shuttle_destination/shuttle2/mining_base = 15 SECONDS ) @@ -150,8 +219,12 @@ dock_target = "surface_dock_1" announcer = "Outpost Automated ATC" - arrival_message = "Attention, shuttle one has arrived to the Main Outpost." - departure_message = "Attention, shuttle one has departed the Main Outpost." + +/datum/shuttle_destination/shuttle1/main_base/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Main Outpost." + +/datum/shuttle_destination/shuttle1/main_base/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Main Outpost." /datum/shuttle_destination/shuttle2/main_base name = "Main Outpost" @@ -160,8 +233,12 @@ dock_target = "surface_dock_2" announcer = "Outpost Automated ATC" - arrival_message = "Attention, shuttle two has arrived to the Main Outpost." - departure_message = "Attention, shuttle two has departed the Main Outpost." + +/datum/shuttle_destination/shuttle2/main_base/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Main Outpost." + +/datum/shuttle_destination/shuttle2/main_base/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Main Outpost." /datum/shuttle_destination/shuttle1/mining_base @@ -171,8 +248,11 @@ dock_target = "mining_dock_1" announcer = "Outpost Automated ATC" - arrival_message = "Attention, shuttle one has arrived to the Mining Outpost." - departure_message = "Attention, shuttle one has departed the Mining Outpost." +/datum/shuttle_destination/shuttle1/mining_base/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Mining Outpost." + +/datum/shuttle_destination/shuttle1/mining_base/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Mining Outpost." /datum/shuttle_destination/shuttle2/mining_base name = "Mining Outpost" @@ -181,5 +261,9 @@ dock_target = "mining_dock_2" announcer = "Outpost Automated ATC" - arrival_message = "Attention, shuttle two has arrived to the Mining Outpost." - departure_message = "Attention, shuttle two has departed the Mining Outpost." \ No newline at end of file + +/datum/shuttle_destination/shuttle2/mining_base/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Mining Outpost." + +/datum/shuttle_destination/shuttle2/mining_base/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Mining Outpost." \ No newline at end of file diff --git a/maps/southern_cross/shuttles/ert.dm b/maps/southern_cross/shuttles/ert.dm index 5c9aa8c0ba0..4ab0314aff6 100644 --- a/maps/southern_cross/shuttles/ert.dm +++ b/maps/southern_cross/shuttles/ert.dm @@ -50,7 +50,7 @@ dock_target = "response_base" routes_to_make = list( - /datum/shuttle_destination/ert/orbit = 2 MINUTES, + /datum/shuttle_destination/ert/orbit = 1 MINUTE, ) /datum/shuttle_destination/ert/orbit @@ -59,10 +59,10 @@ preferred_interim_area = /area/shuttle/response_ship/transit routes_to_make = list( - /datum/shuttle_destination/ert/outside_SC_1d = 1 MINUTE, - /datum/shuttle_destination/ert/outside_SC_2d = 1 MINUTE, - /datum/shuttle_destination/ert/outside_SC_3d = 1 MINUTE, - /datum/shuttle_destination/ert/sky = 1 MINUTE + /datum/shuttle_destination/ert/outside_SC_1d = 30 SECONDS, + /datum/shuttle_destination/ert/outside_SC_2d = 30 SECONDS, + /datum/shuttle_destination/ert/outside_SC_3d = 30 SECONDS, + /datum/shuttle_destination/ert/sky = 30 SECONDS ) /datum/shuttle_destination/ert/outside_SC_1d @@ -106,8 +106,12 @@ dock_target = "response_shuttle_dock_airlock" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, the Emergency Response Team's shuttle has arrived to the Arrivals Dock." - departure_message = "Attention, the Emergency Response Team's shuttle has departed the Arrivals Dock." + +/datum/shuttle_destination/ert/docked_SC/get_arrival_message() + return "Attention, the Emergency Response Team's shuttle has arrived to the Arrivals Dock." + +/datum/shuttle_destination/ert/docked_SC/get_departure_message() + return "Attention, the Emergency Response Team's shuttle has departed the Arrivals Dock." /datum/shuttle_destination/ert/sky name = "Skies of Sif" @@ -115,7 +119,7 @@ preferred_interim_area = /area/shuttle/response_ship/sky_transit routes_to_make = list( - /datum/shuttle_destination/ert/planet = 30 SECONDS + /datum/shuttle_destination/ert/planet = 15 SECONDS ) /datum/shuttle_destination/ert/planet diff --git a/maps/southern_cross/shuttles/heist.dm b/maps/southern_cross/shuttles/heist.dm index c44712ee0a1..6cc0e357ad6 100644 --- a/maps/southern_cross/shuttles/heist.dm +++ b/maps/southern_cross/shuttles/heist.dm @@ -35,10 +35,10 @@ preferred_interim_area = /area/skipjack_station/transit routes_to_make = list( - /datum/shuttle_destination/heist/outside_SC_1d = 1 MINUTE, - /datum/shuttle_destination/heist/outside_SC_2d = 1 MINUTE, - /datum/shuttle_destination/heist/outside_SC_3d = 1 MINUTE, - /datum/shuttle_destination/heist/sky = 1 MINUTE, + /datum/shuttle_destination/heist/outside_SC_1d = 30 SECONDS, + /datum/shuttle_destination/heist/outside_SC_2d = 30 SECONDS, + /datum/shuttle_destination/heist/outside_SC_3d = 30 SECONDS, + /datum/shuttle_destination/heist/sky = 30 SECONDS, ) /datum/shuttle_destination/heist/outside_SC_1d @@ -82,8 +82,12 @@ // dock_target = "skipjack_shuttle_dock_airlock" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, a shuttle has arrived to the Arrivals Dock." - departure_message = "Attention, a shuttle has departed the Arrivals Dock." + +/datum/shuttle_destination/heist/docked_SC/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Arrivals Dock." + +/datum/shuttle_destination/heist/docked_SC/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Arrivals Dock." /datum/shuttle_destination/heist/sky name = "Skies of Sif" @@ -91,7 +95,7 @@ preferred_interim_area = /area/skipjack_station/sky_transit routes_to_make = list( - /datum/shuttle_destination/heist/planet = 30 SECONDS + /datum/shuttle_destination/heist/planet = 15 SECONDS ) /datum/shuttle_destination/heist/planet diff --git a/maps/southern_cross/shuttles/merc.dm b/maps/southern_cross/shuttles/merc.dm index 93321f8dac0..e47707876ed 100644 --- a/maps/southern_cross/shuttles/merc.dm +++ b/maps/southern_cross/shuttles/merc.dm @@ -34,12 +34,14 @@ /datum/shuttle/web_shuttle/syndicate name = "Mercenary" + visible_name = "Unknown Vessel" warmup_time = 0 can_cloak = TRUE cloaked = TRUE current_area = /area/syndicate_station/start docking_controller_tag = "merc_shuttle" web_master_type = /datum/shuttle_web_master/syndie + flight_time_modifier = 2 // Assumption that 'larger ship + few engines = slower' /datum/shuttle_web_master/syndie destination_class = /datum/shuttle_destination/syndie @@ -55,7 +57,7 @@ dock_target = "merc_base" routes_to_make = list( - /datum/shuttle_destination/syndie/orbit = 3 MINUTES, + /datum/shuttle_destination/syndie/orbit = 1.5 MINUTES, ) /datum/shuttle_destination/syndie/orbit @@ -64,10 +66,10 @@ preferred_interim_area = /area/syndicate_station/transit routes_to_make = list( - /datum/shuttle_destination/syndie/outside_SC_1d = 1 MINUTE, - /datum/shuttle_destination/syndie/outside_SC_2d = 1 MINUTE, - /datum/shuttle_destination/syndie/outside_SC_3d = 1 MINUTE, - /datum/shuttle_destination/syndie/sky = 1 MINUTE + /datum/shuttle_destination/syndie/outside_SC_1d = 30 SECONDS, + /datum/shuttle_destination/syndie/outside_SC_2d = 30 SECONDS, + /datum/shuttle_destination/syndie/outside_SC_3d = 30 SECONDS, + /datum/shuttle_destination/syndie/sky = 30 SECONDS ) /datum/shuttle_destination/syndie/outside_SC_1d @@ -110,8 +112,12 @@ dock_target = "nuke_shuttle_dock_airlock" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, a shuttle has arrived to the Arrivals Dock." - departure_message = "Attention, a shuttle has departed the Arrivals Dock." + +/datum/shuttle_destination/syndie/docked_SC/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Arrivals Dock." + +/datum/shuttle_destination/syndie/docked_SC/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Arrivals Dock." /datum/shuttle_destination/syndie/sky name = "Skies of Sif" @@ -119,7 +125,7 @@ preferred_interim_area = /area/syndicate_station/sky_transit routes_to_make = list( - /datum/shuttle_destination/syndie/planet = 30 SECONDS + /datum/shuttle_destination/syndie/planet = 15 SECONDS ) /datum/shuttle_destination/syndie/planet diff --git a/maps/southern_cross/shuttles/ninja.dm b/maps/southern_cross/shuttles/ninja.dm index c7fa6c68c8a..bda6c60c526 100644 --- a/maps/southern_cross/shuttles/ninja.dm +++ b/maps/southern_cross/shuttles/ninja.dm @@ -5,12 +5,14 @@ /datum/shuttle/web_shuttle/ninja name = "Ninja" + visible_name = "Unknown Vessel" warmup_time = 0 can_cloak = TRUE cloaked = TRUE current_area = /area/ninja_dojo/start docking_controller_tag = "ninja_shuttle" web_master_type = /datum/shuttle_web_master/ninja + flight_time_modifier = 0.5 // Nippon steel. /datum/shuttle_web_master/ninja destination_class = /datum/shuttle_destination/ninja @@ -24,7 +26,7 @@ dock_target = "ninja_base" routes_to_make = list( - /datum/shuttle_destination/ninja/sky = 30 SECONDS, + /datum/shuttle_destination/ninja/sky = 15 SECONDS, ) /datum/shuttle_destination/ninja/orbit @@ -33,10 +35,10 @@ preferred_interim_area = /area/ninja_dojo/transit routes_to_make = list( - /datum/shuttle_destination/ninja/outside_SC_1d = 1 MINUTE, - /datum/shuttle_destination/ninja/outside_SC_2d = 1 MINUTE, - /datum/shuttle_destination/ninja/outside_SC_3d = 1 MINUTE, - /datum/shuttle_destination/ninja/sky = 1 MINUTE, + /datum/shuttle_destination/ninja/outside_SC_1d = 30 SECONDS, + /datum/shuttle_destination/ninja/outside_SC_2d = 30 SECONDS, + /datum/shuttle_destination/ninja/outside_SC_3d = 30 SECONDS, + /datum/shuttle_destination/ninja/sky = 30 SECONDS, ) /datum/shuttle_destination/ninja/outside_SC_1d @@ -80,8 +82,12 @@ dock_target = "ninja_shuttle_dock_airlock" announcer = "Southern Cross Docking Computer" - arrival_message = "Attention, a shuttle has arrived to the Arrivals Dock." - departure_message = "Attention, a shuttle has departed the Arrivals Dock." + +/datum/shuttle_destination/syndie/docked_SC/get_arrival_message() + return "Attention, [master.my_shuttle.visible_name] has arrived to the Arrivals Dock." + +/datum/shuttle_destination/syndie/docked_SC/get_departure_message() + return "Attention, [master.my_shuttle.visible_name] has departed the Arrivals Dock." /datum/shuttle_destination/ninja/sky name = "Skies of Sif" @@ -89,7 +95,7 @@ preferred_interim_area = /area/ninja_dojo/sky_transit routes_to_make = list( - /datum/shuttle_destination/ninja/planet = 30 SECONDS + /datum/shuttle_destination/ninja/planet = 15 SECONDS ) /datum/shuttle_destination/ninja/planet diff --git a/nano/templates/flight.tmpl b/nano/templates/flight.tmpl index b3c27dc9cdb..2ffec337bad 100644 --- a/nano/templates/flight.tmpl +++ b/nano/templates/flight.tmpl @@ -1,3 +1,22 @@ +{{if data.autopilot == 1}} +
+

AI PILOT (CLASS D) ACTIVE

+ This vessel will start and stop automatically.
+ Ensure that all non-cycling capable hatches and doors are closed, as the automated system may not be able to control them.
+ Docking and flight controls are locked. To unlock, disable the automated flight system.

+
+{{/if}} + +{{if data.can_rename == 1}} +
+
+
+ {{:helper.link('Rename', 'pencil', {"rename_command" : 1})}} +
+
+
+{{/if}} +

Shuttle Status

{{if data.is_moving == 0}}
@@ -81,6 +100,18 @@
{{/if}} + {{if data.can_autopilot == 1}} +
+
+ Automated Flight Control: +
+ + {{:helper.link('On', 'circle-check', {'autopilot_on_command' : 1}, (data.autopilot == 1)? 'selected' : null)}} + {{:helper.link('Off', 'circle-close ', {'autopilot_off_command' : 1}, (data.autopilot == 0)? 'selected' : null)}} +
+ + {{/if}} + {{/if}} {{if data.is_moving == 0}}