From c2fa5dcc48df2dff44263f94246c2c8f8ff79b81 Mon Sep 17 00:00:00 2001 From: nmajask Date: Mon, 26 Jul 2021 19:31:32 -0400 Subject: [PATCH 01/16] Ports "Ship construction through the power of science!" - Ports https://github.com/BeeStation/BeeStation-Hornet/pull/1398 --- .../configuration/entries/game_options.dm | 7 + code/game/area/areas/shuttles.dm | 4 + code/game/machinery/shuttle/custom_shuttle.dm | 33 ++ code/game/machinery/shuttle/shuttle_engine.dm | 138 ++++++++ code/game/machinery/shuttle/shuttle_heater.dm | 134 ++++++++ .../circuitboards/computer_circuitboards.dm | 8 + .../circuitboards/machine_circuitboards.dm | 25 ++ code/game/objects/items/shuttle_creator.dm | 301 ++++++++++++++++++ code/game/objects/items/shuttle_upgrades.dm | 39 +++ code/modules/mob/dead/observer/observer.dm | 1 + code/modules/mob/mob_defines.dm | 2 + .../research/designs/comp_board_designs.dm | 16 + .../research/designs/machine_designs.dm | 24 ++ code/modules/research/designs/misc_designs.dm | 30 ++ code/modules/research/designs/tool_designs.dm | 10 + .../research/machinery/circuit_imprinter.dm | 3 +- code/modules/research/techweb/all_nodes.dm | 37 +++ code/modules/shuttle/custom_shuttle.dm | 263 +++++++++++++++ code/modules/shuttle/navigation_computer.dm | 11 +- code/modules/shuttle/shuttle.dm | 4 + config/config.txt | 4 + yogstation.dme | 6 + 22 files changed, 1097 insertions(+), 3 deletions(-) create mode 100644 code/game/machinery/shuttle/custom_shuttle.dm create mode 100644 code/game/machinery/shuttle/shuttle_engine.dm create mode 100644 code/game/machinery/shuttle/shuttle_heater.dm create mode 100644 code/game/objects/items/shuttle_creator.dm create mode 100644 code/game/objects/items/shuttle_upgrades.dm create mode 100644 code/modules/shuttle/custom_shuttle.dm diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 0b522ee75d45..2c6d3aff2746 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -399,3 +399,10 @@ /datum/config_entry/number/engine_type config_entry_value = 3 + +//Shuttle size limiter +/datum/config_entry/number/max_shuttle_count + config_entry_value = 6 + +/datum/config_entry/number/max_shuttle_size + config_entry_value = 250 diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index 15b626434753..8ff9140009a3 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -106,6 +106,10 @@ /area/shuttle/custom name = "Custom player shuttle" +/area/shuttle/custom/powered + name = "Custom Powered player shuttle" + requires_power = FALSE + /area/shuttle/arrival name = "Arrival Shuttle" unique = TRUE // SSjob refers to this area for latejoiners diff --git a/code/game/machinery/shuttle/custom_shuttle.dm b/code/game/machinery/shuttle/custom_shuttle.dm new file mode 100644 index 000000000000..7c83cade69f3 --- /dev/null +++ b/code/game/machinery/shuttle/custom_shuttle.dm @@ -0,0 +1,33 @@ +/obj/machinery/shuttle + name = "shuttle component" + desc = "Something for shuttles." + density = TRUE + obj_integrity = 250 + max_integrity = 250 + icon = 'icons/turf/shuttle.dmi' + icon_state = "burst_plasma" + idle_power_usage = 150 + circuit = /obj/item/circuitboard/machine/shuttle/engine + var/icon_state_closed = "burst_plasma" + var/icon_state_open = "burst_plasma_open" + var/icon_state_off = "burst_plasma_off" + +/obj/machinery/shuttle/Initialize() + . = ..() + GLOB.custom_shuttle_machines += src + +/obj/machinery/shuttle/Destroy() + . = ..() + GLOB.custom_shuttle_machines -= src + +/obj/machinery/shuttle/attackby(obj/item/I, mob/living/user, params) + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm new file mode 100644 index 000000000000..e3cdec77b6e2 --- /dev/null +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -0,0 +1,138 @@ +//----------------------------------------------- +//-------------Engine Thrusters------------------ +//----------------------------------------------- + +#define ENGINE_HEAT_TARGET 600 +#define ENGINE_HEATING_POWER 5000000 + +/obj/machinery/shuttle/engine + name = "shuttle thruster" + desc = "A thruster for shuttles." + density = TRUE + obj_integrity = 250 + max_integrity = 250 + icon = 'icons/turf/shuttle.dmi' + icon_state = "burst_plasma" + idle_power_usage = 150 + circuit = /obj/item/circuitboard/machine/shuttle/engine + var/thrust = 0 + var/fuel_use = 0 + var/bluespace_capable = TRUE + var/cooldown = 0 + var/thruster_active = FALSE + var/datum/weakref/attached_heater + +/obj/machinery/shuttle/engine/plasma + name = "plasma thruster" + desc = "A thruster that burns plasma stored in an adjacent plasma thruster heater." + icon_state = "burst_plasma" + icon_state_off = "burst_plasma_off" + + idle_power_usage = 0 + circuit = /obj/item/circuitboard/machine/shuttle/engine/plasma + thrust = 25 + fuel_use = 0.24 + bluespace_capable = FALSE + cooldown = 45 + +/obj/machinery/shuttle/engine/void + name = "void thruster" + desc = "A thruster using technology to breach voidspace for propulsion." + icon_state = "burst_void" + icon_state_off = "burst_void" + icon_state_closed = "burst_void" + icon_state_open = "burst_void_open" + idle_power_usage = 0 + circuit = /obj/item/circuitboard/machine/shuttle/engine/void + thrust = 400 + fuel_use = 0 + bluespace_capable = TRUE + cooldown = 90 + +/obj/machinery/shuttle/engine/Initialize() + . = ..() + check_setup() + +/obj/machinery/shuttle/engine/on_construction() + . = ..() + check_setup() + +/obj/machinery/shuttle/engine/proc/check_setup() + var/heater_turf + switch(dir) + if(NORTH) + heater_turf = get_offset_target_turf(src, 0, 1) + if(SOUTH) + heater_turf = get_offset_target_turf(src, 0, -1) + if(EAST) + heater_turf = get_offset_target_turf(src, 1, 0) + if(WEST) + heater_turf = get_offset_target_turf(src, -1, 0) + if(!heater_turf) + attached_heater = null + update_engine() + return + attached_heater = null + for(var/obj/machinery/atmospherics/components/unary/shuttle/heater/as_heater in heater_turf) + if(as_heater.dir != dir) + continue + if(as_heater.panel_open) + continue + if(!as_heater.anchored) + continue + attached_heater = WEAKREF(as_heater) + break + update_engine() + return + +/obj/machinery/shuttle/engine/proc/update_engine() + if(!attached_heater) + icon_state = icon_state_off + thruster_active = FALSE + return + var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolved_heater = attached_heater.resolve() + if(panel_open) + thruster_active = FALSE + else if(resolved_heater?.hasFuel(1)) + icon_state = icon_state_closed + thruster_active = TRUE + else + thruster_active = FALSE + icon_state = icon_state_off + return + +/obj/machinery/shuttle/engine/void/update_engine() + if(panel_open) + thruster_active = FALSE + return + thruster_active = TRUE + icon_state = icon_state_closed + return + +//Thanks to spaceheater.dm for inspiration :) +/obj/machinery/shuttle/engine/proc/fireEngine() + var/turf/heatTurf = loc + if(!heatTurf) + return + var/datum/gas_mixture/env = heatTurf.return_air() + var/heat_cap = env.heat_capacity() + var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap + req_power = min(req_power, ENGINE_HEATING_POWER) + var/deltaTemperature = req_power / heat_cap + if(deltaTemperature < 0) + return + env.set_temperature(env.return_temperature() + deltaTemperature) + air_update_turf() + +/obj/machinery/shuttle/engine/attackby(obj/item/I, mob/living/user, params) + check_setup() + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm new file mode 100644 index 000000000000..80c46fde7374 --- /dev/null +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -0,0 +1,134 @@ +//----------------------------------------------- +//--------------Engine Heaters------------------- +//This uses atmospherics, much like a thermomachine, +//but instead of changing temp, it stores plasma and uses +//it for the engine. +//----------------------------------------------- +/obj/machinery/atmospherics/components/unary/shuttle + name = "shuttle atmospherics device" + desc = "This does something to do with shuttle atmospherics" + icon_state = "heater" + icon = 'icons/turf/shuttle.dmi' + +/obj/machinery/atmospherics/components/unary/shuttle/heater + name = "engine heater" + desc = "Directs energy into compressed particles in order to power an attached thruster." + icon_state = "heater_pipe" + var/icon_state_closed = "heater_pipe" + var/icon_state_open = "heater_pipe_open" + var/icon_state_off = "heater_pipe" + idle_power_usage = 50 + circuit = /obj/item/circuitboard/machine/shuttle/heater + + density = TRUE + max_integrity = 400 + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30) + layer = OBJ_LAYER + showpipe = TRUE + + pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + + var/gas_type = /datum/gas/plasma + var/efficiency_multiplier = 1 + var/gas_capacity = 0 + +/obj/machinery/atmospherics/components/unary/shuttle/heater/New() + . = ..() + GLOB.custom_shuttle_machines += src + SetInitDirections() + update_adjacent_engines() + updateGasStats() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/Destroy() + . = ..() + update_adjacent_engines() + GLOB.custom_shuttle_machines -= src + +/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction() + ..(dir, dir) + SetInitDirections() + update_adjacent_engines() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/default_change_direction_wrench(mob/user, obj/item/I) + if(!..()) + return FALSE + SetInitDirections() + var/obj/machinery/atmospherics/node = nodes[1] + if(node) + node.disconnect(src) + nodes[1] = null + if(!parents[1]) + return + nullifyPipenet(parents[1]) + + atmosinit() + node = nodes[1] + if(node) + node.atmosinit() + node.addMember(src) + build_network() + return TRUE + +/obj/machinery/atmospherics/components/unary/shuttle/heater/RefreshParts() + var/cap = 0 + var/eff = 0 + for(var/obj/item/stock_parts/matter_bin/M in component_parts) + cap += M.rating + for(var/obj/item/stock_parts/micro_laser/L in component_parts) + eff += L.rating + gas_capacity = 5000 * ((cap - 1) ** 2) + 1000 + efficiency_multiplier = round(((eff / 2) / 2.8) ** 2, 0.1) + updateGasStats() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/examine(mob/user) + . = ..() + var/datum/gas_mixture/air_contents = airs[1] + . += "The engine heater's gas dial reads [air_contents.get_moles(gas_type)] moles of gas.
" //This probably has issues [air_contents.get_moles] + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/updateGasStats() + var/datum/gas_mixture/air_contents = airs[1] + if(!air_contents) + return + air_contents.set_volume(gas_capacity) + air_contents.set_temperature(T20C) + if(gas_type) + air_contents.set_moles(gas_type) + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required) + var/datum/gas_mixture/air_contents = airs[1] + var/moles = air_contents.total_moles() + return moles >= required + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/consumeFuel(var/amount) + var/datum/gas_mixture/air_contents = airs[1] + air_contents.remove(amount) + return + +/obj/machinery/atmospherics/components/unary/shuttle/heater/attackby(obj/item/I, mob/living/user, params) + update_adjacent_engines() + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/update_adjacent_engines() + var/engine_turf + switch(dir) + if(NORTH) + engine_turf = get_offset_target_turf(src, 0, -1) + if(SOUTH) + engine_turf = get_offset_target_turf(src, 0, 1) + if(EAST) + engine_turf = get_offset_target_turf(src, -1, 0) + if(WEST) + engine_turf = get_offset_target_turf(src, 1, 0) + if(!engine_turf) + return + for(var/obj/machinery/shuttle/engine/E in engine_turf) + E.check_setup() diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index a830d0b7c042..d1718ac9fa1d 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -377,6 +377,14 @@ name = "circuit board (Xenobiology Console)" icon_state = "science" build_path = /obj/machinery/computer/camera_advanced/xenobio + +/obj/item/circuitboard/computer/shuttle/flight_control + name = "Shuttle Flight Control (Computer Board)" + build_path = /obj/machinery/computer/custom_shuttle + +/obj/item/circuitboard/computer/shuttle/docker + name = "Shuttle Navigation Computer (Computer Board)" + build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/custom //Security diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 35d91e5d9924..3fd1abff94d5 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1230,3 +1230,28 @@ /obj/item/stack/sheet/mineral/silver = 1) needs_anchored = FALSE + +/obj/item/circuitboard/machine/shuttle/engine + name = "Thruster (Machine Board)" + build_path = /obj/machinery/shuttle/engine + req_components = list() + +/obj/item/circuitboard/machine/shuttle/engine/plasma + name = "Plasma Thruster (Machine Board)" + build_path = /obj/machinery/shuttle/engine/plasma + req_components = list(/obj/item/stock_parts/capacitor = 2, + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/micro_laser = 1) + +/obj/item/circuitboard/machine/shuttle/engine/void + name = "Void Thruster (Machine Board)" + build_path = /obj/machinery/shuttle/engine/void + req_components = list(/obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/micro_laser/quadultra = 1) + +/obj/item/circuitboard/machine/shuttle/heater + name = "Electronic Engine Heater (Machine Board)" + build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater + req_components = list(/obj/item/stock_parts/micro_laser = 2, + /obj/item/stock_parts/matter_bin = 1) diff --git a/code/game/objects/items/shuttle_creator.dm b/code/game/objects/items/shuttle_creator.dm new file mode 100644 index 000000000000..e7b796d1d2f3 --- /dev/null +++ b/code/game/objects/items/shuttle_creator.dm @@ -0,0 +1,301 @@ +#define SHUTTLE_CREATOR_MAX_SIZE CONFIG_GET(number/max_shuttle_size) +#define CUSTOM_SHUTTLE_LIMIT CONFIG_GET(number/max_shuttle_count) + +GLOBAL_VAR_INIT(custom_shuttle_count, 0) //The amount of custom shuttles created to prevent creating hundreds +GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (Heaters, engines) + +/obj/item/shuttle_creator + name = "Rapid Shuttle Designator" + icon = 'icons/obj/tools.dmi' + icon_state = "rsd" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + desc = "A device used to define the area required for custom ships. Uses bluespace crystals to create bluespace-capable ships." + density = FALSE + anchored = FALSE + flags_1 = CONDUCT_1 + item_flags = NOBLUDGEON + force = 0 + throwforce = 8 + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_NORMAL + req_access_txt = "11" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + resistance_flags = FIRE_PROOF + var/ready = TRUE + var/recorded_shuttle_area + var/list/loggedTurfs = list() + var/loggedOldArea + var/linkedShuttleId + +/obj/item/shuttle_creator/attack_self(mob/user) + ..() + if(linkedShuttleId) + return + if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) + return + return check_current_area(user) + +/obj/item/shuttle_creator/afterattack(atom/target, mob/user, proximity_flag) + . = ..() + if(!ready) + to_chat(user, "You need to define a shuttle area first.") + return + if(!proximity_flag) + return + if(istype(target, /obj/machinery/door/airlock)) + if(get_area(target) != loggedOldArea) + to_chat(user, "Caution, airlock must be on the shuttle to function as a dock.") + return + if(linkedShuttleId) + return + if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) + to_chat(user, "Shuttle limit reached, sorry.") + return + if(!create_shuttle_area(user)) + return + if(shuttle_create_docking_port(target, user)) + to_chat(user, "Shuttle created!") + return + else if(istype(target, /obj/machinery/computer/custom_shuttle)) + if(!linkedShuttleId) + to_chat(user, "Error, no defined shuttle linked to device") + return + var/obj/machinery/computer/custom_shuttle/console = target + console.linkShuttle(linkedShuttleId) + to_chat(user, "Console linked successfully!") + return + else if(istype(target, /obj/machinery/computer/camera_advanced/shuttle_docker/custom)) + if(!linkedShuttleId) + to_chat(user, "Error, no defined shuttle linked to device") + return + var/obj/machinery/computer/camera_advanced/shuttle_docker/custom/console = target + console.linkShuttle(linkedShuttleId) + to_chat(user, "Console linked successfully!") + return + to_chat(user, "The [src] bleeps. Select an airlock to create a docking port, or a valid machine to link.") + return + +/obj/item/shuttle_creator/proc/calculate_bounds(obj/docking_port/mobile/port) + if(!port || !istype(port, /obj/docking_port/mobile)) + return FALSE + //Heights is the distance away from the port + //width is the distance perpendicular to the port + var/minX = INFINITY + var/maxX = 0 + var/minY = INFINITY + var/maxY = 0 + for(var/turf/T in loggedTurfs) + minX = min(T.x, minX) + maxX = max(T.x, maxX) + minY = min(T.y, minY) + maxY = max(T.y, maxY) + //Make sure shuttle was actually found. + if(maxX == INFINITY || maxY == INFINITY) + return FALSE + minX-- + minY-- + var/width = maxX - minX + var/height = maxY - minY + var/offset_x = port.x - minX + var/offset_y = port.y - minY + switch(port.dir) //Source: code/datums/shuttles.dm line 77 (14/03/2020) :) + if(NORTH) + port.width = width + port.height = height + port.dwidth = offset_x - 1 + port.dheight = offset_y - 1 + if(EAST) + port.width = height + port.height = width + port.dwidth = height - offset_y + port.dheight = offset_x - 1 + if(SOUTH) + port.width = width + port.height = height + port.dwidth = width - offset_x + port.dheight = height - offset_y + if(WEST) + port.width = height + port.height = width + port.dwidth = offset_y - 1 + port.dheight = width - offset_x + to_chat(usr, "Created shuttle with dir [port.dir], width [port.width], height [port.height], dwidth [port.dwidth], dheight [port.dheight]") + return TRUE + +//Go through all the all_turfs and check which direction doesn't have the shuttle +/obj/item/shuttle_creator/proc/getNonShuttleDirection(turf/targetTurf) + var/position = null + if(!(get_offset_target_turf(targetTurf, 0, 1) in loggedTurfs)) + if(position != null) + return null + position = NORTH + if(!(get_offset_target_turf(targetTurf, 0, -1) in loggedTurfs)) + if(position != null) + return null + position = SOUTH + if(!(get_offset_target_turf(targetTurf, 1, 0) in loggedTurfs)) + if(position != null) + return null + position = EAST + if(!(get_offset_target_turf(targetTurf, -1, 0) in loggedTurfs)) + if(position != null) + return null + position = WEST + to_chat(usr, "Direction to space is [position]") + return position + +/obj/item/shuttle_creator/proc/invertDir(var/input_dir) + if(input_dir == NORTH) + return SOUTH + else if(input_dir == SOUTH) + return NORTH + else if(input_dir == EAST) + return WEST + else if(input_dir == WEST) + return EAST + return null + +/obj/item/shuttle_creator/proc/shuttle_create_docking_port(atom/target, mob/user) + + if(loggedTurfs.len == 0 || !recorded_shuttle_area) + to_chat(user, "Invalid shuttle, restarting bluespace systems...") + return FALSE + + var/datum/map_template/shuttle/new_shuttle = new /datum/map_template/shuttle() + + var/obj/docking_port/mobile/port = new /obj/docking_port/mobile(get_turf(target)) + var/obj/docking_port/stationary/stationary_port = new /obj/docking_port/stationary(get_turf(target)) + port.callTime = 50 + port.dir = 1 //Point away from space. + port.id = "custom_[GLOB.custom_shuttle_count]" + linkedShuttleId = port.id + port.ignitionTime = 25 + port.name = "Custom Shuttle" + port.port_direction = 2 + port.preferred_direction = 4 + port.area_type = recorded_shuttle_area + + var/portDirection = getNonShuttleDirection(get_turf(port)) + var/invertedDir = invertDir(portDirection) + if(!portDirection || !invertedDir) + to_chat(usr, "Shuttle creation aborted, docking airlock must be on an external wall. Please select a new airlock.") + port.Destroy() + stationary_port.Destroy() + linkedShuttleId = null + return FALSE + port.dir = invertedDir + port.port_direction = portDirection + + if(!calculate_bounds(port)) + to_chat(usr, "Bluespace calculations failed, please select a new airlock.") + port.Destroy() + stationary_port.Destroy() + linkedShuttleId = null + return FALSE + + port.shuttle_areas = list() + //var/list/all_turfs = port.return_ordered_turfs(port.x, port.y, port.z, port.dir) + var/list/all_turfs = loggedTurfs + for(var/i in 1 to all_turfs.len) + var/turf/curT = all_turfs[i] + var/area/cur_area = curT.loc + //Add the area to the shuttle <3 + if(istype(cur_area, recorded_shuttle_area)) + if(istype(curT, /turf/open/space)) + continue + if(length(curT.baseturfs) < 2) + continue + //Add the shuttle base shit to the shuttle + curT.baseturfs.Insert(3, /turf/baseturf_skipover/shuttle) + port.shuttle_areas[cur_area] = TRUE + + port.linkup(new_shuttle, stationary_port) + + port.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0) + port.initiate_docking(stationary_port) + + port.mode = SHUTTLE_IDLE + port.timer = 0 + + port.register() + GLOB.custom_shuttle_count ++ + message_admins("[ADMIN_LOOKUPFLW(user)] created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") + log_game("[key_name(user)] created a new shuttle with a [src] at [AREACOORD(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") + return TRUE + +/obj/item/shuttle_creator/proc/create_shuttle_area(mob/user) + if(!loggedTurfs) + return FALSE + //Create the new area + var/area/shuttle/custom/powered/newS + var/area/oldA = loggedOldArea + var/str = stripped_input(user, "Shuttle Name:", "Blueprint Editing", "", MAX_NAME_LEN) + if(!str || !length(str)) + return FALSE + if(length(str) > 50) + to_chat(user, "The provided ship name is too long, blares the [src]") + return FALSE +/* + if(OOC_FILTER_CHECK(str)) + to_chat(user, "Nanotrasen prohibited words are in use in this shuttle name, blares the [src] in a slightly offended tone.") + return FALSE +*/ + newS = new /area/shuttle/custom/powered() + newS.setup(str) + newS.set_dynamic_lighting() + //Shuttles always have gravity + newS.has_gravity = TRUE + newS.requires_power = TRUE + //Record the area for use when creating the docking port + recorded_shuttle_area = newS + + for(var/i in 1 to loggedTurfs.len) + var/turf/turf_holder = loggedTurfs[i] + var/area/old_area = turf_holder.loc + newS.contents += turf_holder + turf_holder.change_area(old_area, newS) + + newS.reg_in_areas_in_z() + + var/list/firedoors = oldA.firedoors + for(var/door in firedoors) + var/obj/machinery/door/firedoor/FD = door + FD.CalculateAffectingAreas() + return TRUE + +/obj/item/shuttle_creator/proc/check_current_area(mob/user) + var/static/area_or_turf_fail_types = typecacheof(list( + /turf/open/space, + /area/shuttle + )) + //Check to see if the user can make a new area to prevent spamming + if(user) + if(user.create_area_cooldown >= world.time) + to_chat(user, "Smoke vents from the [src], maybe you should let it cooldown before using it again.") + return + user.create_area_cooldown = world.time + 10 + //Detect the turfs connected in the curerrent enclosed area + var/list/turfs = detect_room(get_turf(user), area_or_turf_fail_types) + if(!turfs) + to_chat(user, "Shuttles must be created in an airtight space, ensure that the shuttle is airtight, including corners.") + return + if(turfs.len > SHUTTLE_CREATOR_MAX_SIZE) + to_chat(user, "The [src]'s internal cooling system wizzes violently and a message appears on the screen, \"Caution, this device can only handle the creation of shuttles up to [SHUTTLE_CREATOR_MAX_SIZE] units in size. Please reduce your shuttle by [turfs.len-SHUTTLE_CREATOR_MAX_SIZE]. Sorry for the inconvinience\"") + return + //Check to see if it's a valid shuttle + for(var/i in 1 to turfs.len) + var/area/space/place = get_area(turfs[i]) + //If any of the turfs are on station / not in space, a shuttle cannot be forced there + if(!place) + to_chat(user, "You can't seem to overpower the bluespace harmonics in this location, try somewhere else.") + return + if(!istype(place, /area/space)) + to_chat(user, "Caution, shuttle must not use any material connected to the station. Your shuttle is currenly overlapping with [place.name]") + return + + loggedOldArea = get_area(get_turf(user)) + loggedTurfs = turfs + icon_state = "rsd_used" + to_chat(user, "Your current area was logged into the [src], select an airlock to act as the docking point.") diff --git a/code/game/objects/items/shuttle_upgrades.dm b/code/game/objects/items/shuttle_upgrades.dm new file mode 100644 index 000000000000..c64f643b6dc7 --- /dev/null +++ b/code/game/objects/items/shuttle_upgrades.dm @@ -0,0 +1,39 @@ +/obj/item/shuttle_route_optimisation + name = "Route Optimisation Upgrade" + desc = "Used on a custom shuttle control console to calculate more efficient routes." + icon = 'icons/obj/module.dmi' + icon_state = "shuttledisk" + force = 0 + throwforce = 8 + throw_speed = 3 + throw_range = 5 + density = FALSE + anchored = FALSE + item_flags = NOBLUDGEON + var/upgrade_amount = 0.8 + +/obj/item/shuttle_route_optimisation/hyperlane + name = "Bluespace Hyperlane Calculator" + desc = "Used on a custom shuttle control console to allow for the following of bluespace hyperlanes, increasing the efficiency of the shuttle." + icon_state = "shuttledisk_better" + upgrade_amount = 0.6 + +/obj/item/shuttle_route_optimisation/void + name = "Voidspace Route Calculator" + desc = "Used on a custom shuttle control console to allow it to navigate into voidspace, making the routes almost instant." + icon_state = "shuttledisk_void" + upgrade_amount = 0.2 + +/obj/item/shuttle_route_optimisation/attack_obj(obj/O, mob/living/user) + . = ..() + if(!istype(O, /obj/machinery/computer)) + return + if(!istype(O, /obj/machinery/computer/custom_shuttle)) + to_chat(user, "This upgrade only works on a custom shuttle flight console.") + return + if (!user.transferItemToLoc(src, get_turf(O))) + return + var/obj/machinery/computer/custom_shuttle/link_comp = O + link_comp.distance_multiplier = clamp(link_comp.distance_multiplier, 0, upgrade_amount) //I have no clue what clamp even does, but I think this should work + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + to_chat(usr, "You insert the disk into the flight computer, allowing for routes to be [upgrade_amount]x the original distance.") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 8ec3522e686f..c00f1b7607cf 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -273,6 +273,7 @@ Works together with spawning an observer, noted above. stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now if(can_reenter_corpse && client) //yogs start oobe_client = client //yogs end + onGhost() var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 96ba894f1e8e..2797bcc65051 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -219,3 +219,5 @@ /// A mock client, provided by tests and friends var/datum/client_interface/mock_client + + var/create_area_cooldown diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index 83400fc18f2b..53305c207cf3 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -285,3 +285,19 @@ build_path = /obj/item/circuitboard/computer/nanite_cloud_controller category = list("Computer Boards") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/shuttle/flight_control + name = "Computer Design (Shuttle Flight Controls)" + desc = "Allows for the construction of circuit boards used to build a console that enables shuttle flight" + id = "shuttle_control" + build_path = /obj/item/circuitboard/computer/shuttle/flight_control + category = list("Computer Boards", "Shuttle Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/shuttle/shuttle_docker + name = "Computer Design (Private Navigation Computer)" + desc = "Allows for the construction of circuit boards used to build a console that enables the targetting of custom flight locations" + id = "shuttle_docker" + build_path = /obj/item/circuitboard/computer/shuttle/docker + category = list("Computer Boards", "Shuttle Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 0360b7dbfa97..3a9c6d0820ac 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -2,6 +2,30 @@ //////////////MISC Boards/////////////// //////////////////////////////////////// +/datum/design/board/shuttle/engine/plasma + name = "Machine Design (Plasma Thruster Board)" + desc = "The circuit board for a plasma thruster." + id = "engine_plasma" + build_path = /obj/item/circuitboard/machine/shuttle/engine/plasma + category = list ("Shuttle Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/shuttle/engine/void + name = "Machine Design (Void Thruster Board)" + desc = "The circuit board for a void thruster." + id = "engine_void" + build_path = /obj/item/circuitboard/machine/shuttle/engine/void + category = list ("Shuttle Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/shuttle/engine/heater + name = "Machine Design (Engine Heater Board)" + desc = "The circuit board for an engine heater." + id = "engine_heater" + build_path = /obj/item/circuitboard/machine/shuttle/heater + category = list ("Shuttle Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/board/smes name = "Machine Design (SMES Board)" desc = "The circuit board for an SMES." diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 99924c91b004..d50cd0f7d6b4 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -3,6 +3,36 @@ /////////////////HUDs//////////////////// ///////////////////////////////////////// +/datum/design/shuttle_speed_upgrade + name = "Shuttle Route Optimisation Upgrade" + desc = "A disk that allows for calculating shorter routes when inserted into a flight control console." + id = "disk_shuttle_route" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) + build_path = /obj/item/shuttle_route_optimisation + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/shuttle_speed_upgrade_hyper + name = "Shuttle Bluespace Hyperlane Optimisation Upgrade" + desc = "A disk that allows for calculating shorter routes when inserted into a flight control console. This one abuses bluespace hyperlanes for increased efficiency." + id = "disk_shuttle_route_hyper" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) + build_path = /obj/item/shuttle_route_optimisation/hyperlane + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/shuttle_speed_upgrade_void + name = "Shuttle Voidspace Optimisation Upgrade" + desc = "A disk that allows for calculating shorter routes when inserted into a flight control console. This one access voidspace for increased efficiency." + id = "disk_shuttle_route_void" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) + build_path = /obj/item/shuttle_route_optimisation/void + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/health_hud name = "Health Scanner HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index ffc14a6bb941..4a983f4a3619 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -23,6 +23,16 @@ category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/shuttlecreator + name = "Rapid Shuttle Designator" + desc = "An advanced device capable of defining areas for use in the creation of shuttles" + id = "shuttle_creator" + build_path = /obj/item/shuttle_creator + build_type = PROTOLATHE + materials = list(/datum/material/iron = 8000, /datum/material/titanium = 5000, /datum/material/bluespace = 5000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/exwelder name = "Experimental Welding Tool" desc = "An experimental welder capable of self-fuel generation." diff --git a/code/modules/research/machinery/circuit_imprinter.dm b/code/modules/research/machinery/circuit_imprinter.dm index 948dad61db94..8415564f6d09 100644 --- a/code/modules/research/machinery/circuit_imprinter.dm +++ b/code/modules/research/machinery/circuit_imprinter.dm @@ -14,7 +14,8 @@ "Subspace Telecomms", "Research Machinery", "Misc. Machinery", - "Computer Parts" + "Computer Parts", + "Shuttle Machinery" ) production_animation = "circuit_imprinter_ani" allowed_buildtypes = IMPRINTER diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 85342c69313e..bec96d316068 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -272,6 +272,43 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 +/////////////////////////shuttle tech///////////////////////// +/datum/techweb_node/basic_shuttle_tech + id = "basic_shuttle" + display_name = "Basic Shuttle Research" + description = "Research the technology required to create and use basic shuttles." + prereq_ids = list("bluespace_travel", "adv_engi") + design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) + export_price = 5000 + +/datum/techweb_node/shuttle_route_upgrade + id = "shuttle_route_upgrade" + display_name = "Route Optimisation Upgrade" + description = "Research into bluespace tunnelling, allowing us to reduce flight times by up to 20%!" + prereq_ids = list("basic_shuttle") + design_ids = list("disk_shuttle_route") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 2500 + +/datum/techweb_node/shuttle_route_upgrade_hyper + id = "shuttle_route_upgrade_hyper" + display_name = "Hyperlane Optimisation Upgrade" + description = "Research into bluespace hyperlane, allowing us to reduce flight times by up to 40%!" + prereq_ids = list("shuttle_route_upgrade", "micro_bluespace") + design_ids = list("disk_shuttle_route_hyper") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +/datum/techweb_node/shuttle_route_upgrade_void + id = "shuttle_route_upgrade_void" + display_name = "Nullspace Breaching Upgrade" + description = "Research into voidspace tunnelling, allowing us to significantly reduce flight times." + prereq_ids = list("shuttle_route_upgrade_hyper", "alientech") + design_ids = list("disk_shuttle_route_void", "engine_void") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 12500) + export_price = 5000 + /////////////////////////robotics tech///////////////////////// /datum/techweb_node/robotics id = "robotics" diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm new file mode 100644 index 000000000000..cbcaf41caedf --- /dev/null +++ b/code/modules/shuttle/custom_shuttle.dm @@ -0,0 +1,263 @@ +#define Z_DIST 500 +#define CUSTOM_ENGINES_START_TIME 65 +#define CALCULATE_STATS_COOLDOWN 2 + +/obj/machinery/computer/custom_shuttle + name = "nanotrasen shuttle flight controller" + desc = "A terminal used to fly shuttles defined by the Shuttle Zoning Designator" + circuit = /obj/item/circuitboard/computer/shuttle/flight_control + icon_screen = "shuttle" + icon_keyboard = "tech_key" + light_color = LIGHT_COLOR_CYAN + req_access = list( ) + var/shuttleId + var/possible_destinations = "whiteship_home" + var/admin_controlled + var/no_destination_swap = 0 + var/calculated_mass = 0 + var/calculated_dforce = 0 + var/calculated_speed = 0 + var/calculated_engine_count = 0 + var/calculated_consumption = 0 + var/calculated_cooldown = 0 + var/calculated_non_operational_thrusters = 0 + var/calculated_fuel_less_thrusters = 0 + var/target_fuel_cost = 0 + var/targetLocation + var/datum/browser/popup + + var/stat_calc_cooldown = 0 + + //Upgrades + var/distance_multiplier = 1 + +/obj/machinery/computer/custom_shuttle/examine(mob/user) + . = ..() + . += distance_multiplier < 1 ? "Bluespace shortcut module installed. Route is [distance_multiplier]x the original length." : "" + +/obj/machinery/computer/custom_shuttle/ui_interact(mob/user) + var/list/options = params2list(possible_destinations) + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + var/dat = "[M ? "Current Location : [M.getStatusText()]" : "Shuttle link required."]

" + if(M) + dat += "Run Flight Calculations
" + dat += "Shuttle Data
" + dat += "Shuttle Mass: [calculated_mass/10]tons
" + dat += "Engine Force: [calculated_dforce]kN ([calculated_engine_count] engines)
" + dat += "Sublight Speed: [calculated_speed]ms-1
" + dat += calculated_speed < 1 ? "INSUFFICIENT ENGINE POWER
" : "" + dat += calculated_non_operational_thrusters > 0 ? "Warning: [calculated_non_operational_thrusters] thrusters offline.
" : "" + dat += "Fuel Consumption: [calculated_consumption]units per distance
" + dat += "Engine Cooldown: [calculated_cooldown]s
" + var/destination_found + for(var/obj/docking_port/stationary/S in SSshuttle.stationary) + if(!options.Find(S.id)) + continue + if(!M.check_dock(S, silent=TRUE)) + continue + if(calculated_speed == 0) + break + destination_found = TRUE + var/dist = round(calculateDistance(S)) + dat += "Target [S.name] (Dist: [dist] | Fuel Cost: [round(dist * calculated_consumption)] | Time: [round(dist / calculated_speed)])
" + if(!destination_found) + dat += "No valid destinations
" + dat += "
[targetLocation ? "Target Location : [targetLocation]" : "No Target Location"]" + dat += "
Initate Flight
" + dat += "Close" + + popup = new(user, "computer", M ? M.name : "shuttle", 350, 450) + popup.set_content("
[dat]
") + //popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/custom_shuttle/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + src.add_fingerprint(usr) + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return + + if(href_list["calculate"]) + calculateStats() + ui_interact(usr) + return + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + if(!M) + return + if(M.launch_status == ENDGAME_LAUNCHED) + return + if(href_list["setloc"]) + SetTargetLocation(href_list["setloc"]) + ui_interact(usr) + return + else if(href_list["fly"]) + Fly() + ui_interact(usr) + return + +/obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/docking_port/stationary/port) + var/deltaX = port.x - x + var/deltaY = port.y - y + var/deltaZ = (port.z - z) * Z_DIST + return sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * distance_multiplier + +/obj/machinery/computer/custom_shuttle/proc/linkShuttle(var/new_id) + shuttleId = new_id + possible_destinations = "whiteship_home;shuttle[new_id]_custom" + +/obj/machinery/computer/custom_shuttle/proc/calculateStats(var/useFuel = FALSE, var/dist = 0, var/ignore_cooldown = FALSE) + if(!ignore_cooldown && stat_calc_cooldown >= world.time) + to_chat(usr, "You are using this too fast, please slow down") + return + stat_calc_cooldown = world.time + CALCULATE_STATS_COOLDOWN + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + if(!M) + return FALSE + //Reset data + calculated_mass = 0 + calculated_dforce = 0 + calculated_speed = 0 + calculated_engine_count = 0 + calculated_consumption = 0 + calculated_cooldown = 0 + calculated_fuel_less_thrusters = 0 + calculated_non_operational_thrusters = 0 + //Calculate all the data + var/list/areas = M.shuttle_areas + for(var/shuttleArea in areas) + calculated_mass += length(get_area_turfs(shuttleArea)) + for(var/obj/machinery/shuttle/engine/E in shuttleArea) + E.check_setup() + if(!E.thruster_active) //Skipover thrusters with no valid heater + calculated_non_operational_thrusters ++ + continue + if(E.attached_heater) + var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolvedHeater = E.attached_heater.resolve() + if(resolvedHeater && !resolvedHeater.hasFuel(dist * E.fuel_use) && useFuel) + calculated_fuel_less_thrusters ++ + continue + calculated_engine_count++ + calculated_dforce += E.thrust + calculated_consumption += E.fuel_use + calculated_cooldown = max(calculated_cooldown, E.cooldown) + //This should really be accelleration, but its a 2d spessman game so who cares + if(calculated_mass == 0) + return FALSE + calculated_speed = (calculated_dforce*1000) / (calculated_mass*100) + return TRUE + +/obj/machinery/computer/custom_shuttle/proc/consumeFuel(var/dist) + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + if(!M) + return FALSE + //Calculate all the data + for(var/obj/machinery/shuttle/engine/shuttle_machine in GLOB.custom_shuttle_machines) + shuttle_machine.check_setup() + if(!shuttle_machine.thruster_active) + continue + if(get_area(M) != get_area(shuttle_machine)) + continue + if(shuttle_machine.attached_heater) + var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolvedHeater = shuttle_machine.attached_heater.resolve() + if(resolvedHeater && !resolvedHeater.hasFuel(dist * shuttle_machine.fuel_use)) + continue + resolvedHeater?.consumeFuel(dist * shuttle_machine.fuel_use) + shuttle_machine.fireEngine() + +/obj/machinery/computer/custom_shuttle/proc/SetTargetLocation(var/newTarget) + if(!(newTarget in params2list(possible_destinations))) + log_admin("[usr] attempted to href dock exploit on [src] with target location \"[newTarget]\"") + message_admins("[usr] just attempted to href dock exploit on [src] with target location \"[newTarget]\"") + return + targetLocation = newTarget + say("Shuttle route calculated.") + return + +/obj/machinery/computer/custom_shuttle/proc/Fly() + if(!targetLocation) + return + var/obj/docking_port/mobile/linkedShuttle = SSshuttle.getShuttle(shuttleId) + if(!linkedShuttle) + return + if(linkedShuttle.mode != SHUTTLE_IDLE) + return + if(!calculateStats(TRUE, 0, TRUE)) + return + if(calculated_fuel_less_thrusters > 0) + say("Warning, [calculated_fuel_less_thrusters] do not have enough fuel for this journey, engine output may be limitted.") + if(calculated_speed < 1) + say("Insufficient engine power, shuttle requires [calculated_mass / 10]kN of thrust.") + return + var/obj/docking_port/stationary/targetPort = SSshuttle.getDock(targetLocation) + if(!targetPort) + return + var/dist = calculateDistance(targetPort) + var/time = min(max(round(dist / calculated_speed), 10), 90) + linkedShuttle.callTime = time * 10 + linkedShuttle.rechargeTime = calculated_cooldown + //We need to find the direction of this console to the port + linkedShuttle.port_direction = angle2dir(dir2angle(dir) - (dir2angle(linkedShuttle.dir)) + 180) + linkedShuttle.preferred_direction = NORTH + linkedShuttle.ignitionTime = CUSTOM_ENGINES_START_TIME + linkedShuttle.count_engines() + linkedShuttle.hyperspace_sound(HYPERSPACE_WARMUP) + var/throwForce = clamp((calculated_speed / 2) - 5, 0, 10) + linkedShuttle.movement_force = list("KNOCKDOWN" = calculated_speed > 5 ? 3 : 0, "THROW" = throwForce) + if(!(targetLocation in params2list(possible_destinations))) + log_admin("[usr] attempted to launch a shuttle that has been affected by href dock exploit on [src] with target location \"[targetLocation]\"") + message_admins("[usr] attempted to launch a shuttle that has been affected by href dock exploit on [src] with target location \"[targetLocation]\"") + return + switch(SSshuttle.moveShuttle(shuttleId, targetLocation, 1)) + if(0) + consumeFuel(dist) + say("Shuttle departing. Please stand away from the doors.") + if(1) + to_chat(usr, "Invalid shuttle requested.") + else + to_chat(usr, "Unable to comply.") + return + +/obj/machinery/computer/custom_shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) + if(port && (shuttleId == initial(shuttleId) || override)) + linkShuttle(port.id) + +//Custom shuttle docker locations +/obj/machinery/computer/camera_advanced/shuttle_docker/custom + name = "Shuttle Navigation Computer" + desc = "Used to designate a precise transit location for private ships." + lock_override = NONE + whitelist_turfs = list(/turf/open/space, /turf/open/lava) + jumpto_ports = list("whiteship_home" = 1) + view_range = 12 + designate_time = 100 + circuit = /obj/item/circuitboard/computer/shuttle/docker + +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/Initialize() + . = ..() + GLOB.jam_on_wardec += src + +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/Destroy() + GLOB.jam_on_wardec -= src + return ..() + +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/placeLandingSpot() + if(!shuttleId) + return //Only way this would happen is if someone else delinks the console while in use somehow + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + if(M?.mode != SHUTTLE_IDLE) + to_chat(usr, "You cannot target locations while in transit.") + return + ..() + +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/attack_hand(mob/user) + if(!shuttleId) + to_chat(user, "You must link the console to a shuttle first.") + return + return ..() + +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/proc/linkShuttle(var/new_id) + shuttleId = new_id + shuttlePortId = "shuttle[new_id]_custom" diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index fff0b4c8c18f..d0e30ae91ba1 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -14,6 +14,7 @@ var/view_range = 0 var/x_offset = 0 var/y_offset = 0 + var/list/whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava) var/space_turfs_only = TRUE var/see_hidden = FALSE var/designate_time = 0 @@ -29,6 +30,7 @@ var/obj/docking_port/stationary/S = V if(jumpto_ports[S.id]) z_lock |= S.z + whitelist_turfs = typecacheof(whitelist_turfs) /obj/machinery/computer/camera_advanced/shuttle_docker/Destroy() . = ..() @@ -228,12 +230,17 @@ if(hidden_turf_info) . = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT + if(length(whitelist_turfs)) + var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type + if(!is_type_in_typecache(turf_type, whitelist_turfs)) + return SHUTTLE_DOCKER_BLOCKED +/* if(space_turfs_only) var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type var/area/A = get_area(T) if(!ispath(turf_type, /turf/open/space) && !ispath(A.type, /area/icemoon)) return SHUTTLE_DOCKER_BLOCKED - +*/ // Checking for overlapping dock boundaries for(var/i in 1 to overlappers.len) var/obj/docking_port/port = overlappers[i] @@ -345,4 +352,4 @@ C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) C.clear_fullscreen("flash", 3) else - playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) \ No newline at end of file + playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 11aa65c70b88..974456c3f25e 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -832,6 +832,10 @@ if(!QDELETED(E)) engine_list += E . += E.engine_power + for(var/obj/machinery/shuttle/engine/E in areaInstance.contents) + if(!QDELETED(E)) + engine_list += E + . += E.thruster_active ? 1 : 0 // Double initial engines to get to 0.5 minimum // Lose all initial engines to get to 2 diff --git a/config/config.txt b/config/config.txt index 0ea77d2f4e84..6493b96c180e 100644 --- a/config/config.txt +++ b/config/config.txt @@ -442,3 +442,7 @@ AUTO_PROFILE ## Uncomment to disable hard deletes entirely, even things that explicitly request. This is not recommended unless you have a need for it during events or other high pop times where performance is key. #DISABLE_ALL_HARD_DELETES + +## Custom shuttle spam prevention. Changine these numbers allows you to change the maxsize and amount of custom shuttles. +MAX_SHUTTLE_COUNT 6 +MAX_SHUTTLE_SIZE 300 diff --git a/yogstation.dme b/yogstation.dme index df5920d57f70..bcd72c82f8b2 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -798,6 +798,9 @@ #include "code\game\machinery\porta_turret\portable_turret.dm" #include "code\game\machinery\porta_turret\portable_turret_construct.dm" #include "code\game\machinery\porta_turret\portable_turret_cover.dm" +#include "code\game\machinery\shuttle\custom_shuttle.dm" +#include "code\game\machinery\shuttle\shuttle_engine.dm" +#include "code\game\machinery\shuttle\shuttle_heater.dm" #include "code\game\machinery\telecomms\broadcasting.dm" #include "code\game\machinery\telecomms\machine_interactions.dm" #include "code\game\machinery\telecomms\telecomunications.dm" @@ -967,6 +970,8 @@ #include "code\game\objects\items\sharpener.dm" #include "code\game\objects\items\shields.dm" #include "code\game\objects\items\shooting_range.dm" +#include "code\game\objects\items\shuttle_creator.dm" +#include "code\game\objects\items\shuttle_upgrades.dm" #include "code\game\objects\items\signs.dm" #include "code\game\objects\items\singularityhammer.dm" #include "code\game\objects\items\stunbaton.dm" @@ -2890,6 +2895,7 @@ #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" +#include "code\modules\shuttle\custom_shuttle.dm" #include "code\modules\shuttle\docking.dm" #include "code\modules\shuttle\elevator.dm" #include "code\modules\shuttle\emergency.dm" From ad59cf443a60cea82c1c07ce609867d5e86f802f Mon Sep 17 00:00:00 2001 From: nmajask Date: Tue, 27 Jul 2021 02:23:07 -0400 Subject: [PATCH 02/16] Ports some changes - Ports https://github.com/BeeStation/BeeStation-Hornet/pull/1904/files# and https://github.com/BeeStation/BeeStation-Hornet/pull/1529 --- code/game/objects/items/shuttle_creator.dm | 301 -------------- code/game/objects/items/shuttle_upgrades.dm | 39 -- code/modules/shuttle/custom_shuttle.dm | 7 +- .../shuttle_creation/shuttle_creator.dm | 371 ++++++++++++++++++ .../shuttle_creator_actions.dm | 101 +++++ .../shuttle_creator_console.dm | 93 +++++ .../shuttle_creation/shuttle_creator_eye.dm | 54 +++ .../shuttle_creator_overlay.dm | 52 +++ .../shuttle_creation/shuttle_upgrades.dm | 39 ++ icons/obj/tools.dmi | Bin 23472 -> 26656 bytes 10 files changed, 716 insertions(+), 341 deletions(-) create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_creator.dm create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_creator_overlay.dm create mode 100644 code/modules/shuttle/shuttle_creation/shuttle_upgrades.dm diff --git a/code/game/objects/items/shuttle_creator.dm b/code/game/objects/items/shuttle_creator.dm index e7b796d1d2f3..e69de29bb2d1 100644 --- a/code/game/objects/items/shuttle_creator.dm +++ b/code/game/objects/items/shuttle_creator.dm @@ -1,301 +0,0 @@ -#define SHUTTLE_CREATOR_MAX_SIZE CONFIG_GET(number/max_shuttle_size) -#define CUSTOM_SHUTTLE_LIMIT CONFIG_GET(number/max_shuttle_count) - -GLOBAL_VAR_INIT(custom_shuttle_count, 0) //The amount of custom shuttles created to prevent creating hundreds -GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (Heaters, engines) - -/obj/item/shuttle_creator - name = "Rapid Shuttle Designator" - icon = 'icons/obj/tools.dmi' - icon_state = "rsd" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - desc = "A device used to define the area required for custom ships. Uses bluespace crystals to create bluespace-capable ships." - density = FALSE - anchored = FALSE - flags_1 = CONDUCT_1 - item_flags = NOBLUDGEON - force = 0 - throwforce = 8 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_NORMAL - req_access_txt = "11" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF - var/ready = TRUE - var/recorded_shuttle_area - var/list/loggedTurfs = list() - var/loggedOldArea - var/linkedShuttleId - -/obj/item/shuttle_creator/attack_self(mob/user) - ..() - if(linkedShuttleId) - return - if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) - return - return check_current_area(user) - -/obj/item/shuttle_creator/afterattack(atom/target, mob/user, proximity_flag) - . = ..() - if(!ready) - to_chat(user, "You need to define a shuttle area first.") - return - if(!proximity_flag) - return - if(istype(target, /obj/machinery/door/airlock)) - if(get_area(target) != loggedOldArea) - to_chat(user, "Caution, airlock must be on the shuttle to function as a dock.") - return - if(linkedShuttleId) - return - if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) - to_chat(user, "Shuttle limit reached, sorry.") - return - if(!create_shuttle_area(user)) - return - if(shuttle_create_docking_port(target, user)) - to_chat(user, "Shuttle created!") - return - else if(istype(target, /obj/machinery/computer/custom_shuttle)) - if(!linkedShuttleId) - to_chat(user, "Error, no defined shuttle linked to device") - return - var/obj/machinery/computer/custom_shuttle/console = target - console.linkShuttle(linkedShuttleId) - to_chat(user, "Console linked successfully!") - return - else if(istype(target, /obj/machinery/computer/camera_advanced/shuttle_docker/custom)) - if(!linkedShuttleId) - to_chat(user, "Error, no defined shuttle linked to device") - return - var/obj/machinery/computer/camera_advanced/shuttle_docker/custom/console = target - console.linkShuttle(linkedShuttleId) - to_chat(user, "Console linked successfully!") - return - to_chat(user, "The [src] bleeps. Select an airlock to create a docking port, or a valid machine to link.") - return - -/obj/item/shuttle_creator/proc/calculate_bounds(obj/docking_port/mobile/port) - if(!port || !istype(port, /obj/docking_port/mobile)) - return FALSE - //Heights is the distance away from the port - //width is the distance perpendicular to the port - var/minX = INFINITY - var/maxX = 0 - var/minY = INFINITY - var/maxY = 0 - for(var/turf/T in loggedTurfs) - minX = min(T.x, minX) - maxX = max(T.x, maxX) - minY = min(T.y, minY) - maxY = max(T.y, maxY) - //Make sure shuttle was actually found. - if(maxX == INFINITY || maxY == INFINITY) - return FALSE - minX-- - minY-- - var/width = maxX - minX - var/height = maxY - minY - var/offset_x = port.x - minX - var/offset_y = port.y - minY - switch(port.dir) //Source: code/datums/shuttles.dm line 77 (14/03/2020) :) - if(NORTH) - port.width = width - port.height = height - port.dwidth = offset_x - 1 - port.dheight = offset_y - 1 - if(EAST) - port.width = height - port.height = width - port.dwidth = height - offset_y - port.dheight = offset_x - 1 - if(SOUTH) - port.width = width - port.height = height - port.dwidth = width - offset_x - port.dheight = height - offset_y - if(WEST) - port.width = height - port.height = width - port.dwidth = offset_y - 1 - port.dheight = width - offset_x - to_chat(usr, "Created shuttle with dir [port.dir], width [port.width], height [port.height], dwidth [port.dwidth], dheight [port.dheight]") - return TRUE - -//Go through all the all_turfs and check which direction doesn't have the shuttle -/obj/item/shuttle_creator/proc/getNonShuttleDirection(turf/targetTurf) - var/position = null - if(!(get_offset_target_turf(targetTurf, 0, 1) in loggedTurfs)) - if(position != null) - return null - position = NORTH - if(!(get_offset_target_turf(targetTurf, 0, -1) in loggedTurfs)) - if(position != null) - return null - position = SOUTH - if(!(get_offset_target_turf(targetTurf, 1, 0) in loggedTurfs)) - if(position != null) - return null - position = EAST - if(!(get_offset_target_turf(targetTurf, -1, 0) in loggedTurfs)) - if(position != null) - return null - position = WEST - to_chat(usr, "Direction to space is [position]") - return position - -/obj/item/shuttle_creator/proc/invertDir(var/input_dir) - if(input_dir == NORTH) - return SOUTH - else if(input_dir == SOUTH) - return NORTH - else if(input_dir == EAST) - return WEST - else if(input_dir == WEST) - return EAST - return null - -/obj/item/shuttle_creator/proc/shuttle_create_docking_port(atom/target, mob/user) - - if(loggedTurfs.len == 0 || !recorded_shuttle_area) - to_chat(user, "Invalid shuttle, restarting bluespace systems...") - return FALSE - - var/datum/map_template/shuttle/new_shuttle = new /datum/map_template/shuttle() - - var/obj/docking_port/mobile/port = new /obj/docking_port/mobile(get_turf(target)) - var/obj/docking_port/stationary/stationary_port = new /obj/docking_port/stationary(get_turf(target)) - port.callTime = 50 - port.dir = 1 //Point away from space. - port.id = "custom_[GLOB.custom_shuttle_count]" - linkedShuttleId = port.id - port.ignitionTime = 25 - port.name = "Custom Shuttle" - port.port_direction = 2 - port.preferred_direction = 4 - port.area_type = recorded_shuttle_area - - var/portDirection = getNonShuttleDirection(get_turf(port)) - var/invertedDir = invertDir(portDirection) - if(!portDirection || !invertedDir) - to_chat(usr, "Shuttle creation aborted, docking airlock must be on an external wall. Please select a new airlock.") - port.Destroy() - stationary_port.Destroy() - linkedShuttleId = null - return FALSE - port.dir = invertedDir - port.port_direction = portDirection - - if(!calculate_bounds(port)) - to_chat(usr, "Bluespace calculations failed, please select a new airlock.") - port.Destroy() - stationary_port.Destroy() - linkedShuttleId = null - return FALSE - - port.shuttle_areas = list() - //var/list/all_turfs = port.return_ordered_turfs(port.x, port.y, port.z, port.dir) - var/list/all_turfs = loggedTurfs - for(var/i in 1 to all_turfs.len) - var/turf/curT = all_turfs[i] - var/area/cur_area = curT.loc - //Add the area to the shuttle <3 - if(istype(cur_area, recorded_shuttle_area)) - if(istype(curT, /turf/open/space)) - continue - if(length(curT.baseturfs) < 2) - continue - //Add the shuttle base shit to the shuttle - curT.baseturfs.Insert(3, /turf/baseturf_skipover/shuttle) - port.shuttle_areas[cur_area] = TRUE - - port.linkup(new_shuttle, stationary_port) - - port.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0) - port.initiate_docking(stationary_port) - - port.mode = SHUTTLE_IDLE - port.timer = 0 - - port.register() - GLOB.custom_shuttle_count ++ - message_admins("[ADMIN_LOOKUPFLW(user)] created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") - log_game("[key_name(user)] created a new shuttle with a [src] at [AREACOORD(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") - return TRUE - -/obj/item/shuttle_creator/proc/create_shuttle_area(mob/user) - if(!loggedTurfs) - return FALSE - //Create the new area - var/area/shuttle/custom/powered/newS - var/area/oldA = loggedOldArea - var/str = stripped_input(user, "Shuttle Name:", "Blueprint Editing", "", MAX_NAME_LEN) - if(!str || !length(str)) - return FALSE - if(length(str) > 50) - to_chat(user, "The provided ship name is too long, blares the [src]") - return FALSE -/* - if(OOC_FILTER_CHECK(str)) - to_chat(user, "Nanotrasen prohibited words are in use in this shuttle name, blares the [src] in a slightly offended tone.") - return FALSE -*/ - newS = new /area/shuttle/custom/powered() - newS.setup(str) - newS.set_dynamic_lighting() - //Shuttles always have gravity - newS.has_gravity = TRUE - newS.requires_power = TRUE - //Record the area for use when creating the docking port - recorded_shuttle_area = newS - - for(var/i in 1 to loggedTurfs.len) - var/turf/turf_holder = loggedTurfs[i] - var/area/old_area = turf_holder.loc - newS.contents += turf_holder - turf_holder.change_area(old_area, newS) - - newS.reg_in_areas_in_z() - - var/list/firedoors = oldA.firedoors - for(var/door in firedoors) - var/obj/machinery/door/firedoor/FD = door - FD.CalculateAffectingAreas() - return TRUE - -/obj/item/shuttle_creator/proc/check_current_area(mob/user) - var/static/area_or_turf_fail_types = typecacheof(list( - /turf/open/space, - /area/shuttle - )) - //Check to see if the user can make a new area to prevent spamming - if(user) - if(user.create_area_cooldown >= world.time) - to_chat(user, "Smoke vents from the [src], maybe you should let it cooldown before using it again.") - return - user.create_area_cooldown = world.time + 10 - //Detect the turfs connected in the curerrent enclosed area - var/list/turfs = detect_room(get_turf(user), area_or_turf_fail_types) - if(!turfs) - to_chat(user, "Shuttles must be created in an airtight space, ensure that the shuttle is airtight, including corners.") - return - if(turfs.len > SHUTTLE_CREATOR_MAX_SIZE) - to_chat(user, "The [src]'s internal cooling system wizzes violently and a message appears on the screen, \"Caution, this device can only handle the creation of shuttles up to [SHUTTLE_CREATOR_MAX_SIZE] units in size. Please reduce your shuttle by [turfs.len-SHUTTLE_CREATOR_MAX_SIZE]. Sorry for the inconvinience\"") - return - //Check to see if it's a valid shuttle - for(var/i in 1 to turfs.len) - var/area/space/place = get_area(turfs[i]) - //If any of the turfs are on station / not in space, a shuttle cannot be forced there - if(!place) - to_chat(user, "You can't seem to overpower the bluespace harmonics in this location, try somewhere else.") - return - if(!istype(place, /area/space)) - to_chat(user, "Caution, shuttle must not use any material connected to the station. Your shuttle is currenly overlapping with [place.name]") - return - - loggedOldArea = get_area(get_turf(user)) - loggedTurfs = turfs - icon_state = "rsd_used" - to_chat(user, "Your current area was logged into the [src], select an airlock to act as the docking point.") diff --git a/code/game/objects/items/shuttle_upgrades.dm b/code/game/objects/items/shuttle_upgrades.dm index c64f643b6dc7..e69de29bb2d1 100644 --- a/code/game/objects/items/shuttle_upgrades.dm +++ b/code/game/objects/items/shuttle_upgrades.dm @@ -1,39 +0,0 @@ -/obj/item/shuttle_route_optimisation - name = "Route Optimisation Upgrade" - desc = "Used on a custom shuttle control console to calculate more efficient routes." - icon = 'icons/obj/module.dmi' - icon_state = "shuttledisk" - force = 0 - throwforce = 8 - throw_speed = 3 - throw_range = 5 - density = FALSE - anchored = FALSE - item_flags = NOBLUDGEON - var/upgrade_amount = 0.8 - -/obj/item/shuttle_route_optimisation/hyperlane - name = "Bluespace Hyperlane Calculator" - desc = "Used on a custom shuttle control console to allow for the following of bluespace hyperlanes, increasing the efficiency of the shuttle." - icon_state = "shuttledisk_better" - upgrade_amount = 0.6 - -/obj/item/shuttle_route_optimisation/void - name = "Voidspace Route Calculator" - desc = "Used on a custom shuttle control console to allow it to navigate into voidspace, making the routes almost instant." - icon_state = "shuttledisk_void" - upgrade_amount = 0.2 - -/obj/item/shuttle_route_optimisation/attack_obj(obj/O, mob/living/user) - . = ..() - if(!istype(O, /obj/machinery/computer)) - return - if(!istype(O, /obj/machinery/computer/custom_shuttle)) - to_chat(user, "This upgrade only works on a custom shuttle flight console.") - return - if (!user.transferItemToLoc(src, get_turf(O))) - return - var/obj/machinery/computer/custom_shuttle/link_comp = O - link_comp.distance_multiplier = clamp(link_comp.distance_multiplier, 0, upgrade_amount) //I have no clue what clamp even does, but I think this should work - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - to_chat(usr, "You insert the disk into the flight computer, allowing for routes to be [upgrade_amount]x the original distance.") diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index cbcaf41caedf..7c9d76f727f4 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -229,7 +229,12 @@ name = "Shuttle Navigation Computer" desc = "Used to designate a precise transit location for private ships." lock_override = NONE - whitelist_turfs = list(/turf/open/space, /turf/open/lava) + whitelist_turfs = list(/turf/open/space, + /turf/open/lava, + /turf/open/floor/plating/beach, + /turf/open/floor/plating/ashplanet, + /turf/open/floor/plating/asteroid, + /turf/open/floor/plating/lavaland_baseturf) jumpto_ports = list("whiteship_home" = 1) view_range = 12 designate_time = 100 diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm new file mode 100644 index 000000000000..21663eceee87 --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -0,0 +1,371 @@ +#define SHUTTLE_CREATOR_MAX_SIZE CONFIG_GET(number/max_shuttle_size) +#define CUSTOM_SHUTTLE_LIMIT CONFIG_GET(number/max_shuttle_count) +#define CARDINAL_DIRECTIONS_X list(1, 0, -1, 0) +#define CARDINAL_DIRECTIONS_Y list(0, 1, 0, -1) + +GLOBAL_VAR_INIT(custom_shuttle_count, 0) //The amount of custom shuttles created to prevent creating hundreds +GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (Heaters, engines) + +//============ Shuttle Creator Object ============ +/obj/item/shuttle_creator + name = "Rapid Shuttle Designator" + icon = 'icons/obj/tools.dmi' + icon_state = "rsd" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + desc = "A device used to define the area required for custom ships. Uses bluespace crystals to create bluespace-capable ships." + density = FALSE + anchored = FALSE + flags_1 = CONDUCT_1 + item_flags = NOBLUDGEON + force = 0 + throwforce = 8 + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_NORMAL + req_access_txt = "11" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + resistance_flags = FIRE_PROOF + var/ready = TRUE + //pre-designation + var/override_max_shuttles = FALSE + var/obj/machinery/computer/camera_advanced/shuttle_creator/internal_shuttle_creator + //During designation + var/overwritten_area = /area/space + var/list/loggedTurfs = list() + var/loggedOldArea + var/recorded_shuttle_area + var/datum/shuttle_creator_overlay_holder/overlay_holder + //After designation + var/linkedShuttleId + +/obj/item/shuttle_creator/Initialize() + . = ..() + internal_shuttle_creator = new() + internal_shuttle_creator.owner_rsd = src + overlay_holder = new() + +/obj/item/shuttle_creator/Destroy() + . = ..() + if(internal_shuttle_creator) + internal_shuttle_creator.owner_rsd = null + QDEL_NULL(internal_shuttle_creator) + if(overlay_holder) + QDEL_NULL(overlay_holder) + +/obj/item/shuttle_creator/attack_self(mob/user) + ..() + if(linkedShuttleId) + return + if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT && !override_max_shuttles) + to_chat(user, "Too many shuttles have been created.") + message_admins("[ADMIN_FLW(user)] attempted to create a shuttle, however [CUSTOM_SHUTTLE_LIMIT] have already been created.") + return + if(!internal_shuttle_creator) + return + overlay_holder.add_client(user.client) + internal_shuttle_creator.attack_hand(user) + +/obj/item/shuttle_creator/afterattack(atom/target, mob/user, proximity_flag) + . = ..() + if(!ready) + to_chat(user, "You need to define a shuttle area first.") + return + if(!proximity_flag) + return + if(istype(target, /obj/machinery/computer/custom_shuttle)) + if(!linkedShuttleId) + to_chat(user, "Error, no defined shuttle linked to device") + return + var/obj/machinery/computer/custom_shuttle/console = target + console.linkShuttle(linkedShuttleId) + to_chat(user, "Console linked successfully!") + return + else if(istype(target, /obj/machinery/computer/camera_advanced/shuttle_docker/custom)) + if(!linkedShuttleId) + to_chat(user, "Error, no defined shuttle linked to device") + return + var/obj/machinery/computer/camera_advanced/shuttle_docker/custom/console = target + console.linkShuttle(linkedShuttleId) + to_chat(user, "Console linked successfully!") + return + to_chat(user, "The [src] bleeps. Select an airlock to create a docking port, or a valid machine to link.") + return + +//=========== shuttle designation actions ============ +/obj/item/shuttle_creator/proc/calculate_bounds(obj/docking_port/mobile/port) + if(!port || !istype(port, /obj/docking_port/mobile)) + return FALSE + //Heights is the distance away from the port + //width is the distance perpendicular to the port + var/minX = INFINITY + var/maxX = 0 + var/minY = INFINITY + var/maxY = 0 + for(var/turf/T in loggedTurfs) + minX = min(T.x, minX) + maxX = max(T.x, maxX) + minY = min(T.y, minY) + maxY = max(T.y, maxY) + //Make sure shuttle was actually found. + if(maxX == INFINITY || maxY == INFINITY) + return FALSE + minX-- + minY-- + var/width = maxX - minX + var/height = maxY - minY + var/offset_x = port.x - minX + var/offset_y = port.y - minY + switch(port.dir) //Source: code/datums/shuttles.dm line 77 (14/03/2020) :) + if(NORTH) + port.width = width + port.height = height + port.dwidth = offset_x - 1 + port.dheight = offset_y - 1 + if(EAST) + port.width = height + port.height = width + port.dwidth = height - offset_y + port.dheight = offset_x - 1 + if(SOUTH) + port.width = width + port.height = height + port.dwidth = width - offset_x + port.dheight = height - offset_y + if(WEST) + port.width = height + port.height = width + port.dwidth = offset_y - 1 + port.dheight = width - offset_x + return TRUE + +//Go through all the all_turfs and check which direction doesn't have the shuttle +/obj/item/shuttle_creator/proc/getNonShuttleDirection(turf/targetTurf) + var/position = null + if(!(get_offset_target_turf(targetTurf, 0, 1) in loggedTurfs)) + if(position != null) + return null + position = NORTH + if(!(get_offset_target_turf(targetTurf, 0, -1) in loggedTurfs)) + if(position != null) + return null + position = SOUTH + if(!(get_offset_target_turf(targetTurf, 1, 0) in loggedTurfs)) + if(position != null) + return null + position = EAST + if(!(get_offset_target_turf(targetTurf, -1, 0) in loggedTurfs)) + if(position != null) + return null + position = WEST + return position + +/obj/item/shuttle_creator/proc/invertDir(var/input_dir) + if(input_dir == NORTH) + return SOUTH + else if(input_dir == SOUTH) + return NORTH + else if(input_dir == EAST) + return WEST + else if(input_dir == WEST) + return EAST + return null + +/obj/item/shuttle_creator/proc/shuttle_create_docking_port(atom/target, mob/user) + + if(loggedTurfs.len == 0 || !recorded_shuttle_area) + to_chat(user, "Invalid shuttle, restarting bluespace systems...") + return FALSE + + var/datum/map_template/shuttle/new_shuttle = new /datum/map_template/shuttle() + + var/obj/docking_port/mobile/port = new /obj/docking_port/mobile(get_turf(target)) + var/obj/docking_port/stationary/stationary_port = new /obj/docking_port/stationary(get_turf(target)) + port.callTime = 50 + port.dir = 1 //Point away from space. + port.id = "custom_[GLOB.custom_shuttle_count]" + linkedShuttleId = port.id + port.ignitionTime = 25 + port.name = "Custom Shuttle" + port.port_direction = 2 + port.preferred_direction = 4 + port.area_type = recorded_shuttle_area + + var/portDirection = getNonShuttleDirection(get_turf(port)) + var/invertedDir = invertDir(portDirection) + if(!portDirection || !invertedDir) + to_chat(usr, "Shuttle creation aborted, docking airlock must be on an external wall. Please select a new airlock.") + port.Destroy() + stationary_port.Destroy() + linkedShuttleId = null + return FALSE + port.dir = invertedDir + port.port_direction = portDirection + + if(!calculate_bounds(port)) + to_chat(usr, "Bluespace calculations failed, please select a new airlock.") + port.Destroy() + stationary_port.Destroy() + linkedShuttleId = null + return FALSE + + port.shuttle_areas = list() + //var/list/all_turfs = port.return_ordered_turfs(port.x, port.y, port.z, port.dir) + var/list/all_turfs = loggedTurfs + for(var/i in 1 to all_turfs.len) + var/turf/curT = all_turfs[i] + var/area/cur_area = curT.loc + //Add the area to the shuttle <3 + if(istype(cur_area, recorded_shuttle_area)) + if(istype(curT, /turf/open/space)) + continue + if(length(curT.baseturfs) < 2) + continue + //Add the shuttle base shit to the shuttle + curT.baseturfs.Insert(3, /turf/baseturf_skipover/shuttle) + port.shuttle_areas[cur_area] = TRUE + + port.linkup(new_shuttle, stationary_port) + + port.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0) + port.initiate_docking(stationary_port) + + port.mode = SHUTTLE_IDLE + port.timer = 0 + + port.register() + + icon_state = "rsd_used" + + //Clear highlights + overlay_holder.clear_highlights() + GLOB.custom_shuttle_count ++ + message_admins("[ADMIN_LOOKUPFLW(user)] created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") + log_game("[key_name(user)] created a new shuttle with a [src] at [AREACOORD(user)] ([GLOB.custom_shuttle_count] custom shuttles, limit is [CUSTOM_SHUTTLE_LIMIT])") + return TRUE + +/obj/item/shuttle_creator/proc/create_shuttle_area(mob/user) + //Check to see if the user can make a new area to prevent spamming + if(user) + if(user.create_area_cooldown >= world.time) + to_chat(user, "Smoke vents from the [src], maybe you should let it cooldown before using it again.") + return FALSE + user.create_area_cooldown = world.time + 10 + if(!loggedTurfs) + return FALSE + //Create the new area + var/area/shuttle/custom/powered/newS + var/area/oldA = loggedOldArea + var/str = stripped_input(user, "Shuttle Name:", "Blueprint Editing", "", MAX_NAME_LEN) + if(!str || !length(str)) + return FALSE + if(length(str) > 50) + to_chat(user, "The provided ship name is too long, blares the [src]") + return FALSE +/* + if(OOC_FILTER_CHECK(str)) + to_chat(user, "Nanotrasen prohibited words are in use in this shuttle name, blares the [src] in a slightly offended tone.") + return FALSE +*/ + newS = new /area/shuttle/custom/powered() + newS.setup(str) + newS.set_dynamic_lighting() + //Shuttles always have gravity + newS.has_gravity = TRUE + newS.requires_power = TRUE + //Record the area for use when creating the docking port + recorded_shuttle_area = newS + + for(var/i in 1 to loggedTurfs.len) + var/turf/turf_holder = loggedTurfs[i] + var/area/old_area = turf_holder.loc + newS.contents += turf_holder + turf_holder.change_area(old_area, newS) + + newS.reg_in_areas_in_z() + + var/list/firedoors = oldA.firedoors + for(var/door in firedoors) + var/obj/machinery/door/firedoor/FD = door + FD.CalculateAffectingAreas() + return TRUE + +//Checks an area to ensure that the turfs provided are valid to be made into a shuttle +/obj/item/shuttle_creator/proc/check_area(list/turfs) + if(!turfs) + to_chat(usr, "Shuttles must be created in an airtight space, ensure that the shuttle is airtight, including corners.") + return FALSE + if(turfs.len > SHUTTLE_CREATOR_MAX_SIZE) + to_chat(usr, "The [src]'s internal cooling system wizzes violently and a message appears on the screen, \"Caution, this device can only handle the creation of shuttles up to [SHUTTLE_CREATOR_MAX_SIZE] units in size. Please reduce your shuttle by [turfs.len-SHUTTLE_CREATOR_MAX_SIZE]. Sorry for the inconvinience\"") + return FALSE + //Check to see if it's a valid shuttle + for(var/i in 1 to turfs.len) + var/area/place = get_area(turfs[i]) + //If any of the turfs are on station / not in space, a shuttle cannot be forced there + if(!place) + to_chat(usr, "You can't seem to overpower the bluespace harmonics in this location, try somewhere else.") + return FALSE + if(istype(place, /area/space)) + overwritten_area = /area/space + else if(istype(place, /area/lavaland/surface/outdoors)) + overwritten_area = /area/lavaland/surface/outdoors + else + to_chat(usr, "Caution, shuttle must not use any material connected to the station. Your shuttle is currenly overlapping with [place.name]") + return FALSE + //Finally, check to see if the area is actually attached + if(!LAZYLEN(loggedTurfs)) + return TRUE + for(var/turf/T in turfs) + if(turf_connected_to_saved_turfs(T)) + return TRUE + CHECK_TICK + to_chat(usr, "Caution, new areas of the shuttle must be connected to the other areas of the shuttle.") + return FALSE + +/obj/item/shuttle_creator/proc/turf_connected_to_saved_turfs(turf/T) + for(var/i in 1 to 4) + var/turf/adjacentT = get_offset_target_turf(T, CARDINAL_DIRECTIONS_X[i], CARDINAL_DIRECTIONS_Y[i]) + if(adjacentT in loggedTurfs) + return TRUE + return FALSE + +/obj/item/shuttle_creator/proc/turf_in_list(turf/T) + return loggedTurfs.Find(T) + +/obj/item/shuttle_creator/proc/add_single_turf(turf/T) + if(!check_area(list(T))) + return FALSE + loggedTurfs |= T + loggedOldArea = get_area(T) + overlay_holder.highlight_turf(T) + +/obj/item/shuttle_creator/proc/add_saved_area(mob/user) + var/static/area_or_turf_fail_types = typecacheof(list( + /turf/open/space, + /area/shuttle + )) + //Detect the turfs connected in the curerrent enclosed area + var/list/turfs = detect_room(get_turf(user), area_or_turf_fail_types) + if(!check_area(turfs)) + return FALSE + loggedOldArea = get_area(get_turf(user)) + loggedTurfs |= turfs + overlay_holder.highlight_area(turfs) + //TODO READD THIS SHIT: icon_state = "rsd_used" + to_chat(user, "You add the area into the buffer of the [src], you made add more areas or select an airlock to act as a docking port to complete the shuttle.") + return turfs + +/obj/item/shuttle_creator/proc/remove_single_turf(turf/T) + if(!turf_in_list(T)) + return + loggedTurfs -= T + loggedOldArea = get_area(T) + overlay_holder.unhighlight_turf(T) + +/obj/item/shuttle_creator/proc/reset_saved_area() + overlay_holder.clear_highlights() + loggedTurfs.Cut() + to_chat(usr, "You reset the area buffer on the [src].") + +#undef CARDINAL_DIRECTIONS_X +#undef CARDINAL_DIRECTIONS_Y diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm new file mode 100644 index 000000000000..f50b3bf59f49 --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm @@ -0,0 +1,101 @@ +//============ Actions ============ +/datum/action/innate/shuttle_creator + icon_icon = 'icons/mob/actions/actions_shuttle.dmi' + var/mob/living/C + var/mob/camera/aiEye/remote/shuttle_creation/remote_eye + var/obj/item/shuttle_creator/shuttle_creator + +/datum/action/innate/shuttle_creator/Activate() + if(!target) + return TRUE + C = owner + remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/shuttle_creator/internal_console = target + shuttle_creator = internal_console.owner_rsd + +//Add an area +/datum/action/innate/shuttle_creator/designate_area + name = "Designate Room" + button_icon_state = "designate_area" + +/datum/action/innate/shuttle_creator/designate_area/Activate() + if(..()) + return + shuttle_creator.add_saved_area(remote_eye) + +//Add a single turf +/datum/action/innate/shuttle_creator/designate_turf + name = "Designate Turf" + button_icon_state = "designate_turf" + +/datum/action/innate/shuttle_creator/designate_turf/Activate() + if(..()) + return + var/turf/T = get_turf(remote_eye) + if(istype(T, /turf/open/space)) + var/connectors_exist = FALSE + for(var/obj/structure/lattice/lattice in T) + connectors_exist = TRUE + break + if(!connectors_exist) + to_chat(usr, "This turf requires support, build some catwalks or lattices.") + return + if(!shuttle_creator.check_area(list(T))) + return + if(shuttle_creator.turf_in_list(T)) + return + shuttle_creator.add_single_turf(T) + +//Clear a single entire area +/datum/action/innate/shuttle_creator/clear_turf + name = "Clear Turf" + button_icon_state = "clear_turf" + +/datum/action/innate/shuttle_creator/clear_turf/Activate() + if(..()) + return + shuttle_creator.remove_single_turf(get_turf(remote_eye)) + +//Clear the entire area +/datum/action/innate/shuttle_creator/reset + name = "Reset Buffer" + button_icon_state = "clear_area" + +/datum/action/innate/shuttle_creator/reset/Activate() + if(..()) + return + shuttle_creator.reset_saved_area() + +//Finish the shuttle +/datum/action/innate/shuttle_creator/airlock + name = "Select Docking Airlock" + button_icon_state = "select_airlock" + +/datum/action/innate/shuttle_creator/airlock/Activate() + if(..()) + return + var/turf/T = get_turf(remote_eye) + for(var/obj/machinery/door/airlock/A in T) + if(get_area(A) != shuttle_creator.loggedOldArea) + to_chat(C, "Caution, airlock must be on the shuttle to function as a dock.") + return + if(shuttle_creator.linkedShuttleId) + return + if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) + to_chat(C, "Shuttle limit reached, sorry.") + return + if(shuttle_creator.loggedTurfs.len > SHUTTLE_CREATOR_MAX_SIZE) + to_chat(C, "This shuttle is too large!") + return + if(!shuttle_creator.getNonShuttleDirection(T)) + to_chat(C, "Docking port must be on an external wall, with only 1 side exposed to space.") + return + if(!shuttle_creator.create_shuttle_area(C)) + return + if(shuttle_creator.shuttle_create_docking_port(A, C)) + to_chat(C, "Shuttle created!") + //Remove eye control + var/obj/machinery/computer/camera_advanced/shuttle_creator/internal_console = target + internal_console.remove_eye_control() + qdel(internal_console) + return diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm new file mode 100644 index 000000000000..6945c934279f --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm @@ -0,0 +1,93 @@ +//============The internal camera console used for designating the area============= +/obj/machinery/computer/camera_advanced/shuttle_creator + name = "internal shuttle creator console" + desc = "You should not have access to this, please report this as a bug" + networks = list() + var/obj/item/shuttle_creator/owner_rsd + var/datum/action/innate/shuttle_creator/designate_area/area_action = new + var/datum/action/innate/shuttle_creator/designate_turf/turf_action = new + var/datum/action/innate/shuttle_creator/clear_turf/clear_turf_action = new + var/datum/action/innate/shuttle_creator/reset/reset_action = new + var/datum/action/innate/shuttle_creator/airlock/airlock_action = new + +/obj/machinery/computer/camera_advanced/shuttle_creator/check_eye(mob/user) + if(user.eye_blind || user.incapacitated()) + user.unset_machine() + +/obj/machinery/computer/camera_advanced/shuttle_creator/CreateEye() + eyeobj = new /mob/camera/aiEye/remote/shuttle_creation(get_turf(owner_rsd)) + eyeobj.origin = src + eyeobj.use_static = USE_STATIC_NONE + +/obj/machinery/computer/camera_advanced/shuttle_creator/is_operational() + return TRUE + +/obj/machinery/computer/camera_advanced/shuttle_creator/can_interact(mob/user) + if(!isliving(user)) + return FALSE + var/mob/living/L = user + if(L.incapacitated()) + return FALSE + return TRUE + +/obj/machinery/computer/camera_advanced/shuttle_creator/GrantActions(mob/living/user) + ..(user) + eyeobj.invisibility = SEE_INVISIBLE_LIVING + if(area_action) + area_action.target = src + area_action.Grant(user) + actions += area_action + if(turf_action) + turf_action.target = src + turf_action.Grant(user) + actions += turf_action + if(clear_turf_action) + clear_turf_action.target = src + clear_turf_action.Grant(user) + actions += clear_turf_action + if(reset_action) + reset_action.target = src + reset_action.Grant(user) + actions += reset_action + if(airlock_action) + airlock_action.target = src + airlock_action.Grant(user) + actions += airlock_action + +/obj/machinery/computer/camera_advanced/shuttle_creator/remove_eye_control(mob/living/user) + . = ..() + owner_rsd.overlay_holder.remove_client() + eyeobj.invisibility = INVISIBILITY_MAXIMUM + if(user.client) + user.client.images -= eyeobj.user_image + +/obj/machinery/computer/camera_advanced/shuttle_creator/attack_hand(mob/user) + if(!is_operational()) //you cant use broken machine you chumbis + return + if(current_user) + to_chat(user, "The console is already in use!") + return + var/mob/living/L = user + if(!can_use(user)) + return + if(!eyeobj) + CreateEye() + if(!eyeobj.eye_initialized) + var/camera_location = get_turf(owner_rsd) + if(camera_location) + eyeobj.eye_initialized = TRUE + give_eye_control(L) + eyeobj.setLoc(camera_location) + var/mob/camera/aiEye/remote/shuttle_creation/shuttle_eye = eyeobj + shuttle_eye.source_turf = get_turf(user) + else + user.unset_machine() + else + var/camera_location = get_turf(owner_rsd) + var/mob/camera/aiEye/remote/shuttle_creation/eye = eyeobj + give_eye_control(L) + if(camera_location) + eye.source_turf = camera_location + eyeobj.setLoc(camera_location) + else + eyeobj.setLoc(eyeobj.loc) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm new file mode 100644 index 000000000000..a6cc73cd2f38 --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm @@ -0,0 +1,54 @@ +//===============Camera Eye================ +/mob/camera/aiEye/remote/shuttle_creation + name = "shuttle holo-drone" + icon = 'icons/obj/tools.dmi' + icon_state = "shuttle_drone" + visible_icon = FALSE + acceleration = 0 + var/turf/source_turf + var/max_range = 12 + +/mob/camera/aiEye/remote/shuttle_creation/Initialize() + . = ..() + setLoc(get_turf(source_turf)) + +/mob/camera/aiEye/remote/shuttle_creation/update_remote_sight(mob/living/user) + user.sight = BLIND|SEE_TURFS + user.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + user.sync_lighting_plane_alpha() + return TRUE + +/mob/camera/aiEye/remote/shuttle_creation/relaymove(mob/user, direct) + dir = direct //This camera eye is visible as a drone, and needs to keep the dir updated + var/initial = initial(sprint) + var/max_sprint = 50 + + if(cooldown && cooldown < world.timeofday) // 3 seconds + sprint = initial + + for(var/i = 0; i < max(sprint, initial); i += 20) + var/turf/step = get_turf(get_step(src, direct)) + if(step && can_move_to(step)) + setLoc(step) + + cooldown = world.timeofday + 5 + if(acceleration) + sprint = min(sprint + 0.5, max_sprint) + else + sprint = initial + +/mob/camera/aiEye/remote/shuttle_creation/proc/can_move_to(var/turf/T) + var/origin_x = source_turf.x + var/origin_y = source_turf.y + var/change_X = abs(origin_x - T.x) + var/change_Y = abs(origin_y - T.y) + return (change_X < max_range && change_Y < max_range) + +/mob/camera/aiEye/remote/shuttle_creation/setLoc(T) + ..() + if(eye_user?.client) + eye_user.client.images -= user_image + var/image/I = image(icon, loc, icon_state, FLY_LAYER, dir) + I.plane = MASSIVE_OBJ_LAYER + user_image = I + eye_user.client.images += user_image diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_overlay.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_overlay.dm new file mode 100644 index 000000000000..919b1f02211e --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_overlay.dm @@ -0,0 +1,52 @@ +/* + * Manages the overlays for the shuttle creator drone. +*/ + +/datum/shuttle_creator_overlay_holder + var/client/holder + var/list/images = list() + var/list/turfs = list() + +/datum/shuttle_creator_overlay_holder/proc/add_client(client/C) + holder = C + holder.images += images + +/datum/shuttle_creator_overlay_holder/proc/remove_client() + holder.images -= images + holder = null + +/datum/shuttle_creator_overlay_holder/proc/clear_highlights() + if(holder) + holder.images -= images + images.Cut() + turfs.Cut() + +/datum/shuttle_creator_overlay_holder/proc/create_hightlight(turf/T) + if(T in turfs) + return + var/image/I = image('icons/turf/overlays.dmi', T, "greenOverlay") + I.plane = ABOVE_LIGHTING_PLANE + images += I + holder.images += I + turfs += T + +/datum/shuttle_creator_overlay_holder/proc/remove_hightlight(turf/T) + if(!(T in turfs)) + return + turfs -= T + holder.images -= images + for(var/image/I in images) + if(get_turf(I) != T) + continue + images -= I + holder.images += images + +/datum/shuttle_creator_overlay_holder/proc/highlight_area(list/turfs) + for(var/turf/T in turfs) + highlight_turf(T) + +/datum/shuttle_creator_overlay_holder/proc/highlight_turf(turf/T) + create_hightlight(T) + +/datum/shuttle_creator_overlay_holder/proc/unhighlight_turf(turf/T) + remove_hightlight(T) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_upgrades.dm b/code/modules/shuttle/shuttle_creation/shuttle_upgrades.dm new file mode 100644 index 000000000000..c64f643b6dc7 --- /dev/null +++ b/code/modules/shuttle/shuttle_creation/shuttle_upgrades.dm @@ -0,0 +1,39 @@ +/obj/item/shuttle_route_optimisation + name = "Route Optimisation Upgrade" + desc = "Used on a custom shuttle control console to calculate more efficient routes." + icon = 'icons/obj/module.dmi' + icon_state = "shuttledisk" + force = 0 + throwforce = 8 + throw_speed = 3 + throw_range = 5 + density = FALSE + anchored = FALSE + item_flags = NOBLUDGEON + var/upgrade_amount = 0.8 + +/obj/item/shuttle_route_optimisation/hyperlane + name = "Bluespace Hyperlane Calculator" + desc = "Used on a custom shuttle control console to allow for the following of bluespace hyperlanes, increasing the efficiency of the shuttle." + icon_state = "shuttledisk_better" + upgrade_amount = 0.6 + +/obj/item/shuttle_route_optimisation/void + name = "Voidspace Route Calculator" + desc = "Used on a custom shuttle control console to allow it to navigate into voidspace, making the routes almost instant." + icon_state = "shuttledisk_void" + upgrade_amount = 0.2 + +/obj/item/shuttle_route_optimisation/attack_obj(obj/O, mob/living/user) + . = ..() + if(!istype(O, /obj/machinery/computer)) + return + if(!istype(O, /obj/machinery/computer/custom_shuttle)) + to_chat(user, "This upgrade only works on a custom shuttle flight console.") + return + if (!user.transferItemToLoc(src, get_turf(O))) + return + var/obj/machinery/computer/custom_shuttle/link_comp = O + link_comp.distance_multiplier = clamp(link_comp.distance_multiplier, 0, upgrade_amount) //I have no clue what clamp even does, but I think this should work + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + to_chat(usr, "You insert the disk into the flight computer, allowing for routes to be [upgrade_amount]x the original distance.") diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index f232e01217cd28e8611fc153cd399bc7e64e7723..8a0c20a9520ecedec4fda7edca7ed19ae1d4780a 100644 GIT binary patch delta 7054 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 From d7b934c7097de5366a12ae50412057da874a2ef2 Mon Sep 17 00:00:00 2001 From: nmajask Date: Tue, 27 Jul 2021 18:21:02 -0400 Subject: [PATCH 03/16] Should fix some stuff - Removed some unused files - Fixed a change to a random file --- code/game/machinery/shuttle/custom_shuttle.dm | 33 ----- code/game/machinery/shuttle/shuttle_engine.dm | 138 ------------------ code/game/machinery/shuttle/shuttle_heater.dm | 134 ----------------- code/modules/mob/dead/observer/observer.dm | 1 - 4 files changed, 306 deletions(-) delete mode 100644 code/game/machinery/shuttle/custom_shuttle.dm delete mode 100644 code/game/machinery/shuttle/shuttle_engine.dm delete mode 100644 code/game/machinery/shuttle/shuttle_heater.dm diff --git a/code/game/machinery/shuttle/custom_shuttle.dm b/code/game/machinery/shuttle/custom_shuttle.dm deleted file mode 100644 index 7c83cade69f3..000000000000 --- a/code/game/machinery/shuttle/custom_shuttle.dm +++ /dev/null @@ -1,33 +0,0 @@ -/obj/machinery/shuttle - name = "shuttle component" - desc = "Something for shuttles." - density = TRUE - obj_integrity = 250 - max_integrity = 250 - icon = 'icons/turf/shuttle.dmi' - icon_state = "burst_plasma" - idle_power_usage = 150 - circuit = /obj/item/circuitboard/machine/shuttle/engine - var/icon_state_closed = "burst_plasma" - var/icon_state_open = "burst_plasma_open" - var/icon_state_off = "burst_plasma_off" - -/obj/machinery/shuttle/Initialize() - . = ..() - GLOB.custom_shuttle_machines += src - -/obj/machinery/shuttle/Destroy() - . = ..() - GLOB.custom_shuttle_machines -= src - -/obj/machinery/shuttle/attackby(obj/item/I, mob/living/user, params) - if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) - return - if(default_pry_open(I)) - return - if(panel_open) - if(default_change_direction_wrench(user, I)) - return - if(default_deconstruction_crowbar(I)) - return - return ..() diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm deleted file mode 100644 index e3cdec77b6e2..000000000000 --- a/code/game/machinery/shuttle/shuttle_engine.dm +++ /dev/null @@ -1,138 +0,0 @@ -//----------------------------------------------- -//-------------Engine Thrusters------------------ -//----------------------------------------------- - -#define ENGINE_HEAT_TARGET 600 -#define ENGINE_HEATING_POWER 5000000 - -/obj/machinery/shuttle/engine - name = "shuttle thruster" - desc = "A thruster for shuttles." - density = TRUE - obj_integrity = 250 - max_integrity = 250 - icon = 'icons/turf/shuttle.dmi' - icon_state = "burst_plasma" - idle_power_usage = 150 - circuit = /obj/item/circuitboard/machine/shuttle/engine - var/thrust = 0 - var/fuel_use = 0 - var/bluespace_capable = TRUE - var/cooldown = 0 - var/thruster_active = FALSE - var/datum/weakref/attached_heater - -/obj/machinery/shuttle/engine/plasma - name = "plasma thruster" - desc = "A thruster that burns plasma stored in an adjacent plasma thruster heater." - icon_state = "burst_plasma" - icon_state_off = "burst_plasma_off" - - idle_power_usage = 0 - circuit = /obj/item/circuitboard/machine/shuttle/engine/plasma - thrust = 25 - fuel_use = 0.24 - bluespace_capable = FALSE - cooldown = 45 - -/obj/machinery/shuttle/engine/void - name = "void thruster" - desc = "A thruster using technology to breach voidspace for propulsion." - icon_state = "burst_void" - icon_state_off = "burst_void" - icon_state_closed = "burst_void" - icon_state_open = "burst_void_open" - idle_power_usage = 0 - circuit = /obj/item/circuitboard/machine/shuttle/engine/void - thrust = 400 - fuel_use = 0 - bluespace_capable = TRUE - cooldown = 90 - -/obj/machinery/shuttle/engine/Initialize() - . = ..() - check_setup() - -/obj/machinery/shuttle/engine/on_construction() - . = ..() - check_setup() - -/obj/machinery/shuttle/engine/proc/check_setup() - var/heater_turf - switch(dir) - if(NORTH) - heater_turf = get_offset_target_turf(src, 0, 1) - if(SOUTH) - heater_turf = get_offset_target_turf(src, 0, -1) - if(EAST) - heater_turf = get_offset_target_turf(src, 1, 0) - if(WEST) - heater_turf = get_offset_target_turf(src, -1, 0) - if(!heater_turf) - attached_heater = null - update_engine() - return - attached_heater = null - for(var/obj/machinery/atmospherics/components/unary/shuttle/heater/as_heater in heater_turf) - if(as_heater.dir != dir) - continue - if(as_heater.panel_open) - continue - if(!as_heater.anchored) - continue - attached_heater = WEAKREF(as_heater) - break - update_engine() - return - -/obj/machinery/shuttle/engine/proc/update_engine() - if(!attached_heater) - icon_state = icon_state_off - thruster_active = FALSE - return - var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolved_heater = attached_heater.resolve() - if(panel_open) - thruster_active = FALSE - else if(resolved_heater?.hasFuel(1)) - icon_state = icon_state_closed - thruster_active = TRUE - else - thruster_active = FALSE - icon_state = icon_state_off - return - -/obj/machinery/shuttle/engine/void/update_engine() - if(panel_open) - thruster_active = FALSE - return - thruster_active = TRUE - icon_state = icon_state_closed - return - -//Thanks to spaceheater.dm for inspiration :) -/obj/machinery/shuttle/engine/proc/fireEngine() - var/turf/heatTurf = loc - if(!heatTurf) - return - var/datum/gas_mixture/env = heatTurf.return_air() - var/heat_cap = env.heat_capacity() - var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap - req_power = min(req_power, ENGINE_HEATING_POWER) - var/deltaTemperature = req_power / heat_cap - if(deltaTemperature < 0) - return - env.set_temperature(env.return_temperature() + deltaTemperature) - air_update_turf() - -/obj/machinery/shuttle/engine/attackby(obj/item/I, mob/living/user, params) - check_setup() - if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) - return - if(default_pry_open(I)) - return - if(panel_open) - if(default_change_direction_wrench(user, I)) - return - if(default_deconstruction_crowbar(I)) - return - return ..() diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm deleted file mode 100644 index 80c46fde7374..000000000000 --- a/code/game/machinery/shuttle/shuttle_heater.dm +++ /dev/null @@ -1,134 +0,0 @@ -//----------------------------------------------- -//--------------Engine Heaters------------------- -//This uses atmospherics, much like a thermomachine, -//but instead of changing temp, it stores plasma and uses -//it for the engine. -//----------------------------------------------- -/obj/machinery/atmospherics/components/unary/shuttle - name = "shuttle atmospherics device" - desc = "This does something to do with shuttle atmospherics" - icon_state = "heater" - icon = 'icons/turf/shuttle.dmi' - -/obj/machinery/atmospherics/components/unary/shuttle/heater - name = "engine heater" - desc = "Directs energy into compressed particles in order to power an attached thruster." - icon_state = "heater_pipe" - var/icon_state_closed = "heater_pipe" - var/icon_state_open = "heater_pipe_open" - var/icon_state_off = "heater_pipe" - idle_power_usage = 50 - circuit = /obj/item/circuitboard/machine/shuttle/heater - - density = TRUE - max_integrity = 400 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30) - layer = OBJ_LAYER - showpipe = TRUE - - pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY - - var/gas_type = /datum/gas/plasma - var/efficiency_multiplier = 1 - var/gas_capacity = 0 - -/obj/machinery/atmospherics/components/unary/shuttle/heater/New() - . = ..() - GLOB.custom_shuttle_machines += src - SetInitDirections() - update_adjacent_engines() - updateGasStats() - -/obj/machinery/atmospherics/components/unary/shuttle/heater/Destroy() - . = ..() - update_adjacent_engines() - GLOB.custom_shuttle_machines -= src - -/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction() - ..(dir, dir) - SetInitDirections() - update_adjacent_engines() - -/obj/machinery/atmospherics/components/unary/shuttle/heater/default_change_direction_wrench(mob/user, obj/item/I) - if(!..()) - return FALSE - SetInitDirections() - var/obj/machinery/atmospherics/node = nodes[1] - if(node) - node.disconnect(src) - nodes[1] = null - if(!parents[1]) - return - nullifyPipenet(parents[1]) - - atmosinit() - node = nodes[1] - if(node) - node.atmosinit() - node.addMember(src) - build_network() - return TRUE - -/obj/machinery/atmospherics/components/unary/shuttle/heater/RefreshParts() - var/cap = 0 - var/eff = 0 - for(var/obj/item/stock_parts/matter_bin/M in component_parts) - cap += M.rating - for(var/obj/item/stock_parts/micro_laser/L in component_parts) - eff += L.rating - gas_capacity = 5000 * ((cap - 1) ** 2) + 1000 - efficiency_multiplier = round(((eff / 2) / 2.8) ** 2, 0.1) - updateGasStats() - -/obj/machinery/atmospherics/components/unary/shuttle/heater/examine(mob/user) - . = ..() - var/datum/gas_mixture/air_contents = airs[1] - . += "The engine heater's gas dial reads [air_contents.get_moles(gas_type)] moles of gas.
" //This probably has issues [air_contents.get_moles] - -/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/updateGasStats() - var/datum/gas_mixture/air_contents = airs[1] - if(!air_contents) - return - air_contents.set_volume(gas_capacity) - air_contents.set_temperature(T20C) - if(gas_type) - air_contents.set_moles(gas_type) - -/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required) - var/datum/gas_mixture/air_contents = airs[1] - var/moles = air_contents.total_moles() - return moles >= required - -/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/consumeFuel(var/amount) - var/datum/gas_mixture/air_contents = airs[1] - air_contents.remove(amount) - return - -/obj/machinery/atmospherics/components/unary/shuttle/heater/attackby(obj/item/I, mob/living/user, params) - update_adjacent_engines() - if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) - return - if(default_pry_open(I)) - return - if(panel_open) - if(default_change_direction_wrench(user, I)) - return - if(default_deconstruction_crowbar(I)) - return - return ..() - -/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/update_adjacent_engines() - var/engine_turf - switch(dir) - if(NORTH) - engine_turf = get_offset_target_turf(src, 0, -1) - if(SOUTH) - engine_turf = get_offset_target_turf(src, 0, 1) - if(EAST) - engine_turf = get_offset_target_turf(src, -1, 0) - if(WEST) - engine_turf = get_offset_target_turf(src, 1, 0) - if(!engine_turf) - return - for(var/obj/machinery/shuttle/engine/E in engine_turf) - E.check_setup() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index c00f1b7607cf..8ec3522e686f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -273,7 +273,6 @@ Works together with spawning an observer, noted above. stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now if(can_reenter_corpse && client) //yogs start oobe_client = client //yogs end - onGhost() var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse From 77c5be1b783ebbbd2249d72762108984d0c5e4e0 Mon Sep 17 00:00:00 2001 From: nmajask Date: Tue, 27 Jul 2021 18:35:21 -0400 Subject: [PATCH 04/16] Should fix more stuff - Added some more important files - Added the icons I forgot to add --- code/game/machinery/shuttle/custom_shuttle.dm | 33 +++++ code/game/machinery/shuttle/shuttle_engine.dm | 138 ++++++++++++++++++ code/game/machinery/shuttle/shuttle_heater.dm | 134 +++++++++++++++++ icons/mob/actions/actions_shuttle.dmi | Bin 0 -> 4028 bytes icons/obj/module.dmi | Bin 18978 -> 19954 bytes icons/obj/tools.dmi | Bin 26656 -> 25264 bytes 6 files changed, 305 insertions(+) create mode 100644 code/game/machinery/shuttle/custom_shuttle.dm create mode 100644 code/game/machinery/shuttle/shuttle_engine.dm create mode 100644 code/game/machinery/shuttle/shuttle_heater.dm create mode 100644 icons/mob/actions/actions_shuttle.dmi diff --git a/code/game/machinery/shuttle/custom_shuttle.dm b/code/game/machinery/shuttle/custom_shuttle.dm new file mode 100644 index 000000000000..7c83cade69f3 --- /dev/null +++ b/code/game/machinery/shuttle/custom_shuttle.dm @@ -0,0 +1,33 @@ +/obj/machinery/shuttle + name = "shuttle component" + desc = "Something for shuttles." + density = TRUE + obj_integrity = 250 + max_integrity = 250 + icon = 'icons/turf/shuttle.dmi' + icon_state = "burst_plasma" + idle_power_usage = 150 + circuit = /obj/item/circuitboard/machine/shuttle/engine + var/icon_state_closed = "burst_plasma" + var/icon_state_open = "burst_plasma_open" + var/icon_state_off = "burst_plasma_off" + +/obj/machinery/shuttle/Initialize() + . = ..() + GLOB.custom_shuttle_machines += src + +/obj/machinery/shuttle/Destroy() + . = ..() + GLOB.custom_shuttle_machines -= src + +/obj/machinery/shuttle/attackby(obj/item/I, mob/living/user, params) + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm new file mode 100644 index 000000000000..e3cdec77b6e2 --- /dev/null +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -0,0 +1,138 @@ +//----------------------------------------------- +//-------------Engine Thrusters------------------ +//----------------------------------------------- + +#define ENGINE_HEAT_TARGET 600 +#define ENGINE_HEATING_POWER 5000000 + +/obj/machinery/shuttle/engine + name = "shuttle thruster" + desc = "A thruster for shuttles." + density = TRUE + obj_integrity = 250 + max_integrity = 250 + icon = 'icons/turf/shuttle.dmi' + icon_state = "burst_plasma" + idle_power_usage = 150 + circuit = /obj/item/circuitboard/machine/shuttle/engine + var/thrust = 0 + var/fuel_use = 0 + var/bluespace_capable = TRUE + var/cooldown = 0 + var/thruster_active = FALSE + var/datum/weakref/attached_heater + +/obj/machinery/shuttle/engine/plasma + name = "plasma thruster" + desc = "A thruster that burns plasma stored in an adjacent plasma thruster heater." + icon_state = "burst_plasma" + icon_state_off = "burst_plasma_off" + + idle_power_usage = 0 + circuit = /obj/item/circuitboard/machine/shuttle/engine/plasma + thrust = 25 + fuel_use = 0.24 + bluespace_capable = FALSE + cooldown = 45 + +/obj/machinery/shuttle/engine/void + name = "void thruster" + desc = "A thruster using technology to breach voidspace for propulsion." + icon_state = "burst_void" + icon_state_off = "burst_void" + icon_state_closed = "burst_void" + icon_state_open = "burst_void_open" + idle_power_usage = 0 + circuit = /obj/item/circuitboard/machine/shuttle/engine/void + thrust = 400 + fuel_use = 0 + bluespace_capable = TRUE + cooldown = 90 + +/obj/machinery/shuttle/engine/Initialize() + . = ..() + check_setup() + +/obj/machinery/shuttle/engine/on_construction() + . = ..() + check_setup() + +/obj/machinery/shuttle/engine/proc/check_setup() + var/heater_turf + switch(dir) + if(NORTH) + heater_turf = get_offset_target_turf(src, 0, 1) + if(SOUTH) + heater_turf = get_offset_target_turf(src, 0, -1) + if(EAST) + heater_turf = get_offset_target_turf(src, 1, 0) + if(WEST) + heater_turf = get_offset_target_turf(src, -1, 0) + if(!heater_turf) + attached_heater = null + update_engine() + return + attached_heater = null + for(var/obj/machinery/atmospherics/components/unary/shuttle/heater/as_heater in heater_turf) + if(as_heater.dir != dir) + continue + if(as_heater.panel_open) + continue + if(!as_heater.anchored) + continue + attached_heater = WEAKREF(as_heater) + break + update_engine() + return + +/obj/machinery/shuttle/engine/proc/update_engine() + if(!attached_heater) + icon_state = icon_state_off + thruster_active = FALSE + return + var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolved_heater = attached_heater.resolve() + if(panel_open) + thruster_active = FALSE + else if(resolved_heater?.hasFuel(1)) + icon_state = icon_state_closed + thruster_active = TRUE + else + thruster_active = FALSE + icon_state = icon_state_off + return + +/obj/machinery/shuttle/engine/void/update_engine() + if(panel_open) + thruster_active = FALSE + return + thruster_active = TRUE + icon_state = icon_state_closed + return + +//Thanks to spaceheater.dm for inspiration :) +/obj/machinery/shuttle/engine/proc/fireEngine() + var/turf/heatTurf = loc + if(!heatTurf) + return + var/datum/gas_mixture/env = heatTurf.return_air() + var/heat_cap = env.heat_capacity() + var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap + req_power = min(req_power, ENGINE_HEATING_POWER) + var/deltaTemperature = req_power / heat_cap + if(deltaTemperature < 0) + return + env.set_temperature(env.return_temperature() + deltaTemperature) + air_update_turf() + +/obj/machinery/shuttle/engine/attackby(obj/item/I, mob/living/user, params) + check_setup() + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm new file mode 100644 index 000000000000..80c46fde7374 --- /dev/null +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -0,0 +1,134 @@ +//----------------------------------------------- +//--------------Engine Heaters------------------- +//This uses atmospherics, much like a thermomachine, +//but instead of changing temp, it stores plasma and uses +//it for the engine. +//----------------------------------------------- +/obj/machinery/atmospherics/components/unary/shuttle + name = "shuttle atmospherics device" + desc = "This does something to do with shuttle atmospherics" + icon_state = "heater" + icon = 'icons/turf/shuttle.dmi' + +/obj/machinery/atmospherics/components/unary/shuttle/heater + name = "engine heater" + desc = "Directs energy into compressed particles in order to power an attached thruster." + icon_state = "heater_pipe" + var/icon_state_closed = "heater_pipe" + var/icon_state_open = "heater_pipe_open" + var/icon_state_off = "heater_pipe" + idle_power_usage = 50 + circuit = /obj/item/circuitboard/machine/shuttle/heater + + density = TRUE + max_integrity = 400 + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30) + layer = OBJ_LAYER + showpipe = TRUE + + pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + + var/gas_type = /datum/gas/plasma + var/efficiency_multiplier = 1 + var/gas_capacity = 0 + +/obj/machinery/atmospherics/components/unary/shuttle/heater/New() + . = ..() + GLOB.custom_shuttle_machines += src + SetInitDirections() + update_adjacent_engines() + updateGasStats() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/Destroy() + . = ..() + update_adjacent_engines() + GLOB.custom_shuttle_machines -= src + +/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction() + ..(dir, dir) + SetInitDirections() + update_adjacent_engines() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/default_change_direction_wrench(mob/user, obj/item/I) + if(!..()) + return FALSE + SetInitDirections() + var/obj/machinery/atmospherics/node = nodes[1] + if(node) + node.disconnect(src) + nodes[1] = null + if(!parents[1]) + return + nullifyPipenet(parents[1]) + + atmosinit() + node = nodes[1] + if(node) + node.atmosinit() + node.addMember(src) + build_network() + return TRUE + +/obj/machinery/atmospherics/components/unary/shuttle/heater/RefreshParts() + var/cap = 0 + var/eff = 0 + for(var/obj/item/stock_parts/matter_bin/M in component_parts) + cap += M.rating + for(var/obj/item/stock_parts/micro_laser/L in component_parts) + eff += L.rating + gas_capacity = 5000 * ((cap - 1) ** 2) + 1000 + efficiency_multiplier = round(((eff / 2) / 2.8) ** 2, 0.1) + updateGasStats() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/examine(mob/user) + . = ..() + var/datum/gas_mixture/air_contents = airs[1] + . += "The engine heater's gas dial reads [air_contents.get_moles(gas_type)] moles of gas.
" //This probably has issues [air_contents.get_moles] + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/updateGasStats() + var/datum/gas_mixture/air_contents = airs[1] + if(!air_contents) + return + air_contents.set_volume(gas_capacity) + air_contents.set_temperature(T20C) + if(gas_type) + air_contents.set_moles(gas_type) + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required) + var/datum/gas_mixture/air_contents = airs[1] + var/moles = air_contents.total_moles() + return moles >= required + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/consumeFuel(var/amount) + var/datum/gas_mixture/air_contents = airs[1] + air_contents.remove(amount) + return + +/obj/machinery/atmospherics/components/unary/shuttle/heater/attackby(obj/item/I, mob/living/user, params) + update_adjacent_engines() + if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I)) + return + if(default_pry_open(I)) + return + if(panel_open) + if(default_change_direction_wrench(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + return ..() + +/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/update_adjacent_engines() + var/engine_turf + switch(dir) + if(NORTH) + engine_turf = get_offset_target_turf(src, 0, -1) + if(SOUTH) + engine_turf = get_offset_target_turf(src, 0, 1) + if(EAST) + engine_turf = get_offset_target_turf(src, -1, 0) + if(WEST) + engine_turf = get_offset_target_turf(src, 1, 0) + if(!engine_turf) + return + for(var/obj/machinery/shuttle/engine/E in engine_turf) + E.check_setup() diff --git a/icons/mob/actions/actions_shuttle.dmi b/icons/mob/actions/actions_shuttle.dmi new file mode 100644 index 0000000000000000000000000000000000000000..399f50941504776390a319835b29aec781dc5b90 GIT binary patch literal 4028 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 diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 8a0c20a9520ecedec4fda7edca7ed19ae1d4780a..9caa9228f5dfd89b750320b3ddad03e03027ad30 100644 GIT binary patch delta 5549 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 M)HTs*)OL#hKO(sbFaQ7m delta 6955 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 Date: Tue, 27 Jul 2021 18:46:16 -0400 Subject: [PATCH 05/16] Oh, I didn't update the dme - Should fix this, maybe? --- yogstation.dme | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/yogstation.dme b/yogstation.dme index bcd72c82f8b2..3755058bea13 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2911,6 +2911,12 @@ #include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\syndicate.dm" #include "code\modules\shuttle\white_ship.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_creator.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_creator_actions.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_creator_console.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_creator_eye.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_creator_overlay.dm" +#include "code\modules\shuttle\shuttle_creation\shuttle_upgrades.dm" #include "code\modules\spells\spell.dm" #include "code\modules\spells\spell_types\aimed.dm" #include "code\modules\spells\spell_types\area_teleport.dm" From 31e9c402c1d89064db572ba0870d89078b73289a Mon Sep 17 00:00:00 2001 From: nmajask Date: Tue, 27 Jul 2021 18:54:59 -0400 Subject: [PATCH 06/16] Probably should add the turf icons - Added the turf icons --- icons/turf/shuttle.dmi | Bin 45994 -> 57305 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/turf/shuttle.dmi b/icons/turf/shuttle.dmi index a09cb7a84737e03f854c10726e722725f6b859b8..7c96dcf1b4b4f74a22db0adf2342cf34c02b1286 100644 GIT binary patch literal 57305 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

7w(|-9uxc;?2 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ⅆ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 literal 45994 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

!c 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 Y@@wY(c#I*H;}CFZs_LkGQnCvBFNt<5X#fBK From 020aa4030fcc33f7721d5ade9bce7479491fbcec Mon Sep 17 00:00:00 2001 From: nmajask Date: Thu, 29 Jul 2021 01:57:45 -0400 Subject: [PATCH 07/16] Fixes the name filter One down, two to go - Fixes the name filter by using isnotpetty instead of OOC_FILTER_CHECK, now if you make a shuttle with a bad name, it will message the admins. --- code/modules/shuttle/shuttle_creation/shuttle_creator.dm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm index 21663eceee87..69de2a2d91ae 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -262,11 +262,13 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He if(length(str) > 50) to_chat(user, "The provided ship name is too long, blares the [src]") return FALSE -/* - if(OOC_FILTER_CHECK(str)) +//Yogs Start: Runs the name through the petty filter. If they trip it, it will cause the shuttle creation to fail, messages the admins, and put the RSD on cooldown. + if(isnotpretty(str)) to_chat(user, "Nanotrasen prohibited words are in use in this shuttle name, blares the [src] in a slightly offended tone.") + message_admins("[ADMIN_LOOKUPFLW(user)] attempted to created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)], but failed because of tripping a petty filter") + user.create_area_cooldown = world.time + 10 return FALSE -*/ +//Yogs End newS = new /area/shuttle/custom/powered() newS.setup(str) newS.set_dynamic_lighting() From a92ffab63359dc4109df3c8f0ff123afa9d31b42 Mon Sep 17 00:00:00 2001 From: nmajask Date: Wed, 4 Aug 2021 00:35:26 -0400 Subject: [PATCH 08/16] Fixes the tech web - Fixes the tech web - Adds the new icons for the RSD --- code/modules/research/techweb/layout.dm | 534 +++++++++--------- icons/obj/tools.dmi | Bin 25264 -> 24618 bytes .../modules/research/techweb/all_nodes.dm | 49 +- 3 files changed, 321 insertions(+), 262 deletions(-) diff --git a/code/modules/research/techweb/layout.dm b/code/modules/research/techweb/layout.dm index 13caacb682b4..a2e777139efe 100644 --- a/code/modules/research/techweb/layout.dm +++ b/code/modules/research/techweb/layout.dm @@ -8,505 +8,525 @@ // In addition, hovering over a node will show the coordinates if do_node_drag is set /datum/techweb_node/base - ui_x = 32 - ui_y = -128 + ui_x = 32 + ui_y = -128 /datum/techweb_node/mmi - ui_x = -32 - ui_y = 96 + ui_x = -32 + ui_y = 96 /datum/techweb_node/cyborg - ui_x = -96 - ui_y = 96 + ui_x = -96 + ui_y = 96 /datum/techweb_node/mech - ui_x = -448 - ui_y = 0 + ui_x = -448 + ui_y = 0 /datum/techweb_node/mech_tools - ui_x = -448 - ui_y = -64 + ui_x = -448 + ui_y = -64 /datum/techweb_node/basic_tools - ui_x = -96 - ui_y = -384 + ui_x = -96 + ui_y = -384 /datum/techweb_node/biotech - ui_x = 160 - ui_y = -128 + ui_x = 160 + ui_y = -128 /datum/techweb_node/datatheory - ui_x = 160 - ui_y = -256 + ui_x = 160 + ui_y = -256 /datum/techweb_node/engineering - ui_x = 32 - ui_y = -256 + ui_x = 32 + ui_y = -256 /datum/techweb_node/bluespace_basic - ui_x = -96 - ui_y = -192 + ui_x = -96 + ui_y = -192 /datum/techweb_node/robotics - ui_x = -160 - ui_y = 96 + ui_x = -160 + ui_y = 96 /datum/techweb_node/emp_basic - ui_x = -96 - ui_y = -128 + ui_x = -96 + ui_y = -128 /datum/techweb_node/clown - ui_x = 256 - ui_y = -576 + ui_x = 256 + ui_y = -576 /datum/techweb_node/sec_basic - ui_x = -512 - ui_y = -672 + ui_x = -512 + ui_y = -672 /datum/techweb_node/odysseus - ui_x = 352 - ui_y = -384 + ui_x = 352 + ui_y = -384 -/datum/techweb_node/spacepod_basic - ui_x = -160 - ui_y = -448 +/datum/techweb_node/spacevehicle_basic + ui_x = -32 + ui_y = -736 /datum/techweb_node/adv_biotech - ui_x = 288 - ui_y = -96 + ui_x = 288 + ui_y = -96 /datum/techweb_node/bio_process - ui_x = 224 - ui_y = -224 + ui_x = 224 + ui_y = -224 /datum/techweb_node/imp_wt_surgery - ui_x = 224 - ui_y = 64 + ui_x = 224 + ui_y = 64 /datum/techweb_node/neural_programming - ui_x = 544 - ui_y = -160 + ui_x = 544 + ui_y = -160 /datum/techweb_node/cloning - ui_x = 288 - ui_y = -256 + ui_x = 288 + ui_y = -256 /datum/techweb_node/cryotech - ui_x = 160 - ui_y = -192 + ui_x = 160 + ui_y = -192 /datum/techweb_node/subdermal_implants - ui_x = 288 - ui_y = -32 + ui_x = 288 + ui_y = -32 /datum/techweb_node/botany - ui_x = 320 - ui_y = -224 + ui_x = 320 + ui_y = -224 /datum/techweb_node/nanite_bio - ui_x = 480 - ui_y = -288 + ui_x = 480 + ui_y = -288 /datum/techweb_node/alientech - ui_x = 288 - ui_y = 320 + ui_x = 288 + ui_y = 320 /datum/techweb_node/high_efficiency - ui_x = -32 - ui_y = -320 + ui_x = -32 + ui_y = -320 /datum/techweb_node/comptech - ui_x = 192 - ui_y = -320 + ui_x = 192 + ui_y = -320 /datum/techweb_node/cyber_implants - ui_x = 352 - ui_y = -32 + ui_x = 352 + ui_y = -32 /datum/techweb_node/nanite_base - ui_x = 480 - ui_y = -224 + ui_x = 480 + ui_y = -224 /datum/techweb_node/adv_engi - ui_x = -32 - ui_y = -256 + ui_x = -32 + ui_y = -256 /datum/techweb_node/adv_power - ui_x = -128 - ui_y = -320 + ui_x = -128 + ui_y = -320 /datum/techweb_node/practical_bluespace - ui_x = -192 - ui_y = -224 + ui_x = -192 + ui_y = -224 /datum/techweb_node/basic_plasma - ui_x = 32 - ui_y = -320 + ui_x = 32 + ui_y = -320 /datum/techweb_node/cyborg_upg_util - ui_x = -96 - ui_y = 160 + ui_x = -96 + ui_y = 160 /datum/techweb_node/basic_mining - ui_x = 96 - ui_y = -384 + ui_x = 96 + ui_y = -384 /datum/techweb_node/weaponry - ui_x = -576 - ui_y = -416 + ui_x = -576 + ui_y = -416 /datum/techweb_node/smartmine - ui_x = -512 - ui_y = -800 + ui_x = -512 + ui_y = -800 /datum/techweb_node/nanite_mesh - ui_x = 416 - ui_y = -288 + ui_x = 416 + ui_y = -288 /datum/techweb_node/spacepod_lock - ui_x = -224 - ui_y = -448 + ui_x = 32 + ui_y = -768 /datum/techweb_node/telecomms - ui_x = 256 - ui_y = -320 + ui_x = 256 + ui_y = -320 /datum/techweb_node/adv_robotics - ui_x = -160 - ui_y = 160 + ui_x = -160 + ui_y = 160 /datum/techweb_node/ai - ui_x = 608 - ui_y = -96 + ui_x = 608 + ui_y = -96 /datum/techweb_node/emp_adv - ui_x = -160 - ui_y = -128 + ui_x = -160 + ui_y = -128 /datum/techweb_node/integrated_HUDs - ui_x = -96 - ui_y = -64 + ui_x = -96 + ui_y = -64 /datum/techweb_node/electric_weapons - ui_x = -480 - ui_y = -480 + ui_x = -480 + ui_y = -480 /datum/techweb_node/camera_theory - ui_x = 96 - ui_y = -320 + ui_x = 96 + ui_y = -320 /datum/techweb_node/landmine - ui_x = -512 - ui_y = -736 + ui_x = -512 + ui_y = -736 + +/datum/techweb_node/basic_shuttle_tech + ui_x = -96 + ui_y = -736 + +/datum/techweb_node/shuttle_route_upgrade + ui_x = -160 + ui_y = -736 /datum/techweb_node/spacepod_disabler - ui_x = -64 - ui_y = -576 + ui_x = 32 + ui_y = -704 /datum/techweb_node/spacepod_pseat - ui_x = -160 - ui_y = -512 - -/datum/techweb_node/xenology - ui_x = 480 - ui_y = -96 + ui_x = 32 + ui_y = -832 /datum/techweb_node/cyborg_upg_med - ui_x = 352 - ui_y = -160 - -/datum/techweb_node/cyborg_upg_surgkit - ui_x = 416 - ui_y = -160 + ui_x = 352 + ui_y = -160 /datum/techweb_node/cyber_organs - ui_x = 352 - ui_y = -96 + ui_x = 352 + ui_y = -96 /datum/techweb_node/medical_weapons - ui_x = -480 - ui_y = -544 + ui_x = -480 + ui_y = -544 /datum/techweb_node/med_mech_tools - ui_x = 288 - ui_y = -160 + ui_x = 288 + ui_y = -160 /datum/techweb_node/alien_bio - ui_x = 224 - ui_y = 256 + ui_x = 224 + ui_y = 256 /datum/techweb_node/adv_surgery - ui_x = 288 - ui_y = 64 + ui_x = 288 + ui_y = 64 /datum/techweb_node/posibrain - ui_x = 608 - ui_y = -160 + ui_x = 608 + ui_y = -160 /datum/techweb_node/adv_cyber_implants - ui_x = 416 - ui_y = -32 + ui_x = 416 + ui_y = -32 /datum/techweb_node/nanite_synaptic - ui_x = 576 - ui_y = -352 + ui_x = 576 + ui_y = -352 /datum/techweb_node/nanite_neural - ui_x = 512 - ui_y = -352 + ui_x = 512 + ui_y = -352 /datum/techweb_node/nanite_harmonic - ui_x = 448 - ui_y = -352 + ui_x = 448 + ui_y = -352 /datum/techweb_node/alien_surgery - ui_x = 352 - ui_y = 256 + ui_x = 352 + ui_y = 256 + +/datum/techweb_node/shuttle_route_upgrade_void + ui_x = 352 + ui_y = 320 /datum/techweb_node/nanite_hazard - ui_x = 288 - ui_y = 256 + ui_x = 288 + ui_y = 256 /datum/techweb_node/alien_engi - ui_x = 224 - ui_y = 320 + ui_x = 224 + ui_y = 320 /datum/techweb_node/micro_bluespace - ui_x = -320 - ui_y = -224 + ui_x = -320 + ui_y = -224 /datum/techweb_node/combat_cyber_implants - ui_x = 480 - ui_y = -32 + ui_x = 480 + ui_y = -32 /datum/techweb_node/spacepod_storage - ui_x = -160 - ui_y = -576 + ui_x = 96 + ui_y = -832 /datum/techweb_node/spacepod_lockbuster - ui_x = -224 - ui_y = -512 + ui_x = 96 + ui_y = -768 /datum/techweb_node/spacepod_iarmor - ui_x = -224 - ui_y = -576 + ui_x = 160 + ui_y = -832 /datum/techweb_node/computer_hardware_basic - ui_x = 256 - ui_y = -448 + ui_x = 256 + ui_y = -448 /datum/techweb_node/computer_board_gaming - ui_x = 192 - ui_y = -384 + ui_x = 192 + ui_y = -384 /datum/techweb_node/comp_recordkeeping - ui_x = 256 - ui_y = -384 + ui_x = 256 + ui_y = -384 /datum/techweb_node/nanite_smart - ui_x = 544 - ui_y = -288 + ui_x = 544 + ui_y = -288 /datum/techweb_node/anomaly - ui_x = -224 - ui_y = -288 + ui_x = -224 + ui_y = -288 /datum/techweb_node/NVGtech - ui_x = -160 - ui_y = -64 + ui_x = -160 + ui_y = -64 /datum/techweb_node/adv_mining - ui_x = 96 - ui_y = -448 + ui_x = 96 + ui_y = -448 /datum/techweb_node/janitor - ui_x = -320 - ui_y = -160 + ui_x = -320 + ui_y = -160 /datum/techweb_node/exp_tools - ui_x = -96 - ui_y = -448 + ui_x = -96 + ui_y = -448 /datum/techweb_node/rcd_upgrade - ui_x = -32 - ui_y = -448 + ui_x = -32 + ui_y = -448 /datum/techweb_node/adv_weaponry - ui_x = -576 - ui_y = -576 + ui_x = -576 + ui_y = -576 /datum/techweb_node/advmine - ui_x = -448 - ui_y = -800 + ui_x = -448 + ui_y = -800 /datum/techweb_node/radioactive_weapons - ui_x = -704 - ui_y = -736 + ui_x = -704 + ui_y = -736 /datum/techweb_node/syndicate_basic - ui_x = -384 - ui_y = -672 + ui_x = -384 + ui_y = -672 /datum/techweb_node/bluespace_power - ui_x = -192 - ui_y = -352 + ui_x = -192 + ui_y = -352 /datum/techweb_node/mech_tesla - ui_x = -576 - ui_y = -256 + ui_x = -576 + ui_y = -256 /datum/techweb_node/bluespace_travel - ui_x = -256 - ui_y = -224 + ui_x = -256 + ui_y = -224 /datum/techweb_node/adv_plasma - ui_x = 32 - ui_y = -384 + ui_x = 32 + ui_y = -384 /datum/techweb_node/spacepod_ka - ui_x = -64 - ui_y = -512 + ui_x = 32 + ui_y = -640 /datum/techweb_node/ballistic_weapons - ui_x = -736 - ui_y = -416 + ui_x = -736 + ui_y = -416 /datum/techweb_node/gygax - ui_x = -672 - ui_y = -160 + ui_x = -672 + ui_y = -160 /datum/techweb_node/phazon - ui_x = -736 - ui_y = -128 + ui_x = -736 + ui_y = -128 /datum/techweb_node/adv_mecha - ui_x = -576 - ui_y = -96 + ui_x = -576 + ui_y = -96 /datum/techweb_node/emp_super - ui_x = -224 - ui_y = -128 + ui_x = -224 + ui_y = -128 /datum/techweb_node/mech_ion - ui_x = -672 - ui_y = -256 + ui_x = -672 + ui_y = -256 /datum/techweb_node/spacepod_lasers - ui_x = 0 - ui_y = -576 + ui_x = 96 + ui_y = -704 + +/datum/techweb_node/shuttle_route_upgrade_hyper + ui_x = -224 + ui_y = -736 + +/datum/techweb_node/cyborg_upg_surgkit + ui_x = 416 + ui_y = -160 /datum/techweb_node/cyber_organs_upgraded - ui_x = 416 - ui_y = -96 + ui_x = 416 + ui_y = -96 /datum/techweb_node/exp_surgery - ui_x = 352 - ui_y = 64 + ui_x = 352 + ui_y = 64 /datum/techweb_node/nanite_combat - ui_x = -320 - ui_y = -672 + ui_x = -320 + ui_y = -672 /datum/techweb_node/advanced_bluespace - ui_x = -384 - ui_y = -160 + ui_x = -384 + ui_y = -160 /datum/techweb_node/mech_teleporter - ui_x = -416 - ui_y = -256 + ui_x = -416 + ui_y = -256 /datum/techweb_node/mech_diamond_drill - ui_x = 128 - ui_y = -512 + ui_x = 96 + ui_y = -512 /datum/techweb_node/spacepod_advmining - ui_x = 0 - ui_y = -512 + ui_x = 96 + ui_y = -640 + +/datum/techweb_node/adv_rcd_upgrade + ui_x = 32 + ui_y = -448 /datum/techweb_node/beam_weapons - ui_x = -640 - ui_y = -736 + ui_x = -640 + ui_y = -736 /datum/techweb_node/explosive_weapons - ui_x = -736 - ui_y = -576 + ui_x = -736 + ui_y = -576 /datum/techweb_node/exotic_ammo - ui_x = -704 - ui_y = -672 + ui_x = -704 + ui_y = -672 /datum/techweb_node/gravity_gun - ui_x = -320 - ui_y = -288 + ui_x = -320 + ui_y = -288 /datum/techweb_node/durand - ui_x = -672 - ui_y = -96 + ui_x = -672 + ui_y = -96 /datum/techweb_node/unregulated_bluespace - ui_x = -384 - ui_y = -608 + ui_x = -384 + ui_y = -608 /datum/techweb_node/syndicate_surgery - ui_x = -320 - ui_y = -608 + ui_x = -320 + ui_y = -608 /datum/techweb_node/mech_modules - ui_x = -640 - ui_y = -32 + ui_x = -640 + ui_y = -32 /datum/techweb_node/mech_wormhole_gen - ui_x = -416 - ui_y = -320 + ui_x = -416 + ui_y = -320 /datum/techweb_node/spacepod_advplasmacutter - ui_x = 64 - ui_y = -512 + ui_x = 160 + ui_y = -640 /datum/techweb_node/mech_scattershot - ui_x = -800 - ui_y = -352 + ui_x = -800 + ui_y = -352 /datum/techweb_node/mech_carbine - ui_x = -800 - ui_y = -416 + ui_x = -800 + ui_y = -416 /datum/techweb_node/mech_lmg - ui_x = -736 - ui_y = -352 + ui_x = -736 + ui_y = -352 /datum/techweb_node/adv_mecha_tools - ui_x = -576 - ui_y = -32 + ui_x = -576 + ui_y = -32 + +/datum/techweb_node/xenology + ui_x = 480 + ui_y = -96 /datum/techweb_node/adv_beam_weapons - ui_x = -640 - ui_y = -832 + ui_x = -640 + ui_y = -832 /datum/techweb_node/mech_laser - ui_x = -704 - ui_y = -896 + ui_x = -704 + ui_y = -896 /datum/techweb_node/mech_disabler - ui_x = -448 - ui_y = -224 + ui_x = -448 + ui_y = -224 /datum/techweb_node/mech_grenade_launcher - ui_x = -800 - ui_y = -512 + ui_x = -800 + ui_y = -512 /datum/techweb_node/mech_missile_rack - ui_x = -800 - ui_y = -640 + ui_x = -800 + ui_y = -640 /datum/techweb_node/clusterbang_launcher - ui_x = -800 - ui_y = -576 + ui_x = -800 + ui_y = -576 /datum/techweb_node/mech_laser_heavy - ui_x = -576 - ui_y = -896 + ui_x = -576 + ui_y = -896 /datum/techweb_node/mech_xray - ui_x = -640 - ui_y = -896 \ No newline at end of file + ui_x = -640 + ui_y = -896 diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 9caa9228f5dfd89b750320b3ddad03e03027ad30..062b2458c66d5cebcc342a4d0cdba0ab9eb75ddd 100644 GIT binary patch delta 4977 zcmV-%6OQb##R00o0gxnrdU{k?bVOxyV{&P5bZKvH004NLrI*ca+b|G>&(>2A$yF*W zIX~^em%>5eL-Gm&MKbal)DM( zh8=aSSc|(K%VaT<_B*i_t0GzK4Anb-`r^FwMy$onXskATlPolUu@h^NCyQ5>jXC{& zf#u63NIu?!;62*0Ks#P(SR@N=tUQXfDAG>?WL+C9%hTCe)M`+=iA22pz! z+Jj>JK`{oQ7>7`dMJUE26k`&KaS6rPgra;RulnTiQ#85^NYv^<8P1#{Bypu88s&5^+R z!Ge*mYn|sodFtA-l65%wbX=FCY`xKC-#H|0uzN+A?<_`h=+W?M4m}vP&7nsJWDb4I zkB~hz4G=fnl}&N&cMv;W4(@s=zZFj}8?kxbCVv44!WufY-PpNrv#A0aKmr|8v&BM$ z41arYQ}>m}KXTHIViRJcCW~JphQ!9>+J)eRH1&1~k9HR(Yyxe=gq`gsEuLh(&FoH? zu|sC!$xicNCQM#cU`Vpr*&Q-;3GUP_o=!qwQXm0hoEVP_h=+&~C|l}RgpEoP|Mrio zdo9V5b!BuVSw5c``AYZxbicnVS?8SJ`F}mGt*WX@#WI4AJ@%Nbxw%<691hyr+K9HD zH!rb1p+r~*w&tNPRSD3B<`5#cPnVQn)%6EcIx3#=fBM%KZO!-Jq=2yJ0Jql-Y`n=-5z_IpSRMxIAqVUSv73gcxheoeDx?zeJiKbhBBJ}{0rkg4HiBeTnrE+s~ z@p`?Kl$0<$Jj~$WAYQLmH+r_vvVYwvSj{n&r2G1t@4rdu#(&mrd31cJ8NH`}ebM$x zeUW->>jgtE^7VMs-)~o|7hjj~gs%VV`*&U-s;WxCXjBVY`Xki%f!1Oe92^X5Idpe- z$2`B@0*KY|`|!gLGi};5%bZ6usPQ^}U()&?EW3W=0cj3xacLb-4crAcTAatZoB>OuLTN3?Wt$xfFK>NWz z09qO$*6h*94n}?5`I@^|tI+)QM2t|n^%JRwu8~aLOwo@dB7HGt6i}Q9H)ef$d$nb) z@4N3ly1Tn$ZZBQBq<^}*yE$~|P*R>F*@-w)uVvYjc)ui6)Q&pS*0J=0th|O>;04~R|33+lMOMN z70Jvkr&~W(Jwi2NE!AM<=a6dsbRzQrGIJh4Ca|`+Sk>A`M}IhFVhbRvP@w)3XWDKm zo^E|X5HgFk#l=d0q`NNJ!i4SzAP9nxY9!)MG3k!N)2%NEf{@LaTPIZz1VNa3=u!Cp zE}4~3tb2t*oxgWMQ54hhBW zcH1sqyvTd+y+Av=iK0=WK(I^&=GzbbwPz(1dOgUiqDPf7G6 z`cqqfB7a00|A!COgc<*uni^G6UQTgwam@6Op7zmGK0cq%IQGaRkFaIS7V9rW$Vl4j z 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 diff --git a/yogstation/code/modules/research/techweb/all_nodes.dm b/yogstation/code/modules/research/techweb/all_nodes.dm index d5229ff2ff74..1bb74e0eac37 100644 --- a/yogstation/code/modules/research/techweb/all_nodes.dm +++ b/yogstation/code/modules/research/techweb/all_nodes.dm @@ -13,8 +13,10 @@ /datum/techweb_node/basic_tools prereq_ids = list("base") -/datum/techweb_node/spacepod_basic - id = "spacepod_basic" + +/////////////////////////space vehicle tech///////////////////////// +/datum/techweb_node/spacevehicle_basic + id = "spacevehicle_basic" display_name = "Spacepod Construction" description = "Basic stuff to construct Spacepods. Don't crash your first spacepod into the station, especially while going more than 10 m/s." research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) @@ -28,7 +30,7 @@ description = "Keeps greytiders out of your spacepods." research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) export_price = 2750 - prereq_ids = list("spacepod_basic", "engineering") + prereq_ids = list("spacevehicle_basic", "engineering") design_ids = list("podlock_keyed", "podkey", "podmisc_tracker") /datum/techweb_node/spacepod_disabler @@ -37,7 +39,7 @@ description = "For a bit of pew pew space battles" research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) export_price = 3500 - prereq_ids = list("spacepod_basic", "weaponry") + prereq_ids = list("spacevehicle_basic", "weaponry") design_ids = list("podgun_disabler") /datum/techweb_node/spacepod_lasers @@ -82,7 +84,7 @@ description = "For bringing along victims as you fly off into the far reaches of space" research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3750) export_price = 3750 - prereq_ids = list("spacepod_basic", "adv_engi") + prereq_ids = list("spacevehicle_basic", "adv_engi") design_ids = list("podcargo_seat") /datum/techweb_node/spacepod_storage @@ -112,6 +114,43 @@ prereq_ids = list("spacepod_storage", "high_efficiency") design_ids = list("podarmor_industiral", "podarmor_sec", "podarmor_gold") +/datum/techweb_node/basic_shuttle_tech + id = "basic_shuttle_tech" + display_name = "Basic Shuttle Research" + description = "Research the technology required to create and use basic shuttles." + prereq_ids = list("bluespace_travel", "adv_engi", "spacevehicle_basic") + design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +/datum/techweb_node/shuttle_route_upgrade + id = "shuttle_route_upgrade" + display_name = "Route Optimisation Upgrade" + description = "Research into bluespace tunnelling, allowing us to reduce flight times by up to 20%!" + prereq_ids = list("spacevehicle_basic") + design_ids = list("disk_shuttle_route") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 2500 + +/datum/techweb_node/shuttle_route_upgrade_hyper + id = "shuttle_route_upgrade_hyper" + display_name = "Hyperlane Optimisation Upgrade" + description = "Research into bluespace hyperlane, allowing us to reduce flight times by up to 40%!" + prereq_ids = list("shuttle_route_upgrade", "micro_bluespace") + design_ids = list("disk_shuttle_route_hyper") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + export_price = 5000 + +/datum/techweb_node/shuttle_route_upgrade_void + id = "shuttle_route_upgrade_void" + display_name = "Nullspace Breaching Upgrade" + description = "Research into voidspace tunnelling, allowing us to significantly reduce flight times." + prereq_ids = list("shuttle_route_upgrade_hyper", "alientech") + design_ids = list("engine_void", "disk_shuttle_route_void") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 2500 + + /datum/techweb_node/syndicate_surgery id = "syndicate_surgery" display_name = "Syndicate Surgery" From dbdd04e5689346d3cd7ff0d7da301cb216d5c841 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sun, 5 Sep 2021 03:21:16 -0400 Subject: [PATCH 09/16] Should fix some stuff with the shuttles Should fix most of the runtimes and issues that ive had thanks to Jamie's help. Should bring this from ""functional"" to "functional". --- code/game/machinery/shuttle/shuttle_engine.dm | 3 +++ .../shuttle/shuttle_creation/shuttle_creator_actions.dm | 2 +- code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm index e3cdec77b6e2..acba95a3c431 100644 --- a/code/game/machinery/shuttle/shuttle_engine.dm +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -119,6 +119,9 @@ var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap req_power = min(req_power, ENGINE_HEATING_POWER) var/deltaTemperature = req_power / heat_cap + var/deltaTemperature = 0 + if(!heat_cap == 0) + deltaTemperature = req_power / heat_cap if(deltaTemperature < 0) return env.set_temperature(env.return_temperature() + deltaTemperature) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm index f50b3bf59f49..9ee46638d41d 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm @@ -96,6 +96,6 @@ to_chat(C, "Shuttle created!") //Remove eye control var/obj/machinery/computer/camera_advanced/shuttle_creator/internal_console = target - internal_console.remove_eye_control() + internal_console.remove_eye_control(C) qdel(internal_console) return diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm index a6cc73cd2f38..4eea6bfe8856 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm @@ -1,8 +1,8 @@ //===============Camera Eye================ /mob/camera/aiEye/remote/shuttle_creation name = "shuttle holo-drone" - icon = 'icons/obj/tools.dmi' - icon_state = "shuttle_drone" + icon = 'icons/obj/mining.dmi' + icon_state = "construction_drone" visible_icon = FALSE acceleration = 0 var/turf/source_turf @@ -11,6 +11,7 @@ /mob/camera/aiEye/remote/shuttle_creation/Initialize() . = ..() setLoc(get_turf(source_turf)) + icon_state = "construction_drone" /mob/camera/aiEye/remote/shuttle_creation/update_remote_sight(mob/living/user) user.sight = BLIND|SEE_TURFS From 0205a979d57f7f4cbb479f967a28bd0906602174 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sun, 5 Sep 2021 03:22:49 -0400 Subject: [PATCH 10/16] I am too tired for this why github desktop, WHY!! --- code/game/machinery/shuttle/shuttle_engine.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm index acba95a3c431..98e324b3d020 100644 --- a/code/game/machinery/shuttle/shuttle_engine.dm +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -118,7 +118,6 @@ var/heat_cap = env.heat_capacity() var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap req_power = min(req_power, ENGINE_HEATING_POWER) - var/deltaTemperature = req_power / heat_cap var/deltaTemperature = 0 if(!heat_cap == 0) deltaTemperature = req_power / heat_cap From 446d615d1662897a6dcf40984bba4ee594dcb404 Mon Sep 17 00:00:00 2001 From: nmajask Date: Mon, 13 Sep 2021 18:20:56 -0400 Subject: [PATCH 11/16] Adds spaceship navigation beacons They kinda work. --- .../research/designs/machine_designs.dm | 8 +++ code/modules/shuttle/navigation_computer.dm | 19 +++++- .../shuttle/spaceship_navigation_beacon.dm | 63 +++++++++++++++++++ yogstation.dme | 1 + 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 code/modules/shuttle/spaceship_navigation_beacon.dm diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 3a9c6d0820ac..42433517b4e3 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -26,6 +26,14 @@ category = list ("Shuttle Machinery") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/board/spaceship_navigation_beacon + name = "Machine Design (Bluespace Navigation Gigabeacon)" + desc = "The circuit board for a Bluespace Navigation Gigabeacon." + id = "spaceship_navigation_beacon" + build_path = /obj/item/circuitboard/machine/spaceship_navigation_beacon + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/board/smes name = "Machine Design (SMES Board)" desc = "The circuit board for an SMES." diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index d0e30ae91ba1..5ad9115b8f06 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -11,6 +11,7 @@ var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes var/obj/docking_port/stationary/my_port //the custom docking port placed by this console var/obj/docking_port/mobile/shuttle_port //the mobile docking port of the connected shuttle + var/list/locked_traits = list(ZTRAIT_RESERVED, ZTRAIT_CENTCOM, ZTRAIT_AWAY, ZTRAIT_REEBE) //traits forbided for custom docking var/view_range = 0 var/x_offset = 0 var/y_offset = 0 @@ -164,7 +165,7 @@ if(current_user.client) current_user.client.images += the_eye.placed_images to_chat(current_user, "Transit location designated") - return + return TRUE /obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget() if(!designating_target_loc || !current_user || (eyeobj.loc != designating_target_loc) || (stat & (NOPOWER|BROKEN)) ) @@ -192,7 +193,7 @@ var/turf/eyeturf = get_turf(the_eye) if(!eyeturf) return SHUTTLE_DOCKER_BLOCKED - if(z_lock.len && !(eyeturf.z in z_lock)) + if(!eyeturf.z || SSmapping.level_has_any_trait(eyeturf.z, locked_traits)) return SHUTTLE_DOCKER_BLOCKED . = SHUTTLE_DOCKER_LANDING_CLEAR @@ -331,13 +332,25 @@ var/list/L = list() for(var/V in SSshuttle.stationary) if(!V) + stack_trace("SSshuttle.stationary have null entry!") continue var/obj/docking_port/stationary/S = V if(console.z_lock.len && !(S.z in console.z_lock)) continue if(console.jumpto_ports[S.id]) - L[S.name] = S + L["([L.len])[S.name]"] = S + for(var/V in SSshuttle.beacons) + if(!V) + stack_trace("SSshuttle.beacons have null entry!") + continue + var/obj/machinery/spaceship_navigation_beacon/nav_beacon = V + if(!nav_beacon.z || SSmapping.level_has_any_trait(nav_beacon.z, console.locked_traits)) + break + if(!nav_beacon.locked) + L["([L.len]) [nav_beacon.name] located: [nav_beacon.x] [nav_beacon.y] [nav_beacon.z]"] = nav_beacon + else + L["([L.len]) [nav_beacon.name] locked"] = null playsound(console, 'sound/machines/terminal_prompt.ogg', 25, 0) var/selected = input("Choose location to jump to", "Locations", null) as null|anything in L if(QDELETED(src) || QDELETED(target) || !isliving(target)) diff --git a/code/modules/shuttle/spaceship_navigation_beacon.dm b/code/modules/shuttle/spaceship_navigation_beacon.dm new file mode 100644 index 000000000000..89e02920a732 --- /dev/null +++ b/code/modules/shuttle/spaceship_navigation_beacon.dm @@ -0,0 +1,63 @@ +/obj/item/circuitboard/machine/spaceship_navigation_beacon + name = "Bluespace Navigation Gigabeacon (Machine Board)" + build_path = /obj/machinery/spaceship_navigation_beacon + req_components = list() + + +/obj/machinery/spaceship_navigation_beacon + name = "Bluespace Navigation Gigabeacon" + desc = "A device that creates a bluespace anchor that allow ships jump near to it." + icon = 'icons/obj/abductor.dmi' + icon_state = "core" + use_power = IDLE_POWER_USE + idle_power_usage = 0 + density = TRUE + circuit = /obj/item/circuitboard/machine/spaceship_navigation_beacon + + var/locked = FALSE //Locked beacons don't allow to jump to it. + + +/obj/machinery/spaceship_navigation_beacon/Initialize() + . = ..() + SSshuttle.beacons |= src + +obj/machinery/spaceship_navigation_beacon/emp_act() + locked = TRUE + +/obj/machinery/spaceship_navigation_beacon/Destroy() + SSshuttle.beacons -= src + return ..() + +// update the icon_state +/obj/machinery/spaceship_navigation_beacon/update_icon() + if(powered()) + icon_state = "core" + else + icon_state = "core-open" + +/obj/machinery/spaceship_navigation_beacon/power_change() + . = ..() + update_icon() + +/obj/machinery/spaceship_navigation_beacon/multitool_act(mob/living/user, obj/item/multitool/I) + if(panel_open) + var/new_name = "Beacon_[input("Enter the custom name for this beacon", "It be Beacon ..your input..") as text]" + if(new_name && Adjacent(user)) + name = new_name + to_chat(user, "You change beacon name to [name].") + else + locked =!locked + to_chat(user, "You [locked ? "" : "un"]lock [src].") + return TRUE + +/obj/machinery/spaceship_navigation_beacon/examine() + .=..() + . += "Status: [locked ? "LOCKED" : "Stable"] " + +/obj/machinery/spaceship_navigation_beacon/attackby(obj/item/W, mob/user, params) + if(default_deconstruction_screwdriver(user, "core-open", "core", W)) + return + if(default_deconstruction_crowbar(W)) + return + + return ..() diff --git a/yogstation.dme b/yogstation.dme index 2996d84f504a..47d9d74c4f4d 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2913,6 +2913,7 @@ #include "code\modules\shuttle\ripple.dm" #include "code\modules\shuttle\shuttle.dm" #include "code\modules\shuttle\shuttle_rotate.dm" +#include "code\modules\shuttle\spaceship_navigation_beacon.dm" #include "code\modules\shuttle\special.dm" #include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\syndicate.dm" From a65232321fe0676e670b4a529736598922673b52 Mon Sep 17 00:00:00 2001 From: nmajask Date: Mon, 13 Sep 2021 18:31:16 -0400 Subject: [PATCH 12/16] should fix the beacons why do i do this the way i do --- code/controllers/subsystem/shuttle.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 8f0bafeca1da..15845c5036bc 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -8,6 +8,7 @@ SUBSYSTEM_DEF(shuttle) var/list/mobile = list() var/list/stationary = list() + var/list/beacons = list() var/list/transit = list() var/list/transit_requesters = list() From 5f906cc478526bd6b0fd1cd71635661c75cac0c1 Mon Sep 17 00:00:00 2001 From: nmajask Date: Mon, 13 Sep 2021 19:42:45 -0400 Subject: [PATCH 13/16] Ports some fixes by Dennok Ports "Custom shuttle offsets and view range depends on ship size. #2685" by Dennok and "Custom transit dir for custom shuttle #2689" by Dennok --- code/modules/shuttle/custom_shuttle.dm | 12 ++++++++---- code/modules/shuttle/shuttle.dm | 1 + .../shuttle/shuttle_creation/shuttle_creator.dm | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 7c9d76f727f4..74bec8cf4c11 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -198,9 +198,6 @@ var/time = min(max(round(dist / calculated_speed), 10), 90) linkedShuttle.callTime = time * 10 linkedShuttle.rechargeTime = calculated_cooldown - //We need to find the direction of this console to the port - linkedShuttle.port_direction = angle2dir(dir2angle(dir) - (dir2angle(linkedShuttle.dir)) + 180) - linkedShuttle.preferred_direction = NORTH linkedShuttle.ignitionTime = CUSTOM_ENGINES_START_TIME linkedShuttle.count_engines() linkedShuttle.hyperspace_sound(HYPERSPACE_WARMUP) @@ -263,6 +260,13 @@ return return ..() -/obj/machinery/computer/camera_advanced/shuttle_docker/custom/proc/linkShuttle(var/new_id) +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/proc/linkShuttle(new_id) shuttleId = new_id shuttlePortId = "shuttle[new_id]_custom" + + //Take info from connected port and calculate amendments + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(new_id) + var/list/shuttlebounds = M.return_coords() + view_range = min(round(max(M.width, M.height)*0.5), 15) + x_offset = round((shuttlebounds[1] + shuttlebounds[3])*0.5) - M.x + y_offset = round((shuttlebounds[2] + shuttlebounds[4])*0.5) - M.y diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 974456c3f25e..8b59f0e7fcc9 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -826,6 +826,7 @@ /obj/docking_port/mobile/proc/count_engines() . = 0 + engine_list.Cut() for(var/thing in shuttle_areas) var/area/shuttle/areaInstance = thing for(var/obj/structure/shuttle/engine/E in areaInstance.contents) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm index 69de2a2d91ae..0dc4bad7c4cc 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -56,6 +56,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He /obj/item/shuttle_creator/attack_self(mob/user) ..() if(linkedShuttleId) + select_preferred_direction(user) return if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT && !override_max_shuttles) to_chat(user, "Too many shuttles have been created.") @@ -188,6 +189,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He port.ignitionTime = 25 port.name = "Custom Shuttle" port.port_direction = 2 + port.preferred_direction = EAST port.preferred_direction = 4 port.area_type = recorded_shuttle_area @@ -237,6 +239,9 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He icon_state = "rsd_used" + //Select shuttle fly direction. + select_preferred_direction(user) + //Clear highlights overlay_holder.clear_highlights() GLOB.custom_shuttle_count ++ @@ -292,6 +297,16 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He FD.CalculateAffectingAreas() return TRUE +//Select shuttle fly direction. +/obj/item/shuttle_creator/proc/select_preferred_direction(mob/user) + var/obj/docking_port/mobile/port = SSshuttle.getShuttle(linkedShuttleId) + if(!port || !istype(port, /obj/docking_port/mobile)) + return FALSE + var/static/list/choice = list("NORTH" = NORTH, "SOUTH" = SOUTH, "EAST" = EAST, "WEST" = WEST) + var/Pdir = input(user, "Shuttle Fly Direction:", "Blueprint Editing", "NORTH") as null|anything in list("NORTH", "SOUTH", "EAST", "WEST") + if(Pdir) + port.preferred_direction = choice[Pdir] + //Checks an area to ensure that the turfs provided are valid to be made into a shuttle /obj/item/shuttle_creator/proc/check_area(list/turfs) if(!turfs) From 159406d2407b64a0c1b2d33ee5fb01423792b1ef Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 18 Sep 2021 03:22:20 -0400 Subject: [PATCH 14/16] Admin RSD and minor tweaks - Added the Admin RSD, which ignores the shuttle size and area limit, allowing you to turn whole chucks of the station into shuttles - Renamed the shuttle navigation computer to the shuttle zoning designator to avoid confusion - Tweaked the designs for the shuttle circuit board design to use the correct name for the boards - Moved the Bluespace Navigation Gigabeacon board into shuttle machinery --- .../research/designs/comp_board_designs.dm | 4 ++-- .../research/designs/machine_designs.dm | 2 +- code/modules/shuttle/custom_shuttle.dm | 4 ++-- .../shuttle_creation/shuttle_creator.dm | 19 +++++++++++++++--- .../shuttle_creator_actions.dm | 2 +- icons/obj/tools.dmi | Bin 24618 -> 25057 bytes 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index 53305c207cf3..c6cda870418c 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -287,7 +287,7 @@ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/shuttle/flight_control - name = "Computer Design (Shuttle Flight Controls)" + name = "Computer Design (Shuttle Flight Controller)" desc = "Allows for the construction of circuit boards used to build a console that enables shuttle flight" id = "shuttle_control" build_path = /obj/item/circuitboard/computer/shuttle/flight_control @@ -295,7 +295,7 @@ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/shuttle/shuttle_docker - name = "Computer Design (Private Navigation Computer)" + name = "Computer Design (Shuttle Zoning Designator)" desc = "Allows for the construction of circuit boards used to build a console that enables the targetting of custom flight locations" id = "shuttle_docker" build_path = /obj/item/circuitboard/computer/shuttle/docker diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 42433517b4e3..a21214d5e40f 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -31,7 +31,7 @@ desc = "The circuit board for a Bluespace Navigation Gigabeacon." id = "spaceship_navigation_beacon" build_path = /obj/item/circuitboard/machine/spaceship_navigation_beacon - category = list ("Teleportation Machinery") + category = list ("Shuttle Machinery") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/smes diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 74bec8cf4c11..03cb5cfbfe74 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -98,7 +98,7 @@ ui_interact(usr) return -/obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/docking_port/stationary/port) +/obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/port) var/deltaX = port.x - x var/deltaY = port.y - y var/deltaZ = (port.z - z) * Z_DIST @@ -223,7 +223,7 @@ //Custom shuttle docker locations /obj/machinery/computer/camera_advanced/shuttle_docker/custom - name = "Shuttle Navigation Computer" + name = "Shuttle Zoning Designator" desc = "Used to designate a precise transit location for private ships." lock_override = NONE whitelist_turfs = list(/turf/open/space, diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm index 0dc4bad7c4cc..d4bd4178117b 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -30,6 +30,8 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He //pre-designation var/override_max_shuttles = FALSE var/obj/machinery/computer/camera_advanced/shuttle_creator/internal_shuttle_creator + var/ignore_max_shuttle_size = FALSE + var/ignore_area = FALSE //During designation var/overwritten_area = /area/space var/list/loggedTurfs = list() @@ -237,7 +239,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He port.register() - icon_state = "rsd_used" + icon_state = initial(icon_state) + "_used" //Select shuttle fly direction. select_preferred_direction(user) @@ -270,7 +272,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He //Yogs Start: Runs the name through the petty filter. If they trip it, it will cause the shuttle creation to fail, messages the admins, and put the RSD on cooldown. if(isnotpretty(str)) to_chat(user, "Nanotrasen prohibited words are in use in this shuttle name, blares the [src] in a slightly offended tone.") - message_admins("[ADMIN_LOOKUPFLW(user)] attempted to created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)], but failed because of tripping a petty filter") + message_admins("[ADMIN_LOOKUPFLW(user)] attempted to created a new shuttle with a [src] at [ADMIN_VERBOSEJMP(user)], but failed because of not passing the pretty filter") user.create_area_cooldown = world.time + 10 return FALSE //Yogs End @@ -312,7 +314,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He if(!turfs) to_chat(usr, "Shuttles must be created in an airtight space, ensure that the shuttle is airtight, including corners.") return FALSE - if(turfs.len > SHUTTLE_CREATOR_MAX_SIZE) + if(turfs.len > SHUTTLE_CREATOR_MAX_SIZE && !ignore_max_shuttle_size) to_chat(usr, "The [src]'s internal cooling system wizzes violently and a message appears on the screen, \"Caution, this device can only handle the creation of shuttles up to [SHUTTLE_CREATOR_MAX_SIZE] units in size. Please reduce your shuttle by [turfs.len-SHUTTLE_CREATOR_MAX_SIZE]. Sorry for the inconvinience\"") return FALSE //Check to see if it's a valid shuttle @@ -326,6 +328,8 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He overwritten_area = /area/space else if(istype(place, /area/lavaland/surface/outdoors)) overwritten_area = /area/lavaland/surface/outdoors + else if(ignore_area) + overwritten_area = place else to_chat(usr, "Caution, shuttle must not use any material connected to the station. Your shuttle is currenly overlapping with [place.name]") return FALSE @@ -384,5 +388,14 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He loggedTurfs.Cut() to_chat(usr, "You reset the area buffer on the [src].") +//Yogs: Admin RSD for bussing and messing around. I am not liable for any crashed servers this may cause. This one removes the size and area limits, allowing you to turn the entire station into a shuttle if you want. +/obj/item/shuttle_creator/admin + name = "Admin Rapid Shuttle Designator" + icon_state = "arsd" + desc = "An experimental RSD with the size and area limits disabled. It is covered in warning of what not to do." + override_max_shuttles = TRUE + ignore_max_shuttle_size = TRUE + ignore_area = TRUE + #undef CARDINAL_DIRECTIONS_X #undef CARDINAL_DIRECTIONS_Y diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm index 9ee46638d41d..0cf06721aff7 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_actions.dm @@ -84,7 +84,7 @@ if(GLOB.custom_shuttle_count > CUSTOM_SHUTTLE_LIMIT) to_chat(C, "Shuttle limit reached, sorry.") return - if(shuttle_creator.loggedTurfs.len > SHUTTLE_CREATOR_MAX_SIZE) + if(shuttle_creator.loggedTurfs.len > SHUTTLE_CREATOR_MAX_SIZE && !shuttle_creator.ignore_max_shuttle_size) to_chat(C, "This shuttle is too large!") return if(!shuttle_creator.getNonShuttleDirection(T)) diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 062b2458c66d5cebcc342a4d0cdba0ab9eb75ddd..c0678bfd96a0e5e4164f83d76eb5459a3eb0ba38 100644 GIT binary patch delta 4798 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 C^?G#x delta 4357 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 From f35ad53c276916fa0d77adc7429e32dc11bbb366 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 18 Sep 2021 13:27:16 -0400 Subject: [PATCH 15/16] Fixes Bluespace Navigation Gigabeacon not being able to be researched - I forgot to add Bluespace Navigation Gigabeacon to the lists of unlocks for Spacepod Construction, so I fixed that --- yogstation/code/modules/research/techweb/all_nodes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation/code/modules/research/techweb/all_nodes.dm b/yogstation/code/modules/research/techweb/all_nodes.dm index 1bb74e0eac37..6136be1c7d39 100644 --- a/yogstation/code/modules/research/techweb/all_nodes.dm +++ b/yogstation/code/modules/research/techweb/all_nodes.dm @@ -22,7 +22,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 2500 prereq_ids = list("base") - design_ids = list("podcore", "podarmor_civ", "podarmor_dark", "spacepod_main") + design_ids = list("podcore", "podarmor_civ", "podarmor_dark", "spacepod_main", "spaceship_navigation_beacon") /datum/techweb_node/spacepod_lock id = "spacepod_lock" From 2a59620f45b1886d2ab59742c6c254290089d4f2 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sun, 3 Oct 2021 20:04:48 -0400 Subject: [PATCH 16/16] readded the RSD sprites got to love merge conflicts --- icons/obj/tools.dmi | Bin 27048 -> 28131 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index ff31df768418cd96fda53883555b062bc9ccd06c..e21b6cfb6cfe605f7c4f78ca5f1a16cc1c52655c 100644 GIT binary patch delta 8684 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 TEtC2ZgxKVzRivsV%s&1X7#mzE delta 7542 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