mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-25 09:31:13 +00:00
Merge master into map-development
This commit is contained in:
@@ -37,7 +37,7 @@ var/datum/controller/process/effects/effect_master
|
||||
effects_objects += E
|
||||
|
||||
if (EFFECT_DESTROY)
|
||||
qdel(E)
|
||||
returnToPool(E)
|
||||
|
||||
F_SCHECK
|
||||
|
||||
@@ -61,7 +61,7 @@ var/datum/controller/process/effects/effect_master
|
||||
if (EFFECT_DESTROY)
|
||||
effects_visuals -= V
|
||||
V.end()
|
||||
qdel(V)
|
||||
returnToPool(V)
|
||||
|
||||
F_SCHECK
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ var/datum/controller/process/night_lighting/nl_ctrl
|
||||
|
||||
/datum/controller/process/night_lighting/setup()
|
||||
name = "night lighting controller"
|
||||
schedule_interval = 3600 // Every 5 minutes.
|
||||
schedule_interval = 5 MINUTES
|
||||
|
||||
nl_ctrl = src
|
||||
|
||||
@@ -18,34 +18,26 @@ var/datum/controller/process/night_lighting/nl_ctrl
|
||||
// Stop trying to delete processes. Not how it goes.
|
||||
disabled = 1
|
||||
|
||||
|
||||
/datum/controller/process/night_lighting/preStart()
|
||||
|
||||
switch (worldtime2ticks())
|
||||
if (0 to config.nl_finish)
|
||||
deactivate()
|
||||
if (config.nl_start to TICKS_IN_DAY)
|
||||
activate()
|
||||
|
||||
var/time = worldtime2hours()
|
||||
if (time <= config.nl_finish || time >= config.nl_start)
|
||||
activate()
|
||||
else
|
||||
deactivate()
|
||||
|
||||
/datum/controller/process/night_lighting/doWork()
|
||||
if (manual_override) // don't automatically change lighting if it was manually changed in-game
|
||||
return
|
||||
|
||||
switch (worldtime2ticks())
|
||||
if (0 to config.nl_finish)
|
||||
if (isactive)
|
||||
command_announcement.Announce("Good morning. The time is [worldtime2text()]. \n\nThe automated systems aboard the [station_name()] will now return the public hallway lighting levels to normal.", "Automated Lighting System", new_sound = 'sound/misc/bosuns_whistle.ogg')
|
||||
deactivate()
|
||||
|
||||
if (config.nl_start to TICKS_IN_DAY)
|
||||
if (!isactive)
|
||||
command_announcement.Announce("Good evening. The time is [worldtime2text()]. \n\nThe automated systems aboard the [station_name()] will now dim lighting in the public hallways in order to accommodate the circadian rhythm of some species.", "Automated Lighting System", new_sound = 'sound/misc/bosuns_whistle.ogg')
|
||||
activate()
|
||||
|
||||
else
|
||||
if (isactive)
|
||||
deactivate()
|
||||
var/time = worldtime2hours()
|
||||
if (time <= config.nl_finish || time >= config.nl_start)
|
||||
if (!isactive)
|
||||
command_announcement.Announce("Good evening. The time is [worldtime2text()]. \n\nThe automated systems aboard the [station_name()] will now dim lighting in the public hallways in order to accommodate the circadian rhythm of some species.", "Automated Lighting System", new_sound = 'sound/misc/bosuns_whistle.ogg')
|
||||
activate()
|
||||
else
|
||||
if (isactive)
|
||||
command_announcement.Announce("Good morning. The time is [worldtime2text()]. \n\nThe automated systems aboard the [station_name()] will now return the public hallway lighting levels to normal.", "Automated Lighting System", new_sound = 'sound/misc/bosuns_whistle.ogg')
|
||||
deactivate()
|
||||
|
||||
// 'whitelisted' areas are areas that have nightmode explicitly enabled
|
||||
|
||||
|
||||
@@ -4,54 +4,141 @@
|
||||
* Scheduler *
|
||||
************/
|
||||
/datum/controller/process/scheduler
|
||||
var/list/scheduled_tasks
|
||||
var/tick_completed = TRUE
|
||||
var/list/queued_tasks
|
||||
var/list/datum/scheduled_task/tasks = list()
|
||||
var/datum/scheduled_task/head
|
||||
|
||||
/datum/controller/process/scheduler/setup()
|
||||
name = "scheduler"
|
||||
schedule_interval = 2 SECONDS
|
||||
scheduled_tasks = list()
|
||||
schedule_interval = 2
|
||||
scheduler = src
|
||||
|
||||
/datum/controller/process/scheduler/doWork()
|
||||
if (tick_completed)
|
||||
queued_tasks = scheduled_tasks.Copy()
|
||||
tick_completed = FALSE
|
||||
while (head && !PSCHED_CHECK_TICK)
|
||||
if (head.destroyed)
|
||||
head.kill()
|
||||
head = head.next
|
||||
tasks -= head
|
||||
continue
|
||||
if (head.trigger_time >= world.time)
|
||||
return // Nothing after this will be ready to fire.
|
||||
|
||||
while (queued_tasks.len)
|
||||
var/datum/scheduled_task/task = queued_tasks[queued_tasks.len]
|
||||
queued_tasks.len--
|
||||
// This one's ready to fire, process it.
|
||||
var/datum/scheduled_task/task = head
|
||||
head = task.next
|
||||
task.pre_process()
|
||||
task.process()
|
||||
task.post_process()
|
||||
if (task.destroyed) // post_process probably destroyed it.
|
||||
tasks -= task
|
||||
task.kill()
|
||||
|
||||
/datum/controller/process/scheduler/proc/queue(datum/scheduled_task/task)
|
||||
if (!task || !task.trigger_time)
|
||||
warning("scheduler: Invalid task queued! Ignoring.")
|
||||
return
|
||||
// Reset this in-case we're doing a rebuild.
|
||||
task.next = null
|
||||
if (!head && !tasks.len)
|
||||
head = task
|
||||
tasks += task
|
||||
return
|
||||
|
||||
if (!head) // Head's missing but we still have tasks, rebuild.
|
||||
tasks += task
|
||||
rebuild_queue()
|
||||
return
|
||||
|
||||
var/datum/scheduled_task/curr = head
|
||||
while (curr.next && curr.trigger_time < task.trigger_time)
|
||||
curr = curr.next
|
||||
|
||||
if (!curr.next)
|
||||
// We're at the end of the queue, just append.
|
||||
curr.next = task
|
||||
tasks += task
|
||||
return
|
||||
|
||||
// Inserting midway into the list.
|
||||
var/old_next = curr.next
|
||||
curr.next = task
|
||||
task.next = old_next
|
||||
tasks += task
|
||||
|
||||
// Rebuilds the queue linked-list, removing invalid or destroyed entries.
|
||||
/datum/controller/process/scheduler/proc/rebuild_queue()
|
||||
log_debug("scheduler: Rebuilding queue.")
|
||||
var/list/old_tasks = tasks
|
||||
tasks = list()
|
||||
if (!old_tasks.len)
|
||||
log_debug("scheduler: rebuild was called on empty queue! Aborting.")
|
||||
return
|
||||
|
||||
// Find the head.
|
||||
for (var/thing in old_tasks)
|
||||
var/datum/scheduled_task/task = thing
|
||||
if (QDELETED(task))
|
||||
scheduled_tasks -= task
|
||||
old_tasks -= task
|
||||
continue
|
||||
|
||||
if (world.time > task.trigger_time)
|
||||
unschedule(task)
|
||||
task.pre_process()
|
||||
task.process()
|
||||
task.post_process()
|
||||
F_SCHECK
|
||||
if (task.destroyed)
|
||||
old_tasks -= task
|
||||
task.kill()
|
||||
continue
|
||||
|
||||
tick_completed = TRUE
|
||||
if (!head || task.trigger_time < head.trigger_time)
|
||||
head = task
|
||||
|
||||
if (!head)
|
||||
log_debug("scheduler: unable to find head! Purging task queue.")
|
||||
for (var/thing in old_tasks)
|
||||
var/datum/scheduled_task/task = thing
|
||||
if (QDELETED(task))
|
||||
continue
|
||||
|
||||
task.kill()
|
||||
|
||||
head = null
|
||||
return
|
||||
|
||||
// Don't queue the head.
|
||||
tasks += head
|
||||
old_tasks -= head
|
||||
|
||||
// Now rebuild the queue.
|
||||
for (var/thing in old_tasks)
|
||||
var/datum/scheduled_task/task = thing
|
||||
|
||||
queue(task)
|
||||
|
||||
log_debug("scheduler: Queue diff is [old_tasks.len - tasks.len].")
|
||||
|
||||
/datum/controller/process/scheduler/statProcess()
|
||||
..()
|
||||
stat(null, "[scheduled_tasks.len] tasks, [queued_tasks.len] queued")
|
||||
stat(null, "[tasks.len] task\s")
|
||||
|
||||
/datum/controller/process/scheduler/proc/schedule(var/datum/scheduled_task/st)
|
||||
scheduled_tasks += st
|
||||
destroyed_event.register(st, src, /datum/controller/process/scheduler/proc/unschedule)
|
||||
queue(st)
|
||||
|
||||
/datum/controller/process/scheduler/proc/unschedule(var/datum/scheduled_task/st)
|
||||
if(st in scheduled_tasks)
|
||||
scheduled_tasks -= st
|
||||
destroyed_event.unregister(st, src)
|
||||
st.destroyed = TRUE
|
||||
|
||||
/**********
|
||||
* Helpers *
|
||||
**********/
|
||||
/proc/schedule(source, the_proc, time, ...)
|
||||
if (time < 0)
|
||||
return
|
||||
time += world.time
|
||||
var/list/the_args
|
||||
if (length(args) > 3)
|
||||
the_args = args.Copy(4)
|
||||
else
|
||||
the_args = list()
|
||||
if (source)
|
||||
return schedule_task_with_source(time, the_proc, the_args)
|
||||
else
|
||||
return schedule_task(time, the_proc, the_args)
|
||||
|
||||
/proc/schedule_task_in(var/in_time, var/procedure, var/list/arguments = list())
|
||||
return schedule_task(world.time + in_time, procedure, arguments)
|
||||
|
||||
@@ -77,68 +164,3 @@
|
||||
var/datum/scheduled_task/st = new/datum/scheduled_task/source(trigger_time, source, procedure, arguments, /proc/repeat_scheduled_task, list(repeat_interval))
|
||||
scheduler.schedule(st)
|
||||
return st
|
||||
|
||||
/*************
|
||||
* Task Datum *
|
||||
*************/
|
||||
/datum/scheduled_task
|
||||
var/trigger_time
|
||||
var/procedure
|
||||
var/list/arguments
|
||||
var/task_after_process
|
||||
var/list/task_after_process_args
|
||||
|
||||
/datum/scheduled_task/New(var/trigger_time, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args)
|
||||
..()
|
||||
src.trigger_time = trigger_time
|
||||
src.procedure = procedure
|
||||
src.arguments = arguments ? arguments : list()
|
||||
src.task_after_process = task_after_process ? task_after_process : /proc/destroy_scheduled_task
|
||||
src.task_after_process_args = istype(task_after_process_args) ? task_after_process_args : list()
|
||||
task_after_process_args += src
|
||||
|
||||
/datum/scheduled_task/Destroy()
|
||||
procedure = null
|
||||
arguments.Cut()
|
||||
task_after_process = null
|
||||
task_after_process_args.Cut()
|
||||
return ..()
|
||||
|
||||
/datum/scheduled_task/proc/pre_process()
|
||||
task_triggered_event.raise_event(list(src))
|
||||
|
||||
/datum/scheduled_task/proc/process()
|
||||
if(procedure)
|
||||
call(procedure)(arglist(arguments))
|
||||
|
||||
/datum/scheduled_task/proc/post_process()
|
||||
call(task_after_process)(arglist(task_after_process_args))
|
||||
|
||||
// Resets the trigger time, has no effect if the task has already triggered
|
||||
/datum/scheduled_task/proc/trigger_task_in(var/trigger_in)
|
||||
src.trigger_time = world.time + trigger_in
|
||||
|
||||
/datum/scheduled_task/source
|
||||
var/datum/source
|
||||
|
||||
/datum/scheduled_task/source/New(var/trigger_time, var/datum/source, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args)
|
||||
src.source = source
|
||||
destroyed_event.register(src.source, src, /datum/scheduled_task/source/proc/source_destroyed)
|
||||
..(trigger_time, procedure, arguments, task_after_process, task_after_process_args)
|
||||
|
||||
/datum/scheduled_task/source/Destroy()
|
||||
source = null
|
||||
return ..()
|
||||
|
||||
/datum/scheduled_task/source/process()
|
||||
call(source, procedure)(arglist(arguments))
|
||||
|
||||
/datum/scheduled_task/source/proc/source_destroyed()
|
||||
qdel(src)
|
||||
|
||||
/proc/destroy_scheduled_task(var/datum/scheduled_task/st)
|
||||
qdel(st)
|
||||
|
||||
/proc/repeat_scheduled_task(var/trigger_delay, var/datum/scheduled_task/st)
|
||||
st.trigger_time = world.time + trigger_delay
|
||||
scheduler.schedule(st)
|
||||
|
||||
@@ -177,8 +177,8 @@ var/list/gamemode_cache = list()
|
||||
var/ghost_interaction = 0
|
||||
|
||||
var/night_lighting = 0
|
||||
var/nl_start = 19 * TICKS_IN_HOUR
|
||||
var/nl_finish = 8 * TICKS_IN_HOUR
|
||||
var/nl_start = 19
|
||||
var/nl_finish = 8
|
||||
|
||||
var/comms_password = ""
|
||||
|
||||
@@ -187,6 +187,7 @@ var/list/gamemode_cache = list()
|
||||
var/use_discord_bot = 0
|
||||
var/discord_bot_host = "localhost"
|
||||
var/discord_bot_port = 0
|
||||
var/use_discord_pins = 0
|
||||
var/python_path = "python" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix
|
||||
var/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge.
|
||||
var/use_overmap = 0
|
||||
@@ -629,10 +630,10 @@ var/list/gamemode_cache = list()
|
||||
config.night_lighting = 1
|
||||
|
||||
if("nl_start_hour")
|
||||
config.nl_start = text2num(value) * TICKS_IN_HOUR
|
||||
config.nl_start = text2num(value)
|
||||
|
||||
if("nl_finish_hour")
|
||||
config.nl_finish = text2num(value) * TICKS_IN_HOUR
|
||||
config.nl_finish = text2num(value)
|
||||
|
||||
if("disable_player_mice")
|
||||
config.disable_player_mice = 1
|
||||
@@ -652,6 +653,9 @@ var/list/gamemode_cache = list()
|
||||
if("discord_bot_port")
|
||||
config.discord_bot_port = value
|
||||
|
||||
if("use_discord_pins")
|
||||
config.use_discord_pins = 1
|
||||
|
||||
if("python_path")
|
||||
if(value)
|
||||
config.python_path = value
|
||||
@@ -878,6 +882,8 @@ var/list/gamemode_cache = list()
|
||||
discord_bot.active = 1
|
||||
if ("robust_debug")
|
||||
discord_bot.robust_debug = 1
|
||||
if ("subscriber")
|
||||
discord_bot.subscriber_role = value
|
||||
else
|
||||
log_misc("Unknown setting in discord configuration: '[name]'")
|
||||
|
||||
|
||||
@@ -194,8 +194,16 @@ datum/controller/vote
|
||||
|
||||
proc/submit_vote(var/ckey, var/vote)
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if (mode == "crew_transfer")
|
||||
if(config.vote_no_dead && usr && !usr.client.holder)
|
||||
if (isnewplayer(usr))
|
||||
usr << "<span class='warning'>You must be playing or have been playing to start a vote.</span>"
|
||||
return 0
|
||||
else if (isobserver(usr))
|
||||
var/mob/dead/observer/O = usr
|
||||
if (O.started_as_observer)
|
||||
usr << "<span class='warning'>You must be playing or have been playing to start a vote.</span>"
|
||||
return 0
|
||||
if(vote && vote >= 1 && vote <= choices.len)
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
@@ -211,6 +219,16 @@ datum/controller/vote
|
||||
// Transfer votes are their own little special snowflake
|
||||
var/next_allowed_time = 0
|
||||
if (vote_type == "crew_transfer")
|
||||
if (config.vote_no_dead && !usr.client.holder)
|
||||
if (isnewplayer(usr))
|
||||
usr << "<span class='warning'>You must be playing or have been playing to start a vote.</span>"
|
||||
return 0
|
||||
else if (isobserver(usr))
|
||||
var/mob/dead/observer/O = usr
|
||||
if (O.started_as_observer)
|
||||
usr << "<span class='warning'>You must be playing or have been playing to start a vote.</span>"
|
||||
return 0
|
||||
|
||||
if (last_transfer_vote)
|
||||
next_allowed_time = (last_transfer_vote + config.vote_delay)
|
||||
else
|
||||
@@ -275,16 +293,16 @@ datum/controller/vote
|
||||
|
||||
log_vote(text)
|
||||
world << "<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 [config.vote_period/10] seconds to vote.</font>"
|
||||
for(var/client/C in clients)
|
||||
for(var/cc in clients)
|
||||
var/client/C = cc
|
||||
if(C.prefs.asfx_togs & ASFX_VOTE) //Personal mute
|
||||
C << sound('sound/effects/vote.ogg')
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("gamemode")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("custom")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
C << sound('sound/effects/vote.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("gamemode")
|
||||
C << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("custom")
|
||||
C << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if(mode == "gamemode" && round_progressing)
|
||||
round_progressing = 0
|
||||
world << "<font color='red'><b>Round start has been delayed.</b></font>"
|
||||
|
||||
Reference in New Issue
Block a user