mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-13 08:03:43 +01:00
File standardisation (#13131)
* Adds the check components * Adds in trailing newlines * Converts all CRLF to LF * Post merge EOF * Post merge line endings * Final commit
This commit is contained in:
+897
-897
File diff suppressed because it is too large
Load Diff
@@ -16,4 +16,4 @@
|
||||
|
||||
/datum/controller/proc/Recover()
|
||||
|
||||
/datum/controller/proc/stat_entry()
|
||||
/datum/controller/proc/stat_entry()
|
||||
|
||||
+102
-102
@@ -1,102 +1,102 @@
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
|
||||
name = "Failsafe"
|
||||
|
||||
// The length of time to check on the MC (in deciseconds).
|
||||
// Set to 0 to disable.
|
||||
var/processing_interval = 20
|
||||
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
|
||||
var/defcon = 5
|
||||
//the world.time of the last check, so the mc can restart US if we hang.
|
||||
// (Real friends look out for *eachother*)
|
||||
var/lasttick = 0
|
||||
|
||||
// Track the MC iteration to make sure its still on track.
|
||||
var/master_iteration = 0
|
||||
var/running = TRUE
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
qdel(Failsafe)
|
||||
Failsafe = src
|
||||
Initialize()
|
||||
|
||||
/datum/controller/failsafe/Initialize()
|
||||
set waitfor = 0
|
||||
Failsafe.Loop()
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
|
||||
|
||||
/datum/controller/failsafe/Destroy()
|
||||
running = FALSE
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/datum/controller/failsafe/proc/Loop()
|
||||
while(running)
|
||||
lasttick = world.time
|
||||
if(!Master)
|
||||
// Replace the missing Master! This should never, ever happen.
|
||||
new /datum/controller/master()
|
||||
// Only poke it if overrides are not in effect.
|
||||
if(processing_interval > 0)
|
||||
if(Master.processing && Master.iteration)
|
||||
// Check if processing is done yet.
|
||||
if(Master.iteration == master_iteration)
|
||||
switch(defcon)
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
message_admins("<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5 - defcon) * processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5 - defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5 - defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
if(defcon <= 1)
|
||||
sleep(processing_interval * 2)
|
||||
else
|
||||
sleep(processing_interval)
|
||||
else
|
||||
defcon = 5
|
||||
sleep(initial(processing_interval))
|
||||
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
/**
|
||||
* Failsafe
|
||||
*
|
||||
* Pretty much pokes the MC to make sure it's still alive.
|
||||
**/
|
||||
|
||||
GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
|
||||
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
|
||||
name = "Failsafe"
|
||||
|
||||
// The length of time to check on the MC (in deciseconds).
|
||||
// Set to 0 to disable.
|
||||
var/processing_interval = 20
|
||||
// The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC.
|
||||
var/defcon = 5
|
||||
//the world.time of the last check, so the mc can restart US if we hang.
|
||||
// (Real friends look out for *eachother*)
|
||||
var/lasttick = 0
|
||||
|
||||
// Track the MC iteration to make sure its still on track.
|
||||
var/master_iteration = 0
|
||||
var/running = TRUE
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
qdel(Failsafe)
|
||||
Failsafe = src
|
||||
Initialize()
|
||||
|
||||
/datum/controller/failsafe/Initialize()
|
||||
set waitfor = 0
|
||||
Failsafe.Loop()
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
|
||||
|
||||
/datum/controller/failsafe/Destroy()
|
||||
running = FALSE
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/datum/controller/failsafe/proc/Loop()
|
||||
while(running)
|
||||
lasttick = world.time
|
||||
if(!Master)
|
||||
// Replace the missing Master! This should never, ever happen.
|
||||
new /datum/controller/master()
|
||||
// Only poke it if overrides are not in effect.
|
||||
if(processing_interval > 0)
|
||||
if(Master.processing && Master.iteration)
|
||||
// Check if processing is done yet.
|
||||
if(Master.iteration == master_iteration)
|
||||
switch(defcon)
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
message_admins("<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5 - defcon) * processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5 - defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5 - defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
if(defcon <= 1)
|
||||
sleep(processing_interval * 2)
|
||||
else
|
||||
sleep(processing_interval)
|
||||
else
|
||||
defcon = 5
|
||||
sleep(initial(processing_interval))
|
||||
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
|
||||
@@ -64,4 +64,4 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
call(src, I)()
|
||||
var/end_tick = world.time
|
||||
if(end_tick - start_tick)
|
||||
warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!")
|
||||
warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!")
|
||||
|
||||
@@ -615,4 +615,4 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if(client_count < config.disable_high_pop_mc_mode_amount)
|
||||
processing = config.base_mc_tick_rate
|
||||
else if(client_count > config.high_pop_mc_mode_amount)
|
||||
processing = config.high_pop_mc_tick_rate
|
||||
processing = config.high_pop_mc_tick_rate
|
||||
|
||||
@@ -214,4 +214,4 @@
|
||||
next_fire = world.time + wait
|
||||
if("queued_priority") //editing this breaks things.
|
||||
return 0
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
@@ -33,4 +33,4 @@ SUBSYSTEM_DEF(acid)
|
||||
processing -= O
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -78,4 +78,4 @@ SUBSYSTEM_DEF(afk)
|
||||
break
|
||||
|
||||
#undef AFK_WARNED
|
||||
#undef AFK_CRYOD
|
||||
#undef AFK_CRYOD
|
||||
|
||||
@@ -382,4 +382,4 @@ SUBSYSTEM_DEF(air)
|
||||
#undef SSAIR_EXCITEDGROUPS
|
||||
#undef SSAIR_HIGHPRESSURE
|
||||
#undef SSAIR_HOTSPOTS
|
||||
#undef SSAIR_SUPERCONDUCTIVITY
|
||||
#undef SSAIR_SUPERCONDUCTIVITY
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
SUBSYSTEM_DEF(alarms)
|
||||
name = "Alarms"
|
||||
init_order = INIT_ORDER_ALARMS // 2
|
||||
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
var/datum/alarm_handler/burglar/burglar_alarm = new()
|
||||
var/datum/alarm_handler/camera/camera_alarm = new()
|
||||
var/datum/alarm_handler/fire/fire_alarm = new()
|
||||
var/datum/alarm_handler/motion/motion_alarm = new()
|
||||
var/datum/alarm_handler/power/power_alarm = new()
|
||||
var/list/datum/alarm/all_handlers
|
||||
|
||||
/datum/controller/subsystem/alarms/Initialize(start_timeofday)
|
||||
all_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/alarms/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/active_alarms()
|
||||
var/list/all_alarms = new ()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
SUBSYSTEM_DEF(alarms)
|
||||
name = "Alarms"
|
||||
init_order = INIT_ORDER_ALARMS // 2
|
||||
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
var/datum/alarm_handler/burglar/burglar_alarm = new()
|
||||
var/datum/alarm_handler/camera/camera_alarm = new()
|
||||
var/datum/alarm_handler/fire/fire_alarm = new()
|
||||
var/datum/alarm_handler/motion/motion_alarm = new()
|
||||
var/datum/alarm_handler/power/power_alarm = new()
|
||||
var/list/datum/alarm/all_handlers
|
||||
|
||||
/datum/controller/subsystem/alarms/Initialize(start_timeofday)
|
||||
all_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/alarms/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/active_alarms()
|
||||
var/list/all_alarms = new ()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
|
||||
@@ -14,4 +14,4 @@ SUBSYSTEM_DEF(assets)
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -63,4 +63,4 @@ SUBSYSTEM_DEF(chat)
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
@@ -1,299 +1,299 @@
|
||||
SUBSYSTEM_DEF(events)
|
||||
name = "Events"
|
||||
init_order = INIT_ORDER_EVENTS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
// Report events at the end of the rouund
|
||||
var/report_at_round_end = 0
|
||||
|
||||
// UI vars
|
||||
var/window_x = 700
|
||||
var/window_y = 600
|
||||
var/table_options = " align='center'"
|
||||
var/head_options = " style='font-weight:bold;'"
|
||||
var/row_options1 = " width='85px'"
|
||||
var/row_options2 = " width='260px'"
|
||||
var/row_options3 = " width='150px'"
|
||||
|
||||
// Event vars
|
||||
var/datum/event_container/selected_event_container = null
|
||||
var/list/active_events = list()
|
||||
var/list/finished_events = list()
|
||||
var/list/allEvents
|
||||
var/list/event_containers = list(
|
||||
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
|
||||
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
|
||||
EVENT_LEVEL_MAJOR = new/datum/event_container/major
|
||||
)
|
||||
|
||||
var/datum/event_meta/new_event = new
|
||||
|
||||
/datum/controller/subsystem/events/Initialize()
|
||||
allEvents = subtypesof(/datum/event)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/events/fire()
|
||||
for(var/datum/event/E in active_events)
|
||||
E.process()
|
||||
|
||||
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/list/datum/event_container/EC = event_containers[i]
|
||||
EC.process()
|
||||
|
||||
/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E)
|
||||
if(!E.event_meta) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
|
||||
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
||||
return
|
||||
|
||||
finished_events += E
|
||||
|
||||
var/theseverity
|
||||
|
||||
if(!E.severity)
|
||||
theseverity = EVENT_LEVEL_MODERATE
|
||||
|
||||
if(!E.severity == EVENT_LEVEL_MUNDANE && !E.severity == EVENT_LEVEL_MODERATE && !E.severity == EVENT_LEVEL_MAJOR)
|
||||
theseverity = EVENT_LEVEL_MODERATE //just to be careful
|
||||
|
||||
if(E.severity)
|
||||
theseverity = E.severity
|
||||
|
||||
// Add the event back to the list of available events
|
||||
var/datum/event_container/EC = event_containers[theseverity]
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
EC.available_events += EM
|
||||
|
||||
log_debug("Event '[EM.name]' has completed at [station_time_timestamp()].")
|
||||
|
||||
/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay)
|
||||
var/list/datum/event_container/EC = event_containers[severity]
|
||||
EC.next_event_time += delay
|
||||
|
||||
/datum/controller/subsystem/events/proc/Interact(var/mob/living/user)
|
||||
|
||||
var/html = GetInteractWindow()
|
||||
|
||||
var/datum/browser/popup = new(user, "event_manager", "Event Manager", window_x, window_y)
|
||||
popup.set_content(html)
|
||||
popup.open()
|
||||
|
||||
/datum/controller/subsystem/events/proc/RoundEnd()
|
||||
if(!report_at_round_end)
|
||||
return
|
||||
|
||||
to_chat(world, "<br><br><br><font size=3><b>Random Events This Round:</b></font>")
|
||||
for(var/datum/event/E in active_events|finished_events)
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
if(EM.name == "Nothing")
|
||||
continue
|
||||
var/message = "'[EM.name]' began at [station_time_timestamp("hh:mm:ss", E.startedAt)] "
|
||||
if(E.isRunning)
|
||||
message += "and is still running."
|
||||
else
|
||||
if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes
|
||||
message += "and ended at [station_time_timestamp("hh:mm:ss", E.endedAt)]."
|
||||
else
|
||||
message += "and ran to completion."
|
||||
|
||||
to_chat(world, message)
|
||||
|
||||
/datum/controller/subsystem/events/proc/GetInteractWindow()
|
||||
var/html = "<A align='right' href='?src=[UID()];refresh=1'>Refresh</A>"
|
||||
|
||||
if(selected_event_container)
|
||||
var/event_time = max(0, selected_event_container.next_event_time - world.time)
|
||||
html += "<A align='right' href='?src=[UID()];back=1'>Back</A><br>"
|
||||
html += "Time till start: [round(event_time / 600, 0.1)]<br>"
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Available [severity_to_string[selected_event_container.severity]] Events (queued & running events will not be displayed)</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options2]>Name </td><td>Weight </td><td>MinWeight </td><td>MaxWeight </td><td>OneShot </td><td>Enabled </td><td><span class='alert'>CurrWeight </span></td><td>Remove</td></tr>"
|
||||
for(var/datum/event_meta/EM in selected_event_container.available_events)
|
||||
html += "<tr>"
|
||||
html += "<td>[EM.name]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_weight=\ref[EM]'>[EM.weight]</A></td>"
|
||||
html += "<td>[EM.min_weight]</td>"
|
||||
html += "<td>[EM.max_weight]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_oneshot=\ref[EM]'>[EM.one_shot]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_enabled=\ref[EM]'>[EM.enabled]</A></td>"
|
||||
html += "<td><span class='alert'>[EM.get_weight(number_active_with_role())]</span></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];remove=\ref[EM];EC=\ref[selected_event_container]'>Remove</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Add Event</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr [head_options]><td[row_options2]>Name</td><td[row_options2]>Type</td><td[row_options1]>Weight</td><td[row_options1]>OneShot</td></tr>"
|
||||
html += "<tr>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_name=\ref[new_event]'>[new_event.name ? new_event.name : "Enter Event"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_type=\ref[new_event]'>[new_event.event_type ? new_event.event_type : "Select Type"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_weight=\ref[new_event]'>[new_event.weight ? new_event.weight : 0]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_oneshot=\ref[new_event]'>[new_event.one_shot]</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "<A align='right' href='?src=[UID()];add=\ref[selected_event_container]'>Add</A><br>"
|
||||
html += "</div>"
|
||||
else
|
||||
html += "<A align='right' href='?src=[UID()];toggle_report=1'>Round End Report: [report_at_round_end ? "On": "Off"]</A><br>"
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Event Start</h2>"
|
||||
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options1]>Starts At</td><td[row_options1]>Starts In</td><td[row_options3]>Adjust Start</td><td[row_options1]>Pause</td><td[row_options1]>Interval Mod</td></tr>"
|
||||
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/datum/event_container/EC = event_containers[severity]
|
||||
var/next_event_at = max(0, EC.next_event_time - world.time)
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[severity]]</td>"
|
||||
html += "<td>[station_time_timestamp("hh:mm:ss", max(EC.next_event_time, world.time))]</td>"
|
||||
html += "<td>[round(next_event_at / 600, 0.1)]</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];dec_timer=2;event=\ref[EC]'>--</A>"
|
||||
html += "<A align='right' href='?src=[UID()];dec_timer=1;event=\ref[EC]'>-</A>"
|
||||
html += "<A align='right' href='?src=[UID()];inc_timer=1;event=\ref[EC]'>+</A>"
|
||||
html += "<A align='right' href='?src=[UID()];inc_timer=2;event=\ref[EC]'>++</A>"
|
||||
html += "</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];pause=\ref[EC]'>[EC.delayed ? "Resume" : "Pause"]</A>"
|
||||
html += "</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];interval=\ref[EC]'>[EC.delay_modifier]</A>"
|
||||
html += "</td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Next Event</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options3]>Event Rotation</td><td>Clear</td></tr>"
|
||||
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/datum/event_container/EC = event_containers[severity]
|
||||
var/datum/event_meta/EM = EC.next_event
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[severity]]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];select_event=\ref[EC]'>[EM ? EM.name : "Random"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];view_events=\ref[EC]'>View</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];clear=\ref[EC]'>Clear</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Running Events</h2>"
|
||||
html += "Estimated times, affected by master controller delays."
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options1]>Ends At</td><td[row_options1]>Ends In</td><td[row_options3]>Stop</td></tr>"
|
||||
for(var/datum/event/E in active_events)
|
||||
if(!E.event_meta)
|
||||
continue
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
var/ends_at = E.startedAt + (E.lastProcessAt() * 20) // A best estimate, based on how often the manager processes
|
||||
var/ends_in = max(0, round((ends_at - world.time) / 600, 0.1))
|
||||
var/no_end = E.noAutoEnd
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[EM.severity]]</td>"
|
||||
html += "<td>[EM.name]</td>"
|
||||
html += "<td>[no_end ? "N/A" : station_time_timestamp("hh:mm:ss", ends_at)]</td>"
|
||||
html += "<td>[no_end ? "N/A" : ends_in]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];stop=\ref[E]'>Stop</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
return html
|
||||
|
||||
/datum/controller/subsystem/events/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
|
||||
if(href_list["toggle_report"])
|
||||
report_at_round_end = !report_at_round_end
|
||||
admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
|
||||
else if(href_list["dec_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/decrease = (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
|
||||
EC.next_event_time -= decrease
|
||||
admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
|
||||
else if(href_list["inc_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/increase = (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
|
||||
EC.next_event_time += increase
|
||||
admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
|
||||
else if(href_list["select_event"])
|
||||
var/datum/event_container/EC = locate(href_list["select_event"])
|
||||
var/datum/event_meta/EM = EC.SelectEvent()
|
||||
if(EM)
|
||||
admin_log_and_message_admins("has queued the [severity_to_string[EC.severity]] event '[EM.name]'.")
|
||||
else if(href_list["pause"])
|
||||
var/datum/event_container/EC = locate(href_list["pause"])
|
||||
EC.delayed = !EC.delayed
|
||||
admin_log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.")
|
||||
else if(href_list["interval"])
|
||||
var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null
|
||||
if(delay && delay > 0)
|
||||
var/datum/event_container/EC = locate(href_list["interval"])
|
||||
EC.delay_modifier = delay
|
||||
admin_log_and_message_admins("has set the interval modifier for [severity_to_string[EC.severity]] events to [EC.delay_modifier].")
|
||||
else if(href_list["stop"])
|
||||
if(alert("Stopping an event may have unintended side-effects. Continue?","Stopping Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event/E = locate(href_list["stop"])
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
admin_log_and_message_admins("has stopped the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
E.kill()
|
||||
else if(href_list["view_events"])
|
||||
selected_event_container = locate(href_list["view_events"])
|
||||
else if(href_list["back"])
|
||||
selected_event_container = null
|
||||
else if(href_list["set_name"])
|
||||
var/name = clean_input("Enter event name.", "Set Name")
|
||||
if(name)
|
||||
var/datum/event_meta/EM = locate(href_list["set_name"])
|
||||
EM.name = name
|
||||
else if(href_list["set_type"])
|
||||
var/type = input("Select event type.", "Select") as null|anything in allEvents
|
||||
if(type)
|
||||
var/datum/event_meta/EM = locate(href_list["set_type"])
|
||||
EM.event_type = type
|
||||
else if(href_list["set_weight"])
|
||||
var/weight = input("Enter weight. A higher value means higher chance for the event of being selected.", "Set Weight") as num|null
|
||||
if(weight && weight > 0)
|
||||
var/datum/event_meta/EM = locate(href_list["set_weight"])
|
||||
EM.weight = weight
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has changed the weight of the [severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
|
||||
else if(href_list["toggle_oneshot"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_oneshot"])
|
||||
EM.one_shot = !EM.one_shot
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["toggle_enabled"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_enabled"])
|
||||
EM.enabled = !EM.enabled
|
||||
admin_log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["remove"])
|
||||
if(alert("This will remove the event from rotation. Continue?","Removing Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event_meta/EM = locate(href_list["remove"])
|
||||
var/datum/event_container/EC = locate(href_list["EC"])
|
||||
EC.available_events -= EM
|
||||
admin_log_and_message_admins("has removed the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["add"])
|
||||
if(!new_event.name || !new_event.event_type)
|
||||
return
|
||||
if(alert("This will add a new event to the rotation. Continue?","Add Event!","Yes","No") != "Yes")
|
||||
return
|
||||
new_event.severity = selected_event_container.severity
|
||||
selected_event_container.available_events += new_event
|
||||
admin_log_and_message_admins("has added \a [severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
|
||||
new_event = new
|
||||
else if(href_list["clear"])
|
||||
var/datum/event_container/EC = locate(href_list["clear"])
|
||||
if(EC.next_event)
|
||||
admin_log_and_message_admins("has dequeued the [severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
|
||||
EC.next_event = null
|
||||
|
||||
Interact(usr)
|
||||
SUBSYSTEM_DEF(events)
|
||||
name = "Events"
|
||||
init_order = INIT_ORDER_EVENTS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
// Report events at the end of the rouund
|
||||
var/report_at_round_end = 0
|
||||
|
||||
// UI vars
|
||||
var/window_x = 700
|
||||
var/window_y = 600
|
||||
var/table_options = " align='center'"
|
||||
var/head_options = " style='font-weight:bold;'"
|
||||
var/row_options1 = " width='85px'"
|
||||
var/row_options2 = " width='260px'"
|
||||
var/row_options3 = " width='150px'"
|
||||
|
||||
// Event vars
|
||||
var/datum/event_container/selected_event_container = null
|
||||
var/list/active_events = list()
|
||||
var/list/finished_events = list()
|
||||
var/list/allEvents
|
||||
var/list/event_containers = list(
|
||||
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
|
||||
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
|
||||
EVENT_LEVEL_MAJOR = new/datum/event_container/major
|
||||
)
|
||||
|
||||
var/datum/event_meta/new_event = new
|
||||
|
||||
/datum/controller/subsystem/events/Initialize()
|
||||
allEvents = subtypesof(/datum/event)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/events/fire()
|
||||
for(var/datum/event/E in active_events)
|
||||
E.process()
|
||||
|
||||
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/list/datum/event_container/EC = event_containers[i]
|
||||
EC.process()
|
||||
|
||||
/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E)
|
||||
if(!E.event_meta) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
|
||||
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
||||
return
|
||||
|
||||
finished_events += E
|
||||
|
||||
var/theseverity
|
||||
|
||||
if(!E.severity)
|
||||
theseverity = EVENT_LEVEL_MODERATE
|
||||
|
||||
if(!E.severity == EVENT_LEVEL_MUNDANE && !E.severity == EVENT_LEVEL_MODERATE && !E.severity == EVENT_LEVEL_MAJOR)
|
||||
theseverity = EVENT_LEVEL_MODERATE //just to be careful
|
||||
|
||||
if(E.severity)
|
||||
theseverity = E.severity
|
||||
|
||||
// Add the event back to the list of available events
|
||||
var/datum/event_container/EC = event_containers[theseverity]
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
EC.available_events += EM
|
||||
|
||||
log_debug("Event '[EM.name]' has completed at [station_time_timestamp()].")
|
||||
|
||||
/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay)
|
||||
var/list/datum/event_container/EC = event_containers[severity]
|
||||
EC.next_event_time += delay
|
||||
|
||||
/datum/controller/subsystem/events/proc/Interact(var/mob/living/user)
|
||||
|
||||
var/html = GetInteractWindow()
|
||||
|
||||
var/datum/browser/popup = new(user, "event_manager", "Event Manager", window_x, window_y)
|
||||
popup.set_content(html)
|
||||
popup.open()
|
||||
|
||||
/datum/controller/subsystem/events/proc/RoundEnd()
|
||||
if(!report_at_round_end)
|
||||
return
|
||||
|
||||
to_chat(world, "<br><br><br><font size=3><b>Random Events This Round:</b></font>")
|
||||
for(var/datum/event/E in active_events|finished_events)
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
if(EM.name == "Nothing")
|
||||
continue
|
||||
var/message = "'[EM.name]' began at [station_time_timestamp("hh:mm:ss", E.startedAt)] "
|
||||
if(E.isRunning)
|
||||
message += "and is still running."
|
||||
else
|
||||
if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes
|
||||
message += "and ended at [station_time_timestamp("hh:mm:ss", E.endedAt)]."
|
||||
else
|
||||
message += "and ran to completion."
|
||||
|
||||
to_chat(world, message)
|
||||
|
||||
/datum/controller/subsystem/events/proc/GetInteractWindow()
|
||||
var/html = "<A align='right' href='?src=[UID()];refresh=1'>Refresh</A>"
|
||||
|
||||
if(selected_event_container)
|
||||
var/event_time = max(0, selected_event_container.next_event_time - world.time)
|
||||
html += "<A align='right' href='?src=[UID()];back=1'>Back</A><br>"
|
||||
html += "Time till start: [round(event_time / 600, 0.1)]<br>"
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Available [severity_to_string[selected_event_container.severity]] Events (queued & running events will not be displayed)</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options2]>Name </td><td>Weight </td><td>MinWeight </td><td>MaxWeight </td><td>OneShot </td><td>Enabled </td><td><span class='alert'>CurrWeight </span></td><td>Remove</td></tr>"
|
||||
for(var/datum/event_meta/EM in selected_event_container.available_events)
|
||||
html += "<tr>"
|
||||
html += "<td>[EM.name]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_weight=\ref[EM]'>[EM.weight]</A></td>"
|
||||
html += "<td>[EM.min_weight]</td>"
|
||||
html += "<td>[EM.max_weight]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_oneshot=\ref[EM]'>[EM.one_shot]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_enabled=\ref[EM]'>[EM.enabled]</A></td>"
|
||||
html += "<td><span class='alert'>[EM.get_weight(number_active_with_role())]</span></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];remove=\ref[EM];EC=\ref[selected_event_container]'>Remove</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Add Event</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr [head_options]><td[row_options2]>Name</td><td[row_options2]>Type</td><td[row_options1]>Weight</td><td[row_options1]>OneShot</td></tr>"
|
||||
html += "<tr>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_name=\ref[new_event]'>[new_event.name ? new_event.name : "Enter Event"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_type=\ref[new_event]'>[new_event.event_type ? new_event.event_type : "Select Type"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];set_weight=\ref[new_event]'>[new_event.weight ? new_event.weight : 0]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];toggle_oneshot=\ref[new_event]'>[new_event.one_shot]</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "<A align='right' href='?src=[UID()];add=\ref[selected_event_container]'>Add</A><br>"
|
||||
html += "</div>"
|
||||
else
|
||||
html += "<A align='right' href='?src=[UID()];toggle_report=1'>Round End Report: [report_at_round_end ? "On": "Off"]</A><br>"
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Event Start</h2>"
|
||||
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options1]>Starts At</td><td[row_options1]>Starts In</td><td[row_options3]>Adjust Start</td><td[row_options1]>Pause</td><td[row_options1]>Interval Mod</td></tr>"
|
||||
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/datum/event_container/EC = event_containers[severity]
|
||||
var/next_event_at = max(0, EC.next_event_time - world.time)
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[severity]]</td>"
|
||||
html += "<td>[station_time_timestamp("hh:mm:ss", max(EC.next_event_time, world.time))]</td>"
|
||||
html += "<td>[round(next_event_at / 600, 0.1)]</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];dec_timer=2;event=\ref[EC]'>--</A>"
|
||||
html += "<A align='right' href='?src=[UID()];dec_timer=1;event=\ref[EC]'>-</A>"
|
||||
html += "<A align='right' href='?src=[UID()];inc_timer=1;event=\ref[EC]'>+</A>"
|
||||
html += "<A align='right' href='?src=[UID()];inc_timer=2;event=\ref[EC]'>++</A>"
|
||||
html += "</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];pause=\ref[EC]'>[EC.delayed ? "Resume" : "Pause"]</A>"
|
||||
html += "</td>"
|
||||
html += "<td>"
|
||||
html += "<A align='right' href='?src=[UID()];interval=\ref[EC]'>[EC.delay_modifier]</A>"
|
||||
html += "</td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Next Event</h2>"
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options3]>Event Rotation</td><td>Clear</td></tr>"
|
||||
for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
var/datum/event_container/EC = event_containers[severity]
|
||||
var/datum/event_meta/EM = EC.next_event
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[severity]]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];select_event=\ref[EC]'>[EM ? EM.name : "Random"]</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];view_events=\ref[EC]'>View</A></td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];clear=\ref[EC]'>Clear</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
html += "<div class='block'>"
|
||||
html += "<h2>Running Events</h2>"
|
||||
html += "Estimated times, affected by master controller delays."
|
||||
html += "<table[table_options]>"
|
||||
html += "<tr[head_options]><td[row_options1]>Severity</td><td[row_options2]>Name</td><td[row_options1]>Ends At</td><td[row_options1]>Ends In</td><td[row_options3]>Stop</td></tr>"
|
||||
for(var/datum/event/E in active_events)
|
||||
if(!E.event_meta)
|
||||
continue
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
var/ends_at = E.startedAt + (E.lastProcessAt() * 20) // A best estimate, based on how often the manager processes
|
||||
var/ends_in = max(0, round((ends_at - world.time) / 600, 0.1))
|
||||
var/no_end = E.noAutoEnd
|
||||
html += "<tr>"
|
||||
html += "<td>[severity_to_string[EM.severity]]</td>"
|
||||
html += "<td>[EM.name]</td>"
|
||||
html += "<td>[no_end ? "N/A" : station_time_timestamp("hh:mm:ss", ends_at)]</td>"
|
||||
html += "<td>[no_end ? "N/A" : ends_in]</td>"
|
||||
html += "<td><A align='right' href='?src=[UID()];stop=\ref[E]'>Stop</A></td>"
|
||||
html += "</tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
return html
|
||||
|
||||
/datum/controller/subsystem/events/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
|
||||
if(href_list["toggle_report"])
|
||||
report_at_round_end = !report_at_round_end
|
||||
admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
|
||||
else if(href_list["dec_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/decrease = (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
|
||||
EC.next_event_time -= decrease
|
||||
admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
|
||||
else if(href_list["inc_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/increase = (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
|
||||
EC.next_event_time += increase
|
||||
admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
|
||||
else if(href_list["select_event"])
|
||||
var/datum/event_container/EC = locate(href_list["select_event"])
|
||||
var/datum/event_meta/EM = EC.SelectEvent()
|
||||
if(EM)
|
||||
admin_log_and_message_admins("has queued the [severity_to_string[EC.severity]] event '[EM.name]'.")
|
||||
else if(href_list["pause"])
|
||||
var/datum/event_container/EC = locate(href_list["pause"])
|
||||
EC.delayed = !EC.delayed
|
||||
admin_log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [severity_to_string[EC.severity]] events.")
|
||||
else if(href_list["interval"])
|
||||
var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null
|
||||
if(delay && delay > 0)
|
||||
var/datum/event_container/EC = locate(href_list["interval"])
|
||||
EC.delay_modifier = delay
|
||||
admin_log_and_message_admins("has set the interval modifier for [severity_to_string[EC.severity]] events to [EC.delay_modifier].")
|
||||
else if(href_list["stop"])
|
||||
if(alert("Stopping an event may have unintended side-effects. Continue?","Stopping Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event/E = locate(href_list["stop"])
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
admin_log_and_message_admins("has stopped the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
E.kill()
|
||||
else if(href_list["view_events"])
|
||||
selected_event_container = locate(href_list["view_events"])
|
||||
else if(href_list["back"])
|
||||
selected_event_container = null
|
||||
else if(href_list["set_name"])
|
||||
var/name = clean_input("Enter event name.", "Set Name")
|
||||
if(name)
|
||||
var/datum/event_meta/EM = locate(href_list["set_name"])
|
||||
EM.name = name
|
||||
else if(href_list["set_type"])
|
||||
var/type = input("Select event type.", "Select") as null|anything in allEvents
|
||||
if(type)
|
||||
var/datum/event_meta/EM = locate(href_list["set_type"])
|
||||
EM.event_type = type
|
||||
else if(href_list["set_weight"])
|
||||
var/weight = input("Enter weight. A higher value means higher chance for the event of being selected.", "Set Weight") as num|null
|
||||
if(weight && weight > 0)
|
||||
var/datum/event_meta/EM = locate(href_list["set_weight"])
|
||||
EM.weight = weight
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has changed the weight of the [severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
|
||||
else if(href_list["toggle_oneshot"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_oneshot"])
|
||||
EM.one_shot = !EM.one_shot
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["toggle_enabled"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_enabled"])
|
||||
EM.enabled = !EM.enabled
|
||||
admin_log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["remove"])
|
||||
if(alert("This will remove the event from rotation. Continue?","Removing Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event_meta/EM = locate(href_list["remove"])
|
||||
var/datum/event_container/EC = locate(href_list["EC"])
|
||||
EC.available_events -= EM
|
||||
admin_log_and_message_admins("has removed the [severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["add"])
|
||||
if(!new_event.name || !new_event.event_type)
|
||||
return
|
||||
if(alert("This will add a new event to the rotation. Continue?","Add Event!","Yes","No") != "Yes")
|
||||
return
|
||||
new_event.severity = selected_event_container.severity
|
||||
selected_event_container.available_events += new_event
|
||||
admin_log_and_message_admins("has added \a [severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
|
||||
new_event = new
|
||||
else if(href_list["clear"])
|
||||
var/datum/event_container/EC = locate(href_list["clear"])
|
||||
if(EC.next_event)
|
||||
admin_log_and_message_admins("has dequeued the [severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
|
||||
EC.next_event = null
|
||||
|
||||
Interact(usr)
|
||||
|
||||
@@ -432,4 +432,4 @@ SUBSYSTEM_DEF(garbage)
|
||||
CHECK_TICK
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
SUBSYSTEM_DEF(holiday)
|
||||
name = "Holiday"
|
||||
init_order = INIT_ORDER_HOLIDAY // 3
|
||||
flags = SS_NO_FIRE
|
||||
var/list/holidays
|
||||
|
||||
/datum/controller/subsystem/holiday/Initialize(start_timeofday)
|
||||
if(!config.allow_holidays)
|
||||
return ..() //Holiday stuff was not enabled in the config!
|
||||
|
||||
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
|
||||
for(var/H in subtypesof(/datum/holiday))
|
||||
var/datum/holiday/holiday = new H()
|
||||
if(holiday.shouldCelebrate(DD, MM, YY))
|
||||
holiday.celebrate()
|
||||
if(!holidays)
|
||||
holidays = list()
|
||||
holidays[holiday.name] = holiday
|
||||
|
||||
if(holidays)
|
||||
holidays = shuffle(holidays)
|
||||
world.update_status()
|
||||
for(var/datum/holiday/H in holidays)
|
||||
if(H.eventChance)
|
||||
if(prob(H.eventChance))
|
||||
H.handle_event()
|
||||
|
||||
return ..()
|
||||
SUBSYSTEM_DEF(holiday)
|
||||
name = "Holiday"
|
||||
init_order = INIT_ORDER_HOLIDAY // 3
|
||||
flags = SS_NO_FIRE
|
||||
var/list/holidays
|
||||
|
||||
/datum/controller/subsystem/holiday/Initialize(start_timeofday)
|
||||
if(!config.allow_holidays)
|
||||
return ..() //Holiday stuff was not enabled in the config!
|
||||
|
||||
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
|
||||
for(var/H in subtypesof(/datum/holiday))
|
||||
var/datum/holiday/holiday = new H()
|
||||
if(holiday.shouldCelebrate(DD, MM, YY))
|
||||
holiday.celebrate()
|
||||
if(!holidays)
|
||||
holidays = list()
|
||||
holidays[holiday.name] = holiday
|
||||
|
||||
if(holidays)
|
||||
holidays = shuffle(holidays)
|
||||
world.update_status()
|
||||
for(var/datum/holiday/H in holidays)
|
||||
if(H.eventChance)
|
||||
if(prob(H.eventChance))
|
||||
H.handle_event()
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -39,4 +39,4 @@ SUBSYSTEM_DEF(idlenpcpool)
|
||||
if(SA.stat != DEAD)
|
||||
SA.consider_wakeup()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -84,4 +84,4 @@ SUBSYSTEM_DEF(lighting)
|
||||
|
||||
/datum/controller/subsystem/lighting/Recover()
|
||||
initialized = SSlighting.initialized
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -33,4 +33,4 @@ SUBSYSTEM_DEF(mapping)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/mapping/Recover()
|
||||
flags |= SS_NO_INIT
|
||||
flags |= SS_NO_INIT
|
||||
|
||||
@@ -83,4 +83,4 @@ SUBSYSTEM_DEF(medals)
|
||||
/datum/controller/subsystem/medals/proc/ClearScore(client/player)
|
||||
if(isnull(world.SetScores(player.ckey, "", config.medal_hub_address, config.medal_hub_password)))
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.ckey].")
|
||||
message_admins("Error! Failed to contact hub to clear scores for [player.ckey]!")
|
||||
message_admins("Error! Failed to contact hub to clear scores for [player.ckey]!")
|
||||
|
||||
@@ -33,4 +33,4 @@ SUBSYSTEM_DEF(mobs)
|
||||
else
|
||||
GLOB.mob_list.Remove(M)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -34,4 +34,4 @@ SUBSYSTEM_DEF(npcpool)
|
||||
if(SA.stat != DEAD)
|
||||
SA.handle_automated_speech()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(fastprocess)
|
||||
name = "Fast Processing"
|
||||
wait = 2
|
||||
stat_tag = "FP"
|
||||
stat_tag = "FP"
|
||||
|
||||
@@ -2,4 +2,4 @@ PROCESSING_SUBSYSTEM_DEF(obj)
|
||||
name = "Objects"
|
||||
priority = FIRE_PRIORITY_OBJ
|
||||
flags = SS_NO_INIT
|
||||
wait = 20
|
||||
wait = 20
|
||||
|
||||
@@ -34,4 +34,4 @@ SUBSYSTEM_DEF(processing)
|
||||
|
||||
/datum/proc/process()
|
||||
set waitfor = 0
|
||||
return PROCESS_KILL
|
||||
return PROCESS_KILL
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
SUBSYSTEM_DEF(radio)
|
||||
name = "Radio"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
|
||||
var/list/radiochannels = list(
|
||||
"Common" = PUB_FREQ,
|
||||
"Science" = SCI_FREQ,
|
||||
"Command" = COMM_FREQ,
|
||||
"Medical" = MED_FREQ,
|
||||
"Engineering" = ENG_FREQ,
|
||||
"Security" = SEC_FREQ,
|
||||
"Response Team" = ERT_FREQ,
|
||||
"Special Ops" = DTH_FREQ,
|
||||
"Syndicate" = SYND_FREQ,
|
||||
"SyndTeam" = SYNDTEAM_FREQ,
|
||||
"Supply" = SUP_FREQ,
|
||||
"Service" = SRV_FREQ,
|
||||
"AI Private" = AI_FREQ,
|
||||
"Medical(I)" = MED_I_FREQ,
|
||||
"Security(I)" = SEC_I_FREQ
|
||||
)
|
||||
var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ)
|
||||
var/list/ANTAG_FREQS = list(SYND_FREQ, SYNDTEAM_FREQ)
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
// This is fucking disgusting and needs to die
|
||||
/datum/controller/subsystem/radio/proc/frequency_span_class(var/frequency)
|
||||
// Antags!
|
||||
if(frequency in ANTAG_FREQS)
|
||||
return "syndradio"
|
||||
// centcomm channels (deathsquid and ert)
|
||||
if(frequency in CENT_FREQS)
|
||||
return "centradio"
|
||||
// This switch used to be a shit tonne of if statements. I am gonna find who made this and give them a kind talking to
|
||||
switch(frequency)
|
||||
if(COMM_FREQ)
|
||||
return "comradio"
|
||||
if(AI_FREQ)
|
||||
return "airadio"
|
||||
if(SEC_FREQ)
|
||||
return "secradio"
|
||||
if(ENG_FREQ)
|
||||
return "engradio"
|
||||
if(SCI_FREQ)
|
||||
return "sciradio"
|
||||
if(MED_FREQ)
|
||||
return "medradio"
|
||||
if(SUP_FREQ)
|
||||
return "supradio"
|
||||
if(SRV_FREQ)
|
||||
return "srvradio"
|
||||
|
||||
// If the above switch somehow failed. And it needs the SSradio. part otherwise it fails to compile
|
||||
if(frequency in DEPT_FREQS)
|
||||
return "deptradio"
|
||||
|
||||
// If its none of the others
|
||||
return "radio"
|
||||
|
||||
|
||||
/datum/controller/subsystem/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
frequency.add_listener(device, filter)
|
||||
return frequency
|
||||
|
||||
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
|
||||
var/f_text = num2text(old_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(frequency)
|
||||
frequency.remove_listener(device)
|
||||
|
||||
if(frequency.devices.len == 0)
|
||||
qdel(frequency)
|
||||
frequencies -= f_text
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/radio/proc/return_frequency(var/new_frequency as num)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
return frequency
|
||||
|
||||
|
||||
// ALL THE SHIT BELOW THIS LINE ISNT PART OF THE SUBSYSTEM AND REALLY NEEDS ITS OWN FILE
|
||||
SUBSYSTEM_DEF(radio)
|
||||
name = "Radio"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
|
||||
var/list/radiochannels = list(
|
||||
"Common" = PUB_FREQ,
|
||||
"Science" = SCI_FREQ,
|
||||
"Command" = COMM_FREQ,
|
||||
"Medical" = MED_FREQ,
|
||||
"Engineering" = ENG_FREQ,
|
||||
"Security" = SEC_FREQ,
|
||||
"Response Team" = ERT_FREQ,
|
||||
"Special Ops" = DTH_FREQ,
|
||||
"Syndicate" = SYND_FREQ,
|
||||
"SyndTeam" = SYNDTEAM_FREQ,
|
||||
"Supply" = SUP_FREQ,
|
||||
"Service" = SRV_FREQ,
|
||||
"AI Private" = AI_FREQ,
|
||||
"Medical(I)" = MED_I_FREQ,
|
||||
"Security(I)" = SEC_I_FREQ
|
||||
)
|
||||
var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ)
|
||||
var/list/ANTAG_FREQS = list(SYND_FREQ, SYNDTEAM_FREQ)
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
// This is fucking disgusting and needs to die
|
||||
/datum/controller/subsystem/radio/proc/frequency_span_class(var/frequency)
|
||||
// Antags!
|
||||
if(frequency in ANTAG_FREQS)
|
||||
return "syndradio"
|
||||
// centcomm channels (deathsquid and ert)
|
||||
if(frequency in CENT_FREQS)
|
||||
return "centradio"
|
||||
// This switch used to be a shit tonne of if statements. I am gonna find who made this and give them a kind talking to
|
||||
switch(frequency)
|
||||
if(COMM_FREQ)
|
||||
return "comradio"
|
||||
if(AI_FREQ)
|
||||
return "airadio"
|
||||
if(SEC_FREQ)
|
||||
return "secradio"
|
||||
if(ENG_FREQ)
|
||||
return "engradio"
|
||||
if(SCI_FREQ)
|
||||
return "sciradio"
|
||||
if(MED_FREQ)
|
||||
return "medradio"
|
||||
if(SUP_FREQ)
|
||||
return "supradio"
|
||||
if(SRV_FREQ)
|
||||
return "srvradio"
|
||||
|
||||
// If the above switch somehow failed. And it needs the SSradio. part otherwise it fails to compile
|
||||
if(frequency in DEPT_FREQS)
|
||||
return "deptradio"
|
||||
|
||||
// If its none of the others
|
||||
return "radio"
|
||||
|
||||
|
||||
/datum/controller/subsystem/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
frequency.add_listener(device, filter)
|
||||
return frequency
|
||||
|
||||
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
|
||||
var/f_text = num2text(old_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(frequency)
|
||||
frequency.remove_listener(device)
|
||||
|
||||
if(frequency.devices.len == 0)
|
||||
qdel(frequency)
|
||||
frequencies -= f_text
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/radio/proc/return_frequency(var/new_frequency as num)
|
||||
var/f_text = num2text(new_frequency)
|
||||
var/datum/radio_frequency/frequency = frequencies[f_text]
|
||||
|
||||
if(!frequency)
|
||||
frequency = new
|
||||
frequency.frequency = new_frequency
|
||||
frequencies[f_text] = frequency
|
||||
|
||||
return frequency
|
||||
|
||||
|
||||
// ALL THE SHIT BELOW THIS LINE ISNT PART OF THE SUBSYSTEM AND REALLY NEEDS ITS OWN FILE
|
||||
|
||||
@@ -311,4 +311,4 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
QDEL_LIST(remove_images)
|
||||
|
||||
#undef CALL_SHUTTLE_REASON_LENGTH
|
||||
#undef CALL_SHUTTLE_REASON_LENGTH
|
||||
|
||||
@@ -39,4 +39,4 @@ SUBSYSTEM_DEF(sun)
|
||||
if(!SC.powernet)
|
||||
solars.Remove(SC)
|
||||
continue
|
||||
SC.update()
|
||||
SC.update()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -518,4 +518,4 @@ SUBSYSTEM_DEF(timer)
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
#undef TIMER_MAX
|
||||
#undef TIMER_ID_MAX
|
||||
#undef TIMER_ID_MAX
|
||||
|
||||
+401
-401
@@ -1,401 +1,401 @@
|
||||
SUBSYSTEM_DEF(vote)
|
||||
name = "Vote"
|
||||
wait = 10
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/initiator = null
|
||||
var/started_time = null
|
||||
var/time_remaining = 0
|
||||
var/mode = null
|
||||
var/question = null
|
||||
var/list/choices = list()
|
||||
var/list/voted = list()
|
||||
var/list/voting = list()
|
||||
var/list/current_votes = list()
|
||||
var/list/round_voters = list()
|
||||
var/auto_muted = 0
|
||||
|
||||
/datum/controller/subsystem/vote/fire()
|
||||
if(mode)
|
||||
// No more change mode votes after the game has started.
|
||||
if(mode == "gamemode" && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
to_chat(world, "<b>Voting aborted due to game start.</b>")
|
||||
reset()
|
||||
return
|
||||
|
||||
// Calculate how much time is remaining by comparing current time, to time of vote start,
|
||||
// plus vote duration
|
||||
time_remaining = round((started_time + config.vote_period - world.time)/10)
|
||||
|
||||
if(time_remaining < 0)
|
||||
result()
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(null,"window=vote")
|
||||
reset()
|
||||
else
|
||||
for(var/client/C in voting)
|
||||
update_panel(C)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/vote/proc/autotransfer()
|
||||
initiate_vote("crew_transfer","the server")
|
||||
|
||||
/datum/controller/subsystem/vote/proc/reset()
|
||||
initiator = null
|
||||
time_remaining = 0
|
||||
mode = null
|
||||
question = null
|
||||
choices.Cut()
|
||||
voted.Cut()
|
||||
voting.Cut()
|
||||
current_votes.Cut()
|
||||
|
||||
if(auto_muted && !config.ooc_allowed && !(config.auto_toggle_ooc_during_round && SSticker.current_state == GAME_STATE_PLAYING))
|
||||
auto_muted = 0
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically enabled due to vote end.</b>")
|
||||
log_admin("OOC was toggled automatically due to vote end.")
|
||||
message_admins("OOC has been toggled on automatically.")
|
||||
|
||||
|
||||
/datum/controller/subsystem/vote/proc/get_result()
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
var/list/sorted_choices = list()
|
||||
var/sorted_highest
|
||||
var/sorted_votes = -1
|
||||
//get the highest number of votes, while also sorting the list
|
||||
while(choices.len)
|
||||
// This is a very inefficient sorting method, but that's okay
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
if(sorted_votes < votes)
|
||||
sorted_highest = option
|
||||
sorted_votes = votes
|
||||
if(votes > greatest_votes)
|
||||
greatest_votes = votes
|
||||
sorted_votes = -1
|
||||
total_votes += choices[sorted_highest]
|
||||
sorted_choices[sorted_highest] = choices[sorted_highest] || 0
|
||||
choices -= sorted_highest
|
||||
choices = sorted_choices
|
||||
//default-vote for everyone who didn't vote
|
||||
if(!config.vote_no_default && choices.len)
|
||||
var/non_voters = (GLOB.clients.len - total_votes)
|
||||
if(non_voters > 0)
|
||||
if(mode == "restart")
|
||||
choices["Continue Playing"] += non_voters
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == "gamemode")
|
||||
if(master_mode in choices)
|
||||
choices[master_mode] += non_voters
|
||||
if(choices[master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[master_mode]
|
||||
else if(mode == "crew_transfer")
|
||||
var/factor = 0.5
|
||||
switch(world.time / (10 * 60)) // minutes
|
||||
if(0 to 60)
|
||||
factor = 0.5
|
||||
if(61 to 120)
|
||||
factor = 0.8
|
||||
if(121 to 240)
|
||||
factor = 1
|
||||
if(241 to 300)
|
||||
factor = 1.2
|
||||
else
|
||||
factor = 1.4
|
||||
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
|
||||
to_chat(world, "<font color='purple'>Crew Transfer Factor: [factor]</font>")
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
|
||||
|
||||
|
||||
//get all options with that many votes and return them in a list
|
||||
. = list()
|
||||
if(greatest_votes)
|
||||
for(var/option in choices)
|
||||
if(choices[option] == greatest_votes)
|
||||
. += option
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/announce_result()
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
if(winners.len > 0)
|
||||
if(winners.len > 1)
|
||||
if(mode != "gamemode" || SSticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
|
||||
text = "<b>Vote Tied Between:</b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t[option]\n"
|
||||
. = pick(winners)
|
||||
|
||||
for(var/key in current_votes)
|
||||
if(choices[current_votes[key]] == .)
|
||||
round_voters += key // Keep track of who voted for the winning round.
|
||||
if(mode == "gamemode" && (. == "extended" || SSticker.hide_mode == 0)) // Announce Extended gamemode, but not other gamemodes
|
||||
text += "<b>Vote Result: [.] ([choices[.]] vote\s)</b>"
|
||||
else
|
||||
if(mode == "custom")
|
||||
// Completely replace text to show all results in custom votes
|
||||
text = "<b><span style='text-decoration: underline;'>[question]</span></b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t<b>[option]: [choices[option]] vote\s</b>\n"
|
||||
for(var/option in (choices-winners))
|
||||
text += "\t[option]: [choices[option]] vote\s\n"
|
||||
else if(mode != "gamemode")
|
||||
text += "<b>Vote Result: [.] ([choices[.]] vote\s)</b>"
|
||||
else
|
||||
text += "<b>The vote has ended.</b>" // What will be shown if it is a gamemode vote that isn't extended
|
||||
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
log_vote(text)
|
||||
to_chat(world, "<font color='purple'>[text]</font>")
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/result()
|
||||
. = announce_result()
|
||||
var/restart = 0
|
||||
if(.)
|
||||
switch(mode)
|
||||
if("restart")
|
||||
if(. == "Restart Round")
|
||||
restart = 1
|
||||
if("gamemode")
|
||||
if(master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(SSticker && SSticker.mode)
|
||||
restart = 1
|
||||
else
|
||||
master_mode = .
|
||||
if(!going)
|
||||
going = 1
|
||||
to_chat(world, "<font color='red'><b>The round will start soon.</b></font>")
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
|
||||
|
||||
if(restart)
|
||||
world.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/submit_vote(var/ckey, var/vote)
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
if(vote && 1<=vote && vote<=choices.len)
|
||||
voted += usr.ckey
|
||||
choices[choices[vote]]++ //check this
|
||||
current_votes[ckey] = vote
|
||||
return vote
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(var/vote_type, var/initiator_key)
|
||||
if(!mode)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
|
||||
reset()
|
||||
switch(vote_type)
|
||||
if("restart")
|
||||
choices.Add("Restart Round","Continue Playing")
|
||||
if("gamemode")
|
||||
if(SSticker.current_state >= 2)
|
||||
return 0
|
||||
choices.Add(config.votable_modes)
|
||||
if("crew_transfer")
|
||||
if(check_rights(R_ADMIN|R_MOD))
|
||||
if(SSticker.current_state <= 2)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
else
|
||||
if(SSticker.current_state <= 2)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("custom")
|
||||
question = html_encode(input(usr,"What is the vote for?") as text|null)
|
||||
if(!question) return 0
|
||||
for(var/i=1,i<=10,i++)
|
||||
var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null))
|
||||
if(!option || mode || !usr.client) break
|
||||
choices.Add(option)
|
||||
else
|
||||
return 0
|
||||
mode = vote_type
|
||||
initiator = initiator_key
|
||||
started_time = world.time
|
||||
var/text = "[capitalize(mode)] vote started by [initiator]."
|
||||
if(mode == "custom")
|
||||
text += "\n[question]"
|
||||
if(usr)
|
||||
log_admin("[capitalize(mode)] ([question]) vote started by [key_name(usr)].")
|
||||
else if(usr)
|
||||
log_admin("[capitalize(mode)] vote started by [key_name(usr)].")
|
||||
|
||||
log_vote(text)
|
||||
to_chat(world, {"<font color='purple'><b>[text]</b>
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [config.vote_period/10] seconds to vote.</font>"})
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if("gamemode")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if("custom")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if(mode == "gamemode" && going)
|
||||
going = 0
|
||||
to_chat(world, "<font color='red'><b>Round start has been delayed.</b></font>")
|
||||
if(mode == "crew_transfer" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to a crew transfer vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to crew_transfer vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
if(mode == "gamemode" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to the gamemode vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to gamemode vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
if(mode == "custom" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to a custom vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to custom vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
|
||||
time_remaining = round(config.vote_period/10)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/browse_to(var/client/C)
|
||||
if(!C)
|
||||
return
|
||||
var/admin = check_rights(R_ADMIN, 0, user = C.mob)
|
||||
voting |= C
|
||||
|
||||
var/dat = {"<script>
|
||||
function update_vote_div(new_content) {
|
||||
var votediv = document.getElementById("vote_div");
|
||||
if(votediv) {
|
||||
votediv.innerHTML = new_content;
|
||||
}
|
||||
}
|
||||
</script>"}
|
||||
if(mode)
|
||||
dat += "<div id='vote_div'>[vote_html(C)]</div><hr>"
|
||||
if(admin)
|
||||
dat += "(<a href='?src=[UID()];vote=cancel'>Cancel Vote</a>) "
|
||||
else
|
||||
dat += "<div id='vote_div'><h2>Start a vote:</h2><hr><ul><li>"
|
||||
//restart
|
||||
if(admin || config.allow_vote_restart)
|
||||
dat += "<a href='?src=[UID()];vote=restart'>Restart</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
dat += "</li><li>"
|
||||
if(admin || config.allow_vote_restart)
|
||||
dat += "<a href='?src=[UID()];vote=crew_transfer'>Crew Transfer</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Crew Transfer (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
|
||||
dat += "</li><li>"
|
||||
//gamemode
|
||||
if(admin || config.allow_vote_mode)
|
||||
dat += "<a href='?src=[UID()];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
dat += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
|
||||
dat += "</li>"
|
||||
//custom
|
||||
if(admin)
|
||||
dat += "<li><a href='?src=[UID()];vote=custom'>Custom</a></li>"
|
||||
dat += "</ul></div><hr>"
|
||||
var/datum/browser/popup = new(C.mob, "vote", "Voting Panel", nref=src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/controller/subsystem/vote/proc/update_panel(var/client/C)
|
||||
C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div")
|
||||
|
||||
/datum/controller/subsystem/vote/proc/vote_html(var/client/C)
|
||||
. = ""
|
||||
if(question)
|
||||
. += "<h2>Vote: '[question]'</h2>"
|
||||
else
|
||||
. += "<h2>Vote: [capitalize(mode)]</h2>"
|
||||
. += "Time Left: [time_remaining] s<hr><ul>"
|
||||
for(var/i = 1, i <= choices.len, i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(current_votes[C.ckey] == i)
|
||||
. += "<li><b><a href='?src=[UID()];vote=[i]'>[choices[i]] ([votes] vote\s)</a></b></li>"
|
||||
else
|
||||
. += "<li><a href='?src=[UID()];vote=[i]'>[choices[i]] ([votes] vote\s)</a></li>"
|
||||
|
||||
. += "</ul>"
|
||||
|
||||
|
||||
/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc)
|
||||
if(!usr || !usr.client)
|
||||
return //not necessary but meh...just in-case somebody does something stupid
|
||||
var/admin = check_rights(R_ADMIN,0)
|
||||
if(href_list["close"])
|
||||
voting -= usr.client
|
||||
return
|
||||
switch(href_list["vote"])
|
||||
if("open")
|
||||
// vote proc will automatically get called after this switch ends
|
||||
if("cancel")
|
||||
if(admin && mode)
|
||||
var/votedesc = capitalize(mode)
|
||||
if(mode == "custom")
|
||||
votedesc += " ([question])"
|
||||
admin_log_and_message_admins("cancelled the running [votedesc] vote.")
|
||||
reset()
|
||||
if("toggle_restart")
|
||||
if(admin)
|
||||
config.allow_vote_restart = !config.allow_vote_restart
|
||||
if("toggle_gamemode")
|
||||
if(admin)
|
||||
config.allow_vote_mode = !config.allow_vote_mode
|
||||
if("restart")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("restart",usr.key)
|
||||
if("gamemode")
|
||||
if(config.allow_vote_mode || admin)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("crew_transfer")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("crew_transfer",usr.key)
|
||||
if("custom")
|
||||
if(admin)
|
||||
initiate_vote("custom",usr.key)
|
||||
else
|
||||
submit_vote(usr.ckey, round(text2num(href_list["vote"])))
|
||||
update_panel(usr.client)
|
||||
return
|
||||
usr.vote()
|
||||
|
||||
|
||||
/mob/verb/vote()
|
||||
set category = "OOC"
|
||||
set name = "Vote"
|
||||
|
||||
if(SSvote)
|
||||
SSvote.browse_to(client)
|
||||
SUBSYSTEM_DEF(vote)
|
||||
name = "Vote"
|
||||
wait = 10
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/initiator = null
|
||||
var/started_time = null
|
||||
var/time_remaining = 0
|
||||
var/mode = null
|
||||
var/question = null
|
||||
var/list/choices = list()
|
||||
var/list/voted = list()
|
||||
var/list/voting = list()
|
||||
var/list/current_votes = list()
|
||||
var/list/round_voters = list()
|
||||
var/auto_muted = 0
|
||||
|
||||
/datum/controller/subsystem/vote/fire()
|
||||
if(mode)
|
||||
// No more change mode votes after the game has started.
|
||||
if(mode == "gamemode" && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
to_chat(world, "<b>Voting aborted due to game start.</b>")
|
||||
reset()
|
||||
return
|
||||
|
||||
// Calculate how much time is remaining by comparing current time, to time of vote start,
|
||||
// plus vote duration
|
||||
time_remaining = round((started_time + config.vote_period - world.time)/10)
|
||||
|
||||
if(time_remaining < 0)
|
||||
result()
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(null,"window=vote")
|
||||
reset()
|
||||
else
|
||||
for(var/client/C in voting)
|
||||
update_panel(C)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/vote/proc/autotransfer()
|
||||
initiate_vote("crew_transfer","the server")
|
||||
|
||||
/datum/controller/subsystem/vote/proc/reset()
|
||||
initiator = null
|
||||
time_remaining = 0
|
||||
mode = null
|
||||
question = null
|
||||
choices.Cut()
|
||||
voted.Cut()
|
||||
voting.Cut()
|
||||
current_votes.Cut()
|
||||
|
||||
if(auto_muted && !config.ooc_allowed && !(config.auto_toggle_ooc_during_round && SSticker.current_state == GAME_STATE_PLAYING))
|
||||
auto_muted = 0
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically enabled due to vote end.</b>")
|
||||
log_admin("OOC was toggled automatically due to vote end.")
|
||||
message_admins("OOC has been toggled on automatically.")
|
||||
|
||||
|
||||
/datum/controller/subsystem/vote/proc/get_result()
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
var/list/sorted_choices = list()
|
||||
var/sorted_highest
|
||||
var/sorted_votes = -1
|
||||
//get the highest number of votes, while also sorting the list
|
||||
while(choices.len)
|
||||
// This is a very inefficient sorting method, but that's okay
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
if(sorted_votes < votes)
|
||||
sorted_highest = option
|
||||
sorted_votes = votes
|
||||
if(votes > greatest_votes)
|
||||
greatest_votes = votes
|
||||
sorted_votes = -1
|
||||
total_votes += choices[sorted_highest]
|
||||
sorted_choices[sorted_highest] = choices[sorted_highest] || 0
|
||||
choices -= sorted_highest
|
||||
choices = sorted_choices
|
||||
//default-vote for everyone who didn't vote
|
||||
if(!config.vote_no_default && choices.len)
|
||||
var/non_voters = (GLOB.clients.len - total_votes)
|
||||
if(non_voters > 0)
|
||||
if(mode == "restart")
|
||||
choices["Continue Playing"] += non_voters
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == "gamemode")
|
||||
if(master_mode in choices)
|
||||
choices[master_mode] += non_voters
|
||||
if(choices[master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[master_mode]
|
||||
else if(mode == "crew_transfer")
|
||||
var/factor = 0.5
|
||||
switch(world.time / (10 * 60)) // minutes
|
||||
if(0 to 60)
|
||||
factor = 0.5
|
||||
if(61 to 120)
|
||||
factor = 0.8
|
||||
if(121 to 240)
|
||||
factor = 1
|
||||
if(241 to 300)
|
||||
factor = 1.2
|
||||
else
|
||||
factor = 1.4
|
||||
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
|
||||
to_chat(world, "<font color='purple'>Crew Transfer Factor: [factor]</font>")
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
|
||||
|
||||
|
||||
//get all options with that many votes and return them in a list
|
||||
. = list()
|
||||
if(greatest_votes)
|
||||
for(var/option in choices)
|
||||
if(choices[option] == greatest_votes)
|
||||
. += option
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/announce_result()
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
if(winners.len > 0)
|
||||
if(winners.len > 1)
|
||||
if(mode != "gamemode" || SSticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
|
||||
text = "<b>Vote Tied Between:</b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t[option]\n"
|
||||
. = pick(winners)
|
||||
|
||||
for(var/key in current_votes)
|
||||
if(choices[current_votes[key]] == .)
|
||||
round_voters += key // Keep track of who voted for the winning round.
|
||||
if(mode == "gamemode" && (. == "extended" || SSticker.hide_mode == 0)) // Announce Extended gamemode, but not other gamemodes
|
||||
text += "<b>Vote Result: [.] ([choices[.]] vote\s)</b>"
|
||||
else
|
||||
if(mode == "custom")
|
||||
// Completely replace text to show all results in custom votes
|
||||
text = "<b><span style='text-decoration: underline;'>[question]</span></b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t<b>[option]: [choices[option]] vote\s</b>\n"
|
||||
for(var/option in (choices-winners))
|
||||
text += "\t[option]: [choices[option]] vote\s\n"
|
||||
else if(mode != "gamemode")
|
||||
text += "<b>Vote Result: [.] ([choices[.]] vote\s)</b>"
|
||||
else
|
||||
text += "<b>The vote has ended.</b>" // What will be shown if it is a gamemode vote that isn't extended
|
||||
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
log_vote(text)
|
||||
to_chat(world, "<font color='purple'>[text]</font>")
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/result()
|
||||
. = announce_result()
|
||||
var/restart = 0
|
||||
if(.)
|
||||
switch(mode)
|
||||
if("restart")
|
||||
if(. == "Restart Round")
|
||||
restart = 1
|
||||
if("gamemode")
|
||||
if(master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(SSticker && SSticker.mode)
|
||||
restart = 1
|
||||
else
|
||||
master_mode = .
|
||||
if(!going)
|
||||
going = 1
|
||||
to_chat(world, "<font color='red'><b>The round will start soon.</b></font>")
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
|
||||
|
||||
if(restart)
|
||||
world.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/submit_vote(var/ckey, var/vote)
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
if(vote && 1<=vote && vote<=choices.len)
|
||||
voted += usr.ckey
|
||||
choices[choices[vote]]++ //check this
|
||||
current_votes[ckey] = vote
|
||||
return vote
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(var/vote_type, var/initiator_key)
|
||||
if(!mode)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
|
||||
reset()
|
||||
switch(vote_type)
|
||||
if("restart")
|
||||
choices.Add("Restart Round","Continue Playing")
|
||||
if("gamemode")
|
||||
if(SSticker.current_state >= 2)
|
||||
return 0
|
||||
choices.Add(config.votable_modes)
|
||||
if("crew_transfer")
|
||||
if(check_rights(R_ADMIN|R_MOD))
|
||||
if(SSticker.current_state <= 2)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
else
|
||||
if(SSticker.current_state <= 2)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("custom")
|
||||
question = html_encode(input(usr,"What is the vote for?") as text|null)
|
||||
if(!question) return 0
|
||||
for(var/i=1,i<=10,i++)
|
||||
var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null))
|
||||
if(!option || mode || !usr.client) break
|
||||
choices.Add(option)
|
||||
else
|
||||
return 0
|
||||
mode = vote_type
|
||||
initiator = initiator_key
|
||||
started_time = world.time
|
||||
var/text = "[capitalize(mode)] vote started by [initiator]."
|
||||
if(mode == "custom")
|
||||
text += "\n[question]"
|
||||
if(usr)
|
||||
log_admin("[capitalize(mode)] ([question]) vote started by [key_name(usr)].")
|
||||
else if(usr)
|
||||
log_admin("[capitalize(mode)] vote started by [key_name(usr)].")
|
||||
|
||||
log_vote(text)
|
||||
to_chat(world, {"<font color='purple'><b>[text]</b>
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [config.vote_period/10] seconds to vote.</font>"})
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if("gamemode")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if("custom")
|
||||
world << sound('sound/ambience/alarm4.ogg')
|
||||
if(mode == "gamemode" && going)
|
||||
going = 0
|
||||
to_chat(world, "<font color='red'><b>Round start has been delayed.</b></font>")
|
||||
if(mode == "crew_transfer" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to a crew transfer vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to crew_transfer vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
if(mode == "gamemode" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to the gamemode vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to gamemode vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
if(mode == "custom" && config.ooc_allowed)
|
||||
auto_muted = 1
|
||||
config.ooc_allowed = !( config.ooc_allowed )
|
||||
to_chat(world, "<b>The OOC channel has been automatically disabled due to a custom vote.</b>")
|
||||
log_admin("OOC was toggled automatically due to custom vote.")
|
||||
message_admins("OOC has been toggled off automatically.")
|
||||
|
||||
time_remaining = round(config.vote_period/10)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/browse_to(var/client/C)
|
||||
if(!C)
|
||||
return
|
||||
var/admin = check_rights(R_ADMIN, 0, user = C.mob)
|
||||
voting |= C
|
||||
|
||||
var/dat = {"<script>
|
||||
function update_vote_div(new_content) {
|
||||
var votediv = document.getElementById("vote_div");
|
||||
if(votediv) {
|
||||
votediv.innerHTML = new_content;
|
||||
}
|
||||
}
|
||||
</script>"}
|
||||
if(mode)
|
||||
dat += "<div id='vote_div'>[vote_html(C)]</div><hr>"
|
||||
if(admin)
|
||||
dat += "(<a href='?src=[UID()];vote=cancel'>Cancel Vote</a>) "
|
||||
else
|
||||
dat += "<div id='vote_div'><h2>Start a vote:</h2><hr><ul><li>"
|
||||
//restart
|
||||
if(admin || config.allow_vote_restart)
|
||||
dat += "<a href='?src=[UID()];vote=restart'>Restart</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
dat += "</li><li>"
|
||||
if(admin || config.allow_vote_restart)
|
||||
dat += "<a href='?src=[UID()];vote=crew_transfer'>Crew Transfer</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Crew Transfer (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
|
||||
dat += "</li><li>"
|
||||
//gamemode
|
||||
if(admin || config.allow_vote_mode)
|
||||
dat += "<a href='?src=[UID()];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
dat += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
|
||||
dat += "</li>"
|
||||
//custom
|
||||
if(admin)
|
||||
dat += "<li><a href='?src=[UID()];vote=custom'>Custom</a></li>"
|
||||
dat += "</ul></div><hr>"
|
||||
var/datum/browser/popup = new(C.mob, "vote", "Voting Panel", nref=src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/controller/subsystem/vote/proc/update_panel(var/client/C)
|
||||
C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div")
|
||||
|
||||
/datum/controller/subsystem/vote/proc/vote_html(var/client/C)
|
||||
. = ""
|
||||
if(question)
|
||||
. += "<h2>Vote: '[question]'</h2>"
|
||||
else
|
||||
. += "<h2>Vote: [capitalize(mode)]</h2>"
|
||||
. += "Time Left: [time_remaining] s<hr><ul>"
|
||||
for(var/i = 1, i <= choices.len, i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(current_votes[C.ckey] == i)
|
||||
. += "<li><b><a href='?src=[UID()];vote=[i]'>[choices[i]] ([votes] vote\s)</a></b></li>"
|
||||
else
|
||||
. += "<li><a href='?src=[UID()];vote=[i]'>[choices[i]] ([votes] vote\s)</a></li>"
|
||||
|
||||
. += "</ul>"
|
||||
|
||||
|
||||
/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc)
|
||||
if(!usr || !usr.client)
|
||||
return //not necessary but meh...just in-case somebody does something stupid
|
||||
var/admin = check_rights(R_ADMIN,0)
|
||||
if(href_list["close"])
|
||||
voting -= usr.client
|
||||
return
|
||||
switch(href_list["vote"])
|
||||
if("open")
|
||||
// vote proc will automatically get called after this switch ends
|
||||
if("cancel")
|
||||
if(admin && mode)
|
||||
var/votedesc = capitalize(mode)
|
||||
if(mode == "custom")
|
||||
votedesc += " ([question])"
|
||||
admin_log_and_message_admins("cancelled the running [votedesc] vote.")
|
||||
reset()
|
||||
if("toggle_restart")
|
||||
if(admin)
|
||||
config.allow_vote_restart = !config.allow_vote_restart
|
||||
if("toggle_gamemode")
|
||||
if(admin)
|
||||
config.allow_vote_mode = !config.allow_vote_mode
|
||||
if("restart")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("restart",usr.key)
|
||||
if("gamemode")
|
||||
if(config.allow_vote_mode || admin)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("crew_transfer")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("crew_transfer",usr.key)
|
||||
if("custom")
|
||||
if(admin)
|
||||
initiate_vote("custom",usr.key)
|
||||
else
|
||||
submit_vote(usr.ckey, round(text2num(href_list["vote"])))
|
||||
update_panel(usr.client)
|
||||
return
|
||||
usr.vote()
|
||||
|
||||
|
||||
/mob/verb/vote()
|
||||
set category = "OOC"
|
||||
set name = "Vote"
|
||||
|
||||
if(SSvote)
|
||||
SSvote.browse_to(client)
|
||||
|
||||
@@ -80,4 +80,4 @@ SUBSYSTEM_DEF(weather)
|
||||
if((z in W.impacted_z_levels) && W.area_type == active_area.type)
|
||||
A = W
|
||||
break
|
||||
return A
|
||||
return A
|
||||
|
||||
+104
-104
@@ -1,104 +1,104 @@
|
||||
//TODO: rewrite and standardise all controller datums to the datum/controller type
|
||||
//TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done
|
||||
|
||||
|
||||
/client/proc/restart_controller(controller in list("Master", "Failsafe"))
|
||||
set category = "Debug"
|
||||
set name = "Restart Controller"
|
||||
set desc = "Restart one of the various periodic loop controllers for the game (be careful!)"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
switch(controller)
|
||||
if("Master")
|
||||
Recreate_MC()
|
||||
feedback_add_details("admin_verb","RMaster")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
feedback_add_details("admin_verb","RFailsafe")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
|
||||
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
|
||||
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
|
||||
if(!holder) return
|
||||
switch(controller)
|
||||
if("failsafe")
|
||||
debug_variables(Failsafe)
|
||||
feedback_add_details("admin_verb", "dfailsafe")
|
||||
if("Master")
|
||||
debug_variables(Master)
|
||||
feedback_add_details("admin_verb","Dsmc")
|
||||
if("Ticker")
|
||||
debug_variables(SSticker)
|
||||
feedback_add_details("admin_verb","DTicker")
|
||||
if("Air")
|
||||
debug_variables(SSair)
|
||||
feedback_add_details("admin_verb","DAir")
|
||||
if("Jobs")
|
||||
debug_variables(SSjobs)
|
||||
feedback_add_details("admin_verb","DJobs")
|
||||
if("Sun")
|
||||
debug_variables(SSsun)
|
||||
feedback_add_details("admin_verb","DSun")
|
||||
if("Radio")
|
||||
debug_variables(SSradio)
|
||||
feedback_add_details("admin_verb","DRadio")
|
||||
if("Configuration")
|
||||
debug_variables(config)
|
||||
feedback_add_details("admin_verb","DConf")
|
||||
if("pAI")
|
||||
debug_variables(paiController)
|
||||
feedback_add_details("admin_verb","DpAI")
|
||||
if("Cameras")
|
||||
debug_variables(cameranet)
|
||||
feedback_add_details("admin_verb","DCameras")
|
||||
if("Garbage")
|
||||
debug_variables(SSgarbage)
|
||||
feedback_add_details("admin_verb","DGarbage")
|
||||
if("Event")
|
||||
debug_variables(SSevents)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(SSalarms)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Nano")
|
||||
debug_variables(SSnanoui)
|
||||
feedback_add_details("admin_verb","DNano")
|
||||
if("Vote")
|
||||
debug_variables(SSvote)
|
||||
feedback_add_details("admin_verb","DVote")
|
||||
if("Fires")
|
||||
debug_variables(SSfires)
|
||||
feedback_add_details("admin_verb","DFires")
|
||||
if("Mob")
|
||||
debug_variables(SSmobs)
|
||||
feedback_add_details("admin_verb","DMob")
|
||||
if("NPC Pool")
|
||||
debug_variables(SSnpcpool)
|
||||
feedback_add_details("admin_verb","DNPCPool")
|
||||
if("Shuttle")
|
||||
debug_variables(SSshuttle)
|
||||
feedback_add_details("admin_verb","DShuttle")
|
||||
if("Timer")
|
||||
debug_variables(SStimer)
|
||||
feedback_add_details("admin_verb","DTimer")
|
||||
if("Weather")
|
||||
debug_variables(SSweather)
|
||||
feedback_add_details("admin_verb","DWeather")
|
||||
if("Space")
|
||||
debug_variables(space_manager)
|
||||
feedback_add_details("admin_verb","DSpace")
|
||||
if("Mob Hunt Server")
|
||||
debug_variables(SSmob_hunt)
|
||||
feedback_add_details("admin_verb","DMobHuntServer")
|
||||
if("Input")
|
||||
debug_variables(SSinput)
|
||||
feedback_add_details("admin_verb","DInput")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||
//TODO: rewrite and standardise all controller datums to the datum/controller type
|
||||
//TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done
|
||||
|
||||
|
||||
/client/proc/restart_controller(controller in list("Master", "Failsafe"))
|
||||
set category = "Debug"
|
||||
set name = "Restart Controller"
|
||||
set desc = "Restart one of the various periodic loop controllers for the game (be careful!)"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
switch(controller)
|
||||
if("Master")
|
||||
Recreate_MC()
|
||||
feedback_add_details("admin_verb","RMaster")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
feedback_add_details("admin_verb","RFailsafe")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
|
||||
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
|
||||
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
|
||||
if(!holder) return
|
||||
switch(controller)
|
||||
if("failsafe")
|
||||
debug_variables(Failsafe)
|
||||
feedback_add_details("admin_verb", "dfailsafe")
|
||||
if("Master")
|
||||
debug_variables(Master)
|
||||
feedback_add_details("admin_verb","Dsmc")
|
||||
if("Ticker")
|
||||
debug_variables(SSticker)
|
||||
feedback_add_details("admin_verb","DTicker")
|
||||
if("Air")
|
||||
debug_variables(SSair)
|
||||
feedback_add_details("admin_verb","DAir")
|
||||
if("Jobs")
|
||||
debug_variables(SSjobs)
|
||||
feedback_add_details("admin_verb","DJobs")
|
||||
if("Sun")
|
||||
debug_variables(SSsun)
|
||||
feedback_add_details("admin_verb","DSun")
|
||||
if("Radio")
|
||||
debug_variables(SSradio)
|
||||
feedback_add_details("admin_verb","DRadio")
|
||||
if("Configuration")
|
||||
debug_variables(config)
|
||||
feedback_add_details("admin_verb","DConf")
|
||||
if("pAI")
|
||||
debug_variables(paiController)
|
||||
feedback_add_details("admin_verb","DpAI")
|
||||
if("Cameras")
|
||||
debug_variables(cameranet)
|
||||
feedback_add_details("admin_verb","DCameras")
|
||||
if("Garbage")
|
||||
debug_variables(SSgarbage)
|
||||
feedback_add_details("admin_verb","DGarbage")
|
||||
if("Event")
|
||||
debug_variables(SSevents)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(SSalarms)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Nano")
|
||||
debug_variables(SSnanoui)
|
||||
feedback_add_details("admin_verb","DNano")
|
||||
if("Vote")
|
||||
debug_variables(SSvote)
|
||||
feedback_add_details("admin_verb","DVote")
|
||||
if("Fires")
|
||||
debug_variables(SSfires)
|
||||
feedback_add_details("admin_verb","DFires")
|
||||
if("Mob")
|
||||
debug_variables(SSmobs)
|
||||
feedback_add_details("admin_verb","DMob")
|
||||
if("NPC Pool")
|
||||
debug_variables(SSnpcpool)
|
||||
feedback_add_details("admin_verb","DNPCPool")
|
||||
if("Shuttle")
|
||||
debug_variables(SSshuttle)
|
||||
feedback_add_details("admin_verb","DShuttle")
|
||||
if("Timer")
|
||||
debug_variables(SStimer)
|
||||
feedback_add_details("admin_verb","DTimer")
|
||||
if("Weather")
|
||||
debug_variables(SSweather)
|
||||
feedback_add_details("admin_verb","DWeather")
|
||||
if("Space")
|
||||
debug_variables(space_manager)
|
||||
feedback_add_details("admin_verb","DSpace")
|
||||
if("Mob Hunt Server")
|
||||
debug_variables(SSmob_hunt)
|
||||
feedback_add_details("admin_verb","DMobHuntServer")
|
||||
if("Input")
|
||||
debug_variables(SSinput)
|
||||
feedback_add_details("admin_verb","DInput")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||
|
||||
Reference in New Issue
Block a user