Cleaned out my WIP folder.

This commit is contained in:
Chinsky
2015-02-03 08:27:18 +03:00
parent 7b3c3cf600
commit 2a1f0849d8
12 changed files with 10 additions and 11 deletions

View File

@@ -0,0 +1,104 @@
/*
The overmap system allows adding new maps to the big 'galaxy' map.
Idea is that new sectors can be added by just ticking in new maps and recompiling.
Not real hot-plugging, but still pretty modular.
It uses the fact that all ticked in .dme maps are melded together into one as different zlevels.
Metaobjects are used to make it not affected by map order in .dme and carry some additional info.
*************************************************************
Metaobject
*************************************************************
/obj/effect/mapinfo, sectors.dm
Used to build overmap in beginning, has basic information needed to create overmap objects and make shuttles work.
Its name and icon (if non-standard) vars will be applied to resulting overmap object.
'mapy' and 'mapx' vars are optional, sector will be assigned random overmap coordinates if they are not set.
Has two important vars:
obj_type - type of overmap object it spawns. Could be overriden for custom overmap objects.
landing_area - type of area used as inbound shuttle landing, null if no shuttle landing area.
Object could be placed anywhere on zlevel. Should only be placed on zlevel that should appear on overmap as a separate entitety.
Right after creation it sends itself to nullspace and creates an overmap object, corresponding to this zlevel.
*************************************************************
Overmap object
*************************************************************
/obj/effect/map, sectors.dm
Represents a zlevel on the overmap. Spawned by metaobjects at the startup.
var/area/shuttle/shuttle_landing - keeps a reference to the area of where inbound shuttles should land
-CanPass should be overriden for access restrictions
-Crossed/Uncrossed can be overriden for applying custom effects.
Remember to call ..() in children, it updates ship's current sector.
subtype /ship of this object represents spacefaring vessels.
It has 'current_sector' var that keeps refernce to, well, sector ship currently in.
*************************************************************
Helm console
*************************************************************
/obj/machinery/computer/helm, helm.dm
On creation console seeks a ship overmap object corresponding to this zlevel and links it.
Clicking with empty hand on it starts steering, Cancel-Camera-View stops it.
Helm console relays movement of mob to the linked overmap object.
Helm console currently has no interface. All travel happens instanceously too.
Sector shuttles are not supported currently, only ship shuttles.
*************************************************************
Exploration shuttle terminal
*************************************************************
A generic shuttle controller.
Has a var landing_type defining type of area shuttle should be landing at.
On initalizing, checks for a shuttle corresponding to this zlevel, and creates one if it's not there.
Changes desitnation area depending on current sector ship is in.
Currently updating is called in attack_hand(), until a better place is found.
Currently no modifications were made to interface to display availability of landing area in sector.
*************************************************************
Guide to how make new sector
*************************************************************
0.Map
Remember to define shuttle areas if you want sector be accessible via shuttles.
Currently there are no other ways to reach sectors from ships.
In examples, 4x6 shuttle area is used. In case of shuttle area being too big, it will apear in bottom left corner of it.
Remember to put a helm console and engine control console on ship maps.
Ships need engines to move. Currently there are only thermal engines.
Thermal engines are just a unary atmopheric machine, like a vent. They need high-pressure gas input to produce more thrust.
1.Metaobject
All vars needed for it to work could be set directly in map editor, so in most cases you won't have to define new in code.
Remember to set landing_area var for sectors.
2.Overmap object
If you need custom behaviour on entering/leaving this sector, or restricting access to it, you can define your custom map object.
Remember to put this new type into spawn_type var of metaobject.
3.Shuttle console
Remember to place one on the actual shuttle too, or it won't be able to return from sector without ship-side recall.
Remember to set landing_type var to ship-side shuttle area type.
shuttle_tag can be set to custom name (it shows up in console interface)
5.Engines
Actual engines could be any type of machinery, as long as it creates a ship_engine datum for itself.
6.Tick map in and compile.
Sector should appear on overmap (in random place if you didn't set mapx,mapy)
TODO:
shuttle console:
checking occupied pad or not with docking controllers
?landing pad size detection
non-zlevel overmap objects
field generator
meteor fields
speed-based chance for a rock in the ship
debris fields
speed-based chance of
debirs in the ship
a drone
EMP
nebulaes
*/

View File

