Merge branch 'master' into crewobjectivesandmiscreants

This commit is contained in:
deathride58
2017-10-01 23:45:49 +00:00
committed by GitHub
485 changed files with 81708 additions and 13183 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(blackbox)
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
query_record_playercount.Execute()
if(config.use_exp_tracking)
if(CONFIG_GET(flag/use_exp_tracking))
if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check
update_exp(10,FALSE)
+9 -14
View File
@@ -54,32 +54,27 @@ SUBSYSTEM_DEF(dbcore)
if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
return FALSE
if(!config.sql_enabled)
if(!CONFIG_GET(flag/sql_enabled))
return FALSE
var/user = global.sqlfdbklogin
var/pass = global.sqlfdbkpass
var/db = global.sqlfdbkdb
var/address = global.sqladdress
var/port = global.sqlport
var/user = CONFIG_GET(string/feedback_login)
var/pass = CONFIG_GET(string/feedback_password)
var/db = CONFIG_GET(string/feedback_database)
var/address = CONFIG_GET(string/address)
var/port = CONFIG_GET(number/port)
doConnect("dbi:mysql:[db]:[address]:[port]", user, pass)
_dm_db_connect(_db_con, "dbi:mysql:[db]:[address]:[port]", user, pass, Default_Cursor, null)
. = IsConnected()
if (!.)
log_sql("Connect() failed | [ErrorMsg()]")
++failed_connections
/datum/controller/subsystem/dbcore/proc/doConnect(dbi_handler, user_handler, password_handler)
if(!config.sql_enabled)
return FALSE
return _dm_db_connect(_db_con, dbi_handler, user_handler, password_handler, Default_Cursor, null)
/datum/controller/subsystem/dbcore/proc/Disconnect()
failed_connections = 0
return _dm_db_close(_db_con)
/datum/controller/subsystem/dbcore/proc/IsConnected()
if(!config.sql_enabled)
if(!CONFIG_GET(flag/sql_enabled))
return FALSE
return _dm_db_is_connected(_db_con)
@@ -87,7 +82,7 @@ SUBSYSTEM_DEF(dbcore)
return _dm_db_quote(_db_con, str)
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
if(!config.sql_enabled)
if(!CONFIG_GET(flag/sql_enabled))
return "Database disabled by configuration"
return _dm_db_error_msg(_db_con)
+2 -2
View File
@@ -56,7 +56,7 @@ SUBSYSTEM_DEF(events)
//selects a random event based on whether it can occur and it's 'weight'(probability)
/datum/controller/subsystem/events/proc/spawnEvent()
set waitfor = FALSE //for the admin prompt
if(!config.allow_random_events)
if(!CONFIG_GET(flag/allow_random_events))
// var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control
// if(E) E.runEvent()
return
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(events)
//sets up the holidays and holidays list
/datum/controller/subsystem/events/proc/getHoliday()
if(!config.allow_holidays)
if(!CONFIG_GET(flag/allow_holidays))
return // Holiday stuff was not enabled in the config!
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
+18 -14
View File
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(job)
/datum/controller/subsystem/job/Initialize(timeofday)
if(!occupations.len)
SetupOccupations()
if(config.load_jobs_from_txt)
if(CONFIG_GET(flag/load_jobs_from_txt))
LoadJobs()
..()
@@ -106,7 +106,7 @@ SUBSYSTEM_DEF(job)
if(player.mind && job.title in player.mind.restricted_roles)
Debug("FOC incompatible with antagonist role, Player: [player]")
continue
if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("FOC non-human failed, Player: [player]")
continue
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
@@ -143,7 +143,7 @@ SUBSYSTEM_DEF(job)
Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("GRJ non-human failed, Player: [player]")
continue
@@ -245,11 +245,12 @@ SUBSYSTEM_DEF(job)
setup_officer_positions()
//Jobs will have fewer access permissions if the number of players exceeds the threshold defined in game_options.txt
if(config.minimal_access_threshold)
if(config.minimal_access_threshold > unassigned.len)
config.jobs_have_minimal_access = 0
var/mat = CONFIG_GET(number/minimal_access_threshold)
if(mat)
if(mat > unassigned.len)
CONFIG_SET(flag/jobs_have_minimal_access, FALSE)
else
config.jobs_have_minimal_access = 1
CONFIG_SET(flag/jobs_have_minimal_access, TRUE)
//Shuffle players and jobs
unassigned = shuffle(unassigned)
@@ -317,7 +318,7 @@ SUBSYSTEM_DEF(job)
Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("DO non-human failed, Player: [player], Job:[job.title]")
continue
@@ -415,8 +416,8 @@ SUBSYSTEM_DEF(job)
to_chat(M, "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>")
if(job.req_admin_notify)
to_chat(M, "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>")
if(config.minimal_access_threshold)
to_chat(M, "<FONT color='blue'><B>As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>")
if(CONFIG_GET(number/minimal_access_threshold))
to_chat(M, "<FONT color='blue'><B>As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>")
if(job && H)
job.after_spawn(H, M)
@@ -429,9 +430,10 @@ SUBSYSTEM_DEF(job)
if(!J)
throw EXCEPTION("setup_officer_positions(): Security officer job is missing")
if(config.security_scaling_coeff > 0)
var/ssc = CONFIG_GET(number/security_scaling_coeff)
if(ssc > 0)
if(J.spawn_positions > 0)
var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len/config.security_scaling_coeff))) //Scale between configured minimum and 12 officers
var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len / ssc))) //Scale between configured minimum and 12 officers
Debug("Setting open security officer positions to [officer_positions]")
J.total_positions = officer_positions
J.spawn_positions = officer_positions
@@ -491,8 +493,10 @@ SUBSYSTEM_DEF(job)
SSblackbox.add_details("job_preferences",tmp_str)
/datum/controller/subsystem/job/proc/PopcapReached()
if(config.hard_popcap || config.extreme_popcap)
var/relevent_cap = max(config.hard_popcap, config.extreme_popcap)
var/hpc = CONFIG_GET(number/hard_popcap)
var/epc = CONFIG_GET(number/extreme_popcap)
if(hpc || epc)
var/relevent_cap = max(hpc, epc)
if((initial_players_to_assign - unassigned.len) >= relevent_cap)
return 1
return 0
+1 -1
View File
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/Initialize(timeofday)
if(!initialized)
if (config.starlight)
if (CONFIG_GET(flag/starlight))
for(var/I in GLOB.sortedAreas)
var/area/A = I
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
+6 -5
View File
@@ -43,19 +43,19 @@ SUBSYSTEM_DEF(mapping)
loading_ruins = TRUE
var/mining_type = config.minetype
if (mining_type == "lavaland")
seedRuins(list(ZLEVEL_LAVALAND), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
spawn_rivers()
// deep space ruins
var/space_zlevels = list()
for(var/i in ZLEVEL_SPACEMIN to ZLEVEL_SPACEMAX)
switch(i)
if(ZLEVEL_MINING, ZLEVEL_LAVALAND, ZLEVEL_EMPTY_SPACE, ZLEVEL_TRANSIT)
if(ZLEVEL_MINING, ZLEVEL_LAVALAND, ZLEVEL_EMPTY_SPACE, ZLEVEL_TRANSIT, ZLEVEL_CITYOFCOGS)
continue
else
space_zlevels += i
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
loading_ruins = FALSE
repopulate_sorted_areas()
// Set up Z-level transistions.
@@ -141,7 +141,8 @@ SUBSYSTEM_DEF(mapping)
var/players = GLOB.clients.len
var/list/mapvotes = list()
//count votes
if(global.config.allow_map_voting)
var/amv = CONFIG_GET(flag/allow_map_voting)
if(amv)
for (var/client/c in GLOB.clients)
var/vote = c.prefs.preferred_map
if (!vote)
@@ -174,7 +175,7 @@ SUBSYSTEM_DEF(mapping)
mapvotes.Remove(map)
continue
if(global.config.allow_map_voting)
if(amv)
mapvotes[map] = mapvotes[map]*VM.voteweight
var/pickedmap = pickweight(mapvotes)
+1 -1
View File
@@ -9,7 +9,7 @@ SUBSYSTEM_DEF(minimap)
/datum/controller/subsystem/minimap/Initialize(timeofday)
var/hash = md5(SSmapping.config.GetFullMapPath())
if(config.generate_minimaps)
if(CONFIG_GET(flag/generate_minimaps))
if(hash == trim(file2text(hash_path())))
for(var/z in z_levels) //We have these files cached, let's register them
register_asset("minimap_[z].png", fcopy_rsc(map_path(z)))
+47 -39
View File
@@ -22,47 +22,54 @@ SUBSYSTEM_DEF(persistence)
/datum/controller/subsystem/persistence/proc/LoadSatchels()
var/placed_satchel = 0
var/path
var/obj/item/storage/backpack/satchel/flat/F = new()
if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy compatability to convert old format to new
if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy conversion. Will only ever run once.
var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
var/sav_text
secret_satchels[SSmapping.config.map_name] >> sav_text
fdel("data/npc_saves/SecretSatchels.sav")
if(sav_text)
old_secret_satchels = splittext(sav_text,"#")
if(old_secret_satchels.len >= 20)
var/satchel_string = pick_n_take(old_secret_satchels)
for(var/map in secret_satchels)
var/json_file = file("data/npc_saves/SecretSatchels[map].json")
var/list/legacy_secret_satchels = splittext(secret_satchels[map],"#")
var/list/satchels = list()
for(var/i=1,i<=legacy_secret_satchels.len,i++)
var/satchel_string = legacy_secret_satchels[i]
var/list/chosen_satchel = splittext(satchel_string,"|")
if(chosen_satchel.len == 3)
F.x = text2num(chosen_satchel[1])
F.y = text2num(chosen_satchel[2])
F.z = ZLEVEL_STATION_PRIMARY
path = text2path(chosen_satchel[3])
else
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
if(!fexists(json_file))
return
var/list/json = json_decode(file2text(json_file))
old_secret_satchels = json["data"]
if(old_secret_satchels.len)
if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
var/pos = rand(1, old_secret_satchels.len)
old_secret_satchels.Cut(pos, pos+1)
F.x = old_secret_satchels[pos]["x"]
F.y = old_secret_satchels[pos]["y"]
F.z = ZLEVEL_STATION_PRIMARY
path = text2path(old_secret_satchels[pos]["saved_obj"])
if(!ispath(path))
return
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
F.hide(1)
new path(F)
placed_satchel++
var/list/free_satchels = list()
var/list/data = list()
data["x"] = text2num(chosen_satchel[1])
data["y"] = text2num(chosen_satchel[2])
data["saved_obj"] = chosen_satchel[3]
satchels += list(data)
var/list/file_data = list()
file_data["data"] = satchels
WRITE_FILE(json_file, json_encode(file_data))
fdel("data/npc_saves/SecretSatchels.sav")
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
var/list/json = list()
if(fexists(json_file))
json = json_decode(file2text(json_file))
old_secret_satchels = json["data"]
var/obj/item/storage/backpack/satchel/flat/F
if(old_secret_satchels && old_secret_satchels.len >= 10) //guards against low drop pools assuring that one player cannot reliably find his own gear.
var/pos = rand(1, old_secret_satchels.len)
F = new()
old_secret_satchels.Cut(pos, pos+1 % old_secret_satchels.len)
F.x = old_secret_satchels[pos]["x"]
F.y = old_secret_satchels[pos]["y"]
F.z = ZLEVEL_STATION_PRIMARY
path = text2path(old_secret_satchels[pos]["saved_obj"])
if(F)
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
F.hide(1)
if(ispath(path))
new path(F)
placed_satchel++
var/free_satchels = 0
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY)))) //Nontrivially expensive but it's roundstart only
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
free_satchels += new /obj/item/storage/backpack/satchel/flat/secret(T)
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchel) >= (50 - old_secret_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
new /obj/item/storage/backpack/satchel/flat/secret(T)
free_satchels++
if((free_satchels + placed_satchel) == 10) //ten tiles, more than enough to kill anything that moves
break
/datum/controller/subsystem/persistence/proc/LoadPoly()
@@ -176,8 +183,8 @@ SUBSYSTEM_DEF(persistence)
CollectRoundtype()
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
var/list/satchels = list()
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
var/list/satchels_to_add = list()
for(var/A in new_secret_satchels)
var/obj/item/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION_PRIMARY || F.invisibility != INVISIBILITY_MAXIMUM)
@@ -196,11 +203,12 @@ SUBSYSTEM_DEF(persistence)
data["x"] = F.x
data["y"] = F.y
data["saved_obj"] = pick(savable_obj)
satchels += list(data)
satchels_to_add += list(data)
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
var/list/file_data = list()
file_data["data"] = satchels
fdel(json_file)
file_data["data"] = old_secret_satchels + satchels_to_add
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
+12 -9
View File
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(server_maint)
var/list/currentrun
/datum/controller/subsystem/server_maint/Initialize(timeofday)
if (config.hub)
if (CONFIG_GET(flag/hub))
world.update_hub_visibility(TRUE)
..()
@@ -21,16 +21,19 @@ SUBSYSTEM_DEF(server_maint)
var/list/currentrun = src.currentrun
var/round_started = SSticker.HasRoundStarted()
var/kick_inactive = CONFIG_GET(flag/kick_inactive)
var/afk_period
if(kick_inactive)
afk_period = CONFIG_GET(number/afk_period)
for(var/I in currentrun)
var/client/C = I
//handle kicking inactive players
if(round_started && config.kick_inactive)
if(C.is_afk(config.afk_period))
var/cmob = C.mob
if(!(isobserver(cmob) || (isdead(cmob) && C.holder)))
log_access("AFK: [key_name(C)]")
to_chat(C, "<span class='danger'>You have been inactive for more than [DisplayTimeText(config.afk_period)] and have been disconnected.</span>")
qdel(C)
if(round_started && kick_inactive && C.is_afk(afk_period))
var/cmob = C.mob
if(!(isobserver(cmob) || (isdead(cmob) && C.holder)))
log_access("AFK: [key_name(C)]")
to_chat(C, "<span class='danger'>You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.</span>")
qdel(C)
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]")
@@ -40,7 +43,7 @@ SUBSYSTEM_DEF(server_maint)
/datum/controller/subsystem/server_maint/Shutdown()
kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", TRUE) //second parameter ensures only afk clients are kicked
var/server = config.server
var/server = CONFIG_GET(string/server)
for(var/thing in GLOB.clients)
if(!thing)
continue
+3 -3
View File
@@ -176,9 +176,9 @@ SUBSYSTEM_DEF(shuttle)
Good luck.")
return
emergency = backup_shuttle
if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay)
to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.")
var/srd = CONFIG_GET(number/shuttle_refuel_delay)
if(world.time - SSticker.round_start_time < srd)
to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.")
return
switch(emergency.mode)
+2 -1
View File
@@ -10,7 +10,8 @@ SUBSYSTEM_DEF(squeak)
var/list/exposed_wires = list()
/datum/controller/subsystem/squeak/Initialize(timeofday)
trigger_migration(config.mice_roundstart)
trigger_migration(CONFIG_GET(number/mice_roundstart))
return ..()
/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10)
if(!num_mice)
+10 -1
View File
@@ -57,6 +57,9 @@ SUBSYSTEM_DEF(throwing)
var/pure_diagonal
var/diagonal_error
var/datum/callback/callback
var/paused = FALSE
var/delayed_time = 0
var/last_move = 0
/datum/thrownthing/proc/tick()
var/atom/movable/AM = thrownthing
@@ -64,14 +67,20 @@ SUBSYSTEM_DEF(throwing)
finalize()
return
if(paused)
delayed_time += world.time - last_move
return
if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
finalize()
return
var/atom/step
last_move = world.time
//calculate how many tiles to move, making up for any missed ticks.
var/tilestomove = Ceiling(min(((((world.time+world.tick_lag) - start_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait))
var/tilestomove = Ceiling(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait))
while (tilestomove-- > 0)
if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc))
finalize()
+16 -152
View File
@@ -51,14 +51,14 @@ SUBSYSTEM_DEF(ticker)
var/queue_delay = 0
var/list/queued_players = list() //used for join queues when the server exceeds the hard population cap
var/obj/screen/cinematic = null //used for station explosion cinematic
var/maprotatechecked = 0
var/news_report
var/late_join_disabled
var/roundend_check_paused = FALSE
var/round_start_time = 0
var/list/round_start_events
var/mode_result = "undefined"
@@ -79,16 +79,18 @@ SUBSYSTEM_DEF(ticker)
if(!GLOB.syndicate_code_response)
GLOB.syndicate_code_response = generate_code_phrase()
..()
start_at = world.time + (config.lobby_countdown * 10)
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
/datum/controller/subsystem/ticker/fire()
switch(current_state)
if(GAME_STATE_STARTUP)
if(Master.initializations_finished_with_no_players_logged_in)
start_at = world.time + (config.lobby_countdown * 10)
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
for(var/client/C in GLOB.clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
if(CONFIG_GET(flag/irc_announce_new_game))
SERVER_TOOLS_CHAT_BROADCAST("New round starting on [SSmapping.config.map_name]!")
current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
@@ -137,7 +139,7 @@ SUBSYSTEM_DEF(ticker)
scripture_states = scripture_unlock_alert(scripture_states)
SSshuttle.autoEnd()
if(!mode.explosion_in_progress && mode.check_finished(force_ending) || force_ending)
if(!roundend_check_paused && mode.check_finished(force_ending) || force_ending)
current_state = GAME_STATE_FINISHED
toggle_ooc(TRUE) // Turn it on
toggle_dooc(TRUE)
@@ -207,7 +209,7 @@ SUBSYSTEM_DEF(ticker)
else
mode.announce()
if(!config.ooc_during_round)
if(!CONFIG_GET(flag/ooc_during_round))
toggle_ooc(FALSE) // Turn it off
CHECK_TICK
@@ -280,144 +282,7 @@ SUBSYSTEM_DEF(ticker)
qdel(bomb)
if(epi)
explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
if( cinematic )
return //already a cinematic in progress!
for (var/datum/html_interface/hi in GLOB.html_interfaces)
hi.closeAll()
SStgui.close_all_uis()
//Turn off the shuttles, there's no escape now
if(!station_missed && bomb)
SSshuttle.registerHostileEnvironment(src)
SSshuttle.lockdown = TRUE
//initialise our cinematic screen object
cinematic = new /obj/screen{icon='icons/effects/station_explosion.dmi';icon_state="station_intact";layer=21;mouse_opacity = MOUSE_OPACITY_TRANSPARENT;screen_loc="1,0";}(src)
for(var/mob/M in GLOB.mob_list)
M.notransform = TRUE //stop everything moving
if(M.client)
M.client.screen += cinematic //show every client the cinematic
var/actually_blew_up = TRUE
//Now animate the cinematic
switch(station_missed)
if(NUKE_NEAR_MISS) //nuke was nearby but (mostly) missed
if(mode && !override )
override = mode.name
switch( override )
if("nuclear emergency") //Nuke wasn't on station when it blew up
flick("intro_nuke",cinematic)
sleep(35)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb)
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
if("cult")
cinematic.icon_state = null
flick("intro_cult",cinematic)
sleep(25)
SEND_SOUND(world, sound('sound/magic/enter_blood.ogg'))
sleep(28)
SEND_SOUND(world, sound('sound/machines/terminal_off.ogg'))
sleep(20)
flick("station_corrupted",cinematic)
SEND_SOUND(world, sound('sound/effects/ghost.ogg'))
actually_blew_up = FALSE
if("fake") //The round isn't over, we're just freaking people out for fun
flick("intro_nuke",cinematic)
sleep(35)
SEND_SOUND(world, sound('sound/items/bikehorn.ogg'))
flick("summary_selfdes",cinematic)
actually_blew_up = FALSE
else
flick("intro_nuke",cinematic)
sleep(35)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb)
if(NUKE_MISS_STATION || NUKE_SYNDICATE_BASE) //nuke was nowhere nearby //TODO: a really distant explosion animation
sleep(50)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb)
actually_blew_up = station_missed == NUKE_SYNDICATE_BASE //don't kill everyone on station if it detonated off station
else //station was destroyed
if( mode && !override )
override = mode.name
switch( override )
if("nuclear emergency") //Nuke Ops successfully bombed the station
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb)
cinematic.icon_state = "summary_nukewin"
if("AI malfunction") //Malf (screen,explosion,summary)
flick("intro_malf",cinematic)
sleep(76)
flick("station_explode_fade_red",cinematic)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb) //TODO: If we ever decide to actually detonate the vault bomb
cinematic.icon_state = "summary_malf"
if("blob") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_selfdes"
if("cult") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_cult"
if("no_core") //Nuke failed to detonate as it had no core
flick("intro_nuke",cinematic)
sleep(35)
flick("station_intact",cinematic)
SEND_SOUND(world, sound('sound/ambience/signal.ogg'))
addtimer(CALLBACK(src, .proc/finish_cinematic, null, FALSE), 100)
return //Faster exit, since nothing happened
else //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red", cinematic)
SEND_SOUND(world, sound('sound/effects/explosion_distant.ogg'))
station_explosion_detonation(bomb)
cinematic.icon_state = "summary_selfdes"
//If its actually the end of the round, wait for it to end.
//Otherwise if its a verb it will continue on afterwards.
var/bombloc = null
if(actually_blew_up)
if(bomb && bomb.loc)
bombloc = bomb.z
else if(!station_missed)
bombloc = ZLEVEL_STATION_PRIMARY
if(mode)
mode.explosion_in_progress = 0
to_chat(world, "<B>The station was destoyed by the nuclear blast!</B>")
mode.station_was_nuked = (station_missed<2) //station_missed==1 is a draw. the station becomes irradiated and needs to be evacuated.
addtimer(CALLBACK(src, .proc/finish_cinematic, bombloc, actually_blew_up), 300)
/datum/controller/subsystem/ticker/proc/finish_cinematic(killz, actually_blew_up)
if(cinematic)
qdel(cinematic) //end the cinematic
cinematic = null
for(var/mob/M in GLOB.mob_list)
M.notransform = FALSE
if(actually_blew_up && !isnull(killz) && M.stat != DEAD && M.z == killz)
M.gib()
/datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.ready == PLAYER_READY_TO_PLAY && player.mind)
@@ -575,7 +440,7 @@ SUBSYSTEM_DEF(ticker)
CHECK_TICK
if(config.cross_allowed)
if(CONFIG_GET(string/cross_server_address))
send_news_report()
CHECK_TICK
@@ -672,7 +537,8 @@ SUBSYSTEM_DEF(ticker)
to_chat(world, "<font color='purple'><b>Tip of the round: </b>[html_encode(m)]</font>")
/datum/controller/subsystem/ticker/proc/check_queue()
if(!queued_players.len || !config.hard_popcap)
var/hpc = CONFIG_GET(number/hard_popcap)
if(!queued_players.len || !hpc)
return
queue_delay++
@@ -680,7 +546,7 @@ SUBSYSTEM_DEF(ticker)
switch(queue_delay)
if(5) //every 5 ticks check if there is a slot available
if(living_player_count() < config.hard_popcap)
if(living_player_count() < hpc)
if(next_in_line && next_in_line.client)
to_chat(next_in_line, "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>")
SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg'))
@@ -694,7 +560,7 @@ SUBSYSTEM_DEF(ticker)
queue_delay = 0
/datum/controller/subsystem/ticker/proc/check_maprotate()
if (!config.maprotation)
if (!CONFIG_GET(flag/maprotation))
return
if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
return
@@ -704,7 +570,7 @@ SUBSYSTEM_DEF(ticker)
maprotatechecked = 1
//map rotate chance defaults to 75% of the length of the round (in minutes)
if (!prob((world.time/600)*config.maprotatechancedelta))
if (!prob((world.time/600)*CONFIG_GET(number/maprotatechancedelta)))
return
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
@@ -751,13 +617,11 @@ SUBSYSTEM_DEF(ticker)
queue_delay = SSticker.queue_delay
queued_players = SSticker.queued_players
cinematic = SSticker.cinematic
maprotatechecked = SSticker.maprotatechecked
round_start_time = SSticker.round_start_time
queue_delay = SSticker.queue_delay
queued_players = SSticker.queued_players
cinematic = SSticker.cinematic
maprotatechecked = SSticker.maprotatechecked
modevoted = SSticker.modevoted
@@ -866,7 +730,7 @@ SUBSYSTEM_DEF(ticker)
return
if(!delay)
delay = config.round_end_countdown * 10
delay = CONFIG_GET(number/round_end_countdown) * 10
var/skip_delay = check_rights()
if(delay_end && !skip_delay)
+17 -14
View File
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/fire() //called by master_controller
if(mode)
time_remaining = round((started_time + config.vote_period - world.time)/10)
time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10)
if(time_remaining < 0)
result()
@@ -54,7 +54,7 @@ SUBSYSTEM_DEF(vote)
if(votes > greatest_votes)
greatest_votes = votes
//default-vote for everyone who didn't vote
if(!config.vote_no_default && choices.len)
if(!CONFIG_GET(flag/default_no_vote) && choices.len)
var/list/non_voters = GLOB.directory.Copy()
non_voters -= voted
for (var/non_voter_ckey in non_voters)
@@ -146,7 +146,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/submit_vote(vote)
if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder)
return 0
if(!(usr.ckey in voted))
if(vote && 1<=vote && vote<=choices.len)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
if(!mode)
if(started_time)
var/next_allowed_time = (started_time + config.vote_delay)
var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay))
if(mode)
to_chat(usr, "<span class='warning'>There is already a vote in progress! please wait for it to finish.</span>")
return 0
@@ -198,8 +198,9 @@ SUBSYSTEM_DEF(vote)
if(mode == "custom")
text += "\n[question]"
log_vote(text)
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [DisplayTimeText(config.vote_period)] to vote.</font>")
time_remaining = round(config.vote_period/10)
var/vp = CONFIG_GET(number/vote_period)
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [DisplayTimeText(vp)] to vote.</font>")
time_remaining = round(vp/10)
for(var/c in GLOB.clients)
var/client/C = c
var/datum/action/vote/V = new
@@ -238,20 +239,22 @@ SUBSYSTEM_DEF(vote)
else
. += "<h2>Start a vote:</h2><hr><ul><li>"
//restart
if(trialmin || config.allow_vote_restart)
var/avr = CONFIG_GET(flag/allow_vote_restart)
if(trialmin || avr)
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
else
. += "<font color='grey'>Restart (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[avr ? "Allowed" : "Disallowed"]</a>)"
. += "</li><li>"
//gamemode
if(trialmin || config.allow_vote_mode)
var/avm = CONFIG_GET(flag/allow_vote_mode)
if(trialmin || avm)
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
else
. += "<font color='grey'>GameMode (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[avm ? "Allowed" : "Disallowed"]</a>)"
. += "</li>"
//custom
@@ -275,15 +278,15 @@ SUBSYSTEM_DEF(vote)
reset()
if("toggle_restart")
if(usr.client.holder)
config.allow_vote_restart = !config.allow_vote_restart
CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart))
if("toggle_gamemode")
if(usr.client.holder)
config.allow_vote_mode = !config.allow_vote_mode
CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode))
if("restart")
if(config.allow_vote_restart || usr.client.holder)
if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder)
initiate_vote("restart",usr.key)
if("gamemode")
if(config.allow_vote_mode || usr.client.holder)
if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder)
initiate_vote("gamemode",usr.key)
if("custom")
if(usr.client.holder)