mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Cleans Up WIP Event System + New Grid Check For It
Separates the 'count and assess everything' stuff to it's own datum, called the metric datum, which I plan to add on to in the future to make counting and metrics easier. Makes decision process a bit more weight-based, will probably continue tweaking later. Makes the admin debug UI have links to change settings easily. Adds replacement for grid check event, which works similar to the old one, but is now based on a physical machine in the game world, that Engineering can hack to make the event end faster, if so desired. Note that the machine is not mapped in, and won't be mapped in until the event system is ready for launch. Adds grid_check variables to SMESes and APCs to make them stop doing work without draining the battery. Grid checks in the new system are caused by a "power spike" which originates from the engine and will cause bad things, should no grid checker machine be connected to the power-net. These power spikes occur when the GM decides that a grid check is a good event to have. The grid checker can be built and deconstructed using the standard machine construction methods.
This commit is contained in:
82
code/modules/metric/activity.dm
Normal file
82
code/modules/metric/activity.dm
Normal file
@@ -0,0 +1,82 @@
|
||||
// This checks an individual player's activity level. People who have been afk for a few minutes aren't punished as much as those
|
||||
// who were afk for hours, as they're most likely gone for good.
|
||||
/datum/metric/proc/assess_player_activity(var/mob/M)
|
||||
. = 100
|
||||
if(!M)
|
||||
. = 0
|
||||
return
|
||||
|
||||
if(!M.mind || !M.client) // Logged out. They might come back but we can't do any meaningful assessments for now.
|
||||
. = 0
|
||||
return
|
||||
|
||||
var/afk = M.client.is_afk(1 MINUTE)
|
||||
if(afk) // Deduct points based on length of AFK-ness.
|
||||
switch(afk) // One minute is equal to 600, for reference.
|
||||
if(1 MINUTE to 10 MINUTES) // People gone for this emough of time hopefully will come back soon.
|
||||
. -= round( (afk / 200), 1)
|
||||
if(10 MINUTES to 30 MINUTES)
|
||||
. -= round( (afk / 150), 1)
|
||||
if(30 MINUTES to INFINITY) // They're probably not coming back if it's been 30 minutes.
|
||||
. -= 100
|
||||
. = max(. , 0) // No negative numbers, or else people could drag other, non-afk players down.
|
||||
|
||||
// This checks a whole department's collective activity.
|
||||
/datum/metric/proc/assess_department(var/department)
|
||||
if(!department)
|
||||
return
|
||||
var/departmental_activity = 0
|
||||
var/departmental_size = 0
|
||||
for(var/mob/M in player_list)
|
||||
if(guess_department(M) != department) // Ignore people outside the department we're assessing.
|
||||
continue
|
||||
departmental_activity += assess_player_activity(M)
|
||||
departmental_size++
|
||||
if(departmental_size)
|
||||
departmental_activity = departmental_activity / departmental_size // Average it out.
|
||||
return departmental_activity
|
||||
|
||||
/datum/metric/proc/assess_all_departments(var/cutoff_number = 3, var/list/department_blacklist = list())
|
||||
var/list/activity = list()
|
||||
for(var/department in departments)
|
||||
activity[department] = assess_department(department)
|
||||
log_debug("Assessing department [department]. They have activity of [activity[department]].")
|
||||
|
||||
var/list/most_active_departments = list() // List of winners.
|
||||
var/highest_activity = null // Department who is leading in activity, if one exists.
|
||||
var/highest_number = 0 // Activity score needed to beat to be the most active department.
|
||||
for(var/i = 1, i <= cutoff_number, i++)
|
||||
log_debug("Doing [i]\th round of counting.")
|
||||
for(var/department in activity)
|
||||
if(department in department_blacklist) // Blacklisted?
|
||||
continue
|
||||
if(activity[department] > highest_number && activity[department] > 0) // More active than the current highest department?
|
||||
highest_activity = department
|
||||
highest_number = activity[department]
|
||||
|
||||
if(highest_activity) // Someone's a winner.
|
||||
most_active_departments.Add(highest_activity) // Add to the list of most active.
|
||||
activity.Remove(highest_activity) // Remove them from the other list so they don't win more than once.
|
||||
log_debug("[highest_activity] has won the [i]\th round of activity counting.")
|
||||
highest_activity = null // Now reset for the next round.
|
||||
highest_number = 0
|
||||
//todo: finish
|
||||
return most_active_departments
|
||||
|
||||
/datum/metric/proc/assess_all_living_mobs() // Living refers to the type, not the stat variable.
|
||||
. = 0
|
||||
var/num = 0
|
||||
for(var/mob/living/L in player_list)
|
||||
. += assess_player_activity(L)
|
||||
num++
|
||||
if(num)
|
||||
. = round(. / num, 0.1)
|
||||
|
||||
/datum/metric/proc/assess_all_dead_mobs() // Ditto.
|
||||
. = 0
|
||||
var/num = 0
|
||||
for(var/mob/observer/dead/O in player_list)
|
||||
. += assess_player_activity(O)
|
||||
num++
|
||||
if(num)
|
||||
. = round(. / num, 0.1)
|
||||
72
code/modules/metric/department.dm
Normal file
72
code/modules/metric/department.dm
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
// This proc tries to find the department of an arbitrary mob.
|
||||
/datum/metric/proc/guess_department(var/mob/M)
|
||||
var/list/found_roles = list()
|
||||
. = ROLE_UNKNOWN
|
||||
|
||||
// Records are usually the most reliable way to get what job someone is.
|
||||
var/datum/data/record/R = find_general_record("name", M.real_name)
|
||||
if(R) // We found someone with a record.
|
||||
var/recorded_rank = R.fields["real_rank"]
|
||||
found_roles = role_name_to_department(recorded_rank)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN) // We found the correct department, so we can stop now.
|
||||
return
|
||||
|
||||
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
|
||||
// Let's check the mind.
|
||||
if(M.mind)
|
||||
found_roles = role_name_to_department(M.mind.assigned_role)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN)
|
||||
return
|
||||
|
||||
// At this point, they don't have a mind, or for some reason assigned_role didn't work.
|
||||
found_roles = role_name_to_department(M.job)
|
||||
. = found_roles[1]
|
||||
if(. != ROLE_UNKNOWN)
|
||||
return
|
||||
|
||||
return ROLE_UNKNOWN // Welp.
|
||||
|
||||
// Feed this proc the name of a job, and it will try to figure out what department they are apart of.
|
||||
// Note that this returns a list, as some jobs are in more than one department, like Command. The 'primary' department is the first
|
||||
// in the list, e.g. a HoS has Security as first, Command as second in the returned list.
|
||||
/datum/metric/proc/role_name_to_department(var/role_name)
|
||||
var/list/result = list()
|
||||
|
||||
if(role_name in security_positions)
|
||||
result += ROLE_SECURITY
|
||||
|
||||
if(role_name in engineering_positions)
|
||||
result += ROLE_ENGINEERING
|
||||
|
||||
if(role_name in medical_positions)
|
||||
result += ROLE_MEDICAL
|
||||
|
||||
if(role_name in science_positions)
|
||||
result += ROLE_RESEARCH
|
||||
|
||||
if(role_name in cargo_positions)
|
||||
result += ROLE_CARGO
|
||||
|
||||
if(role_name in civilian_positions)
|
||||
result += ROLE_CIVILIAN
|
||||
|
||||
if(role_name in nonhuman_positions)
|
||||
result += ROLE_SYNTHETIC
|
||||
|
||||
if(role_name in command_positions) // We do Command last, since we consider command to only be a primary department for hop/admin.
|
||||
result += ROLE_COMMAND
|
||||
|
||||
if(!result.len) // No department was found.
|
||||
result += ROLE_UNKNOWN
|
||||
return result
|
||||
|
||||
/datum/metric/proc/count_people_in_department(var/department)
|
||||
if(!department)
|
||||
return
|
||||
for(var/mob/M in player_list)
|
||||
if(guess_department(M) != department) // Ignore people outside the department we're counting.
|
||||
continue
|
||||
. += 1
|
||||
15
code/modules/metric/metric.dm
Normal file
15
code/modules/metric/metric.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
// This is a global datum used to retrieve certain information about the round, such as activity of a department or a specific
|
||||
// player.
|
||||
|
||||
/datum/metric
|
||||
var/departments = list(
|
||||
ROLE_COMMAND,
|
||||
ROLE_SECURITY,
|
||||
ROLE_ENGINEERING,
|
||||
ROLE_MEDICAL,
|
||||
ROLE_RESEARCH,
|
||||
ROLE_CARGO,
|
||||
ROLE_CIVILIAN,
|
||||
ROLE_SYNTHETIC
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user