@@ -0,0 +1,101 @@
//Zlevel where overmap objects should be
#define OVERMAP_ZLEVEL 1
//How far from the edge of overmap zlevel could randomly placed objects spawn
#define OVERMAP_EDGE 7
//list used to track which zlevels are being 'moved' by the proc below
var/list/moving_levels = list()
//Proc to 'move' stars in spess
//yes it looks ugly, but it should only fire when state actually change.
//null direction stops movement
proc/toggle_move_stars(zlevel, direction)
if(!zlevel)
return
var/gen_dir = null
if(direction & (NORTH|SOUTH))
gen_dir += "ns"
else if(direction & (EAST|WEST))
gen_dir += "ew"
if(!direction)
gen_dir = null
if (moving_levels["zlevel"] != gen_dir)
moving_levels["zlevel"] = gen_dir
for(var/turf/space/S in world)
if(S.z == zlevel)
spawn(0)
var/turf/T = S
if(!gen_dir)
T.icon_state = "[((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25]"
else
T.icon_state = "speedspace_[gen_dir]_[rand(1,15)]"
for(var/atom/movable/AM in T)
if (!AM.anchored)
AM.throw_at(get_step(T,reverse_direction(direction)), 5, 1)
//list used to cache empty zlevels to avoid nedless map bloat
var/list/cached_space = list()
proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A)
var/obj/effect/map/M = map_sectors["[T.z]"]
if (!M)
return
var/mapx = M.x
var/mapy = M.y
var/nx = 1
var/ny = 1
var/nz = M.map_z
if(T.x <= TRANSITIONEDGE)
nx = world.maxx - TRANSITIONEDGE - 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = max(1, mapx-1)
else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
nx = TRANSITIONEDGE + 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = min(world.maxx, mapx+1)
else if (T.y <= TRANSITIONEDGE)
ny = world.maxy - TRANSITIONEDGE -2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = max(1, mapy-1)
else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
ny = TRANSITIONEDGE + 2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = min(world.maxy, mapy+1)
testing("[A] moving from [M] ([M.x], [M.y]) to ([mapx],[mapy]).")
var/turf/map = locate(mapx,mapy,OVERMAP_ZLEVEL)
var/obj/effect/map/TM = locate() in map
if(TM)
nz = TM.map_z
testing("Destination: [TM]")
else
if(cached_space.len)
var/obj/effect/map/sector/temporary/cache = cached_space[cached_space.len]
cached_space -= cache
nz = cache.map_z
cache.x = mapx
cache.y = mapy
testing("Destination: *cached* [TM]")
else
world.maxz++
nz = world.maxz
TM = new /obj/effect/map/sector/temporary(mapx, mapy, nz)
testing("Destination: *new* [TM]")
var/turf/dest = locate(nx,ny,nz)
if(dest)
A.loc = dest
if(istype(M, /obj/effect/map/sector/temporary))
var/obj/effect/map/sector/temporary/source = M
if (source.can_die())
testing("Catching [M] for future use")
source.loc = null
cached_space += source

View File

