diff --git a/SQL/mentor.sql b/SQL/mentor.sql index c5fb7f0d83..45d0829d88 100644 --- a/SQL/mentor.sql +++ b/SQL/mentor.sql @@ -5,10 +5,10 @@ CREATE TABLE `mentor_memo` ( `last_editor` varchar(32) DEFAULT NULL, `edits` text, PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `mentor` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/SQL/mentor_prefixed.sql b/SQL/mentor_prefixed.sql new file mode 100644 index 0000000000..81e76f333e --- /dev/null +++ b/SQL/mentor_prefixed.sql @@ -0,0 +1,14 @@ +CREATE TABLE `SS13_mentor_memo` ( + `ckey` varchar(32) NOT NULL, + `memotext` text NOT NULL, + `timestamp` datetime NOT NULL, + `last_editor` varchar(32) DEFAULT NULL, + `edits` text, + PRIMARY KEY (`ckey`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `SS13_mentor` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/code/__DEFINES/events.dm b/code/__DEFINES/events.dm index d39932e1a7..d189969b8e 100644 --- a/code/__DEFINES/events.dm +++ b/code/__DEFINES/events.dm @@ -7,3 +7,31 @@ #define EVENT_READY 1 #define EVENT_CANCELLED 2 #define EVENT_INTERRUPTED 3 + +///Events that mess with or create artificial intelligences, such as vending machines and the AI itself +#define EVENT_CATEGORY_AI "AI issues" +///Events that spawn anomalies, which might be the source of anomaly cores +#define EVENT_CATEGORY_ANOMALIES "Anomalies" +///Events pertaining cargo, messages incoming to the station and job slots +#define EVENT_CATEGORY_BUREAUCRATIC "Bureaucratic" +///Events that cause breakages and malfunctions that could be fixed by engineers +#define EVENT_CATEGORY_ENGINEERING "Engineering" +///Events that spawn creatures with simple desires, such as to hunt +#define EVENT_CATEGORY_ENTITIES "Entities" +///Events that should have no harmful effects, and might be useful to the crew +#define EVENT_CATEGORY_FRIENDLY "Friendly" +///Events that affect the body and mind +#define EVENT_CATEGORY_HEALTH "Health" +///Events reserved for special occassions +#define EVENT_CATEGORY_HOLIDAY "Holiday" +///Events with enemy groups with a more complex plan +#define EVENT_CATEGORY_INVASION "Invasion" +///Events that make a mess +#define EVENT_CATEGORY_JANITORIAL "Janitorial" +///Events that summon meteors and other debris, and stationwide waves of harmful space weather +#define EVENT_CATEGORY_SPACE "Space Threats" +///Events summoned by a wizard +#define EVENT_CATEGORY_WIZARD "Wizard" + +/// Return from admin setup to stop the event from triggering entirely. +#define ADMIN_CANCEL_EVENT "cancel event" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index c4252ad542..5b457dd9cc 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -9,6 +9,14 @@ * Misc */ +// Generic listoflist safe add and removal macros: +///If value is a list, wrap it in a list so it can be used with list add/remove operations +#define LIST_VALUE_WRAP_LISTS(value) (islist(value) ? list(value) : value) +///Add an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun +#define UNTYPED_LIST_ADD(list, item) (list += LIST_VALUE_WRAP_LISTS(item)) +///Remove an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun +#define UNTYPED_LIST_REMOVE(list, item) (list -= LIST_VALUE_WRAP_LISTS(item)) + #define LAZYINITLIST(L) if (!L) { L = list(); } #define UNSETEMPTY(L) if (L && !length(L)) L = null ///Like LAZYCOPY - copies an input list if the list has entries, If it doesn't the assigned list is nulled diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index a7947f5f07..78e1899f53 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -123,6 +123,6 @@ for(var/path in typesof(/obj/item/coin)) var/obj/item/coin/C = new path UNTIL(C.flags_1 & INITIALIZED_1) //we want to make sure the value is calculated and not null. - GLOB.coin_values[path] = C.value + GLOB.coin_values[path] = C.get_item_credit_value() qdel(C) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 3660770596..2dd13eb1ac 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -93,41 +93,6 @@ SUBSYSTEM_DEF(events) else if(. == EVENT_READY) E.runEvent(random = TRUE) -//allows a client to trigger an event -//aka Badmin Central -// > Not in modules/admin -// REEEEEEEEE -// Why the heck is this here! Took me so damn long to find! -/client/proc/forceEvent() - set name = "Trigger Event" - set category = "Admin.Events" - - if(!holder ||!check_rights(R_FUN)) - return - - holder.forceEvent() - -/datum/admins/proc/forceEvent() - var/dat = "" - var/normal = "" - var/magic = "" - var/holiday = "" - for(var/datum/round_event_control/E in SSevents.control) - dat = "
[E]" - if(E.holidayID) - holiday += dat - else if(E.wizardevent) - magic += dat - else - normal += dat - - dat = normal + "
" + magic + "
" + holiday - - var/datum/browser/popup = new(usr, "forceevent", "Force Random Event", 300, 750) - popup.set_content(dat) - popup.open() - - /* ////////////// // HOLIDAYS // diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 21b469190a..4fa6476176 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -31,7 +31,6 @@ var/jackpots = 0 var/paymode = HOLOCHIP //toggles between HOLOCHIP/COIN, defined above var/cointype = /obj/item/coin/iron //default cointype - var/list/coinvalues = list() var/list/reels = list(list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0) var/list/symbols = list(SEVEN = 1, "&" = 2, "@" = 2, "$" = 2, "?" = 2, "#" = 2, "!" = 2, "%" = 2) //if people are winning too much, multiply every number in this list by 2 and see if they are still winning too much. @@ -49,11 +48,6 @@ INVOKE_ASYNC(src, .proc/toggle_reel_spin, FALSE) - for(cointype in typesof(/obj/item/coin)) - var/obj/item/coin/C = new cointype - coinvalues["[cointype]"] = C.get_item_credit_value() - qdel(C) //Sigh - /obj/machinery/computer/slot_machine/Destroy() if(balance) give_payout(balance) @@ -336,7 +330,7 @@ if(throwit && target) H.throw_at(target, 3, 10) else - var/value = coinvalues["[cointype]"] + var/value = GLOB.coin_values[cointype] if(value <= 0) CRASH("Coin value of zero, refusing to payout in dispenser") while(amount >= value) diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm new file mode 100644 index 0000000000..4e4338d019 --- /dev/null +++ b/code/modules/admin/force_event.dm @@ -0,0 +1,97 @@ +///Allows an admin to force an event +/client/proc/forceEvent() + set name = "Trigger Event" + set category = "Admin.Events" + + if(!holder || !check_rights(R_FUN)) + return + + holder.forceEvent() + +///Opens up the Force Event Panel +/datum/admins/proc/forceEvent() + if(!check_rights(R_FUN)) + return + + var/datum/force_event/ui = new(usr) + ui.ui_interact(usr) + +/// Force Event Panel +/datum/force_event + +/datum/force_event/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ForceEvent") + ui.open() + +/datum/force_event/ui_state(mob/user) + return GLOB.fun_state + +/datum/force_event/ui_static_data(mob/user) + var/static/list/category_to_icons + if(!category_to_icons) + category_to_icons = list( + EVENT_CATEGORY_AI = "robot", + EVENT_CATEGORY_ANOMALIES = "cloud-bolt", + EVENT_CATEGORY_BUREAUCRATIC = "print", + EVENT_CATEGORY_ENGINEERING = "wrench", + EVENT_CATEGORY_ENTITIES = "ghost", + EVENT_CATEGORY_FRIENDLY = "face-smile", + EVENT_CATEGORY_HEALTH = "brain", + EVENT_CATEGORY_HOLIDAY = "calendar", + EVENT_CATEGORY_INVASION = "user-group", + EVENT_CATEGORY_JANITORIAL = "bath", + EVENT_CATEGORY_SPACE = "meteor", + EVENT_CATEGORY_WIZARD = "hat-wizard", + ) + var/list/data = list() + + var/list/categories_seen = list() + var/list/categories = list() + + var/list/events = list() + + for(var/datum/round_event_control/event_control as anything in SSevents.control) + //add category + if(!categories_seen[event_control.category]) + categories_seen[event_control.category] = TRUE + UNTYPED_LIST_ADD(categories, list( + "name" = event_control.category, + "icon" = category_to_icons[event_control.category], + )) + //add event, with one value matching up the category + UNTYPED_LIST_ADD(events, list( + "name" = event_control.name, + "description" = event_control.description, + "type" = event_control.type, + "category" = event_control.category, + )) + data["categories"] = categories + data["events"] = events + return data + +/datum/force_event/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) + return + if(!check_rights(R_FUN)) + return + switch(action) + if("forceevent") + var/announce_event = params["announce"] + var/string_path = params["type"] + if(!string_path) + return + var/event_to_run_type = text2path(string_path) + if(!event_to_run_type) + return + var/datum/round_event_control/event = locate(event_to_run_type) in SSevents.control + if(!event) + return + if(event.admin_setup(usr) == ADMIN_CANCEL_EVENT) + return + var/always_announce_chance = 100 + var/no_announce_chance = 0 + event.runEvent(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) + message_admins("[key_name_admin(usr)] has triggered an event. ([event.name])") + log_admin("[key_name(usr)] has triggered an event. ([event.name])") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c19145d2c0..e0fbd7ef6e 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -173,27 +173,6 @@ message_admins("[key_name_admin(usr)] tried to create a qareen. Unfortunately, there were no candidates available.") log_admin("[key_name(usr)] failed to create a qareen.") - else if(href_list["forceevent"]) - if(!check_rights(R_FUN)) - return - var/datum/round_event_control/E = locate(href_list["forceevent"]) in SSevents.control - if(E) - E.admin_setup(usr) - var/datum/round_event/event = E.runEvent() - if(event.announceWhen>0) - event.processing = FALSE - var/prompt = alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No", "Cancel") - switch(prompt) - if("Cancel") - event.kill() - return - if("No") - event.announceWhen = -1 - event.processing = TRUE - message_admins("[key_name_admin(usr)] has triggered an event. ([E.name])") - log_admin("[key_name(usr)] has triggered an event. ([E.name])") - return - else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"]) var/adminckey = href_list["dbsearchadmin"] var/playerckey = href_list["dbsearchckey"] @@ -2799,10 +2778,17 @@ if(query_get_mentor.NextRow()) to_chat(usr, "[ckey] is already a mentor.") return - var/datum/db_query/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')") + var/datum/db_query/query_add_mentor = SSdbcore.NewQuery( + "INSERT INTO [format_table_name("mentor")] (id, ckey) VALUES (:id, :ckey)", + list("id" = null, "ckey" = ckey) + ) if(!query_add_mentor.warn_execute()) return - var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');") + var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery({" + INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) + VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add mentor', :mentor_ckey, CONCAT('Admin removed: ', :mentor_ckey)) + "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "mentor_ckey" = ckey) + ) if(!query_add_admin_log.warn_execute()) return else diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index f4b1cf12c6..bef99a3d30 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -466,10 +466,10 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]") var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") - var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) + var/announce_ion_laws = (show_log == "Yes" ? 100 : 0) var/datum/round_event/ion_storm/add_law_only/ion = new() - ion.announceEvent = announce_ion_laws + ion.announce_chance = announce_ion_laws ion.ionMessage = input SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index 02289684f5..e3c084b161 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -583,13 +583,15 @@ // log_admin("[key_name(holder)] has Un-Fully Immersed everyone.") if(E) E.processing = FALSE - if(E.announceWhen>0) + if(E.announce_when>0) switch(alert(holder, "Would you like to alert the crew?", "Alert", "Yes", "No", "Cancel")) + if("Yes") + E.announce_chance = 100 if("Cancel") E.kill() return if("No") - E.announceWhen = -1 + E.announce_chance = 0 E.processing = TRUE if(holder) log_admin("[key_name(holder)] used secret [action]") diff --git a/code/modules/antagonists/disease/disease_event.dm b/code/modules/antagonists/disease/disease_event.dm index 385cee998b..f80af46eac 100644 --- a/code/modules/antagonists/disease/disease_event.dm +++ b/code/modules/antagonists/disease/disease_event.dm @@ -5,7 +5,8 @@ weight = 7 max_occurrences = 1 min_players = 5 - + category = EVENT_CATEGORY_HEALTH + description = "Spawns a sentient disease, who wants to infect as many people as possible." /datum/round_event/ghost_role/sentient_disease role_name = "sentient disease" diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm index fbee439dda..f3b1ebb4c5 100644 --- a/code/modules/antagonists/morph/morph.dm +++ b/code/modules/antagonists/morph/morph.dm @@ -220,6 +220,8 @@ typepath = /datum/round_event/ghost_role/morph weight = 0 //Admin only max_occurrences = 1 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a hungry shapeshifting blobby creature." /datum/round_event/ghost_role/morph minimum_required = 1 diff --git a/code/modules/antagonists/revenant/revenant_spawn_event.dm b/code/modules/antagonists/revenant/revenant_spawn_event.dm index cb534b6613..b188e0c79c 100644 --- a/code/modules/antagonists/revenant/revenant_spawn_event.dm +++ b/code/modules/antagonists/revenant/revenant_spawn_event.dm @@ -6,7 +6,8 @@ weight = 7 max_occurrences = 1 min_players = 5 - + category = EVENT_CATEGORY_ENTITIES + description = "Spawns an angry, soul sucking ghost." /datum/round_event/ghost_role/revenant var/ignore_mobcheck = FALSE diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm index cdb1b32aad..9b62de57bf 100644 --- a/code/modules/antagonists/slaughter/slaughterevent.dm +++ b/code/modules/antagonists/slaughter/slaughterevent.dm @@ -5,6 +5,8 @@ max_occurrences = 1 earliest_start = 1 HOURS min_players = 20 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a slaughter demon, to hunt by travelling through pools of blood." /datum/round_event_control/slaughter/canSpawnEvent() weight = initial(src.weight) diff --git a/code/modules/antagonists/swarmer/swarmer_event.dm b/code/modules/antagonists/swarmer/swarmer_event.dm index 3df7e6c0e9..e70d76812d 100644 --- a/code/modules/antagonists/swarmer/swarmer_event.dm +++ b/code/modules/antagonists/swarmer/swarmer_event.dm @@ -6,7 +6,8 @@ earliest_start = 30 MINUTES min_players = 35 dynamic_should_hijack = TRUE - + category = EVENT_CATEGORY_INVASION + description = "A robotic menace invades the station consuming everything for materials and reproducing." /datum/round_event/spawn_swarmer diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 3abe65a790..d8c7af788f 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -3,6 +3,8 @@ //this datum is used by the events controller to dictate how it selects events /datum/round_event_control var/name //The human-readable name of the event + var/category //The category of the event + var/description //The description of the event var/typepath //The typepath of the event datum /datum/round_event var/weight = 10 //The weight this event has in the random-selection process. @@ -38,6 +40,7 @@ min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1) /datum/round_event_control/wizard + category = EVENT_CATEGORY_WIZARD wizardevent = TRUE var/can_be_midround_wizard = TRUE @@ -107,13 +110,22 @@ log_admin_private("[key_name(usr)] cancelled event [name].") SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath) -/datum/round_event_control/proc/runEvent(random = FALSE) +/* +Runs the event +* Arguments: +* - random: shows if the event was triggered randomly, or by on purpose by an admin or an item +* - announce_chance_override: if the value is not null, overrides the announcement chance when an admin calls an event +*/ +/datum/round_event_control/proc/runEvent(random = FALSE, announce_chance_override = null, admin_forced = FALSE) var/datum/round_event/E = new typepath() E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) E.control = src SSblackbox.record_feedback("tally", "event_ran", 1, "[E]") occurrences++ + if(announce_chance_override != null) + E.announce_chance = announce_chance_override + testing("[time2text(world.time, "hh:mm:ss")] [E.type]") if(random) log_game("Random Event triggering: [name] ([typepath])") @@ -129,18 +141,29 @@ var/processing = TRUE var/datum/round_event_control/control - var/startWhen = 0 //When in the lifetime to call start(). - var/announceWhen = 0 //When in the lifetime to call announce(). Set an event's announceWhen to -1 if announcement should not be shown. - var/endWhen = 0 //When in the lifetime the event should end. + /// When in the lifetime to call start(). + /// This is in seconds - so 1 = ~2 seconds in. + var/start_when = 0 + /// When in the lifetime to call announce(). If you don't want it to announce use announce_chance, below. + /// This is in seconds - so 1 = ~2 seconds in. + var/announce_when = 0 + /// Probability of announcing, used in prob(), 0 to 100, default 100. Called in process, and for a second time in the ion storm event. + var/announce_chance = 100 + /// When in the lifetime the event should end. + /// This is in seconds - so 1 = ~2 seconds in. + var/end_when = 0 - var/activeFor = 0 //How long the event has existed. You don't need to change this. - var/current_players = 0 //Amount of of alive, non-AFK human players on server at the time of event start + /// How long the event has existed. You don't need to change this. + var/activeFor = 0 + /// Amount of of alive, non-AFK human players on server at the time of event start + var/current_players = 0 var/threat = 0 - var/fakeable = TRUE //Can be faked by fake news event. + /// Can be faked by fake news event. + var/fakeable = TRUE //Called first before processing. //Allows you to setup your event, such as randomly -//setting the startWhen and or announceWhen variables. +//setting the start_when and or announce_when variables. //Only called once. //EDIT: if there's anything you want to override within the new() call, it will not be overridden by the time this proc is called. //It will only have been overridden by the time we get to announce() start() tick() or end() (anything but setup basically). @@ -148,7 +171,7 @@ /datum/round_event/proc/setup() return -//Called when the tick is equal to the startWhen variable. +//Called when the tick is equal to the start_when variable. //Allows you to start before announcing or vice versa. //Only called once. /datum/round_event/proc/start() @@ -165,20 +188,20 @@ notify_ghosts("[control.name] has an object of interest: [atom_of_interest]!", source=atom_of_interest, action=NOTIFY_ORBIT, header="Something's Interesting!") return -//Called when the tick is equal to the announceWhen variable. +//Called when the tick is equal to the announce_when variable. //Allows you to announce before starting or vice versa. //Only called once. /datum/round_event/proc/announce(fake) return -//Called on or after the tick counter is equal to startWhen. +//Called on or after the tick counter is equal to start_when. //You can include code related to your event or add your own //time stamped events. //Called more than once. /datum/round_event/proc/tick() return -//Called on or after the tick is equal or more than endWhen +//Called on or after the tick is equal or more than end_when //You can include code related to the event ending. //Do not place spawn() in here, instead use tick() to check for //the activeFor variable. @@ -197,28 +220,28 @@ if(!processing) return - if(activeFor == startWhen) + if(activeFor == start_when) processing = FALSE start() processing = TRUE - if(activeFor == announceWhen) + if(activeFor == announce_when && prob(announce_chance)) processing = FALSE announce(FALSE) processing = TRUE - if(startWhen < activeFor && activeFor < endWhen) + if(start_when < activeFor && activeFor < end_when) processing = FALSE tick() processing = TRUE - if(activeFor == endWhen) + if(activeFor == end_when) processing = FALSE end() processing = TRUE // Everything is done, let's clean up. - if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen) + if(activeFor >= end_when && activeFor >= announce_when && activeFor >= start_when) processing = FALSE kill() diff --git a/code/modules/events/abductor.dm b/code/modules/events/abductor.dm index 9fe3a2a7a9..64c743d1a1 100755 --- a/code/modules/events/abductor.dm +++ b/code/modules/events/abductor.dm @@ -6,6 +6,8 @@ min_players = 30 earliest_start = 30 MINUTES dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "One or more abductor teams spawns, and they plan to experiment on the crew." /datum/round_event/ghost_role/abductor minimum_required = 2 diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index f7014df648..cf94253bbb 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -5,9 +5,11 @@ min_players = 25 max_occurrences = 1 dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "A xenomorph larva spawns on a random vent." /datum/round_event/ghost_role/alien_infestation - announceWhen = 400 + announce_when = 400 minimum_required = 1 role_name = "alien larva" @@ -19,7 +21,7 @@ /datum/round_event/ghost_role/alien_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) + announce_when = rand(announce_when, announce_when + 50) if(prob(50)) spawncount++ diff --git a/code/modules/events/anomaly.dm b/code/modules/events/anomaly.dm index ae0d5442ad..456a83958d 100644 --- a/code/modules/events/anomaly.dm +++ b/code/modules/events/anomaly.dm @@ -5,11 +5,13 @@ min_players = 1 max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun. weight = 15 + category = EVENT_CATEGORY_ANOMALIES + description = "This anomaly shocks and explodes. This is the base type." /datum/round_event/anomaly var/area/impact_area var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux - announceWhen = 1 + announce_when = 1 /datum/round_event/anomaly/proc/findEventArea() diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index fd64b20244..f058f37da4 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -4,10 +4,11 @@ max_occurrences = 1 weight = 5 + description = "This anomaly randomly teleports all items and mobs in a large area." /datum/round_event/anomaly/anomaly_bluespace - startWhen = 3 - announceWhen = 10 + start_when = 3 + announce_when = 10 anomaly_path = /obj/effect/anomaly/bluespace /datum/round_event/anomaly/anomaly_bluespace/announce(fake) diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index 6368e70b94..d3b1e8ea7e 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -4,10 +4,11 @@ max_occurrences = 5 weight = 20 + description = "This anomaly shocks and explodes." /datum/round_event/anomaly/anomaly_flux - startWhen = 10 - announceWhen = 3 + start_when = 10 + announce_when = 3 anomaly_path = /obj/effect/anomaly/flux /datum/round_event/anomaly/anomaly_flux/announce(fake) diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm index c1b4ade5c0..232d2ddd35 100644 --- a/code/modules/events/anomaly_grav.dm +++ b/code/modules/events/anomaly_grav.dm @@ -4,11 +4,11 @@ max_occurrences = 5 weight = 20 - + description = "This anomaly throws things around." /datum/round_event/anomaly/anomaly_grav - startWhen = 3 - announceWhen = 20 + start_when = 3 + announce_when = 20 anomaly_path = /obj/effect/anomaly/grav /datum/round_event/anomaly/anomaly_grav/announce(fake) diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 83c1fa64cc..dee0330743 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -5,10 +5,11 @@ min_players = 5 max_occurrences = 5 weight = 20 + description = "This anomaly sets things on fire, and creates a pyroclastic slime." /datum/round_event/anomaly/anomaly_pyro - startWhen = 3 - announceWhen = 10 + start_when = 3 + announce_when = 10 anomaly_path = /obj/effect/anomaly/pyro /datum/round_event/anomaly/anomaly_pyro/announce(fake) diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm index 7228030616..43dcc0baf4 100644 --- a/code/modules/events/anomaly_vortex.dm +++ b/code/modules/events/anomaly_vortex.dm @@ -5,10 +5,11 @@ min_players = 20 max_occurrences = 2 weight = 5 + description = "This anomaly sucks in and detonates items." /datum/round_event/anomaly/anomaly_vortex - startWhen = 10 - announceWhen = 3 + start_when = 10 + announce_when = 3 anomaly_path = /obj/effect/anomaly/bhole /datum/round_event/anomaly/anomaly_vortex/announce(fake) diff --git a/code/modules/events/atmos_speed.dm b/code/modules/events/atmos_speed.dm index 17a02d3dd1..64e6e883cc 100644 --- a/code/modules/events/atmos_speed.dm +++ b/code/modules/events/atmos_speed.dm @@ -3,10 +3,12 @@ typepath = /datum/round_event/atmos_flux max_occurrences = 5 weight = 10 + category = EVENT_CATEGORY_ENGINEERING + description = "Modifies the speed of the SSair randomly, ends after one minute." /datum/round_event/atmos_flux - announceWhen = 1 - endWhen = 600 + announce_when = 1 + end_when = 600 var/original_speed /datum/round_event/atmos_flux/announce(fake) diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index 89a84d3494..63d7122cb8 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -4,6 +4,8 @@ max_occurrences = 1 weight = 4 earliest_start = 5 MINUTES + category = EVENT_CATEGORY_FRIENDLY + description = "A colourful display can be seen through select windows. And the kitchen." /datum/round_event_control/aurora_caelus/canSpawnEvent(players, gamemode) if(!CONFIG_GET(flag/starlight)) @@ -11,9 +13,9 @@ return ..() /datum/round_event/aurora_caelus - announceWhen = 1 - startWhen = 9 - endWhen = 50 + announce_when = 1 + start_when = 9 + end_when = 50 var/list/aurora_colors = list("#A2FF80", "#A2FF8B", "#A2FF96", "#A2FFA5", "#A2FFB6", "#A2FFC7", "#A2FFDE", "#A2FFEE") var/aurora_progress = 0 //this cycles from 1 to 8, slowly changing colors from gentle green to gentle blue diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index e31711661d..d28c5d6512 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -7,9 +7,11 @@ earliest_start = 60 MINUTES min_players = 35 dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a new blob overmind." /datum/round_event/ghost_role/blob - announceWhen = -1 + announce_when = -1 role_name = "blob overmind" fakeable = TRUE diff --git a/code/modules/events/brain_trauma.dm b/code/modules/events/brain_trauma.dm index 0529d102dc..85d69a1509 100644 --- a/code/modules/events/brain_trauma.dm +++ b/code/modules/events/brain_trauma.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/brain_trauma weight = 25 min_players = 5 + category = EVENT_CATEGORY_HEALTH + description = "A crewmember gains a random trauma." /datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode) if(!..()) return FALSE diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index 1b275af4fb..cab9daaa55 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -5,10 +5,12 @@ min_players = 15 max_occurrences = 1 + category = EVENT_CATEGORY_AI + description = "Vending machines will attack people until the Patient Zero is disabled." /datum/round_event/brand_intelligence - announceWhen = 21 - endWhen = 1000 //Ends when all vending machines are subverted anyway. + announce_when = 21 + end_when = 1000 //Ends when all vending machines are subverted anyway. var/list/obj/machinery/vending/vendingMachines = list() var/list/obj/machinery/vending/infectedMachines = list() var/obj/machinery/vending/originMachine diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 7246c9aedf..fc35df791b 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -3,9 +3,11 @@ typepath = /datum/round_event/bureaucratic_error max_occurrences = 1 weight = 5 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Randomly opens and closes job slots, along with changing the overflow role." /datum/round_event/bureaucratic_error - announceWhen = 1 + announce_when = 1 /datum/round_event/bureaucratic_error/announce(fake) priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert") diff --git a/code/modules/events/camerafailure.dm b/code/modules/events/camerafailure.dm index 8d7ef3204c..453b919c5b 100644 --- a/code/modules/events/camerafailure.dm +++ b/code/modules/events/camerafailure.dm @@ -4,6 +4,8 @@ weight = 100 max_occurrences = 20 alert_observers = FALSE + category = EVENT_CATEGORY_ENGINEERING + description = "Turns off a random amount of cameras." /datum/round_event/camera_failure fakeable = FALSE diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index f927a59ad6..bed6cf84ea 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -5,6 +5,8 @@ min_players = 2 earliest_start = 10 MINUTES max_occurrences = 6 + category = EVENT_CATEGORY_ENTITIES + description = "Summons a school of space carp." /datum/round_event_control/carp_migration/New() . = ..() @@ -14,12 +16,12 @@ earliest_start *= 0.5 /datum/round_event/carp_migration - announceWhen = 3 - startWhen = 50 + announce_when = 3 + start_when = 50 var/hasAnnounced = FALSE /datum/round_event/carp_migration/setup() - startWhen = rand(40, 60) + start_when = rand(40, 60) /datum/round_event/carp_migration/announce(fake) if(prob(50)) diff --git a/code/modules/events/cat_surgeon.dm b/code/modules/events/cat_surgeon.dm index 025d2d2325..254fdaecca 100644 --- a/code/modules/events/cat_surgeon.dm +++ b/code/modules/events/cat_surgeon.dm @@ -1,45 +1,47 @@ /datum/round_event_control/cat_surgeon - name = "Cat Surgeon" - typepath = /datum/round_event/cat_surgeon - max_occurrences = 1 - weight = 5 + name = "Cat Surgeon" + typepath = /datum/round_event/cat_surgeon + max_occurrences = 1 + weight = 5 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a crazy surgeon ready to perverse things with the crew." /datum/round_event/cat_surgeon/announce(fake) priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?", sender_override = "Nanotrasen Psych Ward", has_important_message = TRUE) /datum/round_event/cat_surgeon/start() - var/list/spawn_locs = list() - var/list/unsafe_spawn_locs = list() - for(var/X in GLOB.xeno_spawn) - if(!isfloorturf(X)) - unsafe_spawn_locs += X - continue - var/turf/open/floor/F = X - var/datum/gas_mixture/A = F.air - var/oxy_moles = A.get_moles(GAS_O2) - if((oxy_moles < 16 || oxy_moles > 50) || A.get_moles(GAS_PLASMA) || A.get_moles(GAS_CO2) >= 10) - unsafe_spawn_locs += F - continue - if((A.return_temperature() <= 270) || (A.return_temperature() >= 360)) - unsafe_spawn_locs += F - continue - var/pressure = A.return_pressure() - if((pressure <= 20) || (pressure >= 550)) - unsafe_spawn_locs += F - continue - spawn_locs += F + var/list/spawn_locs = list() + var/list/unsafe_spawn_locs = list() + for(var/X in GLOB.xeno_spawn) + if(!isfloorturf(X)) + unsafe_spawn_locs += X + continue + var/turf/open/floor/F = X + var/datum/gas_mixture/A = F.air + var/oxy_moles = A.get_moles(GAS_O2) + if((oxy_moles < 16 || oxy_moles > 50) || A.get_moles(GAS_PLASMA) || A.get_moles(GAS_CO2) >= 10) + unsafe_spawn_locs += F + continue + if((A.return_temperature() <= 270) || (A.return_temperature() >= 360)) + unsafe_spawn_locs += F + continue + var/pressure = A.return_pressure() + if((pressure <= 20) || (pressure >= 550)) + unsafe_spawn_locs += F + continue + spawn_locs += F - if(!spawn_locs.len) - spawn_locs += unsafe_spawn_locs + if(!spawn_locs.len) + spawn_locs += unsafe_spawn_locs - if(!spawn_locs.len) - message_admins("No valid spawn locations found, aborting...") - return MAP_ERROR + if(!spawn_locs.len) + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR - var/turf/T = get_turf(pick(spawn_locs)) - var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T) - playsound(S, 'sound/misc/catscream.ogg', 75, 1, -1) - message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]") - log_game("A cat surgeon has been spawned at [COORD(T)]") - return SUCCESSFUL_SPAWN + var/turf/T = get_turf(pick(spawn_locs)) + var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T) + playsound(S, 'sound/misc/catscream.ogg', 75, 1, -1) + message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]") + log_game("A cat surgeon has been spawned at [COORD(T)]") + return SUCCESSFUL_SPAWN diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index 0342ca4643..b47dad0c93 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -2,9 +2,11 @@ name = "Communications Blackout" typepath = /datum/round_event/communications_blackout weight = 30 + category = EVENT_CATEGORY_ENGINEERING + description = "Heavily emps all telecommunication machines, blocking all communication for a while." /datum/round_event/communications_blackout - announceWhen = 1 + announce_when = 1 /datum/round_event/communications_blackout/announce(fake) var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \ diff --git a/code/modules/events/devil.dm b/code/modules/events/devil.dm index 7d6e0bd441..3d6382b2a4 100644 --- a/code/modules/events/devil.dm +++ b/code/modules/events/devil.dm @@ -2,6 +2,8 @@ name = "Create Devil" typepath = /datum/round_event/ghost_role/devil max_occurrences = 0 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a devil, looking forward to makings deals with crewmembers to get their souls." /datum/round_event/ghost_role/devil var/success_spawn = 0 diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 517cf33b82..753349fdd6 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -4,9 +4,11 @@ max_occurrences = 1 min_players = 3 weight = 5 + category = EVENT_CATEGORY_HEALTH + description = "A classic or advanced disease will infect some crewmembers." /datum/round_event/disease_outbreak - announceWhen = 15 + announce_when = 15 var/virus_type @@ -24,7 +26,7 @@ priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7") /datum/round_event/disease_outbreak/setup() - announceWhen = rand(15, 30) + announce_when = rand(15, 30) /datum/round_event/disease_outbreak/start() diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index 941478d52a..6b0139c449 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -5,10 +5,12 @@ max_occurrences = 1000 earliest_start = 0 MINUTES alert_observers = FALSE + category = EVENT_CATEGORY_SPACE + description = "A single space dust is hurled at the station." /datum/round_event/space_dust - startWhen = 1 - endWhen = 2 + start_when = 1 + end_when = 2 fakeable = FALSE /datum/round_event/space_dust/start() @@ -21,11 +23,13 @@ max_occurrences = 1 min_players = 10 earliest_start = 20 MINUTES + category = EVENT_CATEGORY_SPACE + description = "The station is pelted by an extreme amount of sand for several minutes." /datum/round_event/sandstorm - startWhen = 1 - endWhen = 150 // ~5 min - announceWhen = 0 + start_when = 1 + end_when = 150 // ~5 min + announce_when = 0 fakeable = FALSE /datum/round_event/sandstorm/announce(fake) diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index b850b4db62..f04389b1a1 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -4,12 +4,13 @@ earliest_start = 10 MINUTES min_players = 5 weight = 40 - alert_observers = FALSE + category = EVENT_CATEGORY_ENGINEERING + description = "Destroys all lights in a large area." /datum/round_event/electrical_storm var/lightsoutAmount = 1 var/lightsoutRange = 25 - announceWhen = 1 + announce_when = 1 /datum/round_event/electrical_storm/announce(fake) if(prob(50)) diff --git a/code/modules/events/fake_virus.dm b/code/modules/events/fake_virus.dm index cebf1ed14b..ec69f9e2c9 100644 --- a/code/modules/events/fake_virus.dm +++ b/code/modules/events/fake_virus.dm @@ -2,6 +2,8 @@ name = "Fake Virus" typepath = /datum/round_event/fake_virus weight = 20 + category = EVENT_CATEGORY_HEALTH + description = "Some crewmembers suffer from temporary hypochondria." /datum/round_event/fake_virus/start() var/list/fake_virus_victims = list() diff --git a/code/modules/events/false_alarm.dm b/code/modules/events/false_alarm.dm index 5ac75cf087..95b7d1c3ce 100644 --- a/code/modules/events/false_alarm.dm +++ b/code/modules/events/false_alarm.dm @@ -4,7 +4,8 @@ weight = 20 max_occurrences = 5 var/forced_type //Admin abuse - + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Fakes an event announcement." /datum/round_event_control/falsealarm/admin_setup() if(!check_rights(R_FUN)) @@ -17,15 +18,15 @@ if(!initial(event.fakeable)) continue possible_types += E - + forced_type = input(usr, "Select the scare.","False event") as null|anything in possible_types /datum/round_event_control/falsealarm/canSpawnEvent(players_amt, gamemode) return ..() && length(gather_false_events()) /datum/round_event/falsealarm - announceWhen = 0 - endWhen = 1 + announce_when = 0 + end_when = 1 fakeable = FALSE /datum/round_event/falsealarm/announce(fake) diff --git a/code/modules/events/floorcluwne.dm b/code/modules/events/floorcluwne.dm index ce9a2d8cc3..6b91fb2ca2 100644 --- a/code/modules/events/floorcluwne.dm +++ b/code/modules/events/floorcluwne.dm @@ -4,7 +4,8 @@ max_occurrences = 0 min_players = 20 weight = 10 - + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a floor cluwne, will hunt a random player and most likely gib them, prepare for adminhelps." /datum/round_event/floor_cluwne/start() var/list/spawn_locs = list() diff --git a/code/modules/events/fugitive_spawning.dm b/code/modules/events/fugitive_spawning.dm index a09f0f584e..13964d6ec6 100644 --- a/code/modules/events/fugitive_spawning.dm +++ b/code/modules/events/fugitive_spawning.dm @@ -4,6 +4,8 @@ max_occurrences = 1 min_players = 20 earliest_start = 30 MINUTES //deadchat sink, lets not even consider it early on. + category = EVENT_CATEGORY_INVASION + description = "Fugitives will hide on the station, followed by hunters." /datum/round_event/ghost_role/fugitives minimum_required = 1 diff --git a/code/modules/events/ghost_role.dm b/code/modules/events/ghost_role.dm index ae1d1320a5..baabb435bc 100644 --- a/code/modules/events/ghost_role.dm +++ b/code/modules/events/ghost_role.dm @@ -7,6 +7,8 @@ var/minimum_required = 1 var/role_name = "debug rat with cancer" // Q U A L I T Y M E M E S var/list/spawned_mobs = list() + var/status + var/cached_announcement_chance fakeable = FALSE /datum/round_event/ghost_role/start() @@ -17,7 +19,10 @@ // to prevent us from getting gc'd halfway through processing = FALSE - var/status = spawn_role() + status = spawn_role() + if(isnull(cached_announcement_chance)) + cached_announcement_chance = announce_chance //only announce once we've finished the spawning loop. + announce_chance = (status == SUCCESSFUL_SPAWN ? cached_announcement_chance : 0) if((status == WAITING_FOR_SOMETHING)) if(retry >= MAX_SPAWN_ATTEMPT) message_admins("[role_name] event has exceeded maximum spawn attempts. Aborting and refunding.") diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 1bb0ee617a..c39a6e1bb2 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -3,10 +3,12 @@ typepath = /datum/round_event/grid_check weight = 10 max_occurrences = 3 + category = EVENT_CATEGORY_ENGINEERING + description = "Turns off all APCs for a while, or until they are manually rebooted." /datum/round_event/grid_check - announceWhen = 1 - startWhen = 1 + announce_when = 1 + start_when = 1 /datum/round_event/grid_check/announce(fake) priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff") diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 930a2b884f..4f94576fa6 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -4,6 +4,8 @@ weight = 10 max_occurrences = 2 min_players = 10 // To avoid shafting lowpop + category = EVENT_CATEGORY_HEALTH + description = "A random crewmember's heart gives out." /datum/round_event_control/heart_attack/canSpawnEvent(var/players_amt, var/gamemode) if(!..()) return FALSE diff --git a/code/modules/events/high_priority_bounty.dm b/code/modules/events/high_priority_bounty.dm index ffdcd8840b..90f27b19f9 100644 --- a/code/modules/events/high_priority_bounty.dm +++ b/code/modules/events/high_priority_bounty.dm @@ -4,6 +4,8 @@ max_occurrences = 3 weight = 20 earliest_start = 10 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Creates bounties that are three times original worth." /datum/round_event/high_priority_bounty/announce(fake) priority_announce("Central Command has issued a high-priority cargo bounty. Details have been sent to all bounty consoles.", "Nanotrasen Bounty Program") diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index 9824355e4b..fd45eb4ccf 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -5,6 +5,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Gives everyone treats, and turns Ian and Polly into their festive versions." /datum/round_event/spooky/start() ..() diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index 16ae047729..ebe44d3e00 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -11,6 +11,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Puts people on dates! They must protect each other. Sometimes a vengeful third wheel spawns." /datum/round_event/valentines/start() ..() diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index e043caa29d..a9bedb3c57 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -68,6 +68,8 @@ weight = 20 max_occurrences = 1 earliest_start = 30 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Spawns santa, who shall roam the station, handing out gifts." /datum/round_event/santa var/mob/living/carbon/human/santa //who is our santa? diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index 482abe67f2..a48191e8a1 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -13,7 +13,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 min_players = 15 max_occurrences = 5 var/atom/special_target - + category = EVENT_CATEGORY_SPACE + description = "The station passes through an immovable rod." /datum/round_event_control/immovable_rod/admin_setup() if(!check_rights(R_FUN)) @@ -24,7 +25,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 special_target = get_turf(usr) /datum/round_event/immovable_rod - announceWhen = 5 + announce_when = 5 /datum/round_event/immovable_rod/announce(fake) priority_announce("What the fuck was that?!", "General Alert", has_important_message = TRUE) diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index f25b476657..0fefb43170 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -5,6 +5,8 @@ typepath = /datum/round_event/ion_storm weight = 15 min_players = 2 + category = EVENT_CATEGORY_AI + description = "Gives the AI a new, randomized law." /datum/round_event/ion_storm var/replaceLawsetChance = 25 //chance the AI's lawset is completely replaced with something else per config weights @@ -14,8 +16,8 @@ var/botEmagChance = 10 var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means it is announced var/ionMessage = null - var/ionAnnounceChance = 33 - announceWhen = 1 + announce_when = 1 + announce_chance = 33 /datum/round_event/ion_storm/add_law_only // special subtype that adds a law only replaceLawsetChance = 0 @@ -25,7 +27,7 @@ botEmagChance = 0 /datum/round_event/ion_storm/announce(fake) - if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake) + if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(announce_chance)) || fake) priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm", has_important_message = prob(80)) diff --git a/code/modules/events/major_dust.dm b/code/modules/events/major_dust.dm index 3f7cbc77f5..dc24a52b19 100644 --- a/code/modules/events/major_dust.dm +++ b/code/modules/events/major_dust.dm @@ -2,6 +2,7 @@ name = "Major Space Dust" typepath = /datum/round_event/meteor_wave/major_dust weight = 8 + description = "The station is pelted by sand." /datum/round_event/meteor_wave/major_dust wave_name = "space dust" diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index d8e52cf46d..2a0c45a5ff 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -5,6 +5,8 @@ max_occurrences = 5 min_players = 1 var/forced_hallucination + category = EVENT_CATEGORY_HEALTH + description = "Multiple crewmembers start to hallucinate the same thing." /datum/round_event_control/mass_hallucination/admin_setup() if(!check_rights(R_FUN)) diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm index c4711055d9..a625f53788 100644 --- a/code/modules/events/meateor_wave.dm +++ b/code/modules/events/meateor_wave.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/meteor_wave/meaty weight = 2 max_occurrences = 1 + description = "A meteor wave made of meat." /datum/round_event/meteor_wave/meaty wave_name = "meaty" diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index a3e0eb70ff..a3534be3ea 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -10,22 +10,24 @@ min_players = 15 max_occurrences = 3 earliest_start = 25 MINUTES + category = EVENT_CATEGORY_SPACE + description = "A regular meteor wave." /datum/round_event/meteor_wave - startWhen = 6 - endWhen = 66 - announceWhen = 1 + start_when = 6 + end_when = 66 + announce_when = 1 threat = 15 var/list/wave_type var/wave_name = "normal" var/direction /datum/round_event/meteor_wave/setup() - announceWhen = 1 - startWhen = 150 // 5 minutes + announce_when = 1 + start_when = 150 // 5 minutes if(GLOB.singularity_counter) - startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) - endWhen = startWhen + 60 + start_when *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) + end_when = start_when + 60 /datum/round_event/meteor_wave/New() ..() @@ -61,9 +63,9 @@ kill() /datum/round_event/meteor_wave/announce(fake) - priority_announce(generateMeteorString(startWhen,TRUE,direction), "Meteor Alert", "meteors", has_important_message = TRUE) + priority_announce(generateMeteorString(start_when,TRUE,direction), "Meteor Alert", "meteors", has_important_message = TRUE) -/proc/generateMeteorString(startWhen,syndiealert,direction) +/proc/generateMeteorString(start_when,syndiealert,direction) var/directionstring switch(direction) if(NORTH) @@ -74,7 +76,7 @@ directionstring = " towards starboard" if(WEST) directionstring = " towards port" - return "Meteors have been detected on a collision course with the station[directionstring]. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter && syndiealert ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]" + return "Meteors have been detected on a collision course with the station[directionstring]. Estimated time until impact: [round((start_when * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter && syndiealert ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]" /datum/round_event/meteor_wave/tick() if(ISMULTIPLE(activeFor, 3)) @@ -87,7 +89,7 @@ min_players = 20 max_occurrences = 3 earliest_start = 35 MINUTES - + description = "A meteor wave with higher chance of big meteors." /datum/round_event/meteor_wave/threatening wave_name = "threatening" @@ -100,6 +102,7 @@ min_players = 25 max_occurrences = 3 earliest_start = 45 MINUTES + description = "A meteor wave that might summon a tunguska class meteor." /datum/round_event/meteor_wave/catastrophic wave_name = "catastrophic" diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm index 373c495972..5bf842ba47 100644 --- a/code/modules/events/mice_migration.dm +++ b/code/modules/events/mice_migration.dm @@ -2,6 +2,8 @@ name = "Mice Migration" typepath = /datum/round_event/mice_migration weight = 10 + category = EVENT_CATEGORY_ENTITIES + description = "A horde of mice arrives, and perhaps even the Rat King themselves." /datum/round_event/mice_migration var/minimum_mice = 5 diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 62f9c88d49..71351d85be 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -4,6 +4,8 @@ max_occurrences = 1 min_players = 20 dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a nightmare, aiming to darken the station." /datum/round_event/ghost_role/nightmare minimum_required = 1 diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 8d8adf2735..cbefa58c7b 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -2,7 +2,9 @@ name = "Lone Operative" typepath = /datum/round_event/ghost_role/operative weight = 0 //Admin only - max_occurrences = 0 //Now it is actually admin only + max_occurrences = 1 + category = EVENT_CATEGORY_INVASION + description = "A single nuclear operative assaults the station." /datum/round_event/ghost_role/operative minimum_required = 1 diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 188d733cd8..1b1fdee584 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -6,6 +6,8 @@ min_players = 10 earliest_start = 30 MINUTES dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "The crew will either pay up, or face a pirate assault." #define PIRATES_ROGUES "Rogues" // #define PIRATES_SILVERSCALES "Silverscales" diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index 59bb22e9af..b1b68fb585 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -4,6 +4,8 @@ weight = 2 min_players = 15 earliest_start = 30 MINUTES + category = EVENT_CATEGORY_ENTITIES + description = "Syndicate troops pour out of portals." /datum/round_event/portal_storm/syndicate_shocktroop boss_types = list(/mob/living/simple_animal/hostile/syndicate/melee/space/stormtrooper = 2) @@ -15,6 +17,8 @@ typepath = /datum/round_event/portal_storm/portal_storm_narsie weight = 0 max_occurrences = 0 + category = EVENT_CATEGORY_ENTITIES + description = "Nar'sie constructs pour out of portals." /datum/round_event/portal_storm/portal_storm_narsie boss_types = list(/mob/living/simple_animal/hostile/construct/builder = 6) @@ -22,9 +26,9 @@ /mob/living/simple_animal/hostile/construct/wraith/hostile = 6) /datum/round_event/portal_storm - startWhen = 7 - endWhen = 999 - announceWhen = 1 + start_when = 7 + end_when = 999 + announce_when = 1 var/list/boss_spawn = list() var/list/boss_types = list() //only configure this if you have hostiles @@ -53,7 +57,7 @@ while(number_of_hostiles > hostiles_spawn.len) hostiles_spawn += get_random_station_turf() - next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1) + next_boss_spawn = start_when + CEILING(2 * number_of_hostiles / number_of_bosses, 1) /datum/round_event/portal_storm/announce(fake) do_announce() @@ -117,7 +121,7 @@ /datum/round_event/portal_storm/proc/time_to_end() if(!hostile_types.len && !boss_types.len) - endWhen = activeFor + end_when = activeFor if(!number_of_hostiles && number_of_bosses) - endWhen = activeFor + end_when = activeFor diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index d35f4931fb..110ab745a0 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -3,10 +3,12 @@ typepath = /datum/round_event/grey_tide max_occurrences = 2 min_players = 5 + category = EVENT_CATEGORY_ENGINEERING + description = "Bolts open all doors in one or more departments." /datum/round_event/grey_tide - announceWhen = 50 - endWhen = 20 + announce_when = 50 + end_when = 20 var/list/area/areasToOpen = list() var/list/potential_areas = list(/area/command, /area/engineering, @@ -17,8 +19,8 @@ var/severity = 1 /datum/round_event/grey_tide/setup() - announceWhen = rand(50, 60) - endWhen = rand(20, 30) + announce_when = rand(50, 60) + end_when = rand(20, 30) severity = rand(1,3) for(var/i in 1 to severity) var/picked_area = pick_n_take(potential_areas) diff --git a/code/modules/events/processor_overload.dm b/code/modules/events/processor_overload.dm index 6f20d954ed..578520f565 100644 --- a/code/modules/events/processor_overload.dm +++ b/code/modules/events/processor_overload.dm @@ -3,9 +3,11 @@ typepath = /datum/round_event/processor_overload weight = 15 min_players = 20 + category = EVENT_CATEGORY_ENGINEERING + description = "Emps the telecomm processors, scrambling radio speech. Might blow up a few." /datum/round_event/processor_overload - announceWhen = 1 + announce_when = 1 /datum/round_event/processor_overload/announce(fake) var/alert = pick( "Exospheric bubble inbound. Processor overload is likely. Please contact you*%xp25)`6cq-BZZT", \ diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 52a207fd14..5ba3d017e1 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -2,14 +2,16 @@ name = "Radiation Storm" typepath = /datum/round_event/radiation_storm max_occurrences = 1 + category = EVENT_CATEGORY_SPACE + description = "Radiation storm affects the station, forcing the crew to escape to maintenance." /datum/round_event/radiation_storm /datum/round_event/radiation_storm/setup() - startWhen = 3 - endWhen = startWhen + 1 - announceWhen = 1 + start_when = 3 + end_when = start_when + 1 + announce_when = 1 /datum/round_event/radiation_storm/announce(fake) priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation", has_important_message = TRUE) diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index d90792c88f..8cccaba68b 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -2,7 +2,8 @@ name = "Random Human-level Intelligence" typepath = /datum/round_event/ghost_role/sentience weight = 10 - + category = EVENT_CATEGORY_FRIENDLY + description = "An animal or robot becomes sentient!" /datum/round_event/ghost_role/sentience minimum_required = 1 @@ -75,6 +76,8 @@ name = "Station-wide Human-level Intelligence" typepath = /datum/round_event/ghost_role/sentience/all weight = 0 + category = EVENT_CATEGORY_FRIENDLY + description = "ALL animals and robots become sentient, provided there is enough ghosts." /datum/round_event/ghost_role/sentience/all one = "all" diff --git a/code/modules/events/shuttle_catastrophe b/code/modules/events/shuttle_catastrophe.dm similarity index 94% rename from code/modules/events/shuttle_catastrophe rename to code/modules/events/shuttle_catastrophe.dm index d948b39d3b..2e431a8a34 100644 --- a/code/modules/events/shuttle_catastrophe +++ b/code/modules/events/shuttle_catastrophe.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/shuttle_catastrophe weight = 10 max_occurrences = 1 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Replaces the emergency shuttle with a random one." /datum/round_event_control/shuttle_catastrophe/canSpawnEvent(players, gamemode) if(SSshuttle.emergency.name == "Build your own shuttle kit") diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index 38d52797d7..49a0f94000 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -13,10 +13,12 @@ typepath = /datum/round_event/shuttle_loan max_occurrences = 1 earliest_start = 7 MINUTES + category = EVENT_CATEGORY_BUREAUCRATIC + description = "If cargo accepts the offer, fills the shuttle with loot and/or enemies." /datum/round_event/shuttle_loan - announceWhen = 1 - endWhen = 500 + announce_when = 1 + end_when = 500 var/dispatched = 0 var/dispatch_type = 0 var/bonus_points = 10000 @@ -72,7 +74,7 @@ var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) D.adjust_money(bonus_points) - endWhen = activeFor + 1 + end_when = activeFor + 1 SSshuttle.supply.mode = SHUTTLE_CALL SSshuttle.supply.destination = SSshuttle.getDock("supply_home") @@ -101,9 +103,9 @@ /datum/round_event/shuttle_loan/tick() if(dispatched) if(SSshuttle.supply.mode != SHUTTLE_IDLE) - endWhen = activeFor + end_when = activeFor else - endWhen = activeFor + 1 + end_when = activeFor + 1 /datum/round_event/shuttle_loan/end() if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched) diff --git a/code/modules/events/space_dragon.dm b/code/modules/events/space_dragon.dm index e06666b6bb..d06327ec0f 100644 --- a/code/modules/events/space_dragon.dm +++ b/code/modules/events/space_dragon.dm @@ -6,11 +6,13 @@ earliest_start = 30 MINUTES min_players = 20 dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a space dragon, which will try to take over the station." /datum/round_event/ghost_role/space_dragon minimum_required = 1 role_name = "Space Dragon" - announceWhen = 10 + announce_when = 10 /datum/round_event/ghost_role/space_dragon/announce(fake) priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert", has_important_message = TRUE) diff --git a/code/modules/events/space_ninja.dm b/code/modules/events/space_ninja.dm index 4a9dc4d2eb..aaf3f1a302 100644 --- a/code/modules/events/space_ninja.dm +++ b/code/modules/events/space_ninja.dm @@ -6,6 +6,8 @@ earliest_start = 30 MINUTES min_players = 15 dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "A space ninja infiltrates the station." /datum/round_event/ghost_role/space_ninja minimum_required = 1 diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index a96e74f1e4..1bbcb0dd92 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -4,6 +4,8 @@ weight = 15 max_occurrences = 3 min_players = 20 + category = EVENT_CATEGORY_ENTITIES + description = "Kudzu begins to overtake the station. Might spawn man-traps." /datum/round_event/spacevine fakeable = FALSE diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 23ce6ce730..6e8c29d3a9 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -4,15 +4,17 @@ weight = 5 max_occurrences = 1 min_players = 15 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns spider eggs, ready to hatch." /datum/round_event/spider_infestation - announceWhen = 400 + announce_when = 400 var/spawncount = 1 /datum/round_event/spider_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) + announce_when = rand(announce_when, announce_when + 50) spawncount = rand(5, 8) /datum/round_event/spider_infestation/announce(fake) diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index 7705ece78a..31b14bb8b9 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -5,6 +5,8 @@ max_occurrences = 4 earliest_start = 10 MINUTES min_players = 5 // To make your chance of getting help a bit higher. + category = EVENT_CATEGORY_HEALTH + description = "A random crewmember gets appendicitis." /datum/round_event/spontaneous_appendicitis fakeable = FALSE diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index 2464432d72..f7240f9e8b 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -5,6 +5,8 @@ weight = 5 max_occurrences = 4 earliest_start = 10 MINUTES + category = EVENT_CATEGORY_BUREAUCRATIC + description = "A pod containing a random supply crate lands on the station." ///Spawns a cargo pod containing a random cargo supply pack on a random area of the station /datum/round_event/stray_cargo @@ -20,7 +22,7 @@ * Also randomizes the start timer */ /datum/round_event/stray_cargo/setup() - startWhen = rand(20, 40) + start_when = rand(20, 40) impact_area = find_event_area() if(!impact_area) CRASH("No valid areas for cargo pod found.") @@ -89,6 +91,7 @@ weight = 0 max_occurrences = 0 earliest_start = 30 MINUTES + description = "A pod containing syndicate gear lands on the station." /datum/round_event/stray_cargo/syndicate possible_pack_types = list(/datum/supply_pack/misc/syndicate) diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm index d873e6ca8f..08deaae7d5 100644 --- a/code/modules/events/supermatter_surge.dm +++ b/code/modules/events/supermatter_surge.dm @@ -4,6 +4,8 @@ weight = 20 max_occurrences = 5 earliest_start = 10 MINUTES + category = EVENT_CATEGORY_ENGINEERING + description = "Randomly modifies the supermatter's power, giving the engineers a lot of headaches." /datum/round_event_control/supermatter_surge/canSpawnEvent() if(GLOB.main_supermatter_engine?.has_been_powered) diff --git a/code/modules/events/supernova.dm b/code/modules/events/supernova.dm index 7862e85709..16c81e4056 100644 --- a/code/modules/events/supernova.dm +++ b/code/modules/events/supernova.dm @@ -4,18 +4,20 @@ weight = 5 max_occurrences = 1 min_players = 2 + category = EVENT_CATEGORY_SPACE + description = "Several modified radstorms hit the station." /datum/round_event/supernova - announceWhen = 40 - startWhen = 1 - endWhen = 300 + announce_when = 40 + start_when = 1 + end_when = 300 var/power = 1 var/datum/sun/supernova var/storm_count = 0 var/announced = FALSE /datum/round_event/supernova/setup() - announceWhen = rand(4, 60) + announce_when = rand(4, 60) supernova = new SSsun.suns += supernova switch(rand(1,5)) @@ -53,10 +55,10 @@ sucker_light.give_home_power() /datum/round_event/supernova/tick() - var/midpoint = round((endWhen-startWhen)/2) + var/midpoint = round((end_when-start_when)/2) if(activeFor < midpoint) supernova.power_mod = min(supernova.power_mod*1.2, power) - if(activeFor > endWhen-10) + if(activeFor > end_when-10) supernova.power_mod /= 4 if(prob(round(supernova.power_mod)) && prob(5-storm_count) && !SSweather.get_weather_by_type(/datum/weather/rad_storm)) SSweather.run_weather(/datum/weather/rad_storm/supernova) diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm index be697c9b6d..ac9d103f5f 100644 --- a/code/modules/events/travelling_trader.dm +++ b/code/modules/events/travelling_trader.dm @@ -4,10 +4,12 @@ weight = 8 max_occurrences = 2 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_FRIENDLY + description = "A mysterious figure requests something to the crew and rewards them with something for getting it done." /datum/round_event/travelling_trader - startWhen = 0 - endWhen = 900 //you effectively have 15 minutes to complete the traders request, before they disappear + start_when = 0 + end_when = 900 //you effectively have 15 minutes to complete the traders request, before they disappear var/mob/living/carbon/human/dummy/travelling_trader/trader var/atom/spawn_location //where the trader appears diff --git a/code/modules/events/untie_shoes.dm b/code/modules/events/untie_shoes.dm index 5a0da3ebc2..17dd2ca8b2 100644 --- a/code/modules/events/untie_shoes.dm +++ b/code/modules/events/untie_shoes.dm @@ -4,6 +4,8 @@ weight = 50 max_occurrences = 10 alert_observers = FALSE + category = EVENT_CATEGORY_HEALTH + description = "Unties people's shoes, with a chance to knot them as well." /datum/round_event/untied_shoes fakeable = FALSE diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 2c03531bcc..fb88f81598 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -3,11 +3,13 @@ typepath = /datum/round_event/vent_clog weight = 10 max_occurrences = 3 + category = EVENT_CATEGORY_HEALTH + description = "All the scrubbers onstation spit random chemicals in smoke form." /datum/round_event/vent_clog - announceWhen = 1 - startWhen = 5 - endWhen = 35 + announce_when = 1 + start_when = 5 + end_when = 35 var/interval = 2 var/list/vents = list() var/randomProbability = 0 @@ -62,7 +64,7 @@ priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", has_important_message = TRUE) /datum/round_event/vent_clog/setup() - endWhen = rand(120, 180) + end_when = rand(120, 180) for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines) var/turf/T = get_turf(temp_vent) var/area/A = T.loc @@ -108,6 +110,7 @@ min_players = 15 max_occurrences = 1 earliest_start = 35 MINUTES + description = "Extra dangerous chemicals come out of the scrubbers." /datum/round_event/vent_clog/threatening randomProbability = 10 @@ -120,6 +123,7 @@ min_players = 25 max_occurrences = 1 earliest_start = 45 MINUTES + description = "EXTREMELY dangerous chemicals come out of the scrubbers." /datum/round_event/vent_clog/catastrophic randomProbability = 30 @@ -129,6 +133,7 @@ name = "Clogged Vents: Beer" typepath = /datum/round_event/vent_clog/beer max_occurrences = 0 + description = "Spits out beer through the scrubber system." /datum/round_event/vent_clog/beer reagentsAmount = 100 @@ -137,6 +142,7 @@ name = "Anti-Plasma Flood" typepath = /datum/round_event/vent_clog/plasma_decon max_occurrences = 0 + description = "Freezing smoke comes out of the scrubbers." /datum/round_event/vent_clog/beer/announce() priority_announce("The scrubbers network is experiencing an unexpected surge of pressurized beer. Some ejection of contents may occur.", "Atmospherics alert") diff --git a/code/modules/events/wisdomcow.dm b/code/modules/events/wisdomcow.dm index 553dd8f309..3c03911d1d 100644 --- a/code/modules/events/wisdomcow.dm +++ b/code/modules/events/wisdomcow.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/wisdomcow max_occurrences = 1 weight = 10 + category = EVENT_CATEGORY_FRIENDLY + description = "A cow appears to tell you wise words." /datum/round_event/wisdomcow/announce(fake) priority_announce("A wise cow has been spotted in the area. Be sure to ask for her advice.", "Nanotrasen Cow Ranching Agency") diff --git a/code/modules/events/wizard/aid.dm b/code/modules/events/wizard/aid.dm index 5f49b48900..2380027284 100644 --- a/code/modules/events/wizard/aid.dm +++ b/code/modules/events/wizard/aid.dm @@ -6,6 +6,7 @@ typepath = /datum/round_event/wizard/robelesscasting max_occurrences = 1 earliest_start = 0 MINUTES + description = "Wizard no longer needs robes to cast spells." /datum/round_event/wizard/robelesscasting/start() @@ -28,6 +29,7 @@ typepath = /datum/round_event/wizard/improvedcasting max_occurrences = 4 //because that'd be max level spells earliest_start = 0 MINUTES + description = "Levels up the wizard's spells." /datum/round_event/wizard/improvedcasting/start() for(var/i in GLOB.mob_living_list) diff --git a/code/modules/events/wizard/blobies.dm b/code/modules/events/wizard/blobies.dm index 7438b462f6..6933847f80 100644 --- a/code/modules/events/wizard/blobies.dm +++ b/code/modules/events/wizard/blobies.dm @@ -3,6 +3,7 @@ weight = 3 typepath = /datum/round_event/wizard/blobies max_occurrences = 3 + description = "Spawns a blob spore on every corpse." /datum/round_event/wizard/blobies/start() diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index 061de0ea7c..639673ac15 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -5,6 +5,7 @@ max_occurrences = 3 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE + description = "Gives everyone a cursed item." //Note about adding items to this: Because of how NODROP_1 works if an item spawned to the hands can also be equiped to a slot //it will be able to be put into that slot from the hand, but then get stuck there. To avoid this make a new subtype of any diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index ce6b4802fa..f08a40751d 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -5,6 +5,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "A department is turned into an independent state." /datum/round_event/wizard/deprevolt/start() diff --git a/code/modules/events/wizard/embeddies.dm b/code/modules/events/wizard/embeddies.dm index fe08b9c743..32c9affb6d 100644 --- a/code/modules/events/wizard/embeddies.dm +++ b/code/modules/events/wizard/embeddies.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/embedpocalypse max_occurrences = 1 earliest_start = 0 MINUTES + description = "Everything becomes pointy enough to embed in people when thrown." /datum/round_event/wizard/embedpocalypse/start() for(var/obj/item/I in world) @@ -26,6 +27,7 @@ typepath = /datum/round_event/wizard/embedpocalypse/sticky max_occurrences = 1 earliest_start = 0 MINUTES + description = "Everything becomes sticky enough to be glued to people when thrown." /datum/round_event_control/wizard/embedpocalypse/sticky/canSpawnEvent(players_amt, gamemode) if(GLOB.embedpocalypse) diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm index 3ba20f4768..7a89fc14bd 100644 --- a/code/modules/events/wizard/fakeexplosion.dm +++ b/code/modules/events/wizard/fakeexplosion.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/fake_explosion max_occurrences = 1 earliest_start = 0 MINUTES + description = "The nuclear explosion cutscene begins to play to scare the crew." /datum/round_event/wizard/fake_explosion/start() sound_to_playing_players('sound/machines/alarm.ogg') diff --git a/code/modules/events/wizard/ghost.dm b/code/modules/events/wizard/ghost.dm index c288953efb..5a11616b8f 100644 --- a/code/modules/events/wizard/ghost.dm +++ b/code/modules/events/wizard/ghost.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/ghost max_occurrences = 1 earliest_start = 0 MINUTES + description = "Ghosts become visible." /datum/round_event/wizard/ghost/start() var/msg = "You suddenly feel extremely obvious..." @@ -18,6 +19,7 @@ typepath = /datum/round_event/wizard/possession max_occurrences = 5 earliest_start = 0 MINUTES + description = "Ghosts become visible and gain the power of possession." /datum/round_event/wizard/possession/start() for(var/mob/dead/observer/G in GLOB.player_list) diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 82e72df3b9..1864ad6d20 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/greentext max_occurrences = 1 earliest_start = 0 MINUTES + description = "The Green Text appears on the station, tempting people to try and pick it up." /datum/round_event/wizard/greentext/start() diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 29704168e9..2b7e9bcf17 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/imposter max_occurrences = 1 earliest_start = 0 MINUTES + description = "Spawns a doppelganger of the wizard." /datum/round_event/wizard/imposter/start() for(var/datum/mind/M in SSticker.mode.wizards) diff --git a/code/modules/events/wizard/invincible.dm b/code/modules/events/wizard/invincible.dm index b69d1541ee..0dea1fbaf7 100644 --- a/code/modules/events/wizard/invincible.dm +++ b/code/modules/events/wizard/invincible.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/invincible max_occurrences = 5 earliest_start = 0 MINUTES + description = "Everyone is invincible for a short time ticks." /datum/round_event/wizard/invincible/start() diff --git a/code/modules/events/wizard/lava.dm b/code/modules/events/wizard/lava.dm index 9a882b45df..75962c81ad 100644 --- a/code/modules/events/wizard/lava.dm +++ b/code/modules/events/wizard/lava.dm @@ -4,9 +4,10 @@ typepath = /datum/round_event/wizard/lava max_occurrences = 3 earliest_start = 0 MINUTES + description = "Turns the floor into hot lava." /datum/round_event/wizard/lava - endWhen = 0 + end_when = 0 var/started = FALSE /datum/round_event/wizard/lava/start() diff --git a/code/modules/events/wizard/madness.dm b/code/modules/events/wizard/madness.dm index ac86236623..de2c30a032 100644 --- a/code/modules/events/wizard/madness.dm +++ b/code/modules/events/wizard/madness.dm @@ -3,6 +3,7 @@ weight = 1 typepath = /datum/round_event/wizard/madness earliest_start = 0 MINUTES + description = "Reveals a horrifying truth to everyone, giving them a trauma." var/forced_secret diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm index 052143722e..b900a2da9f 100644 --- a/code/modules/events/wizard/magicarp.dm +++ b/code/modules/events/wizard/magicarp.dm @@ -4,13 +4,14 @@ typepath = /datum/round_event/wizard/magicarp max_occurrences = 1 earliest_start = 0 MINUTES + description = "Summons a school of carps with magic projectiles." /datum/round_event/wizard/magicarp - announceWhen = 3 - startWhen = 50 + announce_when = 3 + start_when = 50 /datum/round_event/wizard/magicarp/setup() - startWhen = rand(40, 60) + start_when = rand(40, 60) /datum/round_event/wizard/magicarp/announce(fake) priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index fb4d433905..ff3ebdd128 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -5,6 +5,7 @@ max_occurrences = 1 //Exponential growth is nothing to sneeze at! earliest_start = 0 MINUTES var/mobs_to_dupe = 0 + description = "Rapidly multiplies the animals on the station." /datum/round_event_control/wizard/petsplosion/preRunEvent() for(var/mob/living/simple_animal/F in GLOB.alive_mob_list) @@ -16,7 +17,7 @@ ..() /datum/round_event/wizard/petsplosion - endWhen = 61 //1 minute (+1 tick for endWhen not to interfere with tick) + end_when = 61 //1 minute (+1 tick for end_when not to interfere with tick) var/countdown = 0 var/mobs_duped = 0 diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 5c3b8432c1..8c45a9504b 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -5,6 +5,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE + description = "Gives everyone a random race." /datum/round_event/wizard/race var/list/stored_name @@ -16,7 +17,7 @@ stored_name = list() stored_species = list() stored_dna = list() - endWhen = rand(600,1200) //10 to 20 minutes + end_when = rand(600,1200) //10 to 20 minutes ..() /datum/round_event/wizard/race/start() diff --git a/code/modules/events/wizard/rpgloot.dm b/code/modules/events/wizard/rpgloot.dm index bf3104450e..911a9bf665 100644 --- a/code/modules/events/wizard/rpgloot.dm +++ b/code/modules/events/wizard/rpgloot.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/rpgloot max_occurrences = 1 earliest_start = 0 MINUTES + description = "Every item in the world will have fantastical names." /datum/round_event/wizard/rpgloot/start() var/upgrade_scroll_chance = 0 diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm index 18b8c8e21c..5659818b48 100644 --- a/code/modules/events/wizard/shuffle.dm +++ b/code/modules/events/wizard/shuffle.dm @@ -8,6 +8,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles everyone around on the station." /datum/round_event/wizard/shuffleloc/start() var/list/moblocs = list() @@ -45,6 +46,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles the names of everyone around the station." /datum/round_event/wizard/shufflenames/start() var/list/mobnames = list() @@ -80,6 +82,7 @@ max_occurrences = 3 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles the minds of everyone around the station, except for the wizard." /datum/round_event/wizard/shuffleminds/start() var/list/mobs = list() diff --git a/code/modules/events/wizard/summons.dm b/code/modules/events/wizard/summons.dm index ac1160e0f5..886dfdfd10 100644 --- a/code/modules/events/wizard/summons.dm +++ b/code/modules/events/wizard/summons.dm @@ -5,6 +5,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Summons a gun for everyone. Might turn people into survivalists." /datum/round_event_control/wizard/summonguns/New() if(CONFIG_GET(flag/no_summon_guns)) @@ -21,6 +22,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Summons a magic item for everyone. Might turn people into survivalists." /datum/round_event_control/wizard/summonmagic/New() if(CONFIG_GET(flag/no_summon_magic)) diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 3207e3b635..413658e34d 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -4,11 +4,12 @@ max_occurrences = 3 weight = 2 min_players = 2 - + category = EVENT_CATEGORY_SPACE + description = "Space time anomalies appear on the station, randomly teleporting people who walk into them." /datum/round_event/wormholes - announceWhen = 10 - endWhen = 60 + announce_when = 10 + end_when = 60 var/list/pick_turfs = list() var/list/wormholes = list() @@ -16,8 +17,8 @@ var/number_of_wormholes = 400 /datum/round_event/wormholes/setup() - announceWhen = rand(0, 20) - endWhen = rand(40, 80) + announce_when = rand(0, 20) + end_when = rand(40, 80) /datum/round_event/wormholes/start() for(var/turf/open/floor/T in world) diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index 10b825440a..9c538f4bde 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -5,6 +5,8 @@ weight = -1 max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Hides surprise filled easter eggs in maintenance." /datum/round_event/easter/announce(fake) priority_announce(pick("Hip-hop into Easter!","Find some Bunny's stash!","Today is National 'Hunt a Wabbit' Day.","Be kind, give Chocolate Eggs!")) @@ -16,6 +18,8 @@ typepath = /datum/round_event/rabbitrelease weight = 5 max_occurrences = 10 + category = EVENT_CATEGORY_HOLIDAY + description = "Summons a wave of cute rabbits." /datum/round_event/rabbitrelease/announce(fake) priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", "aliens") diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 5dd8ad9155..8ef60d8b54 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -15,6 +15,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Spawns Jacq, a friendly mob that gives players a couple fun stuff to do." /datum/round_event/jacqueen/start() ..() diff --git a/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm b/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm index 6f5f0e3dba..9c4becbdcf 100644 --- a/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm +++ b/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm @@ -5,8 +5,8 @@ max_occurrences = 2 earliest_start = 20 MINUTES min_players = 5 - - + category = EVENT_CATEGORY_ENTITIES + description = "Annoying little creatures go around the station causing havoc and hacking everything." /datum/round_event/gremlin var/static/list/acceptable_spawns = list("xeno_spawn", "generic event spawn", "blobstart", "Assistant") diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index 2c6bef81c2..113a0b33fa 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -43,6 +43,7 @@ to_chat(usr, "You slide \the [pen] into \the [src]'s pen slot.") inserted_item = pen playsound(src, 'sound/machines/button.ogg', 50, 1) + SStgui.update_uis(src) /obj/item/modular_computer/tablet/proc/remove_pen() if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) @@ -52,6 +53,7 @@ usr.put_in_hands(inserted_item) to_chat(usr, "You remove [inserted_item] from \the [src]'s pen slot.") inserted_item = null + SStgui.update_uis(src) else to_chat(usr, "\The [src] does not have a pen in it!") @@ -78,9 +80,21 @@ QDEL_NULL(inserted_item) return ..() +/obj/item/modular_computer/tablet/ui_act(action, params) + . = ..() + if(.) + return + if(action == "TABLET_eject_pen") + if(istype(src, /obj/item/modular_computer/tablet)) + var/obj/item/modular_computer/tablet/self = src + if(self.can_have_pen) + self.remove_pen() + return TRUE + /obj/item/modular_computer/tablet/ui_data(mob/user) . = ..() - .["PC_showpeneject"] = inserted_item ? 1 : 0 + .["TABLET_show_pen_eject"] = inserted_item ? 1 : 0 + /obj/item/modular_computer/tablet/update_icon_state() if(has_variants) if(!finish_color) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 27fb30a459..67ab3817ae 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -242,8 +242,9 @@ to_chat(user, "You need to secure the assembly before you can add glass.") return var/obj/item/stack/sheet/S = W - if(S.use(2)) - glass_type = W.type + S = S.split_stack(amount=2) + if(S) + glass_type = S playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) user.visible_message("[user] places the glass on the solar assembly.", "You place the glass on the solar assembly.") if(tracker) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 98b04a8382..7862f24715 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -232,9 +232,12 @@ var/amount = materials.mat_container.materials[mat_id] var/ref = REF(M) l += "* [amount] of [M.name]: " - if(amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT) l += "1x [RDSCREEN_NOBREAK]" if(amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" - if(amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*10) l += "10x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*20) l += "20x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*50) l += "50x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT) l += "Max Stack[RDSCREEN_NOBREAK]" l += "" l += "[RDSCREEN_NOBREAK]" return l diff --git a/code/modules/tgui/states/fun.dm b/code/modules/tgui/states/fun.dm new file mode 100644 index 0000000000..ba72f40fd0 --- /dev/null +++ b/code/modules/tgui/states/fun.dm @@ -0,0 +1,17 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + +/** + * tgui state: fun_state + * + * Checks that the user has the fun privilige. + */ + +GLOBAL_DATUM_INIT(fun_state, /datum/ui_state/fun_state, new) + +/datum/ui_state/fun_state/can_use_topic(src_object, mob/user) + if(check_rights_for(user.client, R_FUN)) + return UI_INTERACTIVE + return UI_CLOSE diff --git a/config/config.txt b/config/config.txt index 8db6b1f725..cda573d11d 100644 --- a/config/config.txt +++ b/config/config.txt @@ -42,6 +42,7 @@ $include entries/vote.txt $include plushies/defines.txt # Special Sandstorm configs $include sandstorm/config.txt +$include sandstorm/balance.txt # Special SPLURT configs $include splurt/fetish_content.txt diff --git a/config/sandstorm/balance.txt b/config/sandstorm/balance.txt new file mode 100644 index 0000000000..1268cb1904 --- /dev/null +++ b/config/sandstorm/balance.txt @@ -0,0 +1,59 @@ +# Special Sandstorm balance config! + +### +## CRYPTOMINER +### + +## Should cryptominers work in non-atmos turf (ex. space)? +## Uncomment this to disable atmos processing (cheat mode) +#CRYPTO_IGNORE_ATMOS + +## What point multiplier should cryptominers use? +## Determined by heat level, or uses MAX in cheat mode +CRYPTO_MULTIPLIER_MIN 0.2 +CRYPTO_MULTIPLIER_MID 1 +CRYPTO_MULTIPLIER_MAX 3 + +## What heat thresholds should cryptominers use? +## This is measured in Kelvins +CRYPTO_HEAT_THRESHOLD_MIN 225 +CRYPTO_HEAT_THRESHOLD_MID 273 +CRYPTO_HEAT_THRESHOLD_MAX 500 + +## How much heat should cryptominers produce? +## This amount is added to the environment on process +CRYPTO_HEAT_POWER 100 + +## How long between cryptominers producing resources? +## Currently unimplemented! +CRYPTO_MINING_TIME 3000 + +## What material amount should the cryptominers produce? +## This is modified by the MULTIPLIER value +## Currently unimplemented! +CRYPTO_PAYOUT_AMOUNT 50 + +## How much power should the cryptominer use? +## Currently unimplemented! +CRYPTO_POWER_USE_IDLE 20 +CRYPTO_POWER_USE_ACTIVE 200 +CRYPTO_POWER_USE_PROCESS 20 + +### +## AUTODOC +### + +## How long should the autodoc take to perform surgery? +## This is modified by stock part ratings +AUTODOC_TIME_SURGERY_BASE 350 + +### +## BLUESPACE MINER +### + +## How much should the bluespace miner produce, compared to normal? +## This is modified by stock part ratings +BLUESPACEMINER_MULT_OUTPUT 1 + +## What is the minimum stock part tier to produce bluespace crystals? +BLUESPACEMINER_CRYSTAL_TIER 5 diff --git a/html/changelogs/archive/2023-01.yml b/html/changelogs/archive/2023-01.yml index eab41fd3ad..5a0e8bddad 100644 --- a/html/changelogs/archive/2023-01.yml +++ b/html/changelogs/archive/2023-01.yml @@ -203,3 +203,5 @@ - rscadd: nightstalker tail - rscdel: striked out issue from zombie making blood recovery not possible - tweak: vault suit to work + LeDrascol: + - server: Added configuration settings for Cryptominer, Autodoc, and Bluespace Miner. diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 567fc8ace8..73cc4b6853 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 3e57f4eca4..f87bed82d0 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 7926ead12d..077a3b43db 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/modular_citadel/code/modules/mentor/mentor_memo.dm b/modular_citadel/code/modules/mentor/mentor_memo.dm index 59ea92febd..c64101c30e 100644 --- a/modular_citadel/code/modules/mentor/mentor_memo.dm +++ b/modular_citadel/code/modules/mentor/mentor_memo.dm @@ -94,7 +94,7 @@ var/datum/db_query/update_query = SSdbcore.NewQuery({" UPDATE [format_table_name("mentor_memo")] SET memotext = :new_memo, last_editor = :ckey, edits = :edit_text WHERE ckey = :target_ckey - "}, list("new_memo" = new_memo, "ckey" = ckey, "edit_text" = (edit_text ? "" : edit_text), "target_ckey" = target_ckey)) + "}, list("new_memo" = new_memo, "ckey" = ckey, "edit_text" = (edit_text || ""), "target_ckey" = target_ckey)) if(!update_query.Execute()) var/err = update_query.ErrorMsg() qdel(update_query) diff --git a/modular_sand/code/controllers/configuration/entries/sandstorm_balance.dm b/modular_sand/code/controllers/configuration/entries/sandstorm_balance.dm new file mode 100644 index 0000000000..f739dec7b1 --- /dev/null +++ b/modular_sand/code/controllers/configuration/entries/sandstorm_balance.dm @@ -0,0 +1,66 @@ +/// CRYPTOMINERS /// +// Should cryptominers work in non-atmos turf +/datum/config_entry/flag/crypto_ignore_atmos + +// Cryptominer point multipliers +/datum/config_entry/number/crypto_multiplier_min + config_entry_value = 0.20 + integer = FALSE + +/datum/config_entry/number/crypto_multiplier_mid + config_entry_value = 1 + integer = FALSE + +/datum/config_entry/number/crypto_multiplier_max + config_entry_value = 3 + integer = FALSE + +// Cryptominer heat thresholds +/datum/config_entry/number/crypto_heat_threshold_min + config_entry_value = 225 + +/datum/config_entry/number/crypto_heat_threshold_mid + config_entry_value = 273 + +/datum/config_entry/number/crypto_heat_threshold_max + config_entry_value = 500 + +// Cryptominer heat produced +/datum/config_entry/number/crypto_heat_power + config_entry_value = 100 + +/* + * The contained configuration values are currently unimplemented + * +// Cryptominer processing time +/datum/config_entry/number/crypto_mining_time + config_entry_value = 3000 + +// Cryptominer base payout +/datum/config_entry/number/crypto_payout_amount + config_entry_value = 50 + +// Cryptominer power use +/datum/config_entry/number/crypto_power_use_idle + config_entry_value = 20 + +/datum/config_entry/number/crypto_power_use_active + config_entry_value = 200 + +/datum/config_entry/number/crypto_power_use_process + config_entry_value = 20 +*/ + +/// AUTODOC /// +// Autodoc processing time +/datum/config_entry/number/autodoc_time_surgery_base + config_entry_value = 350 + +/// BLUESPACE MINER /// +// BSM production output multiplier +/datum/config_entry/number/bluespaceminer_mult_output + config_entry_value = 1 + +// BSM minimum tier for bluespace crystals +/datum/config_entry/number/bluespaceminer_crystal_tier + config_entry_value = 5 diff --git a/modular_sand/code/game/machinery/autodoc.dm b/modular_sand/code/game/machinery/autodoc.dm index fcd00555c4..d4d266200b 100644 --- a/modular_sand/code/game/machinery/autodoc.dm +++ b/modular_sand/code/game/machinery/autodoc.dm @@ -1,3 +1,6 @@ +// Configuration defines +#define AUTODOC_TIME_BASE CONFIG_GET(number/autodoc_time_surgery_base) + /obj/machinery/autodoc name = "autodoc" desc = "An advanced machine used for inserting organs and implants into the occupant." @@ -17,8 +20,11 @@ . = ..() update_icon() + // Set initial time based on config + surgerytime = max(AUTODOC_TIME_BASE,10) + /obj/machinery/autodoc/RefreshParts() - var/max_time = 350 + var/max_time = AUTODOC_TIME_BASE for(var/obj/item/stock_parts/L in component_parts) max_time -= (L.rating*10) surgerytime = max(max_time,10) @@ -165,3 +171,5 @@ return obj_flags |= EMAGGED to_chat(user, span_warning("You reprogram [src]'s surgery procedures.")) + +#undef AUTODOC_TIME_BASE diff --git a/modular_sand/code/game/machinery/cryptominers.dm b/modular_sand/code/game/machinery/cryptominers.dm index 33f87a8e9f..6738511b4f 100644 --- a/modular_sand/code/game/machinery/cryptominers.dm +++ b/modular_sand/code/game/machinery/cryptominers.dm @@ -1,3 +1,22 @@ +// Configuration defines +/* + * Some entries are currently unimplemented + * +#define CRYPTO_POWER_USE CONFIG_GET(number/crypto_power_use_process) +#define CRYPTO_POWER_IDLE CONFIG_GET(number/crypto_power_use_idle) +#define CRYPTO_POWER_ACTIVE CONFIG_GET(number/crypto_power_use_active) +#define CRYPTO_MININGTIME CONFIG_GET(number/crypto_mining_time) +#define CRYPTO_MININGPOINTS CONFIG_GET(number/crypto_payout_amount) +*/ +#define CRYPTO_TEMP_MIN CONFIG_GET(number/crypto_heat_threshold_min) +#define CRYPTO_TEMP_MID CONFIG_GET(number/crypto_heat_threshold_mid) +#define CRYPTO_TEMP_MAX CONFIG_GET(number/crypto_heat_threshold_max) +#define CRYPTO_MULT_MIN CONFIG_GET(number/crypto_multiplier_min) +#define CRYPTO_MULT_MID CONFIG_GET(number/crypto_multiplier_mid) +#define CRYPTO_MULT_MAX CONFIG_GET(number/crypto_multiplier_max) +#define CRYPTO_HEATING_POWER CONFIG_GET(number/crypto_heat_power) +#define CRYPTO_IGNORE_ATMOS CONFIG_GET(flag/crypto_ignore_atmos) + /obj/machinery/cryptominer name = "cryptocurrency miner" desc = "This handy-dandy machine will produce credits for your enjoyment." @@ -12,11 +31,6 @@ var/mining = FALSE var/miningtime = 3000 var/miningpoints = 50 - var/mintemp = TCRYO // 225K equals approximately -55F or -48C - var/midtemp = T0C // 273K equals 32F or 0C - var/maxtemp = 500 // 500K equals approximately 440F or 226C - var/heatingPower = 100 // Heat added each processing - var/require_conductivity = TRUE // Prevent use in space var/datum/bank_account/pay_me = null /obj/machinery/cryptominer/Initialize(mapload) @@ -59,7 +73,7 @@ return to_chat(user, span_notice("You link \the [CARD] to \the [src].")) pay_me = CARD.registered_account - say("Now using [pay_me.account_holder ? "[pay_me.account_holder]'s" : span_boldwarning("ERROR")] account.") + say("Now using [pay_me.account_holder ? "[pay_me.account_holder]s" : span_boldwarning("ERROR")] account.") return /obj/machinery/cryptominer/AltClick(mob/user) @@ -68,13 +82,13 @@ balloon_alert(user, "resetting") if(do_after(user, 5 SECONDS, target = src)) pay_me = SSeconomy.get_dep_account(ACCOUNT_CAR) - say("Now using [pay_me.account_holder]'s account.") + say("Now using [pay_me.account_holder]s account.") /obj/machinery/cryptominer/examine(mob/user) . = ..() if(in_range(user, src) || isobserver(user)) - . += span_notice("A little screen on the machine reads: Currently the linked bank account is [pay_me.account_holder ? "[pay_me.account_holder]'s" : span_boldwarning("ERROR")].") - . += "Modify the destination of the credits using your id on it while it is inactive and has it's panel open." + . += span_notice("A little screen on the machine reads: Currently the linked bank account is [pay_me.account_holder ? "[pay_me.account_holder]s" : span_boldwarning("ERROR")].") + . += "Modify the destination of the credits using your id on it while it is inactive and has its panel open." . += "Alt-Click to reset to the Cargo budget." /obj/machinery/cryptominer/process() @@ -85,18 +99,19 @@ // Check for tiles with no conductivity (space) if(T.thermal_conductivity == 0) + // Cheat mode: Skip all atmos code and give points + // Placed first, as servers are more likely to use it + if(CRYPTO_IGNORE_ATMOS) + produce_points(CRYPTO_MULT_MAX) + return + // Normal mode: Warn the user and stop processing - if(require_conductivity) + else say("Invalid atmospheric conditions detected! Shutting off!") playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) set_mining(FALSE) return - // Cheat mode: Skip all atmos code and give points - else - produce_points(3) - return - // Get air var/datum/gas_mixture/env = T.return_air() if(!env) @@ -105,24 +120,29 @@ // Get temp var/env_temp = env.return_temperature() + // Define temperature settings + var/temp_min = CRYPTO_TEMP_MIN // 225K equals approximately -55F or -48C + var/temp_mid = CRYPTO_TEMP_MID // 273K equals 32F or 0C + var/temp_max = CRYPTO_TEMP_MAX // 500K equals approximately 440F or 226C + // Check for temperature effects // Minimum (most likely) - if(env_temp <= mintemp) - produce_points(3) + if(env_temp <= temp_min) + produce_points(CRYPTO_MULT_MAX) // Mid - else if((env_temp <= midtemp) && (env_temp >= mintemp)) - produce_points(1) + else if((env_temp <= temp_mid) && (env_temp >= temp_min)) + produce_points(CRYPTO_MULT_MID) // Maximum - else if((env_temp <= maxtemp) && (env_temp >= midtemp)) - produce_points(0.20) + else if((env_temp <= temp_max) && (env_temp >= temp_mid)) + produce_points(CRYPTO_MULT_MIN) // Overheat - else if(env_temp >= maxtemp) + else if(env_temp >= temp_max) say("Critical overheating detected! Shutting off!") playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) set_mining(FALSE) - // Increase heat by heatingPower - env.set_temperature(env_temp + heatingPower) + // Increase heat by heating_power + env.set_temperature(env_temp + CRYPTO_HEATING_POWER) // Update air air_update_turf() @@ -148,15 +168,25 @@ set_mining(TRUE) /obj/machinery/cryptominer/proc/set_mining(new_value) + // Check if status changed if(new_value == mining) return //No changes - mining = new_value - if(mining) - START_PROCESSING(SSmachines, src) - else - STOP_PROCESSING(SSmachines, src) - update_icon() + // Set status new value + mining = new_value + + // Check if mining should run + if(mining) + // Start processing + START_PROCESSING(SSmachines, src) + + // Mining should not run + else + // Stop processing + STOP_PROCESSING(SSmachines, src) + + // Update machine icon + update_icon() /obj/machinery/cryptominer/syndie name = "syndicate cryptocurrency miner" @@ -198,3 +228,21 @@ icon_state = "loop_nano" else icon_state = "on_nano" + +/* + * Some entries are currently unimplemented + * +#undef CRYPTO_POWER_USE +#undef CRYPTO_POWER_IDLE +#undef CRYPTO_POWER_ACTIVE +#undef CRYPTO_MININGTIME +#undef CRYPTO_MININGPOINTS +*/ +#undef CRYPTO_TEMP_MIN +#undef CRYPTO_TEMP_MID +#undef CRYPTO_TEMP_MAX +#undef CRYPTO_MULT_MIN +#undef CRYPTO_MULT_MID +#undef CRYPTO_MULT_MAX +#undef CRYPTO_HEATING_POWER +#undef CRYPTO_IGNORE_ATMOS diff --git a/modular_sand/code/game/objects/items/plushes.dm b/modular_sand/code/game/objects/items/plushes.dm index 9ed4c6f90c..fb50c80ce9 100644 --- a/modular_sand/code/game/objects/items/plushes.dm +++ b/modular_sand/code/game/objects/items/plushes.dm @@ -15,9 +15,17 @@ if(GLOB.saliith_plushie && (GLOB.saliith_plushie != src)) return INITIALIZE_HINT_QDEL + // Appear on orbit menu + GLOB.poi_list += src + // Return normally . = ..() +/obj/item/toy/plush/lizardplushie/saliith/Destroy() + // Let's not keep the reference hanging around + GLOB.poi_list -= src + . = ..() + /obj/item/toy/plush/lizardplushie/saliith/ComponentInitialize() . = ..() @@ -70,7 +78,7 @@ // Define pronouns var/p_they = p_they() //var/p_their = p_their() - var/p_s = p_s() + var/p_s = p_s() // Check if user is Saliith himself if(user.ckey == "sandpoot") @@ -152,13 +160,13 @@ // Move grenade to the user item_grenade.forceMove(user) - + // Set the detonation time item_grenade.preprime(volume = 10) - + // Return return - + // Return normally return ..() @@ -223,7 +231,7 @@ return ..() // Pinpointer for plushie toy -/obj/item/pinpointer/plushie_saliith +/obj/item/pinpointer/plushie_saliith name = "Saliith plushie pinpointer" desc = "A handheld tracking device that locates Saliith's plushie." icon = 'modular_sand/icons/obj/device.dmi' diff --git a/modular_sand/code/modules/jobs/job_types/prisoner.dm b/modular_sand/code/modules/jobs/job_types/prisoner.dm new file mode 100644 index 0000000000..3921e11891 --- /dev/null +++ b/modular_sand/code/modules/jobs/job_types/prisoner.dm @@ -0,0 +1,3 @@ +// I'm letting you get 5 spawn positions because latejoin is broken, do not disappoint +/datum/job/prisoner + spawn_positions = 5 diff --git a/modular_sand/code/modules/mining/machine_bluespaceminer.dm b/modular_sand/code/modules/mining/machine_bluespaceminer.dm index 9241f8745e..80fd0dadd9 100644 --- a/modular_sand/code/modules/mining/machine_bluespaceminer.dm +++ b/modular_sand/code/modules/mining/machine_bluespaceminer.dm @@ -1,3 +1,7 @@ +// Configuration defines +#define BLUESPACE_MINER_BONUS_MULT CONFIG_GET(number/bluespaceminer_mult_output) +#define BLUESPACE_MINER_CRYSTAL_TIER CONFIG_GET(number/bluespaceminer_crystal_tier) + /obj/machinery/mineral/bluespace_miner name = "bluespace mining machine" desc = "A machine that uses the magic of Bluespace to slowly generate materials and add them to a linked ore silo." @@ -8,7 +12,16 @@ circuit = /obj/item/circuitboard/machine/bluespace_miner layer = BELOW_OBJ_LAYER init_process = TRUE - var/list/ore_rates = list(/datum/material/iron = 0.3, /datum/material/glass = 0.3, /datum/material/plasma = 0.1, /datum/material/silver = 0.1, /datum/material/gold = 0.05, /datum/material/titanium = 0.05, /datum/material/uranium = 0.05, /datum/material/diamond = 0.02) + var/list/ore_rates = list( + /datum/material/iron = 0.3, + /datum/material/glass = 0.3, + /datum/material/plasma = 0.1, + /datum/material/silver = 0.1, + /datum/material/gold = 0.05, + /datum/material/titanium = 0.05, + /datum/material/uranium = 0.05, + /datum/material/diamond = 0.02 + ) var/datum/component/remote_materials/materials var/multiplier = 0 //Multiplier by tier, has been made fair and everything @@ -16,11 +29,14 @@ . = ..() materials = AddComponent(/datum/component/remote_materials, "bsm", mapload) + // Set initial multiplier based on config + multiplier *= BLUESPACE_MINER_BONUS_MULT + /obj/machinery/mineral/bluespace_miner/examine(mob/user) . = ..() if(in_range(user, src) || isobserver(user)) . += span_notice("A small screen on the machine reads, \"Efficiency at [multiplier * 100]%\"") - if(multiplier >= 5) + if(multiplier >= BLUESPACE_MINER_CRYSTAL_TIER) . += span_notice("Bluespace generation is active.") if(!anchored) . += span_warning("The machine won't work while not firmly secured to the ground.") @@ -38,11 +54,14 @@ multiplier += L.rating stock_amt++ multiplier /= stock_amt - if(multiplier >= 5) + if(multiplier >= BLUESPACE_MINER_CRYSTAL_TIER) ore_rates[/datum/material/bluespace] = 0.01 else ore_rates -= /datum/material/bluespace + // Apply config multiplier here to not interfere with bluespace material check + multiplier *= BLUESPACE_MINER_BONUS_MULT + /obj/machinery/mineral/bluespace_miner/Destroy() materials = null return ..() @@ -108,3 +127,6 @@ if(default_unfasten_wrench(user, I)) return TRUE return FALSE + +#undef BLUESPACE_MINER_BONUS_MULT +#undef BLUESPACE_MINER_CRYSTAL_TIER diff --git a/tgstation.dme b/tgstation.dme index bb004258d0..064ac65d49 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1512,6 +1512,7 @@ #include "code\modules\admin\create_object.dm" #include "code\modules\admin\create_poll.dm" #include "code\modules\admin\create_turf.dm" +#include "code\modules\admin\force_event.dm" #include "code\modules\admin\fun_balloon.dm" #include "code\modules\admin\holder2.dm" #include "code\modules\admin\ipintel.dm" @@ -2217,6 +2218,7 @@ #include "code\modules\events\processor_overload.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\sentience.dm" +#include "code\modules\events\shuttle_catastrophe.dm" #include "code\modules\events\shuttle_loan.dm" #include "code\modules\events\space_dragon.dm" #include "code\modules\events\space_ninja.dm" @@ -3709,6 +3711,7 @@ #include "code\modules\tgui\states\debug.dm" #include "code\modules\tgui\states\deep_inventory.dm" #include "code\modules\tgui\states\default.dm" +#include "code\modules\tgui\states\fun.dm" #include "code\modules\tgui\states\hands.dm" #include "code\modules\tgui\states\human_adjacent.dm" #include "code\modules\tgui\states\inventory.dm" @@ -3933,6 +3936,7 @@ #include "modular_sand\code\_onclick\hud\hud.dm" #include "modular_sand\code\_onclick\hud\screen_objects.dm" #include "modular_sand\code\controllers\configuration\entries\sandstorm.dm" +#include "modular_sand\code\controllers\configuration\entries\sandstorm_balance.dm" #include "modular_sand\code\controllers\subsystem\interactions.dm" #include "modular_sand\code\controllers\subsystem\job.dm" #include "modular_sand\code\controllers\subsystem\language.dm" @@ -4122,6 +4126,7 @@ #include "modular_sand\code\modules\integrated_electronics\subtypes\output.dm" #include "modular_sand\code\modules\jobs\job_types\_job.dm" #include "modular_sand\code\modules\jobs\job_types\_job_alt_titles.dm" +#include "modular_sand\code\modules\jobs\job_types\prisoner.dm" #include "modular_sand\code\modules\keybindings\keybind\carbon.dm" #include "modular_sand\code\modules\language\dragon.dm" #include "modular_sand\code\modules\language\language.dm" diff --git a/tgui/packages/common/collections.ts b/tgui/packages/common/collections.ts index a5ccd7003e..ae3f402b13 100644 --- a/tgui/packages/common/collections.ts +++ b/tgui/packages/common/collections.ts @@ -306,3 +306,24 @@ export const zip = (...arrays: T): Zip => { export const zipWith = iterateeFn => (...arrays) => { return map(values => iterateeFn(...values))(zip(...arrays)); }; + +/** + * This method takes a collection of items and a number, returning a collection + * of collections, where the maximum amount of items in each is that second arg + */ +export const paginate = (collection: T[], maxPerPage: number): T[][] => { + const pages: T[][] = []; + let page: T[] = []; + let itemsToAdd = maxPerPage; + + for (const item of collection) { + page.push(item); + itemsToAdd--; + if (!itemsToAdd) { + itemsToAdd = maxPerPage; + pages.push(page); + page = []; + } + } + return pages; +}; diff --git a/tgui/packages/tgui/interfaces/ForceEvent.tsx b/tgui/packages/tgui/interfaces/ForceEvent.tsx new file mode 100644 index 0000000000..a486f52482 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ForceEvent.tsx @@ -0,0 +1,197 @@ +import { paginate } from 'common/collections'; +import { useBackend, useLocalState } from '../backend'; +import { Stack, Button, Icon, Input, Section, Tabs } from '../components'; +import { Window } from '../layouts'; + +const CATEGORY_PAGE_ITEMS = 4; +const EVENT_PAGE_ITEMS = 2; +const EVENT_PAGE_MAXCHARS = 48; + +/** + * Same as paginate, but respecting event names with a character max length + * that will also create a new page if created + */ +const paginateEvents = (events: Event[], maxPerPage: number): Event[][] => { + const pages: Event[][] = []; + let page: Event[] = []; + // conditions that make a new page + let itemsToAdd = maxPerPage; + let maxChars = EVENT_PAGE_MAXCHARS; + + for (const event of events) { + maxChars -= event.name.length; + if (maxChars <= 0) { + // would overflow the next line over + itemsToAdd = maxPerPage; + maxChars = EVENT_PAGE_MAXCHARS - event.name.length; + pages.push(page); + page = []; + } + page.push(event); + itemsToAdd--; + if (!itemsToAdd) { + // max amount of items we allow + itemsToAdd = maxPerPage; + maxChars = EVENT_PAGE_MAXCHARS; + pages.push(page); + page = []; + } + } + if (page.length) { + pages.push(page); + } + return pages; +}; + +type Event = { + name: string; + description: string; + type: string; + category: string; +}; + +type Category = { + name: string; + icon: string; +}; + +type ForceEventData = { + categories: Category[]; + events: Event[]; +}; + +export const ForceEvent = (props, context) => { + return ( + + + + + + + + + + + + + ); +}; + +export const PanelOptions = (props, context) => { + const [searchQuery, setSearchQuery] = useLocalState( + context, + 'searchQuery', + '' + ); + + const [announce, setAnnounce] = useLocalState(context, 'announce', true); + + return ( + + + + + + setSearchQuery(e.target.value)} + placeholder="Search..." + value={searchQuery} + /> + + + setAnnounce(!announce)}> + Announce + + + + ); +}; + +export const EventSection = (props, context) => { + const { data, act } = useBackend(context); + const { categories, events } = data; + + const [category] = useLocalState(context, 'category', categories[0]); + const [searchQuery] = useLocalState(context, 'searchQuery', ''); + const [announce] = useLocalState(context, 'announce', true); + + const preparedEvents = paginateEvents( + events.filter((event) => { + // remove events not in the category you're looking at + if (!searchQuery && event.category !== category.name) { + return false; + } + // remove events not being searched for, if a search is active + if (searchQuery && !event.name.toLowerCase().includes(searchQuery)) { + return false; + } + return true; + }), + EVENT_PAGE_ITEMS + ); + + const sectionTitle = searchQuery ? 'Searching...' : category.name + ' Events'; + + return ( +
}> + + {preparedEvents.map((eventPage, i) => ( + + + {eventPage.map((event) => ( + + + + ))} + + + ))} + +
+ ); +}; + +export const EventTabs = (props, context) => { + const { data } = useBackend(context); + const { categories } = data; + + const [category, setCategory] = useLocalState( + context, + 'category', + categories[0] + ); + + const layerCats = paginate(categories, CATEGORY_PAGE_ITEMS); + + return ( +
+ {layerCats.map((page, i) => ( + + {page.map((cat) => ( + setCategory(cat)}> + {cat.name} + + ))} + + ))} +
+ ); +}; diff --git a/tgui/packages/tgui/layouts/NtosWindow.js b/tgui/packages/tgui/layouts/NtosWindow.js index 5c282c369a..b6a0146431 100644 --- a/tgui/packages/tgui/layouts/NtosWindow.js +++ b/tgui/packages/tgui/layouts/NtosWindow.js @@ -28,7 +28,7 @@ export const NtosWindow = (props, context) => { PC_stationtime, PC_programheaders = [], PC_showexitprogram, - PC_showpeneject, + TABLET_show_pen_eject, } = data; return ( { src={resolveAsset(PC_apclinkicon)} /> )} - {!!PC_showpeneject && ( + {!!TABLET_show_pen_eject && (