mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Cleaned out my WIP folder.
This commit is contained in:
104
code/modules/overmap/README.dm
Normal file
104
code/modules/overmap/README.dm
Normal 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
|
||||
*/
|
||||
101
code/modules/overmap/_defines.dm
Normal file
101
code/modules/overmap/_defines.dm
Normal 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
|
||||
124
code/modules/overmap/sectors.dm
Normal file
124
code/modules/overmap/sectors.dm
Normal 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
|
||||
99
code/modules/overmap/ships/computers/engine_control.dm
Normal file
99
code/modules/overmap/ships/computers/engine_control.dm
Normal 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()
|
||||
174
code/modules/overmap/ships/computers/helm.dm
Normal file
174
code/modules/overmap/ships/computers/helm.dm
Normal 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()
|
||||
|
||||
139
code/modules/overmap/ships/computers/shuttle.dm
Normal file
139
code/modules/overmap/ships/computers/shuttle.dm
Normal 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)
|
||||
60
code/modules/overmap/ships/engines/engine.dm
Normal file
60
code/modules/overmap/ships/engines/engine.dm
Normal 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)
|
||||
99
code/modules/overmap/ships/engines/thermal.dm
Normal file
99
code/modules/overmap/ships/engines/thermal.dm
Normal 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
|
||||
105
code/modules/overmap/ships/ship.dm
Normal file
105
code/modules/overmap/ships/ship.dm
Normal 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)
|
||||
Reference in New Issue
Block a user