@@ -0,0 +1,124 @@
//===================================================================================
//Hook for building overmap
//===================================================================================
var/global/list/map_sectors = list()
/hook/startup/proc/build_map()
if(!config.use_overmap)
return 1
testing("Building overmap...")
var/obj/effect/mapinfo/data
for(var/level in 1 to world.maxz)
data = locate("sector[level]")
if (data)
testing("Located sector \"[data.name]\" at [data.mapx],[data.mapy] corresponding to zlevel [level]")
map_sectors["[level]"] = new data.obj_type(data)
return 1
//===================================================================================
//Metaobject for storing information about sector this zlevel is representing.
//Should be placed only once on every zlevel.
//===================================================================================
/obj/effect/mapinfo/
name = "map info metaobject"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
invisibility = 101
var/obj_type //type of overmap object it spawns
var/landing_area //type of area used as inbound shuttle landing, null if no shuttle landing area
var/zlevel
var/mapx //coordinates on the
var/mapy //overmap zlevel
var/known = 1
/obj/effect/mapinfo/New()
tag = "sector[z]"
zlevel = z
loc = null
/obj/effect/mapinfo/sector
name = "generic sector"
obj_type = /obj/effect/map/sector
/obj/effect/mapinfo/ship
name = "generic ship"
obj_type = /obj/effect/map/ship
//===================================================================================
//Overmap object representing zlevel
//===================================================================================
/obj/effect/map
name = "map object"
icon = 'icons/obj/items.dmi'
icon_state = "sheet-plasteel"
var/map_z = 0
var/area/shuttle/shuttle_landing
var/always_known = 1
/obj/effect/map/New(var/obj/effect/mapinfo/data)
map_z = data.zlevel
name = data.name
always_known = data.known
if (data.icon != 'icons/mob/screen1.dmi')
icon = data.icon
icon_state = data.icon_state
if(data.desc)
desc = data.desc
var/new_x = data.mapx ? data.mapx : rand(OVERMAP_EDGE, world.maxx - OVERMAP_EDGE)
var/new_y = data.mapy ? data.mapy : rand(OVERMAP_EDGE, world.maxy - OVERMAP_EDGE)
loc = locate(new_x, new_y, OVERMAP_ZLEVEL)
if(data.landing_area)
shuttle_landing = locate(data.landing_area)
/obj/effect/map/CanPass(atom/movable/A)
testing("[A] attempts to enter sector\"[name]\"")
return 1
/obj/effect/map/Crossed(atom/movable/A)
testing("[A] has entered sector\"[name]\"")
if (istype(A,/obj/effect/map/ship))
var/obj/effect/map/ship/S = A
S.current_sector = src
/obj/effect/map/Uncrossed(atom/movable/A)
testing("[A] has left sector\"[name]\"")
if (istype(A,/obj/effect/map/ship))
var/obj/effect/map/ship/S = A
S.current_sector = null
/obj/effect/map/sector
name = "generic sector"
desc = "Sector with some stuff in it."
anchored = 1
//Space stragglers go here
/obj/effect/map/sector/temporary
name = "Deep Space"
icon_state = ""
always_known = 0
/obj/effect/map/sector/temporary/New(var/nx, var/ny, var/nz)
loc = locate(nx, ny, OVERMAP_ZLEVEL)
map_z = nz
map_sectors["[map_z]"] = src
testing("Temporary sector at [x],[y] was created, corresponding zlevel is [map_z].")
/obj/effect/map/sector/temporary/Del()
map_sectors["[map_z]"] = null
testing("Temporary sector at [x],[y] was deleted.")
if (can_die())
testing("Associated zlevel disappeared.")
world.maxz--
/obj/effect/map/sector/temporary/proc/can_die(var/mob/observer)
testing("Checking if sector at [map_z] can die.")
for(var/mob/M in player_list)
if(M != observer && M.z == map_z)
testing("There are people on it.")
return 0
return 1

View File

