Files
Bubberstation/code/controllers/subsystem/traitor.dm
vincentiusvin ef036eb869 Assorted Ordnance Code+Map Quality Pass and QoL (#67097)
Three main things I do:

Reinforce the remap that i have made with code changes, making the atmos control devices sane and easy to put if someone else stumbles upon this part of the code again. (a4aea1e - f16e620)

Splits the ordnance areas and renames them, kills ordnance misc and things that have nothing to do with ordnance (anymore?) moves them to exp_lab (useful stuff here) and aux_lab (fluff stuff here like laser range in delta or second circuit lab in tram). (0c99f9f- 3c82a88)

Adds a roundstart program disk containing nt frontier to the ordnance office table. Added a hint to file manager there too to help give players a nudge on how to publish papers. (fd747dc)

First one: Makes mapping these things not require varedit, nicer for other people that dont know how the atmos control stuffs works.

Second one: Misc lab has nothing to do with ordnance jesus christ. Also ord hallway is now irrelevant, our ordnance labs are very far from box now. Will probably make downstreams a bit angry for a while though since they might not be fully up to date on the ordnance maps.

Third one: Pretty much justified it in the about section.

Why is this not atomic: This touches all five maps and needs code backing, so I might as well combine them into one maintenance PR instead of giving my peers merge conflict three times.
2022-06-02 17:15:17 -06:00

136 lines
6.2 KiB
Plaintext

SUBSYSTEM_DEF(traitor)
name = "Traitor"
flags = SS_KEEP_TIMING
wait = 10 SECONDS
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
/// A list of all uplink items mapped by type
var/list/uplink_items_by_type = list()
/// A list of all uplink items
var/list/uplink_items = list()
/// File to load configurations from.
var/configuration_path = "config/traitor_objective.json"
/// Global configuration data that gets applied to each objective when it is created.
/// Basic objective format
/// '/datum/traitor_objective/path/to/objective': {
/// "global_progression_influence_intensity": 0
/// }
var/configuration_data = list()
/// The coefficient multiplied by the current_global_progression for new joining traitors to calculate their progression
var/newjoin_progression_coeff = 0.6
/// The current progression that all traitors should be at in the round
var/current_global_progression = 0
/// The amount of deviance from the current global progression before you start getting 2x the current scaling or no scaling at all
/// Also affects objectives, so -50% progress reduction or 50% progress boost.
var/progression_scaling_deviance = 20 MINUTES
/// The current uplink handlers being managed
var/list/datum/uplink_handler/uplink_handlers = list()
/// The current scaling per minute of progression. Has a maximum value of 1 MINUTES.
var/current_progression_scaling = 1 MINUTES
/// Used to handle the probability of getting an objective.
var/datum/traitor_category_handler/category_handler
/// The current debug handler for objectives. Used for debugging objectives
var/datum/traitor_objective_debug/traitor_debug_panel
/// Used by the debug menu, decides whether newly created objectives should generate progression and telecrystals. Do not modify for non-debug purposes.
var/generate_objectives = TRUE
/// Objectives that have been completed by type. Used for limiting objectives.
var/list/taken_objectives_by_type = list()
/// Contains 3 areas: 2 areas to scan in order to triangulate the third one which is the structural weakpoint itself
var/list/station_weakpoints = list()
/datum/controller/subsystem/traitor/Initialize(start_timeofday)
. = ..()
category_handler = new()
traitor_debug_panel = new(category_handler)
if(fexists(configuration_path))
var/list/data = json_decode(file2text(file(configuration_path)))
for(var/typepath in data)
var/actual_typepath = text2path(typepath)
if(!actual_typepath)
log_world("[configuration_path] has an invalid type ([typepath]) that doesn't exist in the codebase! Please correct or remove [typepath]")
configuration_data[actual_typepath] = data[typepath]
/// List of high-security areas that we pick required ones from
var/list/allowed_areas = typecacheof(list(/area/station/command,
/area/station/cargo/qm,
/area/station/comms,
/area/station/engineering,
/area/station/science,
/area/station/security,
))
var/list/blacklisted_areas = typecacheof(list(/area/station/engineering/hallway,
/area/station/engineering/lobby,
/area/station/engineering/storage,
/area/station/science/lobby,
/area/station/security/prison,
))
var/list/possible_areas = GLOB.the_station_areas.Copy()
for(var/area/possible_area as anything in possible_areas)
if(!is_type_in_typecache(possible_area, allowed_areas) || initial(possible_area.outdoors) || is_type_in_typecache(possible_area, blacklisted_areas))
possible_areas -= possible_area
for(var/i in 1 to 3)
station_weakpoints += pick_n_take(possible_areas)
/datum/controller/subsystem/traitor/fire(resumed)
var/player_count = length(GLOB.alive_player_list)
// Has a maximum of 1 minute, however the value can be lower if there are lower players than the ideal
// player count for a traitor to be threatening. Rounds to the nearest 10% of a minute to prevent weird
// values from appearing in the UI. Traitor scaling multiplier bypasses the limit and only multiplies the end value.
// from all of our calculations.
current_progression_scaling = max(min(
(player_count / CONFIG_GET(number/traitor_ideal_player_count)) * 1 MINUTES,
1 MINUTES
), 0.1 MINUTES) * CONFIG_GET(number/traitor_scaling_multiplier)
var/progression_scaling_delta = (wait / (1 MINUTES)) * current_progression_scaling
var/previous_global_progression = current_global_progression
current_global_progression += progression_scaling_delta
for(var/datum/uplink_handler/handler in uplink_handlers)
if(!handler.has_progression || QDELETED(handler))
uplink_handlers -= handler
var/deviance = (previous_global_progression - handler.progression_points) / progression_scaling_deviance
if(abs(deviance) < 0.01)
// If deviance is less than 1%, just set them to the current global progression
// Prevents problems with precision errors.
handler.progression_points = current_global_progression
else
var/amount_to_give = progression_scaling_delta + (progression_scaling_delta * deviance)
amount_to_give = clamp(amount_to_give, 0, progression_scaling_delta * 2)
handler.progression_points += amount_to_give
handler.update_objectives()
handler.on_update()
/datum/controller/subsystem/traitor/proc/register_uplink_handler(datum/uplink_handler/uplink_handler)
if(!uplink_handler.has_progression)
return
uplink_handlers |= uplink_handler
// An uplink handler can be registered multiple times if they get assigned to new uplinks, so
// override is set to TRUE here because it is intentional that they could get added multiple times.
RegisterSignal(uplink_handler, COMSIG_PARENT_QDELETING, .proc/uplink_handler_deleted, override = TRUE)
/datum/controller/subsystem/traitor/proc/uplink_handler_deleted(datum/uplink_handler/uplink_handler)
SIGNAL_HANDLER
uplink_handlers -= uplink_handler
/datum/controller/subsystem/traitor/proc/on_objective_taken(datum/traitor_objective/objective)
if(!istype(objective))
return
var/datum/traitor_objective/current_type = objective.type
while(current_type != /datum/traitor_objective)
if(!taken_objectives_by_type[current_type])
taken_objectives_by_type[current_type] = list(objective)
else
taken_objectives_by_type[current_type] += objective
current_type = type2parent(current_type)
/datum/controller/subsystem/traitor/proc/get_taken_count(datum/traitor_objective/objective_type)
return length(taken_objectives_by_type[objective_type])