235b79fb5a
Basically, they key difference between StonedMC and CarnMC is that when multiple ticks want to run at the same byond tick, we divvy up the tick between the subsystems, rather then allow one subsystem to hog it all. The key difference between StonedMC and GoonPS is that we allow the subsystems to tell us how to divvy up the tick using flags and priority. The new SS_ flags allows us to select behaviors that used to be piggybacked as side effects of dynamic wait or default but sometimes unneeded behavior. Dynamic wait is 100% gone, lower priority and SS_BACKGROUND are better more refined ways of doing this when combined with MC_TICK_CHECK I have by design never looked at the inners of goonPS, so this is all original code but I know it uses two loops because of comments by goon devs on reddit threads, that design didn't make sense before, but when I can tell a SS how much of a byond tick it is allowed to have, knowing how many need to run this tick is helpful I also know a bit more about how it works from piecing together comments in #vgstation. Detailed list of changes: Subsystems now have flags, allowing fine grain control over things like rather or not it processes, inits, rather it's wait is how long between runs (post run timing) or how long between starts, and rather or not late fires should cause the next fire to be earlier. Mc now has two loops One loop handles queuing shit, one loop handles running shit. MC now splits up tick allotment rather than first come first serve Subsystems can even request a bigger share using higher priorities. (It will even resume subsystems it paused if other subsystems hadn't used as much as it predicted they might need) Default fps is now 20 This is related enough to the MC and it's a change that's really long since over due All code oddities are most likely to be necessities to lower overhead on the mc since it runs every tick
247 lines
7.8 KiB
Plaintext
247 lines
7.8 KiB
Plaintext
var/datum/subsystem/shuttle/SSshuttle
|
|
|
|
/datum/subsystem/shuttle
|
|
name = "Shuttles"
|
|
wait = 10
|
|
init_order = 3
|
|
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
|
|
|
|
var/list/mobile = list()
|
|
var/list/stationary = list()
|
|
var/list/transit = list()
|
|
|
|
//emergency shuttle stuff
|
|
var/obj/docking_port/mobile/emergency/emergency
|
|
var/obj/docking_port/mobile/emergency/backup/backup_shuttle
|
|
var/emergencyCallTime = 6000 //time taken for emergency shuttle to reach the station when called (in deciseconds)
|
|
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
|
var/emergencyEscapeTime = 1200 //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
|
var/area/emergencyLastCallLoc
|
|
var/emergencyNoEscape
|
|
|
|
//supply shuttle stuff
|
|
var/obj/docking_port/mobile/supply/supply
|
|
var/ordernum = 1 //order number given to next order
|
|
var/points = 5000 //number of trade-points we have
|
|
var/centcom_message = "" //Remarks from Centcom on how well you checked the last order.
|
|
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies
|
|
|
|
var/list/supply_packs = list()
|
|
var/list/shoppinglist = list()
|
|
var/list/requestlist = list()
|
|
var/list/orderhistory = list()
|
|
|
|
var/datum/round_event/shuttle_loan/shuttle_loan
|
|
|
|
/datum/subsystem/shuttle/New()
|
|
NEW_SS_GLOBAL(SSshuttle)
|
|
|
|
/datum/subsystem/shuttle/Initialize(timeofday)
|
|
if(!emergency)
|
|
WARNING("No /obj/docking_port/mobile/emergency placed on the map!")
|
|
if(!backup_shuttle)
|
|
WARNING("No /obj/docking_port/mobile/emergency/backup placed on the map!")
|
|
if(!supply)
|
|
WARNING("No /obj/docking_port/mobile/supply placed on the map!")
|
|
|
|
ordernum = rand(1, 9000)
|
|
|
|
for(var/pack in subtypesof(/datum/supply_pack))
|
|
var/datum/supply_pack/P = new pack()
|
|
if(!P.contains)
|
|
continue
|
|
supply_packs[P.type] = P
|
|
|
|
initial_move()
|
|
..()
|
|
|
|
|
|
/datum/subsystem/shuttle/fire()
|
|
for(var/thing in mobile)
|
|
if(thing)
|
|
var/obj/docking_port/mobile/P = thing
|
|
P.check()
|
|
continue
|
|
mobile.Remove(thing)
|
|
|
|
/datum/subsystem/shuttle/proc/getShuttle(id)
|
|
for(var/obj/docking_port/mobile/M in mobile)
|
|
if(M.id == id)
|
|
return M
|
|
WARNING("couldn't find shuttle with id: [id]")
|
|
|
|
/datum/subsystem/shuttle/proc/getDock(id)
|
|
for(var/obj/docking_port/stationary/S in stationary)
|
|
if(S.id == id)
|
|
return S
|
|
WARNING("couldn't find dock with id: [id]")
|
|
|
|
/datum/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
|
|
if(!emergency)
|
|
WARNING("requestEvac(): There is no emergency shuttle, but the \
|
|
shuttle was called. Using the backup shuttle instead.")
|
|
if(!backup_shuttle)
|
|
throw EXCEPTION("requestEvac(): There is no emergency shuttle, \
|
|
or backup shuttle! The game will be unresolvable. This is \
|
|
possibly a mapping error, more likely a bug with the shuttle \
|
|
manipulation system, or badminry. It is possible to manually \
|
|
resolve this problem by loading an emergency shuttle template \
|
|
manually, and then calling register() on the mobile docking port. \
|
|
Good luck.")
|
|
return
|
|
emergency = backup_shuttle
|
|
|
|
if(world.time - round_start_time < config.shuttle_refuel_delay)
|
|
user << "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again."
|
|
return
|
|
|
|
switch(emergency.mode)
|
|
if(SHUTTLE_RECALL)
|
|
user << "The emergency shuttle may not be called while returning to Centcom."
|
|
return
|
|
if(SHUTTLE_CALL)
|
|
user << "The emergency shuttle is already on its way."
|
|
return
|
|
if(SHUTTLE_DOCKED)
|
|
user << "The emergency shuttle is already here."
|
|
return
|
|
if(SHUTTLE_ESCAPE)
|
|
user << "The emergency shuttle is moving away to a safe distance."
|
|
return
|
|
if(SHUTTLE_STRANDED)
|
|
user << "The emergency shuttle has been disabled by Centcom."
|
|
return
|
|
|
|
call_reason = trim(html_encode(call_reason))
|
|
|
|
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH)
|
|
user << "You must provide a reason."
|
|
return
|
|
|
|
var/area/signal_origin = get_area(user)
|
|
var/emergency_reason = "\nNature of emergency:\n\n[call_reason]"
|
|
if(seclevel2num(get_security_level()) == SEC_LEVEL_RED) // There is a serious threat we gotta move no time to give them five minutes.
|
|
emergency.request(null, 0.5, signal_origin, html_decode(emergency_reason), 1)
|
|
else
|
|
emergency.request(null, 1, signal_origin, html_decode(emergency_reason), 0)
|
|
|
|
log_game("[key_name(user)] has called the shuttle.")
|
|
message_admins("[key_name_admin(user)] has called the shuttle.")
|
|
|
|
return
|
|
|
|
// Called when an emergency shuttle mobile docking port is
|
|
// destroyed, which will only happen with admin intervention
|
|
/datum/subsystem/shuttle/proc/emergencyDeregister()
|
|
// When a new emergency shuttle is created, it will override the
|
|
// backup shuttle.
|
|
src.emergency = src.backup_shuttle
|
|
|
|
/datum/subsystem/shuttle/proc/cancelEvac(mob/user)
|
|
if(canRecall())
|
|
emergency.cancel(get_area(user))
|
|
log_game("[key_name(user)] has recalled the shuttle.")
|
|
message_admins("[key_name_admin(user)] has recalled the shuttle.")
|
|
return 1
|
|
|
|
/datum/subsystem/shuttle/proc/canRecall()
|
|
if(emergency.mode != SHUTTLE_CALL)
|
|
return
|
|
if(ticker.mode.name == "meteor")
|
|
return
|
|
if(seclevel2num(get_security_level()) == SEC_LEVEL_RED)
|
|
if(emergency.timeLeft(1) < emergencyCallTime * 0.25)
|
|
return
|
|
else
|
|
if(emergency.timeLeft(1) < emergencyCallTime * 0.5)
|
|
return
|
|
return 1
|
|
|
|
/datum/subsystem/shuttle/proc/autoEvac()
|
|
var/callShuttle = 1
|
|
|
|
for(var/thing in shuttle_caller_list)
|
|
if(istype(thing, /mob/living/silicon/ai))
|
|
var/mob/living/silicon/ai/AI = thing
|
|
if(AI.stat || !AI.client)
|
|
continue
|
|
else if(istype(thing, /obj/machinery/computer/communications))
|
|
var/obj/machinery/computer/communications/C = thing
|
|
if(C.stat & BROKEN)
|
|
continue
|
|
|
|
var/turf/T = get_turf(thing)
|
|
if(T && T.z == ZLEVEL_STATION)
|
|
callShuttle = 0
|
|
break
|
|
|
|
if(callShuttle)
|
|
if(EMERGENCY_IDLE_OR_RECALLED)
|
|
emergency.request(null, 2.5)
|
|
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
|
|
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
|
|
|
|
//try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons
|
|
/datum/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
|
|
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
|
|
if(!M)
|
|
return 1
|
|
var/obj/docking_port/stationary/dockedAt = M.get_docked()
|
|
var/destination = dockHome
|
|
if(dockedAt && dockedAt.id == dockHome)
|
|
destination = dockAway
|
|
if(timed)
|
|
if(M.request(getDock(destination)))
|
|
return 2
|
|
else
|
|
if(M.dock(getDock(destination)))
|
|
return 2
|
|
return 0 //dock successful
|
|
|
|
|
|
/datum/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
|
|
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
|
|
var/obj/docking_port/stationary/D = getDock(dockId)
|
|
|
|
if(!M)
|
|
return 1
|
|
if(timed)
|
|
if(M.request(D))
|
|
return 2
|
|
else
|
|
if(M.dock(D))
|
|
return 2
|
|
return 0 //dock successful
|
|
|
|
/datum/subsystem/shuttle/proc/initial_move()
|
|
for(var/obj/docking_port/mobile/M in mobile)
|
|
if(!M.roundstart_move)
|
|
continue
|
|
moveShuttle(M.id, "[M.roundstart_move]", 0)
|
|
CHECK_TICK
|
|
|
|
/datum/subsystem/shuttle/Recover()
|
|
if (istype(SSshuttle.mobile))
|
|
mobile = SSshuttle.mobile
|
|
if (istype(SSshuttle.stationary))
|
|
stationary = SSshuttle.stationary
|
|
if (istype(SSshuttle.transit))
|
|
transit = SSshuttle.transit
|
|
if (istype(SSshuttle.discoveredPlants))
|
|
discoveredPlants = SSshuttle.discoveredPlants
|
|
if (istype(SSshuttle.requestlist))
|
|
requestlist = SSshuttle.requestlist
|
|
if (istype(SSshuttle.orderhistory))
|
|
orderhistory = SSshuttle.orderhistory
|
|
if (istype(SSshuttle.emergency))
|
|
emergency = SSshuttle.emergency
|
|
if (istype(SSshuttle.backup_shuttle))
|
|
backup_shuttle = SSshuttle.backup_shuttle
|
|
if (istype(SSshuttle.supply))
|
|
supply = SSshuttle.supply
|
|
|
|
centcom_message = SSshuttle.centcom_message
|
|
ordernum = SSshuttle.ordernum
|
|
points = SSshuttle.points
|
|
|