@@ -0,0 +1,99 @@
//Engine control and monitoring console
/obj/machinery/computer/engines
name = "engine control console"
icon_state = "id"
var/state = "status"
var/list/engines = list()
var/obj/effect/map/ship/linked
/obj/machinery/computer/engines/initialize()
linked = map_sectors["[z]"]
if (linked)
if (!linked.eng_control)
linked.eng_control = src
testing("Engines console at level [z] found a corresponding overmap object '[linked.name]'.")
else
testing("Engines console at level [z] was unable to find a corresponding overmap object.")
for(var/datum/ship_engine/E in engines)
if (E.zlevel == z && !(E in engines))
engines += E
/obj/machinery/computer/engines/attack_hand(var/mob/user as mob)
if(..())
user.unset_machine()
return
if(!isAI(user))
user.set_machine(src)
ui_interact(user)
/obj/machinery/computer/engines/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!linked)
return
var/data[0]
data["state"] = state
var/list/enginfo[0]
for(var/datum/ship_engine/E in engines)
var/list/rdata[0]
rdata["eng_type"] = E.name
rdata["eng_on"] = E.is_on()
rdata["eng_thrust"] = E.get_thrust()
rdata["eng_thrust_limiter"] = round(E.get_thrust_limit()*100)
rdata["eng_status"] = E.get_status()
rdata["eng_reference"] = "\ref[E]"
enginfo.Add(list(rdata))
data["engines_info"] = enginfo
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "engines_control.tmpl", "[linked.name] Engines Control", 380, 530)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/engines/Topic(href, href_list)
if(..())
return
if(href_list["state"])
state = href_list["state"]
if(href_list["engine"])
if(href_list["set_limit"])
var/datum/ship_engine/E = locate(href_list["engine"])
var/newlim = input("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
var/limit = Clamp(newlim/100, 0, 1)
if(E)
E.set_thrust_limit(limit)
if(href_list["limit"])
var/datum/ship_engine/E = locate(href_list["engine"])
var/limit = Clamp(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1)
if(E)
E.set_thrust_limit(limit)
if(href_list["toggle"])
var/datum/ship_engine/E = locate(href_list["engine"])
if(E)
E.toggle()
add_fingerprint(usr)
updateUsrDialog()
/obj/machinery/computer/engines/proc/burn()
if(engines.len == 0)
return 0
var/res = 0
for(var/datum/ship_engine/E in engines)
res |= E.burn()
return res
/obj/machinery/computer/engines/proc/get_total_thrust()
for(var/datum/ship_engine/E in engines)
. += E.get_thrust()

View File

@@ -0,0 +1,174 @@
/obj/machinery/computer/helm
name = "helm control console"
icon_state = "id"
var/state = "status"
var/obj/effect/map/ship/linked //connected overmap object
var/autopilot = 0
var/manual_control = 0
var/list/known_sectors = list()
var/dx //desitnation
var/dy //coordinates
/obj/machinery/computer/helm/initialize()
linked = map_sectors["[z]"]
if (linked)
if(!linked.nav_control)
linked.nav_control = src
testing("Helm console at level [z] found a corresponding overmap object '[linked.name]'.")
else
testing("Helm console at level [z] was unable to find a corresponding overmap object.")
for(var/level in map_sectors)
var/obj/effect/map/sector/S = map_sectors["[level]"]
if (istype(S) && S.always_known)
var/datum/data/record/R = new()
R.fields["name"] = S.name
R.fields["x"] = S.x
R.fields["y"] = S.y
known_sectors += R
/obj/machinery/computer/helm/process()
..()
if (autopilot && dx && dy)
var/turf/T = locate(dx,dy,1)
if(linked.loc == T)
if(linked.is_still())
autopilot = 0
else
linked.decelerate()
var/brake_path = linked.get_brake_path()
if(get_dist(linked.loc, T) > brake_path)
linked.accelerate(get_dir(linked.loc, T))
else
linked.decelerate()
return
/obj/machinery/computer/helm/relaymove(var/mob/user, direction)
if(manual_control && linked)
linked.relaymove(user,direction)
return 1
/obj/machinery/computer/helm/check_eye(var/mob/user as mob)
if (!manual_control)
return null
if (!get_dist(user, src) > 1 || user.blinded || !linked )
return null
user.reset_view(linked)
return 1
/obj/machinery/computer/helm/attack_hand(var/mob/user as mob)
if(..())
user.unset_machine()
manual_control = 0
return
if(!isAI(user))
user.set_machine(src)
ui_interact(user)
/obj/machinery/computer/helm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!linked)
return
var/data[0]
data["state"] = state
data["sector"] = linked.current_sector ? linked.current_sector.name : "Deep Space"
data["sector_info"] = linked.current_sector ? linked.current_sector.desc : "Not Available"
data["s_x"] = linked.x
data["s_y"] = linked.y
data["dest"] = dy && dx
data["d_x"] = dx
data["d_y"] = dy
data["speed"] = linked.get_speed()
data["accel"] = round(linked.get_acceleration())
data["heading"] = linked.get_heading() ? dir2angle(linked.get_heading()) : 0
data["autopilot"] = autopilot
data["manual_control"] = manual_control
var/list/locations[0]
for (var/datum/data/record/R in known_sectors)
var/list/rdata[0]
rdata["name"] = R.fields["name"]
rdata["x"] = R.fields["x"]
rdata["y"] = R.fields["y"]
rdata["reference"] = "\ref[R]"
locations.Add(list(rdata))
data["locations"] = locations
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "helm.tmpl", "[linked.name] Helm Control", 380, 530)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/helm/Topic(href, href_list)
if(..())
return
if (!linked)
return
if (href_list["add"])
var/datum/data/record/R = new()
var/sec_name = input("Input naviation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
if(!sec_name)
sec_name = "Sector #[known_sectors.len]"
R.fields["name"] = sec_name
switch(href_list["add"])
if("current")
R.fields["x"] = linked.x
R.fields["y"] = linked.y
if("new")
var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
R.fields["x"] = Clamp(newx, 1, world.maxx)
var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
R.fields["y"] = Clamp(newy, 1, world.maxy)
known_sectors += R
if (href_list["remove"])
var/datum/data/record/R = locate(href_list["remove"])
known_sectors.Remove(R)
if (href_list["setx"])
var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null
if (newx)
dx = Clamp(newx, 1, world.maxx)
if (href_list["sety"])
var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null
if (newy)
dy = Clamp(newy, 1, world.maxy)
if (href_list["x"] && href_list["y"])
dx = text2num(href_list["x"])
dy = text2num(href_list["y"])
if (href_list["reset"])
dx = 0
dy = 0
if (href_list["move"])
var/ndir = text2num(href_list["move"])
linked.relaymove(usr, ndir)
if (href_list["brake"])
linked.decelerate()
if (href_list["apilot"])
autopilot = !autopilot
if (href_list["manual"])
manual_control = !manual_control
if (href_list["state"])
state = href_list["state"]
add_fingerprint(usr)
updateUsrDialog()

View File

@@ -0,0 +1,139 @@
//Shuttle controller computer for shuttles going between sectors
/datum/shuttle/ferry/var/range = 0 //how many overmap tiles can shuttle go, for picking destinatiosn and returning.
/obj/machinery/computer/shuttle_control/explore
name = "exploration shuttle console"
shuttle_tag = "Exploration"
req_access = list()
var/landing_type //area for shuttle ship-side
var/obj/effect/map/destination //current destination
var/obj/effect/map/home //current destination
/obj/machinery/computer/shuttle_control/explore/initialize()
..()
home = map_sectors["[z]"]
shuttle_tag = "[shuttle_tag]-[z]"
if(!shuttle_controller.shuttles[shuttle_tag])
var/datum/shuttle/ferry/shuttle = new()
shuttle.warmup_time = 10
shuttle.area_station = locate(landing_type)
shuttle.area_offsite = shuttle.area_station
shuttle_controller.shuttles[shuttle_tag] = shuttle
shuttle_controller.process_shuttles += shuttle
testing("Exploration shuttle '[shuttle_tag]' at zlevel [z] successfully added.")
//Sets destination to new sector. Can be null.
/obj/machinery/computer/shuttle_control/explore/proc/update_destination(var/obj/effect/map/D)
destination = D
if(destination && shuttle_controller.shuttles[shuttle_tag])
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
shuttle.area_offsite = destination.shuttle_landing
testing("Shuttle controller [shuttle_tag] now sends shuttle to [destination]")
shuttle_controller.shuttles[shuttle_tag] = shuttle
//Gets all sectors with landing zones in shuttle's range
/obj/machinery/computer/shuttle_control/explore/proc/get_possible_destinations()
var/list/res = list()
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
for (var/obj/effect/map/S in orange(shuttle.range, home))
if(S.shuttle_landing)
res += S
return res
//Checks if current destination is still reachable
/obj/machinery/computer/shuttle_control/explore/proc/check_destination()
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
return shuttle && destination && get_dist(home, destination) <= shuttle.range
/obj/machinery/computer/shuttle_control/explore/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
if (!istype(shuttle))
return
//If we are already there, or can't reach place anymore, reset destination
if(!shuttle.location && !check_destination())
destination = null
//check if shuttle can fly at all
var/can_go = !isnull(destination)
var/current_destination = destination ? destination.name : "None"
//shuttle doesn't need destination set to return home, as long as it's in range.
if(shuttle.location)
current_destination = "Return"
var/area/offsite = shuttle.area_offsite
var/obj/effect/map/cur_loc = map_sectors["[offsite.z]"]
can_go = (get_dist(home,cur_loc) <= shuttle.range)
//disable picking locations if there are none, or shuttle is already off-site
var/list/possible_d = get_possible_destinations()
var/can_pick = !shuttle.location && possible_d.len
var/shuttle_state
switch(shuttle.moving_status)
if(SHUTTLE_IDLE) shuttle_state = "idle"
if(SHUTTLE_WARMUP) shuttle_state = "warmup"
if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit"
var/shuttle_status
switch (shuttle.process_state)
if(IDLE_STATE)
if (shuttle.in_use)
shuttle_status = "Busy."
else if (!shuttle.location)
shuttle_status = "Standing-by at station."
else
shuttle_status = "Standing-by at offsite location."
if(WAIT_LAUNCH, FORCE_LAUNCH)
shuttle_status = "Shuttle has recieved command and will depart shortly."
if(WAIT_ARRIVE)
shuttle_status = "Proceeding to destination."
if(WAIT_FINISH)
shuttle_status = "Arriving at destination now."
data = list(
"destination_name" = current_destination,
"can_pick" = can_pick,
"shuttle_status" = shuttle_status,
"shuttle_state" = shuttle_state,
"has_docking" = shuttle.docking_controller? 1 : 0,
"docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null,
"docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null,
"can_launch" = can_go && shuttle.can_launch(),
"can_cancel" = can_go && shuttle.can_cancel(),
"can_force" = can_go && shuttle.can_force(),
)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "shuttle_control_console_exploration.tmpl", "[shuttle_tag] Shuttle Control", 470, 310)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/shuttle_control/explore/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
src.add_fingerprint(usr)
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
if (!istype(shuttle))
return
if(href_list["pick"])
var/obj/effect/map/self = map_sectors["[z]"]
if(self)
var/list/possible_d = get_possible_destinations()
var/obj/effect/map/D
if(possible_d.len)
D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d
update_destination(D)
if(href_list["move"])
shuttle.launch(src)
if(href_list["force"])
shuttle.force_launch(src)
else if(href_list["cancel"])
shuttle.cancel_launch(src)

