mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
Merge pull request #13437 from neersighted/clickable_stats
Refactor MC/Failsafe/add Subsystems
This commit is contained in:
@@ -6,6 +6,7 @@ var/datum/subsystem/air/SSair
|
||||
wait = 5
|
||||
dynamic_wait = 1
|
||||
dwait_upper = 50
|
||||
display = 1
|
||||
|
||||
var/cost_turfs = 0
|
||||
var/cost_groups = 0
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
var/datum/subsystem/assets/SSasset
|
||||
|
||||
/datum/subsystem/assets
|
||||
name = "Assets"
|
||||
priority = -3
|
||||
|
||||
var/list/cache = list()
|
||||
|
||||
/datum/subsystem/assets/New()
|
||||
NEW_SS_GLOBAL(SSasset)
|
||||
|
||||
/datum/subsystem/assets/Initialize(timeofday, zlevel)
|
||||
if (zlevel)
|
||||
return ..()
|
||||
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
|
||||
for(var/client/C in clients)
|
||||
// Doing this to a client too soon after they've connected can cause issues, also the proc we call sleeps.
|
||||
spawn(10)
|
||||
getFilesSlow(C, cache, FALSE)
|
||||
..()
|
||||
@@ -2,13 +2,15 @@ var/datum/subsystem/garbage_collector/SSgarbage
|
||||
|
||||
/datum/subsystem/garbage_collector
|
||||
name = "Garbage"
|
||||
can_fire = 1
|
||||
wait = 5
|
||||
priority = -1
|
||||
wait = 5
|
||||
dynamic_wait = 1
|
||||
dwait_upper = 50
|
||||
dwait_delta = 10
|
||||
dwait_buffer = 0
|
||||
display = 2
|
||||
|
||||
can_fire = 1 // This needs to fire before round start.
|
||||
|
||||
var/collection_timeout = 300// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
|
||||
var/max_run_time = 1 // how long, in deciseconds, can we run before waiting for the next tick
|
||||
|
||||
@@ -4,10 +4,11 @@ var/datum/subsystem/lighting/SSlighting
|
||||
|
||||
/datum/subsystem/lighting
|
||||
name = "Lighting"
|
||||
wait = 5
|
||||
priority = 1
|
||||
wait = 5
|
||||
dynamic_wait = 1
|
||||
dwait_delta = 3
|
||||
display = 5
|
||||
|
||||
var/list/changed_lights = list() //list of all datum/light_source that need updating
|
||||
var/changed_lights_workload = 0 //stats on the largest number of lights (max changed_lights.len)
|
||||
|
||||
@@ -3,6 +3,7 @@ var/datum/subsystem/machines/SSmachine
|
||||
/datum/subsystem/machines
|
||||
name = "Machines"
|
||||
priority = 9
|
||||
display = 3
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/powernets = list()
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
// Activate this to debug tile mismatches in the minimap.
|
||||
// This will store the full information on each tile and compare it the next time you run the minimap.
|
||||
// It can be used to find out what's changed since the last iteration.
|
||||
// Only activate this when you need it - this should never be active on a live server!
|
||||
// #define MINIMAP_DEBUG
|
||||
|
||||
var/datum/subsystem/minimap/SSminimap
|
||||
|
||||
/datum/subsystem/minimap
|
||||
name = "Minimap"
|
||||
priority = -2
|
||||
|
||||
var/const/MAX_ICON_DIMENSION = 1024
|
||||
var/const/ICON_SIZE = 4
|
||||
|
||||
/datum/subsystem/minimap/New()
|
||||
NEW_SS_GLOBAL(SSminimap)
|
||||
|
||||
/datum/subsystem/minimap/Initialize(timeofday, zlevel)
|
||||
if (zlevel)
|
||||
return ..()
|
||||
for(var/z = 1 to world.maxz)
|
||||
generate(z)
|
||||
for (var/z = 1 to world.maxz)
|
||||
register_asset("minimap_[z].png", file("[getMinimapFile(z)].png"))
|
||||
..()
|
||||
|
||||
/datum/subsystem/minimap/proc/generate(z, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
|
||||
var/result_path = "[src.getMinimapFile(z)].png"
|
||||
var/hash_path = "[src.getMinimapFile(z)].md5"
|
||||
var/list/tiles = block(locate(x1, y1, z), locate(x2, y2, z))
|
||||
var/hash = ""
|
||||
var/temp
|
||||
var/obj/obj
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
var/tiledata_path = "data/minimaps/debug_tiledata_[z].sav"
|
||||
var/savefile/F = new/savefile(tiledata_path)
|
||||
#endif
|
||||
|
||||
// Note for future developer: If you have tiles on the map with random or dynamic icons this hash check will fail
|
||||
// every time. You'll have to modify this code to generate a unique hash for your object.
|
||||
// Don't forget to modify the minimap generation code to use a default icon (or skip generation altogether).
|
||||
for (var/turf/tile in tiles)
|
||||
if (istype(tile.loc, /area/asteroid) || istype(tile.loc, /area/mine/unexplored) || istype(tile, /turf/simulated/mineral) || (istype(tile.loc, /area/space) && istype(tile, /turf/simulated/floor/plating/asteroid)))
|
||||
temp = "/area/asteroid"
|
||||
else if (istype(tile.loc, /area/mine) && istype(tile, /turf/simulated/floor/plating/asteroid))
|
||||
temp = "/area/mine/explored"
|
||||
else if (tile.loc.type == /area/start || (tile.type == /turf/space && !(locate(/obj/structure/lattice) in tile)) || istype(tile, /turf/space/transit))
|
||||
temp = "/turf/space"
|
||||
if (locate(/obj/structure/lattice/catwalk) in tile)
|
||||
|
||||
else
|
||||
else if (tile.type == /turf/space)
|
||||
if (locate(/obj/structure/lattice/catwalk) in tile)
|
||||
temp = "/obj/structure/lattice/catwalk"
|
||||
else
|
||||
temp = "/obj/structure/lattice"
|
||||
else if (tile.type == /turf/simulated/floor/plating/abductor)
|
||||
temp = "/turf/simulated/floor/plating/abductor"
|
||||
else if (tile.type == /turf/simulated/floor/plating && (locate(/obj/structure/window/shuttle) in tile))
|
||||
temp = "/obj/structure/window/shuttle"
|
||||
else
|
||||
temp = "[tile.icon][tile.icon_state][tile.dir]"
|
||||
|
||||
obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
if (obj) temp = "[temp]/obj/structure/transit_tube[obj.icon_state][obj.dir]"
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
if (F["/[tile.y]/[tile.x]"] && F["/[tile.y]/[tile.x]"] != temp)
|
||||
CRASH("Mismatch: [tile.type] at [tile.x],[tile.y],[tile.z] ([tile.icon], [tile.icon_state], [tile.dir])")
|
||||
else
|
||||
F["/[tile.y]/[tile.x]"] << temp
|
||||
#endif
|
||||
|
||||
hash = md5("[hash][temp]")
|
||||
|
||||
if (fexists(result_path))
|
||||
if (!fexists(hash_path) || trim(file2text(hash_path)) != hash)
|
||||
fdel(result_path)
|
||||
fdel(hash_path)
|
||||
|
||||
if (!fexists(result_path))
|
||||
ASSERT(x1 > 0)
|
||||
ASSERT(y1 > 0)
|
||||
ASSERT(x2 <= world.maxx)
|
||||
ASSERT(y2 <= world.maxy)
|
||||
|
||||
var/icon/map_icon = new/icon('html/mapbase1024.png')
|
||||
|
||||
// map_icon is fine and contains only 1 direction at this point.
|
||||
|
||||
ASSERT(map_icon.Width() == MAX_ICON_DIMENSION && map_icon.Height() == MAX_ICON_DIMENSION)
|
||||
|
||||
|
||||
var/i = 0
|
||||
var/icon/turf_icon
|
||||
var/icon/obj_icon
|
||||
var/old_icon
|
||||
var/old_icon_state
|
||||
var/old_dir
|
||||
var/new_icon
|
||||
var/new_icon_state
|
||||
var/new_dir
|
||||
|
||||
for (var/turf/tile in tiles)
|
||||
if (tile.loc.type != /area/start && (tile.type != /turf/space || (locate(/obj/structure/lattice) in tile) || (locate(/obj/structure/transit_tube) in tile)) && !istype(tile, /turf/space/transit))
|
||||
if (istype(tile.loc, /area/asteroid) || istype(tile.loc, /area/mine/unexplored) || istype(tile, /turf/simulated/mineral) || (istype(tile.loc, /area/space) && istype(tile, /turf/simulated/floor/plating/asteroid)))
|
||||
new_icon = 'icons/turf/mining.dmi'
|
||||
new_icon_state = "rock"
|
||||
new_dir = 2
|
||||
else if (istype(tile.loc, /area/mine) && istype(tile, /turf/simulated/floor/plating/asteroid))
|
||||
new_icon = 'icons/turf/floors.dmi'
|
||||
new_icon_state = "asteroid"
|
||||
new_dir = 2
|
||||
else if (tile.type == /turf/simulated/floor/plating/abductor)
|
||||
new_icon = 'icons/turf/floors.dmi'
|
||||
new_icon_state = "alienpod1"
|
||||
new_dir = 2
|
||||
else if (tile.type == /turf/space)
|
||||
obj = locate(/obj/structure/lattice) in tile
|
||||
|
||||
if (!obj) obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
ASSERT(obj != null)
|
||||
|
||||
if (obj)
|
||||
new_icon = obj.icon
|
||||
new_dir = obj.dir
|
||||
new_icon_state = obj.icon_state
|
||||
else if (tile.type == /turf/simulated/floor/plating && (locate(/obj/structure/window/shuttle) in tile))
|
||||
new_icon = 'icons/obj/structures.dmi'
|
||||
new_dir = 2
|
||||
new_icon_state = "swindow"
|
||||
else
|
||||
new_icon = tile.icon
|
||||
new_icon_state = tile.icon_state
|
||||
new_dir = tile.dir
|
||||
|
||||
if (new_icon != old_icon || new_icon_state != old_icon_state || new_dir != old_dir)
|
||||
old_icon = new_icon
|
||||
old_icon_state = new_icon_state
|
||||
old_dir = new_dir
|
||||
|
||||
turf_icon = new/icon(new_icon, new_icon_state, new_dir, 1, 0)
|
||||
turf_icon.Scale(ICON_SIZE, ICON_SIZE)
|
||||
|
||||
if (tile.type != /turf/space || (locate(/obj/structure/lattice) in tile))
|
||||
obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
if (obj)
|
||||
obj_icon = new/icon(obj.icon, obj.icon_state, obj.dir, 1, 0)
|
||||
obj_icon.Scale(ICON_SIZE, ICON_SIZE)
|
||||
turf_icon.Blend(obj_icon, ICON_OVERLAY)
|
||||
|
||||
map_icon.Blend(turf_icon, ICON_OVERLAY, ((tile.x - 1) * ICON_SIZE), ((tile.y - 1) * ICON_SIZE))
|
||||
|
||||
if ((++i) % 512 == 0) sleep(1) // deliberate delay to avoid lag spikes
|
||||
|
||||
else
|
||||
sleep(-1) // avoid sleeping if possible: prioritize pending procs
|
||||
|
||||
// BYOND BUG: map_icon now contains 4 directions? Create a new icon with only a single state.
|
||||
var/icon/result_icon = new/icon()
|
||||
|
||||
result_icon.Insert(map_icon, "", SOUTH, 1, 0)
|
||||
|
||||
fcopy(result_icon, result_path)
|
||||
text2file(hash, hash_path)
|
||||
|
||||
/datum/subsystem/minimap/proc/getMinimapFile(zlevel)
|
||||
return "data/minimaps/map_[zlevel]"
|
||||
|
||||
/datum/subsystem/minimap/proc/sendMinimaps(client/client)
|
||||
for (var/z = 1 to world.maxz)
|
||||
send_asset(client, "minimap_[z].png")
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
#undef MINIMAP_DEBUG
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@ var/datum/subsystem/mobs/SSmob
|
||||
/datum/subsystem/mobs
|
||||
name = "Mobs"
|
||||
priority = 4
|
||||
display = 4
|
||||
|
||||
|
||||
/datum/subsystem/mobs/New()
|
||||
|
||||
@@ -2,22 +2,22 @@ var/datum/subsystem/nano/SSnano
|
||||
|
||||
/datum/subsystem/nano
|
||||
name = "NanoUI"
|
||||
can_fire = 1
|
||||
wait = 10
|
||||
priority = 16
|
||||
display = 6
|
||||
|
||||
can_fire = 1 // This needs to fire before round start.
|
||||
|
||||
var/list/open_uis = list() // A list of open NanoUIs, grouped by src_object and ui_key.
|
||||
var/list/processing_uis = list() // A list of processing NanoUIs, not grouped.
|
||||
|
||||
|
||||
/datum/subsystem/nano/New()
|
||||
NEW_SS_GLOBAL(SSnano) // Register the subsystem.
|
||||
|
||||
NEW_SS_GLOBAL(SSnano)
|
||||
|
||||
/datum/subsystem/nano/stat_entry()
|
||||
..("O:[open_uis.len]|P:[processing_uis.len]") // Show how many interfaces we have open/are processing.
|
||||
|
||||
|
||||
/datum/subsystem/nano/fire() // Process UIs.
|
||||
for(var/thing in processing_uis)
|
||||
var/datum/nanoui/ui = thing
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
var/datum/subsystem/npcpool/SSbp
|
||||
var/datum/subsystem/npcpool/SSnpc
|
||||
|
||||
/datum/subsystem/npcpool
|
||||
name = "NPCPool"
|
||||
priority = 100
|
||||
name = "NPC Pool"
|
||||
priority = 17
|
||||
display = 6
|
||||
|
||||
var/list/canBeUsed = list()
|
||||
var/list/canBeUsed_non = list()
|
||||
@@ -17,7 +18,7 @@ var/datum/subsystem/npcpool/SSbp
|
||||
botPool_l |= toInsert
|
||||
|
||||
/datum/subsystem/npcpool/New()
|
||||
NEW_SS_GLOBAL(SSbp)
|
||||
NEW_SS_GLOBAL(SSnpc)
|
||||
|
||||
/datum/subsystem/npcpool/stat_entry()
|
||||
..("T:[botPool_l.len + botPool_l_non.len]|D:[needsDelegate.len]|A:[needsAssistant.len + needsHelp_non.len]|U:[canBeUsed.len + canBeUsed_non.len]")
|
||||
|
||||
@@ -2,7 +2,7 @@ var/datum/subsystem/pai/SSpai
|
||||
|
||||
/datum/subsystem/pai
|
||||
name = "pAI"
|
||||
wait = 20
|
||||
priority = 20
|
||||
|
||||
var/askDelay = 600
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var/datum/subsystem/radio/radio_controller
|
||||
var/datum/subsystem/radio/SSradio
|
||||
|
||||
/datum/subsystem/radio
|
||||
name = "Radio"
|
||||
@@ -7,7 +7,7 @@ var/datum/subsystem/radio/radio_controller
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
/datum/subsystem/radio/New()
|
||||
NEW_SS_GLOBAL(radio_controller)
|
||||
NEW_SS_GLOBAL(SSradio)
|
||||
|
||||
/datum/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
var/datum/subsystem/server_maint/SSserver
|
||||
|
||||
/datum/subsystem/server_maint
|
||||
name = "Server Tasks"
|
||||
wait = 6000
|
||||
priority = 19
|
||||
|
||||
/datum/subsystem/server_maint/New()
|
||||
NEW_SS_GLOBAL(SSserver)
|
||||
|
||||
/datum/subsystem/server_maint/fire()
|
||||
//handle kicking inactive players
|
||||
if(config.kick_inactive > 0)
|
||||
|
||||
@@ -547,7 +547,7 @@
|
||||
|
||||
/obj/machinery/computer/supplycomp/proc/post_signal(command)
|
||||
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
|
||||
|
||||
if(!frequency) return
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ var/datum/subsystem/ticker/ticker
|
||||
|
||||
/datum/subsystem/ticker
|
||||
name = "Ticker"
|
||||
can_fire = 1
|
||||
priority = 0
|
||||
|
||||
can_fire = 1 // This needs to fire before round start.
|
||||
|
||||
var/current_state = GAME_STATE_STARTUP //state of current round (used by process()) Use the defines GAME_STATE_* !
|
||||
var/force_ending = 0 //Round was ended by admin intervention
|
||||
|
||||
@@ -20,7 +21,7 @@ var/datum/subsystem/ticker/ticker
|
||||
|
||||
var/list/datum/mind/minds = list() //The characters in the game. Used for objective tracking.
|
||||
|
||||
//These bible variables should be a preference
|
||||
//These bible variables should be a preference
|
||||
var/Bible_icon_state //icon_state the chaplain has chosen for his bible
|
||||
var/Bible_item_state //item_state the chaplain has chosen for his bible
|
||||
var/Bible_name //name of the bible
|
||||
@@ -67,7 +68,7 @@ var/datum/subsystem/ticker/ticker
|
||||
switch(current_state)
|
||||
if(GAME_STATE_STARTUP)
|
||||
timeLeft = config.lobby_countdown * 10
|
||||
world << "<B><FONT color='blue'>Welcome to the pre-game lobby!</FONT></B>"
|
||||
world << "<b><font color='blue'>Welcome to the pre-game lobby!</font></b>"
|
||||
world << "Please, setup your character and select ready. Game will start in [config.lobby_countdown] seconds"
|
||||
current_state = GAME_STATE_PREGAME
|
||||
|
||||
@@ -178,8 +179,7 @@ var/datum/subsystem/ticker/ticker
|
||||
equip_characters()
|
||||
data_core.manifest()
|
||||
|
||||
master_controller.roundHasStarted()
|
||||
|
||||
Master.RoundStart()
|
||||
|
||||
world << "<FONT color='blue'><B>Welcome to [station_name()], enjoy your stay!</B></FONT>"
|
||||
world << sound('sound/AI/welcome.ogg')
|
||||
@@ -205,7 +205,7 @@ var/datum/subsystem/ticker/ticker
|
||||
return 1
|
||||
|
||||
|
||||
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
|
||||
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
|
||||
/datum/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null)
|
||||
if( cinematic ) return //already a cinematic in progress!
|
||||
|
||||
@@ -261,8 +261,6 @@ var/datum/subsystem/ticker/ticker
|
||||
if(2) //nuke was nowhere nearby //TODO: a really distant explosion animation
|
||||
sleep(50)
|
||||
world << sound('sound/effects/explosionfar.ogg')
|
||||
|
||||
|
||||
else //station was destroyed
|
||||
if( mode && !override )
|
||||
override = mode.name
|
||||
|
||||
Reference in New Issue
Block a user