diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 5693ab50842..1554b1e728b 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -34,6 +34,7 @@ //turf-only flags #define NOJAUNT 1 +#define UNUSED_TRANSIT_TURF 2 /* These defines are used specifically with the atom/pass_flags bitmask diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 66a58345b70..03212bb81b3 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -13,6 +13,7 @@ #define EMERGENCY_AT_LEAST_DOCKED (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_IDLE && SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_CALL) // Shuttle return values +#define SHUTTLE_CAN_DOCK "can_dock" #define SHUTTLE_NOT_A_DOCKING_PORT "not_a_docking_port" #define SHUTTLE_DWIDTH_TOO_LARGE "docking_width_too_large" #define SHUTTLE_WIDTH_TOO_LARGE "width_too_large" @@ -30,3 +31,7 @@ // Ripples, effects that signal a shuttle's arrival #define SHUTTLE_RIPPLE_TIME 100 #define SHUTTLE_RIPPLE_FADEIN 50 + +#define TRANSIT_REQUEST 1 +#define TRANSIT_READY 2 +#define TRANSIT_FULL 3 diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 8dc1b168856..0a8fd071163 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -13,7 +13,6 @@ var/datum/subsystem/shuttle/SSshuttle var/list/transit = list() var/list/turf/transit_turfs = list() - var/list/turf/transit_turfs_in_use = list() //emergency shuttle stuff var/obj/docking_port/mobile/emergency/emergency @@ -67,9 +66,12 @@ var/datum/subsystem/shuttle/SSshuttle for(var/i in block(A, B)) var/turf/T = i transit_turfs += T + T.flags |= UNUSED_TRANSIT_TURF #ifdef HIGHLIGHT_DYNAMIC_TRANSIT if((T.x == A.x) || (T.x == B.x) || (T.y == A.y) || (T.y == B.y)) T.color = "#ffff00" + else + T.color = "#00ffff" #endif world.log << "[transit_turfs.len] transit turfs registered" @@ -234,60 +236,43 @@ var/datum/subsystem/shuttle/SSshuttle /datum/subsystem/shuttle/proc/requestTransitZone(obj/docking_port/mobile/M) // First, determine the size of the needed zone - var/transit_width = M.width + 14 // view range is 7, both ways is 14 - var/transit_height = M.height + 14 + var/transit_width = M.width + M.dwidth + 14 + var/transit_height = M.height + M.dheight + 14 // Then find a place to put the zone world << "Transit requested for [M]" - CHECK_TICK - var/list/availible = transit_turfs - transit_turfs_in_use - CHECK_TICK - - world << "There are [availible.len] turfs that are free" - var/list/proposed_zone - for(var/i in shuffle(availible)) - var/turf/topleft = i - world << "Trying [COORD(topleft)]" - CHECK_TICK - var/turf/bottomright = locate(topleft.x + transit_width, - topleft.y + transit_height, topleft.z) - if(!bottomright) - continue - CHECK_TICK - if(!(bottomright in transit_turfs)) - world << "Bottomright [COORD(bottomright)] not in \ - transit_turfs, trying another topleft" - continue - CHECK_TICK - if(bottomright in transit_turfs_in_use) - world << "Bottomright [COORD(bottomright)] in use..." - continue - CHECK_TICK - proposed_zone = block(topleft, bottomright) - CHECK_TICK - world << "Proposed zone of [proposed_zone.len] turfs made" - CHECK_TICK - if(!proposed_zone) - world << "Proposed zone was null." - continue - var/list/L - CHECK_TICK - L = proposed_zone | transit_turfs_in_use - if(L.len) - world << "Proposed zone contains in use turfs, continuing" - continue - CHECK_TICK - break + base: + for(var/i in transit_turfs) + CHECK_TICK + var/turf/topleft = i + if(!(topleft.flags & UNUSED_TRANSIT_TURF)) + world << "Topleft [COORD(topleft)] is used" + var/turf/bottomright = locate(topleft.x + transit_width, + topleft.y + transit_height, topleft.z) + if(!bottomright) + continue + if(!(bottomright.flags & UNUSED_TRANSIT_TURF)) + world << "Bottomright [COORD(bottomright)] is used." + continue + + proposed_zone = block(topleft, bottomright) + world << "Proposed zone of [proposed_zone.len] turfs made" + if(!proposed_zone) + world << "Proposed zone was null." + continue + for(var/j in proposed_zone) + var/turf/T = j + if(!(T.flags & UNUSED_TRANSIT_TURF)) + continue base + break if((!proposed_zone) || (!proposed_zone.len)) world << "We couldn't find a suitable transit zone" return - CHECK_TICK - transit_turfs_in_use |= proposed_zone world << "Now creating transit port" var/turf/topleft = proposed_zone[1] // Then create a transit docking port in the middle @@ -298,16 +283,17 @@ var/datum/subsystem/shuttle/SSshuttle var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint) new_transit_dock.assigned_turfs = proposed_zone new_transit_dock.name = "Transit for [M.id]/[M.name]" - new_transit_dock.setDir(M.travelDir) - CHECK_TICK + new_transit_dock.setDir(M.dir) world << "Now setting turf type" for(var/i in new_transit_dock.assigned_turfs) var/turf/open/space/transit/T = i + T.flags |= UNUSED_TRANSIT_TURF T.ChangeTurf(/turf/open/space/transit) T.setDir(M.travelDir) T.update_icon() + world << "Done!" return new_transit_dock // Then return it diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index f65d290ceb4..1591d13aedb 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -288,7 +288,25 @@ else G.dom_attempts = min(1,G.dom_attempts) + if(SHUTTLE_DOCKED) + if(time_left <= ENGINES_START_TIME) + mode = SHUTTLE_IGNITING + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == UNLAUNCHED) //Pods will not launch from the mine/planet, and other ships won't launch unless we tell them to. + M.mode = SHUTTLE_IGNITING + + if(SHUTTLE_IGNITING) + var/success = TRUE + + success &= (requestTransitZone() == TRANSIT_READY) + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == UNLAUNCHED) + success &= (M.requestTransitZone() == TRANSIT_READY) + if(!success) + setTimer(ENGINES_START_TIME * 10) if(time_left <= 50 && !sound_played) //4 seconds left:REV UP THOSE ENGINES BOYS. - should sync up with the launch sound_played = 1 //Only rev them up once. diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm new file mode 100644 index 00000000000..449648702fb --- /dev/null +++ b/code/modules/shuttle/on_move.dm @@ -0,0 +1,58 @@ +/atom/movable/proc/onShuttleMove(turf/T1, rotation) + if(rotation) + shuttleRotate(rotation) + loc = T1 + return 1 + +/obj/onShuttleMove() + if(invisibility >= INVISIBILITY_ABSTRACT) + return 0 + . = ..() + +/atom/movable/light/onShuttleMove() + return 0 + +/obj/machinery/door/onShuttleMove() + . = ..() + if(!.) + return + addtimer(src, "close", 0) + +/mob/onShuttleMove() + if(!move_on_shuttle) + return 0 + . = ..() + if(!.) + return + if(client) + if(buckled) + shake_camera(src, 2, 1) // turn it down a bit come on + else + shake_camera(src, 7, 1) + +/mob/living/carbon/onShuttleMove() + . = ..() + if(!.) + return + if(!buckled) + Weaken(3) + +// Shuttle Rotation // + +/atom/proc/shuttleRotate(rotation) + //rotate our direction + setDir(angle2dir(rotation+dir2angle(dir))) + + //resmooth if need be. + if(smooth) + queue_smooth(src) + + //rotate the pixel offsets too. + if (pixel_x || pixel_y) + if (rotation < 0) + rotation += 360 + for (var/turntimes=rotation/90;turntimes>0;turntimes--) + var/oldPX = pixel_x + var/oldPY = pixel_y + pixel_x = oldPY + pixel_y = (oldPX*(-1)) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 9c8c9c7373e..f0e952efe6d 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -12,9 +12,10 @@ anchored = 1 var/id - dir = NORTH//this should point -away- from the dockingport door, ie towards the ship + // this should point -away- from the dockingport door, ie towards the ship + dir = NORTH var/width = 0 //size of covered area, perpendicular to dir - var/height = 0 //size of covered area, paralell to dir + var/height = 0 //size of covered area, parallel to dir var/dwidth = 0 //position relative to covered area, perpendicular to dir var/dheight = 0 //position relative to covered area, parallel to dir @@ -178,8 +179,8 @@ var/area/shuttle/areaInstance var/timer //used as a timer (if you want time left to complete move, use timeLeft proc) - var/mode = SHUTTLE_IDLE //current shuttle mode (see /__DEFINES/stat.dm) - var/callTime = 150 //time spent in transit (deciseconds)7 + var/mode = SHUTTLE_IDLE //current shuttle mode + var/callTime = 150 //time spent in transit (deciseconds) var/ignitionTime = 100 // time spent "starting the engines" var/roundstart_move //id of port to send shuttle to at roundstart var/travelDir = 0 //direction the shuttle would travel in @@ -232,7 +233,7 @@ //this is a hook for custom behaviour. Maybe at some point we could add checks to see if engines are intact /obj/docking_port/mobile/proc/canMove() - return 0 //0 means we can move + return TRUE //this is to check if this shuttle can physically dock at dock S /obj/docking_port/mobile/proc/canDock(obj/docking_port/stationary/S) @@ -240,7 +241,7 @@ return SHUTTLE_NOT_A_DOCKING_PORT if(istype(S, /obj/docking_port/stationary/transit)) - return FALSE + return SHUTTLE_CAN_DOCK if(dwidth > S.dwidth) return SHUTTLE_DWIDTH_TOO_LARGE @@ -265,7 +266,7 @@ // attempt to move us where we currently are, it will get weird. return SHUTTLE_ALREADY_DOCKED - return FALSE + return SHUTTLE_CAN_DOCK //call the shuttle to destination S /obj/docking_port/mobile/proc/request(obj/docking_port/stationary/S) @@ -274,7 +275,7 @@ // We're already docked there, don't need to do anything. // Triggering shuttle movement code in place is weird return - else if(status) + else if(status != SHUTTLE_CAN_DOCK) var/msg = "request(): shuttle [src] cannot dock at [S], \ error: [status]" message_admins(msg) @@ -290,7 +291,7 @@ timer = world.time if(SHUTTLE_RECALL) if(S == destination) - timer = world.time - timeLeft(1) + timer = world.time + timeLeft(1) else destination = S timer = world.time @@ -298,7 +299,7 @@ if(SHUTTLE_IDLE, SHUTTLE_IGNITING) destination = S mode = SHUTTLE_IGNITING - timer = world.time + timer = world.time + ignitionTime //recall the shuttle to where it was previously /obj/docking_port/mobile/proc/cancel() @@ -314,11 +315,17 @@ /obj/docking_port/mobile/proc/requestTransitZone() if(requesting_transit) - return FALSE + return TRANSIT_REQUEST + if(assigned_transit) + return TRANSIT_READY + requesting_transit = TRUE assigned_transit = SSshuttle.requestTransitZone(src) - . = istype(assigned_transit) requesting_transit = FALSE + if(istype(assigned_transit)) + return TRANSIT_READY + else + return TRANSIT_FULL /obj/docking_port/mobile/proc/enterTransit() previous = null @@ -334,24 +341,6 @@ else WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]") -//default shuttleRotate -/atom/proc/shuttleRotate(rotation) - //rotate our direction - setDir(angle2dir(rotation+dir2angle(dir))) - - //resmooth if need be. - if(smooth) - queue_smooth(src) - - //rotate the pixel offsets too. - if (pixel_x || pixel_y) - if (rotation < 0) - rotation += 360 - for (var/turntimes=rotation/90;turntimes>0;turntimes--) - var/oldPX = pixel_x - var/oldPY = pixel_y - pixel_x = oldPY - pixel_y = (oldPX*(-1)) /obj/docking_port/mobile/proc/jumpToNullSpace() // Destroys the docking port and the shuttle contents. @@ -415,13 +404,13 @@ var/status = canDock(S1) if(status == SHUTTLE_ALREADY_DOCKED) return status - else if(status) + else if(status != SHUTTLE_CAN_DOCK) var/msg = "dock(): shuttle [src] cannot dock at [S1], \ error: [status]" message_admins(msg) return status - if(canMove()) + if(!canMove()) return -1 closePortDoors() @@ -498,44 +487,6 @@ loc = S1.loc setDir(S1.dir) -/atom/movable/proc/onShuttleMove(turf/T1, rotation) - if(rotation) - shuttleRotate(rotation) - loc = T1 - return 1 - -/obj/onShuttleMove() - if(invisibility >= INVISIBILITY_ABSTRACT) - return 0 - . = ..() - -/atom/movable/light/onShuttleMove() - return 0 - -/obj/machinery/door/onShuttleMove() - . = ..() - if(!.) - return - addtimer(src, "close", 0) - -/mob/onShuttleMove() - if(!move_on_shuttle) - return 0 - . = ..() - if(!.) - return - if(client) - if(buckled) - shake_camera(src, 2, 1) // turn it down a bit come on - else - shake_camera(src, 7, 1) - -/mob/living/carbon/onShuttleMove() - . = ..() - if(!.) - return - if(!buckled) - Weaken(3) /obj/docking_port/mobile/proc/findRoundstartDock() var/obj/docking_port/stationary/D @@ -606,11 +557,8 @@ if(!ripples.len && (timeLeft <= SHUTTLE_RIPPLE_TIME) && ((mode == SHUTTLE_CALL) || (mode == SHUTTLE_RECALL))) create_ripples(destination) - // Stall until we get a transit slot if(mode == SHUTTLE_IGNITING) - var/success = requestTransitZone() - if(!success) - timer = world.time + requestTransitZone() if(timeLeft <= 0) switch(mode) @@ -623,6 +571,9 @@ setTimer(20) //can't dock for some reason, try again in 2 seconds return if(SHUTTLE_IGNITING) + if(requestTransitZone() != TRANSIT_READY) + setTimer(20) + return mode = SHUTTLE_CALL timer = world.time enterTransit() @@ -641,9 +592,15 @@ /obj/docking_port/mobile/proc/timeLeft(divisor) if(divisor <= 0) divisor = 10 + + var/xTime + if(mode != SHUTTLE_IGNITING) + xTime = callTime + else + xTime = ignitionTime if(!timer) - return round(callTime/divisor, 1) - return max( round((timer+callTime-world.time)/divisor,1), 0 ) + return round(xTime/divisor, 1) + return max( round((timer+xTime-world.time)/divisor,1), 0 ) // returns 3-letter mode string, used by status screens and mob status panel /obj/docking_port/mobile/proc/getModeStr() diff --git a/tgstation.dme b/tgstation.dme index 732a3e2d65f..e3129740525 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1698,6 +1698,7 @@ #include "code\modules\shuttle\emergency.dm" #include "code\modules\shuttle\ferry.dm" #include "code\modules\shuttle\manipulator.dm" +#include "code\modules\shuttle\on_move.dm" #include "code\modules\shuttle\ripple.dm" #include "code\modules\shuttle\shuttle.dm" #include "code\modules\shuttle\special.dm"