View File

@@ -0,0 +1,60 @@
//Engine component object
var/list/ship_engines = list()
/datum/ship_engine
var/name = "ship engine"
var/obj/machinery/engine //actual engine object
var/zlevel = 0
/datum/ship_engine/New(var/obj/machinery/holder)
engine = holder
zlevel = holder.z
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == zlevel && !(src in E.engines))
E.engines += src
break
//Tries to fire the engine. If successfull, returns 1
/datum/ship_engine/proc/burn()
if(!engine)
die()
return 1
//Returns status string for this engine
/datum/ship_engine/proc/get_status()
if(!engine)
die()
return "All systems nominal"
/datum/ship_engine/proc/get_thrust()
if(!engine)
die()
return 100
//Sets thrust limiter, a number between 0 and 1
/datum/ship_engine/proc/set_thrust_limit(var/new_limit)
if(!engine)
die()
return 1
/datum/ship_engine/proc/get_thrust_limit()
if(!engine)
die()
return 1
/datum/ship_engine/proc/is_on()
if(!engine)
die()
return 1
/datum/ship_engine/proc/toggle()
if(!engine)
die()
return 1
/datum/ship_engine/proc/die()
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == zlevel)
E.engines -= src
break
del(src)

View File

@@ -0,0 +1,99 @@
//Thermal nozzle engine
/datum/ship_engine/thermal
name = "thermal engine"
/datum/ship_engine/thermal/get_status()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return "Fuel pressure: [E.air_contents.return_pressure()]"
/datum/ship_engine/thermal/get_thrust()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
if(!is_on())
return 0
var/pressurized_coef = E.air_contents.return_pressure()/E.effective_pressure
return round(E.thrust_limit * E.nominal_thrust * pressurized_coef)
/datum/ship_engine/thermal/burn()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.burn()
/datum/ship_engine/thermal/set_thrust_limit(var/new_limit)
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
E.thrust_limit = new_limit
/datum/ship_engine/thermal/get_thrust_limit()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.thrust_limit
/datum/ship_engine/thermal/is_on()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.on
/datum/ship_engine/thermal/toggle()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
E.on = !E.on
//Actual thermal nozzle engine object
/obj/machinery/atmospherics/unary/engine
name = "engine nozzle"
desc = "Simple thermal nozzle, uses heated gast to propell the ship."
icon = 'icons/obj/ship_engine.dmi'
icon_state = "nozzle"
var/on = 1
var/thrust_limit = 1 //Value between 1 and 0 to limit the resulting thrust
var/nominal_thrust = 3000
var/effective_pressure = 3000
var/datum/ship_engine/thermal/controller
/obj/machinery/atmospherics/unary/engine/initialize()
..()
controller = new(src)
/obj/machinery/atmospherics/unary/engine/Del()
..()
controller.die()
/obj/machinery/atmospherics/unary/engine/proc/burn()
if (!on)
return
if(air_contents.temperature > 0)
var/transfer_moles = 100 * air_contents.volume/max(air_contents.temperature * R_IDEAL_GAS_EQUATION, 0,01)
transfer_moles = round(thrust_limit * transfer_moles, 0.01)
if(transfer_moles > air_contents.total_moles)
on = !on
return 0
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
if(air_contents.temperature > PHORON_MINIMUM_BURN_TEMPERATURE)
var/exhaust_dir = reverse_direction(dir)
var/turf/T = get_step(src,exhaust_dir)
if(T)
new/obj/effect/engine_exhaust(T,exhaust_dir,air_contents.temperature)
return 1
//Exhaust effect
/obj/effect/engine_exhaust
name = "engine exhaust"
icon = 'icons/effects/effects.dmi'
icon_state = "exhaust"
anchored = 1
New(var/turf/nloc, var/ndir, var/temp)
set_dir(ndir)
..(nloc)
if(nloc)
nloc.hotspot_expose(temp,125)
spawn(20)
loc = null

