Files
Aurora.3/code/modules/overmap/overmap_shuttle.dm
Fluffy d9c44532fc Refactored directionals (#20082)
Refactored directionals, ported lists of directions from TG, got rid of
useless proc to get the reverse direction.
2024-10-25 17:56:02 +00:00

326 lines
13 KiB
Plaintext

/datum/shuttle/autodock/overmap
warmup_time = 10
var/range = 0 //how many overmap tiles can shuttle go, for picking destinations and returning.
var/fuel_consumption = 0 //Amount of moles of gas consumed per trip; If zero, then shuttle is magic and does not need fuel
var/list/obj/structure/fuel_port/fuel_ports //the fuel ports of the shuttle (but usually just one)
category = /datum/shuttle/autodock/overmap
/datum/shuttle/autodock/overmap/New(var/_name, var/obj/effect/shuttle_landmark/start_waypoint)
..(_name, start_waypoint)
refresh_fuel_ports_list()
for(var/area/A in shuttle_area) //If shuttles initialize after the blueprints, they won't set correctly so we do it here.
var/obj/item/blueprints/shuttle/blueprints = locate() in A
if(blueprints)
blueprints.set_valid_z_levels()
/datum/shuttle/autodock/overmap/proc/refresh_fuel_ports_list() //loop through all
fuel_ports = list()
for(var/area/A in shuttle_area)
for(var/obj/structure/fuel_port/fuel_port_in_area in A)
fuel_port_in_area.parent_shuttle = src
fuel_ports |= fuel_port_in_area
/datum/shuttle/autodock/overmap/fuel_check(var/check_only = FALSE) // "check_only" lets you check the fuel levels without using any.
if(!src.try_consume_fuel(check_only)) //insufficient fuel
for(var/area/A in shuttle_area)
for(var/mob/living/M in A)
M.show_message(SPAN_WARNING("You hear the shuttle engines sputter... perhaps it doesn't have enough fuel?"), 2,
SPAN_WARNING("The shuttle shakes but fails to take off."), 1)
return 0 //failure!
return 1 //sucess, continue with launch
/datum/shuttle/autodock/overmap/proc/can_go()
if(!next_location)
return FALSE
if(moving_status == SHUTTLE_INTRANSIT)
return FALSE //already going somewhere, current_location may be an intransit location instead of in a sector
return get_dist(waypoint_sector(current_location), waypoint_sector(next_location)) <= range
/datum/shuttle/autodock/overmap/can_launch()
return ..() && can_go()
/datum/shuttle/autodock/overmap/can_force()
return ..() && can_go()
/datum/shuttle/autodock/overmap/get_travel_time()
var/distance_mod = get_dist(waypoint_sector(current_location),waypoint_sector(next_location))
return move_time * (1 + distance_mod)
/datum/shuttle/autodock/overmap/proc/set_destination(var/obj/effect/shuttle_landmark/A)
if(A != current_location)
next_location = A
/datum/shuttle/autodock/overmap/proc/get_possible_destinations()
var/list/res = list()
for (var/obj/effect/overmap/visitable/S in range(get_turf(waypoint_sector(current_location)), range))
var/list/waypoints = S.get_waypoints(name)
for(var/obj/effect/shuttle_landmark/LZ in waypoints)
if(LZ.is_valid(src))
res["[waypoints[LZ]] - [LZ.name]"] = LZ
return res
/datum/shuttle/autodock/overmap/get_location_name()
if(moving_status == SHUTTLE_INTRANSIT)
return "In transit"
return "[waypoint_sector(current_location)] - [current_location]"
/datum/shuttle/autodock/overmap/get_destination_name()
if(!next_location)
return "None"
return "[waypoint_sector(next_location)] - [next_location]"
/datum/shuttle/autodock/overmap/proc/try_consume_fuel(var/check_only = FALSE) //returns 1 if sucessful, returns 0 if error (like insufficient fuel)
if(!fuel_consumption)
return 1 //shuttles with zero fuel consumption are magic and can always launch
if(!fuel_ports.len)
return 0 //Nowhere to get fuel from
var/list/obj/item/tank/fuel_tanks = list()
for(var/obj/structure/FP in fuel_ports) //loop through fuel ports and assemble list of all fuel tanks
var/obj/item/tank/FT = locate() in FP
if(FT)
fuel_tanks += FT
if(!fuel_tanks.len)
return 0 //can't launch if you have no fuel TANKS in the ports
var/total_flammable_gas_moles = 0
for(var/obj/item/tank/FT in fuel_tanks)
total_flammable_gas_moles += FT.air_contents.get_by_flag(XGM_GAS_FUEL)
if(total_flammable_gas_moles < fuel_consumption) //not enough fuel
return 0
// We are going to succeed if we got to here, so start consuming that fuel
var/fuel_to_consume = fuel_consumption
for(var/obj/item/tank/FT in fuel_tanks) //loop through tanks, consume their fuel one by one
var/fuel_available = FT.air_contents.get_by_flag(XGM_GAS_FUEL)
if(!fuel_available) // Didn't even have fuel.
continue
if(check_only)
return 1
if(fuel_available >= fuel_to_consume)
FT.remove_air_by_flag(XGM_GAS_FUEL, fuel_to_consume)
return 1 //ALL REQUIRED FUEL HAS BEEN CONSUMED, GO FOR LAUNCH!
else //this tank doesn't have enough to launch shuttle by itself, so remove all its fuel, then continue loop
fuel_to_consume -= fuel_available
FT.remove_air_by_flag(XGM_GAS_FUEL, fuel_available)
/datum/shuttle/autodock/overmap/on_move_interim()
..()
for(var/obj/machinery/computer/shuttle_control/explore/E in shuttle_computers)
var/obj/effect/overmap/visitable/ship/S = E.connected
if(S)
S.halt()
S.unhalt()
#define FUEL_PORT_UNSECURED 0
#define FUEL_PORT_BOLTED 1
#define FUEL_PORT_WELDED 2
/obj/structure/fuel_port //empty
name = "fuel port"
desc = "The fuel input port of the shuttle. Holds one fuel tank. Use a crowbar to open and close it."
desc_info = "The fuel port must be wrenched and welded in place before it can be loaded and used by the shuttle."
icon = 'icons/turf/shuttle.dmi'
icon_state = "fuel_port"
density = 0
anchored = 1
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
var/state = FUEL_PORT_WELDED
var/icon_closed = "fuel_port"
var/icon_empty = "fuel_port_empty"
var/icon_full = "fuel_port_full"
var/opened = 0
var/parent_shuttle
var/port_item_path = /obj/item/fuel_port
/obj/structure/fuel_port/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
switch(state)
if(FUEL_PORT_UNSECURED)
. += SPAN_NOTICE("\The [src] is in place, but not attached to anything.")
if(FUEL_PORT_BOLTED)
. += SPAN_NOTICE("\The [src]'s external reinforcing bolts are deployed and locked.")
if(FUEL_PORT_WELDED)
. += SPAN_NOTICE("\The [src] is bolted and welded in place.")
/obj/structure/fuel_port/Initialize(mapload, var/placement_dir, var/constructed)
. = ..()
switch(placement_dir)
if(NORTH)
pixel_y = 32
if(SOUTH)
pixel_y = -32
if(EAST)
pixel_x = 32
if(WEST)
pixel_x = -32
if(constructed)
state = FUEL_PORT_UNSECURED
update_shuttle()
/obj/structure/fuel_port/New(loc, var/placement_dir, var/constructed = FALSE)
. = ..()
/obj/structure/fuel_port/Destroy()
update_shuttle()
return ..()
/obj/structure/fuel_port/attack_hand(mob/user)
if(state == FUEL_PORT_UNSECURED)
to_chat(user, SPAN_NOTICE("You remove \the [src] from its position."))
var/obj/item/fuel_port/P = new port_item_path(user.loc)
user.put_in_active_hand(P)
qdel(src)
else if(!opened)
to_chat(user, SPAN_WARNING("\The [src] is secured tightly. You'll need to pry it open with a crowbar."))
return
else if(contents.len > 0)
user.put_in_hands(contents[1])
update_icon()
/obj/structure/fuel_port/update_icon()
. = ..()
if(opened)
if(contents.len > 0)
icon_state = icon_full
else
icon_state = icon_empty
else
icon_state = icon_closed
/obj/structure/fuel_port/attackby(obj/item/attacking_item, mob/user)
if(attacking_item.iscrowbar())
if(state != FUEL_PORT_WELDED)
to_chat(user, SPAN_WARNING("\The [src] must be bolted and welded in place before it can be opened!"))
return
else if(opened)
to_chat(user, SPAN_NOTICE("You close \the [src]."))
playsound(src.loc, 'sound/effects/closet_close.ogg', 25, 0, -3)
opened = 0
else
to_chat(user, SPAN_NOTICE("You pry \the [src] open."))
playsound(src.loc, 'sound/effects/closet_open.ogg', 15, 1, -3)
opened = 1
else if(istype(attacking_item, /obj/item/tank))
if(state != FUEL_PORT_WELDED)
to_chat(user, SPAN_WARNING("\The [src] must be welded in place before a new tank can be added!"))
return
if(!opened)
to_chat(user, SPAN_NOTICE("\The [src] isn't open!"))
return
if(contents.len == 0)
user.unEquip(attacking_item, TRUE, src)
else if(attacking_item.iswrench())
switch(state)
if(FUEL_PORT_WELDED)
to_chat(user, SPAN_WARNING("\The [src] is welded in place!"))
return
if(FUEL_PORT_BOLTED)
attacking_item.play_tool_sound(get_turf(src), 75)
user.visible_message(SPAN_NOTICE("\The [user] unsecures \the [src]'s reinforcing bolts from the wall."), \
SPAN_NOTICE("You undo \the [src]'s external reinforcing bolts."), \
SPAN_WARNING("You hear a ratcheting noise."))
state = FUEL_PORT_UNSECURED
if(FUEL_PORT_UNSECURED)
attacking_item.play_tool_sound(get_turf(src), 75)
user.visible_message(SPAN_NOTICE("\The [user] secures \the [src] to the wall."), \
SPAN_NOTICE("You secure \the [src]'s external reinforcing bolts."), \
SPAN_WARNING("You hear a ratcheting noise."))
state = FUEL_PORT_BOLTED
else if(attacking_item.iswelder())
var/obj/item/weldingtool/WT = attacking_item
switch(state)
if(FUEL_PORT_UNSECURED)
to_chat(user, SPAN_WARNING("\The [src]'s external reinforcing bolts must be secured!"))
return
if(FUEL_PORT_BOLTED)
if(WT.use(5, user))
playsound(get_turf(src), 'sound/items/welder_pry.ogg', 50, TRUE)
user.visible_message(SPAN_NOTICE("\The [user] starts to weld \the [src] to the wall."), \
SPAN_NOTICE("You start to weld \the [src] to the wall."), \
SPAN_WARNING("You hear the sound of metal being welded."))
if(attacking_item.use_tool(src, user, 20, volume = 50))
if(!src || !WT.isOn())
return
state = FUEL_PORT_WELDED
to_chat(user, SPAN_NOTICE("You weld \the [src] to the wall."))
else
to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
if(FUEL_PORT_WELDED)
if(contents.len > 0)
to_chat(user, SPAN_WARNING("\The [src] cannot be detached with a tank inside!"))
return
if(WT.use(0, user))
playsound(get_turf(src), 'sound/items/welder_pry.ogg', 50, TRUE)
user.visible_message(SPAN_NOTICE("\The [user] starts to cut \the [src] free from the wall."), \
SPAN_NOTICE("You start to cut \the [src] free from the wall."), \
SPAN_WARNING("You hear the sound of metal being welded."))
if(attacking_item.use_tool(src, user, 20, volume = 50))
if(!src || !WT.isOn())
return
state = FUEL_PORT_BOLTED
to_chat(user, SPAN_NOTICE("You cut \the [src] free from the wall."))
else
to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
update_icon()
/obj/structure/fuel_port/proc/update_shuttle()
var/area/A = get_area(src)
if(A in SSshuttle.shuttle_areas) //Check if we're in a shuttle and refresh its fuel ports
for(var/shuttle_tag in SSshuttle.shuttles)
var/datum/shuttle/autodock/overmap/S = SSshuttle.shuttles[shuttle_tag]
if(istype(S) && (A in S.shuttle_area))
S.refresh_fuel_ports_list()
// Walls hide stuff inside them, but we want to be visible.
/obj/structure/fuel_port/hide()
return
/obj/structure/fuel_port/phoron // The best and most expensive fuel. Likely to be in the hands of corporate forces, though the well-off along with military forces throughout the Spur also have a good chance of using it.
/obj/structure/fuel_port/phoron/scc
icon = 'icons/obj/spaceship/scc/ship_engine.dmi'
/obj/structure/fuel_port/phoron/Initialize()
. = ..()
new /obj/item/tank/phoron/shuttle(src)
/obj/structure/fuel_port/hydrogen // The most common and serviceable fuel for a shuttle. It's not as good as phoron, but it will still get you places. It's also not scarce! Used by practically everyone.
/obj/structure/fuel_port/hydrogen/Initialize()
. = ..()
new /obj/item/tank/hydrogen/shuttle(src)
/obj/item/fuel_port
name = "fuel port"
desc = "The fuel input port of the shuttle. Must be attached to a wall."
icon = 'icons/turf/shuttle.dmi'
icon_state = "fuel_port"
item_state = "fuel_port"
var/port_path = /obj/structure/fuel_port
/obj/item/fuel_port/afterattack(atom/A, mob/user, proximity_flag, click_parameters)
if(!proximity_flag)
return
if(use_check_and_message(user))
return
if(!iswall(A) || !isturf(user.loc))
to_chat(user, SPAN_WARNING("You can't place this here!"))
return
if(get_area(A) != get_area(user)) //To make sure that we don't get fuel ports attached outside the shuttle area, etc
to_chat(user, SPAN_WARNING("You must be in the same area as the target location to attach \the [src]!"))
return
var/placement_dir = get_dir(user, A)
if (!(placement_dir in GLOB.cardinals))
to_chat(user, SPAN_WARNING("You must stand directly in front of the location you wish to place that on."))
return
user.visible_message(SPAN_NOTICE("\The [user] fastens \the [src] to \the [A]."), SPAN_NOTICE("You fasten \the [src] to \the [A]."))
user.drop_from_inventory(src)
new port_path(user.loc, placement_dir, TRUE)
qdel(src)
#undef FUEL_PORT_UNSECURED
#undef FUEL_PORT_BOLTED
#undef FUEL_PORT_WELDED
#undef waypoint_sector