View File

@@ -0,0 +1,105 @@
/obj/effect/map/ship
name = "generic ship"
desc = "Space faring vessel."
icon_state = "sheet-sandstone"
var/vessel_mass = 9000 //tonnes, random number
var/default_delay = 60
var/list/speed = list(0,0)
var/last_burn = 0
var/list/last_movement = list(0,0)
var/fore_dir = NORTH
var/obj/effect/map/current_sector
var/obj/machinery/computer/helm/nav_control
var/obj/machinery/computer/engines/eng_control
/obj/effect/map/ship/initialize()
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == map_z)
eng_control = E
break
for(var/obj/machinery/computer/helm/H in machines)
if (H.z == map_z)
nav_control = H
break
processing_objects.Add(src)
/obj/effect/map/ship/relaymove(mob/user, direction)
accelerate(direction)
/obj/effect/map/ship/proc/is_still()
return !(speed[1] || speed[2])
/obj/effect/map/ship/proc/get_acceleration()
return eng_control.get_total_thrust()/vessel_mass
/obj/effect/map/ship/proc/get_speed()
return round(sqrt(speed[1]*speed[1] + speed[2]*speed[2]))
/obj/effect/map/ship/proc/get_heading()
var/res = 0
if(speed[1])
if(speed[1] > 0)
res |= EAST
else
res |= WEST
if(speed[2])
if(speed[2] > 0)
res |= NORTH
else
res |= SOUTH
return res
/obj/effect/map/ship/proc/adjust_speed(n_x, n_y)
speed[1] = Clamp(speed[1] + n_x, -default_delay, default_delay)
speed[2] = Clamp(speed[2] + n_y, -default_delay, default_delay)
if(is_still())
toggle_move_stars(map_z)
else
toggle_move_stars(map_z, fore_dir)
/obj/effect/map/ship/proc/can_burn()
if (!eng_control)
return 0
if (world.time < last_burn + 10)
return 0
if (!eng_control.burn())
return 0
return 1
/obj/effect/map/ship/proc/get_brake_path()
if(!get_acceleration())
return INFINITY
return max(abs(speed[1]),abs(speed[2]))/get_acceleration()
/obj/effect/map/ship/proc/decelerate()
if(!is_still() && can_burn())
if (speed[1])
adjust_speed(-SIGN(speed[1]) * min(get_acceleration(),speed[1]), 0)
if (speed[2])
adjust_speed(0, -SIGN(speed[2]) * min(get_acceleration(),speed[2]))
last_burn = world.time
/obj/effect/map/ship/proc/accelerate(direction)
if(can_burn())
last_burn = world.time
if(direction & EAST)
adjust_speed(get_acceleration(), 0)
if(direction & WEST)
adjust_speed(-get_acceleration(), 0)
if(direction & NORTH)
adjust_speed(0, get_acceleration())
if(direction & SOUTH)
adjust_speed(0, -get_acceleration())
/obj/effect/map/ship/process()
if(!is_still())
var/list/deltas = list(0,0)
for(var/i=1, i<=2, i++)
if(speed[i] && world.time > last_movement[i] + default_delay - speed[i])
deltas[i] = speed[i] > 0 ? 1 : -1
last_movement[i] = world.time
var/turf/newloc = locate(x + deltas[1], y + deltas[2], z)
if(newloc)
Move(newloc)