From cd4c446655e121b54c0607cc2888639379dd5bcd Mon Sep 17 00:00:00 2001 From: "tgstation-server-ci[bot]" <161980869+tgstation-server-ci[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 00:52:35 +0000 Subject: [PATCH 001/135] Update TGS DMAPI --- code/__DEFINES/tgs.dm | 2 +- code/modules/tgs/v5/__interop_version.dm | 2 +- code/modules/tgs/v5/_defines.dm | 1 + code/modules/tgs/v5/topic.dm | 4 +++- code/modules/tgs/v5/undefs.dm | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index 4766b3dfe661e..42f2d5fc31fee 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,7 +1,7 @@ // tgstation-server DMAPI // The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119. -#define TGS_DMAPI_VERSION "7.2.1" +#define TGS_DMAPI_VERSION "7.3.0" // All functions and datums outside this document are subject to change with any version and should not be relied on. diff --git a/code/modules/tgs/v5/__interop_version.dm b/code/modules/tgs/v5/__interop_version.dm index f4806f7adb97c..29ea239ad84db 100644 --- a/code/modules/tgs/v5/__interop_version.dm +++ b/code/modules/tgs/v5/__interop_version.dm @@ -1 +1 @@ -"5.9.0" +"5.10.0" diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm index 92c7a8388a711..a47bfd78000bc 100644 --- a/code/modules/tgs/v5/_defines.dm +++ b/code/modules/tgs/v5/_defines.dm @@ -95,6 +95,7 @@ #define DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION "newServerVersion" #define DMAPI5_TOPIC_PARAMETER_BROADCAST_MESSAGE "broadcastMessage" +#define DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT "clientCount" #define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE "commandResponse" #define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE "commandResponseMessage" #define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses" diff --git a/code/modules/tgs/v5/topic.dm b/code/modules/tgs/v5/topic.dm index e1f2cb6385789..59e5e63e5cd42 100644 --- a/code/modules/tgs/v5/topic.dm +++ b/code/modules/tgs/v5/topic.dm @@ -149,7 +149,9 @@ if(DMAPI5_TOPIC_COMMAND_HEALTHCHECK) if(event_handler && event_handler.receive_health_checks) event_handler.HandleEvent(TGS_EVENT_HEALTH_CHECK) - return TopicResponse() + var/list/health_check_response = TopicResponse() + health_check_response[DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT] = TGS_CLIENT_COUNT + return health_check_response; if(DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH) detached = FALSE diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm index 237207fdfd056..acd19dfa6411c 100644 --- a/code/modules/tgs/v5/undefs.dm +++ b/code/modules/tgs/v5/undefs.dm @@ -18,7 +18,6 @@ #undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER #undef DMAPI5_PARAMETER_CUSTOM_COMMANDS -#undef DMAPI5_PARAMETER_TOPIC_PORT #undef DMAPI5_CHUNK #undef DMAPI5_CHUNK_PAYLOAD @@ -95,6 +94,7 @@ #undef DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION #undef DMAPI5_TOPIC_PARAMETER_BROADCAST_MESSAGE +#undef DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT #undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE #undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE #undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES From 44f12e432dfed920d3ce72c0dd10a19a7f3a7b3e Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 19:06:08 +0300 Subject: [PATCH 002/135] =?UTF-8?q?=D0=A7=D0=95=D0=A0=D0=9D=D0=90=D0=AF=20?= =?UTF-8?q?=D0=9E=D0=A0=D0=91=D0=98=D0=A2=D0=90=20=D0=A1=20=D0=9A=D0=A3?= =?UTF-8?q?=D0=A7=D0=95=D0=99=20=D0=90=D0=9D=D0=A2=D0=90=D0=93=D0=9E=D0=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/dynamic/dynamic.dm | 4 +- .../subsystem/persistence/_persistence.dm | 2 + code/controllers/subsystem/statpanel.dm | 1 + code/controllers/subsystem/ticker.dm | 10 +- code/modules/admin/admin.dm | 9 +- code/modules/admin/topic.dm | 3 +- code/modules/events/_event.dm | 27 +- config/events.json | 13 + config/game_options.txt | 47 + modular_bandastation/modular_bandastation.dme | 2 + .../storyteller/_storyteller.dm | 4 + .../storyteller/_storyteller.dme | 45 + .../code/_defines/storyteller_config.dm | 149 +++ .../code/_defines/storyteller_defines.dm | 98 ++ .../storyteller/code/divergency_report.dm | 60 + .../storyteller/code/event_defines/_event.dm | 77 ++ .../crewset/_antagonist_event.dm | 184 +++ .../code/event_defines/crewset/changeling.dm | 15 + .../code/event_defines/crewset/heretic.dm | 20 + .../code/event_defines/crewset/malf.dm | 53 + .../code/event_defines/crewset/nuke_ops.dm | 43 + .../code/event_defines/crewset/spies.dm | 14 + .../code/event_defines/crewset/traitors.dm | 14 + .../event_defines/disabled_event_overrides.dm | 32 + .../code/event_defines/ghostset/override.dm | 30 + .../code/event_defines/ghostset/voidwalker.dm | 42 + .../code/event_defines/major/override.dm | 95 ++ .../code/event_defines/moderate/override.dm | 51 + .../code/event_defines/mundane/override.dm | 138 +++ .../code/event_defines/override_events.dm | 43 + .../storyteller/code/gamemode.dm | 1006 +++++++++++++++++ .../storyteller/code/jobs_restrictions.dm | 54 + .../storyteller/code/scheduled_event.dm | 96 ++ .../code/storytellers/data/tracks.dm | 10 + .../code/storytellers/tellers/_storyteller.dm | 141 +++ .../storytellers/tellers/storyteller_bomb.dm | 17 + .../storytellers/tellers/storyteller_chill.dm | 22 + .../storytellers/tellers/storyteller_clown.dm | 24 + .../tellers/storyteller_default.dm | 6 + .../tellers/storyteller_extended.dm | 8 + .../tellers/storyteller_fragile.dm | 22 + .../storytellers/tellers/storyteller_gamer.dm | 20 + modular_bandastation/storyteller/code/vote.dm | 68 ++ .../storyteller/code/vote_reminder.dm | 36 + 44 files changed, 2845 insertions(+), 10 deletions(-) create mode 100644 config/events.json create mode 100644 modular_bandastation/storyteller/_storyteller.dm create mode 100644 modular_bandastation/storyteller/_storyteller.dme create mode 100644 modular_bandastation/storyteller/code/_defines/storyteller_config.dm create mode 100644 modular_bandastation/storyteller/code/_defines/storyteller_defines.dm create mode 100644 modular_bandastation/storyteller/code/divergency_report.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/_event.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/malf.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/spies.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/override.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/major/override.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/moderate/override.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/mundane/override.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/override_events.dm create mode 100644 modular_bandastation/storyteller/code/gamemode.dm create mode 100644 modular_bandastation/storyteller/code/jobs_restrictions.dm create mode 100644 modular_bandastation/storyteller/code/scheduled_event.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/data/tracks.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm create mode 100644 modular_bandastation/storyteller/code/vote.dm create mode 100644 modular_bandastation/storyteller/code/vote_reminder.dm diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index 1134230db3600..facf8ff2a2a3a 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -321,7 +321,7 @@ SUBSYSTEM_DEF(dynamic) SSticker.news_report = SSshuttle.emergency?.is_hijacked() ? SHUTTLE_HIJACK : STATION_EVACUATED /datum/controller/subsystem/dynamic/proc/send_intercept() - if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready + /*if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready addtimer(CALLBACK(src, PROC_REF(send_intercept)), 10 SECONDS) return @@ -376,7 +376,7 @@ SUBSYSTEM_DEF(dynamic) priority_announce("Отчет был скопирован и распечатан на всех консолях связи.", "Отчет о безопасности", SSstation.announcer.get_rand_report_sound()) // BANDASTATION EDIT END - No Blue roundstart #endif - + */ // BANDASTATION EDIT END - Storyteller return . /// Generate the advisory level depending on the shown threat level. diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index d38d7fa372e25..fac49c6882c7d 100644 --- a/code/controllers/subsystem/persistence/_persistence.dm +++ b/code/controllers/subsystem/persistence/_persistence.dm @@ -48,6 +48,7 @@ SUBSYSTEM_DEF(persistence) var/tram_hits_this_round = 0 var/tram_hits_last_round = 0 + var/last_storyteller_type = "" // BANDASTATION EDIT ADD: Storyteller votes /// A json database to data/message_bottles.json var/datum/json_database/message_bottles_database /// An index used to create unique ids for the message bottles database @@ -71,6 +72,7 @@ SUBSYSTEM_DEF(persistence) load_delamination_counter() load_tram_counter() load_adventures() + load_storyteller_type() // BANDASTATION EDIT ADD - Storyteller return SS_INIT_SUCCESS ///Collects all data to persist. diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index cf158586ce497..3ab186a4143a2 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -26,6 +26,7 @@ SUBSYSTEM_DEF(statpanels) global_data = list( "Map: [SSmapping.current_map?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, + "Storyteller: [SSgamemode.storyteller ? SSgamemode.storyteller.name : "N/A"]", // BANDASTATION EDIT ADDITION "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", "Round Time: [ROUND_TIME()]", diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index bb18a45b72d9a..92111de584176 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -159,6 +159,7 @@ SUBSYSTEM_DEF(ticker) to_chat(world, span_notice("Welcome to [station_name()]!")) send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.current_map.map_name]!"), CONFIG_GET(string/channel_announce_new_game)) current_state = GAME_STATE_PREGAME + SSvote.initiate_vote(/datum/vote/storyteller, "Storyteller Vote", forced = TRUE) // BANDASTATION EDIT ADDITION SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) fire() @@ -232,7 +233,13 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK //Configure mode and assign player to antagonists var/can_continue = FALSE - can_continue = SSdynamic.pre_setup() //Choose antagonists + + // can_continue = SSdynamic.pre_setup() //Choose antagonists // BANDASTATION EDIT - STORYTELLER (note: maybe disable) + // BANDASTATION EDIT BEGIN - STORYTELLER + SSgamemode.init_storyteller() + can_continue = SSgamemode.pre_setup() + // BANDASTATION EDIT END - STORYTELLER + CHECK_TICK SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_JOBS_ASSIGNED, src) can_continue = can_continue && SSjob.divide_occupations() //Distribute jobs @@ -299,6 +306,7 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE SSdynamic.post_setup() + SSgamemode.post_setup() // BANDASTATION EDIT - Storyteller GLOB.start_state = new /datum/station_state() GLOB.start_state.count() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5f40de037f4ae..b9f4b1036c53d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -21,8 +21,11 @@ var/dat = "
Game Panel

" if(SSticker.current_state <= GAME_STATE_PREGAME) - dat += "(Manage Dynamic Rulesets)
" - dat += "(Force Roundstart Rulesets)
" + // BANDASTATION EDIT START - STORYTELLER + //dat += "(Manage Dynamic Rulesets)
" + //dat += "(Force Roundstart Rulesets)
" + dat += "(Game Mode Panel)
" + // BANDASTATION EDIT END if (GLOB.dynamic_forced_roundstart_ruleset.len > 0) for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) dat += {"-> [rule.name] <-
"} @@ -31,7 +34,7 @@ dat += "
" if(SSticker.IsRoundInProgress()) dat += "(Game Mode Panel)
" - dat += "(Manage Dynamic Rulesets)
" + //dat += "(Manage Dynamic Rulesets)
" BANDASTATION EDIT - STORYTELLER dat += {"
Create Object
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 6a2666eef9bed..1ddec84716730 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -69,7 +69,8 @@ else if(href_list["gamemode_panel"]) if(!check_rights(R_ADMIN)) return - SSdynamic.admin_panel() + //SSdynamic.admin_panel() // BANDASTATION EDIT - STORYTELLER + SSgamemode.admin_panel(usr) // BANDASTATION EDIT - STORYTELLER else if(href_list["call_shuttle"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a1e8aef5b6c91..374e8fa0d88b0 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -1,4 +1,5 @@ -#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (10 SECONDS) +// #define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (10 SECONDS) +#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (2 MINUTES) // BANDASTATION EDIT CHANGE - STORYTELLER (взято с буббера как настройка скайрата, возможно стоит снести именно это изменение?) //this singleton datum is used by the events controller to dictate how it selects events /datum/round_event_control @@ -74,7 +75,8 @@ SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) return FALSE - if(earliest_start >= world.time-SSticker.round_start_time) + //if(earliest_start >= world.time-SSticker.round_start_time) // BANDASTATION EDIT - STORYTELLER + if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) // BANDASTATION EDIT: Roundstart checks added return FALSE if(!allow_magic && wizardevent != SSevents.wizardmode) return FALSE @@ -102,8 +104,27 @@ triggering = TRUE // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. - message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") + //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") // BANDASTATION EDIT - STORYTELLER + // BANDASTATION EDIT START - Only delay on roundstart + if(SSticker.HasRoundStarted()) + message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ + CANCEL | \ + SOMETHING ELSE)") + for(var/client/staff as anything in GLOB.admins) + if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) + SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) + sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) + + if(triggering) + message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ + CANCEL | \ + SOMETHING ELSE)") + sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) + else + message_admins(" Roundstart event chosen: [name].") + // BANDASTATION EDIT END + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!can_spawn_event(players_amt)) message_admins("Second pre-condition check for [name] failed, rerolling...") diff --git a/config/events.json b/config/events.json new file mode 100644 index 0000000000000..a30ccaf58ab53 --- /dev/null +++ b/config/events.json @@ -0,0 +1,13 @@ +{ + "/datum/round_event_control": + { + "weight" : 10, + "min_players" : 0, + "max_occurrences" : 100, + "earliest_start" : 20, + "track" : "Moderate", + "cost" : 1, + "reoccurence_penalty_multiplier" : 1, + "shared_occurence_type" : null + } +} diff --git a/config/game_options.txt b/config/game_options.txt index 8300cdcac8cef..0ca4d97b7efc7 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -559,3 +559,50 @@ MAX_POSITIVE_QUIRKS 6 # If the value is lower than 1, it'll tend to even out the odds # If higher than 1, it'll lean toward common spawns even more. RANDOM_LOOT_WEIGHT_MODIFIER 1 + +## Gamemode configurations + +## Multipliers for points gained over time for event tracks. +MUNDANE_POINT_GAIN_MULTIPLIER 1 +MODERATE_POINT_GAIN_MULTIPLIER 1 +MAJOR_POINT_GAIN_MULTIPLIER 1 +ROLESET_POINT_GAIN_MULTIPLIER 1 +OBJECTIVES_POINT_GAIN_MULTIPLIER 1 + +## Multipliers for points to spend on roundstart events. +MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 +MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 +MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 +ROLESET_ROUNDSTART_POINT_MULTIPLIER 1 +OBJECTIVES_ROUNDSTART_POINT_MULTIPLIER 1 + +## Minimum population caps for event tracks to run their events. +MUNDANE_MIN_POP 0 +MODERATE_MIN_POP 0 +MAJOR_MIN_POP 0 +ROLESET_MIN_POP 0 +OBJECTIVES_MIN_POP 0 + +## Point thresholds for tracks to run events. The lesser the more frequent events will be. +MUNDANE_POINT_THRESHOLD 25 +MODERATE_POINT_THRESHOLD 50 +MAJOR_POINT_THRESHOLD 90 +ROLESET_POINT_THRESHOLD 120 +OBJECTIVES_POINT_THRESHOLD 130 + +## Allows the storyteller to scale event frequencies based on population +ALLOW_STORYTELLER_POP_SCALING + +## Thresholds that population frequency scalling penalize up to. +MUNDANE_POP_SCALE_THRESHOLD 10 +MODERATE_POP_SCALE_THRESHOLD 15 +MAJOR_POP_SCALE_THRESHOLD 40 +ROLESET_POP_SCALE_THRESHOLD 45 +OBJECTIVES_POP_SCALE_THRESHOLD 40 + +## The maximum penalties population scalling will apply to the tracks for having less pop than POP_SCALE_THRESHOLD. This is treated as percentages +MUNDANE_POP_SCALE_PENALTY 30 +MODERATE_POP_SCALE_PENALTY 30 +MAJOR_POP_SCALE_PENALTY 30 +ROLESET_POP_SCALE_PENALTY 30 +OBJECTIVES_POP_SCALE_PENALTY 30 diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme index bdbaf6b8311a6..7458f5cd11c2c 100644 --- a/modular_bandastation/modular_bandastation.dme +++ b/modular_bandastation/modular_bandastation.dme @@ -35,3 +35,5 @@ #include "preferences/_preferences.dme" #include "jukebox/_jukebox.dme" #include "objects/_objects.dme" +#include "overrides/_overrides.dme" +#include "storyteller/_storyteller.dme" diff --git a/modular_bandastation/storyteller/_storyteller.dm b/modular_bandastation/storyteller/_storyteller.dm new file mode 100644 index 0000000000000..4e98148703137 --- /dev/null +++ b/modular_bandastation/storyteller/_storyteller.dm @@ -0,0 +1,4 @@ +/datum/modpack/jukebox + name = "Storyteller mode" + desc = "Адаптация режиме сторителлера для Bandastation." + author = "Хто-то" diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme new file mode 100644 index 0000000000000..ade7c2e82f5da --- /dev/null +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -0,0 +1,45 @@ +#include "_storyteller.dm" + +#include "code\_defines\storyteller_defines.dm" +#include "code\_defines\storyteller_config.dm" + +#include "code\event_defines\crewset\_antagonist_event.dm" +#include "code\event_defines\crewset\changeling.dm" +#include "code\event_defines\crewset\heretic.dm" +#include "code\event_defines\crewset\malf.dm" +#include "code\event_defines\crewset\nuke_ops.dm" +#include "code\event_defines\crewset\spies.dm" +#include "code\event_defines\crewset\traitors.dm" + +#include "code\event_defines\ghostset\override.dm" +#include "code\event_defines\ghostset\voidwalker.dm" + +#include "code\event_defines\major\override.dm" +#include "code\event_defines\moderate\override.dm" +#include "code\event_defines\mundane\override.dm" + +#include "code\storytellers\data\tracks.dm" +#include "code\storytellers\tellers\_storyteller.dm" +#include "code\storytellers\tellers\storyteller_bomb.dm" +#include "code\storytellers\tellers\storyteller_chill.dm" +#include "code\storytellers\tellers\storyteller_clown.dm" +#include "code\storytellers\tellers\storyteller_default.dm" +#include "code\storytellers\tellers\storyteller_extended.dm" +#include "code\storytellers\tellers\storyteller_fragile.dm" +#include "code\storytellers\tellers\storyteller_gamer.dm" + +#include "code\divergency_report.dm" +#include "code\scheduled_event.dm" +#include "code\vote_reminder.dm" +#include "code\vote.dm" +#include "code\jobs_restrictions.dm" +#include "code\gamemode.dm" + +#include "code\event_defines\_event.dm" +#include "code\event_defines\override_events.dm" +#include "code\event_defines\disabled_event_overrides.dm" + + + + + diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm new file mode 100644 index 0000000000000..b3c08c1fc81bb --- /dev/null +++ b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm @@ -0,0 +1,149 @@ +///Gamemode related configs below +// Point Gain Multipliers +/datum/config_entry/number/mundane_point_gain_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/moderate_point_gain_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/major_point_gain_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/crewset_point_gain_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/ghostset_point_gain_multiplier + config_entry_value = 1 + min_val = 0 + +// Roundstart points Multipliers +/datum/config_entry/number/mundane_roundstart_point_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/moderate_roundstart_point_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/major_roundstart_point_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/crewset_roundstart_point_multiplier + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/number/ghostset_roundstart_point_multiplier + config_entry_value = 1 + min_val = 0 + +// Minimum population +/datum/config_entry/number/mundane_min_pop + config_entry_value = MUNDANE_MIN_POP + integer = TRUE + min_val = 0 + +/datum/config_entry/number/moderate_min_pop + config_entry_value = MODERATE_MIN_POP + integer = TRUE + min_val = 0 + +/datum/config_entry/number/major_min_pop + config_entry_value = MAJOR_MIN_POP + integer = TRUE + min_val = 0 + +/datum/config_entry/number/crewset_min_pop + config_entry_value = CREWSET_MIN_POP + integer = TRUE + min_val = 0 + +/datum/config_entry/number/ghostset_min_pop + config_entry_value = GHOSTSET_MIN_POP + integer = TRUE + min_val = 0 + +// Point Thresholds +/datum/config_entry/number/mundane_point_threshold + config_entry_value = MUNDANE_POINT_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/moderate_point_threshold + config_entry_value = MODERATE_POINT_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/major_point_threshold + config_entry_value = MAJOR_POINT_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/crewset_point_threshold + config_entry_value = CREWSET_POINT_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/ghostset_point_threshold + config_entry_value = GHOSTSET_POINT_THRESHOLD + integer = TRUE + min_val = 0 + + +/datum/config_entry/flag/allow_storyteller_pop_scaling // Allows storyteller to scale down the event frequency by population + +// Pop scalling thresholds +/datum/config_entry/number/mundane_pop_scale_threshold + config_entry_value = MUNDANE_POP_SCALE_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/moderate_pop_scale_threshold + config_entry_value = MODERATE_POP_SCALE_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/major_pop_scale_threshold + config_entry_value = MAJOR_POP_SCALE_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/crewset_pop_scale_threshold + config_entry_value = CREWSET_POP_SCALE_THRESHOLD + integer = TRUE + min_val = 0 + +/datum/config_entry/number/ghostset_pop_scale_threshold + config_entry_value = GHOSTSET_POP_SCALE_THRESHOLD + integer = TRUE + min_val = 0 + +// Pop scalling penalties +/datum/config_entry/number/mundane_pop_scale_penalty + config_entry_value = MUNDANE_POP_SCALE_PENALTY + integer = TRUE + min_val = 0 + +/datum/config_entry/number/moderate_pop_scale_penalty + config_entry_value = MODERATE_POP_SCALE_PENALTY + integer = TRUE + min_val = 0 + +/datum/config_entry/number/major_pop_scale_penalty + config_entry_value = MAJOR_POP_SCALE_PENALTY + integer = TRUE + min_val = 0 + +/datum/config_entry/number/crewset_pop_scale_penalty + config_entry_value = CREWSET_POP_SCALE_PENALTY + integer = TRUE + min_val = 0 + +/datum/config_entry/number/ghostset_pop_scale_penalty + config_entry_value = GHOSTSET_POP_SCALE_PENALTY + integer = TRUE + min_val = 0 diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm new file mode 100644 index 0000000000000..6ea31c3bace3d --- /dev/null +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -0,0 +1,98 @@ +//Could be bitflags, but that would require a good amount of translations, which eh, either way works for me +/// When the event is combat oriented (spawning monsters, inherently hostile antags) +#define TAG_COMBAT "combat" +/// When the event is spooky (broken lights, some antags) +#define TAG_SPOOKY "spooky" +/// When the event is destructive in a decent capacity (meteors, blob) +#define TAG_DESTRUCTIVE "destructive" +/// When the event impacts most of the crewmembers in some capacity (comms blackout) +#define TAG_COMMUNAL "communal" +/// When the event targets a person for something (appendix, heart attack) +#define TAG_TARGETED "targeted" +/// When the event is positive and helps the crew, in some capacity (Shuttle Loan, Supply Pod) +#define TAG_POSITIVE "positive" +/// When one of the crewmembers becomes an antagonist +#define TAG_CREW_ANTAG "crew_antag" +/// When the antagonist event is focused around team cooperation. +#define TAG_TEAM_ANTAG "team_antag" +/// When one of the non-crewmember players becomes an antagonist +#define TAG_OUTSIDER_ANTAG "away_antag" +/// When the event is considered chaotic by a completely non-biased coder. +#define TAG_CHAOTIC "chaotic" +/// When the event impacts the overmap +#define TAG_OVERMAP "overmap" +/// When the event requires the station to be in space (meteors, carp) +#define TAG_SPACE "space" +/// When the event requires the station to be on planetary. +#define TAG_PLANETARY "planetary" + + +#define EVENT_TRACK_MUNDANE "Mundane" +#define EVENT_TRACK_MODERATE "Moderate" +#define EVENT_TRACK_MAJOR "Major" +#define EVENT_TRACK_CREWSET "Crewset" +#define EVENT_TRACK_GHOSTSET "Ghostset" + +#define ALL_EVENTS "All" +#define UNCATEGORIZED_EVENTS "Uncategorized" + +#define STORYTELLER_WAIT_TIME 20 SECONDS + +#define EVENT_POINT_GAINED_PER_SECOND 0.05 + +#define TRACK_FAIL_POINT_PENALTY_MULTIPLIER 0.5 + +#define GAMEMODE_PANEL_MAIN "Main" +#define GAMEMODE_PANEL_VARIABLES "Variables" + +/// Reused for multipliers of the thresholds +#define MUNDANE_POINT_THRESHOLD 1 +#define MODERATE_POINT_THRESHOLD 1 +#define MAJOR_POINT_THRESHOLD 1 +#define CREWSET_POINT_THRESHOLD 1 +#define GHOSTSET_POINT_THRESHOLD 1 + +#define MUNDANE_MIN_POP 0 +#define MODERATE_MIN_POP 0 +#define MAJOR_MIN_POP 20 +#define CREWSET_MIN_POP 0 +#define GHOSTSET_MIN_POP 0 + +/// Defines for how much pop do we need to stop applying a pop scalling penalty to event frequency. +#define MUNDANE_POP_SCALE_THRESHOLD 25 +#define MODERATE_POP_SCALE_THRESHOLD 32 +#define MAJOR_POP_SCALE_THRESHOLD 45 +#define CREWSET_POP_SCALE_THRESHOLD 45 +#define GHOSTSET_POP_SCALE_THRESHOLD 45 + +/// The maximum penalty coming from pop scalling, when we're at the most minimum point, easing into 0 as we reach the SCALE_THRESHOLD. This is treated as a percentage. +#define MUNDANE_POP_SCALE_PENALTY 35 +#define MODERATE_POP_SCALE_PENALTY 35 +#define MAJOR_POP_SCALE_PENALTY 35 +#define CREWSET_POP_SCALE_PENALTY 35 +#define GHOSTSET_POP_SCALE_PENALTY 35 + +#define STORYTELLER_VOTE "storyteller" + +#define EVENT_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_CREWSET, EVENT_TRACK_GHOSTSET) +#define EVENT_PANEL_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_CREWSET, EVENT_TRACK_GHOSTSET, UNCATEGORIZED_EVENTS, ALL_EVENTS) + +/// Defines for the antag cap to prevent midround injections. +#define ANTAG_CAP_FLAT 1 +#define ANTAG_CAP_DENOMINATOR 9 + +///Below are defines for the percentage fill that the tracks should start on. +- 50% of the value will be added +#define ROUNDSTART_MUNDANE_BASE 20 + +#define ROUNDSTART_MODERATE_BASE 35 + +#define ROUNDSTART_MAJOR_BASE 40 + +#define ROUNDSTART_CREWSET_BASE 60 + +#define ROUNDSTART_GHOSTSET_BASE 40 + +/// Storyteller types below, basically prevents several intense teller rounds in a row +#define STORYTELLER_TYPE_ALWAYS_AVAILABLE 0 +#define STORYTELLER_TYPE_CALM 1 +#define STORYTELLER_TYPE_INTENSE 2 diff --git a/modular_bandastation/storyteller/code/divergency_report.dm b/modular_bandastation/storyteller/code/divergency_report.dm new file mode 100644 index 0000000000000..947dbaa158f73 --- /dev/null +++ b/modular_bandastation/storyteller/code/divergency_report.dm @@ -0,0 +1,60 @@ +/datum/controller/subsystem/gamemode/proc/send_trait_report() + . = "Central Command Status Summary
" + SSstation.generate_station_goals(20) + + var/list/station_goals = SSstation.get_station_goals() + + if(!length(station_goals)) + . = "
No assigned goals.
" + else + . += generate_station_goal_report(station_goals) + if(!SSstation.station_traits.len) + . = "
No identified shift divergencies.
" + else + . += generate_station_trait_report() + + . += "
This concludes your shift-start evaluation. Have a secure shift!
\ +

This label certifies an Intern has reviewed the above before sending. This document is the property of Nanotrasen Corporation.

" + + print_command_report(., "Central Command Status Summary", announce = FALSE) + priority_announce("Hello, crew of [station_name()]. Our intern has finished their shift-start divergency and goals evaluation, which has been sent to your communications console. Have a secure shift!", "Divergency Report", SSstation.announcer.get_rand_report_sound()) + + + +/* + * Generate a list of station goals available to purchase to report to the crew. + * + * Returns a formatted string all station goals that are available to the station. + */ +/datum/controller/subsystem/gamemode/proc/generate_station_goal_report(var/list/station_goals) + . = "
Special Orders for [station_name()]:
" + var/list/goal_reports = list() + for(var/datum/station_goal/station_goal as anything in station_goals) + station_goal.on_report() + goal_reports += station_goal.get_report() + + . += goal_reports.Join("
") + return +/* + * Generate a list of active station traits to report to the crew. + * + * Returns a formatted string of all station traits (that are shown) affecting the station. + */ +/datum/controller/subsystem/gamemode/proc/generate_station_trait_report() + if(!SSstation.station_traits.len) + return + . = "
Identified shift divergencies:
" + for(var/datum/station_trait/station_trait as anything in SSstation.station_traits) + if(!station_trait.show_in_report) + continue + . += "[station_trait.get_report()]
" + return + +/*/datum/controller/subsystem/gamemode/proc/generate_station_goals() + var/list/possible = subtypesof(/datum/station_goal) + var/goal_weights = 0 + while(possible.len && goal_weights < 1) // station goal budget is 1 + var/datum/station_goal/picked = pick_n_take(possible) + goal_weights += initial(picked.weight) + SSstation.goals_by_type += new picked // does this still work? +*/ diff --git a/modular_bandastation/storyteller/code/event_defines/_event.dm b/modular_bandastation/storyteller/code/event_defines/_event.dm new file mode 100644 index 0000000000000..232381eddb3b7 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/_event.dm @@ -0,0 +1,77 @@ +/datum/round_event_control + var/roundstart = FALSE + var/cost = 1 + var/reoccurence_penalty_multiplier = 0.75 + var/shared_occurence_type + var/track = EVENT_TRACK_MODERATE + /// Last calculated weight that the storyteller assigned this event + var/calculated_weight = 0 + var/tags = list() /// Tags of the event + /// List of the shared occurence types. + var/static/list/shared_occurences = list() + /// Whether a roundstart event can happen post roundstart. Very important for events which override job assignments. + var/can_run_post_roundstart = TRUE + +/datum/round_event + /// Whether the event called its start() yet or not. + var/has_started = FALSE + +/// This section of event processing is in a proc because roundstart events may get their start invoked. +/datum/round_event/proc/try_start() + if(has_started) + return + has_started = TRUE + processing = FALSE + start() + processing = TRUE + +/datum/round_event_control/roundstart + roundstart = TRUE + earliest_start = 0 + +///Adds an occurence. Has to use the setter to properly handle shared occurences +/datum/round_event_control/proc/add_occurence() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + shared_occurences[shared_occurence_type]++ + occurrences++ + +///Subtracts an occurence. Has to use the setter to properly handle shared occurences +/datum/round_event_control/proc/subtract_occurence() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + shared_occurences[shared_occurence_type]-- + occurrences-- + +///Gets occurences. Has to use the getter to properly handle shared occurences +/datum/round_event_control/proc/get_occurences() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + return shared_occurences[shared_occurence_type] + return occurrences + +/// Prints the action buttons for this event. +/datum/round_event_control/proc/get_href_actions() + if(SSticker.HasRoundStarted()) + if(roundstart) + if(!can_run_post_roundstart) + return "Fire Schedule" + return "Fire Schedule" + else + return "Fire Schedule Force Next" + else + if(roundstart) + return "Force Roundstart" + else + return "Fire Schedule Force Next" + +/datum/round_event_control/Topic(href, href_list) + . = ..() + switch(href_list["action"]) + if("force_next") + message_admins("[key_name_admin(usr)] has forced scheduled event [src.name].") + log_admin_private("[key_name(usr)] has forced scheduled event [src.name].") + SSgamemode.force_event(src) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm new file mode 100644 index 0000000000000..c1919c5c5ff10 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -0,0 +1,184 @@ +/datum/round_event_control/antagonist + reoccurence_penalty_multiplier = 0 + track = EVENT_TRACK_CREWSET + /// Protected roles from the antag roll. People will not get those roles if a config is enabled + var/protected_roles = list( + JOB_CAPTAIN, + //JOB_BLUESHIELD, + + // Heads of staff + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_QUARTERMASTER, + //JOB_NT_REP, + + // Seccies + JOB_DETECTIVE, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + //JOB_CORRECTIONS_OFFICER, + JOB_PRISONER, + //JOB_SECURITY_MEDIC, + + // Department Guards-Additional + //JOB_BOUNCER, + //JOB_ORDERLY, + //JOB_CUSTOMS_AGENT, + //JOB_ENGINEERING_GUARD, + //JOB_SCIENCE_GUARD, + ) + + /// Restricted roles from the antag roll + var/restricted_roles = list(JOB_AI, JOB_CYBORG) + + /// How many baseline antags do we spawn + var/base_antags = 1 + /// How many maximum antags can we spawn + var/maximum_antags = 2 + /// Strict limit on how many antagonists of this type that should be in this round. 0 to ignore. + var/maximum_antags_global = 0 + /// For this many players we'll add 1 up to the maximum antag amount + var/denominator = 20 + /// The antag flag to be used + var/antag_flag + /// The antag datum to be applied + var/antag_datum + + var/minimum_candidate_base = 1 + + var/list/ruleset_lazy_templates + +/datum/round_event_control/antagonist/New() + . = ..() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_roles |= protected_roles + restricted_roles |= SSstation.antag_restricted_roles + restricted_roles |= SSstation.antag_protected_roles + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_roles |= JOB_ASSISTANT + for(var/datum/job/iterating_job as anything in subtypesof(/datum/job)) + if(initial(iterating_job.restricted_antagonists)) + restricted_roles |= initial(iterating_job.title) + +/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) + . = ..() + if(!.) + return + if(!roundstart && !SSgamemode.can_inject_antags()) + return FALSE + if(!get_antag_amount()) + return FALSE + var/list/candidates = get_candidates() + if(candidates.len < get_minimum_candidates()) + return FALSE + +/datum/round_event_control/antagonist/proc/get_minimum_candidates() + return minimum_candidate_base + +/datum/round_event_control/antagonist/proc/get_candidates() + var/round_started = SSticker.HasRoundStarted() + var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = !round_started, restricted_roles = restricted_roles) + return candidates + +/datum/round_event_control/antagonist/solo + typepath = /datum/round_event/antagonist/solo + +/datum/round_event_control/antagonist/proc/get_antag_amount() + + var/people = SSgamemode.get_correct_popcount() + var/amount = base_antags + FLOOR(people / denominator, 1) + + if(antag_datum && maximum_antags_global > 0) + var/antag_slots_left = maximum_antags_global + for(var/datum/antagonist/existing_antagonist as anything in GLOB.antagonists) + if(QDELETED(existing_antagonist) || QDELETED(existing_antagonist.owner) || QDELETED(existing_antagonist.owner.current)) //This feels messy, but it just werks. + continue + if(!istype(existing_antagonist, antag_datum)) //Obviously ignore other antagonists. + continue + antag_slots_left-- //Slot is occupied. + if(antag_slots_left <= 0) //No point in checking anymore. + break + amount = min(amount, antag_slots_left) + + return min(amount, maximum_antags) + +/datum/round_event/antagonist + fakeable = FALSE + end_when = 60 //This is so prompted picking events have time to run //TODO: refactor events so they can be the masters of themselves, instead of relying on some weirdly timed vars + // ALL of those variables are internal. Check the control event to change them + /// The antag flag passed from control + var/antag_flag + /// The antag datum passed from control + var/antag_datum + /// The antag count passed from control + var/antag_count + /// The restricted roles (jobs) passed from control + var/list/restricted_roles + /// The minds we've setup in setup() and need to finalize in start() + var/list/setup_minds = list() + +/datum/round_event/antagonist/solo + +/datum/round_event/antagonist/setup() + load_vars(control) + candidate_setup(control) + template_setup(control) + +/datum/round_event/antagonist/proc/load_vars(datum/round_event_control/antagonist/cast_control) + // Set up all the different variables on the round_event. God isn't it ugly + // Maybe move this to New() if possible? ~Waterpig + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + antag_count = cast_control.get_antag_amount() + restricted_roles = cast_control.restricted_roles + +/datum/round_event/antagonist/proc/candidate_setup(datum/round_event_control/antagonist/cast_control) + var/list/candidates = cast_control.get_candidates() + for(var/i in 1 to antag_count) + if(!candidates.len) + break + var/mob/candidate = pick_n_take(candidates) + setup_minds += candidate.mind + candidate_roles_setup(candidate) + +/datum/round_event/antagonist/proc/candidate_roles_setup(mob/candidate) + SHOULD_CALL_PARENT(FALSE) + + candidate.mind.special_role = antag_flag + candidate.mind.restricted_roles = restricted_roles + +/datum/round_event/antagonist/proc/template_setup(datum/round_event_control/antagonist/cast_control) + for(var/template in cast_control.ruleset_lazy_templates) + SSmapping.lazy_load_template(template) + +/datum/round_event/antagonist/solo/start() + for(var/datum/mind/antag_mind as anything in setup_minds) + add_datum_to_mind(antag_mind) + +/datum/round_event/antagonist/proc/add_datum_to_mind(datum/mind/antag_mind) + antag_mind.add_antag_datum(antag_datum) + +/datum/round_event_control/antagonist/team + typepath = /datum/round_event/antagonist/team + minimum_candidate_base = 1 + + var/antag_leader_datum + +/datum/round_event_control/antagonist/team/New() + . = ..() + if(isnull(antag_leader_datum)) + antag_leader_datum = antag_datum + +/datum/round_event/antagonist/team + var/antag_leader_datum + +/datum/round_event/antagonist/team/start() + for(var/datum/mind/antag_mind as anything in setup_minds) + add_datum_to_mind(antag_mind) + +/datum/round_event/antagonist/team/load_vars(datum/round_event_control/antagonist/team/cast_control) + . = ..() + antag_leader_datum = cast_control.antag_leader_datum diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm new file mode 100644 index 0000000000000..aa39cf7f451e6 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -0,0 +1,15 @@ +/datum/round_event_control/antagonist/solo/changeling + name = "Changelings" + roundstart = TRUE + + antag_flag = ROLE_CHANGELING + antag_datum = /datum/antagonist/changeling + weight = 8 + min_players = 20 + maximum_antags_global = 4 + + tags = list(TAG_COMBAT, TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/changeling/midround + name = "Genome Awakening (Changelings)" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm new file mode 100644 index 0000000000000..60516d48d28c7 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -0,0 +1,20 @@ +/datum/round_event_control/antagonist/solo/heretic + name = "Heretics" + roundstart = TRUE + + antag_flag = ROLE_HERETIC + antag_datum = /datum/antagonist/heretic + weight = 3 + min_players = 30 + + maximum_antags_global = 2 + + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/heretic/New() + protected_roles |= JOB_CHAPLAIN // Would be silly to get chaplain heretics + . = ..() + +/datum/round_event_control/antagonist/solo/heretic/midround + name = "Midround Heretics" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm new file mode 100644 index 0000000000000..d8007587c4cbd --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -0,0 +1,53 @@ + +/datum/round_event_control/antagonist/solo/malf + name = "Malfunctioning AI Midround" + + base_antags = 1 + maximum_antags = 1 + maximum_antags_global = 1 + + min_players = 20 + roundstart = FALSE + + antag_datum = /datum/antagonist/malf_ai + antag_flag = ROLE_MALF + weight = 1 + tags = list(TAG_CREW_ANTAG, TAG_COMBAT, TAG_DESTRUCTIVE, TAG_CHAOTIC) + restricted_roles = list() + +/datum/round_event_control/antagonist/solo/malf/get_candidates() + return GLOB.ai_list + +/datum/round_event_control/antagonist/solo/malf/roundstart + name = "Malfunctioning AI" + + roundstart = TRUE + typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart + weight = 10 + +// God has abandoned us +/datum/round_event_control/antagonist/solo/malf/roundstart/get_candidates() + var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = TRUE, restricted_roles = restricted_roles) + . = list() + var/datum/job/aijob = SSjob.get_job(JOB_AI) + for(var/mob/candidate as anything in candidates) + if(SSjob.check_job_eligibility(candidate, aijob) == JOB_AVAILABLE) + . += candidate + return . + +/datum/round_event_control/antagonist/solo/malf/roundstart/can_spawn_event(popchecks, allow_magic) + . = ..() + if(!.) + return . + + var/datum/job/ai_job = SSjob.get_job_type(/datum/job/ai) + if(!(ai_job.total_positions - ai_job.current_positions && ai_job.spawn_positions)) + return FALSE + else + return TRUE + +/datum/round_event/antagonist/solo/malf_ai/roundstart/setup() + . = ..() + for(var/datum/mind/new_malf in setup_minds) + GLOB.pre_setup_antags += new_malf + LAZYADDASSOC(SSjob.dynamic_forced_occupations, new_malf.current, "AI") diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm new file mode 100644 index 0000000000000..7dc3a43cfd204 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -0,0 +1,43 @@ +/datum/round_event_control/antagonist/team/nuke_ops + name = "Nuclear Operatives" + roundstart = TRUE + + antag_flag = ROLE_OPERATIVE + antag_datum = /datum/antagonist/nukeop + antag_leader_datum = /datum/antagonist/nukeop/leader + + weight = 0 + tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) + + base_antags = 2 + maximum_antags = 5 + maximum_antags_global = 5 + + typepath = /datum/round_event/antagonist/team/nukie + + ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + +/datum/round_event/antagonist/team/nukie + var/datum/job/job_type = /datum/job/nuclear_operative + var/required_role = ROLE_NUCLEAR_OPERATIVE + + var/datum/team/nuclear/nuke_team + +/datum/round_event/antagonist/team/nukie/candidate_roles_setup(mob/candidate) + candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) + candidate.mind.special_role = required_role + +/datum/round_event/antagonist/team/nukie/start() + // Get our nukie leader + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) + if(!most_experienced) + most_experienced = setup_minds[1] + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) + nuke_team = leader.nuke_team + + // Setup everyone else + for(var/datum/mind/assigned_player in setup_minds) + if(assigned_player == most_experienced) + continue + add_datum_to_mind(assigned_player) + return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm new file mode 100644 index 0000000000000..f4a94625fb33a --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -0,0 +1,14 @@ +/datum/round_event_control/antagonist/solo/spy + name = "Spies" + roundstart = TRUE + + antag_flag = ROLE_SPY + antag_datum = /datum/antagonist/spy + weight = 8 + maximum_antags_global = 4 + + tags = list(TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/spy/midround + name = "Spies (Midround)" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm new file mode 100644 index 0000000000000..8c2ea190743b0 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -0,0 +1,14 @@ +/datum/round_event_control/antagonist/solo/traitor + name = "Traitors" + roundstart = TRUE + + antag_flag = ROLE_TRAITOR + antag_datum = /datum/antagonist/traitor + weight = 16 + maximum_antags_global = 6 + + tags = list(TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/traitor/midround + name = "Sleeper Agents (Traitors)" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm new file mode 100644 index 0000000000000..5e711975ee950 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm @@ -0,0 +1,32 @@ +/datum/round_event_control/slaughter + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_CHAOTIC) + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/sandstorm // it's a shittier meteor wave that kills the server trying to process all the debris + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/sandstorm_classic // it's a shittier meteor wave that kills the server trying to process all the debris + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/icarus_sunbeam + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) + +/datum/round_event_control/dark_matteor + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) + +/datum/round_event_control/wizard + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) + +/datum/round_event_control/mutant_infestation + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm new file mode 100644 index 0000000000000..a2ec235be0ef8 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm @@ -0,0 +1,30 @@ +/datum/round_event_control/nightmare + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT, TAG_SPOOKY) + weight = 4 + +/datum/round_event_control/space_dragon + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT, TAG_CHAOTIC) + weight = 2 + +/datum/round_event_control/space_ninja + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT) + weight = 4 + +/datum/round_event_control/changeling + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT, TAG_CREW_ANTAG) + min_players = 20 + weight = 6 + +/datum/round_event_control/alien_infestation + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CHAOTIC) + weight = 2 + +/datum/round_event_control/spider_infestation + track = EVENT_TRACK_GHOSTSET + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_CHAOTIC) + weight = 2 diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm new file mode 100644 index 0000000000000..5e36b107d18c7 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm @@ -0,0 +1,42 @@ +// TG did not cook this antag into the event system. So I had to make my own + +/datum/round_event_control/voidwalker + name = "Spawn Void Walker" + typepath = /datum/round_event/ghost_role/void_walker + max_occurrences = 1 + weight = 3 + earliest_start = 20 MINUTES + min_players = 30 + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "A Void Walker that drags people out of the station and into the abyss" + map_flags = EVENT_SPACE_ONLY + + track = EVENT_TRACK_GHOSTSET + +/datum/round_event/ghost_role/void_walker + minimum_required = 30 + fakeable = FALSE + role_name = "Void Walker" + +/datum/round_event/ghost_role/void_walker/spawn_role() + var/spawn_location = find_space_spawn() + if(isnull(spawn_location)) + return MAP_ERROR + + var/mob/chosen_one = SSpolling.poll_ghost_candidates(check_jobban = ROLE_VOIDWALKER, role = ROLE_VOIDWALKER, alert_pic = /obj/item/cosmic_skull, jump_target = spawn_location, role_name_text = "Void Walker", amount_to_pick = 1) + if(isnull(chosen_one)) + return NOT_ENOUGH_PLAYERS + var/datum/mind/player_mind = new /datum/mind(chosen_one.key) + player_mind.active = TRUE + + var/mob/living/carbon/human/walker = new (spawn_location) + player_mind.transfer_to(walker) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/voidwalker)) + player_mind.add_antag_datum(/datum/antagonist/voidwalker) + walker.set_species(/datum/species/voidwalker) + playsound(walker, 'sound/effects/magic/ethereal_exit.ogg', 50, TRUE, -1) + message_admins("[ADMIN_LOOKUPFLW(walker)] has been made into a Voidwalker by the midround event.") + walker.log_message("[key_name(walker)] was spawned as a Voidwalker by an event.", LOG_GAME) + spawned_mobs += walker + return SUCCESSFUL_SPAWN diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm new file mode 100644 index 0000000000000..3b24b1f6c7dd5 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -0,0 +1,95 @@ +/datum/round_event_control/earthquake + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + +/datum/round_event_control/bureaucratic_error + track = EVENT_TRACK_MAJOR // Yes, it's annoying. + tags = list(TAG_COMMUNAL) + weight = 5 + +/datum/round_event_control/blob + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_CHAOTIC) + weight = 10 + +/datum/round_event_control/meteor_wave + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) + weight = 10 + max_occurrences = 1 + +/datum/round_event_control/meteor_wave/meaty + weight = 15 + max_occurrences = 1 + +/datum/round_event_control/meteor_wave/threatening + weight = 3 + +/datum/round_event_control/meteor_wave/catastrophic + weight = 0 + +/datum/round_event_control/meteor_wave/ices + weight = 0 + +/datum/round_event_control/radiation_storm + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/wormholes + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/immovable_rod + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + weight = 20 + +/datum/round_event_control/anomaly/anomaly_vortex + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + +/datum/round_event_control/anomaly/anomaly_pyro + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + +/datum/round_event_control/revenant + min_players = 20 + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) + +/datum/round_event_control/abductor + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CHAOTIC) + +/datum/round_event_control/fugitives + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT) + +/datum/round_event_control/voidwalker + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) + +/datum/round_event_control/cme + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL, TAG_CHAOTIC) + +/datum/round_event_control/stray_cargo/changeling_zombie + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC, TAG_SPOOKY) + +/datum/round_event_control/pirates + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_COMBAT) + +/datum/round_event_control/cortical_borer + track = EVENT_TRACK_MAJOR + tags = list(TAG_TARGETED, TAG_SPOOKY) + min_players = 20 + +/datum/round_event_control/morph + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) + +/datum/round_event_control/operative + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm new file mode 100644 index 0000000000000..134799677af5e --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -0,0 +1,51 @@ +/datum/round_event_control/brand_intelligence + tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL, TAG_CHAOTIC) + +/datum/round_event_control/carp_migration + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/communications_blackout + tags = list(TAG_COMMUNAL, TAG_SPOOKY) + +/datum/round_event_control/ion_storm + tags = list(TAG_TARGETED) + +/datum/round_event_control/processor_overload + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/radiation_leak + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/supermatter_surge + tags = list(TAG_TARGETED) + +/datum/round_event_control/stray_meteor + tags = list(TAG_DESTRUCTIVE, TAG_SPACE) + weight = 25 + +/datum/round_event_control/shuttle_catastrophe + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/vent_clog + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/anomaly + weight = 10 // Lower from original 15 because it KEEPS SPAWNING THEM + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE) + +/datum/round_event_control/spacevine + tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC) + +/datum/round_event_control/portal_storm_syndicate + tags = list(TAG_COMBAT, TAG_CHAOTIC) + +/datum/round_event_control/portal_storm_narsie + tags = list(TAG_COMBAT, TAG_CHAOTIC) + +/datum/round_event_control/mold + tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC) + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/obsessed + tags = list(TAG_TARGETED) diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm new file mode 100644 index 0000000000000..59593c8a7ef5e --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -0,0 +1,138 @@ +/datum/round_event_control/aurora_caelus + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_SPACE) + +/datum/round_event_control/brain_trauma + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED) + +/datum/round_event_control/heart_attack + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED) + +/datum/round_event_control/camera_failure + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_SPOOKY) + +/datum/round_event_control/grid_check + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_SPOOKY) + +/datum/round_event_control/disease_outbreak + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED) + +/datum/round_event_control/space_dust + track = EVENT_TRACK_MUNDANE + tags = list(TAG_DESTRUCTIVE, TAG_SPACE) + +/datum/round_event_control/electrical_storm + track = EVENT_TRACK_MUNDANE + tags = list(TAG_SPOOKY) + +/datum/round_event_control/fake_virus + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED) + +/datum/round_event_control/falsealarm + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/market_crash + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/mice_migration + track = EVENT_TRACK_MUNDANE + tags = list(TAG_DESTRUCTIVE) + +/datum/round_event_control/wisdomcow + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_POSITIVE) + +/datum/round_event_control/shuttle_loan + var/list/run_situations = list() + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/mass_hallucination + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/stray_cargo + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/grey_tide + track = EVENT_TRACK_MUNDANE + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) + +/datum/round_event_control/gravity_generator_blackout + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_SPACE) + +/datum/round_event_control/shuttle_insurance + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/tram_malfunction + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED, TAG_SPOOKY) + +/datum/round_event_control/bitrunning_glitch + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED) + +/datum/round_event_control/sentience + track = EVENT_TRACK_MUNDANE + tags = list(TAG_TARGETED, TAG_POSITIVE) + +/datum/round_event_control/easter + track = EVENT_TRACK_MUNDANE + roundstart = TRUE + weight = 0 + max_occurrences = 0 + tags = list(TAG_COMMUNAL, TAG_POSITIVE) + +/datum/round_event_control/rabbitrelease + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_POSITIVE) + +/datum/round_event_control/valentines + track = EVENT_TRACK_MUNDANE + roundstart = TRUE + weight = 0 + max_occurrences = 0 + tags = list(TAG_COMMUNAL, TAG_POSITIVE) + +/datum/round_event_control/santa + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_POSITIVE) + +/datum/round_event_control/spooky + track = EVENT_TRACK_MUNDANE + roundstart = TRUE + weight = 0 + max_occurrences = 0 + tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_SPOOKY) + +//SCRUBBER OVERRIDES +/datum/round_event_control/scrubber_overflow + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL) + +/datum/round_event_control/scrubber_overflow/threatening + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/scrubber_overflow/catastrophic + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/scrubber_overflow/every_vent + weight = 0 + max_occurrences = 0 + +/datum/round_event_control/scrubber_overflow/ices + weight = 0 + max_occurrences = 0 diff --git a/modular_bandastation/storyteller/code/event_defines/override_events.dm b/modular_bandastation/storyteller/code/event_defines/override_events.dm new file mode 100644 index 0000000000000..451e96d5ac9d4 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/override_events.dm @@ -0,0 +1,43 @@ +/datum/round_event/scrubber_overflow + /// Whitelist of reagents we want scrubbers to dispense + safer_chems = list(/datum/reagent/baldium, + /datum/reagent/bluespace, + /datum/reagent/carbon, + /datum/reagent/colorful_reagent, + /datum/reagent/concentrated_barbers_aid, + /datum/reagent/consumable/astrotame, + /datum/reagent/consumable/char, + /datum/reagent/consumable/condensedcapsaicin, + /datum/reagent/consumable/cream, + /datum/reagent/consumable/ethanol/antifreeze, + /datum/reagent/consumable/ethanol/beer, + /datum/reagent/consumable/ethanol/fernet_cola, + /datum/reagent/consumable/ethanol/sugar_rush, + /datum/reagent/consumable/flour, + /datum/reagent/consumable/ice, + /datum/reagent/consumable/laughter, + /datum/reagent/consumable/sugar, + /datum/reagent/consumable/tinlux, + /datum/reagent/cryptobiolin, + /datum/reagent/drug/mushroomhallucinogen, + /datum/reagent/drug/space_drugs, + /datum/reagent/fuel, + /datum/reagent/glitter/blue, + /datum/reagent/glitter/confetti, + /datum/reagent/glitter/pink, + /datum/reagent/glitter/white, + /datum/reagent/gravitum, + /datum/reagent/growthserum, + /datum/reagent/hair_dye, + /datum/reagent/hydrogen_peroxide, + /datum/reagent/lube, + /datum/reagent/lube/superlube, + /datum/reagent/medicine/c2/multiver, + /datum/reagent/metalgen, + /datum/reagent/pax, + /datum/reagent/plastic_polymers, + /datum/reagent/space_cleaner, + /datum/reagent/spraytan, + /datum/reagent/water/salt, + /datum/reagent/yuck, + ) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm new file mode 100644 index 0000000000000..c05847905257f --- /dev/null +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -0,0 +1,1006 @@ +#define INIT_ORDER_GAMEMODE 70 + +SUBSYSTEM_DEF(gamemode) + name = "Gamemode" + init_order = INIT_ORDER_GAMEMODE + runlevels = RUNLEVEL_GAME + flags = SS_BACKGROUND | SS_KEEP_TIMING + wait = 2 SECONDS + + /// List of our event tracks for fast access during for loops. + var/list/event_tracks = EVENT_TRACKS + /// Our storyteller. He progresses our trackboards and picks out events + var/datum/storyteller/storyteller + /// Result of the storyteller vote. Defaults to the guide. + var/voted_storyteller = /datum/storyteller/default + /// List of all the storytellers. Populated at init. Associative from type + var/list/storytellers = list() + /// Next process for our storyteller. The wait time is STORYTELLER_WAIT_TIME + var/next_storyteller_process = 0 + /// Associative list of even track points. + var/list/event_track_points = list( + EVENT_TRACK_MUNDANE = 0, + EVENT_TRACK_MODERATE = 0, + EVENT_TRACK_MAJOR = 0, + EVENT_TRACK_CREWSET = 0, + EVENT_TRACK_GHOSTSET = 0 + ) + /// Last point amount gained of each track. Those are recorded for purposes of estimating how long until next event. + var/list/last_point_gains = list( + EVENT_TRACK_MUNDANE = 0, + EVENT_TRACK_MODERATE = 0, + EVENT_TRACK_MAJOR = 0, + EVENT_TRACK_CREWSET = 0, + EVENT_TRACK_GHOSTSET = 0 + ) + /// Point thresholds at which the events are supposed to be rolled, it is also the base cost for events. + var/list/point_thresholds = list( + EVENT_TRACK_MUNDANE = 100, + EVENT_TRACK_MODERATE = 100, + EVENT_TRACK_MAJOR = 100, + EVENT_TRACK_CREWSET = 100, + EVENT_TRACK_GHOSTSET = 100 + ) + + /// Minimum population thresholds for the tracks to fire off events. + var/list/min_pop_thresholds = list( + EVENT_TRACK_MUNDANE = MUNDANE_MIN_POP, + EVENT_TRACK_MODERATE = MODERATE_MIN_POP, + EVENT_TRACK_MAJOR = MAJOR_MIN_POP, + EVENT_TRACK_CREWSET = CREWSET_MIN_POP, + EVENT_TRACK_GHOSTSET = GHOSTSET_MIN_POP + ) + + /// Configurable multipliers for point gain over time. + var/list/point_gain_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_CREWSET = 1, + EVENT_TRACK_GHOSTSET = 1 + ) + /// Configurable multipliers for roundstart points. + var/list/roundstart_point_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_CREWSET = 1, + EVENT_TRACK_GHOSTSET = 1 + ) + /// Whether we allow pop scaling. This is configured by config, or the storyteller UI + var/allow_pop_scaling = TRUE + + /// Associative list of pop scale thresholds. + var/list/pop_scale_thresholds = list( + EVENT_TRACK_MUNDANE = MUNDANE_POP_SCALE_THRESHOLD, + EVENT_TRACK_MODERATE = MODERATE_POP_SCALE_THRESHOLD, + EVENT_TRACK_MAJOR = MAJOR_POP_SCALE_THRESHOLD, + EVENT_TRACK_CREWSET = CREWSET_POP_SCALE_THRESHOLD, + EVENT_TRACK_GHOSTSET = GHOSTSET_POP_SCALE_THRESHOLD + ) + + /// Associative list of pop scale penalties. + var/list/pop_scale_penalties = list( + EVENT_TRACK_MUNDANE = MUNDANE_POP_SCALE_PENALTY, + EVENT_TRACK_MODERATE = MODERATE_POP_SCALE_PENALTY, + EVENT_TRACK_MAJOR = MAJOR_POP_SCALE_PENALTY, + EVENT_TRACK_CREWSET = CREWSET_POP_SCALE_PENALTY, + EVENT_TRACK_GHOSTSET = GHOSTSET_POP_SCALE_PENALTY + ) + + + + /// Associative list of control events by their track category. Compiled in Init + var/list/event_pools = list() + + /// Events that we have scheduled to run in the nearby future + var/list/scheduled_events = list() + + /// Associative list of tracks to forced event controls. For admins to force events (though they can still invoke them freely outside of the track system) + var/list/forced_next_events = list() + + var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences. + var/list/running = list() //list of all existing /datum/round_event + var/list/currentrun = list() + + /// List of all uncategorized events, because they were wizard or holiday events + var/list/uncategorized = list() + + var/list/holidays //List of all holidays occuring today or null if no holidays + + /// Event frequency multiplier, it exists because wizard, eugh. + var/event_frequency_multiplier = 1 + + /// Current preview page for the statistics UI. + var/statistics_track_page = EVENT_TRACK_MUNDANE + /// Page of the UI panel. + var/panel_page = GAMEMODE_PANEL_MAIN + /// Whether we are viewing the roundstart events or not + var/roundstart_event_view = TRUE + + /// Whether the storyteller has been halted + var/halted_storyteller = FALSE + + /// Ready players for roundstart events. + var/ready_players = 0 + var/active_players = 0 + var/head_crew = 0 + var/eng_crew = 0 + var/sec_crew = 0 + var/med_crew = 0 + + var/wizardmode = FALSE + + var/storyteller_voted = FALSE + +/datum/controller/subsystem/gamemode/Initialize(time, zlevel) + . = ..() + // Populate event pools + for(var/track in event_tracks) + event_pools[track] = list() + + // Populate storytellers + for(var/type in subtypesof(/datum/storyteller)) + storytellers[type] = new type() + + for(var/type in typesof(/datum/round_event_control)) + var/datum/round_event_control/event = new type() + if(!event.typepath || !event.name || !event.valid_for_map()) + continue //don't want this one! leave it for the garbage collector + control += event //add it to the list of all events (controls) + getHoliday() + + load_config_vars() + load_event_config_vars() + + ///Seeding events into track event pools needs to happen after event config vars are loaded + for(var/datum/round_event_control/event as anything in control) + if(event.holidayID || event.wizardevent) + uncategorized += event + continue + event_pools[event.track] += event //Add it to the categorized event pools + return SS_INIT_SUCCESS + + +/datum/controller/subsystem/gamemode/fire(resumed = FALSE) + if(!resumed) + src.currentrun = running.Copy() + + ///Handle scheduled events + for(var/datum/scheduled_event/sch_event in scheduled_events) + if(world.time >= sch_event.start_time) + sch_event.try_fire() + else if(!sch_event.alerted_admins && world.time >= sch_event.start_time - 1 MINUTES) + ///Alert admins 1 minute before running and allow them to cancel or refund the event, once again. + sch_event.alerted_admins = TRUE + message_admins("Scheduled Event: [sch_event.event] will run in [(sch_event.start_time - world.time) / 10] seconds. (CANCEL) (REFUND)") + + if(!halted_storyteller && next_storyteller_process <= world.time && storyteller) + // We update crew information here to adjust population scalling and event thresholds for the storyteller. + update_crew_infos() + next_storyteller_process = world.time + STORYTELLER_WAIT_TIME + storyteller.process(STORYTELLER_WAIT_TIME * 0.1) + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(currentrun.len) + var/datum/thing = currentrun[currentrun.len] + currentrun.len-- + if(thing) + thing.process(wait * 0.1) + else + running.Remove(thing) + if (MC_TICK_CHECK) + return + +/datum/controller/subsystem/gamemode/proc/storyteller_desc(storyteller_name) + for(var/storyteller_type in storytellers) + var/datum/storyteller/storyboy = storytellers[storyteller_type] + if(storyboy.name != storyteller_name) + continue + return storyboy.desc + +/// Gets the number of antagonists the antagonist injection events will stop rolling after. +/datum/controller/subsystem/gamemode/proc/get_antag_cap() + if(isnull(storyteller)) + return 0 + if(!storyteller.antag_divisor) + return 0 + return round(max(min(get_correct_popcount() / storyteller.antag_divisor + sec_crew ,sec_crew * 1.5),ANTAG_CAP_FLAT)) + +/// Whether events can inject more antagonists into the round +/datum/controller/subsystem/gamemode/proc/can_inject_antags() + return (get_antag_cap() > length(GLOB.current_living_antags)) + +/// Gets candidates for antagonist roles. + +/// Todo: Split into get_candidates and post_get_candidates +/datum/controller/subsystem/gamemode/proc/get_candidates( + special_role_flag, + pick_observers, + pick_roundstart_players, + required_time, + inherit_required_time = TRUE, + no_antags = TRUE, + list/restricted_roles, + ) + + + var/list/candidates = list() + var/list/candidate_candidates = list() //lol + if(pick_roundstart_players) + for(var/mob/dead/new_player/player in GLOB.new_player_list) + if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) + candidate_candidates += player + else if(pick_observers) + for(var/mob/player as anything in GLOB.dead_mob_list) + candidate_candidates += player + else + for(var/datum/record/locked/manifest_log as anything in GLOB.manifest.locked) + var/datum/mind/player_mind = manifest_log.mind_ref.resolve() + var/mob/living/player = player_mind.current + if(isnull(player)) + continue + candidate_candidates += player + + + for(var/mob/candidate as anything in candidate_candidates) + if(QDELETED(candidate) || !candidate.key || !candidate.client || !candidate.mind) + continue + if(no_antags && candidate.mind.special_role) + continue + if(restricted_roles && (candidate.mind.assigned_role.title in restricted_roles)) + continue + if(special_role_flag) + if(!(candidate.client.prefs) || !(special_role_flag in candidate.client.prefs.be_special)) + continue + + var/time_to_check + if(required_time) + time_to_check = required_time + else if (inherit_required_time) + time_to_check = GLOB.special_roles[special_role_flag] + + if(time_to_check && candidate.client.get_remaining_days(time_to_check) > 0) + continue + + if(special_role_flag && is_banned_from(candidate.ckey, list(special_role_flag, ROLE_SYNDICATE))) + continue + /* if(is_banned_from(candidate.client.ckey, BAN_ANTAGONIST)) + continue + if(!candidate.client?.prefs?.read_preference(/datum/preference/toggle/be_antag)) + continue */ // Закоменчено, так как требует расширения системы банов и настроек - ввод банов на любых антагов и настроек на то, чтобы вообще быть антагом. + candidates += candidate + return candidates + +/// Gets the correct popcount, returning READY people if roundstart, and active people if not. +/datum/controller/subsystem/gamemode/proc/get_correct_popcount() + if(SSticker.HasRoundStarted()) + update_crew_infos() + return active_players + else + calculate_ready_players() + return ready_players + +/// Refunds and removes a scheduled event. +/datum/controller/subsystem/gamemode/proc/refund_scheduled_event(datum/scheduled_event/refunded) + if(refunded.cost) + var/track_type = refunded.event.track + event_track_points[track_type] += refunded.cost + remove_scheduled_event(refunded) + +/// Schedules an event. +/datum/controller/subsystem/gamemode/proc/force_event(datum/round_event_control/event) + forced_next_events[event.track] = event + +/// Removes a scheduled event. +/datum/controller/subsystem/gamemode/proc/remove_scheduled_event(datum/scheduled_event/removed) + scheduled_events -= removed + qdel(removed) + +/// We need to calculate ready players for the sake of roundstart events becoming eligible. +/datum/controller/subsystem/gamemode/proc/calculate_ready_players() + ready_players = 0 + for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) + if(player.ready == PLAYER_READY_TO_PLAY) + ready_players++ + +/// We roll points to be spent for roundstart events, including antagonists. +/datum/controller/subsystem/gamemode/proc/roll_pre_setup_points() + if(storyteller.disable_distribution || halted_storyteller) + return + /// Distribute points + for(var/track in event_track_points) + var/base_amt + switch(track) + if(EVENT_TRACK_MUNDANE) + base_amt = ROUNDSTART_MUNDANE_BASE + if(EVENT_TRACK_MODERATE) + base_amt = ROUNDSTART_MODERATE_BASE + if(EVENT_TRACK_MAJOR) + base_amt = ROUNDSTART_MAJOR_BASE + if(EVENT_TRACK_CREWSET) + base_amt = ROUNDSTART_CREWSET_BASE + if(EVENT_TRACK_GHOSTSET) + base_amt = ROUNDSTART_GHOSTSET_BASE + var/calc_value = base_amt + calc_value *= roundstart_point_multipliers[track] + calc_value *= storyteller.starting_point_multipliers[track] + calc_value *= (1 + (rand(-storyteller.roundstart_points_variance, storyteller.roundstart_points_variance) / 100)) + event_track_points[track] = max(0, round(calc_value)) + + /// If the storyteller guarantees an antagonist roll, add points to make it so. + if(storyteller.guarantees_roundstart_crewset) + event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] + + /// If we have any forced events, ensure we get enough points for them + for(var/track in event_tracks) + if(forced_next_events[track] && event_track_points[track] < point_thresholds[track]) + event_track_points[track] = point_thresholds[track] + +/// Because roundstart events need 2 steps of firing for purposes of antags, here is the first step handled, happening before occupation division. +/datum/controller/subsystem/gamemode/proc/handle_pre_setup_roundstart_events() + if(storyteller.disable_distribution) + return + if(halted_storyteller) + message_admins("WARNING: Didn't roll roundstart events (including antagonists) due to the storyteller being halted.") + return + while(TRUE) + if(!storyteller.handle_tracks()) + break + +/// Second step of handlind roundstart events, happening after people spawn. +/datum/controller/subsystem/gamemode/proc/handle_post_setup_roundstart_events() + /// Start all roundstart events on post_setup immediately + for(var/datum/round_event/event as anything in running) + if(!event.control.roundstart) + continue + ASYNC + event.try_start() +// INVOKE_ASYNC(event, /datum/round_event.proc/try_start) + +/// Schedules an event to run later. +/datum/controller/subsystem/gamemode/proc/schedule_event(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) + var/datum/scheduled_event/scheduled = new (passed_event, world.time + passed_time, passed_cost, passed_ignore, passed_announce) + var/round_started = SSticker.HasRoundStarted() + if(round_started) + message_admins("Event: [passed_event] has been scheduled to run in [passed_time / 10] seconds. (CANCEL) (REFUND)") + else //Only roundstart events can be scheduled before round start + message_admins("Event: [passed_event] has been scheduled to run on roundstart. (CANCEL)") + scheduled_events += scheduled + +/datum/controller/subsystem/gamemode/proc/update_crew_infos() + // Very similar logic to `get_active_player_count()` + active_players = 0 + head_crew = 0 + eng_crew = 0 + med_crew = 0 + sec_crew = 0 + for(var/mob/player_mob as anything in GLOB.player_list) + if(!player_mob.client) + continue + if(player_mob.stat) //If they're alive + continue + if(player_mob.client.is_afk()) //If afk + continue + if(!ishuman(player_mob)) + continue + active_players++ + if(player_mob.mind?.assigned_role) + var/datum/job/player_role = player_mob.mind.assigned_role + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) + head_crew++ + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_ENGINEERING) + eng_crew++ + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_MEDICAL) + med_crew++ + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) + sec_crew++ + +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event) + . = event.preRunEvent() + if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 + event.max_occurrences = 0 + else if(. == EVENT_READY) + event.run_event(random = TRUE) // fallback to dynamic + +///Resets frequency multiplier. +/datum/controller/subsystem/gamemode/proc/resetFrequency() + event_frequency_multiplier = 1 + +/* /client/proc/forceEvent() + set name = "Trigger Event" + set category = "Admin.Events" + + if(!holder ||!check_rights(R_FUN)) + return + + holder.forceEvent(usr) */ + +/* /datum/admins/forceEvent(mob/user) + SSgamemode.event_panel(user) */ + + +////////////// +// HOLIDAYS // +////////////// +//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays + +//It's easy to add stuff. Just add a holiday datum in code/modules/holiday/holidays.dm +//You can then check if it's a special day in any code in the game by doing if(SSgamemode.holidays["Groundhog Day"]) + +//You can also make holiday random events easily thanks to Pete/Gia's system. +//simply make a random event normally, then assign it a holidayID string which matches the holiday's name. +//Anything with a holidayID, which isn't in the holidays list, will never occur. + +//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc), +//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed! + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!// +////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +//sets up the holidays and holidays list +/datum/controller/subsystem/gamemode/proc/getHoliday() + if(!CONFIG_GET(flag/allow_holidays)) + return // Holiday stuff was not enabled in the config! + for(var/H in subtypesof(/datum/holiday)) + var/datum/holiday/holiday = new H() + var/delete_holiday = TRUE + for(var/timezone in holiday.timezones) + var/time_in_timezone = world.realtime + timezone HOURS + + var/YYYY = text2num(time2text(time_in_timezone, "YYYY")) // get the current year + var/MM = text2num(time2text(time_in_timezone, "MM")) // get the current month + var/DD = text2num(time2text(time_in_timezone, "DD")) // get the current day + var/DDD = time2text(time_in_timezone, "DDD") // get the current weekday + + if(holiday.shouldCelebrate(DD, MM, YYYY, DDD)) + holiday.celebrate() + LAZYSET(holidays, holiday.name, holiday) + delete_holiday = FALSE + break + if(delete_holiday) + qdel(holiday) + + if(holidays) + holidays = shuffle(holidays) + // regenerate station name because holiday prefixes. + set_station_name(new_station_name()) + world.update_status() + +/datum/controller/subsystem/gamemode/proc/toggleWizardmode() + wizardmode = !wizardmode //TODO: decide what to do with wiz events + message_admins("Summon Events has been [wizardmode ? "enabled, events will occur [SSgamemode.event_frequency_multiplier] times as fast" : "disabled"]!") + log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!") + +///Attempts to select players for special roles the mode might have. +/datum/controller/subsystem/gamemode/proc/pre_setup() + // We need to do this to prevent some niche fuckery... and make dep. orders work. Lol + SSjob.reset_occupations() + calculate_ready_players() + roll_pre_setup_points() + handle_pre_setup_roundstart_events() + return TRUE + +///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things +/datum/controller/subsystem/gamemode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. + if(!report) + report = !CONFIG_GET(flag/no_intercept_report) + addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) + + if(SSdbcore.Connect()) + var/list/to_set = list() + var/arguments = list() + if(storyteller) + to_set += "game_mode = :game_mode" + arguments["game_mode"] = storyteller.name + if(GLOB.revdata.originmastercommit) + to_set += "commit_hash = :commit_hash" + arguments["commit_hash"] = GLOB.revdata.originmastercommit + if(to_set.len) + arguments["round_id"] = GLOB.round_id + var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery( + "UPDATE [format_table_name("round")] SET [to_set.Join(", ")] WHERE id = :round_id", + arguments + ) + query_round_game_mode.Execute() + qdel(query_round_game_mode) + addtimer(CALLBACK(src, PROC_REF(send_trait_report)), rand(1 MINUTES, 5 MINUTES)) + handle_post_setup_roundstart_events() + roundstart_event_view = FALSE + return TRUE + + +///Handles late-join antag assignments +/datum/controller/subsystem/gamemode/proc/make_antag_chance(mob/living/carbon/human/character) + return + +/datum/controller/subsystem/gamemode/proc/check_finished(force_ending) //to be called by SSticker + if(!SSticker.setup_done) + return FALSE + if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) + return TRUE + if(GLOB.station_was_nuked) + return TRUE + if(force_ending) + return TRUE + +////////////////////////// +//Reports player logouts// +////////////////////////// +/proc/display_roundstart_logout_report() + var/list/msg = list("[span_boldnotice("Roundstart logout report")]\n\n") + for(var/i in GLOB.mob_living_list) + var/mob/living/L = i + var/mob/living/carbon/C = L + //var/mob/living/carbon/human/H = C - не требуется без функций гет_днр + if (istype(C) && !C.last_mind) + continue // never had a client + + if(L.ckey && !GLOB.directory[L.ckey]) + msg += "[L.name] ([L.key]), the [L.job] (Disconnected)\n" + + + if(L.ckey && L.client) + var/failed = FALSE + if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) + msg += "[L.name] ([L.key]), the [L.job] (Connected, Inactive)\n" + failed = TRUE //AFK client + if(!failed && L.stat) + /* if(H.get_dnr()) //Suicider + msg += "[L.name] ([L.key]), the [L.job] ([span_boldannounce("Suicide")])\n" + failed = TRUE //Disconnected client + */ // - нет функции гет_днр и вызывающих днр состояний + if(!failed && (L.stat == UNCONSCIOUS || L.stat == HARD_CRIT)) + msg += "[L.name] ([L.key]), the [L.job] (Dying)\n" + failed = TRUE //Unconscious + if(!failed && L.stat == DEAD) + msg += "[L.name] ([L.key]), the [L.job] (Dead)\n" + failed = TRUE //Dead + + continue //Happy connected client + for(var/mob/dead/observer/D in GLOB.dead_mob_list) + if(D.mind && D.mind.current == L) + if(L.stat == DEAD) + /* if(H.get_dnr()) //Suicider + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Suicide")])\n" + continue //Disconnected client + else + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" + continue */ // - нет функции гет_днр и вызывающих днр состояний + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" + continue //Dead mob, ghost abandoned + else + if(D.can_reenter_corpse) + continue //Adminghost, or cult/wizard ghost + else + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Ghosted")])\n" + continue //Ghosted while alive + + + for (var/C in GLOB.admins) + to_chat(C, msg.Join()) + +//Set result and news report here +/datum/controller/subsystem/gamemode/proc/set_round_result() + SSticker.mode_result = "undefined" + if(GLOB.station_was_nuked) + SSticker.news_report = STATION_DESTROYED_NUKE + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + SSticker.news_report = STATION_EVACUATED + if(SSshuttle.emergency.is_hijacked()) + SSticker.news_report = SHUTTLE_HIJACK + +/// Loads json event config values from events.txt +/datum/controller/subsystem/gamemode/proc/load_event_config_vars() + var/json_file = file("[global.config.directory]/events.json") + if(!fexists(json_file)) + return + var/list/decoded = json_decode(file2text(json_file)) + for(var/event_text_path in decoded) + var/event_path = text2path(event_text_path) + var/datum/round_event_control/event + for(var/datum/round_event_control/iterated_event as anything in control) + if(iterated_event.type == event_path) + event = iterated_event + break + if(!event) + continue + var/list/var_list = decoded[event_text_path] + for(var/variable in var_list) + var/value = var_list[variable] + switch(variable) + if("weight") + event.weight = value + if("min_players") + event.min_players = value + if("max_occurrences") + event.max_occurrences = value + if("earliest_start") + event.earliest_start = value * (1 MINUTES) + if("track") + if(value in event_tracks) + event.track = value + if("cost") + event.cost = value + if("reoccurence_penalty_multiplier") + event.reoccurence_penalty_multiplier = value + if("shared_occurence_type") + if(!isnull(value)) + value = text2path(value) + event.shared_occurence_type = value + +/// Loads config values from game_options.txt +/datum/controller/subsystem/gamemode/proc/load_config_vars() + point_gain_multipliers[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_point_gain_multiplier) + + roundstart_point_multipliers[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_roundstart_point_multiplier) + + min_pop_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_min_pop) + min_pop_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_min_pop) + min_pop_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_min_pop) + min_pop_thresholds[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_min_pop) + min_pop_thresholds[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_min_pop) + +/datum/controller/subsystem/gamemode/proc/storyteller_vote_choices() + var/client_amount = GLOB.clients.len + var/list/choices = list() + for(var/storyteller_type in storytellers) + var/datum/storyteller/storyboy = storytellers[storyteller_type] + /// Prevent repeating storytellers + if(storyboy.storyteller_type && storyboy.storyteller_type == SSpersistence.last_storyteller_type) + continue + if(!storyboy.votable) + continue + if((storyboy.population_min && storyboy.population_min > client_amount) || (storyboy.population_max && storyboy.population_max < client_amount)) + continue + choices += storyboy.name + ///Because the vote subsystem is dumb and does not support any descriptions, we dump them into world. + to_chat(world, span_notice("[storyboy.name]")) + to_chat(world, span_notice("[storyboy.desc]")) + return choices + +/datum/controller/subsystem/gamemode/proc/storyteller_vote_result(winner_name) + /// Find the winner + voted_storyteller = winner_name + if(storyteller) + return + for(var/storyteller_type in storytellers) + var/datum/storyteller/storyboy = storytellers[storyteller_type] + if(storyboy.name == winner_name) + voted_storyteller = storyteller_type + break + +/datum/controller/subsystem/gamemode/proc/init_storyteller() + var/datum/storyteller/storyteller_pick + if(!voted_storyteller) + storyteller_pick = pick(storytellers) + message_admins("We picked [storyteller_pick] for this rounds storyteller, randomly.") + voted_storyteller = storyteller_pick + if(storyteller) // If this is true, then an admin bussed one, don't overwrite it + return + set_storyteller(voted_storyteller) + +/datum/controller/subsystem/gamemode/proc/set_storyteller(passed_type) + if(!storytellers[passed_type]) + message_admins("Attempted to set an invalid storyteller type: [passed_type].") + CRASH("Attempted to set an invalid storyteller type: [passed_type].") + storyteller = storytellers[passed_type] + + var/datum/storyteller_data/tracks/track_data = storyteller.track_data + point_thresholds[EVENT_TRACK_MUNDANE] = track_data.threshold_mundane * CONFIG_GET(number/mundane_point_threshold) + point_thresholds[EVENT_TRACK_MODERATE] = track_data.threshold_moderate * CONFIG_GET(number/moderate_point_threshold) + point_thresholds[EVENT_TRACK_MAJOR] = track_data.threshold_major * CONFIG_GET(number/major_point_threshold) + point_thresholds[EVENT_TRACK_CREWSET] = track_data.threshold_crewset * CONFIG_GET(number/crewset_point_threshold) + point_thresholds[EVENT_TRACK_GHOSTSET] = track_data.threshold_ghostset * CONFIG_GET(number/ghostset_point_threshold) + + to_chat(world, span_notice("Storyteller is [storyteller.name]!")) + to_chat(world, span_notice("[storyteller.welcome_text]")) + +/// Panel containing information, variables and controls about the gamemode and scheduled event +/datum/controller/subsystem/gamemode/proc/admin_panel(mob/user) + update_crew_infos() + var/round_started = SSticker.HasRoundStarted() + var/list/dat = list() + var/active_pop = get_correct_popcount() + dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " + dat += " HALT Storyteller Event Panel Set Storyteller Refresh" + dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." + dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew]) - Antag Cap: [get_antag_cap()]" + dat += "
" + dat += "Main" + dat += " Variables" + dat += "
" + switch(panel_page) + if(GAMEMODE_PANEL_VARIABLES) + dat += "Reload Config Vars Configs located in game_options.txt." + dat += "
Point Gains Multipliers (only over time):" + dat += "
This affects points gained over time towards scheduling new events of the tracks." + for(var/track in event_tracks) + dat += "
[track]: [point_gain_multipliers[track]]" + dat += "
" + + dat += "Roundstart Points Multipliers:" + dat += "
This affects points generated for roundstart events and antagonists." + for(var/track in event_tracks) + dat += "
[track]: [roundstart_point_multipliers[track]]" + dat += "
" + + dat += "Minimum Population for Tracks:" + dat += "
This are the minimum population caps for events to be able to run." + for(var/track in event_tracks) + dat += "
[track]: [min_pop_thresholds[track]]" + dat += "
" + + dat += "Point Thresholds:" + dat += "
Those are thresholds the tracks require to reach with points to make an event." + for(var/track in event_tracks) + dat += "
[track]: [point_thresholds[track]]" + + if(GAMEMODE_PANEL_MAIN) + var/even = TRUE + dat += "

Event Tracks:

" + dat += "Every track represents progression towards scheduling an event of it's severity" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + for(var/track in event_tracks) + even = !even + var/background_cl = even ? "#17191C" : "#23273C" + var/lower = event_track_points[track] + var/upper = point_thresholds[track] == 0 ? 1000000 : point_thresholds[track] // КРАШИТСЯ ЗДЕСЬ - CREWSET - трэк присылает 0 (временый фикс, 100000 это значит будет низкая вероятность) + var/percent = round((lower/upper)*100) // КРАШИТСЯ ЗДЕСЬ - CREWSET - трэк присылает 0 и делит на + var/next = 0 + var/last_points = last_point_gains[track] + if(last_points) + next = round((upper - lower) / last_points / STORYTELLER_WAIT_TIME * 40 / 6) / 10 + dat += "" + dat += "" //Track + dat += "" //Progress + dat += "" //Next + var/datum/round_event_control/forced_event = forced_next_events[track] + var/forced = forced_event ? "[forced_event.name] X" : "" + dat += "" //Forced + dat += "" //Actions + dat += "" + dat += "
TrackProgressNextForcedActions
[track][percent]% ([lower]/[upper])~[next] m.[forced]Set Pts. Next Event
" + + dat += "

Scheduled Events:

" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + var/sorted_scheduled = list() + for(var/datum/scheduled_event/scheduled as anything in scheduled_events) + sorted_scheduled[scheduled] = scheduled.start_time + sortTim(sorted_scheduled, cmp=/proc/cmp_numeric_asc, associative = TRUE) + even = TRUE + for(var/datum/scheduled_event/scheduled as anything in sorted_scheduled) + even = !even + var/background_cl = even ? "#17191C" : "#23273C" + dat += "" + dat += "" //Name + dat += "" //Severity + var/time = (scheduled.event.roundstart && !round_started) ? "ROUNDSTART" : "[(scheduled.start_time - world.time) / (1 SECONDS)] s." + dat += "" //Time + dat += "" //Actions + dat += "" + dat += "
NameSeverityTimeActions
[scheduled.event.name][scheduled.event.track][time][scheduled.get_href_actions()]
" + + dat += "

Running Events:

" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + even = TRUE + for(var/datum/round_event/event as anything in running) + even = !even + var/background_cl = even ? "#17191C" : "#23273C" + dat += "" + dat += "" //Name + dat += "" //Actions + dat += "" + dat += "
NameActions
[event.control.name]-TBA-
" + + var/datum/browser/popup = new(user, "gamemode_admin_panel", "Gamemode Panel", 670, 650) + popup.set_content(dat.Join()) + popup.open() + + /// Panel containing information and actions regarding events +/datum/controller/subsystem/gamemode/proc/event_panel(mob/user) + var/list/dat = list() + if(storyteller) + dat += "Storyteller: [storyteller.name]" + dat += "
Repetition penalty multiplier: [storyteller.event_repetition_multiplier]" + dat += "
Cost variance: [storyteller.cost_variance]" + if(storyteller.tag_multipliers) + dat += "
Tag multipliers:" + for(var/tag in storyteller.tag_multipliers) + dat += "[tag]:[storyteller.tag_multipliers[tag]] | " + storyteller.calculate_weights(statistics_track_page) + else + dat += "Storyteller: None
Weight and chance statistics will be inaccurate due to the present lack of a storyteller." + dat += "
Roundstart Events Forced Roundstart events will use rolled points, and are guaranteed to trigger (even if the used points are not enough)" + dat += "
Avg. event intervals: " + for(var/track in event_tracks) + if(last_point_gains[track]) + var/est_time = round(point_thresholds[track] / last_point_gains[track] / STORYTELLER_WAIT_TIME * 40 / 6) / 10 + dat += "[track]: ~[est_time] m. | " + dat += "
" + for(var/track in EVENT_PANEL_TRACKS) + dat += "[track]" + dat += "
" + /// Create event info and stats table + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + var/even = TRUE + var/total_weight = 0 + var/list/event_lookup + switch(statistics_track_page) + if(ALL_EVENTS) + event_lookup = control + if(UNCATEGORIZED_EVENTS) + event_lookup = uncategorized + else + event_lookup = event_pools[statistics_track_page] + var/list/assoc_spawn_weight = list() + var/active_pop = get_correct_popcount() + for(var/datum/round_event_control/event as anything in event_lookup) + if(event.roundstart != roundstart_event_view) + continue + if(event.can_spawn_event(active_pop)) + total_weight += event.calculated_weight + assoc_spawn_weight[event] = event.calculated_weight + else + assoc_spawn_weight[event] = 0 + sortTim(assoc_spawn_weight, cmp=/proc/cmp_numeric_dsc, associative = TRUE) + for(var/datum/round_event_control/event as anything in assoc_spawn_weight) + even = !even + var/background_cl = even ? "#17191C" : "#23273C" + dat += "" + dat += "" //Name + dat += "" + var/occurence_string = "[event.occurrences]" + if(event.shared_occurence_type) + occurence_string += " (shared: [event.get_occurences()])" + dat += "" //Occurences + dat += "" //Minimum pop + dat += "" //Minimum time + dat += "" //Can happen? + var/weight_string = "([event.calculated_weight] /raw.[event.weight])" + if(assoc_spawn_weight[event]) + var/percent = round((event.calculated_weight / total_weight) * 100) + weight_string = "[percent]% - [weight_string]" + dat += "" //Weight + dat += "" //Actions + dat += "" + dat += "
NameTagsOccurencesM.PopM.TimeCan OccurWeightActions
[event.name]" //Tags + for(var/tag in event.tags) + dat += "[tag] " + dat += "[occurence_string][event.min_players][event.earliest_start / (1 MINUTES)] m.[assoc_spawn_weight[event] ? "Yes" : "No"][weight_string][event.get_href_actions()]
" + var/datum/browser/popup = new(user, "gamemode_event_panel", "Event Panel", 1000, 600) + popup.set_content(dat.Join()) + popup.open() + +/datum/controller/subsystem/gamemode/Topic(href, href_list) + . = ..() + var/mob/user = usr + if(!check_rights(R_ADMIN)) + return + switch(href_list["panel"]) + if("main") + switch(href_list["action"]) + if("set_storyteller") + message_admins("[key_name_admin(usr)] is picking a new Storyteller.") + var/list/name_list = list() + for(var/storyteller_type in storytellers) + var/datum/storyteller/storyboy = storytellers[storyteller_type] + name_list[storyboy.name] = storyboy.type + var/new_storyteller_name = input(usr, "Choose new storyteller (circumvents voted one):", "Storyteller") as null|anything in name_list + if(!new_storyteller_name) + message_admins("[key_name_admin(usr)] has cancelled picking a Storyteller.") + return + message_admins("[key_name_admin(usr)] has chosen [new_storyteller_name] as the new Storyteller.") + var/new_storyteller_type = name_list[new_storyteller_name] + set_storyteller(new_storyteller_type) + if("halt_storyteller") + halted_storyteller = !halted_storyteller + message_admins("[key_name_admin(usr)] has [halted_storyteller ? "HALTED" : "un-halted"] the Storyteller.") + if("vars") + var/track = href_list["track"] + switch(href_list["var"]) + if("pts_multiplier") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set point gain multiplier for [track] track to [new_value].") + point_gain_multipliers[track] = new_value + if("roundstart_pts") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set roundstart pts multiplier for [track] track to [new_value].") + roundstart_point_multipliers[track] = new_value + if("min_pop") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set minimum population for [track] track to [new_value].") + min_pop_thresholds[track] = new_value + if("pts_threshold") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set point threshold of [track] track to [new_value].") + point_thresholds[track] = new_value + if("reload_config_vars") + message_admins("[key_name_admin(usr)] reloaded gamemode config vars.") + load_config_vars() + if("tab") + var/tab = href_list["tab"] + panel_page = tab + if("open_stats") + event_panel(user) + return + if("track_action") + var/track = href_list["track"] + if(!(track in event_tracks)) + return + switch(href_list["track_action"]) + if("remove_forced") + if(forced_next_events[track]) + var/datum/round_event_control/event = forced_next_events[track] + message_admins("[key_name_admin(usr)] removed forced event [event.name] from track [track].") + forced_next_events -= track + if("set_pts") + var/set_pts = input(usr, "New point amount ([point_thresholds[track]]+ invokes event):", "Set points for [track]") as num|null + if(isnull(set_pts)) + return + event_track_points[track] = set_pts + message_admins("[key_name_admin(usr)] set points of [track] track to [set_pts].") + log_admin_private("[key_name(usr)] set points of [track] track to [set_pts].") + if("next_event") + message_admins("[key_name_admin(usr)] invoked next event for [track] track.") + log_admin_private("[key_name(usr)] invoked next event for [track] track.") + event_track_points[track] = point_thresholds[track] + if(storyteller) + storyteller.handle_tracks() + admin_panel(user) + if("stats") + switch(href_list["action"]) + if("set_roundstart") + roundstart_event_view = !roundstart_event_view + if("set_cat") + var/new_category = href_list["cat"] + if(new_category in EVENT_PANEL_TRACKS) + statistics_track_page = new_category + event_panel(user) diff --git a/modular_bandastation/storyteller/code/jobs_restrictions.dm b/modular_bandastation/storyteller/code/jobs_restrictions.dm new file mode 100644 index 0000000000000..7947064f44d68 --- /dev/null +++ b/modular_bandastation/storyteller/code/jobs_restrictions.dm @@ -0,0 +1,54 @@ +/** + * Job antagonist restriction file + * + * Add relative restrictions to any jobs that you wish to prevent from being + * an antagonist. If you set antagonist_restricted to true without setting restricted_antagonist, + * then the job will be restricted from all antagonists. + */ + +/datum/job + /// Do we allow this job to be an antag of any kind? + var/antagonist_restricted = FALSE + /// If we restrict this job from antagonists, what antags? Leave blank for all antags. + var/list/restricted_antagonists + +/datum/job/head_of_personnel + antagonist_restricted = TRUE + +/datum/job/chief_engineer + antagonist_restricted = TRUE + +/datum/job/chief_medical_officer + antagonist_restricted = TRUE + +/datum/job/research_director + antagonist_restricted = TRUE + +/datum/job/quartermaster + antagonist_restricted = TRUE + +/* +/datum/job/nanotrasen_consultant + antagonist_restricted = TRUE + +/datum/job/blueshield + antagonist_restricted = TRUE + +/datum/job/corrections_officer + antagonist_restricted = TRUE + +/datum/job/orderly + antagonist_restricted = TRUE + +/datum/job/bouncer + antagonist_restricted = TRUE + +/datum/job/customs_agent + antagonist_restricted = TRUE + +/datum/job/engineering_guard + antagonist_restricted = TRUE + +/datum/job/science_guard + antagonist_restricted = TRUE +*/ diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm new file mode 100644 index 0000000000000..df501e14e4956 --- /dev/null +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -0,0 +1,96 @@ +///Scheduled event datum for SSgamemode to put events into. +/datum/scheduled_event + /// What event are scheduling. + var/datum/round_event_control/event + /// When do we start our event + var/start_time = 0 + /// If we were created by a storyteller, here's a cost to refund in case. + var/cost + /// Whether we alerted admins about this schedule when it's close to being invoked. + var/alerted_admins = FALSE + /// Whether we are faking an occurence or not + var/fakes_occurence = TRUE + /// Whether this ignores event can run checks. If bussed by an admin, you want to ignore checks + var/ignores_checks + /// Whether the scheduled event will override the announcement change. If null it won't. TRUE = force yes. FALSE = force no. + var/announce_change + +/datum/scheduled_event/New(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) + . = ..() + event = passed_event + start_time = passed_time + cost = passed_cost + ignores_checks = passed_ignore + announce_change = passed_announce + /// Add a fake occurence to make the weightings/checks properly respect the scheduled event. + event.add_occurence() + fakes_occurence = TRUE + +/datum/scheduled_event/proc/remove_occurence() + if(fakes_occurence) + /// Remove the fake occurence if we still have it + event.subtract_occurence() + fakes_occurence = FALSE + +/// For admins who want to reschedule the event. +/datum/scheduled_event/proc/reschedule(new_time) + start_time = new_time + alerted_admins = FALSE + +/datum/scheduled_event/proc/get_href_actions() + var/round_started = SSticker.HasRoundStarted() + if(round_started) + return "Fire Reschedule Cancel Refund" + else + return "Cancel" + +/// Try and fire off the scheduled event +/datum/scheduled_event/proc/try_fire() + /// Remove our fake occurence pre-emptively for the checks. + remove_occurence() + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = FALSE) + ///If we can't spawn the scheduled event, refund it. + if(!ignores_checks && !event.can_spawn_event(players_amt)) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. + message_admins("Scheduled Event: [event] was unable to run and has been refunded.") + log_admin("Scheduled Event: [event] was unable to run and has been refunded.") + + SSgamemode.refund_scheduled_event(src) + return + + ///Trigger the event and remove the scheduled datum + message_admins("Scheduled Event: [event] successfully triggered.") + SSgamemode.TriggerEvent(event) + SSgamemode.remove_scheduled_event(src) + +/datum/scheduled_event/Destroy() + remove_occurence() + event = null + return ..() + +/datum/scheduled_event/Topic(href, href_list) + . = ..() + if(QDELETED(src)) + return + var/round_started = SSticker.HasRoundStarted() + switch(href_list["action"]) + if("cancel") + message_admins("[key_name_admin(usr)] cancelled scheduled event [event.name].") + log_admin_private("[key_name(usr)] cancelled scheduled event [event.name].") + SSgamemode.remove_scheduled_event(src) + if("refund") + message_admins("[key_name_admin(usr)] refunded scheduled event [event.name].") + log_admin_private("[key_name(usr)] refunded scheduled event [event.name].") + SSgamemode.refund_scheduled_event(src) + if("reschedule") + var/new_schedule = input(usr, "New schedule time (in seconds):", "Reschedule Event") as num|null + if(isnull(new_schedule) || QDELETED(src)) + return + start_time = world.time + new_schedule * 1 SECONDS + message_admins("[key_name_admin(usr)] rescheduled event [event.name] to [new_schedule] seconds.") + log_admin_private("[key_name(usr)] rescheduled event [event.name] to [new_schedule] seconds.") + if("fire") + if(!round_started) + return + message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") + log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") + try_fire() diff --git a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm new file mode 100644 index 0000000000000..59eb76d4bd658 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm @@ -0,0 +1,10 @@ +// A point is added every second, adjust new track threshold overrides accordingly + +/// Storyteller track data, for easy overriding of tracks without having to copypaste +/// thresholds - Used to show how many points the track has to collect before it triggers, lower means faster +/datum/storyteller_data/tracks + var/threshold_mundane = 1200 + var/threshold_moderate = 1800 + var/threshold_major = 8000 + var/threshold_crewset = 1200 + var/threshold_ghostset = 7000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm new file mode 100644 index 0000000000000..d9c001768db65 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -0,0 +1,141 @@ +///The storyteller datum. He operates with the SSgamemode data to run events +/datum/storyteller + /// Name of our storyteller. + var/name = "Badly coded storyteller" + /// Description of our storyteller. + var/desc = "Report this to the coders." + /// Text that the players will be greeted with when this storyteller is chosen. + var/welcome_text = "The storyteller has been selected. Get ready!" + /// This is the multiplier for repetition penalty in event weight. The lower the harsher it is + var/event_repetition_multiplier = 0.6 + /// Multipliers for starting points. // TODO - Rewrite into some variation + var/list/starting_point_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_CREWSET = 1, + EVENT_TRACK_GHOSTSET = 1 + ) + /// The datum containing track size data + var/datum/storyteller_data/tracks/track_data = /datum/storyteller_data/tracks + + /// Percentual variance in the budget of roundstart points. + var/roundstart_points_variance = 30 + + /// Multipliers of weight to apply for each tag of an event. + var/list/tag_multipliers + + /// Percentual variance in cost of the purchased events. Effectively affects frequency of events + var/cost_variance = 30 + + /// Whether the storyteller guaranteed a crewset roll (crew antag) on roundstart. (Still needs to pass pop check) + var/guarantees_roundstart_crewset = TRUE + + /// Whether the storyteller has the distributions disabled. Important for ghost storytellers + var/disable_distribution = FALSE + + /// Whether people can vote for the storyteller + var/votable = TRUE + /// If defined, will need a minimum of population to be votable + var/population_min + /// If defined, it will not be votable if exceeding the population + var/population_max + /// The antag divisor, the higher it is the lower the antag cap gets. Basically means "for every antag_divisor crew, spawn 1 antag". + var/antag_divisor = 8 + + /// Two tellers of the same intensity group can't run in 2 consecutive rounds + var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE + +/datum/storyteller/process(delta_time) + if(disable_distribution) + return + add_points(delta_time) + handle_tracks() + +/// Add points to all tracks while respecting the multipliers. +/datum/storyteller/proc/add_points(delta_time) + var/datum/controller/subsystem/gamemode/mode = SSgamemode + for(var/track in mode.event_track_points) + var/point_gain = delta_time + mode.event_track_points[track] += point_gain + mode.last_point_gains[track] = point_gain + +/// Goes through every track of the gamemode and checks if it passes a threshold to buy an event, if does, buys one. +/datum/storyteller/proc/handle_tracks() + . = FALSE //Has return value for the roundstart loop + var/datum/controller/subsystem/gamemode/mode = SSgamemode + for(var/track in mode.event_track_points) + var/points = mode.event_track_points[track] + if(points >= mode.point_thresholds[track] && find_and_buy_event_from_track(track)) + . = TRUE + +/// Find and buy a valid event from a track. +/datum/storyteller/proc/find_and_buy_event_from_track(track) + . = FALSE + var/datum/round_event_control/picked_event + if(SSgamemode.forced_next_events[track]) //Forced event by admin + /// Dont check any prerequisites, it has been forced by an admin + picked_event = SSgamemode.forced_next_events[track] + SSgamemode.forced_next_events -= track + else + var/player_pop = SSgamemode.get_correct_popcount() + var/pop_required = SSgamemode.min_pop_thresholds[track] + if(player_pop < pop_required) + message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") + log_admin("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") + SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + calculate_weights(track) + var/list/valid_events = list() + // Determine which events are valid to pick + for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) + if(isnull(event)) + continue + if(event.can_spawn_event(player_pop)) + valid_events[event] = event.calculated_weight + ///If we didn't get any events, remove the points inform admins and dont do anything + if(!length(valid_events)) + message_admins("Storyteller failed to pick an event for track of [track].") + log_admin("Storyteller failed to pick an event for track of [track].") + SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + picked_event = pick_weight(valid_events) + if(!picked_event) + message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + log_admin("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + stack_trace("WARNING: Storyteller [src] picked a null from event pool at track [track].") + return + buy_event(picked_event, track) + . = TRUE + +/// Find and buy a valid event from a track. +/datum/storyteller/proc/buy_event(datum/round_event_control/bought_event, track) + var/datum/controller/subsystem/gamemode/mode = SSgamemode + // Perhaps use some bell curve instead of a flat variance? + var/total_cost = bought_event.cost * mode.point_thresholds[track] + if(!bought_event.roundstart) + total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event + mode.event_track_points[track] = max(0, mode.event_track_points[track] - total_cost) + message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + if(bought_event.roundstart) + mode.TriggerEvent(bought_event) + else + mode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) + +/// Calculates the weights of the events from a passed track. +/datum/storyteller/proc/calculate_weights(track) + for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) + var/weight_total = event.weight + /// Apply tag multipliers if able + if(tag_multipliers) + for(var/tag in tag_multipliers) + if(tag in event.tags) + weight_total *= tag_multipliers[tag] + /// Apply occurence multipliers if able + var/occurences = event.get_occurences() + if(occurences) + ///If the event has occured already, apply a penalty multiplier based on amount of occurences + weight_total -= event.reoccurence_penalty_multiplier * weight_total * (1 - (event_repetition_multiplier ** occurences)) + /// Write it + event.calculated_weight = round(weight_total, 1) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm new file mode 100644 index 0000000000000..94044e9938216 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm @@ -0,0 +1,17 @@ +/datum/storyteller/bomb + name = "The Bomb" + desc = "The Bomb will try to make as many destructive events as possible. For when you have a full engineering team. Or not, because they all cryo'd." + welcome_text = "Somebody set up us the bomb." + track_data = /datum/storyteller_data/tracks/bomb + + tag_multipliers = list( + TAG_DESTRUCTIVE = 2 + ) + population_min = 25 + antag_divisor = 10 + storyteller_type = STORYTELLER_TYPE_INTENSE + +/datum/storyteller_data/tracks/bomb + threshold_mundane = 1800 + threshold_moderate = 1400 + threshold_major = 5500 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm new file mode 100644 index 0000000000000..28fe9254f60d1 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm @@ -0,0 +1,22 @@ +/datum/storyteller/chill + name = "The Chill" + desc = "The Chill will be light on events compared to other storytellers, especially so on ones involving combat, destruction, or chaos. Best for more chill rounds." + welcome_text = "If you vote for this storyteller on Ice Box, you have no originality." + + track_data = /datum/storyteller_data/tracks/chill + + guarantees_roundstart_crewset = FALSE + tag_multipliers = list( + TAG_COMBAT = 0.3, + TAG_DESTRUCTIVE = 0.3, + TAG_CHAOTIC = 0.1 + ) + antag_divisor = 32 + storyteller_type = STORYTELLER_TYPE_CALM + +/datum/storyteller_data/tracks/chill + threshold_mundane = 1800 + threshold_moderate = 2700 + threshold_major = 16000 + threshold_crewset = 3600 + threshold_ghostset = 9000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm new file mode 100644 index 0000000000000..251e5fc3a429a --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm @@ -0,0 +1,24 @@ +/datum/storyteller/clown + name = "The Clown" + desc = "The Clown will try to create the most events and antagonists out of all the storytellers, not caring for their weight. \ + As such, it can be truly chaotic and even end rounds prematurely." + welcome_text = "honk" + + track_data = /datum/storyteller_data/tracks/clown + + population_min = 50 + antag_divisor = 4 + storyteller_type = STORYTELLER_TYPE_INTENSE + +/datum/storyteller_data/tracks/clown + threshold_mundane = 700 + threshold_moderate = 1600 + threshold_major = 3200 + threshold_crewset = 1000 + threshold_ghostset = 3200 + +// All the weights are the same to the clown +/datum/storyteller/clown/calculate_weights(track) + for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) + if(event.weight) + event.calculated_weight = 1 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm new file mode 100644 index 0000000000000..7a994db6b64e6 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm @@ -0,0 +1,6 @@ +/datum/storyteller/default + name = "Default Andy" + desc = "Default Andy is the default Storyteller, and the comparison point for every other Storyteller. Best for an average, varied experience." + welcome_text = "If I chopped you up in a meat grinder..." + antag_divisor = 8 + storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm new file mode 100644 index 0000000000000..a50398af3c7b4 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm @@ -0,0 +1,8 @@ +/datum/storyteller/extended + name = "Extended" + desc = "Extended is the absence of a Storyteller. It will not spawn a single event of any sort, or run any Antagonists. Best for rounds where the population is so low that not even peaceful storytellers are low enough." + welcome_text = "How is dorms already full? The shift hasn't even started yet." + disable_distribution = TRUE + population_max = 40 + antag_divisor = 32 + storyteller_type = STORYTELLER_TYPE_CALM diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm new file mode 100644 index 0000000000000..26760d4ea2fb3 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm @@ -0,0 +1,22 @@ +/datum/storyteller/fragile + name = "The Fragile" + desc = "The Fragile will limit destructive, combat-focused, and chaotic events. You'll rarely see midround antagonist roles that usually cause it." + welcome_text = "Handle with care!" + + event_repetition_multiplier = 0.5 + + track_data = /datum/storyteller_data/tracks/fragile + + tag_multipliers = list( + TAG_COMBAT = 0.5, + TAG_DESTRUCTIVE = 0.1, + TAG_CHAOTIC = 0.1 + ) + storyteller_type = STORYTELLER_TYPE_CALM + +/datum/storyteller_data/tracks/fragile + threshold_mundane = 1200 + threshold_moderate = 1800 + threshold_major = 8000 + threshold_crewset = 3000 + threshold_ghostset = 8000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm new file mode 100644 index 0000000000000..cdc428cbd7910 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm @@ -0,0 +1,20 @@ +/datum/storyteller/gamer + name = "The Gamer" + desc = "The Gamer will try to create the most combat focused events, while trying to avoid purely destructive ones." + welcome_text = "Welcome to the Gamer storyteller. Now with 50% more ahelps!" + + track_data = /datum/storyteller_data/tracks/gamer + + tag_multipliers = list( + TAG_COMBAT = 1.5, + TAG_DESTRUCTIVE = 0.7, + TAG_CHAOTIC = 1.3 + ) + population_min = 35 + antag_divisor = 5 + storyteller_type = STORYTELLER_TYPE_INTENSE + +/datum/storyteller_data/tracks/gamer + threshold_moderate = 1300 + threshold_major = 6150 + threshold_ghostset = 6000 diff --git a/modular_bandastation/storyteller/code/vote.dm b/modular_bandastation/storyteller/code/vote.dm new file mode 100644 index 0000000000000..028a425cc72a1 --- /dev/null +++ b/modular_bandastation/storyteller/code/vote.dm @@ -0,0 +1,68 @@ +/datum/vote/var/has_desc = FALSE + +/datum/vote/proc/return_desc(vote_name) + return "" + +/datum/vote/storyteller + name = "Storyteller" + default_message = "Vote for the storyteller!" + has_desc = TRUE + count_method = VOTE_COUNT_METHOD_MULTI + winner_method = VOTE_WINNER_METHOD_SIMPLE + vote_reminder = TRUE + +/datum/vote/storyteller/New() + . = ..() + default_choices = list() + default_choices = SSgamemode.storyteller_vote_choices() + +/datum/vote/storyteller/return_desc(vote_name) + return SSgamemode.storyteller_desc(vote_name) + +/datum/vote/storyteller/create_vote() + . = ..() + if((length(choices) == 1)) // Only one choice, no need to vote. + var/de_facto_winner = choices[1] + SSgamemode.storyteller_vote_result(de_facto_winner) + to_chat(world, span_boldannounce("The storyteller vote has been skipped because there is only one storyteller left to vote for. The storyteller has been changed to [de_facto_winner].")) + return FALSE + +/datum/vote/storyteller/can_be_initiated(mob/by_who, forced = FALSE) + . = ..() + if(forced) + return TRUE + + if(SSgamemode.storyteller_voted) + default_message = "The next Storyteller has already been selected." + return FALSE + +/datum/vote/storyteller/finalize_vote(winning_option) + SSgamemode.storyteller_vote_result(winning_option) + SSgamemode.storyteller_voted = TRUE + +/* +### PERSISTENCE SUBSYSTEM TRACKING BELOW ### +Basically, this keeps track of what we voted last time to prevent it being voted on again. +For this, we use the SSpersistence.last_storyteller_type variable + +We then just check what the last one is in SSgamemode.storyteller_vote_choices() +*/ + +#define STORYTELLER_LAST_FILEPATH "data/storyteller_last_round.txt" + +/// Extends collect_data +/datum/controller/subsystem/persistence/collect_data() + . = ..() + collect_storyteller_type() + +/// Loads last storyteller into last_storyteller_type +/datum/controller/subsystem/persistence/proc/load_storyteller_type() + if(!fexists(STORYTELLER_LAST_FILEPATH)) + return + last_storyteller_type = text2num(file2text(STORYTELLER_LAST_FILEPATH)) + +/// Collects current storyteller and stores it +/datum/controller/subsystem/persistence/proc/collect_storyteller_type() + rustg_file_write("[SSgamemode.storyteller.storyteller_type]", STORYTELLER_LAST_FILEPATH) + +#undef STORYTELLER_LAST_FILEPATH diff --git a/modular_bandastation/storyteller/code/vote_reminder.dm b/modular_bandastation/storyteller/code/vote_reminder.dm new file mode 100644 index 0000000000000..d70579b6019c0 --- /dev/null +++ b/modular_bandastation/storyteller/code/vote_reminder.dm @@ -0,0 +1,36 @@ +/// Следует наверно вынести в отдельный ПР? Напоминалка, что идет голосование. + +/datum/vote + /// Provide a reminder notification to those who haven't voted + var/vote_reminder = FALSE + /// Has the vote reminder fired yet + var/reminder_fired = FALSE + +/// Bubber vote fire proc, original at code/controllers/subsystem/vote.dm +/datum/controller/subsystem/vote/fire() + if(!current_vote) + return + + current_vote.time_remaining = round((current_vote.started_time + CONFIG_GET(number/vote_period) - world.time) / 10) + if(current_vote.time_remaining < 0) + end_vote() + return + + // We give a reminder to latejoiners who may have missed the original vote notification. + if(!current_vote.vote_reminder || current_vote.reminder_fired) + return + + if(current_vote.time_remaining > 45) + return + + current_vote.reminder_fired = TRUE + + for(var/client/late_voter as anything in GLOB.clients) + if(LAZYFIND(voted, late_voter.ckey)) // Skip people who already voted + continue + + if(current_vote.vote_sound && (late_voter.prefs.read_preference(/datum/preference/toggle/sound_announcements))) + SEND_SOUND(late_voter, sound(current_vote.vote_sound)) + + to_chat(late_voter, span_yellowteamradio(span_soapbox("It's time to make your choices for [current_vote.name]! Type 'vote' or click here to place your votes."))) + From 44bc2e421e95b271d5e0f09a6ab68be425b6b7cf Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 19:26:39 +0300 Subject: [PATCH 003/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=84=D0=B8=D0=B3=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/game_options.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/config/game_options.txt b/config/game_options.txt index 0ca4d97b7efc7..b233c64dde705 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -566,29 +566,29 @@ RANDOM_LOOT_WEIGHT_MODIFIER 1 MUNDANE_POINT_GAIN_MULTIPLIER 1 MODERATE_POINT_GAIN_MULTIPLIER 1 MAJOR_POINT_GAIN_MULTIPLIER 1 -ROLESET_POINT_GAIN_MULTIPLIER 1 -OBJECTIVES_POINT_GAIN_MULTIPLIER 1 +CREWSET_POINT_GAIN_MULTIPLIER 1 +GHOSTSET_POINT_GAIN_MULTIPLIER 1 ## Multipliers for points to spend on roundstart events. MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 -ROLESET_ROUNDSTART_POINT_MULTIPLIER 1 -OBJECTIVES_ROUNDSTART_POINT_MULTIPLIER 1 +CREWSET_ROUNDSTART_POINT_MULTIPLIER 1 +GHOSTSET_ROUNDSTART_POINT_MULTIPLIER 1 ## Minimum population caps for event tracks to run their events. MUNDANE_MIN_POP 0 MODERATE_MIN_POP 0 -MAJOR_MIN_POP 0 -ROLESET_MIN_POP 0 -OBJECTIVES_MIN_POP 0 +MAJOR_MIN_POP 20 +CREWSET_MIN_POP 0 +GHOSTSET_MIN_POP 0 -## Point thresholds for tracks to run events. The lesser the more frequent events will be. -MUNDANE_POINT_THRESHOLD 25 -MODERATE_POINT_THRESHOLD 50 -MAJOR_POINT_THRESHOLD 90 -ROLESET_POINT_THRESHOLD 120 -OBJECTIVES_POINT_THRESHOLD 130 +## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. +MUNDANE_POINT_THRESHOLD 1 +MODERATE_POINT_THRESHOLD 1 +MAJOR_POINT_THRESHOLD 1 +CREWSET_POINT_THRESHOLD 1 +GHOSTSET_POINT_THRESHOLD 1 ## Allows the storyteller to scale event frequencies based on population ALLOW_STORYTELLER_POP_SCALING @@ -597,12 +597,12 @@ ALLOW_STORYTELLER_POP_SCALING MUNDANE_POP_SCALE_THRESHOLD 10 MODERATE_POP_SCALE_THRESHOLD 15 MAJOR_POP_SCALE_THRESHOLD 40 -ROLESET_POP_SCALE_THRESHOLD 45 -OBJECTIVES_POP_SCALE_THRESHOLD 40 +CREWSET_POP_SCALE_THRESHOLD 45 +GHOSTSET_POP_SCALE_THRESHOLD 40 ## The maximum penalties population scalling will apply to the tracks for having less pop than POP_SCALE_THRESHOLD. This is treated as percentages MUNDANE_POP_SCALE_PENALTY 30 MODERATE_POP_SCALE_PENALTY 30 MAJOR_POP_SCALE_PENALTY 30 -ROLESET_POP_SCALE_PENALTY 30 -OBJECTIVES_POP_SCALE_PENALTY 30 +CREWSET_POP_SCALE_PENALTY 30 +GHOSTSET_POP_SCALE_PENALTY 30 From e44b127fe8e22a1517f0fa24642f0be5c0801b13 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 19:31:38 +0300 Subject: [PATCH 004/135] =?UTF-8?q?=D0=92=D0=B2=D0=BE=D0=B4=20=D1=87=D0=B5?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B9=20=D0=BE=D1=80=D0=B1=D0=B8=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tellers/storyteller_black_orbit.dm | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm new file mode 100644 index 0000000000000..b98453202967a --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm @@ -0,0 +1,26 @@ +/datum/storyteller/black_orbit + name = "Black Orbit" + desc = "Black Orbit exist only for one purpose. To make you suffer." + welcome_text = "Suffer, b*tch!" + + event_repetition_multiplier = 0.1 + + track_data = /datum/storyteller_data/tracks/black_orbit + + guarantees_roundstart_crewset = FALSE + antag_divisor = 100 //Чтобы было больше антагов + population_min = 10 + + tag_multipliers = list( + TAG_COMBAT = 10, + TAG_DESTRUCTIVE = 10, + TAG_CHAOTIC = 10 + ) + storyteller_type = STORYTELLER_TYPE_INTENSE + +/datum/storyteller_data/tracks/black_orbit + threshold_mundane = 12000000 + threshold_moderate = 18000000 + threshold_major = 80000000 + threshold_crewset = 30000000 + threshold_ghostset = 80000000 From 3d5d0edeee088f4ab705bd7c163d8d86222baa81 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 19:41:13 +0300 Subject: [PATCH 005/135] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D0=B4=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=80=D0=B1=D0=B8=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B2=20=D0=BF=D1=83=D0=BB=20=D0=B3=D0=BE=D0=BB=D0=BE=D1=81?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/_storyteller.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index ade7c2e82f5da..9412660fc39bb 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -27,6 +27,7 @@ #include "code\storytellers\tellers\storyteller_extended.dm" #include "code\storytellers\tellers\storyteller_fragile.dm" #include "code\storytellers\tellers\storyteller_gamer.dm" +#include "code\storytellers\tellers\storyteller_black_orbit.dm" #include "code\divergency_report.dm" #include "code\scheduled_event.dm" From d6e03ecf558a67fcf3145380a1b04ef23581e09f Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 22:01:22 +0300 Subject: [PATCH 006/135] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/dynamic/dynamic.dm | 4 +- .../subsystem/persistence/_persistence.dm | 1 - code/controllers/subsystem/ticker.dm | 3 -- code/modules/admin/topic.dm | 6 ++- code/modules/events/_event.dm | 13 ++--- config/bandastation/bandastation_config.txt | 47 +++++++++++++++++++ config/{ => bandastation}/events.json | 0 config/game_options.txt | 47 ------------------- .../storyteller/_storyteller.dm | 4 +- .../storyteller/_storyteller.dme | 7 +-- .../storyteller/code/_defines/_persistence.dm | 7 +++ .../storyteller/code/_defines/_ticker.dm | 3 ++ .../storyteller/code/divergency_report.dm | 45 ++++++++---------- .../crewset/_antagonist_event.dm | 11 ----- .../event_defines/disabled_event_overrides.dm | 4 -- .../code/event_defines/major/override.dm | 16 ------- .../code/event_defines/moderate/override.dm | 5 -- .../code/event_defines/mundane/override.dm | 4 -- .../storyteller/code/gamemode.dm | 2 +- .../storyteller/code/jobs_restrictions.dm | 26 ---------- .../code/storytellers/data/tracks.dm | 10 ++-- .../code/storytellers/tellers/_storyteller.dm | 16 +++---- modular_bandastation/storyteller/code/vote.dm | 4 +- .../storyteller/code/vote_reminder.dm | 36 -------------- 24 files changed, 107 insertions(+), 214 deletions(-) rename config/{ => bandastation}/events.json (100%) create mode 100644 modular_bandastation/storyteller/code/_defines/_persistence.dm create mode 100644 modular_bandastation/storyteller/code/_defines/_ticker.dm delete mode 100644 modular_bandastation/storyteller/code/vote_reminder.dm diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index f7b45bca18269..3a70adf2b6003 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -321,7 +321,7 @@ SUBSYSTEM_DEF(dynamic) SSticker.news_report = SSshuttle.emergency?.is_hijacked() ? SHUTTLE_HIJACK : STATION_EVACUATED /datum/controller/subsystem/dynamic/proc/send_intercept() - /*if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready + if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready addtimer(CALLBACK(src, PROC_REF(send_intercept)), 10 SECONDS) return @@ -376,7 +376,7 @@ SUBSYSTEM_DEF(dynamic) priority_announce("Отчет был скопирован и распечатан на всех консолях связи.", "Отчет о безопасности", SSstation.announcer.get_rand_report_sound()) // BANDASTATION EDIT END - No Blue roundstart #endif - */ // BANDASTATION EDIT END - Storyteller + return . /// Generate the advisory level depending on the shown threat level. diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index fac49c6882c7d..3d14e1659bddc 100644 --- a/code/controllers/subsystem/persistence/_persistence.dm +++ b/code/controllers/subsystem/persistence/_persistence.dm @@ -48,7 +48,6 @@ SUBSYSTEM_DEF(persistence) var/tram_hits_this_round = 0 var/tram_hits_last_round = 0 - var/last_storyteller_type = "" // BANDASTATION EDIT ADD: Storyteller votes /// A json database to data/message_bottles.json var/datum/json_database/message_bottles_database /// An index used to create unique ids for the message bottles database diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 92111de584176..fe5c69781ab7c 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -233,8 +233,6 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK //Configure mode and assign player to antagonists var/can_continue = FALSE - - // can_continue = SSdynamic.pre_setup() //Choose antagonists // BANDASTATION EDIT - STORYTELLER (note: maybe disable) // BANDASTATION EDIT BEGIN - STORYTELLER SSgamemode.init_storyteller() can_continue = SSgamemode.pre_setup() @@ -306,7 +304,6 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE SSdynamic.post_setup() - SSgamemode.post_setup() // BANDASTATION EDIT - Storyteller GLOB.start_state = new /datum/station_state() GLOB.start_state.count() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1ddec84716730..99406a5851c55 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -69,8 +69,10 @@ else if(href_list["gamemode_panel"]) if(!check_rights(R_ADMIN)) return - //SSdynamic.admin_panel() // BANDASTATION EDIT - STORYTELLER - SSgamemode.admin_panel(usr) // BANDASTATION EDIT - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER + //SSdynamic.admin_panel() + SSgamemode.admin_panel(usr) + // BANDASTATION EDIT END else if(href_list["call_shuttle"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 374e8fa0d88b0..c0e4a48bd796d 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -1,5 +1,4 @@ -// #define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (10 SECONDS) -#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (2 MINUTES) // BANDASTATION EDIT CHANGE - STORYTELLER (взято с буббера как настройка скайрата, возможно стоит снести именно это изменение?) +#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (2 MINUTES) // BANDASTATION EDIT CHANGE - STORYTELLER. Original: 10 SECONDS //this singleton datum is used by the events controller to dictate how it selects events /datum/round_event_control @@ -75,9 +74,11 @@ SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) return FALSE - //if(earliest_start >= world.time-SSticker.round_start_time) // BANDASTATION EDIT - STORYTELLER - if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) // BANDASTATION EDIT: Roundstart checks added + // BANDASTATION EDIT START - STORYTELLER + //if(earliest_start >= world.time-SSticker.round_start_time) + if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) return FALSE + // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) return FALSE if(players_amt < min_players) @@ -104,8 +105,8 @@ triggering = TRUE // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. - //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") // BANDASTATION EDIT - STORYTELLER - // BANDASTATION EDIT START - Only delay on roundstart + // BANDASTATION EDIT START - STORYTELLER + //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") if(SSticker.HasRoundStarted()) message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ CANCEL | \ diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 4ac0212449d55..d255cb3d47da5 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -18,3 +18,50 @@ #MIN_THREAT_TO_ROUNDSTART_PERCENT 30 #MAX_THREAT_TO_ROUNDSTART_PERCENT 60 #MIN_THREAT_LEVEL 20 + +## Gamemode configurations + +## Multipliers for points gained over time for event tracks. +MUNDANE_POINT_GAIN_MULTIPLIER 1 +MODERATE_POINT_GAIN_MULTIPLIER 1 +MAJOR_POINT_GAIN_MULTIPLIER 1 +CREWSET_POINT_GAIN_MULTIPLIER 1 +GHOSTSET_POINT_GAIN_MULTIPLIER 1 + +## Multipliers for points to spend on roundstart events. +MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 +MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 +MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 +CREWSET_ROUNDSTART_POINT_MULTIPLIER 1 +GHOSTSET_ROUNDSTART_POINT_MULTIPLIER 1 + +## Minimum population caps for event tracks to run their events. +MUNDANE_MIN_POP 0 +MODERATE_MIN_POP 0 +MAJOR_MIN_POP 20 +CREWSET_MIN_POP 0 +GHOSTSET_MIN_POP 0 + +## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. +MUNDANE_POINT_THRESHOLD 1 +MODERATE_POINT_THRESHOLD 1 +MAJOR_POINT_THRESHOLD 1 +CREWSET_POINT_THRESHOLD 1 +GHOSTSET_POINT_THRESHOLD 1 + +## Allows the storyteller to scale event frequencies based on population +ALLOW_STORYTELLER_POP_SCALING + +## Thresholds that population frequency scalling penalize up to. +MUNDANE_POP_SCALE_THRESHOLD 10 +MODERATE_POP_SCALE_THRESHOLD 15 +MAJOR_POP_SCALE_THRESHOLD 40 +CREWSET_POP_SCALE_THRESHOLD 45 +GHOSTSET_POP_SCALE_THRESHOLD 40 + +## The maximum penalties population scalling will apply to the tracks for having less pop than POP_SCALE_THRESHOLD. This is treated as percentages +MUNDANE_POP_SCALE_PENALTY 30 +MODERATE_POP_SCALE_PENALTY 30 +MAJOR_POP_SCALE_PENALTY 30 +CREWSET_POP_SCALE_PENALTY 30 +GHOSTSET_POP_SCALE_PENALTY 30 diff --git a/config/events.json b/config/bandastation/events.json similarity index 100% rename from config/events.json rename to config/bandastation/events.json diff --git a/config/game_options.txt b/config/game_options.txt index b233c64dde705..8300cdcac8cef 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -559,50 +559,3 @@ MAX_POSITIVE_QUIRKS 6 # If the value is lower than 1, it'll tend to even out the odds # If higher than 1, it'll lean toward common spawns even more. RANDOM_LOOT_WEIGHT_MODIFIER 1 - -## Gamemode configurations - -## Multipliers for points gained over time for event tracks. -MUNDANE_POINT_GAIN_MULTIPLIER 1 -MODERATE_POINT_GAIN_MULTIPLIER 1 -MAJOR_POINT_GAIN_MULTIPLIER 1 -CREWSET_POINT_GAIN_MULTIPLIER 1 -GHOSTSET_POINT_GAIN_MULTIPLIER 1 - -## Multipliers for points to spend on roundstart events. -MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 -MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 -MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 -CREWSET_ROUNDSTART_POINT_MULTIPLIER 1 -GHOSTSET_ROUNDSTART_POINT_MULTIPLIER 1 - -## Minimum population caps for event tracks to run their events. -MUNDANE_MIN_POP 0 -MODERATE_MIN_POP 0 -MAJOR_MIN_POP 20 -CREWSET_MIN_POP 0 -GHOSTSET_MIN_POP 0 - -## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. -MUNDANE_POINT_THRESHOLD 1 -MODERATE_POINT_THRESHOLD 1 -MAJOR_POINT_THRESHOLD 1 -CREWSET_POINT_THRESHOLD 1 -GHOSTSET_POINT_THRESHOLD 1 - -## Allows the storyteller to scale event frequencies based on population -ALLOW_STORYTELLER_POP_SCALING - -## Thresholds that population frequency scalling penalize up to. -MUNDANE_POP_SCALE_THRESHOLD 10 -MODERATE_POP_SCALE_THRESHOLD 15 -MAJOR_POP_SCALE_THRESHOLD 40 -CREWSET_POP_SCALE_THRESHOLD 45 -GHOSTSET_POP_SCALE_THRESHOLD 40 - -## The maximum penalties population scalling will apply to the tracks for having less pop than POP_SCALE_THRESHOLD. This is treated as percentages -MUNDANE_POP_SCALE_PENALTY 30 -MODERATE_POP_SCALE_PENALTY 30 -MAJOR_POP_SCALE_PENALTY 30 -CREWSET_POP_SCALE_PENALTY 30 -GHOSTSET_POP_SCALE_PENALTY 30 diff --git a/modular_bandastation/storyteller/_storyteller.dm b/modular_bandastation/storyteller/_storyteller.dm index 4e98148703137..2810c4aa3bbbf 100644 --- a/modular_bandastation/storyteller/_storyteller.dm +++ b/modular_bandastation/storyteller/_storyteller.dm @@ -1,4 +1,4 @@ -/datum/modpack/jukebox +/datum/modpack/storyteller name = "Storyteller mode" desc = "Адаптация режиме сторителлера для Bandastation." - author = "Хто-то" + author = "Bubberstation, KageIIte" diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 9412660fc39bb..74127fa42f50f 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -1,5 +1,6 @@ #include "_storyteller.dm" +#include "code\_defines\_persistence.dm" #include "code\_defines\storyteller_defines.dm" #include "code\_defines\storyteller_config.dm" @@ -31,7 +32,6 @@ #include "code\divergency_report.dm" #include "code\scheduled_event.dm" -#include "code\vote_reminder.dm" #include "code\vote.dm" #include "code\jobs_restrictions.dm" #include "code\gamemode.dm" @@ -39,8 +39,3 @@ #include "code\event_defines\_event.dm" #include "code\event_defines\override_events.dm" #include "code\event_defines\disabled_event_overrides.dm" - - - - - diff --git a/modular_bandastation/storyteller/code/_defines/_persistence.dm b/modular_bandastation/storyteller/code/_defines/_persistence.dm new file mode 100644 index 0000000000000..a4822efbb0204 --- /dev/null +++ b/modular_bandastation/storyteller/code/_defines/_persistence.dm @@ -0,0 +1,7 @@ +/datum/controller/subsystem/persistence + var/last_storyteller_type = "" + +/datum/controller/subsystem/persistence/Initialize() + . = ..() + load_storyteller_type() + return . diff --git a/modular_bandastation/storyteller/code/_defines/_ticker.dm b/modular_bandastation/storyteller/code/_defines/_ticker.dm new file mode 100644 index 0000000000000..b51b96443fb3b --- /dev/null +++ b/modular_bandastation/storyteller/code/_defines/_ticker.dm @@ -0,0 +1,3 @@ +/datum/controller/subsystem/ticker/PostSetup() + . = .. () + SSgamemode.post_setup() diff --git a/modular_bandastation/storyteller/code/divergency_report.dm b/modular_bandastation/storyteller/code/divergency_report.dm index 947dbaa158f73..8d5e7b2f87176 100644 --- a/modular_bandastation/storyteller/code/divergency_report.dm +++ b/modular_bandastation/storyteller/code/divergency_report.dm @@ -1,54 +1,47 @@ /datum/controller/subsystem/gamemode/proc/send_trait_report() - . = "Central Command Status Summary
" + . = "Информационное сообщение Департамента разведки Нанотрейзен, Сектор Спинвард, Дата [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR]:
" SSstation.generate_station_goals(20) - var/list/station_goals = SSstation.get_station_goals() - - if(!length(station_goals)) - . = "
No assigned goals.
" - else - . += generate_station_goal_report(station_goals) - if(!SSstation.station_traits.len) - . = "
No identified shift divergencies.
" - else - . += generate_station_trait_report() - - . += "
This concludes your shift-start evaluation. Have a secure shift!
\ -

This label certifies an Intern has reviewed the above before sending. This document is the property of Nanotrasen Corporation.

" - - print_command_report(., "Central Command Status Summary", announce = FALSE) - priority_announce("Hello, crew of [station_name()]. Our intern has finished their shift-start divergency and goals evaluation, which has been sent to your communications console. Have a secure shift!", "Divergency Report", SSstation.announcer.get_rand_report_sound()) + . += generate_station_goal_report() + . += generate_station_trait_report() + . += "
Это включает в себя вашу смену с начала до момента окончания. Удачной смены!
\ +

Этот ярлык подтверждает, что стажёр проверил вышеизложенное перед отправкой. Данный документ является собственностью корпорации Nanotrasen.

" + print_command_report(., "Отчет Центрального Коммандования", announce = FALSE) + priority_announce("Приветствуем вас, экипаж станции [station_name()]. Наш стажёр проверил отчет и возможные отклонения и направил вам результат. Хорошей смены!", "Протокол отклонений", SSstation.announcer.get_rand_report_sound()) /* * Generate a list of station goals available to purchase to report to the crew. * * Returns a formatted string all station goals that are available to the station. */ -/datum/controller/subsystem/gamemode/proc/generate_station_goal_report(var/list/station_goals) - . = "
Special Orders for [station_name()]:
" +/datum/controller/subsystem/gamemode/proc/generate_station_goal_report() + var/list/station_goals = SSstation.get_station_goals() + if(!length(station_goals)) + return "
Активные задачи - отсутствуют.
" var/list/goal_reports = list() for(var/datum/station_goal/station_goal as anything in station_goals) station_goal.on_report() goal_reports += station_goal.get_report() + return "
Специальные цели для [station_name()]:
[goal_reports.Join("
")]" - . += goal_reports.Join("
") - return /* * Generate a list of active station traits to report to the crew. * * Returns a formatted string of all station traits (that are shown) affecting the station. */ /datum/controller/subsystem/gamemode/proc/generate_station_trait_report() - if(!SSstation.station_traits.len) - return - . = "
Identified shift divergencies:
" + if(!length(SSstation.station_traits)) + return "
Нет выявленных отклонений на смене.
" + + var/list/station_traits_report = list("
Выявленные отклонения в смене:
") for(var/datum/station_trait/station_trait as anything in SSstation.station_traits) if(!station_trait.show_in_report) continue - . += "[station_trait.get_report()]
" - return + station_traits_report += "[station_trait.get_report()]
" + + return station_traits_report.Join() /*/datum/controller/subsystem/gamemode/proc/generate_station_goals() var/list/possible = subtypesof(/datum/station_goal) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index c1919c5c5ff10..f0f1adefc4778 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -4,7 +4,6 @@ /// Protected roles from the antag roll. People will not get those roles if a config is enabled var/protected_roles = list( JOB_CAPTAIN, - //JOB_BLUESHIELD, // Heads of staff JOB_HEAD_OF_PERSONNEL, @@ -13,22 +12,12 @@ JOB_CHIEF_MEDICAL_OFFICER, JOB_RESEARCH_DIRECTOR, JOB_QUARTERMASTER, - //JOB_NT_REP, // Seccies JOB_DETECTIVE, JOB_SECURITY_OFFICER, JOB_WARDEN, - //JOB_CORRECTIONS_OFFICER, JOB_PRISONER, - //JOB_SECURITY_MEDIC, - - // Department Guards-Additional - //JOB_BOUNCER, - //JOB_ORDERLY, - //JOB_CUSTOMS_AGENT, - //JOB_ENGINEERING_GUARD, - //JOB_SCIENCE_GUARD, ) /// Restricted roles from the antag roll diff --git a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm index 5e711975ee950..bae00f9d61760 100644 --- a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm +++ b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm @@ -16,10 +16,6 @@ weight = 0 max_occurrences = 0 -/datum/round_event_control/icarus_sunbeam - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) - /datum/round_event_control/dark_matteor track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 3b24b1f6c7dd5..3a892eccce9b8 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -28,9 +28,6 @@ /datum/round_event_control/meteor_wave/catastrophic weight = 0 -/datum/round_event_control/meteor_wave/ices - weight = 0 - /datum/round_event_control/radiation_storm track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL) @@ -69,23 +66,10 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) -/datum/round_event_control/cme - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL, TAG_CHAOTIC) - -/datum/round_event_control/stray_cargo/changeling_zombie - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC, TAG_SPOOKY) - /datum/round_event_control/pirates track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL, TAG_COMBAT) -/datum/round_event_control/cortical_borer - track = EVENT_TRACK_MAJOR - tags = list(TAG_TARGETED, TAG_SPOOKY) - min_players = 20 - /datum/round_event_control/morph track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 134799677af5e..6fe8e18d099ec 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -42,10 +42,5 @@ /datum/round_event_control/portal_storm_narsie tags = list(TAG_COMBAT, TAG_CHAOTIC) -/datum/round_event_control/mold - tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC) - weight = 0 - max_occurrences = 0 - /datum/round_event_control/obsessed tags = list(TAG_TARGETED) diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index 59593c8a7ef5e..816ebfdfa4e34 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -132,7 +132,3 @@ /datum/round_event_control/scrubber_overflow/every_vent weight = 0 max_occurrences = 0 - -/datum/round_event_control/scrubber_overflow/ices - weight = 0 - max_occurrences = 0 diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index c05847905257f..85eb5fccfadeb 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -596,7 +596,7 @@ SUBSYSTEM_DEF(gamemode) /// Loads json event config values from events.txt /datum/controller/subsystem/gamemode/proc/load_event_config_vars() - var/json_file = file("[global.config.directory]/events.json") + var/json_file = file("[global.config.directory]/bandastation/events.json") if(!fexists(json_file)) return var/list/decoded = json_decode(file2text(json_file)) diff --git a/modular_bandastation/storyteller/code/jobs_restrictions.dm b/modular_bandastation/storyteller/code/jobs_restrictions.dm index 7947064f44d68..a9634a56f6362 100644 --- a/modular_bandastation/storyteller/code/jobs_restrictions.dm +++ b/modular_bandastation/storyteller/code/jobs_restrictions.dm @@ -26,29 +26,3 @@ /datum/job/quartermaster antagonist_restricted = TRUE - -/* -/datum/job/nanotrasen_consultant - antagonist_restricted = TRUE - -/datum/job/blueshield - antagonist_restricted = TRUE - -/datum/job/corrections_officer - antagonist_restricted = TRUE - -/datum/job/orderly - antagonist_restricted = TRUE - -/datum/job/bouncer - antagonist_restricted = TRUE - -/datum/job/customs_agent - antagonist_restricted = TRUE - -/datum/job/engineering_guard - antagonist_restricted = TRUE - -/datum/job/science_guard - antagonist_restricted = TRUE -*/ diff --git a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm index 59eb76d4bd658..98323effca33c 100644 --- a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm +++ b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm @@ -3,8 +3,8 @@ /// Storyteller track data, for easy overriding of tracks without having to copypaste /// thresholds - Used to show how many points the track has to collect before it triggers, lower means faster /datum/storyteller_data/tracks - var/threshold_mundane = 1200 - var/threshold_moderate = 1800 - var/threshold_major = 8000 - var/threshold_crewset = 1200 - var/threshold_ghostset = 7000 + var/threshold_mundane = 1200 ///События категории Mundane - скруберы, валентинки, т.е. мелочь + var/threshold_moderate = 1800 ///События категории Moderate - аномалии, лозы, утечка радейки + var/threshold_major = 8000 ///События категории Major - пираты, рад-шторм, бюрократическая ошибка + var/threshold_crewset = 1200 ///События категории Crewset - еретики, генокрады, шпионы, трейторы, нюак, малф (когда активный член экипажа становится антагом (спящий агент)) + var/threshold_ghostset = 7000 ///События категории Ghostset - ниндзя, дракон (когда гостам предлагается роль антага) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index d9c001768db65..d7b464344802e 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -14,7 +14,7 @@ EVENT_TRACK_MODERATE = 1, EVENT_TRACK_MAJOR = 1, EVENT_TRACK_CREWSET = 1, - EVENT_TRACK_GHOSTSET = 1 + EVENT_TRACK_GHOSTSET = 1, ) /// The datum containing track size data var/datum/storyteller_data/tracks/track_data = /datum/storyteller_data/tracks @@ -54,19 +54,17 @@ /// Add points to all tracks while respecting the multipliers. /datum/storyteller/proc/add_points(delta_time) - var/datum/controller/subsystem/gamemode/mode = SSgamemode - for(var/track in mode.event_track_points) + for(var/track in SSgamemode.event_track_points) var/point_gain = delta_time - mode.event_track_points[track] += point_gain - mode.last_point_gains[track] = point_gain + SSgamemode.event_track_points[track] += point_gain + SSgamemode.last_point_gains[track] = point_gain /// Goes through every track of the gamemode and checks if it passes a threshold to buy an event, if does, buys one. /datum/storyteller/proc/handle_tracks() . = FALSE //Has return value for the roundstart loop - var/datum/controller/subsystem/gamemode/mode = SSgamemode - for(var/track in mode.event_track_points) - var/points = mode.event_track_points[track] - if(points >= mode.point_thresholds[track] && find_and_buy_event_from_track(track)) + for(var/track in SSgamemode.event_track_points) + var/points = SSgamemode.event_track_points[track] + if(points >= SSgamemode.point_thresholds[track] && find_and_buy_event_from_track(track)) . = TRUE /// Find and buy a valid event from a track. diff --git a/modular_bandastation/storyteller/code/vote.dm b/modular_bandastation/storyteller/code/vote.dm index 028a425cc72a1..899b7f1a55e77 100644 --- a/modular_bandastation/storyteller/code/vote.dm +++ b/modular_bandastation/storyteller/code/vote.dm @@ -1,4 +1,5 @@ -/datum/vote/var/has_desc = FALSE +/datum/vote/ + var/has_desc = FALSE /datum/vote/proc/return_desc(vote_name) return "" @@ -9,7 +10,6 @@ has_desc = TRUE count_method = VOTE_COUNT_METHOD_MULTI winner_method = VOTE_WINNER_METHOD_SIMPLE - vote_reminder = TRUE /datum/vote/storyteller/New() . = ..() diff --git a/modular_bandastation/storyteller/code/vote_reminder.dm b/modular_bandastation/storyteller/code/vote_reminder.dm deleted file mode 100644 index d70579b6019c0..0000000000000 --- a/modular_bandastation/storyteller/code/vote_reminder.dm +++ /dev/null @@ -1,36 +0,0 @@ -/// Следует наверно вынести в отдельный ПР? Напоминалка, что идет голосование. - -/datum/vote - /// Provide a reminder notification to those who haven't voted - var/vote_reminder = FALSE - /// Has the vote reminder fired yet - var/reminder_fired = FALSE - -/// Bubber vote fire proc, original at code/controllers/subsystem/vote.dm -/datum/controller/subsystem/vote/fire() - if(!current_vote) - return - - current_vote.time_remaining = round((current_vote.started_time + CONFIG_GET(number/vote_period) - world.time) / 10) - if(current_vote.time_remaining < 0) - end_vote() - return - - // We give a reminder to latejoiners who may have missed the original vote notification. - if(!current_vote.vote_reminder || current_vote.reminder_fired) - return - - if(current_vote.time_remaining > 45) - return - - current_vote.reminder_fired = TRUE - - for(var/client/late_voter as anything in GLOB.clients) - if(LAZYFIND(voted, late_voter.ckey)) // Skip people who already voted - continue - - if(current_vote.vote_sound && (late_voter.prefs.read_preference(/datum/preference/toggle/sound_announcements))) - SEND_SOUND(late_voter, sound(current_vote.vote_sound)) - - to_chat(late_voter, span_yellowteamradio(span_soapbox("It's time to make your choices for [current_vote.name]! Type 'vote' or click here to place your votes."))) - From a5ea27c7760dc20ea7272f9c7c09e735733aefce Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 22:31:12 +0300 Subject: [PATCH 007/135] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 3 +++ .../storyteller/code/_defines/storyteller_config.dm | 6 ++++++ modular_bandastation/storyteller/code/gamemode.dm | 9 +++++---- .../code/storytellers/tellers/_storyteller.dm | 12 ++++++------ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index d255cb3d47da5..12030a3900fbb 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -42,6 +42,9 @@ MAJOR_MIN_POP 20 CREWSET_MIN_POP 0 GHOSTSET_MIN_POP 0 +## Basic multiplayer for storytellers +STORYTELLER_MAX_SEC_BASE_MULT 1.5 + ## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. MUNDANE_POINT_THRESHOLD 1 MODERATE_POINT_THRESHOLD 1 diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm index b3c08c1fc81bb..a48e69717681a 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm @@ -67,6 +67,12 @@ integer = TRUE min_val = 0 +// Point Thresholds +/datum/config_entry/number/max_sec_mult + config_entry_value = STORYTELLER_MAX_SEC_BASE_MULT + integer = FALSE + min_val = 0 + // Point Thresholds /datum/config_entry/number/mundane_point_threshold config_entry_value = MUNDANE_POINT_THRESHOLD diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 85eb5fccfadeb..6d7ce70e61691 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -207,11 +207,11 @@ SUBSYSTEM_DEF(gamemode) return 0 if(!storyteller.antag_divisor) return 0 - return round(max(min(get_correct_popcount() / storyteller.antag_divisor + sec_crew ,sec_crew * 1.5),ANTAG_CAP_FLAT)) + return round(clamp(get_correct_popcount() / storyteller.antag_divisor + sec_crew, ANTAG_CAP_FLAT, sec_crew * storyteller.max_sec_mult)) /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() - return (get_antag_cap() > length(GLOB.current_living_antags)) + return get_antag_cap() > length(GLOB.current_living_antags) /// Gets candidates for antagonist roles. @@ -699,6 +699,7 @@ SUBSYSTEM_DEF(gamemode) storyteller = storytellers[passed_type] var/datum/storyteller_data/tracks/track_data = storyteller.track_data + storyteller.max_sec_mult = storyteller.max_sec_mult * CONFIG_GET(number/max_sec_mult) point_thresholds[EVENT_TRACK_MUNDANE] = track_data.threshold_mundane * CONFIG_GET(number/mundane_point_threshold) point_thresholds[EVENT_TRACK_MODERATE] = track_data.threshold_moderate * CONFIG_GET(number/moderate_point_threshold) point_thresholds[EVENT_TRACK_MAJOR] = track_data.threshold_major * CONFIG_GET(number/major_point_threshold) @@ -764,8 +765,8 @@ SUBSYSTEM_DEF(gamemode) even = !even var/background_cl = even ? "#17191C" : "#23273C" var/lower = event_track_points[track] - var/upper = point_thresholds[track] == 0 ? 1000000 : point_thresholds[track] // КРАШИТСЯ ЗДЕСЬ - CREWSET - трэк присылает 0 (временый фикс, 100000 это значит будет низкая вероятность) - var/percent = round((lower/upper)*100) // КРАШИТСЯ ЗДЕСЬ - CREWSET - трэк присылает 0 и делит на + var/upper = point_thresholds[track] + var/percent = round((lower/upper)*100) var/next = 0 var/last_points = last_point_gains[track] if(last_points) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index d7b464344802e..3e098a54cecbb 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -42,7 +42,8 @@ var/population_max /// The antag divisor, the higher it is the lower the antag cap gets. Basically means "for every antag_divisor crew, spawn 1 antag". var/antag_divisor = 8 - + /// Указывает множитель, который используется для максимального количества антагов относительно активного состава СБ, умноженного на этот множитель + var/max_sec_mult = 1 /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE @@ -108,18 +109,17 @@ /// Find and buy a valid event from a track. /datum/storyteller/proc/buy_event(datum/round_event_control/bought_event, track) - var/datum/controller/subsystem/gamemode/mode = SSgamemode // Perhaps use some bell curve instead of a flat variance? - var/total_cost = bought_event.cost * mode.point_thresholds[track] + var/total_cost = bought_event.cost * SSgamemode.point_thresholds[track] if(!bought_event.roundstart) total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event - mode.event_track_points[track] = max(0, mode.event_track_points[track] - total_cost) + SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") if(bought_event.roundstart) - mode.TriggerEvent(bought_event) + SSgamemode.TriggerEvent(bought_event) else - mode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) + SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) From f4b7b8509e01e4e79478b010ab098e2b97ca67c0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 22:32:52 +0300 Subject: [PATCH 008/135] =?UTF-8?q?=D0=A3=D0=BF=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/_defines/storyteller_defines.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 6ea31c3bace3d..5f2cf35fb75bf 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -46,6 +46,7 @@ #define GAMEMODE_PANEL_VARIABLES "Variables" /// Reused for multipliers of the thresholds +#define STORYTELLER_MAX_SEC_BASE_MULT 1.5 #define MUNDANE_POINT_THRESHOLD 1 #define MODERATE_POINT_THRESHOLD 1 #define MAJOR_POINT_THRESHOLD 1 From f31e551571ecf13056bdb45f9f5b912430a24490 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 18 Nov 2024 23:33:23 +0300 Subject: [PATCH 009/135] =?UTF-8?q?=D0=98=D0=B3=D1=80=D0=B0=20=D1=81=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/events.json | 13 ------------- config/bandastation/events.toml | 9 +++++++++ modular_bandastation/storyteller/code/gamemode.dm | 5 +---- 3 files changed, 10 insertions(+), 17 deletions(-) delete mode 100644 config/bandastation/events.json create mode 100644 config/bandastation/events.toml diff --git a/config/bandastation/events.json b/config/bandastation/events.json deleted file mode 100644 index a30ccaf58ab53..0000000000000 --- a/config/bandastation/events.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "/datum/round_event_control": - { - "weight" : 10, - "min_players" : 0, - "max_occurrences" : 100, - "earliest_start" : 20, - "track" : "Moderate", - "cost" : 1, - "reoccurence_penalty_multiplier" : 1, - "shared_occurence_type" : null - } -} diff --git a/config/bandastation/events.toml b/config/bandastation/events.toml new file mode 100644 index 0000000000000..fc0490b21ddc5 --- /dev/null +++ b/config/bandastation/events.toml @@ -0,0 +1,9 @@ +["/datum/round_event_control"] +weight = 10 +min_players = 0 +max_occurrences = 100 +earliest_start = 20 +track = "Moderate" +cost = 1 +reoccurence_penalty_multiplier = 1 +# shared_occurence_type diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 6d7ce70e61691..0a12f1389531a 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -596,10 +596,7 @@ SUBSYSTEM_DEF(gamemode) /// Loads json event config values from events.txt /datum/controller/subsystem/gamemode/proc/load_event_config_vars() - var/json_file = file("[global.config.directory]/bandastation/events.json") - if(!fexists(json_file)) - return - var/list/decoded = json_decode(file2text(json_file)) + var/list/decoded = rustg_read_toml_file("[global.config.directory]/bandastation/events.toml") for(var/event_text_path in decoded) var/event_path = text2path(event_text_path) var/datum/round_event_control/event From 0f788908c27d0c2d2cc7e797994fe3eac9fec70f Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 19 Nov 2024 09:28:04 +0300 Subject: [PATCH 010/135] =?UTF-8?q?=D0=92=D0=BE=D1=81=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=87=D0=B5?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=B8?= =?UTF-8?q?=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8,=20=D0=BF=D0=BB=D1=8E=D1=81=20=D1=80=D0=B5=D0=B2?= =?UTF-8?q?=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/_storyteller.dme | 2 +- .../crewset/_antagonist_event.dm | 3 -- .../event_defines/disabled_event_overrides.dm | 7 ---- .../code/event_defines/major/override.dm | 8 ++--- .../storyteller/code/gamemode.dm | 36 +++++++++---------- .../storyteller/code/jobs_restrictions.dm | 28 --------------- 6 files changed, 21 insertions(+), 63 deletions(-) delete mode 100644 modular_bandastation/storyteller/code/jobs_restrictions.dm diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 74127fa42f50f..5b4b38fcf12fb 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -1,6 +1,7 @@ #include "_storyteller.dm" #include "code\_defines\_persistence.dm" +#include "code\_defines\_ticker.dm" #include "code\_defines\storyteller_defines.dm" #include "code\_defines\storyteller_config.dm" @@ -33,7 +34,6 @@ #include "code\divergency_report.dm" #include "code\scheduled_event.dm" #include "code\vote.dm" -#include "code\jobs_restrictions.dm" #include "code\gamemode.dm" #include "code\event_defines\_event.dm" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index f0f1adefc4778..1978b70250cb4 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -48,9 +48,6 @@ restricted_roles |= SSstation.antag_protected_roles if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_roles |= JOB_ASSISTANT - for(var/datum/job/iterating_job as anything in subtypesof(/datum/job)) - if(initial(iterating_job.restricted_antagonists)) - restricted_roles |= initial(iterating_job.title) /datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) . = ..() diff --git a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm index bae00f9d61760..ebc38b5904f22 100644 --- a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm +++ b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm @@ -19,10 +19,3 @@ /datum/round_event_control/dark_matteor track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) - -/datum/round_event_control/wizard - tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) - -/datum/round_event_control/mutant_infestation - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 3a892eccce9b8..d343042aad197 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -70,10 +70,10 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL, TAG_COMBAT) -/datum/round_event_control/morph - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) - /datum/round_event_control/operative track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) + +/datum/round_event_control/wizard + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0a12f1389531a..4cab9ef68980b 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -234,8 +234,7 @@ SUBSYSTEM_DEF(gamemode) if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) candidate_candidates += player else if(pick_observers) - for(var/mob/player as anything in GLOB.dead_mob_list) - candidate_candidates += player + candidate_candidates += GLOB.dead_mob_list else for(var/datum/record/locked/manifest_log as anything in GLOB.manifest.locked) var/datum/mind/player_mind = manifest_log.mind_ref.resolve() @@ -279,9 +278,9 @@ SUBSYSTEM_DEF(gamemode) if(SSticker.HasRoundStarted()) update_crew_infos() return active_players - else - calculate_ready_players() - return ready_players + + calculate_ready_players() + return ready_players /// Refunds and removes a scheduled event. /datum/controller/subsystem/gamemode/proc/refund_scheduled_event(datum/scheduled_event/refunded) @@ -356,9 +355,7 @@ SUBSYSTEM_DEF(gamemode) for(var/datum/round_event/event as anything in running) if(!event.control.roundstart) continue - ASYNC - event.try_start() -// INVOKE_ASYNC(event, /datum/round_event.proc/try_start) + INVOKE_ASYNC(event, TYPE_PROC_REF(/datum/round_event, try_start)) /// Schedules an event to run later. /datum/controller/subsystem/gamemode/proc/schedule_event(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) @@ -380,9 +377,9 @@ SUBSYSTEM_DEF(gamemode) for(var/mob/player_mob as anything in GLOB.player_list) if(!player_mob.client) continue - if(player_mob.stat) //If they're alive + if(player_mob.stat) continue - if(player_mob.client.is_afk()) //If afk + if(player_mob.client.is_afk()) continue if(!ishuman(player_mob)) continue @@ -521,12 +518,7 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/check_finished(force_ending) //to be called by SSticker if(!SSticker.setup_done) return FALSE - if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) - return TRUE - if(GLOB.station_was_nuked) - return TRUE - if(force_ending) - return TRUE + return force_ending || GLOB.station_was_nuked || SSshuttle?.emergency?.mode == SHUTTLE_ENDGAME ////////////////////////// //Reports player logouts// @@ -596,7 +588,13 @@ SUBSYSTEM_DEF(gamemode) /// Loads json event config values from events.txt /datum/controller/subsystem/gamemode/proc/load_event_config_vars() - var/list/decoded = rustg_read_toml_file("[global.config.directory]/bandastation/events.toml") + var/file_path = "[global.config.directory]/bandastation/events.toml" + var/toml_file = file(file_path) + if(!fexists(toml_file)) + return + var/list/decoded = rustg_read_toml_file(file_path) + if(!length(decoded )) + return for(var/event_text_path in decoded) var/event_path = text2path(event_text_path) var/datum/round_event_control/event @@ -626,9 +624,7 @@ SUBSYSTEM_DEF(gamemode) if("reoccurence_penalty_multiplier") event.reoccurence_penalty_multiplier = value if("shared_occurence_type") - if(!isnull(value)) - value = text2path(value) - event.shared_occurence_type = value + event.shared_occurence_type= !isnull(value) ? text2path(value) : null /// Loads config values from game_options.txt /datum/controller/subsystem/gamemode/proc/load_config_vars() diff --git a/modular_bandastation/storyteller/code/jobs_restrictions.dm b/modular_bandastation/storyteller/code/jobs_restrictions.dm deleted file mode 100644 index a9634a56f6362..0000000000000 --- a/modular_bandastation/storyteller/code/jobs_restrictions.dm +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Job antagonist restriction file - * - * Add relative restrictions to any jobs that you wish to prevent from being - * an antagonist. If you set antagonist_restricted to true without setting restricted_antagonist, - * then the job will be restricted from all antagonists. - */ - -/datum/job - /// Do we allow this job to be an antag of any kind? - var/antagonist_restricted = FALSE - /// If we restrict this job from antagonists, what antags? Leave blank for all antags. - var/list/restricted_antagonists - -/datum/job/head_of_personnel - antagonist_restricted = TRUE - -/datum/job/chief_engineer - antagonist_restricted = TRUE - -/datum/job/chief_medical_officer - antagonist_restricted = TRUE - -/datum/job/research_director - antagonist_restricted = TRUE - -/datum/job/quartermaster - antagonist_restricted = TRUE From ac23d371ead5a4729795edcf4bc673c38cd05c34 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 20 Nov 2024 08:31:47 +0300 Subject: [PATCH 011/135] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subsystem/persistence/_persistence.dm | 1 - .../storyteller/code/divergency_report.dm | 11 +---------- .../storyteller/code/storytellers/data/tracks.dm | 15 ++++++++++----- modular_bandastation/storyteller/code/vote.dm | 2 +- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index 3d14e1659bddc..d38d7fa372e25 100644 --- a/code/controllers/subsystem/persistence/_persistence.dm +++ b/code/controllers/subsystem/persistence/_persistence.dm @@ -71,7 +71,6 @@ SUBSYSTEM_DEF(persistence) load_delamination_counter() load_tram_counter() load_adventures() - load_storyteller_type() // BANDASTATION EDIT ADD - Storyteller return SS_INIT_SUCCESS ///Collects all data to persist. diff --git a/modular_bandastation/storyteller/code/divergency_report.dm b/modular_bandastation/storyteller/code/divergency_report.dm index 8d5e7b2f87176..9c0e715486c4b 100644 --- a/modular_bandastation/storyteller/code/divergency_report.dm +++ b/modular_bandastation/storyteller/code/divergency_report.dm @@ -8,7 +8,7 @@ . += "
Это включает в себя вашу смену с начала до момента окончания. Удачной смены!
\

Этот ярлык подтверждает, что стажёр проверил вышеизложенное перед отправкой. Данный документ является собственностью корпорации Nanotrasen.

" - print_command_report(., "Отчет Центрального Коммандования", announce = FALSE) + print_command_report(., "Отчет Центрального Командования", announce = FALSE) priority_announce("Приветствуем вас, экипаж станции [station_name()]. Наш стажёр проверил отчет и возможные отклонения и направил вам результат. Хорошей смены!", "Протокол отклонений", SSstation.announcer.get_rand_report_sound()) /* @@ -42,12 +42,3 @@ station_traits_report += "[station_trait.get_report()]
" return station_traits_report.Join() - -/*/datum/controller/subsystem/gamemode/proc/generate_station_goals() - var/list/possible = subtypesof(/datum/station_goal) - var/goal_weights = 0 - while(possible.len && goal_weights < 1) // station goal budget is 1 - var/datum/station_goal/picked = pick_n_take(possible) - goal_weights += initial(picked.weight) - SSstation.goals_by_type += new picked // does this still work? -*/ diff --git a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm index 98323effca33c..ba473c07cb9ba 100644 --- a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm +++ b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm @@ -3,8 +3,13 @@ /// Storyteller track data, for easy overriding of tracks without having to copypaste /// thresholds - Used to show how many points the track has to collect before it triggers, lower means faster /datum/storyteller_data/tracks - var/threshold_mundane = 1200 ///События категории Mundane - скруберы, валентинки, т.е. мелочь - var/threshold_moderate = 1800 ///События категории Moderate - аномалии, лозы, утечка радейки - var/threshold_major = 8000 ///События категории Major - пираты, рад-шторм, бюрократическая ошибка - var/threshold_crewset = 1200 ///События категории Crewset - еретики, генокрады, шпионы, трейторы, нюак, малф (когда активный член экипажа становится антагом (спящий агент)) - var/threshold_ghostset = 7000 ///События категории Ghostset - ниндзя, дракон (когда гостам предлагается роль антага) + ///События категории Mundane - скруберы, валентинки, т.е. мелочь + var/threshold_mundane = 1200 + ///События категории Moderate - аномалии, лозы, утечка радейки + var/threshold_moderate = 1800 + ///События категории Major - пираты, рад-шторм, бюрократическая ошибка + var/threshold_major = 8000 + ///События категории Crewset - еретики, генокрады, шпионы, трейторы, нюак, малф (когда активный член экипажа становится антагом (спящий агент)) + var/threshold_crewset = 1200 + ///События категории Ghostset - ниндзя, дракон (когда гостам предлагается роль антага) + var/threshold_ghostset = 7000 diff --git a/modular_bandastation/storyteller/code/vote.dm b/modular_bandastation/storyteller/code/vote.dm index 899b7f1a55e77..32e4bfa7976f4 100644 --- a/modular_bandastation/storyteller/code/vote.dm +++ b/modular_bandastation/storyteller/code/vote.dm @@ -1,4 +1,4 @@ -/datum/vote/ +/datum/vote var/has_desc = FALSE /datum/vote/proc/return_desc(vote_name) From 17af59a4b64091630615c71c836bbfb75037fdd5 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 21 Nov 2024 00:31:44 +0300 Subject: [PATCH 012/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B4=D0=B8?= =?UTF-8?q?=D0=BA=D0=BE=D1=81=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 5 ++++- modular_bandastation/storyteller/_storyteller.dme | 1 - .../event_defines/crewset/_antagonist_event.dm | 2 +- .../code/event_defines/crewset/changeling.dm | 4 ---- .../code/event_defines/crewset/spies.dm | 14 -------------- 5 files changed, 5 insertions(+), 21 deletions(-) delete mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/spies.dm diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index c0e4a48bd796d..76c77238c4825 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -12,7 +12,7 @@ //10 is the default weight. 20 is twice more likely; 5 is half as likely as this default. //0 here does NOT disable the event, it just makes it extremely unlikely - var/earliest_start = 20 MINUTES //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins + var/earliest_start = 20 MINUTES //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins ///BANDASTATION EDIT - STORYTELLER var/min_players = 0 //The minimum amount of alive, non-AFK human players on server required to start the event. var/occurrences = 0 //How many times this event has occurred @@ -198,6 +198,9 @@ Runs the event if(alert_observers) round_event.announce_deadchat(random, event_cause) + log_admin_private("[random ? "Random" : "Forced"] Event triggering: [name] ([typepath]).") + message_admins(span_adminnotice("[random ? "Random" : "Forced"] Event triggering: [name] ([typepath]).")) + SSblackbox.record_feedback("tally", "event_ran", 1, "[round_event]") return round_event diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 5b4b38fcf12fb..54a96b6b2ab09 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -10,7 +10,6 @@ #include "code\event_defines\crewset\heretic.dm" #include "code\event_defines\crewset\malf.dm" #include "code\event_defines\crewset\nuke_ops.dm" -#include "code\event_defines\crewset\spies.dm" #include "code\event_defines\crewset\traitors.dm" #include "code\event_defines\ghostset\override.dm" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 1978b70250cb4..b529909daed9d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -53,7 +53,7 @@ . = ..() if(!.) return - if(!roundstart && !SSgamemode.can_inject_antags()) + if(roundstart || !SSgamemode.can_inject_antags()) return FALSE if(!get_antag_amount()) return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index aa39cf7f451e6..497a4ab51abf4 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -9,7 +9,3 @@ maximum_antags_global = 4 tags = list(TAG_COMBAT, TAG_CREW_ANTAG) - -/datum/round_event_control/antagonist/solo/changeling/midround - name = "Genome Awakening (Changelings)" - roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm deleted file mode 100644 index f4a94625fb33a..0000000000000 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ /dev/null @@ -1,14 +0,0 @@ -/datum/round_event_control/antagonist/solo/spy - name = "Spies" - roundstart = TRUE - - antag_flag = ROLE_SPY - antag_datum = /datum/antagonist/spy - weight = 8 - maximum_antags_global = 4 - - tags = list(TAG_CREW_ANTAG) - -/datum/round_event_control/antagonist/solo/spy/midround - name = "Spies (Midround)" - roundstart = FALSE From 16a07c749c5f84bf1a689cea8bbb4e2f53a3366e Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 21 Nov 2024 18:55:18 +0300 Subject: [PATCH 013/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=BC=D1=83=D0=BD=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 2 +- modular_bandastation/storyteller/_storyteller.dme | 1 + .../code/_defines/storyteller_config.dm | 2 +- .../code/_defines/storyteller_defines.dm | 3 ++- .../code/event_defines/crewset/nuke_ops.dm | 2 +- .../code/event_defines/crewset/spies.dm | 14 ++++++++++++++ .../code/event_defines/major/override.dm | 1 + modular_bandastation/storyteller/code/gamemode.dm | 12 +++++++++--- 8 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/spies.dm diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 12030a3900fbb..613224e237037 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -43,7 +43,7 @@ CREWSET_MIN_POP 0 GHOSTSET_MIN_POP 0 ## Basic multiplayer for storytellers -STORYTELLER_MAX_SEC_BASE_MULT 1.5 +MAX_SEC_MULT 1.5 ## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. MUNDANE_POINT_THRESHOLD 1 diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 54a96b6b2ab09..5b4b38fcf12fb 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -10,6 +10,7 @@ #include "code\event_defines\crewset\heretic.dm" #include "code\event_defines\crewset\malf.dm" #include "code\event_defines\crewset\nuke_ops.dm" +#include "code\event_defines\crewset\spies.dm" #include "code\event_defines\crewset\traitors.dm" #include "code\event_defines\ghostset\override.dm" diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm index a48e69717681a..c8a5b2c0d35cb 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm @@ -69,7 +69,7 @@ // Point Thresholds /datum/config_entry/number/max_sec_mult - config_entry_value = STORYTELLER_MAX_SEC_BASE_MULT + config_entry_value = MAX_SEC_MULT integer = FALSE min_val = 0 diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 5f2cf35fb75bf..f07e295ac7927 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -45,8 +45,9 @@ #define GAMEMODE_PANEL_MAIN "Main" #define GAMEMODE_PANEL_VARIABLES "Variables" +#define MAX_SEC_MULT 1.5 + /// Reused for multipliers of the thresholds -#define STORYTELLER_MAX_SEC_BASE_MULT 1.5 #define MUNDANE_POINT_THRESHOLD 1 #define MODERATE_POINT_THRESHOLD 1 #define MAJOR_POINT_THRESHOLD 1 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 7dc3a43cfd204..0032f31f0a1ad 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -6,7 +6,7 @@ antag_datum = /datum/antagonist/nukeop antag_leader_datum = /datum/antagonist/nukeop/leader - weight = 0 + weight = 6 tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) base_antags = 2 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm new file mode 100644 index 0000000000000..24e88c102eb63 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -0,0 +1,14 @@ +/datum/round_event_control/antagonist/solo/spy + name = "Spies" + roundstart = TRUE + + antag_flag = ROLE_SPY + antag_datum = /datum/antagonist/spy + weight = 0 + maximum_antags_global = 4 + + tags = list(TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/spy/midround + name = "Spies (Midround)" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index d343042aad197..231a13872b58a 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -76,4 +76,5 @@ /datum/round_event_control/wizard track = EVENT_TRACK_MAJOR + weight = 5 tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 4cab9ef68980b..e05aa77910612 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -128,6 +128,7 @@ SUBSYSTEM_DEF(gamemode) var/eng_crew = 0 var/sec_crew = 0 var/med_crew = 0 + var/rnd_crew = 0 var/wizardmode = FALSE @@ -207,7 +208,11 @@ SUBSYSTEM_DEF(gamemode) return 0 if(!storyteller.antag_divisor) return 0 - return round(clamp(get_correct_popcount() / storyteller.antag_divisor + sec_crew, ANTAG_CAP_FLAT, sec_crew * storyteller.max_sec_mult)) + var/max_antags = sec_crew * storyteller.max_sec_mult + var/min_antags = ANTAG_CAP_FLAT + var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew + var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) + return round(clamped_cap) /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() @@ -692,7 +697,8 @@ SUBSYSTEM_DEF(gamemode) storyteller = storytellers[passed_type] var/datum/storyteller_data/tracks/track_data = storyteller.track_data - storyteller.max_sec_mult = storyteller.max_sec_mult * CONFIG_GET(number/max_sec_mult) + var/config_sec_mult = CONFIG_GET(number/max_sec_mult) + storyteller.max_sec_mult = storyteller.max_sec_mult * config_sec_mult point_thresholds[EVENT_TRACK_MUNDANE] = track_data.threshold_mundane * CONFIG_GET(number/mundane_point_threshold) point_thresholds[EVENT_TRACK_MODERATE] = track_data.threshold_moderate * CONFIG_GET(number/moderate_point_threshold) point_thresholds[EVENT_TRACK_MAJOR] = track_data.threshold_major * CONFIG_GET(number/major_point_threshold) @@ -711,7 +717,7 @@ SUBSYSTEM_DEF(gamemode) dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." - dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew]) - Antag Cap: [get_antag_cap()]" + dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [med_crew]) - Antag Cap: [get_antag_cap()]" dat += "
" dat += "Main" dat += " Variables" From c53726dabf2a8f1d327bed029e7c6860a2a5268c Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 21 Nov 2024 19:32:04 +0300 Subject: [PATCH 014/135] =?UTF-8?q?=D0=A1=D0=BD=D0=B8=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B=D1=85=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=AD=D0=BD=D0=B4=D0=B8,=20=D0=B2=D1=8B=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=20=D0=B3=D0=BE=D0=BB=D0=BE=D1=81=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F,=20=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=BE=D0=B4=D1=81=D1=87=D0=B5=D1=82=D0=B0=20(?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D0=B0=20=D0=B2=20=D0=BC=D0=B5=D0=BD=D1=8E)?= =?UTF-8?q?=20=D1=80=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 4 +++- .../storyteller/code/storytellers/data/tracks.dm | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index fe5c69781ab7c..9463186a63e8d 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(ticker) to_chat(world, span_notice("Welcome to [station_name()]!")) send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.current_map.map_name]!"), CONFIG_GET(string/channel_announce_new_game)) current_state = GAME_STATE_PREGAME - SSvote.initiate_vote(/datum/vote/storyteller, "Storyteller Vote", forced = TRUE) // BANDASTATION EDIT ADDITION + //SSvote.initiate_vote(/datum/vote/storyteller, "Storyteller Vote", forced = TRUE) // BANDASTATION EDIT ADDITION SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) fire() diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index e05aa77910612..7920cf2ae2242 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -399,6 +399,8 @@ SUBSYSTEM_DEF(gamemode) med_crew++ if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) sec_crew++ + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) + rnd_crew++ /datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event) . = event.preRunEvent() @@ -717,7 +719,7 @@ SUBSYSTEM_DEF(gamemode) dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." - dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [med_crew]) - Antag Cap: [get_antag_cap()]" + dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [rnd_crew]) - Antag Cap: [get_antag_cap()]" dat += "
" dat += "Main" dat += " Variables" diff --git a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm index ba473c07cb9ba..7ae58b66d2aa6 100644 --- a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm +++ b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm @@ -8,8 +8,8 @@ ///События категории Moderate - аномалии, лозы, утечка радейки var/threshold_moderate = 1800 ///События категории Major - пираты, рад-шторм, бюрократическая ошибка - var/threshold_major = 8000 + var/threshold_major = 4000 ///События категории Crewset - еретики, генокрады, шпионы, трейторы, нюак, малф (когда активный член экипажа становится антагом (спящий агент)) var/threshold_crewset = 1200 ///События категории Ghostset - ниндзя, дракон (когда гостам предлагается роль антага) - var/threshold_ghostset = 7000 + var/threshold_ghostset = 4000 From 144cc89080df42d5e620bec38f6466b135c8c9ea Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 21 Nov 2024 20:15:09 +0300 Subject: [PATCH 015/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD?= =?UTF-8?q?=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 76c77238c4825..225de1400927c 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -108,20 +108,22 @@ // BANDASTATION EDIT START - STORYTELLER //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") if(SSticker.HasRoundStarted()) - message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ + message_admins("Storyteller: Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ CANCEL | \ SOMETHING ELSE)") for(var/client/staff as anything in GLOB.admins) if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) + if(!roundstart) + sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) if(triggering) - message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ + message_admins("Storyteller: Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ CANCEL | \ SOMETHING ELSE)") - sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) + if(!roundstart) + sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) else message_admins(" Roundstart event chosen: [name].") // BANDASTATION EDIT END From 732f82c22c8b0648301f904d1a5519126c53b7cc Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 21 Nov 2024 21:01:22 +0300 Subject: [PATCH 016/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_event.dm | 8 ++++++++ .../storyteller/code/storytellers/tellers/_storyteller.dm | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_event.dm b/modular_bandastation/storyteller/code/event_defines/_event.dm index 232381eddb3b7..b10e49c470904 100644 --- a/modular_bandastation/storyteller/code/event_defines/_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_event.dm @@ -75,3 +75,11 @@ message_admins("[key_name_admin(usr)] has forced scheduled event [src.name].") log_admin_private("[key_name(usr)] has forced scheduled event [src.name].") SSgamemode.force_event(src) + if("schedule") + message_admins("[key_name_admin(usr)] has scheduled event [src.name].") + log_admin_private("[key_name(usr)] has scheduled event [src.name].") + SSgamemode.schedule_event(src) + if("fire") + message_admins("[key_name_admin(usr)] has fired event [src.name].") + log_admin_private("[key_name(usr)] has fired event [src.name].") + SSgamemode.fire(src) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index 3e098a54cecbb..d77eeefd4f36a 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -94,8 +94,8 @@ valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track].") - log_admin("Storyteller failed to pick an event for track of [track].") + message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") + log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER return picked_event = pick_weight(valid_events) From 84faa632d64fd717bc4f0a42fafffc1df7fa4927 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 22 Nov 2024 01:36:57 +0300 Subject: [PATCH 017/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=B1=D0=B0=20=D1=82=D1=80=D0=B8=D0=B3=D0=B3?= =?UTF-8?q?=D0=B5=D1=80=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=20(=D0=B2=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=20=D0=B2=20=D1=80=D0=B0=D1=81=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=88=D0=B5=D0=B4=D1=83=D0=BB=D0=BB?= =?UTF-8?q?=D0=B5=D1=80=D0=B0),=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20SSevent,?= =?UTF-8?q?=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D1=81=D0=B0=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=80=D0=B5=D0=BB=D1=8C=D0=B1=D1=8B=20=D0=B8?= =?UTF-8?q?=D0=B2=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=B8=D0=BD=D0=B8=D1=86=D0=B0=D0=B8=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D0=A1=D0=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 6 +++- code/modules/admin/force_event.dm | 32 ++++++++++++------- .../code/event_defines/crewset/changeling.dm | 2 +- .../code/event_defines/crewset/heretic.dm | 2 +- .../code/event_defines/crewset/malf.dm | 1 + .../code/event_defines/crewset/nuke_ops.dm | 1 + .../code/event_defines/crewset/spies.dm | 2 +- .../code/event_defines/crewset/traitors.dm | 2 +- .../storyteller/code/gamemode.dm | 1 + 9 files changed, 33 insertions(+), 16 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 38fbdaa793bbb..b2b57f863126f 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -64,7 +64,6 @@ SUBSYSTEM_DEF(events) //decides which world.time we should select another random event at. /datum/controller/subsystem/events/proc/reschedule() scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper)) - /** * Selects a random event based on whether it can occur and its 'weight'(probability) * @@ -101,11 +100,16 @@ SUBSYSTEM_DEF(events) ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. /datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger) + /* /// BANDASTATION EDIT START - STORYTELLER - потому-что в жопу вашу систему . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) event_to_trigger.run_event(random = TRUE) + */ /// BANDASTATION EDIT END - STORYTELLER + message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm index 519adbd8a9e5c..f511eb2883aed 100644 --- a/code/modules/admin/force_event.dm +++ b/code/modules/admin/force_event.dm @@ -55,13 +55,22 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM "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, - "has_customization" = !!length(event_control.admin_setup), - )) + if (!SSticker.HasRoundStarted() && event_control.roundstart) + UNTYPED_LIST_ADD(events, list( + "name" = event_control.name, + "description" = event_control.description, + "type" = event_control.type, + "category" = event_control.category, + "has_customization" = !!length(event_control.admin_setup), + )) + if (SSticker.HasRoundStarted() && !event_control.roundstart) + UNTYPED_LIST_ADD(events, list( + "name" = event_control.name, + "description" = event_control.description, + "type" = event_control.type, + "category" = event_control.category, + "has_customization" = !!length(event_control.admin_setup), + )) data["categories"] = categories data["events"] = events return data @@ -73,7 +82,7 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM return switch(action) if("forceevent") - var/announce_event = params["announce"] + //var/announce_event = params["announce"] /// BANDASTATION EDIT - STORYTELLER var/string_path = params["type"] if(!string_path) return @@ -87,8 +96,9 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM for(var/datum/event_admin_setup/admin_setup_datum as anything in event.admin_setup) if(admin_setup_datum.prompt_admins() == ADMIN_CANCEL_EVENT) return - var/always_announce_chance = 100 - var/no_announce_chance = 0 - event.run_event(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) + //var/always_announce_chance = 100 /// BANDASTATION EDIT - STORYTELLER + //var/no_announce_chance = 0 /// BANDASTATION EDIT - STORYTELLER + //event.run_event(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) /// BANDASTATION EDIT - STORYTELLER + SSgamemode.TriggerEvent(event) 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/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 497a4ab51abf4..cff9da46d5357 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -7,5 +7,5 @@ weight = 8 min_players = 20 maximum_antags_global = 4 - + category = EVENT_CATEGORY_INVASION tags = list(TAG_COMBAT, TAG_CREW_ANTAG) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 60516d48d28c7..bae5faf565b06 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -8,7 +8,7 @@ min_players = 30 maximum_antags_global = 2 - + category = EVENT_CATEGORY_INVASION tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CREW_ANTAG) /datum/round_event_control/antagonist/solo/heretic/New() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index d8007587c4cbd..9e78b7e2c5189 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -14,6 +14,7 @@ weight = 1 tags = list(TAG_CREW_ANTAG, TAG_COMBAT, TAG_DESTRUCTIVE, TAG_CHAOTIC) restricted_roles = list() + category = EVENT_CATEGORY_AI /datum/round_event_control/antagonist/solo/malf/get_candidates() return GLOB.ai_list diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 0032f31f0a1ad..5ead094535c6f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -16,6 +16,7 @@ typepath = /datum/round_event/antagonist/team/nukie ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + category = EVENT_CATEGORY_INVASION /datum/round_event/antagonist/team/nukie var/datum/job/job_type = /datum/job/nuclear_operative diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index 24e88c102eb63..b4d3a008a4d4d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -6,7 +6,7 @@ antag_datum = /datum/antagonist/spy weight = 0 maximum_antags_global = 4 - + category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) /datum/round_event_control/antagonist/solo/spy/midround diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 8c2ea190743b0..a231b1ca0909a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -6,7 +6,7 @@ antag_datum = /datum/antagonist/traitor weight = 16 maximum_antags_global = 6 - + category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) /datum/round_event_control/antagonist/solo/traitor/midround diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 7920cf2ae2242..bd75e321d37eb 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -136,6 +136,7 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/Initialize(time, zlevel) . = ..() + SSevents.flags |= SS_NO_FIRE // Populate event pools for(var/track in event_tracks) event_pools[track] = list() From 989a270dcf0e40bedddee59c9aec5e1f784f6fda Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 22 Nov 2024 21:24:17 +0300 Subject: [PATCH 018/135] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F,=20=D0=BF=D0=BE=D0=B6=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 10 ++-- code/modules/events/_event.dm | 22 ++++++- .../storyteller/_storyteller.dme | 4 ++ .../storyteller/code/event_defines/_event.dm | 2 +- .../crewset/_antagonist_event.dm | 14 ++++- .../event_defines/crewset/blood_brothers.dm | 38 ++++++++++++ .../code/event_defines/crewset/clown_ops.dm | 44 ++++++++++++++ .../code/event_defines/crewset/cult.dm | 44 ++++++++++++++ .../code/event_defines/crewset/revolution.dm | 60 +++++++++++++++++++ .../code/event_defines/major/override.dm | 11 ++-- .../code/event_defines/moderate/override.dm | 5 ++ .../code/event_defines/mundane/override.dm | 10 ++++ .../storyteller/code/gamemode.dm | 6 +- .../storyteller/code/scheduled_event.dm | 6 +- 14 files changed, 253 insertions(+), 23 deletions(-) create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/cult.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index b2b57f863126f..987d7612bd642 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -100,16 +100,14 @@ SUBSYSTEM_DEF(events) ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. /datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger) - /* /// BANDASTATION EDIT START - STORYTELLER - потому-что в жопу вашу систему . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) - event_to_trigger.run_event(random = TRUE) - */ /// BANDASTATION EDIT END - STORYTELLER - message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") - log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") - SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) + message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) + //event_to_trigger.run_event(random = TRUE) /// BANDASTATION EDIT - STORYTELLER - переброска ивентов в запланированные, вместо самоспавна ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 225de1400927c..3150b4221a69b 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -1,4 +1,4 @@ -#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (2 MINUTES) // BANDASTATION EDIT CHANGE - STORYTELLER. Original: 10 SECONDS +#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (10 SECONDS) // BANDASTATION EDIT CHANGE - STORYTELLER. Original: 10 SECONDS //this singleton datum is used by the events controller to dictate how it selects events /datum/round_event_control @@ -73,29 +73,45 @@ /datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) + message_admins("Event: [name] was unable to run due max occurrence limit.") + log_admin("Scheduled Event: [name] was unable to run due max occurrence limit.") return FALSE // BANDASTATION EDIT START - STORYTELLER //if(earliest_start >= world.time-SSticker.round_start_time) if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) + message_admins("Event: [name] was unable to run due earliest start timer limit.") + log_admin("Scheduled Event: [name] was unable to run due mearliest start timer limit.") return FALSE // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) + message_admins("Event: [name] was unable to run due magic not allowed and it's wizard mode.") + log_admin("Scheduled Event: [name] was unable to run due magic not allowed and it's wizard mode.") return FALSE if(players_amt < min_players) + message_admins("Event: [name] was unable to run due too low players for event.") + log_admin("Scheduled Event: [name] was unable to run due too low players for event.") return FALSE if(holidayID && !check_holidays(holidayID)) + message_admins("Event: [name] was unable to run due try to run on non-holiday day.") + log_admin("Scheduled Event: [name] was unable to run due try to run on non-holiday day.") return FALSE if(EMERGENCY_ESCAPED_OR_ENDGAMED) + message_admins("Event: [name] was unable to run due escaped or endgamed.") + log_admin("Scheduled Event: [name] was unable to run due escaped or endgamed.") return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) + message_admins("Event: [name] was unable to run due it's ghost role for not midround event.") + log_admin("Scheduled Event: [name] was unable to run due it's ghost role for not midround event.") return FALSE if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) + message_admins("Event: [name] was unable to run due hijack in progress.") + log_admin("Scheduled Event: [name] was unable to run due hijack in progress.") return FALSE return TRUE -/datum/round_event_control/proc/preRunEvent() +/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE) if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN @@ -115,7 +131,7 @@ if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - if(!roundstart) + if(!roundstart && !admin_forced) sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) if(triggering) diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 5b4b38fcf12fb..8d7029eb4ffab 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -12,6 +12,10 @@ #include "code\event_defines\crewset\nuke_ops.dm" #include "code\event_defines\crewset\spies.dm" #include "code\event_defines\crewset\traitors.dm" +#include "code\event_defines\crewset\blood_brothers.dm" +#include "code\event_defines\crewset\cult.dm" +#include "code\event_defines\crewset\clown_ops.dm" +#include "code\event_defines\crewset\revolution.dm" #include "code\event_defines\ghostset\override.dm" #include "code\event_defines\ghostset\voidwalker.dm" diff --git a/modular_bandastation/storyteller/code/event_defines/_event.dm b/modular_bandastation/storyteller/code/event_defines/_event.dm index b10e49c470904..cb42188e99ec8 100644 --- a/modular_bandastation/storyteller/code/event_defines/_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_event.dm @@ -82,4 +82,4 @@ if("fire") message_admins("[key_name_admin(usr)] has fired event [src.name].") log_admin_private("[key_name(usr)] has fired event [src.name].") - SSgamemode.fire(src) + run_event(random = FALSE, admin_forced = TRUE) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index b529909daed9d..6542b2c3cbc42 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -15,7 +15,7 @@ // Seccies JOB_DETECTIVE, - JOB_SECURITY_OFFICER, + //JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_PRISONER, ) @@ -53,12 +53,22 @@ . = ..() if(!.) return - if(roundstart || !SSgamemode.can_inject_antags()) + if(roundstart && SSticker.HasRoundStarted()) + message_admins("Event: [name] was unable to run due event is roundstart and round started.") + log_admin("Event: [name] was unable to run due event is roundstart and round started.") + return FALSE + if(SSgamemode.can_inject_antags()) + message_admins("Event: [name] was unable to run due event can't inject antags over sec cap.") + log_admin("Event: [name] was unable to run due event can't inject antags over sec cap.") return FALSE if(!get_antag_amount()) + message_admins("Event: [name] was unable to run due too many antags.") + log_admin("Event: [name] was unable to run due too many antags.") return FALSE var/list/candidates = get_candidates() if(candidates.len < get_minimum_candidates()) + message_admins("Event: [name] was unable to run due too low candidates count.") + log_admin("Event: [name] was unable to run due too low candidates count.") return FALSE /datum/round_event_control/antagonist/proc/get_minimum_candidates() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm new file mode 100644 index 0000000000000..6191213a0024a --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -0,0 +1,38 @@ +/datum/round_event_control/antagonist/team/blood_brothers + name = "Blood Brother" + roundstart = TRUE + track = EVENT_TRACK_CREWSET + antag_flag = ROLE_BROTHER + antag_datum = /datum/antagonist/brother + + weight = 6 + tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) + + base_antags = 2 + maximum_antags_global = 6 + + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ) + protected_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + +/datum/round_event/antagonist/team/blood_brothers + var/required_role = ROLE_BROTHER + + var/datum/team/brother_team/brother_team + +/datum/round_event/antagonist/team/blood_brothers/candidate_roles_setup(mob/candidate) + candidate.mind.special_role = required_role + +/datum/round_event/antagonist/team/blood_brothers/start() + for(var/datum/mind/assigned_player in setup_minds) + add_datum_to_mind(assigned_player) + return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm new file mode 100644 index 0000000000000..7dbd497e842cb --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -0,0 +1,44 @@ +/datum/round_event_control/antagonist/team/clown_ops + name = "Clown Operatives" + roundstart = TRUE + track = EVENT_TRACK_CREWSET + antag_flag = ROLE_CLOWN_OPERATIVE + antag_datum = /datum/antagonist/nukeop/clownop + antag_leader_datum = /datum/antagonist/nukeop/leader/clownop + + weight = 6 + tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) + + base_antags = 2 + maximum_antags = 5 + maximum_antags_global = 5 + + typepath = /datum/round_event/antagonist/team/clown_ops + + ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + category = EVENT_CATEGORY_INVASION + +/datum/round_event/antagonist/team/clown_ops + var/datum/job/job_type = /datum/job/clown_operative + var/required_role = ROLE_NUCLEAR_OPERATIVE + + var/datum/team/nuclear/nuke_team + +/datum/round_event/antagonist/team/clown_ops/candidate_roles_setup(mob/candidate) + candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) + candidate.mind.special_role = required_role + +/datum/round_event/antagonist/team/clown_ops/start() + // Get our nukie leader + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) + if(!most_experienced) + most_experienced = setup_minds[1] + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) + nuke_team = leader.nuke_team + + // Setup everyone else + for(var/datum/mind/assigned_player in setup_minds) + if(assigned_player == most_experienced) + continue + add_datum_to_mind(assigned_player) + return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm new file mode 100644 index 0000000000000..154c18fa0b907 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -0,0 +1,44 @@ +/datum/round_event_control/antagonist/team/Cult + name = "Cult" + roundstart = TRUE + track = EVENT_TRACK_CREWSET + antag_flag = ROLE_CULTIST + antag_datum = /datum/antagonist/cult + + weight = 1 + tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC, TAG_COMBAT) + + base_antags = 3 + maximum_antags = 6 + maximum_antags_global = 6 + + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHAPLAIN, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + + typepath = /datum/team/cult + + category = EVENT_CATEGORY_INVASION + +/datum/round_event/antagonist/team/cult + var/required_role = ROLE_CULTIST + + var/datum/team/nuclear/nuke_team + +/datum/round_event/antagonist/team/cult/candidate_roles_setup(mob/candidate) + candidate.mind.special_role = required_role + +/datum/round_event/antagonist/team/cult/start() + // Setup everyone else + for(var/datum/mind/assigned_player in setup_minds) + add_datum_to_mind(assigned_player) + return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm new file mode 100644 index 0000000000000..ac516e4af405b --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -0,0 +1,60 @@ +/datum/round_event_control/antagonist/team/revolution + name = "revolution" + roundstart = TRUE + track = EVENT_TRACK_MAJOR + antag_flag = ROLE_REV + antag_datum = /datum/antagonist/rev/ + antag_leader_datum = /datum/antagonist/rev/head + + weight = 0 + tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) + + base_antags = 3 + maximum_antags_global = 6 + + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ) + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_QUARTERMASTER, + JOB_RESEARCH_DIRECTOR, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + + typepath = /datum/team/revolution + +/datum/round_event/antagonist/team/revolution + var/datum/job/job_type = /datum/job/clown_operative + var/required_role = ROLE_REV + + var/datum/team/revolution/rev_team + +/datum/round_event/antagonist/team/revolution/candidate_roles_setup(mob/candidate) + candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) + candidate.mind.special_role = required_role + +/datum/round_event/antagonist/team/revolution/start() + // Get our nukie leader + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) + if(!most_experienced) + most_experienced = setup_minds[1] + var/datum/antagonist/rev/head/leader = most_experienced.add_antag_datum(antag_leader_datum) + rev_team = leader.rev_team + + // Setup everyone else + for(var/datum/mind/assigned_player in setup_minds) + if(assigned_player == most_experienced) + continue + add_datum_to_mind(assigned_player) + return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 231a13872b58a..f2918f31320d2 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -2,11 +2,6 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) -/datum/round_event_control/bureaucratic_error - track = EVENT_TRACK_MAJOR // Yes, it's annoying. - tags = list(TAG_COMMUNAL) - weight = 5 - /datum/round_event_control/blob track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_CHAOTIC) @@ -78,3 +73,9 @@ track = EVENT_TRACK_MAJOR weight = 5 tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) + +/datum/round_event_control/wizard/round_start + track = EVENT_TRACK_MAJOR + weight = 5 + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) + roundstart = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 6fe8e18d099ec..85445a1b543e5 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -44,3 +44,8 @@ /datum/round_event_control/obsessed tags = list(TAG_TARGETED) + +/datum/round_event_control/bureaucratic_error + tags = list(TAG_COMMUNAL) + weight = 5 + max_occurrences = 1 diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index 816ebfdfa4e34..a1d80568a1d07 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -1,3 +1,13 @@ +/datum/round_event_control/space_dust + track = EVENT_TRACK_MUNDANE + weight = 10 + tags = list(TAG_SPACE) + +/datum/round_event_control/camera_failure + track = EVENT_TRACK_MUNDANE + weight = 10 + tags = list(TAG_COMMUNAL) + /datum/round_event_control/aurora_caelus track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_SPACE) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index bd75e321d37eb..0ceef401514f5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -136,7 +136,6 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/Initialize(time, zlevel) . = ..() - SSevents.flags |= SS_NO_FIRE // Populate event pools for(var/track in event_tracks) event_pools[track] = list() @@ -380,6 +379,7 @@ SUBSYSTEM_DEF(gamemode) eng_crew = 0 med_crew = 0 sec_crew = 0 + rnd_crew = 0 for(var/mob/player_mob as anything in GLOB.player_list) if(!player_mob.client) continue @@ -403,8 +403,8 @@ SUBSYSTEM_DEF(gamemode) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) rnd_crew++ -/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event) - . = event.preRunEvent() +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE) + . = event.preRunEvent(admin_forced) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event.max_occurrences = 0 else if(. == EVENT_READY) diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index df501e14e4956..e395efcc21bd2 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -45,7 +45,7 @@ return "Cancel" /// Try and fire off the scheduled event -/datum/scheduled_event/proc/try_fire() +/datum/scheduled_event/proc/try_fire(admin_forced = FALSE) /// Remove our fake occurence pre-emptively for the checks. remove_occurence() var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = FALSE) @@ -59,7 +59,7 @@ ///Trigger the event and remove the scheduled datum message_admins("Scheduled Event: [event] successfully triggered.") - SSgamemode.TriggerEvent(event) + SSgamemode.TriggerEvent(event, admin_forced) SSgamemode.remove_scheduled_event(src) /datum/scheduled_event/Destroy() @@ -93,4 +93,4 @@ return message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") - try_fire() + event.run_event(admin_forced = TRUE) From 15773d3be672cf950fb8f6bfdc000e66df5c0be3 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 23 Nov 2024 16:47:03 +0300 Subject: [PATCH 019/135] =?UTF-8?q?=D0=9E=D1=82=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 2 +- code/modules/events/_event.dm | 6 ++--- .../storyteller/_storyteller.dme | 1 + .../crewset/_antagonist_event.dm | 2 +- .../storyteller/code/scheduled_event.dm | 1 + .../tellers/storyteller_phantom.dm | 26 +++++++++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 987d7612bd642..4db6ba4a3fe59 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -35,7 +35,7 @@ SUBSYSTEM_DEF(events) /datum/controller/subsystem/events/fire(resumed = FALSE) if(!resumed) - checkEvent() //only check these if we aren't resuming a paused fire + //checkEvent() //only check these if we aren't resuming a paused fire src.currentrun = running.Copy() //cache for sanic speed (lists are references anyways) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 3150b4221a69b..a304e5b5963e0 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -1,4 +1,4 @@ -#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (10 SECONDS) // BANDASTATION EDIT CHANGE - STORYTELLER. Original: 10 SECONDS +#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME (60 SECONDS) // BANDASTATION EDIT CHANGE - STORYTELLER. Original: 10 SECONDS //this singleton datum is used by the events controller to dictate how it selects events /datum/round_event_control @@ -124,7 +124,7 @@ // BANDASTATION EDIT START - STORYTELLER //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") if(SSticker.HasRoundStarted()) - message_admins("Storyteller: Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ + message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ CANCEL | \ SOMETHING ELSE)") for(var/client/staff as anything in GLOB.admins) @@ -135,7 +135,7 @@ sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) if(triggering) - message_admins("Storyteller: Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ + message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ CANCEL | \ SOMETHING ELSE)") if(!roundstart) diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 8d7029eb4ffab..1d1ade6710a25 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -34,6 +34,7 @@ #include "code\storytellers\tellers\storyteller_fragile.dm" #include "code\storytellers\tellers\storyteller_gamer.dm" #include "code\storytellers\tellers\storyteller_black_orbit.dm" +#include "code\storytellers\tellers\storyteller_phantom.dm" #include "code\divergency_report.dm" #include "code\scheduled_event.dm" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 6542b2c3cbc42..1d20985ad0d80 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -15,7 +15,7 @@ // Seccies JOB_DETECTIVE, - //JOB_SECURITY_OFFICER, + JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_PRISONER, ) diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index e395efcc21bd2..df9be71b7feea 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -94,3 +94,4 @@ message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") event.run_event(admin_forced = TRUE) + SSgamemode.remove_scheduled_event(src) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm new file mode 100644 index 0000000000000..0d2395c2f5240 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm @@ -0,0 +1,26 @@ +/datum/storyteller/black_orbit + name = "Poops x10" + desc = "It's super friendly storyteller, to make your game more fun." + welcome_text = "Friendship is a magic!" + + event_repetition_multiplier = 0.1 + + track_data = /datum/storyteller_data/tracks/black_orbit + + guarantees_roundstart_crewset = FALSE + antag_divisor = 1 //Чтобы было больше антагов + population_min = 1000 + + tag_multipliers = list( + TAG_COMBAT = 10, + TAG_DESTRUCTIVE = 10, + TAG_CHAOTIC = 10 + ) + storyteller_type = STORYTELLER_TYPE_INTENSE + +/datum/storyteller_data/tracks/black_orbit + threshold_mundane = 60 + threshold_moderate = 120 + threshold_major = 180 + threshold_crewset = 240 + threshold_ghostset = 300 From 4b7d6de487807a6b61f85484fe0ad8d5ca1758d1 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 23 Nov 2024 17:26:18 +0300 Subject: [PATCH 020/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D0=BE=D1=82=D1=8B=20=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 4 +-- code/modules/events/_event.dm | 32 +++++++++---------- .../crewset/_antagonist_event.dm | 16 +++++----- .../storyteller/code/scheduled_event.dm | 6 ++-- .../code/storytellers/tellers/_storyteller.dm | 18 +++++------ 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 4db6ba4a3fe59..da94a14eceac9 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -104,8 +104,8 @@ SUBSYSTEM_DEF(events) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) - message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") - log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) //event_to_trigger.run_event(random = TRUE) /// BANDASTATION EDIT - STORYTELLER - переброска ивентов в запланированные, вместо самоспавна diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a304e5b5963e0..fe9acf90bf9d3 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -73,40 +73,40 @@ /datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) - message_admins("Event: [name] was unable to run due max occurrence limit.") - log_admin("Scheduled Event: [name] was unable to run due max occurrence limit.") + message_admins("Storyteller event: [name] was unable to run due max occurrence limit.") + log_admin("Storyteller event: [name] was unable to run due max occurrence limit.") return FALSE // BANDASTATION EDIT START - STORYTELLER //if(earliest_start >= world.time-SSticker.round_start_time) if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) - message_admins("Event: [name] was unable to run due earliest start timer limit.") - log_admin("Scheduled Event: [name] was unable to run due mearliest start timer limit.") + message_admins("Storyteller event: [name] was unable to run due earliest start timer limit.") + log_admin("Storyteller event: [name] was unable to run due mearliest start timer limit.") return FALSE // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) - message_admins("Event: [name] was unable to run due magic not allowed and it's wizard mode.") - log_admin("Scheduled Event: [name] was unable to run due magic not allowed and it's wizard mode.") + message_admins("Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode.") + log_admin("Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode.") return FALSE if(players_amt < min_players) - message_admins("Event: [name] was unable to run due too low players for event.") - log_admin("Scheduled Event: [name] was unable to run due too low players for event.") + message_admins("Storyteller event: [name] was unable to run due too low players for event.") + log_admin("Storyteller event: [name] was unable to run due too low players for event.") return FALSE if(holidayID && !check_holidays(holidayID)) - message_admins("Event: [name] was unable to run due try to run on non-holiday day.") - log_admin("Scheduled Event: [name] was unable to run due try to run on non-holiday day.") + message_admins("Storyteller event: [name] was unable to run due try to run on non-holiday day.") + log_admin("Storyteller event: [name] was unable to run due try to run on non-holiday day.") return FALSE if(EMERGENCY_ESCAPED_OR_ENDGAMED) - message_admins("Event: [name] was unable to run due escaped or endgamed.") - log_admin("Scheduled Event: [name] was unable to run due escaped or endgamed.") + message_admins("Storyteller event: [name] was unable to run due escaped or endgamed.") + log_admin("Storyteller event: [name] was unable to run due escaped or endgamed.") return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) - message_admins("Event: [name] was unable to run due it's ghost role for not midround event.") - log_admin("Scheduled Event: [name] was unable to run due it's ghost role for not midround event.") + message_admins("Storyteller event: [name] was unable to run due it's ghost role for not midround event.") + log_admin("Storyteller event: [name] was unable to run due it's ghost role for not midround event.") return FALSE if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) - message_admins("Event: [name] was unable to run due hijack in progress.") - log_admin("Scheduled Event: [name] was unable to run due hijack in progress.") + message_admins("Storyteller event: [name] was unable to run due hijack in progress.") + log_admin("Storyteller event: [name] was unable to run due hijack in progress.") return FALSE return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 1d20985ad0d80..8fdba21f3b690 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -54,21 +54,21 @@ if(!.) return if(roundstart && SSticker.HasRoundStarted()) - message_admins("Event: [name] was unable to run due event is roundstart and round started.") - log_admin("Event: [name] was unable to run due event is roundstart and round started.") + message_admins("Storyteller event: [name] was unable to run due event is roundstart and round started.") + log_admin("Storyteller event: [name] was unable to run due event is roundstart and round started.") return FALSE if(SSgamemode.can_inject_antags()) - message_admins("Event: [name] was unable to run due event can't inject antags over sec cap.") - log_admin("Event: [name] was unable to run due event can't inject antags over sec cap.") + message_admins("Storyteller event: [name] was unable to run due event can't inject antags over sec cap.") + log_admin("Storyteller event: [name] was unable to run due event can't inject antags over sec cap.") return FALSE if(!get_antag_amount()) - message_admins("Event: [name] was unable to run due too many antags.") - log_admin("Event: [name] was unable to run due too many antags.") + message_admins("Storyteller event: [name] was unable to run due too many antags.") + log_admin("Storyteller event: [name] was unable to run due too many antags.") return FALSE var/list/candidates = get_candidates() if(candidates.len < get_minimum_candidates()) - message_admins("Event: [name] was unable to run due too low candidates count.") - log_admin("Event: [name] was unable to run due too low candidates count.") + message_admins("Storyteller event: [name] was unable to run due too low candidates count.") + log_admin("Storyteller event: [name] was unable to run due too low candidates count.") return FALSE /datum/round_event_control/antagonist/proc/get_minimum_candidates() diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index df9be71b7feea..4b11b152d2d3e 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -51,14 +51,14 @@ var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = FALSE) ///If we can't spawn the scheduled event, refund it. if(!ignores_checks && !event.can_spawn_event(players_amt)) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. - message_admins("Scheduled Event: [event] was unable to run and has been refunded.") - log_admin("Scheduled Event: [event] was unable to run and has been refunded.") + message_admins("Scheduled Event: [event] was unable to run and has been refunded.") + log_admin("Scheduled Event: [event] was unable to run and has been refunded.") SSgamemode.refund_scheduled_event(src) return ///Trigger the event and remove the scheduled datum - message_admins("Scheduled Event: [event] successfully triggered.") + message_admins("Scheduled Event: [event] successfully triggered.") SSgamemode.TriggerEvent(event, admin_forced) SSgamemode.remove_scheduled_event(src) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index d77eeefd4f36a..b14a686cad55c 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -80,8 +80,8 @@ var/player_pop = SSgamemode.get_correct_popcount() var/pop_required = SSgamemode.min_pop_thresholds[track] if(player_pop < pop_required) - message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") - log_admin("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") + message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") + log_admin("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER return calculate_weights(track) @@ -94,15 +94,15 @@ valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") - log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") + message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") + log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER return picked_event = pick_weight(valid_events) if(!picked_event) - message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - log_admin("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - stack_trace("WARNING: Storyteller [src] picked a null from event pool at track [track].") + message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + log_admin("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + stack_trace("WARNING: Storyteller [src] picked a null from event pool at track [track].") return buy_event(picked_event, track) . = TRUE @@ -114,8 +114,8 @@ if(!bought_event.roundstart) total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) - message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") - log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") if(bought_event.roundstart) SSgamemode.TriggerEvent(bought_event) else From 89e6d55944d6232ca964f2a455e4d185be28d8d7 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 23 Nov 2024 18:11:43 +0300 Subject: [PATCH 021/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B=20=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B6=D0=B5=D0=BB=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 4 ++-- code/modules/admin/force_event.dm | 12 +++++++----- code/modules/events/_event.dm | 10 +++++----- .../code/event_defines/crewset/_antagonist_event.dm | 13 +++++++------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index da94a14eceac9..f93ce290116e8 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -103,11 +103,11 @@ SUBSYSTEM_DEF(events) . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 - else if(. == EVENT_READY) + /*else if(. == EVENT_READY) message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) - //event_to_trigger.run_event(random = TRUE) /// BANDASTATION EDIT - STORYTELLER - переброска ивентов в запланированные, вместо самоспавна + event_to_trigger.run_event(random = TRUE)*/ /// BANDASTATION EDIT - STORYTELLER - Отключение запуска рандом-ивентов ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm index f511eb2883aed..2e1c5e109a4dd 100644 --- a/code/modules/admin/force_event.dm +++ b/code/modules/admin/force_event.dm @@ -82,7 +82,7 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM return switch(action) if("forceevent") - //var/announce_event = params["announce"] /// BANDASTATION EDIT - STORYTELLER + var/announce_event = params["announce"] var/string_path = params["type"] if(!string_path) return @@ -96,9 +96,11 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM for(var/datum/event_admin_setup/admin_setup_datum as anything in event.admin_setup) if(admin_setup_datum.prompt_admins() == ADMIN_CANCEL_EVENT) return - //var/always_announce_chance = 100 /// BANDASTATION EDIT - STORYTELLER - //var/no_announce_chance = 0 /// BANDASTATION EDIT - STORYTELLER - //event.run_event(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) /// BANDASTATION EDIT - STORYTELLER - SSgamemode.TriggerEvent(event) + var/always_announce_chance = 100 + var/no_announce_chance = 0 + if(SSticker.HasRoundStarted()) + event.run_event(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) + else + SSgamemode.schedule_event(event) 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/events/_event.dm b/code/modules/events/_event.dm index fe9acf90bf9d3..f51137c201f17 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -123,7 +123,7 @@ // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. // BANDASTATION EDIT START - STORYTELLER //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") - if(SSticker.HasRoundStarted()) + if(SSticker.HasRoundStarted() && !roundstart && !admin_forced) message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ CANCEL | \ SOMETHING ELSE)") @@ -135,10 +135,10 @@ sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) if(triggering) - message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ - CANCEL | \ - SOMETHING ELSE)") - if(!roundstart) + if(!roundstart && !admin_forced) + message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ + CANCEL | \ + SOMETHING ELSE)") sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) else message_admins(" Roundstart event chosen: [name].") diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 8fdba21f3b690..d377c2b36d8b8 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -42,12 +42,13 @@ /datum/round_event_control/antagonist/New() . = ..() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_roles |= protected_roles - restricted_roles |= SSstation.antag_restricted_roles - restricted_roles |= SSstation.antag_protected_roles - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_roles |= JOB_ASSISTANT + if(!SSticker.HasRoundStarted()) // Снятие защиты от раундстартовых антагов + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_roles |= protected_roles + restricted_roles |= SSstation.antag_restricted_roles + restricted_roles |= SSstation.antag_protected_roles + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_roles |= JOB_ASSISTANT /datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) . = ..() From 3f21a09f2261746186b02914161a2130c0c9ce24 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 23 Nov 2024 23:46:17 +0300 Subject: [PATCH 022/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 34 ++++++++++++++----- .../crewset/_antagonist_event.dm | 26 +++++++++----- .../code/storytellers/tellers/_storyteller.dm | 6 ++++ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index f51137c201f17..d06df14b316dc 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -74,43 +74,61 @@ SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) message_admins("Storyteller event: [name] was unable to run due max occurrence limit.") - log_admin("Storyteller event: [name] was unable to run due max occurrence limit.") return FALSE // BANDASTATION EDIT START - STORYTELLER //if(earliest_start >= world.time-SSticker.round_start_time) if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) message_admins("Storyteller event: [name] was unable to run due earliest start timer limit.") - log_admin("Storyteller event: [name] was unable to run due mearliest start timer limit.") return FALSE // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) message_admins("Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode.") - log_admin("Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode.") return FALSE if(players_amt < min_players) message_admins("Storyteller event: [name] was unable to run due too low players for event.") - log_admin("Storyteller event: [name] was unable to run due too low players for event.") return FALSE if(holidayID && !check_holidays(holidayID)) message_admins("Storyteller event: [name] was unable to run due try to run on non-holiday day.") - log_admin("Storyteller event: [name] was unable to run due try to run on non-holiday day.") return FALSE if(EMERGENCY_ESCAPED_OR_ENDGAMED) message_admins("Storyteller event: [name] was unable to run due escaped or endgamed.") - log_admin("Storyteller event: [name] was unable to run due escaped or endgamed.") return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) message_admins("Storyteller event: [name] was unable to run due it's ghost role for not midround event.") - log_admin("Storyteller event: [name] was unable to run due it's ghost role for not midround event.") return FALSE if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) message_admins("Storyteller event: [name] was unable to run due hijack in progress.") - log_admin("Storyteller event: [name] was unable to run due hijack in progress.") return FALSE return TRUE +/datum/round_event_control/proc/can_spawn_event_error_reason(players_amt, allow_magic = FALSE) + SHOULD_CALL_PARENT(TRUE) + var/message = "success" + if(occurrences >= max_occurrences) + message = "Storyteller event: [name] was unable to run due max occurrence limit." + // BANDASTATION EDIT START - STORYTELLER + //if(earliest_start >= world.time-SSticker.round_start_time) + if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) + message = "Storyteller event: [name] was unable to run due earliest start timer limit." + // BANDASTATION EDIT END + if(!allow_magic && wizardevent != SSevents.wizardmode) + message = "Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode." + if(players_amt < min_players) + message = "Storyteller event: [name] was unable to run due too low players for event." + if(holidayID && !check_holidays(holidayID)) + message = "Storyteller event: [name] was unable to run due try to run on non-holiday day." + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + message = "Storyteller event: [name] was unable to run due escaped or endgamed." + if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) + message = "Storyteller event: [name] was unable to run due it's ghost role for not midround event." + + if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) + message = "Storyteller event: [name] was unable to run due hijack in progress." + + return message + /datum/round_event_control/proc/preRunEvent(admin_forced = FALSE) if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index d377c2b36d8b8..ad2ff473b6bc2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -55,23 +55,33 @@ if(!.) return if(roundstart && SSticker.HasRoundStarted()) - message_admins("Storyteller event: [name] was unable to run due event is roundstart and round started.") - log_admin("Storyteller event: [name] was unable to run due event is roundstart and round started.") return FALSE if(SSgamemode.can_inject_antags()) - message_admins("Storyteller event: [name] was unable to run due event can't inject antags over sec cap.") - log_admin("Storyteller event: [name] was unable to run due event can't inject antags over sec cap.") return FALSE if(!get_antag_amount()) - message_admins("Storyteller event: [name] was unable to run due too many antags.") - log_admin("Storyteller event: [name] was unable to run due too many antags.") return FALSE var/list/candidates = get_candidates() if(candidates.len < get_minimum_candidates()) - message_admins("Storyteller event: [name] was unable to run due too low candidates count.") - log_admin("Storyteller event: [name] was unable to run due too low candidates count.") return FALSE +/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE) + . = ..() + var/message = . + if(message == "success") + return + if(roundstart && SSticker.HasRoundStarted()) + message = "Storyteller event: [name] was unable to run due event is roundstart and round started." + if(SSgamemode.can_inject_antags()) + message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap: [SSgamemode.get_antag_cap()]." + if(!get_antag_amount()) + message = "Storyteller event: [name] was unable to run due no antags count to spawn." + var/list/candidates = get_candidates() + if(candidates.len < get_minimum_candidates()) + message = "Storyteller event: [name] was unable to run due too low candidates count." + + return message + + /datum/round_event_control/antagonist/proc/get_minimum_candidates() return minimum_candidate_base diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index b14a686cad55c..afd8350a12a47 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -94,6 +94,12 @@ valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything if(!length(valid_events)) + for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) + if(isnull(event)) + continue + var/message = event.can_spawn_event_error_reason() + message_admins(message) + log_admin(message) message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER From 2f55d4803b94a852626d798e6248bd347e9a394d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 23 Nov 2024 23:55:30 +0300 Subject: [PATCH 023/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D0=BC?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D0=BE=20=D0=B8=D0=B3=D1=80=D0=BE=D0=BA=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D1=85=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/clown_ops.dm | 1 + .../storyteller/code/event_defines/crewset/cult.dm | 1 + .../storyteller/code/event_defines/crewset/nuke_ops.dm | 1 + .../storyteller/code/event_defines/crewset/revolution.dm | 1 + 4 files changed, 4 insertions(+) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 7dbd497e842cb..6f6e744d0cfef 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -12,6 +12,7 @@ base_antags = 2 maximum_antags = 5 maximum_antags_global = 5 + min_players = 40 typepath = /datum/round_event/antagonist/team/clown_ops diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 154c18fa0b907..6087b6927f8e6 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -11,6 +11,7 @@ base_antags = 3 maximum_antags = 6 maximum_antags_global = 6 + min_players = 40 restricted_roles = list( JOB_AI, diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 5ead094535c6f..6fffbecb3b267 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -12,6 +12,7 @@ base_antags = 2 maximum_antags = 5 maximum_antags_global = 5 + min_players = 40 typepath = /datum/round_event/antagonist/team/nukie diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index ac516e4af405b..0e54ce96b39bc 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -11,6 +11,7 @@ base_antags = 3 maximum_antags_global = 6 + min_players = 40 restricted_roles = list( JOB_AI, From 80fc699f15e41e6b3254ece2593ab64ed5ae88a2 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 10:44:15 +0300 Subject: [PATCH 024/135] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D0=B0=D1=8F=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F,=20=D0=B2?= =?UTF-8?q?=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=80?= =?UTF-8?q?=D0=B3=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8B=20(=D0=BC=D0=B5?= =?UTF-8?q?=D0=B4,=20=D1=80=D0=BD=D0=B4,=20=D0=B8=D0=BD=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B8=D1=8F,=20=D0=B3=D0=BB=D0=B0=D0=B2=D1=8B),=20?= =?UTF-8?q?=D1=87=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20=D0=BB=D0=B8=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D1=85=20=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 26 ++++++++++++------- .../storyteller/_storyteller.dme | 1 + .../code/_defines/storyteller_defines.dm | 1 - .../storyteller/code/event_defines/_event.dm | 6 +++++ .../crewset/_antagonist_event.dm | 2 +- .../event_defines/crewset/blood_brothers.dm | 1 + .../code/event_defines/crewset/obsessed.dm | 14 ++++++++++ .../code/event_defines/major/override.dm | 6 +++++ .../code/event_defines/moderate/override.dm | 10 +++++++ .../code/event_defines/mundane/override.dm | 25 +++++++++--------- .../code/storytellers/tellers/_storyteller.dm | 5 ++-- 11 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index d06df14b316dc..022d860d16736 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -73,32 +73,31 @@ /datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) - message_admins("Storyteller event: [name] was unable to run due max occurrence limit.") return FALSE // BANDASTATION EDIT START - STORYTELLER //if(earliest_start >= world.time-SSticker.round_start_time) if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) - message_admins("Storyteller event: [name] was unable to run due earliest start timer limit.") return FALSE // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) - message_admins("Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode.") return FALSE if(players_amt < min_players) - message_admins("Storyteller event: [name] was unable to run due too low players for event.") return FALSE if(holidayID && !check_holidays(holidayID)) - message_admins("Storyteller event: [name] was unable to run due try to run on non-holiday day.") return FALSE if(EMERGENCY_ESCAPED_OR_ENDGAMED) - message_admins("Storyteller event: [name] was unable to run due escaped or endgamed.") return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) - message_admins("Storyteller event: [name] was unable to run due it's ghost role for not midround event.") return FALSE - + if(SSgamemode.rnd_crew < rnd_required_crew) + return FALSE + if(SSgamemode.med_crew < med_required_crew) + return FALSE + if(SSgamemode.eng_crew < eng_required_crew) + return FALSE + if(SSgamemode.head_crew < head_required_crew) + return FALSE if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) - message_admins("Storyteller event: [name] was unable to run due hijack in progress.") return FALSE return TRUE @@ -123,7 +122,14 @@ message = "Storyteller event: [name] was unable to run due escaped or endgamed." if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) message = "Storyteller event: [name] was unable to run due it's ghost role for not midround event." - + if(SSgamemode.rnd_crew < rnd_required_crew) + message = "Storyteller event: [name] was unable to run due lack of science roles - count/needed [SSgamemode.rnd_crew]/[rnd_required_crew]." + if(SSgamemode.med_crew < med_required_crew) + message = "Storyteller event: [name] was unable to run due lack of medical roles - count/needed [SSgamemode.med_crew]/[med_required_crew]." + if(SSgamemode.eng_crew < eng_required_crew) + message = "Storyteller event: [name] was unable to run due lack of engineering roles - count/needed [SSgamemode.eng_crew]/[eng_required_crew]." + if(SSgamemode.head_crew < head_required_crew) + message = "Storyteller event: [name] was unable to run due lack of heads roles - count/needed [SSgamemode.head_crew]/[head_required_crew]." if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) message = "Storyteller event: [name] was unable to run due hijack in progress." diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index 1d1ade6710a25..dce389bba41bf 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -16,6 +16,7 @@ #include "code\event_defines\crewset\cult.dm" #include "code\event_defines\crewset\clown_ops.dm" #include "code\event_defines\crewset\revolution.dm" +#include "code\event_defines\crewset\obsessed.dm" #include "code\event_defines\ghostset\override.dm" #include "code\event_defines\ghostset\voidwalker.dm" diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index f07e295ac7927..f97c0e25702fb 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -26,7 +26,6 @@ /// When the event requires the station to be on planetary. #define TAG_PLANETARY "planetary" - #define EVENT_TRACK_MUNDANE "Mundane" #define EVENT_TRACK_MODERATE "Moderate" #define EVENT_TRACK_MAJOR "Major" diff --git a/modular_bandastation/storyteller/code/event_defines/_event.dm b/modular_bandastation/storyteller/code/event_defines/_event.dm index cb42188e99ec8..7d49051ad65f6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_event.dm @@ -12,6 +12,12 @@ /// Whether a roundstart event can happen post roundstart. Very important for events which override job assignments. var/can_run_post_roundstart = TRUE + // BANDASTATION EDIT - STORYTELLER - CREW REQUIREMENTS + var/med_required_crew = 0 + var/eng_required_crew = 0 + var/rnd_required_crew = 0 + var/head_required_crew = 0 + /datum/round_event /// Whether the event called its start() yet or not. var/has_started = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index ad2ff473b6bc2..101f525f5bd11 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -72,7 +72,7 @@ if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." if(SSgamemode.can_inject_antags()) - message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap: [SSgamemode.get_antag_cap()]." + message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - sec/cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." if(!get_antag_amount()) message = "Storyteller event: [name] was unable to run due no antags count to spawn." var/list/candidates = get_candidates() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 6191213a0024a..06748451eaee9 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -9,6 +9,7 @@ tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) base_antags = 2 + minimum_candidate_base = 2 maximum_antags_global = 6 restricted_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm new file mode 100644 index 0000000000000..285ec03e3642f --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -0,0 +1,14 @@ +/datum/round_event_control/antagonist/solo/obsessed + name = "Obseesed" + roundstart = TRUE + + antag_flag = ROLE_OBSESSED + antag_datum = /datum/antagonist/obsessed + weight = 10 + maximum_antags_global = 4 + category = EVENT_CATEGORY_INVASION + tags = list(TAG_CREW_ANTAG) + +/datum/round_event_control/antagonist/solo/obsessed/midround + name = "Yandere (Obseesed)" + roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index f2918f31320d2..8498fe362019d 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -1,6 +1,7 @@ /datum/round_event_control/earthquake track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) + eng_required_crew = 2 /datum/round_event_control/blob track = EVENT_TRACK_MAJOR @@ -12,6 +13,7 @@ tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) weight = 10 max_occurrences = 1 + eng_required_crew = 3 /datum/round_event_control/meteor_wave/meaty weight = 15 @@ -26,6 +28,7 @@ /datum/round_event_control/radiation_storm track = EVENT_TRACK_MAJOR tags = list(TAG_COMMUNAL) + med_required_crew = 3 /datum/round_event_control/wormholes track = EVENT_TRACK_MAJOR @@ -35,14 +38,17 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) weight = 20 + eng_required_crew = 2 /datum/round_event_control/anomaly/anomaly_vortex track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) + rnd_required_crew = 3 /datum/round_event_control/anomaly/anomaly_pyro track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) + rnd_required_crew = 3 /datum/round_event_control/revenant min_players = 20 diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 85445a1b543e5..d6994e5264b41 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -1,5 +1,6 @@ /datum/round_event_control/brand_intelligence tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL, TAG_CHAOTIC) + head_required_crew = 1 /datum/round_event_control/carp_migration tags = list(TAG_COMMUNAL) @@ -15,26 +16,34 @@ /datum/round_event_control/radiation_leak tags = list(TAG_COMMUNAL) + eng_required_crew = 2 + med_required_crew = 1 /datum/round_event_control/supermatter_surge tags = list(TAG_TARGETED) + eng_required_crew = 2 /datum/round_event_control/stray_meteor tags = list(TAG_DESTRUCTIVE, TAG_SPACE) weight = 25 + eng_required_crew = 2 /datum/round_event_control/shuttle_catastrophe tags = list(TAG_COMMUNAL) + head_required_crew = 2 /datum/round_event_control/vent_clog tags = list(TAG_COMMUNAL) + head_required_crew = 1 /datum/round_event_control/anomaly weight = 10 // Lower from original 15 because it KEEPS SPAWNING THEM tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE) + rnd_required_crew = 1 /datum/round_event_control/spacevine tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC) + med_required_crew = 2 /datum/round_event_control/portal_storm_syndicate tags = list(TAG_COMBAT, TAG_CHAOTIC) @@ -49,3 +58,4 @@ tags = list(TAG_COMMUNAL) weight = 5 max_occurrences = 1 + head_required_crew = 3 diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index a1d80568a1d07..d188d3ac728c2 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -6,7 +6,8 @@ /datum/round_event_control/camera_failure track = EVENT_TRACK_MUNDANE weight = 10 - tags = list(TAG_COMMUNAL) + tags = list(TAG_COMMUNAL, TAG_SPOOKY) + eng_required_crew = 1 /datum/round_event_control/aurora_caelus track = EVENT_TRACK_MUNDANE @@ -15,14 +16,12 @@ /datum/round_event_control/brain_trauma track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED) + med_required_crew = 1 /datum/round_event_control/heart_attack track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED) - -/datum/round_event_control/camera_failure - track = EVENT_TRACK_MUNDANE - tags = list(TAG_COMMUNAL, TAG_SPOOKY) + med_required_crew = 2 /datum/round_event_control/grid_check track = EVENT_TRACK_MUNDANE @@ -31,14 +30,12 @@ /datum/round_event_control/disease_outbreak track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED) - -/datum/round_event_control/space_dust - track = EVENT_TRACK_MUNDANE - tags = list(TAG_DESTRUCTIVE, TAG_SPACE) + med_required_crew = 1 /datum/round_event_control/electrical_storm track = EVENT_TRACK_MUNDANE tags = list(TAG_SPOOKY) + eng_required_crew = 1 /datum/round_event_control/fake_virus track = EVENT_TRACK_MUNDANE @@ -72,6 +69,7 @@ /datum/round_event_control/stray_cargo track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL) + eng_required_crew = 1 /datum/round_event_control/grey_tide track = EVENT_TRACK_MUNDANE @@ -80,6 +78,7 @@ /datum/round_event_control/gravity_generator_blackout track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL, TAG_SPACE) + eng_required_crew = 1 /datum/round_event_control/shuttle_insurance track = EVENT_TRACK_MUNDANE @@ -88,6 +87,7 @@ /datum/round_event_control/tram_malfunction track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED, TAG_SPOOKY) + eng_required_crew = 1 /datum/round_event_control/bitrunning_glitch track = EVENT_TRACK_MUNDANE @@ -133,12 +133,13 @@ /datum/round_event_control/scrubber_overflow/threatening weight = 0 - max_occurrences = 0 + med_required_crew = 1 /datum/round_event_control/scrubber_overflow/catastrophic weight = 0 - max_occurrences = 0 + med_required_crew = 1 + eng_required_crew = 1 /datum/round_event_control/scrubber_overflow/every_vent weight = 0 - max_occurrences = 0 + head_required_crew = 1 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index afd8350a12a47..ac80bb97dc86a 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -98,8 +98,9 @@ if(isnull(event)) continue var/message = event.can_spawn_event_error_reason() - message_admins(message) - log_admin(message) + if(message != "success") + message_admins(message) + log_admin(message) message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER From 79fcbacf7a98aaa5e17c1f4e523cabe78003ab66 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 12:40:37 +0300 Subject: [PATCH 025/135] =?UTF-8?q?=D0=9E=D1=82=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B2=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D0=B5=20=D0=BE?= =?UTF-8?q?=D1=82=D1=81=D1=83=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F=20=D0=A1?= =?UTF-8?q?=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0ceef401514f5..8e01cf6addd17 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -209,7 +209,7 @@ SUBSYSTEM_DEF(gamemode) if(!storyteller.antag_divisor) return 0 var/max_antags = sec_crew * storyteller.max_sec_mult - var/min_antags = ANTAG_CAP_FLAT + var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) return round(clamped_cap) From 80dbfd0529725a34f84f47f68b817ebdce2993bb Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 19:57:40 +0300 Subject: [PATCH 026/135] =?UTF-8?q?=D0=A0=D0=B5=D0=B1=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D1=81=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/obsessed.dm | 6 +----- .../storyteller/code/event_defines/major/override.dm | 5 ----- .../storyteller/code/event_defines/override_events.dm | 6 ++++++ 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index 285ec03e3642f..f21a6b46811c0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/obsessed name = "Obseesed" - roundstart = TRUE + roundstart = FALSE antag_flag = ROLE_OBSESSED antag_datum = /datum/antagonist/obsessed @@ -8,7 +8,3 @@ maximum_antags_global = 4 category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) - -/datum/round_event_control/antagonist/solo/obsessed/midround - name = "Yandere (Obseesed)" - roundstart = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 8498fe362019d..6d67288ce9ace 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -75,11 +75,6 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) -/datum/round_event_control/wizard - track = EVENT_TRACK_MAJOR - weight = 5 - tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) - /datum/round_event_control/wizard/round_start track = EVENT_TRACK_MAJOR weight = 5 diff --git a/modular_bandastation/storyteller/code/event_defines/override_events.dm b/modular_bandastation/storyteller/code/event_defines/override_events.dm index 451e96d5ac9d4..96a5f126fda4d 100644 --- a/modular_bandastation/storyteller/code/event_defines/override_events.dm +++ b/modular_bandastation/storyteller/code/event_defines/override_events.dm @@ -41,3 +41,9 @@ /datum/reagent/water/salt, /datum/reagent/yuck, ) + +/datum/round_event_control/wizard/round_start + track = EVENT_TRACK_CREWSET + weight = 1 + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) + roundstart = TRUE From e77c40e2380cdbdb86bdb45f23cc49a593851bab Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 20:29:43 +0300 Subject: [PATCH 027/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BE=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/_antagonist_event.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 101f525f5bd11..39c69b2be6147 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -71,7 +71,7 @@ return if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." - if(SSgamemode.can_inject_antags()) + if(!SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - sec/cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." if(!get_antag_amount()) message = "Storyteller event: [name] was unable to run due no antags count to spawn." From 6322089b5ca6b5551a005dafca3113d728f3d03a Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 20:33:42 +0300 Subject: [PATCH 028/135] =?UTF-8?q?=D0=98=20=D1=84=D0=B8=D0=BA=D1=81=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=8C=D0=B5=D0=BA=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/_antagonist_event.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 39c69b2be6147..209eebad8c879 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -56,7 +56,7 @@ return if(roundstart && SSticker.HasRoundStarted()) return FALSE - if(SSgamemode.can_inject_antags()) + if(!SSgamemode.can_inject_antags()) return FALSE if(!get_antag_amount()) return FALSE From 549dceb6cf1492fc4563c4a999141f948f375cce Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 21:03:26 +0300 Subject: [PATCH 029/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=BF=D0=BF=D1=8B=20=D0=B1=D1=80=D0=B0=D1=82=D1=8C=D0=B5?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/crewset/_antagonist_event.dm | 4 ++-- .../storyteller/code/event_defines/crewset/blood_brothers.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 209eebad8c879..e60e3f0844ead 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -165,8 +165,8 @@ for(var/datum/mind/antag_mind as anything in setup_minds) add_datum_to_mind(antag_mind) -/datum/round_event/antagonist/proc/add_datum_to_mind(datum/mind/antag_mind) - antag_mind.add_antag_datum(antag_datum) +/datum/round_event/antagonist/proc/add_datum_to_mind(datum/mind/antag_mind, team) + antag_mind.add_antag_datum(antag_datum, team) /datum/round_event_control/antagonist/team typepath = /datum/round_event/antagonist/team diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 06748451eaee9..b4cc5f4bf1727 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -35,5 +35,5 @@ /datum/round_event/antagonist/team/blood_brothers/start() for(var/datum/mind/assigned_player in setup_minds) - add_datum_to_mind(assigned_player) + add_datum_to_mind(assigned_player, brother_team) return TRUE From 94d1636c6b8ae9201270ccb91fccc6bd196a7daf Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 22:23:28 +0300 Subject: [PATCH 030/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/_antagonist_event.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index e60e3f0844ead..2169902a075e8 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -72,7 +72,7 @@ if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." if(!SSgamemode.can_inject_antags()) - message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - sec/cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." + message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." if(!get_antag_amount()) message = "Storyteller event: [name] was unable to run due no antags count to spawn." var/list/candidates = get_candidates() diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 8e01cf6addd17..0ceef401514f5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -209,7 +209,7 @@ SUBSYSTEM_DEF(gamemode) if(!storyteller.antag_divisor) return 0 var/max_antags = sec_crew * storyteller.max_sec_mult - var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) + var/min_antags = ANTAG_CAP_FLAT var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) return round(clamped_cap) From 6fa3eafd578c4d564d65d7e87f1da20e167916ce Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 24 Nov 2024 22:52:06 +0300 Subject: [PATCH 031/135] =?UTF-8?q?=D0=9A=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D1=81=D0=BF=D0=B0?= =?UTF-8?q?=D0=B2=D0=BD=D0=B0=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2?= =?UTF-8?q?=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/crewset/_antagonist_event.dm | 4 ++-- modular_bandastation/storyteller/code/gamemode.dm | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 2169902a075e8..198d023f66f21 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -56,7 +56,7 @@ return if(roundstart && SSticker.HasRoundStarted()) return FALSE - if(!SSgamemode.can_inject_antags()) + if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) return FALSE if(!get_antag_amount()) return FALSE @@ -71,7 +71,7 @@ return if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." - if(!SSgamemode.can_inject_antags()) + if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." if(!get_antag_amount()) message = "Storyteller event: [name] was unable to run due no antags count to spawn." diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0ceef401514f5..7727877bb6b73 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -209,10 +209,11 @@ SUBSYSTEM_DEF(gamemode) if(!storyteller.antag_divisor) return 0 var/max_antags = sec_crew * storyteller.max_sec_mult - var/min_antags = ANTAG_CAP_FLAT + var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) - return round(clamped_cap) + var/result = round(clamped_cap) + return result /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() From 7dd6f709ad9e00002efc0f0121cdee9aba3628f7 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 25 Nov 2024 22:33:06 +0300 Subject: [PATCH 032/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8C=20=D1=80=D0=B5=D1=80=D0=BE=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 11 +++++------ code/modules/events/_event.dm | 12 +++++++----- .../code/event_defines/crewset/_antagonist_event.dm | 8 ++++---- modular_bandastation/storyteller/code/gamemode.dm | 5 +++-- .../code/storytellers/tellers/_storyteller.dm | 5 +++-- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index f93ce290116e8..40a82667ab796 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -70,7 +70,7 @@ SUBSYSTEM_DEF(events) * Arguments: * * excluded_event - The event path we will be foregoing, if present. */ -/datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event) +/datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event, reroll_reason = FALSE) set waitfor = FALSE //for the admin prompt if(!CONFIG_GET(flag/allow_random_events)) return @@ -96,18 +96,17 @@ SUBSYSTEM_DEF(events) var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - TriggerEvent(event_to_run) + TriggerEvent(event_to_run, reroll_reason) ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. -/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger) +/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger, reroll_reason = FALSE) . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 - /*else if(. == EVENT_READY) + else if(. == EVENT_READY && reroll_reason) message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") - SSgamemode.schedule_event(event_to_trigger, 0, 0, FALSE, TRUE) - event_to_trigger.run_event(random = TRUE)*/ /// BANDASTATION EDIT - STORYTELLER - Отключение запуска рандом-ивентов + event_to_trigger.run_event(random = TRUE) ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 022d860d16736..478a4bc0bf6cb 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -70,7 +70,7 @@ // Checks if the event can be spawned. Used by event controller and "false alarm" event. // Admin-created events override this. -/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE, round_start_event = FALSE) SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) return FALSE @@ -102,7 +102,7 @@ return TRUE -/datum/round_event_control/proc/can_spawn_event_error_reason(players_amt, allow_magic = FALSE) +/datum/round_event_control/proc/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, round_start_event = FALSE) SHOULD_CALL_PARENT(TRUE) var/message = "success" if(occurrences >= max_occurrences) @@ -135,7 +135,7 @@ return message -/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE) +/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE, round_start_event = FALSE) if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN @@ -171,9 +171,11 @@ var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!can_spawn_event(players_amt)) message_admins("Second pre-condition check for [name] failed, rerolling...") - SSevents.spawnEvent(excluded_event = src) + SSevents.spawnEvent(excluded_event = src, reroll_reason = SSgamemode.storyteller.round_start_handle) return EVENT_INTERRUPTED - + else + if(SSgamemode.storyteller.round_start_handle && SSticker.HasRoundStarted()) + SSgamemode.storyteller.round_start_handle = FALSE if(!triggering) return EVENT_CANCELLED //admin cancelled triggering = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 198d023f66f21..122cf3707352b 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -50,11 +50,11 @@ if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_roles |= JOB_ASSISTANT -/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) +/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE, round_start_event = FALSE) . = ..() if(!.) return - if(roundstart && SSticker.HasRoundStarted()) + if(roundstart && (SSticker.HasRoundStarted() && !round_start_event)) return FALSE if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) return FALSE @@ -64,12 +64,12 @@ if(candidates.len < get_minimum_candidates()) return FALSE -/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE) +/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE, round_start_event = FALSE) . = ..() var/message = . if(message == "success") return - if(roundstart && SSticker.HasRoundStarted()) + if(roundstart && (SSticker.HasRoundStarted() && !round_start_event)) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 7727877bb6b73..0d0b0126237a8 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -337,6 +337,7 @@ SUBSYSTEM_DEF(gamemode) /// If the storyteller guarantees an antagonist roll, add points to make it so. if(storyteller.guarantees_roundstart_crewset) + storyteller.round_start_handle = TRUE event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] /// If we have any forced events, ensure we get enough points for them @@ -404,8 +405,8 @@ SUBSYSTEM_DEF(gamemode) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) rnd_crew++ -/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE) - . = event.preRunEvent(admin_forced) +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE, round_start_event = FALSE) + . = event.preRunEvent(admin_forced, round_start_event) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event.max_occurrences = 0 else if(. == EVENT_READY) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index ac80bb97dc86a..4f8677a268216 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -46,6 +46,7 @@ var/max_sec_mult = 1 /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE + var/round_start_handle = FALSE /datum/storyteller/process(delta_time) if(disable_distribution) @@ -97,7 +98,7 @@ for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) if(isnull(event)) continue - var/message = event.can_spawn_event_error_reason() + var/message = event.can_spawn_event_error_reason(round_start_handle) if(message != "success") message_admins(message) log_admin(message) @@ -124,7 +125,7 @@ message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") if(bought_event.roundstart) - SSgamemode.TriggerEvent(bought_event) + SSgamemode.TriggerEvent(bought_event, round_start_event = round_start_handle) else SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) From 9e5d8141ac26e62847a6e3e07642c6c82e72edf8 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 26 Nov 2024 19:01:11 +0300 Subject: [PATCH 033/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=86=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=B9=20=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=BC?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=B8=20=D0=B1=D1=80=D0=B0=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/brother/brother.dm | 6 ++++++ .../event_defines/crewset/blood_brothers.dm | 21 +++---------------- .../code/event_defines/crewset/obsessed.dm | 10 +++++++++ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm index 80d14724170fe..3b0e6e2a5fffc 100644 --- a/code/modules/antagonists/brother/brother.dm +++ b/code/modules/antagonists/brother/brother.dm @@ -24,6 +24,12 @@ return team /datum/antagonist/brother/on_gain() + /// BANDASTATION EDIT START - STORYTELLER - фикс ББ на отсутствие задач и команды + if(!team) + var/datum/team/brother_team/brother_team = new /datum/team/brother_team + brother_team.add_member(owner) + create_team(brother_team) + /// BANDASTATION EDIT END - STORYTELLER - фикс ББ на отсутствие задач и команды objectives += team.objectives owner.special_role = special_role finalize_brother() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index b4cc5f4bf1727..9644e0ada21cc 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,4 +1,4 @@ -/datum/round_event_control/antagonist/team/blood_brothers +/datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" roundstart = TRUE track = EVENT_TRACK_CREWSET @@ -8,9 +8,8 @@ weight = 6 tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) - base_antags = 2 - minimum_candidate_base = 2 - maximum_antags_global = 6 + base_antags = 1 + maximum_antags_global = 4 restricted_roles = list( JOB_AI, @@ -20,20 +19,6 @@ JOB_CAPTAIN, JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, - JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, ) - -/datum/round_event/antagonist/team/blood_brothers - var/required_role = ROLE_BROTHER - - var/datum/team/brother_team/brother_team - -/datum/round_event/antagonist/team/blood_brothers/candidate_roles_setup(mob/candidate) - candidate.mind.special_role = required_role - -/datum/round_event/antagonist/team/blood_brothers/start() - for(var/datum/mind/assigned_player in setup_minds) - add_datum_to_mind(assigned_player, brother_team) - return TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index f21a6b46811c0..777a898d1f329 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -6,5 +6,15 @@ antag_datum = /datum/antagonist/obsessed weight = 10 maximum_antags_global = 4 + typepath = /datum/round_event/antagonist/solo/obsessed category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) + +/datum/round_event/antagonist/solo/obsessed/start() + var/datum/round_event_control/antagonist/re_control = control + var/candidate_list = re_control.get_candidates() + var/mob/living/carbon/human/obsessed = pick_n_take(candidate_list) + obsessed.gain_trauma(/datum/brain_trauma/special/obsessed) + +/datum/round_event/antagonist/solo/obsessed/candidate_setup(datum/round_event_control/antagonist/cast_control) + return From 8e8ef525872223f2b1171f7c654f8fd86742dce6 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 26 Nov 2024 22:34:19 +0300 Subject: [PATCH 034/135] =?UTF-8?q?=D0=A0=D0=B5=D0=B1=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D1=81=20=D0=BD=D1=8E=D0=BA=D0=B8=20=D0=B8=20=D0=BA=D1=83?= =?UTF-8?q?=D0=BB=D1=8C=D1=82=D0=B0=20(=D1=88=D0=B0=D0=BD=D1=81=D1=8B=20?= =?UTF-8?q?=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/clown_ops.dm | 2 +- .../storyteller/code/event_defines/crewset/cult.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 6f6e744d0cfef..6b9c2a9e5200f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -6,7 +6,7 @@ antag_datum = /datum/antagonist/nukeop/clownop antag_leader_datum = /datum/antagonist/nukeop/leader/clownop - weight = 6 + weight = 0 tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) base_antags = 2 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 6087b6927f8e6..d892f2d21a449 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -5,7 +5,7 @@ antag_flag = ROLE_CULTIST antag_datum = /datum/antagonist/cult - weight = 1 + weight = 6 tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC, TAG_COMBAT) base_antags = 3 From cf8c7590d33157c0f1e84b4601014aa47654581c Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 27 Nov 2024 08:12:02 +0300 Subject: [PATCH 035/135] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=91=D0=BB=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0,=20=D0=B8=D0=B7=D0=BC=D0=BD=D0=B5=D0=BD=D0=B5=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=81=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D1=8C=D1=8F=20=D0=B2=20=D0=BB=D0=BE=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 4 ++++ .../storyteller/code/event_defines/major/override.dm | 1 + .../storyteller/code/storytellers/tellers/_storyteller.dm | 7 ------- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 478a4bc0bf6cb..3f9ba32dda036 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -171,6 +171,10 @@ var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!can_spawn_event(players_amt)) message_admins("Second pre-condition check for [name] failed, rerolling...") + var/message = can_spawn_event_error_reason(SSgamemode.storyteller.round_start_handle) + if(message != "success") + message_admins(message) + log_admin(message) SSevents.spawnEvent(excluded_event = src, reroll_reason = SSgamemode.storyteller.round_start_handle) return EVENT_INTERRUPTED else diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 6d67288ce9ace..cc6ce26307c0e 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -7,6 +7,7 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_CHAOTIC) weight = 10 + min_players = 50 /datum/round_event_control/meteor_wave track = EVENT_TRACK_MAJOR diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index 4f8677a268216..208d87dd28ffa 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -95,13 +95,6 @@ valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything if(!length(valid_events)) - for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) - if(isnull(event)) - continue - var/message = event.can_spawn_event_error_reason(round_start_handle) - if(message != "success") - message_admins(message) - log_admin(message) message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER From 1349bc658f033a87ff2d4ec73ea23ef045eead3a Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 27 Nov 2024 18:23:06 +0300 Subject: [PATCH 036/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 12 ++++++---- code/modules/events/_event.dm | 3 ++- .../event_defines/crewset/blood_brothers.dm | 2 +- .../code/event_defines/crewset/changeling.dm | 2 +- .../code/event_defines/crewset/clown_ops.dm | 2 +- .../code/event_defines/crewset/cult.dm | 2 +- .../code/event_defines/crewset/heretic.dm | 2 +- .../code/event_defines/crewset/malf.dm | 2 +- .../code/event_defines/crewset/nuke_ops.dm | 2 +- .../code/event_defines/crewset/revolution.dm | 2 +- .../code/event_defines/crewset/traitors.dm | 2 +- .../storyteller/code/gamemode.dm | 2 ++ .../code/storytellers/tellers/_storyteller.dm | 24 +++++++++++++------ 13 files changed, 37 insertions(+), 22 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 40a82667ab796..2dcc94fdad519 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -70,7 +70,7 @@ SUBSYSTEM_DEF(events) * Arguments: * * excluded_event - The event path we will be foregoing, if present. */ -/datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event, reroll_reason = FALSE) +/datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event) set waitfor = FALSE //for the admin prompt if(!CONFIG_GET(flag/allow_random_events)) return @@ -86,7 +86,7 @@ SUBSYSTEM_DEF(events) if(!event_to_check.can_spawn_event(players_amt)) continue if(event_to_check.weight < 0) //for round-start events etc. - var/res = TriggerEvent(event_to_check) + var/res = SSgamemode.TriggerEvent(event_to_check) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер if(res == EVENT_INTERRUPTED) continue //like it never happened if(res == EVENT_CANT_RUN) @@ -96,17 +96,19 @@ SUBSYSTEM_DEF(events) var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - TriggerEvent(event_to_run, reroll_reason) + SSgamemode.TriggerEvent(event_to_run) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. -/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger, reroll_reason = FALSE) +/* +/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger) . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 - else if(. == EVENT_READY && reroll_reason) + else if(. == EVENT_READY) message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") event_to_trigger.run_event(random = TRUE) + */ /// BANDASTATION EDIT - STORYTELLER - отключение базового фаера событий ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 3f9ba32dda036..8dd9957683d58 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -175,11 +175,12 @@ if(message != "success") message_admins(message) log_admin(message) - SSevents.spawnEvent(excluded_event = src, reroll_reason = SSgamemode.storyteller.round_start_handle) + SSevents.spawnEvent(excluded_event = src) return EVENT_INTERRUPTED else if(SSgamemode.storyteller.round_start_handle && SSticker.HasRoundStarted()) SSgamemode.storyteller.round_start_handle = FALSE + SSgamemode.storyteller.round_start_budget = 0 if(!triggering) return EVENT_CANCELLED //admin cancelled triggering = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 9644e0ada21cc..22e9ec0ac57a4 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" - roundstart = TRUE + roundstart = 8 track = EVENT_TRACK_CREWSET antag_flag = ROLE_BROTHER antag_datum = /datum/antagonist/brother diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index cff9da46d5357..aeaec0c587eb9 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/changeling name = "Changelings" - roundstart = TRUE + roundstart = 12 antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 6b9c2a9e5200f..0a333b22f1538 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/clown_ops name = "Clown Operatives" - roundstart = TRUE + roundstart = 40 track = EVENT_TRACK_CREWSET antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index d892f2d21a449..e1978c450fa41 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/Cult name = "Cult" - roundstart = TRUE + roundstart = 20 track = EVENT_TRACK_CREWSET antag_flag = ROLE_CULTIST antag_datum = /datum/antagonist/cult diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index bae5faf565b06..047a3f3893d14 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/heretic name = "Heretics" - roundstart = TRUE + roundstart = 20 antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 9e78b7e2c5189..8e1751ec5e36d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -22,7 +22,7 @@ /datum/round_event_control/antagonist/solo/malf/roundstart name = "Malfunctioning AI" - roundstart = TRUE + roundstart = 40 typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart weight = 10 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 6fffbecb3b267..15d189fa4f757 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/nuke_ops name = "Nuclear Operatives" - roundstart = TRUE + roundstart = 40 antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 0e54ce96b39bc..b9bdd9725cd94 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/revolution name = "revolution" - roundstart = TRUE + roundstart = 30 track = EVENT_TRACK_MAJOR antag_flag = ROLE_REV antag_datum = /datum/antagonist/rev/ diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index a231b1ca0909a..ccf6cd9bd8b75 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/traitor name = "Traitors" - roundstart = TRUE + roundstart = 10 antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0d0b0126237a8..755c5ed024a6c 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -338,6 +338,7 @@ SUBSYSTEM_DEF(gamemode) /// If the storyteller guarantees an antagonist roll, add points to make it so. if(storyteller.guarantees_roundstart_crewset) storyteller.round_start_handle = TRUE + storyteller.round_start_budget = storyteller.round_start_multiplier * (get_correct_popcount() / storyteller.antag_divisor) event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] /// If we have any forced events, ensure we get enough points for them @@ -411,6 +412,7 @@ SUBSYSTEM_DEF(gamemode) event.max_occurrences = 0 else if(. == EVENT_READY) event.run_event(random = TRUE) // fallback to dynamic + storyteller.round_start_budget -= event.roundstart ///Resets frequency multiplier. /datum/controller/subsystem/gamemode/proc/resetFrequency() diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index 208d87dd28ffa..07d3c649e7367 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -30,7 +30,6 @@ /// Whether the storyteller guaranteed a crewset roll (crew antag) on roundstart. (Still needs to pass pop check) var/guarantees_roundstart_crewset = TRUE - /// Whether the storyteller has the distributions disabled. Important for ghost storytellers var/disable_distribution = FALSE @@ -47,6 +46,8 @@ /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE var/round_start_handle = FALSE + var/round_start_budget = 0 + var/round_start_multiplier = 10 /datum/storyteller/process(delta_time) if(disable_distribution) @@ -94,11 +95,15 @@ if(event.can_spawn_event(player_pop)) valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything - if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") - log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") - SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return + if(SSticker.HasRoundStarted() && round_start_budget <= 0) + if(!length(valid_events)) + message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") + log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") + SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + else + if(!length(valid_events)) + return picked_event = pick_weight(valid_events) if(!picked_event) message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") @@ -114,13 +119,18 @@ var/total_cost = bought_event.cost * SSgamemode.point_thresholds[track] if(!bought_event.roundstart) total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event + else + total_cost = 0 SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") - if(bought_event.roundstart) + if(bought_event.roundstart && round_start_budget > 0) SSgamemode.TriggerEvent(bought_event, round_start_event = round_start_handle) + if(round_start_budget > 0) + find_and_buy_event_from_track(track) else SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) + round_start_budget = 0 /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) From fb1645605b7b4eece3491b8fd80a590719d15466 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 27 Nov 2024 23:48:54 +0300 Subject: [PATCH 037/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D1=83?= =?UTF-8?q?=D0=BB=D1=8C=D1=82=D0=B0,=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=83=D1=81=D0=BA=D0=B0=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82?= =?UTF-8?q?=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 2 +- .../storyteller/code/event_defines/crewset/cult.dm | 4 +--- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 2dcc94fdad519..6eb34f16e6343 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -85,7 +85,7 @@ SUBSYSTEM_DEF(events) continue if(!event_to_check.can_spawn_event(players_amt)) continue - if(event_to_check.weight < 0) //for round-start events etc. + if(event_to_check.roundstart) //for round-start events etc. var/res = SSgamemode.TriggerEvent(event_to_check) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер if(res == EVENT_INTERRUPTED) continue //like it never happened diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index e1978c450fa41..08e0dee29f53a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -11,7 +11,7 @@ base_antags = 3 maximum_antags = 6 maximum_antags_global = 6 - min_players = 40 + //min_players = 40 restricted_roles = list( JOB_AI, @@ -26,8 +26,6 @@ JOB_WARDEN, ) - typepath = /datum/team/cult - category = EVENT_CATEGORY_INVASION /datum/round_event/antagonist/team/cult diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 755c5ed024a6c..3b6f5d3093609 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -882,7 +882,7 @@ SUBSYSTEM_DEF(gamemode) var/list/assoc_spawn_weight = list() var/active_pop = get_correct_popcount() for(var/datum/round_event_control/event as anything in event_lookup) - if(event.roundstart != roundstart_event_view) + if((!roundstart_event_view && event.roundstart) || (roundstart_event_view && !event.roundstart)) continue if(event.can_spawn_event(active_pop)) total_weight += event.calculated_weight From cd92c13de2a275c9552f6f817ea14cabc8d6cafd Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 28 Nov 2024 10:08:55 +0300 Subject: [PATCH 038/135] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=82=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B0,=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B5=D0=B6?= =?UTF-8?q?=D0=B8=D0=BD=D0=B5=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/cult.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 08e0dee29f53a..fb86c8050c9a2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -11,7 +11,7 @@ base_antags = 3 maximum_antags = 6 maximum_antags_global = 6 - //min_players = 40 + min_players = 40 restricted_roles = list( JOB_AI, diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 3b6f5d3093609..b5b7fd8411244 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -724,7 +724,7 @@ SUBSYSTEM_DEF(gamemode) dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." - dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [rnd_crew]) - Antag Cap: [get_antag_cap()]" + dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [rnd_crew]) - Antag Cap: [get_antag_cap()], Antag Count: [length(GLOB.current_living_antags)]" dat += "
" dat += "Main" dat += " Variables" From 5e1ccc9b2a60d208f586348713db089f1018dc71 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 29 Nov 2024 20:47:45 +0300 Subject: [PATCH 039/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B4=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=81=D0=BE=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20=D0=BD=D0=B5=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BD=D0=BE=D0=B9=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 2 +- code/modules/events/_event.dm | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 9463186a63e8d..ab59b422f3084 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -303,7 +303,7 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE - SSdynamic.post_setup() + //SSdynamic.post_setup() /// BANDASTATION EDIT STORYTELLER - отключение пост-сетапа динамика GLOB.start_state = new /datum/station_state() GLOB.start_state.count() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 8dd9957683d58..d85c9138d4d01 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -150,7 +150,7 @@ if(SSticker.HasRoundStarted() && !roundstart && !admin_forced) message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ CANCEL | \ - SOMETHING ELSE)") + SOMETHING ELSE)
") for(var/client/staff as anything in GLOB.admins) if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) @@ -162,7 +162,7 @@ if(!roundstart && !admin_forced) message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ CANCEL | \ - SOMETHING ELSE)") + SOMETHING ELSE)
") sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) else message_admins(" Roundstart event chosen: [name].") @@ -196,15 +196,18 @@ message_admins("[key_name_admin(usr)] cancelled event [name].") log_admin_private("[key_name(usr)] cancelled event [name].") SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath) + SSgamemode.remove_scheduled_event(src) if(href_list["different_event"]) if(!triggering) to_chat(usr, span_admin("Too late to change events now!")) return + SSevents.spawnEvent(excluded_event = src) triggering = FALSE message_admins("[key_name_admin(usr)] chose to have event [name] rolled into a different event.") log_admin_private("[key_name(usr)] rerolled event [name].") SSblackbox.record_feedback("tally", "event_admin_rerolled", 1, typepath) - SSevents.spawnEvent(excluded_event = src) + SSgamemode.remove_scheduled_event(src) + /* Runs the event From a83b55ad5aa98e014462d122a27e2600b22b5f01 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 30 Nov 2024 19:14:29 +0300 Subject: [PATCH 040/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BC=D0=BD?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D1=81=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0=20=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=BE?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 6eb34f16e6343..94462e51f58dc 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -85,12 +85,14 @@ SUBSYSTEM_DEF(events) continue if(!event_to_check.can_spawn_event(players_amt)) continue + if(event_to_check.roundstart) //for round-start events etc. var/res = SSgamemode.TriggerEvent(event_to_check) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер if(res == EVENT_INTERRUPTED) continue //like it never happened if(res == EVENT_CANT_RUN) return + return // Отмена дальнешего исполнения если удачная активация события else event_roster[event_to_check] = event_to_check.weight From f3de8bd0719186f0956ef50a87a37348aaa1cb81 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 12:04:54 +0300 Subject: [PATCH 041/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 12 +++++--- code/modules/events/_event.dm | 8 ++--- .../storyteller/_storyteller.dm | 2 +- .../crewset/_antagonist_event.dm | 29 +++++++++---------- .../event_defines/crewset/blood_brothers.dm | 4 ++- .../code/event_defines/crewset/changeling.dm | 4 ++- .../code/event_defines/crewset/clown_ops.dm | 4 ++- .../code/event_defines/crewset/cult.dm | 4 ++- .../code/event_defines/crewset/heretic.dm | 3 +- .../code/event_defines/crewset/malf.dm | 6 ++-- .../code/event_defines/crewset/nuke_ops.dm | 3 +- .../code/event_defines/crewset/obsessed.dm | 1 + .../code/event_defines/crewset/revolution.dm | 4 ++- .../code/event_defines/crewset/spies.dm | 1 + .../code/event_defines/crewset/traitors.dm | 3 +- .../storyteller/code/gamemode.dm | 2 -- .../storyteller/code/scheduled_event.dm | 8 +++-- .../code/storytellers/tellers/_storyteller.dm | 22 +++++++------- 18 files changed, 68 insertions(+), 52 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 94462e51f58dc..17ac36cbcfab3 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -86,19 +86,23 @@ SUBSYSTEM_DEF(events) if(!event_to_check.can_spawn_event(players_amt)) continue + /* // BANDASTATION EDIT START - STORYTELLER - изменение логики if(event_to_check.roundstart) //for round-start events etc. var/res = SSgamemode.TriggerEvent(event_to_check) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер if(res == EVENT_INTERRUPTED) continue //like it never happened - if(res == EVENT_CANT_RUN) - return - return // Отмена дальнешего исполнения если удачная активация события + if(res == EVENT_CANT_RUN) // BANDASTATION EDIT - STORYTELLER - легкая оптимизация + return // BANDASTATION EDIT - STORYTELLER - легкая оптимизация else event_roster[event_to_check] = event_to_check.weight + */ // BANDASTATION EDIT END - STORYTELLER - изменение логики + event_roster[event_to_check] = event_to_check.weight var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - SSgamemode.TriggerEvent(event_to_run) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер + if(excluded_event) + message_admins("Rerolled to [event_to_run.name].") + SSgamemode.schedule_event(event_to_run, (rand(3, 4) MINUTES), passed_ignore = TRUE) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. /* diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index d85c9138d4d01..6666575e637e0 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -70,7 +70,7 @@ // Checks if the event can be spawned. Used by event controller and "false alarm" event. // Admin-created events override this. -/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE, round_start_event = FALSE) +/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) SHOULD_CALL_PARENT(TRUE) if(occurrences >= max_occurrences) return FALSE @@ -171,16 +171,12 @@ var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!can_spawn_event(players_amt)) message_admins("Second pre-condition check for [name] failed, rerolling...") - var/message = can_spawn_event_error_reason(SSgamemode.storyteller.round_start_handle) + var/message = can_spawn_event_error_reason(players_amt) if(message != "success") message_admins(message) log_admin(message) SSevents.spawnEvent(excluded_event = src) return EVENT_INTERRUPTED - else - if(SSgamemode.storyteller.round_start_handle && SSticker.HasRoundStarted()) - SSgamemode.storyteller.round_start_handle = FALSE - SSgamemode.storyteller.round_start_budget = 0 if(!triggering) return EVENT_CANCELLED //admin cancelled triggering = FALSE diff --git a/modular_bandastation/storyteller/_storyteller.dm b/modular_bandastation/storyteller/_storyteller.dm index 2810c4aa3bbbf..f00ea34cb8163 100644 --- a/modular_bandastation/storyteller/_storyteller.dm +++ b/modular_bandastation/storyteller/_storyteller.dm @@ -1,4 +1,4 @@ /datum/modpack/storyteller name = "Storyteller mode" - desc = "Адаптация режиме сторителлера для Bandastation." + desc = "Адаптация режима сторителлера для Bandastation." author = "Bubberstation, KageIIte" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 122cf3707352b..28df848888682 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -42,19 +42,18 @@ /datum/round_event_control/antagonist/New() . = ..() - if(!SSticker.HasRoundStarted()) // Снятие защиты от раундстартовых антагов - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_roles |= protected_roles - restricted_roles |= SSstation.antag_restricted_roles - restricted_roles |= SSstation.antag_protected_roles - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_roles |= JOB_ASSISTANT - -/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE, round_start_event = FALSE) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_roles |= protected_roles + restricted_roles |= SSstation.antag_restricted_roles + restricted_roles |= SSstation.antag_protected_roles + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_roles |= JOB_ASSISTANT + +/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) . = ..() if(!.) return - if(roundstart && (SSticker.HasRoundStarted() && !round_start_event)) + if(roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) return FALSE if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) return FALSE @@ -64,12 +63,10 @@ if(candidates.len < get_minimum_candidates()) return FALSE -/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE, round_start_event = FALSE) +/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE) . = ..() var/message = . - if(message == "success") - return - if(roundstart && (SSticker.HasRoundStarted() && !round_start_event)) + if(roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." @@ -86,8 +83,8 @@ return minimum_candidate_base /datum/round_event_control/antagonist/proc/get_candidates() - var/round_started = SSticker.HasRoundStarted() - var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = !round_started, restricted_roles = restricted_roles) + var/round_started = SSticker.HasRoundStarted() || (roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) + var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = round_started, restricted_roles = restricted_roles) return candidates /datum/round_event_control/antagonist/solo diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 22e9ec0ac57a4..c2898f54e690e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,6 +1,8 @@ /datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" - roundstart = 8 + roundstart = TRUE + earliest_start = 1 MINUTES + track = EVENT_TRACK_CREWSET antag_flag = ROLE_BROTHER antag_datum = /datum/antagonist/brother diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index aeaec0c587eb9..415f3c5b4f78e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/changeling name = "Changelings" - roundstart = 12 + roundstart = TRUE + earliest_start = 1 MINUTES antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling @@ -9,3 +10,4 @@ maximum_antags_global = 4 category = EVENT_CATEGORY_INVASION tags = list(TAG_COMBAT, TAG_CREW_ANTAG) + protected_roles = list() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 0a333b22f1538..fc639d6def3ea 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,6 +1,8 @@ /datum/round_event_control/antagonist/team/clown_ops name = "Clown Operatives" - roundstart = 40 + roundstart = TRUE + earliest_start = 1 MINUTES + track = EVENT_TRACK_CREWSET antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index fb86c8050c9a2..6216fcdd8dad0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,6 +1,8 @@ /datum/round_event_control/antagonist/team/Cult name = "Cult" - roundstart = 20 + roundstart = TRUE + earliest_start = 1 MINUTES + track = EVENT_TRACK_CREWSET antag_flag = ROLE_CULTIST antag_datum = /datum/antagonist/cult diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 047a3f3893d14..ac4c9f887dc3d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/heretic name = "Heretics" - roundstart = 20 + roundstart = TRUE + earliest_start = 1 MINUTES antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 8e1751ec5e36d..c28e600a5b784 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -6,7 +6,7 @@ maximum_antags = 1 maximum_antags_global = 1 - min_players = 20 + min_players = TRUE roundstart = FALSE antag_datum = /datum/antagonist/malf_ai @@ -22,7 +22,9 @@ /datum/round_event_control/antagonist/solo/malf/roundstart name = "Malfunctioning AI" - roundstart = 40 + roundstart = TRUE + earliest_start = 1 MINUTES + typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart weight = 10 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 15d189fa4f757..197a864a1c613 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/team/nuke_ops name = "Nuclear Operatives" - roundstart = 40 + roundstart = TRUE + earliest_start = 1 MINUTES antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index 777a898d1f329..9ff8782cfed36 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -9,6 +9,7 @@ typepath = /datum/round_event/antagonist/solo/obsessed category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) + protected_roles = list() /datum/round_event/antagonist/solo/obsessed/start() var/datum/round_event_control/antagonist/re_control = control diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index b9bdd9725cd94..0e3445ef8cb18 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,6 +1,8 @@ /datum/round_event_control/antagonist/team/revolution name = "revolution" - roundstart = 30 + roundstart = TRUE + earliest_start = 1 MINUTES + track = EVENT_TRACK_MAJOR antag_flag = ROLE_REV antag_datum = /datum/antagonist/rev/ diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index b4d3a008a4d4d..80a2e0cf7d48a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/spy name = "Spies" roundstart = TRUE + earliest_start = 1 MINUTES antag_flag = ROLE_SPY antag_datum = /datum/antagonist/spy diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index ccf6cd9bd8b75..66e46978a9df0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/traitor name = "Traitors" - roundstart = 10 + roundstart = TRUE + earliest_start = 1 MINUTES antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index b5b7fd8411244..8008ac83e332b 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -338,7 +338,6 @@ SUBSYSTEM_DEF(gamemode) /// If the storyteller guarantees an antagonist roll, add points to make it so. if(storyteller.guarantees_roundstart_crewset) storyteller.round_start_handle = TRUE - storyteller.round_start_budget = storyteller.round_start_multiplier * (get_correct_popcount() / storyteller.antag_divisor) event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] /// If we have any forced events, ensure we get enough points for them @@ -412,7 +411,6 @@ SUBSYSTEM_DEF(gamemode) event.max_occurrences = 0 else if(. == EVENT_READY) event.run_event(random = TRUE) // fallback to dynamic - storyteller.round_start_budget -= event.roundstart ///Resets frequency multiplier. /datum/controller/subsystem/gamemode/proc/resetFrequency() diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index 4b11b152d2d3e..1d9797a8e48c4 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -14,6 +14,7 @@ var/ignores_checks /// Whether the scheduled event will override the announcement change. If null it won't. TRUE = force yes. FALSE = force no. var/announce_change + /// Ивент должен учитывать себя как ивент в начале раунда и не проходить проверки, связанные с этим /datum/scheduled_event/New(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) . = ..() @@ -50,9 +51,10 @@ remove_occurence() var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = FALSE) ///If we can't spawn the scheduled event, refund it. - if(!ignores_checks && !event.can_spawn_event(players_amt)) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. - message_admins("Scheduled Event: [event] was unable to run and has been refunded.") - log_admin("Scheduled Event: [event] was unable to run and has been refunded.") + if(!ignores_checks && !event.can_spawn_event(players_amt) && !admin_forced) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. + var/message = event.can_spawn_event_error_reason(players_amt) + message_admins("Scheduled Event: [event] was unable to run and has been refunded. REASON: [message]") + log_admin("Scheduled Event: [event] was unable to run and has been refunded. REASON: [message]") SSgamemode.refund_scheduled_event(src) return diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index 07d3c649e7367..f3dfa0c30f8b1 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -46,7 +46,6 @@ /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE var/round_start_handle = FALSE - var/round_start_budget = 0 var/round_start_multiplier = 10 /datum/storyteller/process(delta_time) @@ -54,6 +53,8 @@ return add_points(delta_time) handle_tracks() + if(SSticker.HasRoundStarted()) + SSgamemode.storyteller.round_start_handle = FALSE /// Add points to all tracks while respecting the multipliers. /datum/storyteller/proc/add_points(delta_time) @@ -95,7 +96,7 @@ if(event.can_spawn_event(player_pop)) valid_events[event] = event.calculated_weight ///If we didn't get any events, remove the points inform admins and dont do anything - if(SSticker.HasRoundStarted() && round_start_budget <= 0) + if(SSticker.HasRoundStarted()) if(!length(valid_events)) message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") @@ -120,17 +121,18 @@ if(!bought_event.roundstart) total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event else - total_cost = 0 - SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) + total_cost *= antag_divisor / SSgamemode.get_correct_popcount() //Цена на покупку варьируется от количество игроков message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") - if(bought_event.roundstart && round_start_budget > 0) - SSgamemode.TriggerEvent(bought_event, round_start_event = round_start_handle) - if(round_start_budget > 0) - find_and_buy_event_from_track(track) + SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) + if(!SSticker.HasRoundStarted()) + if(bought_event.roundstart) + SSgamemode.schedule_event(bought_event, (15 SECONDS), total_cost) + if(SSgamemode.event_track_points[track] > 0) + find_and_buy_event_from_track(track) else - SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) - round_start_budget = 0 + if(!SSticker.HasRoundStarted()) + SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) From b5d1ba24ad1a6f65b4bb7c29943aab08d1eba9d6 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 15:35:03 +0300 Subject: [PATCH 042/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BD=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=80=D0=B0=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 2 +- .../crewset/_antagonist_event.dm | 10 +++---- .../event_defines/crewset/blood_brothers.dm | 1 - .../code/event_defines/crewset/changeling.dm | 1 - .../code/event_defines/crewset/clown_ops.dm | 1 - .../code/event_defines/crewset/cult.dm | 1 - .../code/event_defines/crewset/heretic.dm | 1 - .../code/event_defines/crewset/malf.dm | 5 ++-- .../code/event_defines/crewset/nuke_ops.dm | 1 - .../code/event_defines/crewset/obsessed.dm | 2 +- .../code/event_defines/crewset/revolution.dm | 1 - .../code/event_defines/crewset/spies.dm | 1 - .../code/event_defines/crewset/traitors.dm | 1 - .../storyteller/code/gamemode.dm | 27 ++++++++++++++++--- .../code/storytellers/tellers/_storyteller.dm | 17 ++++++------ 15 files changed, 42 insertions(+), 30 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 6666575e637e0..6058df3835088 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -135,7 +135,7 @@ return message -/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE, round_start_event = FALSE) +/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE) if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 28df848888682..70500cc3adb01 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -53,20 +53,20 @@ . = ..() if(!.) return - if(roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) + if(roundstart && SSticker.HasRoundStarted()) return FALSE if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) return FALSE if(!get_antag_amount()) return FALSE var/list/candidates = get_candidates() - if(candidates.len < get_minimum_candidates()) + if(length(candidates) < get_minimum_candidates()) return FALSE /datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE) . = ..() var/message = . - if(roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) + if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." @@ -83,8 +83,8 @@ return minimum_candidate_base /datum/round_event_control/antagonist/proc/get_candidates() - var/round_started = SSticker.HasRoundStarted() || (roundstart && SSticker.HasRoundStarted() && earliest_start <= world.time-SSticker.round_start_time) - var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = round_started, restricted_roles = restricted_roles) + var/round_started = SSticker.HasRoundStarted() + var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = !round_started, restricted_roles = restricted_roles) return candidates /datum/round_event_control/antagonist/solo diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index c2898f54e690e..431a01c7b935f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" roundstart = TRUE - earliest_start = 1 MINUTES track = EVENT_TRACK_CREWSET antag_flag = ROLE_BROTHER diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 415f3c5b4f78e..9bf82fd5d2cd2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/solo/changeling name = "Changelings" roundstart = TRUE - earliest_start = 1 MINUTES antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index fc639d6def3ea..16e3c338fa50a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/team/clown_ops name = "Clown Operatives" roundstart = TRUE - earliest_start = 1 MINUTES track = EVENT_TRACK_CREWSET antag_flag = ROLE_CLOWN_OPERATIVE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 6216fcdd8dad0..60be6e0b223d8 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/team/Cult name = "Cult" roundstart = TRUE - earliest_start = 1 MINUTES track = EVENT_TRACK_CREWSET antag_flag = ROLE_CULTIST diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index ac4c9f887dc3d..bae5faf565b06 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/solo/heretic name = "Heretics" roundstart = TRUE - earliest_start = 1 MINUTES antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index c28e600a5b784..5da4622e0dd44 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -5,6 +5,7 @@ base_antags = 1 maximum_antags = 1 maximum_antags_global = 1 + min_players = 20 min_players = TRUE roundstart = FALSE @@ -23,14 +24,14 @@ name = "Malfunctioning AI" roundstart = TRUE - earliest_start = 1 MINUTES + min_players = 20 typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart weight = 10 // God has abandoned us /datum/round_event_control/antagonist/solo/malf/roundstart/get_candidates() - var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = TRUE, restricted_roles = restricted_roles) + var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = TRUE) . = list() var/datum/job/aijob = SSjob.get_job(JOB_AI) for(var/mob/candidate as anything in candidates) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 197a864a1c613..6fffbecb3b267 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/team/nuke_ops name = "Nuclear Operatives" roundstart = TRUE - earliest_start = 1 MINUTES antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index 9ff8782cfed36..d02936b4554a1 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -17,5 +17,5 @@ var/mob/living/carbon/human/obsessed = pick_n_take(candidate_list) obsessed.gain_trauma(/datum/brain_trauma/special/obsessed) -/datum/round_event/antagonist/solo/obsessed/candidate_setup(datum/round_event_control/antagonist/cast_control) +/datum/round_event/antagonist/solo/obsessed/candidate_setup(datum/round_event_control/antagonist/cast_control, no_restricts = TRUE, antag_token = null) return diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 0e3445ef8cb18..70ff37da981de 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/team/revolution name = "revolution" roundstart = TRUE - earliest_start = 1 MINUTES track = EVENT_TRACK_MAJOR antag_flag = ROLE_REV diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index 80a2e0cf7d48a..b4d3a008a4d4d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/solo/spy name = "Spies" roundstart = TRUE - earliest_start = 1 MINUTES antag_flag = ROLE_SPY antag_datum = /datum/antagonist/spy diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 66e46978a9df0..a231b1ca0909a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,7 +1,6 @@ /datum/round_event_control/antagonist/solo/traitor name = "Traitors" roundstart = TRUE - earliest_start = 1 MINUTES antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 8008ac83e332b..0b6043ba4df40 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -133,6 +133,7 @@ SUBSYSTEM_DEF(gamemode) var/wizardmode = FALSE var/storyteller_voted = FALSE + var/roundstart_secs = 0 /datum/controller/subsystem/gamemode/Initialize(time, zlevel) . = ..() @@ -337,7 +338,6 @@ SUBSYSTEM_DEF(gamemode) /// If the storyteller guarantees an antagonist roll, add points to make it so. if(storyteller.guarantees_roundstart_crewset) - storyteller.round_start_handle = TRUE event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] /// If we have any forced events, ensure we get enough points for them @@ -405,8 +405,8 @@ SUBSYSTEM_DEF(gamemode) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) rnd_crew++ -/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE, round_start_event = FALSE) - . = event.preRunEvent(admin_forced, round_start_event) +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE) + . = event.preRunEvent(admin_forced) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event.max_occurrences = 0 else if(. == EVENT_READY) @@ -486,16 +486,37 @@ SUBSYSTEM_DEF(gamemode) ///Attempts to select players for special roles the mode might have. /datum/controller/subsystem/gamemode/proc/pre_setup() // We need to do this to prevent some niche fuckery... and make dep. orders work. Lol + + recalculate_secs() SSjob.reset_occupations() calculate_ready_players() roll_pre_setup_points() handle_pre_setup_roundstart_events() return TRUE +/datum/controller/subsystem/gamemode/proc/recalculate_secs() + sec_crew = 0 + SSjob.divide_occupations(pure = TRUE, allow_all = TRUE) + for(var/i in GLOB.new_player_list) + var/mob/dead/new_player/player = i + if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) + if(is_unassigned_job(player.mind.assigned_role)) + var/list/job_data = list() + var/job_prefs = player.client.prefs.job_preferences + for(var/job in job_prefs) + var/priority = job_prefs[job] + job_data += "[job]: [SSjob.job_priority_level_to_string(priority)]" + to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role this round because your job preferences presented a high chance of all of your selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled. Increase the number of roles set to medium or low priority to reduce the chances of this happening.")) + log_admin("[player.ckey] failed to qualify for any roundstart antagonist role because their job preferences presented a high chance of all of their selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]") + else + if(player.mind?.assigned_role?.departments_list?.Find(/datum/job_department/security) && (!player.mind?.special_role)) + sec_crew++ + ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/controller/subsystem/gamemode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) report = !CONFIG_GET(flag/no_intercept_report) + addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) if(SSdbcore.Connect()) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index f3dfa0c30f8b1..f422218a8a15c 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -45,7 +45,6 @@ var/max_sec_mult = 1 /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE - var/round_start_handle = FALSE var/round_start_multiplier = 10 /datum/storyteller/process(delta_time) @@ -53,8 +52,6 @@ return add_points(delta_time) handle_tracks() - if(SSticker.HasRoundStarted()) - SSgamemode.storyteller.round_start_handle = FALSE /// Add points to all tracks while respecting the multipliers. /datum/storyteller/proc/add_points(delta_time) @@ -122,17 +119,19 @@ total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event else total_cost *= antag_divisor / SSgamemode.get_correct_popcount() //Цена на покупку варьируется от количество игроков + message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) + if(!SSticker.HasRoundStarted()) - if(bought_event.roundstart) - SSgamemode.schedule_event(bought_event, (15 SECONDS), total_cost) - if(SSgamemode.event_track_points[track] > 0) - find_and_buy_event_from_track(track) + SSgamemode.TriggerEvent(bought_event) + SSgamemode.recalculate_secs() + if(SSgamemode.event_track_points[track] > 0) + find_and_buy_event_from_track(track) else - if(!SSticker.HasRoundStarted()) - SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) + SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) From 8b1b4569360c603480c7c28a66fab1a170252904 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 17:52:10 +0300 Subject: [PATCH 043/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B=20=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=20=D1=81?= =?UTF-8?q?=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crewset/_antagonist_event.dm | 2 +- .../event_defines/crewset/blood_brothers.dm | 2 +- .../code/event_defines/crewset/changeling.dm | 2 +- .../code/event_defines/crewset/clown_ops.dm | 2 +- .../code/event_defines/crewset/cult.dm | 2 +- .../code/event_defines/crewset/heretic.dm | 2 +- .../code/event_defines/crewset/malf.dm | 2 +- .../code/event_defines/crewset/nuke_ops.dm | 2 +- .../code/event_defines/crewset/revolution.dm | 2 +- .../code/event_defines/crewset/spies.dm | 2 +- .../code/event_defines/crewset/traitors.dm | 2 +- .../storyteller/code/gamemode.dm | 21 ++++++++++++++++++- .../code/storytellers/tellers/_storyteller.dm | 3 ++- 13 files changed, 33 insertions(+), 13 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 70500cc3adb01..8dfcc0999ee1f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -68,7 +68,7 @@ var/message = . if(roundstart && SSticker.HasRoundStarted()) message = "Storyteller event: [name] was unable to run due event is roundstart and round started." - if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) + if(!SSgamemode.can_inject_antags()) message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." if(!get_antag_amount()) message = "Storyteller event: [name] was unable to run due no antags count to spawn." diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 431a01c7b935f..35fcdcc55a8e9 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" - roundstart = TRUE + roundstart = 1 track = EVENT_TRACK_CREWSET antag_flag = ROLE_BROTHER diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 9bf82fd5d2cd2..077f51e3e9efc 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/changeling name = "Changelings" - roundstart = TRUE + roundstart = 1.9 antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 16e3c338fa50a..ad18bbd2cf06a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/clown_ops name = "Clown Operatives" - roundstart = TRUE + roundstart = 2 track = EVENT_TRACK_CREWSET antag_flag = ROLE_CLOWN_OPERATIVE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 60be6e0b223d8..a34b0c58acbd9 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/Cult name = "Cult" - roundstart = TRUE + roundstart = 3 track = EVENT_TRACK_CREWSET antag_flag = ROLE_CULTIST diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index bae5faf565b06..ed13a7d3b79e0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/heretic name = "Heretics" - roundstart = TRUE + roundstart = 1.5 antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 5da4622e0dd44..78713c7878d10 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -23,7 +23,7 @@ /datum/round_event_control/antagonist/solo/malf/roundstart name = "Malfunctioning AI" - roundstart = TRUE + roundstart = 1.8 min_players = 20 typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 6fffbecb3b267..128fc2575b623 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/nuke_ops name = "Nuclear Operatives" - roundstart = TRUE + roundstart = 2 antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 70ff37da981de..57da82eca3bcd 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/team/revolution name = "revolution" - roundstart = TRUE + roundstart = 2 track = EVENT_TRACK_MAJOR antag_flag = ROLE_REV diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index b4d3a008a4d4d..651dae48dcadc 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/spy name = "Spies" - roundstart = TRUE + roundstart = 10 antag_flag = ROLE_SPY antag_datum = /datum/antagonist/spy diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index a231b1ca0909a..47ff16a45de4c 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/traitor name = "Traitors" - roundstart = TRUE + roundstart = 1.3 antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0b6043ba4df40..1327fcd7b4040 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -216,9 +216,27 @@ SUBSYSTEM_DEF(gamemode) var/result = round(clamped_cap) return result +/datum/controller/subsystem/gamemode/proc/get_antag_count() + var/a_count = 0 + if(SSticker.HasRoundStarted()) + a_count = length(GLOB.current_living_antags) + else + for(var/mob/player_mob as anything in GLOB.player_list) + if(!player_mob.client) + continue + if(player_mob.stat) + continue + if(player_mob.client.is_afk()) + continue + if(!ishuman(player_mob)) + continue + if(player_mob.mind?.special_role) + a_count++ + return a_count + /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() - return get_antag_cap() > length(GLOB.current_living_antags) + return get_antag_cap() > get_antag_count() /// Gets candidates for antagonist roles. @@ -339,6 +357,7 @@ SUBSYSTEM_DEF(gamemode) /// If the storyteller guarantees an antagonist roll, add points to make it so. if(storyteller.guarantees_roundstart_crewset) event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] + storyteller.ready_cost_modifier = SSgamemode.get_correct_popcount() / storyteller.antag_divisor /// If we have any forced events, ensure we get enough points for them for(var/track in event_tracks) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm index f422218a8a15c..fba00f5a00d94 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm @@ -46,6 +46,7 @@ /// Two tellers of the same intensity group can't run in 2 consecutive rounds var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE var/round_start_multiplier = 10 + var/ready_cost_modifier = 1 /datum/storyteller/process(delta_time) if(disable_distribution) @@ -118,7 +119,7 @@ if(!bought_event.roundstart) total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event else - total_cost *= antag_divisor / SSgamemode.get_correct_popcount() //Цена на покупку варьируется от количество игроков + total_cost = (total_cost / ready_cost_modifier) * bought_event.roundstart //antag_divisor / SSgamemode.get_correct_popcount() * bought_event.roundstart //Цена на покупку варьируется от количество игроков и вида ивента message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") From 0fad7bfea552482b55f1315fb3a480c315ee2f83 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 20:46:33 +0300 Subject: [PATCH 044/135] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=BD=D0=B5=D0=B3=D0=BE=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D1=82=D0=B0=20(=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=BC=D0=B0=D0=B7=D0=BE=D0=BB=D0=B8=D0=BB=D0=BE=20?= =?UTF-8?q?=D0=B3=D0=BB=D0=B0=D0=B7=D0=B0),=20=D0=B2=D1=8B=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=D0=BA=D0=B0=20=D0=B8=D0=B7=20=D0=BC=D0=B5=D0=BD=D1=8E=20?= =?UTF-8?q?=D0=BE=D0=BF=D1=86=D0=B8=D0=B9=20=D0=B4=D0=B8=D0=BD=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0,=20=D0=BB=D0=B5=D0=B3=D0=BA=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B2=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B5=20=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2,=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D1=81?= =?UTF-8?q?=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D1=83=20=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=B8=D0=B3=D1=80=D0=BE=D0=BA=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BB=D0=B6=D0=BD=D0=BE=20=D0=B1=D1=8B=D0=BB=D0=BE=20?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D1=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/admin/admin.dm | 4 ++-- code/modules/events/_event.dm | 2 +- .../code/event_defines/crewset/_antagonist_event.dm | 2 +- .../storyteller/code/event_defines/crewset/blood_brothers.dm | 1 + .../storyteller/code/event_defines/crewset/changeling.dm | 1 + .../storyteller/code/event_defines/crewset/clown_ops.dm | 1 + .../storyteller/code/event_defines/crewset/cult.dm | 1 + .../storyteller/code/event_defines/crewset/heretic.dm | 1 + .../storyteller/code/event_defines/crewset/malf.dm | 1 + .../storyteller/code/event_defines/crewset/nuke_ops.dm | 1 + .../storyteller/code/event_defines/crewset/revolution.dm | 1 + .../storyteller/code/event_defines/crewset/spies.dm | 1 + .../storyteller/code/event_defines/crewset/traitors.dm | 1 + 13 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a9a5f3156f9f8..aaf55f87cac0b 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -30,11 +30,11 @@ for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) dat += {"-> [rule.name] <-
"} dat += "(Clear Rulesets)
" - dat += "(Dynamic mode options)
" + //dat += "(Dynamic mode options)
" /// BANDASTATION EDIT - STORYTELLER dat += "
" if(SSticker.IsRoundInProgress()) dat += "(Game Mode Panel)
" - //dat += "(Manage Dynamic Rulesets)
" BANDASTATION EDIT - STORYTELLER + //dat += "(Manage Dynamic Rulesets)
" /// BANDASTATION EDIT - STORYTELLER dat += {"
Create Object
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 6058df3835088..3ddafff00604b 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -115,7 +115,7 @@ if(!allow_magic && wizardevent != SSevents.wizardmode) message = "Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode." if(players_amt < min_players) - message = "Storyteller event: [name] was unable to run due too low players for event." + message = "Storyteller event: [name] was unable to run due too low players for event (amt/min - [players_amt]/[min_players])." if(holidayID && !check_holidays(holidayID)) message = "Storyteller event: [name] was unable to run due try to run on non-holiday day." if(EMERGENCY_ESCAPED_OR_ENDGAMED) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm index 8dfcc0999ee1f..8346f54101a2f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm @@ -55,7 +55,7 @@ return if(roundstart && SSticker.HasRoundStarted()) return FALSE - if(SSticker.HasRoundStarted() && !SSgamemode.can_inject_antags()) + if(!SSgamemode.can_inject_antags()) return FALSE if(!get_antag_amount()) return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 35fcdcc55a8e9..99ee38316aa6e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/blood_brothers name = "Blood Brother" roundstart = 1 + earliest_start = 0 SECONDS track = EVENT_TRACK_CREWSET antag_flag = ROLE_BROTHER diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 077f51e3e9efc..312835bdb829b 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/changeling name = "Changelings" roundstart = 1.9 + earliest_start = 0 SECONDS antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index ad18bbd2cf06a..4d6b9184ef9fd 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/team/clown_ops name = "Clown Operatives" roundstart = 2 + earliest_start = 0 SECONDS track = EVENT_TRACK_CREWSET antag_flag = ROLE_CLOWN_OPERATIVE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index a34b0c58acbd9..460931ba419ff 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/team/Cult name = "Cult" roundstart = 3 + earliest_start = 0 SECONDS track = EVENT_TRACK_CREWSET antag_flag = ROLE_CULTIST diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index ed13a7d3b79e0..2d34fc991f81f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/heretic name = "Heretics" roundstart = 1.5 + earliest_start = 0 SECONDS antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 78713c7878d10..2342dea16c5ae 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -22,6 +22,7 @@ /datum/round_event_control/antagonist/solo/malf/roundstart name = "Malfunctioning AI" + earliest_start = 0 SECONDS roundstart = 1.8 min_players = 20 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 128fc2575b623..314275002ce9e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/team/nuke_ops name = "Nuclear Operatives" roundstart = 2 + earliest_start = 0 SECONDS antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 57da82eca3bcd..622a7b87e132b 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/team/revolution name = "revolution" roundstart = 2 + earliest_start = 0 SECONDS track = EVENT_TRACK_MAJOR antag_flag = ROLE_REV diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index 651dae48dcadc..7803fb0d0d4a7 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/spy name = "Spies" roundstart = 10 + earliest_start = 0 SECONDS antag_flag = ROLE_SPY antag_datum = /datum/antagonist/spy diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 47ff16a45de4c..018b376fa4846 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,6 +1,7 @@ /datum/round_event_control/antagonist/solo/traitor name = "Traitors" roundstart = 1.3 + earliest_start = 0 SECONDS antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor From dc8bbac481025dcb7f2f32bb1ee6d422fe7f4b75 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 21:02:08 +0300 Subject: [PATCH 045/135] =?UTF-8?q?=D0=A1=D0=BD=D0=B8=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D0=BC=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D0=BA=D1=80=D0=B0=D0=B4=D0=B0,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D1=83=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=BD=D0=B5=20=D0=A1=D0=A2=20=D0=BD=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D1=83=D1=8E=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D0=B2=D1=8B=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D0=BB=D0=B0=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 3 ++- .../storyteller/code/event_defines/crewset/changeling.dm | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 3ddafff00604b..9af388af38a7b 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -168,7 +168,8 @@ message_admins(" Roundstart event chosen: [name].") // BANDASTATION EDIT END - var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + // var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) /// BANDASTATION EDIT - STORYTELLER + var/players_amt = SSgamemode.get_correct_popcount() if(!can_spawn_event(players_amt)) message_admins("Second pre-condition check for [name] failed, rerolling...") var/message = can_spawn_event_error_reason(players_amt) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 312835bdb829b..73561202b2248 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -6,7 +6,7 @@ antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling weight = 8 - min_players = 20 + min_players = 15 maximum_antags_global = 4 category = EVENT_CATEGORY_INVASION tags = list(TAG_COMBAT, TAG_CREW_ANTAG) From f4fe61560d2b588f45ce4bde8158039d71d7ab66 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 21:44:38 +0300 Subject: [PATCH 046/135] =?UTF-8?q?=D0=92=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE?= =?UTF-8?q?=D0=BD=D0=B8=D1=81=D1=82=D0=BE=D0=B2=20=D0=B4=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B0=20=D0=A1=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 1327fcd7b4040..b6bbc1bf2dd7c 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -213,7 +213,7 @@ SUBSYSTEM_DEF(gamemode) var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) - var/result = round(clamped_cap) + var/result = sec_crew // round(clamped_cap) return result /datum/controller/subsystem/gamemode/proc/get_antag_count() From ad8a0244f0c58a3e014af3485fa556df04ddc13d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 1 Dec 2024 22:11:03 +0300 Subject: [PATCH 047/135] =?UTF-8?q?=D0=9B=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index b6bbc1bf2dd7c..9ea9d808250d2 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -209,10 +209,10 @@ SUBSYSTEM_DEF(gamemode) return 0 if(!storyteller.antag_divisor) return 0 - var/max_antags = sec_crew * storyteller.max_sec_mult - var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) - var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew - var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) + //var/max_antags = sec_crew * storyteller.max_sec_mult + //var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) + //var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew + //var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) var/result = sec_crew // round(clamped_cap) return result From 7d9e57b1fffb50ed0e7e37818083cd5881f2b5d0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 5 Dec 2024 23:14:22 +0300 Subject: [PATCH 048/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B0=D1=88=D0=B5=D0=B3=D0=BE=20?= =?UTF-8?q?=D0=A1=D0=A2=20=D0=B2=20=D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD?= =?UTF-8?q?=D1=83=20=D0=9C=D0=BE=D0=BD=D0=BA=D0=B5=D1=81=D1=82=D0=B5=D0=B9?= =?UTF-8?q?=D1=88=D0=B5=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/anomaly.dm | 2 +- code/__DEFINES/antagonists.dm | 6 + code/__HELPERS/roundend.dm | 7 + code/_globalvars/lists/objects.dm | 2 + code/controllers/master.dm | 1 + code/controllers/subsystem/dynamic/dynamic.dm | 5 +- .../dynamic/dynamic_rulesets_midround.dm | 2 +- .../dynamic/dynamic_rulesets_roundstart.dm | 2 +- code/controllers/subsystem/events.dm | 24 +- code/controllers/subsystem/job.dm | 109 +++ code/controllers/subsystem/statpanel.dm | 2 +- code/controllers/subsystem/ticker.dm | 2 +- code/controllers/subsystem/vote.dm | 20 +- code/datums/mind/_mind.dm | 4 + code/datums/votes/_vote_datum.dm | 6 + .../game/machinery/computer/communications.dm | 15 +- code/modules/admin/admin.dm | 18 +- code/modules/admin/force_event.dm | 16 +- code/modules/admin/topic.dm | 4 +- .../modules/antagonists/_common/antag_team.dm | 7 + .../antagonists/nukeop/datums/operative.dm | 2 +- .../equipment/nuclear_bomb/_nuclear_bomb.dm | 2 + code/modules/antagonists/nukeop/outfits.dm | 2 +- code/modules/antagonists/wizard/wizard.dm | 2 +- code/modules/bitrunning/event.dm | 2 +- code/modules/events/_event.dm | 128 ++- code/modules/events/anomaly/_anomaly.dm | 1 + code/modules/events/anomaly/anomaly_vortex.dm | 2 +- code/modules/events/aurora_caelus.dm | 2 +- code/modules/events/brand_intelligence.dm | 1 + code/modules/events/bureaucratic_error.dm | 7 +- code/modules/events/carp_migration.dm | 1 + code/modules/events/disease_outbreak.dm | 2 +- code/modules/events/earthquake.dm | 2 +- code/modules/events/false_alarm.dm | 2 +- .../events/ghost_role/alien_infestation.dm | 2 +- code/modules/events/ghost_role/blob.dm | 2 +- .../events/gravity_generator_blackout.dm | 2 +- code/modules/events/grey_tide.dm | 1 + code/modules/events/heart_attack.dm | 2 +- code/modules/events/portal_storm.dm | 2 + code/modules/events/radiation_leak.dm | 1 + code/modules/events/radiation_storm.dm | 1 + code/modules/events/sandstorm.dm | 1 + code/modules/events/scrubber_overflow.dm | 3 +- code/modules/events/shuttle_catastrophe.dm | 3 +- code/modules/events/shuttle_insurance.dm | 3 +- .../events/shuttle_loan/shuttle_loan_event.dm | 2 +- code/modules/events/space_vines/vine_event.dm | 2 +- code/modules/events/spider_infestation.dm | 1 + code/modules/events/stray_cargo.dm | 1 + code/modules/events/supermatter_surge.dm | 2 +- code/modules/events/tram_malfunction.dm | 3 +- code/modules/events/vent_clog.dm | 2 +- code/modules/events/wizard/embeddies.dm | 2 +- code/modules/events/wizard/identity_spoof.dm | 2 +- code/modules/events/wormholes.dm | 1 + code/modules/shuttle/emergency.dm | 4 +- config/bandastation/bandastation_config.txt | 45 +- config/logging.txt | 3 + modular_bandastation/game/_game.dm | 4 + modular_bandastation/game/_game.dme | 8 + modular_bandastation/game/code/_defines.dm | 2 + .../game/code/_game_options.dm | 23 + modular_bandastation/game/code/_procs.dm | 5 + .../game/code/log_categories.dm | 7 + .../game/code/votes/_vote_datum.dm | 5 + modular_bandastation/modular_bandastation.dme | 1 + .../code/modules/client/preferences.dm | 2 + .../storyteller/_storyteller.dme | 47 +- .../storyteller/code/_defines/_persistence.dm | 7 - .../storyteller/code/_defines/_ticker.dm | 3 +- .../code/_defines/storyteller_config.dm | 46 +- .../code/_defines/storyteller_defines.dm | 79 +- .../storyteller/code/_helpers.dm | 74 ++ .../storyteller/code/divergency_report.dm | 44 - .../storyteller/code/dynamic_report.dm | 27 + .../storyteller/code/event_defines/_event.dm | 91 -- .../code/event_defines/_round_event.dm | 227 +++++ .../event_defines/_round_event_control.dm | 285 ++++++ .../crewset/_antagonist_event.dm | 188 ---- .../code/event_defines/crewset/_override.dm | 16 + .../event_defines/crewset/blood_brothers.dm | 61 +- .../code/event_defines/crewset/changeling.dm | 37 +- .../code/event_defines/crewset/clown_ops.dm | 143 ++- .../code/event_defines/crewset/cult.dm | 110 ++- .../code/event_defines/crewset/heretic.dm | 39 +- .../code/event_defines/crewset/malf.dm | 90 +- .../code/event_defines/crewset/nuke_ops.dm | 130 ++- .../code/event_defines/crewset/obsessed.dm | 29 +- .../code/event_defines/crewset/revolution.dm | 88 +- .../code/event_defines/crewset/spies.dm | 1 - .../code/event_defines/crewset/traitors.dm | 36 +- .../code/event_defines/crewset/wizard.dm | 44 + .../event_defines/disabled_event_overrides.dm | 21 - .../code/event_defines/ghostset/nuke_ops.dm | 106 +++ .../code/event_defines/ghostset/override.dm | 28 +- .../event_defines/ghostset/paradox_clone.dm | 102 +++ .../code/event_defines/ghostset/voidwalker.dm | 3 +- .../code/event_defines/ghostset/wizard.dm | 37 + .../code/event_defines/major/override.dm | 106 ++- .../code/event_defines/moderate/override.dm | 87 +- .../code/event_defines/mundane/override.dm | 78 +- .../code/event_defines/override_events.dm | 6 - .../code/events/group/_event_group.dm | 66 ++ .../storyteller/code/events/group/groups.dm | 44 + .../events/object/anomalies_dimensional.dm | 30 + .../storyteller/code/events/summon_wizard.dm | 31 + .../storyteller/code/gamemode.dm | 833 +++++++++++------- .../storyteller/code/readme.md | 44 + .../storyteller/code/scheduled_event.dm | 19 +- .../code/storytellers/_storyteller.dm | 201 +++++ .../code/storytellers/data/tracks.dm | 15 - .../storytellers/storyteller_black_orbit.dm | 8 + .../code/storytellers/storyteller_bomb.dm | 13 + .../code/storytellers/storyteller_chill.dm | 16 + .../code/storytellers/storyteller_clown.dm | 17 + .../{tellers => }/storyteller_default.dm | 5 +- .../{tellers => }/storyteller_extended.dm | 8 +- .../code/storytellers/storyteller_fragile.dm | 13 + .../code/storytellers/storyteller_gamer.dm | 14 + .../code/storytellers/storyteller_jester.dm | 14 + .../code/storytellers/storyteller_mystic.dm | 6 + .../storytellers/storyteller_operative.dm | 23 + .../code/storytellers/storyteller_phantom.dm | 27 + .../code/storytellers/tellers/_storyteller.dm | 152 ---- .../tellers/storyteller_black_orbit.dm | 26 - .../storytellers/tellers/storyteller_bomb.dm | 17 - .../storytellers/tellers/storyteller_chill.dm | 22 - .../storytellers/tellers/storyteller_clown.dm | 24 - .../tellers/storyteller_fragile.dm | 22 - .../storytellers/tellers/storyteller_gamer.dm | 20 - .../tellers/storyteller_phantom.dm | 26 - modular_bandastation/storyteller/code/vote.dm | 47 +- 134 files changed, 3128 insertions(+), 1753 deletions(-) create mode 100644 modular_bandastation/game/_game.dm create mode 100644 modular_bandastation/game/_game.dme create mode 100644 modular_bandastation/game/code/_defines.dm create mode 100644 modular_bandastation/game/code/_game_options.dm create mode 100644 modular_bandastation/game/code/_procs.dm create mode 100644 modular_bandastation/game/code/log_categories.dm create mode 100644 modular_bandastation/game/code/votes/_vote_datum.dm delete mode 100644 modular_bandastation/storyteller/code/_defines/_persistence.dm create mode 100644 modular_bandastation/storyteller/code/_helpers.dm delete mode 100644 modular_bandastation/storyteller/code/divergency_report.dm create mode 100644 modular_bandastation/storyteller/code/dynamic_report.dm delete mode 100644 modular_bandastation/storyteller/code/event_defines/_event.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/_round_event.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/_round_event_control.dm delete mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/_override.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm delete mode 100644 modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm create mode 100644 modular_bandastation/storyteller/code/events/group/_event_group.dm create mode 100644 modular_bandastation/storyteller/code/events/group/groups.dm create mode 100644 modular_bandastation/storyteller/code/events/object/anomalies_dimensional.dm create mode 100644 modular_bandastation/storyteller/code/events/summon_wizard.dm create mode 100644 modular_bandastation/storyteller/code/readme.md create mode 100644 modular_bandastation/storyteller/code/storytellers/_storyteller.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/data/tracks.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_black_orbit.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_chill.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_clown.dm rename modular_bandastation/storyteller/code/storytellers/{tellers => }/storyteller_default.dm (59%) rename modular_bandastation/storyteller/code/storytellers/{tellers => }/storyteller_extended.dm (64%) create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_fragile.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_gamer.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_jester.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_mystic.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_operative.dm create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_phantom.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm delete mode 100644 modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm diff --git a/code/__DEFINES/anomaly.dm b/code/__DEFINES/anomaly.dm index 7422af3fc65d7..cf07b3b7e615c 100644 --- a/code/__DEFINES/anomaly.dm +++ b/code/__DEFINES/anomaly.dm @@ -4,7 +4,7 @@ */ ///Time in ticks before the anomaly goes poof/explodes depending on type. -#define ANOMALY_COUNTDOWN_TIMER (99 SECONDS) +#define ANOMALY_COUNTDOWN_TIMER (200 SECONDS) // BANDASTATION EDIT - STORYTELLER: 99 seconds -> 200 seconds /** * Nuisance/funny anomalies diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index c2b466d7f7f9a..05a9e92ca7f29 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -392,6 +392,12 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( // This flag disables certain checks that presume antagonist datums mean 'baddie'. #define FLAG_FAKE_ANTAG (1 << 0) +/// BANDASTATION EDIT START - STORYTELLER +// The storyteller will ignore this antag datum as counting against the antag cap. +#define FLAG_ANTAG_CAP_IGNORE (1 << 1) +// The storyteller will count everyone on this antag's team as a singular antag instead. +#define FLAG_ANTAG_CAP_TEAM (1 << 2) +/// BANDASTATION EDIT END - STORYTELLER #define HUNTER_PACK_COPS "Spacepol Fugitive Hunters" #define HUNTER_PACK_RUSSIAN "Russian Fugitive Hunters" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 292639f387682..c92b69acac1f3 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -243,6 +243,10 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) //Set news report and mode result SSdynamic.set_round_result() + /// BANDASTATION EDIT START - STORYTELLER + SSgamemode.round_end_report() + SSgamemode.store_roundend_data() // store data on roundend for next round + /// BANDASTATION EDIT END - STORYTELLER to_chat(world, span_infoplain(span_big(span_bold("


The round has ended.")))) log_game("The round has ended.") @@ -305,6 +309,9 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) /datum/controller/subsystem/ticker/proc/build_roundend_report() var/list/parts = list() + //might want to make this a full section + parts += "
[("Storyteller: [SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "N/A"]")]
" //BANDASTATION EDIT - STORYTELLER + //AI laws parts += law_report() diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index f2faf6ae81fe0..f2abe575ca5b1 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -103,3 +103,5 @@ GLOBAL_LIST_INIT(prototype_organs, typecacheof(list( /obj/item/organ/tongue/dullahan, /obj/item/organ/eyes/dullahan, ), only_root_path = TRUE)) + +GLOBAL_LIST_EMPTY(nuke_list) /// BANDASTATION EDIT - STORYTELLER diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 69ba4996fd5e9..db0f455ca76d5 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -388,6 +388,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie if(sleep_offline_after_initializations && CONFIG_GET(flag/resume_after_initializations)) world.sleep_offline = FALSE initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 + SSgamemode.handle_picking_storyteller() //BANDASTATION EDIT - STORYTELLER /** * Initialize a given subsystem and handle the results. diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index d22f30f209934..450dc05818cd1 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -149,7 +149,7 @@ SUBSYSTEM_DEF(dynamic) var/waittime_h = 1800 /// A number between 0 and 100. The maximum amount of threat allowed to generate. - var/max_threat_level = 100 + var/max_threat_level = 0 /// BANDASTATION EDIT - STORYTELLER /// The extra chance multiplier that a heavy impact midround ruleset will run next time. /// For example, if this is set to 50, then the next heavy roll will be about 50% more likely to happen. @@ -334,7 +334,8 @@ SUBSYSTEM_DEF(dynamic) continue min_threat = min(ruleset.cost, min_threat) - var/greenshift = GLOB.dynamic_forced_extended || (threat_level < min_threat && shown_threat < min_threat) //if both shown and real threat are below any ruleset, its extended time + //var/greenshift = GLOB.dynamic_forced_extended || (threat_level < min_threat && shown_threat < min_threat) //if both shown and real threat are below any ruleset, its extended time + var/greenshift = SSgamemode.current_storyteller.disable_distribution // BANDASTATION EDIT - STORYTELLER SSstation.generate_station_goals(greenshift ? INFINITY : CONFIG_GET(number/station_goal_budget)) var/list/datum/station_goal/goals = SSstation.get_station_goals() diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm index 8d05402676846..0e99e02da4ff6 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm @@ -387,7 +387,7 @@ cost = 7 minimum_round_time = 70 MINUTES requirements = REQUIREMENTS_VERY_HIGH_THREAT_NEEDED - ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER flags = HIGH_IMPACT_RULESET signup_item_path = /obj/machinery/nuclearbomb diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm index 79eedc0adb8d7..55529270fd4ae 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm @@ -410,7 +410,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) requirements = list(90,90,90,80,60,40,30,20,10,10) flags = HIGH_IMPACT_RULESET antag_cap = list("denominator" = 18, "offset" = 1) - ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER var/required_role = ROLE_NUCLEAR_OPERATIVE var/datum/team/nuclear/nuke_team ///The job type to dress up our nuclear operative as. diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 17ac36cbcfab3..d87c86a78da81 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -35,7 +35,7 @@ SUBSYSTEM_DEF(events) /datum/controller/subsystem/events/fire(resumed = FALSE) if(!resumed) - //checkEvent() //only check these if we aren't resuming a paused fire + checkEvent() //only check these if we aren't resuming a paused fire src.currentrun = running.Copy() //cache for sanic speed (lists are references anyways) @@ -64,6 +64,7 @@ SUBSYSTEM_DEF(events) //decides which world.time we should select another random event at. /datum/controller/subsystem/events/proc/reschedule() scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper)) + /** * Selects a random event based on whether it can occur and its 'weight'(probability) * @@ -85,36 +86,29 @@ SUBSYSTEM_DEF(events) continue if(!event_to_check.can_spawn_event(players_amt)) continue - - /* // BANDASTATION EDIT START - STORYTELLER - изменение логики if(event_to_check.roundstart) //for round-start events etc. - var/res = SSgamemode.TriggerEvent(event_to_check) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер + var/res = SSgamemode.TriggerEvent(event_to_check) if(res == EVENT_INTERRUPTED) continue //like it never happened - if(res == EVENT_CANT_RUN) // BANDASTATION EDIT - STORYTELLER - легкая оптимизация - return // BANDASTATION EDIT - STORYTELLER - легкая оптимизация + if(res == EVENT_CANT_RUN) + return else event_roster[event_to_check] = event_to_check.weight - */ // BANDASTATION EDIT END - STORYTELLER - изменение логики - event_roster[event_to_check] = event_to_check.weight var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - if(excluded_event) - message_admins("Rerolled to [event_to_run.name].") - SSgamemode.schedule_event(event_to_run, (rand(3, 4) MINUTES), passed_ignore = TRUE) // BANDASTATION EDIT - STORYTELLER - перевод выстрелов событий в сторителлер + TriggerEvent(event_to_run) ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. -/* + /datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger) . = event_to_trigger.preRunEvent() if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) - message_admins("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") - log_game("SSevents sends a [event_to_trigger.name] to Storyteller schedule!") + message_admins("SSevents runs a event: [event_to_trigger.name]!") + log_game("SSevents runs a event: [event_to_trigger.name]!") event_to_trigger.run_event(random = TRUE) - */ /// BANDASTATION EDIT - STORYTELLER - отключение базового фаера событий ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 9af14f226ace5..f2d2ce05bbf3e 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -84,6 +84,10 @@ SUBSYSTEM_DEF(job) ## The game will not read any line that is commented out with a '#', as to allow you to defer to codebase defaults.\n## If you want to override the codebase values, add the value and then uncomment that line by removing the # from the job key's name.\n\ ## Ensure that the key is flush, do not introduce any whitespaces when you uncomment a key. For example:\n## \"# Total Positions\" should always be changed to \"Total Positions\", no additional spacing.\n\ ## Best of luck editing!\n" + /// BANDASTATIONE EDIT START - STORYTELLER + /// Assoc list of new players keyed to the type of job they will currently get + var/list/assigned_players_by_job = list() + /// BANDASTATIONE EDIT END - STORYTELLER /datum/controller/subsystem/job/Initialize() setup_job_lists() @@ -979,3 +983,108 @@ SUBSYSTEM_DEF(job) return TRUE return FALSE + +/// BANDASTATION EDIT START - STORYTELLER +/datum/controller/subsystem/job/proc/GetJob(rank) + if(!length(all_occupations)) + SetupOccupations() + return name_occupations[rank] + +/datum/controller/subsystem/job/proc/GetJobType(jobtype) + RETURN_TYPE(/datum/job) + if(!length(all_occupations)) + SetupOccupations() + return type_occupations[jobtype] + +/datum/controller/subsystem/job/proc/SetupOccupations() + name_occupations = list() + type_occupations = list() + + var/list/all_jobs = subtypesof(/datum/job) + if(!length(all_jobs)) + all_occupations = list() + joinable_occupations = list() + joinable_departments = list() + joinable_departments_by_type = list() + experience_jobs_map = list() + to_chat(world, span_boldannounce("Error setting up jobs, no job datums found")) + return FALSE + + var/list/new_all_occupations = list() + var/list/new_joinable_occupations = list() + var/list/new_joinable_departments = list() + var/list/new_joinable_departments_by_type = list() + var/list/new_experience_jobs_map = list() + + for(var/job_type in all_jobs) + var/datum/job/job = new job_type() + if(!job.config_check()) + continue + if(!job.map_check()) //Even though we initialize before mapping, this is fine because the config is loaded at new + log_job_debug("Removed [job.title] due to map config") + continue + new_all_occupations += job + name_occupations[job.title] = job + type_occupations[job_type] = job + if(job.job_flags & JOB_NEW_PLAYER_JOINABLE) + new_joinable_occupations += job + if(!LAZYLEN(job.departments_list)) + var/datum/job_department/department = new_joinable_departments_by_type[/datum/job_department/undefined] + if(!department) + department = new /datum/job_department/undefined() + new_joinable_departments_by_type[/datum/job_department/undefined] = department + department.add_job(job) + continue + for(var/department_type in job.departments_list) + var/datum/job_department/department = new_joinable_departments_by_type[department_type] + if(!department) + department = new department_type() + new_joinable_departments_by_type[department_type] = department + department.add_job(job) + + sortTim(new_all_occupations, GLOBAL_PROC_REF(cmp_job_display_asc)) + for(var/datum/job/job as anything in new_all_occupations) + if(!job.exp_granted_type) + continue + new_experience_jobs_map[job.exp_granted_type] += list(job) + + sortTim(new_joinable_departments_by_type, GLOBAL_PROC_REF(cmp_department_display_asc), associative = TRUE) + for(var/department_type in new_joinable_departments_by_type) + var/datum/job_department/department = new_joinable_departments_by_type[department_type] + sortTim(department.department_jobs, GLOBAL_PROC_REF(cmp_job_display_asc)) + new_joinable_departments += department + if(department.department_experience_type) + new_experience_jobs_map[department.department_experience_type] = department.department_jobs.Copy() + + all_occupations = new_all_occupations + joinable_occupations = sortTim(new_joinable_occupations, GLOBAL_PROC_REF(cmp_job_display_asc)) + joinable_departments = new_joinable_departments + joinable_departments_by_type = new_joinable_departments_by_type + experience_jobs_map = new_experience_jobs_map + + return TRUE + +/datum/controller/subsystem/job/proc/FreeRole(rank) + if(!rank) + return + var/datum/job/job = GetJob(rank) + if(!job) + return FALSE + job.current_positions = max(0, job.current_positions - 1) + +/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE) + var/atom/destination + + if(M.mind && !is_unassigned_job(M.mind.assigned_role) && length(GLOB.jobspawn_overrides[M.mind.assigned_role.title])) //We're doing something special today. + destination = pick(GLOB.jobspawn_overrides[M.mind.assigned_role.title]) + destination.JoinPlayerHere(M, FALSE) + return TRUE + + if(latejoin_trackers.len) + destination = pick(latejoin_trackers) + destination.JoinPlayerHere(M, buckle) + return TRUE + + destination = get_last_resort_spawn_points() + destination.JoinPlayerHere(M, buckle) +/// BANDASTATION EDIT END - STORYTELLER diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 81fdb8cac5959..e5a06a6a60f82 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -26,7 +26,7 @@ SUBSYSTEM_DEF(statpanels) global_data = list( "Map: [SSmapping.current_map?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, - "Storyteller: [SSgamemode.storyteller ? SSgamemode.storyteller.name : "N/A"]", // BANDASTATION EDIT ADDITION + "Storyteller: [!SSgamemode.secret_storyteller && SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "Secret"]", // BANDASTATION EDIT ADDITION "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", "Round Time: [ROUND_TIME()]", diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index ab59b422f3084..1a532d89d173f 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -235,9 +235,9 @@ SUBSYSTEM_DEF(ticker) var/can_continue = FALSE // BANDASTATION EDIT BEGIN - STORYTELLER SSgamemode.init_storyteller() + CHECK_TICK can_continue = SSgamemode.pre_setup() // BANDASTATION EDIT END - STORYTELLER - CHECK_TICK SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_JOBS_ASSIGNED, src) can_continue = can_continue && SSjob.divide_occupations() //Distribute jobs diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d0e642bd3aa2d..7278cdadf30af 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -119,7 +119,7 @@ SUBSYSTEM_DEF(vote) ) log_vote("vote finalized", vote_log_data) if(to_display) - to_chat(world, span_infoplain(vote_font("\n[to_display]"))) + to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[to_display]"))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT - STORYTELLER: wrap in examine block, use MESSAGE_TYPE_OOC // Finally, doing any effects on vote completion current_vote.finalize_vote(final_winner) @@ -134,6 +134,10 @@ SUBSYSTEM_DEF(vote) return if(CONFIG_GET(flag/no_dead_vote) && voter.stat == DEAD && !voter.client?.holder) return + // BANDASTATION EDIT START - STORYTELLER + if(!current_vote.can_vote(voter)) + return + // BANDASTATION EDIT END - STORYTELLER // If user has already voted, remove their specific vote if(voter.ckey in current_vote.choices_by_ckey) @@ -156,6 +160,10 @@ SUBSYSTEM_DEF(vote) return if(!voter?.ckey) return + // BANDASTATION EDIT START - STORYTELLER + if(!current_vote.can_vote(voter)) + return + // BANDASTATION EDIT END - STORYTELLER if(CONFIG_GET(flag/no_dead_vote) && voter.stat == DEAD && !voter.client?.holder) return @@ -230,9 +238,9 @@ SUBSYSTEM_DEF(vote) var/to_display = current_vote.initiate_vote(vote_initiator_name, duration) log_vote(to_display) - to_chat(world, span_infoplain(vote_font("\n[span_bold(to_display)]\n\ + to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[span_bold(to_display)]\n\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // monkestation edit: wrap in examine block, use MESSAGE_TYPE_OOC // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) @@ -330,6 +338,11 @@ SUBSYSTEM_DEF(vote) "message" = can_vote == VOTE_AVAILABLE ? vote.default_message : can_vote, ) + /// BANDASTATION EDIT START - STORYTELLER + if(vote.has_desc) + vote_data += list("desc" = vote.return_desc(vote_name)) + /// BANDASTATION EDIT END - STORYTELLER + if(vote == current_vote) var/list/choices = list() for(var/key in current_vote.choices) @@ -346,6 +359,7 @@ SUBSYSTEM_DEF(vote) "displayStatistics" = current_vote.display_statistics, "choices" = choices, "vote" = vote_data, + "canVote" = current_vote.can_vote(user), // BANDASTATION EDIT - STORYTELLER ) all_vote_data += list(vote_data) diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index 1df318f9ee46f..4d27df326e1c3 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -102,6 +102,10 @@ var/list/failed_special_equipment /// A list to keep track of which books a person has read (to prevent people from reading the same book again and again for positive mood events) var/list/book_titles_read + /// BANDASTATION EDIT START - STORYTELLER + /// Variable that lets the event picker see if someones getting chosen or not + var/picking = FALSE + /// BANDASTATION EDIT END - STORYTELLER /datum/mind/New(_key) key = _key diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 76833f73ff5b0..2f6aff2395b3d 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -80,6 +80,10 @@ */ /datum/vote/proc/can_be_initiated(forced = FALSE) SHOULD_CALL_PARENT(TRUE) + // BANDASTATION EDIT START - STORYTELLER + if(!player_startable && !forced) + return FALSE + // BANDASTATION EDIT END - STORYTELLER if(!forced && !is_config_enabled()) return "This vote is currently disabled by the server configuration." @@ -97,6 +101,8 @@ for(var/key in default_choices) choices[key] = 0 + list_clear_nulls(choices) // monke edit: ensure no nulls end up in a vote + return TRUE /** diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 9acdaf695286b..148962debba11 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -884,7 +884,19 @@ SSdynamic.unfavorable_situation() if(HACK_SLEEPER) // Trigger one or multiple sleeper agents with the crew (or for latejoining crew) - var/datum/dynamic_ruleset/midround/sleeper_agent_type = /datum/dynamic_ruleset/midround/from_living/autotraitor + // BANDASTATION EDIT START - inject storyteller events instead of dynamic rulesets + var/event_to_spawn = pick_weight(list( + /datum/round_event_control/antagonist/solo/traitor/midround = 75, + // hmmm, let's rarely spawn some non-traitor antags just to spice things up a bit + /datum/round_event_control/antagonist/solo/heretic/midround = 15, + /datum/round_event_control/antagonist/solo/from_ghosts/wizard = 1 + )) + force_event_after(event_to_spawn, "[hacker] hacking a communications console", rand(20 SECONDS, 1 MINUTES)) + priority_announce( + "Attention crew, it appears that someone on your station has hijacked your telecommunications and broadcasted an unknown signal.", + "[command_name()] High-Priority Update", + ) + /* var/datum/dynamic_ruleset/midround/sleeper_agent_type = /datum/dynamic_ruleset/midround/from_living/autotraitor var/max_number_of_sleepers = clamp(round(length(GLOB.alive_player_list) / 20), 1, 3) var/num_agents_created = 0 for(var/num_agents in 1 to rand(1, max_number_of_sleepers)) @@ -902,6 +914,7 @@ "Attention crew, it appears that someone on your station has hijacked your telecommunications and broadcasted an unknown signal.", "[command_name()] High-Priority Update", ) + */ // BANDASTATION EDIT END #undef HACK_PIRATE #undef HACK_FUGITIVES diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index aaf55f87cac0b..78557cd929b5f 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -20,21 +20,23 @@ return var/dat = "
Game Panel

" + /// BANDASTATION EDIT START- STORYTELLER + /* if(SSticker.current_state <= GAME_STATE_PREGAME) - // BANDASTATION EDIT START - STORYTELLER - //dat += "(Manage Dynamic Rulesets)
" - //dat += "(Force Roundstart Rulesets)
" - dat += "(Game Mode Panel)
" - // BANDASTATION EDIT END + + dat += "(Manage Dynamic Rulesets)
" + dat += "(Force Roundstart Rulesets)
" if (GLOB.dynamic_forced_roundstart_ruleset.len > 0) for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) dat += {"-> [rule.name] <-
"} dat += "(Clear Rulesets)
" - //dat += "(Dynamic mode options)
" /// BANDASTATION EDIT - STORYTELLER + dat += "(Dynamic mode options)
" dat += "
" if(SSticker.IsRoundInProgress()) - dat += "(Game Mode Panel)
" - //dat += "(Manage Dynamic Rulesets)
" /// BANDASTATION EDIT - STORYTELLER + dat += "(Manage Dynamic Rulesets)
" + */ + dat += "(Game Mode Panel)
" + /// BANDASTATION EDIT END - STORYTELLER dat += {"
Create Object
diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm index 2e1c5e109a4dd..1f1517bc0fbad 100644 --- a/code/modules/admin/force_event.dm +++ b/code/modules/admin/force_event.dm @@ -55,16 +55,7 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM "icon" = category_to_icons[event_control.category], )) //add event, with one value matching up the category - if (!SSticker.HasRoundStarted() && event_control.roundstart) - UNTYPED_LIST_ADD(events, list( - "name" = event_control.name, - "description" = event_control.description, - "type" = event_control.type, - "category" = event_control.category, - "has_customization" = !!length(event_control.admin_setup), - )) - if (SSticker.HasRoundStarted() && !event_control.roundstart) - UNTYPED_LIST_ADD(events, list( + UNTYPED_LIST_ADD(events, list( "name" = event_control.name, "description" = event_control.description, "type" = event_control.type, @@ -98,9 +89,6 @@ ADMIN_VERB(force_event, R_FUN, "Trigger Event", "Forces an event to occur.", ADM return var/always_announce_chance = 100 var/no_announce_chance = 0 - if(SSticker.HasRoundStarted()) - event.run_event(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) - else - SSgamemode.schedule_event(event) + event.run_event(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 99406a5851c55..1cc1bac9cdfd6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -69,10 +69,10 @@ else if(href_list["gamemode_panel"]) if(!check_rights(R_ADMIN)) return - // BANDASTATION EDIT START - STORYTELLER + /// BANDASTATION EDIT START - STORYTELLER //SSdynamic.admin_panel() SSgamemode.admin_panel(usr) - // BANDASTATION EDIT END + /// BANDASTATION EDIT END - STORYTELLER else if(href_list["call_shuttle"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm index 527196c51c3ea..96f8b4391fa97 100644 --- a/code/modules/antagonists/_common/antag_team.dm +++ b/code/modules/antagonists/_common/antag_team.dm @@ -44,6 +44,13 @@ GLOBAL_LIST_EMPTY(antagonist_teams) new_objective.find_target(dupe_search_range = list(src)) new_objective.update_explanation_text() objectives += new_objective + /// BANDASTATION EDIT START - STORYTELLER. Я удивлен, почему это в Сторителлере, но Окэээй. + for(var/datum/mind/member as anything in members) + for(var/datum/antagonist/antag in member.antag_datums) + if(antag.get_team() == src) + antag.objectives |= new_objective + antag.update_static_data_for_all_viewers()\ + /// BANDASTATION EDIT END - STORYTELLER //Display members/victory/failure/objectives for the team /datum/team/proc/roundend_report() diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index ebaaf8692b2f4..031d745aaf90c 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -198,7 +198,7 @@ /// Actually moves our nukie to where they should be /datum/antagonist/nukeop/proc/move_to_spawnpoint() // Ensure that the nukiebase is loaded, and wait for it if required - SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) + //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER var/turf/destination = get_spawnpoint() owner.current.forceMove(destination) if(!owner.current.onSyndieBase()) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm index 8598a929454b3..a7ee7a97e8160 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm @@ -57,6 +57,7 @@ GLOBAL_VAR(station_nuke_source) /obj/machinery/nuclearbomb/Initialize(mapload) . = ..() countdown = new(src) + GLOB.nuke_list += src /// BANDASTATION EDIT - STORYTELLER core = new /obj/item/nuke_core(src) STOP_PROCESSING(SSobj, core) update_appearance() @@ -68,6 +69,7 @@ GLOBAL_VAR(station_nuke_source) if(!exploding) // If we're not exploding, set the alert level back to normal toggle_nuke_safety() + GLOB.nuke_list -= src /// BANDASTATION EDIT - STORYTELLER QDEL_NULL(countdown) QDEL_NULL(core) return ..() diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 32fe7dfd5c0a6..29cba691d99b8 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -45,7 +45,7 @@ return // We don't require the nukiebase be loaded to function, but lets go ahead and kick off loading just in case - INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) + // INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER var/obj/item/radio/radio = nukie.ears radio.set_frequency(FREQ_SYNDICATE) radio.freqlock = RADIO_FREQENCY_LOCKED diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 617908b5ba617..ba9d843974788 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) /datum/antagonist/wizard/proc/send_to_lair() // And now we ensure that its loaded - SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) + //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) /// BANDASTATION EDIT - STORYTELLER if(!owner.current) return diff --git a/code/modules/bitrunning/event.dm b/code/modules/bitrunning/event.dm index 370957e2ebb0f..c53c97b1dba75 100644 --- a/code/modules/bitrunning/event.dm +++ b/code/modules/bitrunning/event.dm @@ -14,7 +14,7 @@ /// List of servers on the station var/list/datum/weakref/active_servers = list() -/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 9af388af38a7b..bd88060c8013c 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -12,7 +12,7 @@ //10 is the default weight. 20 is twice more likely; 5 is half as likely as this default. //0 here does NOT disable the event, it just makes it extremely unlikely - var/earliest_start = 20 MINUTES //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins ///BANDASTATION EDIT - STORYTELLER + var/earliest_start = 20 MINUTES //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins var/min_players = 0 //The minimum amount of alive, non-AFK human players on server required to start the event. var/occurrences = 0 //How many times this event has occurred @@ -70,15 +70,20 @@ // Checks if the event can be spawned. Used by event controller and "false alarm" event. // Admin-created events override this. -/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER SHOULD_CALL_PARENT(TRUE) + /// BANDASTATION EDIT START - STORYTELLER + if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) + return FALSE + if(event_group && !GLOB.event_groups[event_group].can_run()) + return FALSE + if(roundstart && (!SSgamemode.can_run_roundstart || (SSgamemode.ran_roundstart && !fake_check && !SSgamemode.current_storyteller?.ignores_roundstart))) + return FALSE + /// BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) return FALSE - // BANDASTATION EDIT START - STORYTELLER - //if(earliest_start >= world.time-SSticker.round_start_time) - if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) + if(earliest_start >= (world.time - SSticker.round_start_time)) return FALSE - // BANDASTATION EDIT END if(!allow_magic && wizardevent != SSevents.wizardmode) return FALSE if(players_amt < min_players) @@ -89,53 +94,31 @@ return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) return FALSE - if(SSgamemode.rnd_crew < rnd_required_crew) + /// BANDASTATION EDIT START - STORYTELLER + if(checks_antag_cap) + if(!roundstart && !SSgamemode.can_inject_antags()) + return FALSE + if(!check_enemies()) + return FALSE + if(allowed_storytellers && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) + return FALSE + if(eng_required_power < SSgamemode.current_eng_power) + return FALSE + if(med_required_power < SSgamemode.current_med_power) return FALSE - if(SSgamemode.med_crew < med_required_crew) + if(rnd_required_power < SSgamemode.current_rnd_power) return FALSE - if(SSgamemode.eng_crew < eng_required_crew) + if(head_required_power < SSgamemode.current_head_power) return FALSE - if(SSgamemode.head_crew < head_required_crew) + if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) return FALSE + /// BANDASTATION EDIT END - STORYTELLER if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) return FALSE - return TRUE -/datum/round_event_control/proc/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, round_start_event = FALSE) - SHOULD_CALL_PARENT(TRUE) - var/message = "success" - if(occurrences >= max_occurrences) - message = "Storyteller event: [name] was unable to run due max occurrence limit." - // BANDASTATION EDIT START - STORYTELLER - //if(earliest_start >= world.time-SSticker.round_start_time) - if(!roundstart && earliest_start >= world.time-SSticker.round_start_time ) - message = "Storyteller event: [name] was unable to run due earliest start timer limit." - // BANDASTATION EDIT END - if(!allow_magic && wizardevent != SSevents.wizardmode) - message = "Storyteller event: [name] was unable to run due magic not allowed and it's wizard mode." - if(players_amt < min_players) - message = "Storyteller event: [name] was unable to run due too low players for event (amt/min - [players_amt]/[min_players])." - if(holidayID && !check_holidays(holidayID)) - message = "Storyteller event: [name] was unable to run due try to run on non-holiday day." - if(EMERGENCY_ESCAPED_OR_ENDGAMED) - message = "Storyteller event: [name] was unable to run due escaped or endgamed." - if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) - message = "Storyteller event: [name] was unable to run due it's ghost role for not midround event." - if(SSgamemode.rnd_crew < rnd_required_crew) - message = "Storyteller event: [name] was unable to run due lack of science roles - count/needed [SSgamemode.rnd_crew]/[rnd_required_crew]." - if(SSgamemode.med_crew < med_required_crew) - message = "Storyteller event: [name] was unable to run due lack of medical roles - count/needed [SSgamemode.med_crew]/[med_required_crew]." - if(SSgamemode.eng_crew < eng_required_crew) - message = "Storyteller event: [name] was unable to run due lack of engineering roles - count/needed [SSgamemode.eng_crew]/[eng_required_crew]." - if(SSgamemode.head_crew < head_required_crew) - message = "Storyteller event: [name] was unable to run due lack of heads roles - count/needed [SSgamemode.head_crew]/[head_required_crew]." - if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) - message = "Storyteller event: [name] was unable to run due hijack in progress." - - return message -/datum/round_event_control/proc/preRunEvent(admin_forced = FALSE) +/datum/round_event_control/proc/preRunEvent(forced = FALSE) /// BANDASTATION EDIT - STORYTELLER if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN @@ -145,41 +128,25 @@ triggering = TRUE // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. - // BANDASTATION EDIT START - STORYTELLER - //message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") - if(SSticker.HasRoundStarted() && !roundstart && !admin_forced) - message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (\ - CANCEL | \ - SOMETHING ELSE)") - for(var/client/staff as anything in GLOB.admins) - if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) - SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - - if(!roundstart && !admin_forced) + message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") + /// BANDASTATION EDIT START - STORYTELLER + if(!roundstart) sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) - - if(triggering) - if(!roundstart && !admin_forced) - message_admins("Storyteller: Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5)]: [name]. (\ - CANCEL | \ - SOMETHING ELSE)") - sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME * 0.5) - else - message_admins(" Roundstart event chosen: [name].") - // BANDASTATION EDIT END - - // var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) /// BANDASTATION EDIT - STORYTELLER - var/players_amt = SSgamemode.get_correct_popcount() - if(!can_spawn_event(players_amt)) + /// BANDASTATION EDIT END - STORYTELLER + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + if(!can_spawn_event(players_amt, fake_check = TRUE) && !forced) /// BANDSTATION EDIT - STORYTELLER message_admins("Second pre-condition check for [name] failed, rerolling...") - var/message = can_spawn_event_error_reason(players_amt) - if(message != "success") - message_admins(message) - log_admin(message) SSevents.spawnEvent(excluded_event = src) return EVENT_INTERRUPTED + + /// BANDASTATION EDIT START - STORYTELLER + if(!can_spawn_event(players_amt, fake_check = TRUE) && forced) + message_admins("Second pre-condition check for [name] failed, but event forced, running event regardless this may have issues...") + /// BANDASTATION EDIT END - STORYTELLER + if(!triggering) return EVENT_CANCELLED //admin cancelled + triggering = FALSE return EVENT_READY @@ -193,7 +160,6 @@ message_admins("[key_name_admin(usr)] cancelled event [name].") log_admin_private("[key_name(usr)] cancelled event [name].") SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath) - SSgamemode.remove_scheduled_event(src) if(href_list["different_event"]) if(!triggering) to_chat(usr, span_admin("Too late to change events now!")) @@ -203,7 +169,6 @@ message_admins("[key_name_admin(usr)] chose to have event [name] rolled into a different event.") log_admin_private("[key_name(usr)] rerolled event [name].") SSblackbox.record_feedback("tally", "event_admin_rerolled", 1, typepath) - SSgamemode.remove_scheduled_event(src) /* @@ -244,12 +209,14 @@ Runs the event triggering = FALSE log_game("[random ? "Random" : "Forced"] Event triggering: [name] ([typepath]).") + // BANDASTATION EDIT START - STORYTELLER: event groups + if(event_group) + GLOB.event_groups[event_group].on_run(src) + // BANDASTATION EDIT END + if(alert_observers) round_event.announce_deadchat(random, event_cause) - log_admin_private("[random ? "Random" : "Forced"] Event triggering: [name] ([typepath]).") - message_admins(span_adminnotice("[random ? "Random" : "Forced"] Event triggering: [name] ([typepath]).")) - SSblackbox.record_feedback("tally", "event_ran", 1, "[round_event]") return round_event @@ -292,6 +259,7 @@ Runs the event //This is really only for setting defaults which can be overridden later when New() finishes. /datum/round_event/proc/setup() SHOULD_CALL_PARENT(FALSE) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER return ///Announces the event name to deadchat, override this if what an event should show to deadchat is different to its event name. @@ -345,6 +313,10 @@ Runs the event //This proc will handle the calls to the appropriate procs. /datum/round_event/process() SHOULD_NOT_OVERRIDE(TRUE) + /// BANDASTATION EDIT START - STORYTELLER + if(!setup) + return + /// BANDASTATION EDIT END - STORYTELLER if(!processing) return diff --git a/code/modules/events/anomaly/_anomaly.dm b/code/modules/events/anomaly/_anomaly.dm index 4d1916158f292..53cfde92faeff 100644 --- a/code/modules/events/anomaly/_anomaly.dm +++ b/code/modules/events/anomaly/_anomaly.dm @@ -24,6 +24,7 @@ impact_area = get_area(spawn_location) else impact_area = placer.findValidArea() + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/anomaly/announce(fake) if(isnull(impact_area)) diff --git a/code/modules/events/anomaly/anomaly_vortex.dm b/code/modules/events/anomaly/anomaly_vortex.dm index 2801f61bca94a..06a91f52b0126 100644 --- a/code/modules/events/anomaly/anomaly_vortex.dm +++ b/code/modules/events/anomaly/anomaly_vortex.dm @@ -4,7 +4,7 @@ min_players = 20 max_occurrences = 2 - weight = 10 + weight = 4 //BANDASTATION EDIT - STORYTELLER: 10 ==> 4 description = "This anomaly sucks in and detonates items." min_wizard_trigger_potency = 3 max_wizard_trigger_potency = 7 diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index 2fdd161514903..7089ede474cd3 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -7,7 +7,7 @@ category = EVENT_CATEGORY_FRIENDLY description = "A colourful display can be seen through select windows. And the kitchen." -/datum/round_event_control/aurora_caelus/can_spawn_event(players, allow_magic = FALSE) +/datum/round_event_control/aurora_caelus/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER if(!SSmapping.empty_space) return FALSE return ..() diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index fdbf46d48c6d0..d092747b47835 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -46,6 +46,7 @@ kill() return origin_machine = pick_n_take(vending_machines) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/brand_intelligence/announce(fake) var/machine_name = initial(origin_machine.name) diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 774100fb7356d..0228fdfd18899 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -20,8 +20,11 @@ overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it. for(var/job in jobs) var/datum/job/current = job - current.total_positions = 0 + /// BANDASTATION EDIT START - STORYTELLER + //current.total_positions = 0 + current.total_positions = max(current.total_positions + rand(-2,4), 1) + /// BANDASTATION EDIT END - STORYTELLER return // Adds/removes a random amount of job slots from all jobs. for(var/datum/job/current as anything in jobs) - current.total_positions = max(current.total_positions + rand(-2,4), 0) + current.total_positions = max(current.total_positions + rand(-2,4), 1) /// BANDASTATION EDIT - STORYTELLER diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 25d93f8bd5559..7a2911d6322b3 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -35,6 +35,7 @@ /datum/round_event/carp_migration/setup() start_when = rand(40, 60) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/carp_migration/announce(fake) priority_announce("[fluff_signal] have been detected near [station_name()], please stand-by.", "Lifesign Alert") diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 43c7f98cf19bd..2355b16c2ae5c 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -37,7 +37,7 @@ ///Disease recipient candidates var/list/disease_candidates = list() -/datum/round_event_control/disease_outbreak/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/disease_outbreak/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/earthquake.dm b/code/modules/events/earthquake.dm index 58b0a7e40821a..995dd159302d4 100644 --- a/code/modules/events/earthquake.dm +++ b/code/modules/events/earthquake.dm @@ -15,7 +15,7 @@ max_wizard_trigger_potency = 7 map_flags = EVENT_PLANETARY_ONLY -/datum/round_event_control/earthquake/can_spawn_event(players_amt, allow_magic) +/datum/round_event_control/earthquake/can_spawn_event(players_amt, allow_magic, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/false_alarm.dm b/code/modules/events/false_alarm.dm index 6e5cfdc61a1f3..3e5978c916ed1 100644 --- a/code/modules/events/false_alarm.dm +++ b/code/modules/events/false_alarm.dm @@ -7,7 +7,7 @@ description = "Fakes an event announcement." admin_setup = list(/datum/event_admin_setup/listed_options/false_alarm) -/datum/round_event_control/falsealarm/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/falsealarm/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/ghost_role/alien_infestation.dm b/code/modules/events/ghost_role/alien_infestation.dm index 1c0c938ce89fc..151be3d964452 100644 --- a/code/modules/events/ghost_role/alien_infestation.dm +++ b/code/modules/events/ghost_role/alien_infestation.dm @@ -9,7 +9,7 @@ category = EVENT_CATEGORY_ENTITIES description = "A xenomorph larva spawns on a random vent." -/datum/round_event_control/alien_infestation/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/alien_infestation/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/ghost_role/blob.dm b/code/modules/events/ghost_role/blob.dm index 097620646d875..774dde389bf06 100644 --- a/code/modules/events/ghost_role/blob.dm +++ b/code/modules/events/ghost_role/blob.dm @@ -10,7 +10,7 @@ category = EVENT_CATEGORY_ENTITIES description = "Spawns a new blob overmind." -/datum/round_event_control/blob/can_spawn_event(players, allow_magic = FALSE) +/datum/round_event_control/blob/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER if(EMERGENCY_PAST_POINT_OF_NO_RETURN) // no blobs if the shuttle is past the point of no return return FALSE diff --git a/code/modules/events/gravity_generator_blackout.dm b/code/modules/events/gravity_generator_blackout.dm index 84d67753dce52..08c2a271df600 100644 --- a/code/modules/events/gravity_generator_blackout.dm +++ b/code/modules/events/gravity_generator_blackout.dm @@ -7,7 +7,7 @@ min_wizard_trigger_potency = 0 max_wizard_trigger_potency = 4 -/datum/round_event_control/gravity_generator_blackout/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/gravity_generator_blackout/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/grey_tide.dm b/code/modules/events/grey_tide.dm index 62f5a53374c31..b7024c64e10f5 100644 --- a/code/modules/events/grey_tide.dm +++ b/code/modules/events/grey_tide.dm @@ -20,6 +20,7 @@ announce_when = rand(50, 60) end_when = rand(20, 30) severity = rand(1,3) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER var/list/potential_areas = list(/area/station/command, /area/station/engineering, diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index a0bc06718c08d..000f480b2f062 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -12,7 +12,7 @@ ///Candidates for receiving a healthy dose of heart disease var/list/heart_attack_candidates = list() -/datum/round_event_control/heart_attack/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/heart_attack/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index f96b73e66a295..c6530c7aff586 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/portal_storm/syndicate_shocktroop weight = 2 min_players = 15 + max_occurrences = 1 //BANDASTATION EDIT - STORYTELLER earliest_start = 30 MINUTES category = EVENT_CATEGORY_ENTITIES description = "Syndicate troops pour out of portals." @@ -69,6 +70,7 @@ hostiles_spawn += get_random_station_turf() next_boss_spawn = start_when + CEILING(2 * number_of_hostiles / number_of_bosses, 1) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/portal_storm/announce(fake) set waitfor = 0 diff --git a/code/modules/events/radiation_leak.dm b/code/modules/events/radiation_leak.dm index a5aee22a8b26f..e835a14dd9120 100644 --- a/code/modules/events/radiation_leak.dm +++ b/code/modules/events/radiation_leak.dm @@ -47,6 +47,7 @@ // We found something, we can just return now picked_machine_ref = WEAKREF(sick_device) return + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/radiation_leak/announce(fake) var/obj/machinery/the_source_of_our_problems = picked_machine_ref?.resolve() diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 5b2b6b71ea1dd..95e7f3224be10 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -14,6 +14,7 @@ start_when = 3 end_when = start_when + 1 announce_when = 1 + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /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", ANNOUNCER_RADIATION) diff --git a/code/modules/events/sandstorm.dm b/code/modules/events/sandstorm.dm index 0288b32ec2078..f44276e9ca90c 100644 --- a/code/modules/events/sandstorm.dm +++ b/code/modules/events/sandstorm.dm @@ -30,6 +30,7 @@ /datum/round_event/sandstorm/setup() start_when = rand(70, 90) end_when = rand(110, 140) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/sandstorm/announce(fake) if(!start_side) diff --git a/code/modules/events/scrubber_overflow.dm b/code/modules/events/scrubber_overflow.dm index 7f24648a9e5a7..7c670a4508014 100644 --- a/code/modules/events/scrubber_overflow.dm +++ b/code/modules/events/scrubber_overflow.dm @@ -84,8 +84,9 @@ if(!scrubbers.len) return kill() + setup = TRUE /// BANDASTATION EDIT - STORYTELLER -/datum/round_event_control/scrubber_overflow/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/scrubber_overflow/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return diff --git a/code/modules/events/shuttle_catastrophe.dm b/code/modules/events/shuttle_catastrophe.dm index ed64c52a836a7..df87d2ecdae4a 100644 --- a/code/modules/events/shuttle_catastrophe.dm +++ b/code/modules/events/shuttle_catastrophe.dm @@ -7,7 +7,7 @@ description = "Replaces the emergency shuttle with a random one." admin_setup = list(/datum/event_admin_setup/warn_admin/shuttle_catastrophe, /datum/event_admin_setup/listed_options/shuttle_catastrophe) -/datum/round_event_control/shuttle_catastrophe/can_spawn_event(players, allow_magic = FALSE) +/datum/round_event_control/shuttle_catastrophe/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . @@ -46,6 +46,7 @@ if(!isnull(template.who_can_purchase) && template.credit_cost < INFINITY) //if we could get it from the communications console, it's cool for us to get it here valid_shuttle_templates += template new_shuttle = pick(valid_shuttle_templates) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/shuttle_catastrophe/start() if(SSshuttle.shuttle_insurance) diff --git a/code/modules/events/shuttle_insurance.dm b/code/modules/events/shuttle_insurance.dm index 4442291a9ed9a..fe2f433634c98 100644 --- a/code/modules/events/shuttle_insurance.dm +++ b/code/modules/events/shuttle_insurance.dm @@ -7,7 +7,7 @@ category = EVENT_CATEGORY_BUREAUCRATIC description = "A sketchy but legit insurance offer." -/datum/round_event_control/shuttle_insurance/can_spawn_event(players, allow_magic = FALSE) +/datum/round_event_control/shuttle_insurance/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . @@ -39,6 +39,7 @@ break if(!insurance_evaluation) insurance_evaluation = 5000 //gee i dunno + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/shuttle_insurance/start() insurance_message = new("Shuttle Insurance", "Hey, pal, this is the [ship_name]. Can't help but notice you're rocking a wild and crazy shuttle there with NO INSURANCE! Crazy. What if something happened to it, huh?! We've done a quick evaluation on your rates in this sector and we're offering [insurance_evaluation] to cover for your shuttle in case of any disaster.", list("Purchase Insurance.","Reject Offer.")) diff --git a/code/modules/events/shuttle_loan/shuttle_loan_event.dm b/code/modules/events/shuttle_loan/shuttle_loan_event.dm index c3fa0770c1da9..c3c5c869ccbb8 100644 --- a/code/modules/events/shuttle_loan/shuttle_loan_event.dm +++ b/code/modules/events/shuttle_loan/shuttle_loan_event.dm @@ -11,7 +11,7 @@ ///A list of normally unavailable (or already run) situations datums var/list/unavailable_situations = list(/datum/shuttle_loan_situation/mail_strike) -/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() for(var/datum/round_event/running_event in SSevents.running) if(istype(running_event, /datum/round_event/shuttle_loan)) //Make sure two of these don't happen at once. diff --git a/code/modules/events/space_vines/vine_event.dm b/code/modules/events/space_vines/vine_event.dm index ce9881c990797..195e22b2f94b4 100644 --- a/code/modules/events/space_vines/vine_event.dm +++ b/code/modules/events/space_vines/vine_event.dm @@ -3,7 +3,7 @@ typepath = /datum/round_event/spacevine weight = 15 max_occurrences = 3 - min_players = 10 + min_players = 25 //BANDASTATION EDIT - STORYTELLER: 10 ==> 25 category = EVENT_CATEGORY_ENTITIES description = "Kudzu begins to overtake the station. Might spawn man-traps." min_wizard_trigger_potency = 4 diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index ab518fd3af11c..35a9100942d38 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -16,6 +16,7 @@ /datum/round_event/spider_infestation/setup() announce_when = rand(announce_when, announce_when + 50) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/spider_infestation/announce(fake) priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index 0be1138f59a59..3f140e5511235 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -66,6 +66,7 @@ var/datum/supply_pack/pack_type = pack if(initial(pack_type.special)) stray_spawnable_supply_packs -= pack + setup = TRUE /// BANDASTATION EDIT - STORYTELLER ///Spawns a random supply pack, puts it in a pod, and spawns it on a random tile of the selected area /datum/round_event/stray_cargo/start() diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm index 8d8c50a69f92e..bd0222d8d45d4 100644 --- a/code/modules/events/supermatter_surge.dm +++ b/code/modules/events/supermatter_surge.dm @@ -37,7 +37,7 @@ /datum/event_admin_setup/input_number/surge_spiciness, ) -/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!SSjob.has_minimum_jobs(crew_threshold = 3, jobs = JOB_GROUP_ENGINEERS, head_jobs = list(JOB_CHIEF_ENGINEER))) diff --git a/code/modules/events/tram_malfunction.dm b/code/modules/events/tram_malfunction.dm index 600dfed805b2f..2595fd2006c8d 100644 --- a/code/modules/events/tram_malfunction.dm +++ b/code/modules/events/tram_malfunction.dm @@ -13,7 +13,7 @@ max_wizard_trigger_potency = 3 //Check if there's a tram we can cause to malfunction. -/datum/round_event_control/tram_malfunction/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/tram_malfunction/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if (!.) return FALSE @@ -33,6 +33,7 @@ /datum/round_event/tram_malfunction/setup() end_when = rand(TRAM_MALFUNCTION_TIME_LOWER, TRAM_MALFUNCTION_TIME_UPPER) + setup = TRUE /// BANDASTATION EDIT - STORYTELLER /datum/round_event/tram_malfunction/start() for(var/datum/transport_controller/linear/tram/malfunctioning_controller as anything in SStransport.transports_by_type[TRANSPORT_TYPE_TRAM]) diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index a263059fa7211..cf0aa7a7d3ec3 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -8,7 +8,7 @@ category = EVENT_CATEGORY_JANITORIAL description = "Harmless mobs climb out of a vent." -/datum/round_event_control/vent_clog/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/vent_clog/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return diff --git a/code/modules/events/wizard/embeddies.dm b/code/modules/events/wizard/embeddies.dm index 8b4568942154a..075e3c8064384 100644 --- a/code/modules/events/wizard/embeddies.dm +++ b/code/modules/events/wizard/embeddies.dm @@ -9,7 +9,7 @@ max_wizard_trigger_potency = 7 ///behold... the only reason sticky is a subtype... -/datum/round_event_control/wizard/embedpocalypse/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/wizard/embedpocalypse/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/wizard/identity_spoof.dm b/code/modules/events/wizard/identity_spoof.dm index dcd923c2776a4..f54cf4d88d260 100644 --- a/code/modules/events/wizard/identity_spoof.dm +++ b/code/modules/events/wizard/identity_spoof.dm @@ -5,7 +5,7 @@ max_occurrences = 1 description = "Makes everyone dressed up like a wizard." -/datum/round_event_control/wizard/identity_spoof/can_spawn_event(players_amt, allow_magic = FALSE) +/datum/round_event_control/wizard/identity_spoof/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 5db33818d1276..ac01dc271700b 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to /datum/round_event/wormholes/setup() announce_when = rand(0, 20) end_when = rand(40, 80) + setup = TRUE /datum/round_event/wormholes/start() for(var/turf/open/floor/valid in GLOB.station_turfs) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 2753dfc65f4df..91c9358270328 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -187,7 +187,7 @@ /obj/machinery/computer/emergency_shuttle/proc/increase_hijack_stage() var/obj/docking_port/mobile/emergency/shuttle = SSshuttle.emergency // Begin loading this early, prevents a delay when the shuttle goes to land - INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) + //INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER shuttle.hijack_status++ if(hijack_announce) @@ -596,7 +596,7 @@ var/destination_dock = "emergency_away" if(is_hijacked() || elimination_hijack()) // just double check - SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) + //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER destination_dock = "emergency_syndicate" minor_announce("Corruption detected in \ shuttle navigation protocols. Please contact your \ diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 613224e237037..0ccec476964a9 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -25,32 +25,29 @@ MUNDANE_POINT_GAIN_MULTIPLIER 1 MODERATE_POINT_GAIN_MULTIPLIER 1 MAJOR_POINT_GAIN_MULTIPLIER 1 -CREWSET_POINT_GAIN_MULTIPLIER 1 -GHOSTSET_POINT_GAIN_MULTIPLIER 1 +ROLESET_POINT_GAIN_MULTIPLIER 1 +OBJECTIVES_POINT_GAIN_MULTIPLIER 1 ## Multipliers for points to spend on roundstart events. MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 -CREWSET_ROUNDSTART_POINT_MULTIPLIER 1 -GHOSTSET_ROUNDSTART_POINT_MULTIPLIER 1 +ROLESET_ROUNDSTART_POINT_MULTIPLIER 1 +OBJECTIVES_ROUNDSTART_POINT_MULTIPLIER 1 ## Minimum population caps for event tracks to run their events. MUNDANE_MIN_POP 0 MODERATE_MIN_POP 0 -MAJOR_MIN_POP 20 -CREWSET_MIN_POP 0 -GHOSTSET_MIN_POP 0 +MAJOR_MIN_POP 0 +ROLESET_MIN_POP 0 +OBJECTIVES_MIN_POP 0 -## Basic multiplayer for storytellers -MAX_SEC_MULT 1.5 - -## Point threshold multipliers for tracks to run events. The lesser the more frequent events will be. -MUNDANE_POINT_THRESHOLD 1 -MODERATE_POINT_THRESHOLD 1 -MAJOR_POINT_THRESHOLD 1 -CREWSET_POINT_THRESHOLD 1 -GHOSTSET_POINT_THRESHOLD 1 +## Point thresholds for tracks to run events. The lesser the more frequent events will be. +MUNDANE_POINT_THRESHOLD 25 +MODERATE_POINT_THRESHOLD 50 +MAJOR_POINT_THRESHOLD 90 +ROLESET_POINT_THRESHOLD 120 +OBJECTIVES_POINT_THRESHOLD 130 ## Allows the storyteller to scale event frequencies based on population ALLOW_STORYTELLER_POP_SCALING @@ -59,12 +56,20 @@ ALLOW_STORYTELLER_POP_SCALING MUNDANE_POP_SCALE_THRESHOLD 10 MODERATE_POP_SCALE_THRESHOLD 15 MAJOR_POP_SCALE_THRESHOLD 40 -CREWSET_POP_SCALE_THRESHOLD 45 -GHOSTSET_POP_SCALE_THRESHOLD 40 +ROLESET_POP_SCALE_THRESHOLD 45 +OBJECTIVES_POP_SCALE_THRESHOLD 40 ## The maximum penalties population scalling will apply to the tracks for having less pop than POP_SCALE_THRESHOLD. This is treated as percentages MUNDANE_POP_SCALE_PENALTY 30 MODERATE_POP_SCALE_PENALTY 30 MAJOR_POP_SCALE_PENALTY 30 -CREWSET_POP_SCALE_PENALTY 30 -GHOSTSET_POP_SCALE_PENALTY 30 +ROLESET_POP_SCALE_PENALTY 30 +OBJECTIVES_POP_SCALE_PENALTY 30 + +## How long (in minutes) after roundstart should the server start an automatic crew transfer vote? +## Defaults to 90 minutes. Set to 0 to completely disable automatic crew transfer votes. +TRANSFER_VOTE_TIME 90 + +## If players vote against a crew transfer, how long (in minutes) until another automatic transfer vote will be initiated? +## Defaults to 30 minutes. Set to 0 to completely disable subsequent crew transfer votes. +SUBSEQUENT_TRANSFER_VOTE_TIME 30 diff --git a/config/logging.txt b/config/logging.txt index 2bd9e90fcd95c..2938904e55ced 100644 --- a/config/logging.txt +++ b/config/logging.txt @@ -101,3 +101,6 @@ LOG_WHISPER ## log manual target zone switching LOG_ZONE_SWITCH + +## log storyteller +# LOG_STORYTELLER diff --git a/modular_bandastation/game/_game.dm b/modular_bandastation/game/_game.dm new file mode 100644 index 0000000000000..45f5c7951a256 --- /dev/null +++ b/modular_bandastation/game/_game.dm @@ -0,0 +1,4 @@ +/datum/modpack/logging + name = "Logging mode" + desc = "Адаптация кастомного логирования." + author = "KageIIte" diff --git a/modular_bandastation/game/_game.dme b/modular_bandastation/game/_game.dme new file mode 100644 index 0000000000000..e6cc07ae08c90 --- /dev/null +++ b/modular_bandastation/game/_game.dme @@ -0,0 +1,8 @@ +#include "_game.dm" + +#include "code\_defines.dm" +#include "code\_game_options.dm" +#include "code\_procs.dm" +#include "code\log_categories.dm" + +#include "code\votes\_vote_datum.dm" diff --git a/modular_bandastation/game/code/_defines.dm b/modular_bandastation/game/code/_defines.dm new file mode 100644 index 0000000000000..f5ae307009b61 --- /dev/null +++ b/modular_bandastation/game/code/_defines.dm @@ -0,0 +1,2 @@ +#define LOG_CATEGORY_STORYTELLER "storyteller" +#define LOG_CATEGORY_ANTAG_REP "antag-rep" diff --git a/modular_bandastation/game/code/_game_options.dm b/modular_bandastation/game/code/_game_options.dm new file mode 100644 index 0000000000000..9857758ee641a --- /dev/null +++ b/modular_bandastation/game/code/_game_options.dm @@ -0,0 +1,23 @@ +/datum/config_entry/flag/log_storyteller + +/datum/config_entry/flag/disable_storyteller + +/datum/config_entry/flag/log_antag_rep + +/datum/config_entry/number/transfer_vote_time + default = 90 MINUTES + min_val = 0 + +/datum/config_entry/number/transfer_vote_time/ValidateAndSet(str_val) + . = ..() + if(.) + config_entry_value *= 600 // documented as minutes + +/datum/config_entry/number/subsequent_transfer_vote_time + default = 30 MINUTES + min_val = 0 + +/datum/config_entry/number/subsequent_transfer_vote_time/ValidateAndSet(str_val) + . = ..() + if(.) + config_entry_value *= 600 // documented as minutes diff --git a/modular_bandastation/game/code/_procs.dm b/modular_bandastation/game/code/_procs.dm new file mode 100644 index 0000000000000..b1cb75dae0169 --- /dev/null +++ b/modular_bandastation/game/code/_procs.dm @@ -0,0 +1,5 @@ +/proc/log_storyteller(text, list/data) + logger.Log(LOG_CATEGORY_STORYTELLER, text, data) + +/proc/log_antag_rep(text, list/data) + logger.Log(LOG_CATEGORY_ANTAG_REP, text, data) diff --git a/modular_bandastation/game/code/log_categories.dm b/modular_bandastation/game/code/log_categories.dm new file mode 100644 index 0000000000000..f2a8a5fc63171 --- /dev/null +++ b/modular_bandastation/game/code/log_categories.dm @@ -0,0 +1,7 @@ +/datum/log_category/storyteller + category = LOG_CATEGORY_STORYTELLER + config_flag = /datum/config_entry/flag/log_storyteller + +/datum/log_category/antag_rep + category = LOG_CATEGORY_ANTAG_REP + config_flag = /datum/config_entry/flag/log_antag_rep diff --git a/modular_bandastation/game/code/votes/_vote_datum.dm b/modular_bandastation/game/code/votes/_vote_datum.dm new file mode 100644 index 0000000000000..c69fc89bb40ca --- /dev/null +++ b/modular_bandastation/game/code/votes/_vote_datum.dm @@ -0,0 +1,5 @@ +/datum/vote + var/player_startable = TRUE + +/datum/vote/proc/can_vote(mob/voter) + return TRUE diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme index 67c8069c10d90..b75c94a03806b 100644 --- a/modular_bandastation/modular_bandastation.dme +++ b/modular_bandastation/modular_bandastation.dme @@ -39,3 +39,4 @@ #include "orderables/_orderables.dme" #include "overrides/_overrides.dme" #include "storyteller/_storyteller.dme" +#include "game/_game.dme" diff --git a/modular_bandastation/preferences/code/modules/client/preferences.dm b/modular_bandastation/preferences/code/modules/client/preferences.dm index e9111b6725e98..fb515193c3727 100644 --- a/modular_bandastation/preferences/code/modules/client/preferences.dm +++ b/modular_bandastation/preferences/code/modules/client/preferences.dm @@ -4,6 +4,8 @@ /datum/preferences max_save_slots = 5 var/loadout_points = 0 + ///our current antag rep (base is 10) + var/antag_rep = 10 /datum/preferences/proc/get_loadout_points() var/donation_level = parent.donator_level diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index dce389bba41bf..fa99b05c6fee1 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -1,11 +1,18 @@ #include "_storyteller.dm" -#include "code\_defines\_persistence.dm" -#include "code\_defines\_ticker.dm" #include "code\_defines\storyteller_defines.dm" #include "code\_defines\storyteller_config.dm" +#include "code\_defines\_ticker.dm" +#include "code\_helpers.dm" +#include "code\event_defines\_round_event.dm" +#include "code\event_defines\_round_event_control.dm" -#include "code\event_defines\crewset\_antagonist_event.dm" +#include "code\events\group\_event_group.dm" +#include "code\events\group\groups.dm" +#include "code\events\object\anomalies_dimensional.dm" +#include "code\events\summon_wizard.dm" + +#include "code\event_defines\crewset\_override.dm" #include "code\event_defines\crewset\changeling.dm" #include "code\event_defines\crewset\heretic.dm" #include "code\event_defines\crewset\malf.dm" @@ -17,31 +24,35 @@ #include "code\event_defines\crewset\clown_ops.dm" #include "code\event_defines\crewset\revolution.dm" #include "code\event_defines\crewset\obsessed.dm" +#include "code\event_defines\crewset\wizard.dm" #include "code\event_defines\ghostset\override.dm" #include "code\event_defines\ghostset\voidwalker.dm" +#include "code\event_defines\ghostset\nuke_ops.dm" +#include "code\event_defines\ghostset\wizard.dm" +#include "code\event_defines\ghostset\paradox_clone.dm" #include "code\event_defines\major\override.dm" #include "code\event_defines\moderate\override.dm" #include "code\event_defines\mundane\override.dm" -#include "code\storytellers\data\tracks.dm" -#include "code\storytellers\tellers\_storyteller.dm" -#include "code\storytellers\tellers\storyteller_bomb.dm" -#include "code\storytellers\tellers\storyteller_chill.dm" -#include "code\storytellers\tellers\storyteller_clown.dm" -#include "code\storytellers\tellers\storyteller_default.dm" -#include "code\storytellers\tellers\storyteller_extended.dm" -#include "code\storytellers\tellers\storyteller_fragile.dm" -#include "code\storytellers\tellers\storyteller_gamer.dm" -#include "code\storytellers\tellers\storyteller_black_orbit.dm" -#include "code\storytellers\tellers\storyteller_phantom.dm" - -#include "code\divergency_report.dm" +#include "code\storytellers\_storyteller.dm" +#include "code\storytellers\storyteller_bomb.dm" +#include "code\storytellers\storyteller_chill.dm" +#include "code\storytellers\storyteller_clown.dm" +#include "code\storytellers\storyteller_default.dm" +#include "code\storytellers\storyteller_extended.dm" +#include "code\storytellers\storyteller_fragile.dm" +#include "code\storytellers\storyteller_gamer.dm" +#include "code\storytellers\storyteller_jester.dm" +#include "code\storytellers\storyteller_mystic.dm" +#include "code\storytellers\storyteller_operative.dm" +#include "code\storytellers\storyteller_black_orbit.dm" +#include "code\storytellers\storyteller_phantom.dm" + +#include "code\dynamic_report.dm" #include "code\scheduled_event.dm" #include "code\vote.dm" #include "code\gamemode.dm" -#include "code\event_defines\_event.dm" #include "code\event_defines\override_events.dm" -#include "code\event_defines\disabled_event_overrides.dm" diff --git a/modular_bandastation/storyteller/code/_defines/_persistence.dm b/modular_bandastation/storyteller/code/_defines/_persistence.dm deleted file mode 100644 index a4822efbb0204..0000000000000 --- a/modular_bandastation/storyteller/code/_defines/_persistence.dm +++ /dev/null @@ -1,7 +0,0 @@ -/datum/controller/subsystem/persistence - var/last_storyteller_type = "" - -/datum/controller/subsystem/persistence/Initialize() - . = ..() - load_storyteller_type() - return . diff --git a/modular_bandastation/storyteller/code/_defines/_ticker.dm b/modular_bandastation/storyteller/code/_defines/_ticker.dm index b51b96443fb3b..161e16844e584 100644 --- a/modular_bandastation/storyteller/code/_defines/_ticker.dm +++ b/modular_bandastation/storyteller/code/_defines/_ticker.dm @@ -1,3 +1,4 @@ /datum/controller/subsystem/ticker/PostSetup() . = .. () - SSgamemode.post_setup() + SSgamemode.current_storyteller.process(STORYTELLER_WAIT_TIME * 0.1) // we want this asap + SSgamemode.current_storyteller.round_started = TRUE diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm index c8a5b2c0d35cb..121a512099d13 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm @@ -12,11 +12,11 @@ config_entry_value = 1 min_val = 0 -/datum/config_entry/number/crewset_point_gain_multiplier +/datum/config_entry/number/roleset_point_gain_multiplier config_entry_value = 1 min_val = 0 -/datum/config_entry/number/ghostset_point_gain_multiplier +/datum/config_entry/number/objectives_point_gain_multiplier config_entry_value = 1 min_val = 0 @@ -33,11 +33,11 @@ config_entry_value = 1 min_val = 0 -/datum/config_entry/number/crewset_roundstart_point_multiplier +/datum/config_entry/number/roleset_roundstart_point_multiplier config_entry_value = 1 min_val = 0 -/datum/config_entry/number/ghostset_roundstart_point_multiplier +/datum/config_entry/number/objectives_roundstart_point_multiplier config_entry_value = 1 min_val = 0 @@ -57,22 +57,16 @@ integer = TRUE min_val = 0 -/datum/config_entry/number/crewset_min_pop - config_entry_value = CREWSET_MIN_POP +/datum/config_entry/number/roleset_min_pop + config_entry_value = ROLESET_MIN_POP integer = TRUE min_val = 0 -/datum/config_entry/number/ghostset_min_pop - config_entry_value = GHOSTSET_MIN_POP +/datum/config_entry/number/objectives_min_pop + config_entry_value = OBJECTIVES_MIN_POP integer = TRUE min_val = 0 -// Point Thresholds -/datum/config_entry/number/max_sec_mult - config_entry_value = MAX_SEC_MULT - integer = FALSE - min_val = 0 - // Point Thresholds /datum/config_entry/number/mundane_point_threshold config_entry_value = MUNDANE_POINT_THRESHOLD @@ -89,13 +83,13 @@ integer = TRUE min_val = 0 -/datum/config_entry/number/crewset_point_threshold - config_entry_value = CREWSET_POINT_THRESHOLD +/datum/config_entry/number/roleset_point_threshold + config_entry_value = ROLESET_POINT_THRESHOLD integer = TRUE min_val = 0 -/datum/config_entry/number/ghostset_point_threshold - config_entry_value = GHOSTSET_POINT_THRESHOLD +/datum/config_entry/number/objectives_point_threshold + config_entry_value = OBJECTIVES_POINT_THRESHOLD integer = TRUE min_val = 0 @@ -118,13 +112,13 @@ integer = TRUE min_val = 0 -/datum/config_entry/number/crewset_pop_scale_threshold - config_entry_value = CREWSET_POP_SCALE_THRESHOLD +/datum/config_entry/number/roleset_pop_scale_threshold + config_entry_value = ROLESET_POP_SCALE_THRESHOLD integer = TRUE min_val = 0 -/datum/config_entry/number/ghostset_pop_scale_threshold - config_entry_value = GHOSTSET_POP_SCALE_THRESHOLD +/datum/config_entry/number/objectives_pop_scale_threshold + config_entry_value = OBJECTIVES_POP_SCALE_THRESHOLD integer = TRUE min_val = 0 @@ -144,12 +138,12 @@ integer = TRUE min_val = 0 -/datum/config_entry/number/crewset_pop_scale_penalty - config_entry_value = CREWSET_POP_SCALE_PENALTY +/datum/config_entry/number/roleset_pop_scale_penalty + config_entry_value = ROLESET_POP_SCALE_PENALTY integer = TRUE min_val = 0 -/datum/config_entry/number/ghostset_pop_scale_penalty - config_entry_value = GHOSTSET_POP_SCALE_PENALTY +/datum/config_entry/number/objectives_pop_scale_penalty + config_entry_value = OBJECTIVES_POP_SCALE_PENALTY integer = TRUE min_val = 0 diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index f97c0e25702fb..060ed3b636235 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -1,3 +1,4 @@ + //Could be bitflags, but that would require a good amount of translations, which eh, either way works for me /// When the event is combat oriented (spawning monsters, inherently hostile antags) #define TAG_COMBAT "combat" @@ -17,83 +18,91 @@ #define TAG_TEAM_ANTAG "team_antag" /// When one of the non-crewmember players becomes an antagonist #define TAG_OUTSIDER_ANTAG "away_antag" -/// When the event is considered chaotic by a completely non-biased coder. -#define TAG_CHAOTIC "chaotic" /// When the event impacts the overmap #define TAG_OVERMAP "overmap" /// When the event requires the station to be in space (meteors, carp) #define TAG_SPACE "space" -/// When the event requires the station to be on planetary. +/// When the event requires the station to be planetary. #define TAG_PLANETARY "planetary" +/// When the event is an external threat (meteors, nukies). +#define TAG_EXTERNAL "external" +/// When the event is an alien threat (blob, xenos) +#define TAG_ALIEN "alien" +/// When the event is magical in nature +#define TAG_MAGICAL "magical" #define EVENT_TRACK_MUNDANE "Mundane" #define EVENT_TRACK_MODERATE "Moderate" #define EVENT_TRACK_MAJOR "Major" -#define EVENT_TRACK_CREWSET "Crewset" -#define EVENT_TRACK_GHOSTSET "Ghostset" +#define EVENT_TRACK_ROLESET "Roleset" +#define EVENT_TRACK_OBJECTIVES "Objectives" #define ALL_EVENTS "All" #define UNCATEGORIZED_EVENTS "Uncategorized" -#define STORYTELLER_WAIT_TIME 20 SECONDS +#define STORYTELLER_WAIT_TIME 5 SECONDS -#define EVENT_POINT_GAINED_PER_SECOND 0.05 +#define EVENT_POINT_GAINED_PER_SECOND 0.08 -#define TRACK_FAIL_POINT_PENALTY_MULTIPLIER 0.5 +#define TRACK_FAIL_POINT_PENALTY_MULTIPLIER 0.75 #define GAMEMODE_PANEL_MAIN "Main" #define GAMEMODE_PANEL_VARIABLES "Variables" -#define MAX_SEC_MULT 1.5 - -/// Reused for multipliers of the thresholds -#define MUNDANE_POINT_THRESHOLD 1 -#define MODERATE_POINT_THRESHOLD 1 -#define MAJOR_POINT_THRESHOLD 1 -#define CREWSET_POINT_THRESHOLD 1 -#define GHOSTSET_POINT_THRESHOLD 1 +#define MUNDANE_POINT_THRESHOLD 40 +#define MODERATE_POINT_THRESHOLD 70 +#define MAJOR_POINT_THRESHOLD 130 +#define ROLESET_POINT_THRESHOLD 150 +#define OBJECTIVES_POINT_THRESHOLD 170 -#define MUNDANE_MIN_POP 0 -#define MODERATE_MIN_POP 0 +#define MUNDANE_MIN_POP 4 +#define MODERATE_MIN_POP 6 #define MAJOR_MIN_POP 20 -#define CREWSET_MIN_POP 0 -#define GHOSTSET_MIN_POP 0 +#define ROLESET_MIN_POP 25 +#define OBJECTIVES_MIN_POP 20 /// Defines for how much pop do we need to stop applying a pop scalling penalty to event frequency. #define MUNDANE_POP_SCALE_THRESHOLD 25 #define MODERATE_POP_SCALE_THRESHOLD 32 #define MAJOR_POP_SCALE_THRESHOLD 45 -#define CREWSET_POP_SCALE_THRESHOLD 45 -#define GHOSTSET_POP_SCALE_THRESHOLD 45 +#define ROLESET_POP_SCALE_THRESHOLD 45 +#define OBJECTIVES_POP_SCALE_THRESHOLD 45 /// The maximum penalty coming from pop scalling, when we're at the most minimum point, easing into 0 as we reach the SCALE_THRESHOLD. This is treated as a percentage. #define MUNDANE_POP_SCALE_PENALTY 35 #define MODERATE_POP_SCALE_PENALTY 35 #define MAJOR_POP_SCALE_PENALTY 35 -#define CREWSET_POP_SCALE_PENALTY 35 -#define GHOSTSET_POP_SCALE_PENALTY 35 +#define ROLESET_POP_SCALE_PENALTY 35 +#define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_VOTE "storyteller" -#define EVENT_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_CREWSET, EVENT_TRACK_GHOSTSET) -#define EVENT_PANEL_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_CREWSET, EVENT_TRACK_GHOSTSET, UNCATEGORIZED_EVENTS, ALL_EVENTS) +#define EVENT_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_ROLESET, EVENT_TRACK_OBJECTIVES) +#define EVENT_PANEL_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_ROLESET, EVENT_TRACK_OBJECTIVES, UNCATEGORIZED_EVENTS, ALL_EVENTS) /// Defines for the antag cap to prevent midround injections. -#define ANTAG_CAP_FLAT 1 -#define ANTAG_CAP_DENOMINATOR 9 +#define ANTAG_CAP_FLAT 3 +#define ANTAG_CAP_DENOMINATOR 30 -///Below are defines for the percentage fill that the tracks should start on. +- 50% of the value will be added +///Below are defines for roundstart point pool. The GAIN ones are multiplied by ready population #define ROUNDSTART_MUNDANE_BASE 20 +#define ROUNDSTART_MUNDANE_GAIN 0.5 #define ROUNDSTART_MODERATE_BASE 35 +#define ROUNDSTART_MODERATE_GAIN 1.2 #define ROUNDSTART_MAJOR_BASE 40 +#define ROUNDSTART_MAJOR_GAIN 2 -#define ROUNDSTART_CREWSET_BASE 60 +#define ROUNDSTART_ROLESET_BASE 60 +#define ROUNDSTART_ROLESET_GAIN 2 -#define ROUNDSTART_GHOSTSET_BASE 40 +#define ROUNDSTART_OBJECTIVES_BASE 40 +#define ROUNDSTART_OBJECTIVES_GAIN 2 -/// Storyteller types below, basically prevents several intense teller rounds in a row -#define STORYTELLER_TYPE_ALWAYS_AVAILABLE 0 -#define STORYTELLER_TYPE_CALM 1 -#define STORYTELLER_TYPE_INTENSE 2 +#define SHARED_HIGH_THREAT "high threat event" +#define SHARED_ANOMALIES "anomalous event" +#define SHARED_SCRUBBERS "scrubber-related event" +#define SHARED_METEORS "meteor event" +#define SHARED_BSOD "tech malfunction event" +#define SHARED_CHANGELING "changelings" diff --git a/modular_bandastation/storyteller/code/_helpers.dm b/modular_bandastation/storyteller/code/_helpers.dm new file mode 100644 index 0000000000000..40f4a95673279 --- /dev/null +++ b/modular_bandastation/storyteller/code/_helpers.dm @@ -0,0 +1,74 @@ +GLOBAL_LIST_INIT(blessed_ckeys, list( + "taocat" = list(3, 25), +)) //this is a lmao moment should be a json but its being left here because lol it goes ckey = list(multiplier, base) + +///adjusts antag rep by {VALUE} keeping the value above 0 +/datum/preferences/proc/adjust_antag_rep(value, multiplier = TRUE) + if(multiplier) + value *= return_rep_multiplier() + log_antag_rep("[parent]'s antag rep was adjusted by [value]") + antag_rep += value + if(antag_rep < 1) + log_antag_rep("[parent]'s antag rep was adjusted below 1 resetting to 1") + antag_rep = 1 + save_preferences() + +/datum/preferences/proc/reset_antag_rep() + var/default = return_default_antag_rep() + log_antag_rep("[parent]'s antag rep was reset to default ([default])") + antag_rep = default + save_preferences() + +/datum/preferences/proc/return_default_antag_rep() + if(!parent) + return 10 + if(!(parent.ckey in GLOB.blessed_ckeys)) + return 10 + return GLOB.blessed_ckeys[parent.ckey][2] + +/datum/preferences/proc/return_rep_multiplier() + if(!parent) + return 1 + if(!(parent.ckey in GLOB.blessed_ckeys)) + return 1 + return GLOB.blessed_ckeys[parent.ckey][1] + + +///give it a list of clients and the value aswell if it should be affected by multipliers and let er rip +/proc/mass_adjust_antag_rep(list/clients, value, mulitplier = TRUE) + for(var/client/listed_client as anything in clients) + if(!IS_CLIENT_OR_MOCK(listed_client) || QDELETED(listed_client) || QDELETED(listed_client.prefs)) + continue + listed_client.prefs.adjust_antag_rep(value, mulitplier) + +/proc/return_antag_rep_weight(list/candidates) + . = list() + for(var/anything in candidates) + var/client/client_source + if(ismob(anything)) + var/mob/mob = anything + client_source = mob.client + else if(IS_CLIENT_OR_MOCK(anything)) + client_source = anything + if(QDELETED(client_source) || !client_source.ckey) + continue + .[client_source.ckey] = client_source.prefs?.antag_rep || 10 + + log_antag_rep("Returned Weighted List of [length(.)]", list("before_weight" = candidates, "after_weight" = .)) + +/// Pick a random element from the list and remove it from the list. +/proc/pick_n_take_weighted(list/list_to_pick) + if(length(list_to_pick)) + var/picked = pick_weight(list_to_pick) + list_to_pick -= picked + return picked + +/proc/is_late_arrival(mob/living/player) + var/static/cached_result + if(!isnull(cached_result)) + return cached_result + if(!HAS_TRAIT(SSstation, STATION_TRAIT_LATE_ARRIVALS) || (STATION_TIME_PASSED() > 1 MINUTES)) + return cached_result = FALSE + if(QDELETED(player) || !istype(get_area(player), /area/shuttle/arrival)) + return FALSE + return TRUE diff --git a/modular_bandastation/storyteller/code/divergency_report.dm b/modular_bandastation/storyteller/code/divergency_report.dm deleted file mode 100644 index 9c0e715486c4b..0000000000000 --- a/modular_bandastation/storyteller/code/divergency_report.dm +++ /dev/null @@ -1,44 +0,0 @@ -/datum/controller/subsystem/gamemode/proc/send_trait_report() - . = "Информационное сообщение Департамента разведки Нанотрейзен, Сектор Спинвард, Дата [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR]:
" - SSstation.generate_station_goals(20) - - . += generate_station_goal_report() - . += generate_station_trait_report() - - . += "
Это включает в себя вашу смену с начала до момента окончания. Удачной смены!
\ -

Этот ярлык подтверждает, что стажёр проверил вышеизложенное перед отправкой. Данный документ является собственностью корпорации Nanotrasen.

" - - print_command_report(., "Отчет Центрального Командования", announce = FALSE) - priority_announce("Приветствуем вас, экипаж станции [station_name()]. Наш стажёр проверил отчет и возможные отклонения и направил вам результат. Хорошей смены!", "Протокол отклонений", SSstation.announcer.get_rand_report_sound()) - -/* - * Generate a list of station goals available to purchase to report to the crew. - * - * Returns a formatted string all station goals that are available to the station. - */ -/datum/controller/subsystem/gamemode/proc/generate_station_goal_report() - var/list/station_goals = SSstation.get_station_goals() - if(!length(station_goals)) - return "
Активные задачи - отсутствуют.
" - var/list/goal_reports = list() - for(var/datum/station_goal/station_goal as anything in station_goals) - station_goal.on_report() - goal_reports += station_goal.get_report() - return "
Специальные цели для [station_name()]:
[goal_reports.Join("
")]" - -/* - * Generate a list of active station traits to report to the crew. - * - * Returns a formatted string of all station traits (that are shown) affecting the station. - */ -/datum/controller/subsystem/gamemode/proc/generate_station_trait_report() - if(!length(SSstation.station_traits)) - return "
Нет выявленных отклонений на смене.
" - - var/list/station_traits_report = list("
Выявленные отклонения в смене:
") - for(var/datum/station_trait/station_trait as anything in SSstation.station_traits) - if(!station_trait.show_in_report) - continue - station_traits_report += "[station_trait.get_report()]
" - - return station_traits_report.Join() diff --git a/modular_bandastation/storyteller/code/dynamic_report.dm b/modular_bandastation/storyteller/code/dynamic_report.dm new file mode 100644 index 0000000000000..a37394a9d8c1b --- /dev/null +++ b/modular_bandastation/storyteller/code/dynamic_report.dm @@ -0,0 +1,27 @@ +/// Generate the advisory level depending on the shown threat level. +/datum/controller/subsystem/dynamic/generate_advisory_level() + var/advisory_string = "" + //monkestation edit start: + //switch(round(shown_threat)) + var/list/green_nebula_storytellers = list(/datum/storyteller/extended, /datum/storyteller/chill) //list for calmer storytellers for a greenshift + var/list/midnight_sun_storytellers = list(/datum/storyteller/jester, /datum/storyteller/clown) + var/list/orange_star_storytellers = list(/datum/storyteller/default, /datum/storyteller/fragile, /datum/storyteller/mystic) + var/list/red_moon_storytellers = list(/datum/storyteller/bomb, /datum/storyteller/gamer, /datum/storyteller/operative) + var/list/black_orbit_storytellers = list(/datum/storyteller/black_orbit, /datum/storyteller/pups) //list for the more chaotic storytellers for black sun + if(SSgamemode.selected_storyteller in green_nebula_storytellers) + advisory_string += "Advisory Level: Green Nebula
" + advisory_string += "Your sector's advisory level is Green Nebula. Surveillance information shows no credible threats to Nanotrasen assets within the Spinward Sector at this time. As always, the Department advises maintaining vigilance against potential threats, regardless of a lack of known threats." + if(SSgamemode.selected_storyteller in midnight_sun_storytellers) + advisory_string += "Advisory Level: Midnight Sun
" + advisory_string += "Your sector's advisory level is Midnight Sun. Credible information passed to us by GDI suggests that the Syndicate is preparing to mount a major concerted offensive on Nanotrasen assets in the Spinward Sector to cripple our foothold there. All stations should remain on high alert and prepared to defend themselves." + if(SSgamemode.selected_storyteller in orange_star_storytellers) + advisory_string += "Advisory Level: Orange Star
" + advisory_string += "Your sector's advisory level is Orange Star. Upon reviewing your sector's intelligence, the Department has determined that the risk of enemy activity is moderate to severe. At this advisory, we recommend maintaining a higher degree of security and alertness, and vigilance against threats that may (or will) arise." + if(SSgamemode.selected_storyteller in red_moon_storytellers) + advisory_string += "Advisory Level: Red Moon
" + advisory_string += "Your sector's advisory level is Red Moon. Upon reviewing your sector's intelligence, the Department has determined that the risk of enemy activity is moderate to severe. At this advisory, we recommend maintaining a higher degree of security and alertness, and vigilance against threats that may (or will) arise." + if(SSgamemode.selected_storyteller in black_orbit_storytellers) + advisory_string += "Advisory Level: Black Orbit
" + advisory_string += "Your sector's advisory level is Black Orbit. Central Command has determined that the risk of enemy activity is high. Central Command abandon you and crew. Now only god can help you." + + return advisory_string diff --git a/modular_bandastation/storyteller/code/event_defines/_event.dm b/modular_bandastation/storyteller/code/event_defines/_event.dm deleted file mode 100644 index 7d49051ad65f6..0000000000000 --- a/modular_bandastation/storyteller/code/event_defines/_event.dm +++ /dev/null @@ -1,91 +0,0 @@ -/datum/round_event_control - var/roundstart = FALSE - var/cost = 1 - var/reoccurence_penalty_multiplier = 0.75 - var/shared_occurence_type - var/track = EVENT_TRACK_MODERATE - /// Last calculated weight that the storyteller assigned this event - var/calculated_weight = 0 - var/tags = list() /// Tags of the event - /// List of the shared occurence types. - var/static/list/shared_occurences = list() - /// Whether a roundstart event can happen post roundstart. Very important for events which override job assignments. - var/can_run_post_roundstart = TRUE - - // BANDASTATION EDIT - STORYTELLER - CREW REQUIREMENTS - var/med_required_crew = 0 - var/eng_required_crew = 0 - var/rnd_required_crew = 0 - var/head_required_crew = 0 - -/datum/round_event - /// Whether the event called its start() yet or not. - var/has_started = FALSE - -/// This section of event processing is in a proc because roundstart events may get their start invoked. -/datum/round_event/proc/try_start() - if(has_started) - return - has_started = TRUE - processing = FALSE - start() - processing = TRUE - -/datum/round_event_control/roundstart - roundstart = TRUE - earliest_start = 0 - -///Adds an occurence. Has to use the setter to properly handle shared occurences -/datum/round_event_control/proc/add_occurence() - if(shared_occurence_type) - if(!shared_occurences[shared_occurence_type]) - shared_occurences[shared_occurence_type] = 0 - shared_occurences[shared_occurence_type]++ - occurrences++ - -///Subtracts an occurence. Has to use the setter to properly handle shared occurences -/datum/round_event_control/proc/subtract_occurence() - if(shared_occurence_type) - if(!shared_occurences[shared_occurence_type]) - shared_occurences[shared_occurence_type] = 0 - shared_occurences[shared_occurence_type]-- - occurrences-- - -///Gets occurences. Has to use the getter to properly handle shared occurences -/datum/round_event_control/proc/get_occurences() - if(shared_occurence_type) - if(!shared_occurences[shared_occurence_type]) - shared_occurences[shared_occurence_type] = 0 - return shared_occurences[shared_occurence_type] - return occurrences - -/// Prints the action buttons for this event. -/datum/round_event_control/proc/get_href_actions() - if(SSticker.HasRoundStarted()) - if(roundstart) - if(!can_run_post_roundstart) - return "Fire Schedule" - return "Fire Schedule" - else - return "Fire Schedule Force Next" - else - if(roundstart) - return "Force Roundstart" - else - return "Fire Schedule Force Next" - -/datum/round_event_control/Topic(href, href_list) - . = ..() - switch(href_list["action"]) - if("force_next") - message_admins("[key_name_admin(usr)] has forced scheduled event [src.name].") - log_admin_private("[key_name(usr)] has forced scheduled event [src.name].") - SSgamemode.force_event(src) - if("schedule") - message_admins("[key_name_admin(usr)] has scheduled event [src.name].") - log_admin_private("[key_name(usr)] has scheduled event [src.name].") - SSgamemode.schedule_event(src) - if("fire") - message_admins("[key_name_admin(usr)] has fired event [src.name].") - log_admin_private("[key_name(usr)] has fired event [src.name].") - run_event(random = FALSE, admin_forced = TRUE) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm new file mode 100644 index 0000000000000..279f033a07bca --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -0,0 +1,227 @@ +/datum/round_event + /// Whether the event called its start() yet or not. + var/has_started = FALSE + ///have we finished setup? + var/setup = FALSE + var/excute_round_end_reports = FALSE + +/// This section of event processing is in a proc because roundstart events may get their start invoked. +/datum/round_event/proc/try_start() + if(has_started) + return + has_started = TRUE + processing = FALSE + start() + processing = TRUE + +/datum/round_event_control/roundstart + roundstart = TRUE + earliest_start = 0 + +/datum/round_event/proc/round_end_report() + return + +/datum/round_event/setup() + . = ..() + if(excute_round_end_reports) + SSgamemode.round_end_data |= src + +/datum/round_event/antagonist + fakeable = FALSE + end_when = 6000 //This is so prompted picking events have time to run //TODO: refactor events so they can be the masters of themselves, instead of relying on some weirdly timed vars + +/datum/round_event/antagonist/solo + // ALL of those variables are internal. Check the control event to change them + /// The antag flag passed from control + var/antag_flag + /// The antag datum passed from control + var/antag_datum + /// The antag count passed from control + var/antag_count + /// The restricted roles (jobs) passed from control + var/list/restricted_roles + /// The minds we've setup in setup() and need to finalize in start() + var/list/setup_minds = list() + /// Whether we prompt the players before picking them. + var/prompted_picking = FALSE //TODO: Implement this + /// DO NOT SET THIS MANUALLY, THIS IS INHERITED FROM THE EVENT CONTROLLER ON NEW + var/list/extra_spawned_events + /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so + var/list/preferred_events + +/datum/round_event/antagonist/solo/New(my_processing, datum/round_event_control/event_controller) + . = ..() + if(istype(event_controller, /datum/round_event_control/antagonist/solo)) + var/datum/round_event_control/antagonist/solo/antag_event_controller = event_controller + if(antag_event_controller) + if(antag_event_controller.extra_spawned_events) + extra_spawned_events = fill_with_ones(antag_event_controller.extra_spawned_events) + if(antag_event_controller.preferred_events) + preferred_events = fill_with_ones(antag_event_controller.preferred_events) + +/datum/round_event/antagonist/solo/setup() + var/datum/round_event_control/antagonist/solo/cast_control = control + antag_count = cast_control.get_antag_amount() + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + restricted_roles = cast_control.restricted_roles + prompted_picking = cast_control.prompted_picking + var/list/possible_candidates = cast_control.get_candidates() + var/list/candidates = list() + if(cast_control == SSgamemode.current_roundstart_event && length(SSgamemode.roundstart_antag_minds)) + log_storyteller("Running roundstart antagonist assignment, event: [src], roundstart_antag_minds: [english_list(SSgamemode.roundstart_antag_minds)]") + for(var/datum/mind/antag_mind in SSgamemode.roundstart_antag_minds) + if(!antag_mind.current) + log_storyteller("Roundstart antagonist setup error: antag_mind([antag_mind]) in roundstart_antag_minds without a set mob") + continue + candidates += antag_mind.current + SSgamemode.roundstart_antag_minds -= antag_mind + log_storyteller("Roundstart antag_mind, [antag_mind]") + + //guh + var/list/cliented_list = list() + for(var/mob/living/mob as anything in possible_candidates) + cliented_list += mob.client + + if(length(cliented_list)) + mass_adjust_antag_rep(cliented_list, 1) + + var/list/weighted_candidates = return_antag_rep_weight(possible_candidates) + + while(length(weighted_candidates) && length(candidates) < antag_count) //both of these pick_n_take from weighted_candidates so this should be fine + if(prompted_picking) + var/picked_ckey = pick_n_take_weighted(weighted_candidates) + var/client/picked_client = GLOB.directory[picked_ckey] + if(QDELETED(picked_client)) + continue + var/mob/picked_mob = picked_client.mob + log_storyteller("Prompted antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") + if(picked_mob) + candidates |= SSpolling.poll_candidates( + question = "Would you like to be a [cast_control.name]?", + check_jobban = antag_flag, + role = antag_flag, + poll_time = 20 SECONDS, + group = list(picked_mob), + alert_pic = antag_datum, + role_name_text = lowertext(cast_control.name), + chat_text_border_icon = antag_datum, + ) + else + var/picked_ckey = pick_n_take_weighted(weighted_candidates) + var/client/picked_client = GLOB.directory[picked_ckey] + if(QDELETED(picked_client)) + continue + var/mob/picked_mob = picked_client.mob + picked_mob?.mind?.picking = TRUE + log_storyteller("Picked antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") + candidates |= picked_mob + + var/list/picked_mobs = list() + for(var/i in 1 to antag_count) + if(!length(candidates)) + message_admins("A roleset event got fewer antags then its antag_count and may not function correctly.") + break + + var/mob/candidate = pick_n_take(candidates) + log_storyteller("Antag event spawned mob: [candidate], special role: [candidate.mind?.special_role ? candidate.mind.special_role : "none"]") + + candidate.client?.prefs.reset_antag_rep() + + if(!candidate.mind) + candidate.mind = new /datum/mind(candidate.key) + + setup_minds += candidate.mind + candidate.mind.special_role = antag_flag + candidate.mind.restricted_roles = restricted_roles + picked_mobs += WEAKREF(candidate.client) + + setup = TRUE + control.generate_image(picked_mobs) + if(LAZYLEN(extra_spawned_events)) + var/event_type = pick_weight(extra_spawned_events) + if(!event_type) + return + var/datum/round_event_control/triggered_event = locate(event_type) in SSgamemode.control + //wait a second to avoid any potential omnitraitor bs + addtimer(CALLBACK(triggered_event, TYPE_PROC_REF(/datum/round_event_control, run_event), FALSE, null, FALSE, "storyteller"), 1 SECONDS) + +/datum/round_event/antagonist/solo/start() + for(var/datum/mind/antag_mind as anything in setup_minds) + add_datum_to_mind(antag_mind, antag_mind.current) + +/datum/round_event/antagonist/solo/proc/add_datum_to_mind(datum/mind/antag_mind) + antag_mind.add_antag_datum(antag_datum) + +/datum/round_event/antagonist/solo/proc/spawn_extra_events() + if(!LAZYLEN(extra_spawned_events)) + return + var/datum/round_event_control/event = pick_weight(extra_spawned_events) + event?.run_event(random = FALSE, event_cause = "storyteller") + +/datum/round_event/antagonist/solo/proc/create_human_mob_copy(turf/create_at, mob/living/carbon/human/old_mob, qdel_old_mob = TRUE) + if(!old_mob?.client) + return + + var/mob/living/carbon/human/new_character = new(create_at) + if(!create_at) + SSjob.SendToLateJoin(new_character) + + old_mob.client.prefs.safe_transfer_prefs_to(new_character) + new_character.dna.update_dna_identity() + old_mob.mind.transfer_to(new_character) + if(qdel_old_mob) + qdel(old_mob) + return new_character + +/datum/round_event/antagonist/solo/ghost/start() + for(var/datum/mind/antag_mind as anything in setup_minds) + add_datum_to_mind(antag_mind) + +/datum/round_event/antagonist/solo/ghost/setup() + var/datum/round_event_control/antagonist/solo/cast_control = control + antag_count = cast_control.get_antag_amount() + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + restricted_roles = cast_control.restricted_roles + prompted_picking = cast_control.prompted_picking + var/list/candidates = cast_control.get_candidates() + + //guh + var/list/cliented_list = list() + for(var/mob/living/mob as anything in candidates) + cliented_list += mob.client + if(length(cliented_list)) + mass_adjust_antag_rep(cliented_list, 1) + + if(prompted_picking) + candidates = SSpolling.poll_candidates( + question = "Would you like to be a [cast_control.name]?", + check_jobban = antag_flag, + role = antag_flag, + poll_time = 20 SECONDS, + group = candidates, + alert_pic = antag_datum, + role_name_text = lowertext(cast_control.name), + chat_text_border_icon = antag_datum, + ) + + var/list/weighted_candidates = return_antag_rep_weight(candidates) + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + + candidate_client.prefs?.reset_antag_rep() + + if(!candidate.mind) + candidate.mind = new /datum/mind(candidate.key) + var/mob/living/carbon/human/new_human = make_body(candidate) + new_human.mind.special_role = antag_flag + new_human.mind.restricted_roles = restricted_roles + setup_minds += new_human.mind + selected_count++ + setup = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm new file mode 100644 index 0000000000000..ef956a879ecdc --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -0,0 +1,285 @@ +/datum/round_event_control + /// The typepath to the event group this event is a part of. + var/datum/event_group/event_group = null + var/roundstart = FALSE + var/cost = 1 + var/reoccurence_penalty_multiplier = 0.75 + var/shared_occurence_type + var/track = EVENT_TRACK_MODERATE + /// Last calculated weight that the storyteller assigned this event + var/calculated_weight = 0 + var/tags = list() /// Tags of the event + /// List of the shared occurence types. + var/static/list/shared_occurences = list() + /// Whether a roundstart event can happen post roundstart. Very important for events which override job assignments. + var/can_run_post_roundstart = TRUE + /// If set then the type or list of types of storytellers we are restricted to being trigged by + var/list/allowed_storytellers + ///do we check against the antag cap before attempting a spawn? + var/checks_antag_cap = FALSE + /// List of enemy roles, will check if x amount of these exist exist + var/list/enemy_roles + ///required number of enemies in roles to exist + var/required_enemies = 0 + ///required power of department to start event + var/eng_required_power = 0 + var/med_required_power = 0 + var/rnd_required_power = 0 + var/head_required_power = 0 + +/datum/round_event_control/proc/return_failure_string(players_amt) + var/string + if(roundstart && (world.time-SSticker.round_start_time >= 2 MINUTES)) + string += "Roundstart" + if(occurrences >= max_occurrences) + if(string) + string += "," + string += "Cap Reached" + if(earliest_start >= world.time-SSticker.round_start_time) + if(string) + string += "," + string +="Too Soon" + if(players_amt < min_players) + if(string) + string += "," + string += "Lack of players" + if(holidayID && !check_holidays(holidayID)) + if(string) + string += "," + string += "Holiday Event" + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + if(string) + string += "," + string += "Round End" + if(checks_antag_cap) + if(!roundstart && !SSgamemode.can_inject_antags()) + if(string) + string += "," + string += "Too Many Antags" + return string + +/datum/round_event_control/antagonist/return_failure_string(players_amt) + . =..() + if(!check_enemies()) + if(.) + . += ", " + . += "No Enemies" + if(!check_required()) + if(.) + . += ", " + . += "No Required" + return . + +/datum/round_event_control/antagonist/solo/return_failure_string(players_amt) + . =..() + + var/antag_amt = get_antag_amount() + var/list/candidates = get_candidates() //we should optimize this + if(length(candidates) < antag_amt) + if(.) + . += ", " + . += "Not Enough Candidates!" + + return . + +/datum/round_event_control/proc/generate_image(list/mobs) + return + +/* Для титров +/datum/round_event_control/antagonist/generate_image(list/mobs) + SScredits.generate_major_icon(mobs, event_icon_state) +*/ + +/// Check if our enemy_roles requirement is met, if return_players is set then we will return the list of enemy players instead +/datum/round_event_control/proc/check_enemies(return_players = FALSE) + if(!length(enemy_roles)) + return return_players ? list() : TRUE + + var/job_check = 0 + var/list/enemy_players = list() + if(roundstart) + for(var/enemy in enemy_roles) + var/datum/job/enemy_job = SSjob.GetJob(enemy) + if(enemy_job && SSjob.assigned_players_by_job[enemy_job.type]) + job_check += length(SSjob.assigned_players_by_job[enemy_job.type]) + enemy_players += SSjob.assigned_players_by_job[enemy_job.type] + + else + for(var/mob/M in GLOB.alive_player_list) + if (M.stat == DEAD) + continue // Dead players cannot count as opponents + if (M.mind && (M.mind.assigned_role.title in enemy_roles)) + job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that + enemy_players += M + + if(job_check >= required_enemies) + return return_players ? enemy_players : TRUE + return return_players ? enemy_players : FALSE + +/datum/round_event_control/antagonist/New() + . = ..() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_roles |= protected_roles + +/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) + . = ..() + if(!check_required()) + return FALSE + + if(!.) + return + +/datum/round_event_control/antagonist + checks_antag_cap = TRUE + track = EVENT_TRACK_ROLESET + ///list of required roles, needed for this to form + var/list/exclusive_roles + /// Protected roles from the antag roll. People will not get those roles if a config is enabled + var/list/protected_roles + /// Restricted roles from the antag roll + var/list/restricted_roles + var/event_icon_state + +/datum/round_event_control/antagonist/proc/check_required() + if(!length(exclusive_roles)) + return TRUE + for (var/mob/M in GLOB.alive_player_list) + if (M.stat == DEAD) + continue // Dead players cannot count as passing requirements + if(M.mind && (M.mind.assigned_role.title in exclusive_roles)) + return TRUE + +/datum/round_event_control/antagonist/proc/trim_candidates(list/candidates) + return candidates + +/datum/round_event_control/antagonist/New() + . = ..() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_roles |= protected_roles + +/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) + . = ..() + if(!check_required()) + return FALSE + + if(!.) + return + +/datum/round_event_control/antagonist/solo + typepath = /datum/round_event/antagonist/solo + /// How many baseline antags do we spawn + var/base_antags = 1 + /// How many maximum antags can we spawn + var/maximum_antags = 3 + /// For this many players we'll add 1 up to the maximum antag amount + var/denominator = 20 + /// The antag flag to be used + var/antag_flag + /// The antag datum to be applied + var/antag_datum + /// Prompt players for consent to turn them into antags before doing so. Dont allow this for roundstart. + var/prompted_picking = FALSE + /// A list of extra events to force whenever this one is chosen by the storyteller. + /// Can either be normal list or a weighted list. + var/list/extra_spawned_events + /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so + var/list/preferred_events + +/datum/round_event_control/antagonist/solo/from_ghosts/get_candidates() + var/round_started = SSticker.HasRoundStarted() + var/midround_antag_pref_arg = round_started ? FALSE : TRUE + + var/list/candidates = SSgamemode.get_candidates(antag_flag, antag_flag, observers = TRUE, midround_antag_pref = midround_antag_pref_arg, restricted_roles = restricted_roles) + candidates = trim_candidates(candidates) + return candidates + +/datum/round_event_control/antagonist/solo/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) + . = ..() + if(!.) + return + var/antag_amt = get_antag_amount() + var/list/candidates = get_candidates() + if(length(candidates) < antag_amt) + return FALSE + +/datum/round_event_control/antagonist/solo/proc/get_antag_amount() + var/people = SSgamemode.get_correct_popcount() + var/amount = base_antags + FLOOR(people / denominator, 1) + return min(amount, maximum_antags) + +/datum/round_event_control/antagonist/solo/proc/get_candidates() + var/round_started = SSticker.HasRoundStarted() + var/new_players_arg = round_started ? FALSE : TRUE + var/living_players_arg = round_started ? TRUE : FALSE + var/midround_antag_pref_arg = round_started ? FALSE : TRUE + + var/list/candidates = SSgamemode.get_candidates(antag_flag, antag_flag, FALSE, new_players_arg, living_players_arg, midround_antag_pref = midround_antag_pref_arg, \ + restricted_roles = restricted_roles, required_roles = exclusive_roles) + candidates = trim_candidates(candidates) + return candidates + +///Adds an occurence. Has to use the setter to properly handle shared occurences +/datum/round_event_control/proc/add_occurence() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + shared_occurences[shared_occurence_type]++ + occurrences++ + +///Subtracts an occurence. Has to use the setter to properly handle shared occurences +/datum/round_event_control/proc/subtract_occurence() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + shared_occurences[shared_occurence_type]-- + occurrences-- + +///Gets occurences. Has to use the getter to properly handle shared occurences +/datum/round_event_control/proc/get_occurences() + if(shared_occurence_type) + if(!shared_occurences[shared_occurence_type]) + shared_occurences[shared_occurence_type] = 0 + return shared_occurences[shared_occurence_type] + return occurrences + +/// Prints the action buttons for this event. +/datum/round_event_control/proc/get_href_actions() + if(SSticker.HasRoundStarted()) + if(roundstart) + if(!can_run_post_roundstart) + return "Fire Schedule" + return "Fire Schedule" + else + return "Fire Schedule Force Next" + else + if(roundstart) + return "Add Roundstart Force Roundstart" + else + return "Fire Schedule Force Next" + + +/datum/round_event_control/Topic(href, href_list) + . = ..() + if(QDELETED(src)) + return + switch(href_list["action"]) + if("schedule") + message_admins("[key_name_admin(usr)] scheduled event [src.name].") + log_admin_private("[key_name(usr)] scheduled [src.name].") + SSgamemode.current_storyteller.buy_event(src, src.track) + if("force_next") + if(length(src.admin_setup)) + for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) + if(admin_setup_datum.prompt_admins() == ADMIN_CANCEL_EVENT) + return + message_admins("[key_name_admin(usr)] forced scheduled event [src.name].") + log_admin_private("[key_name(usr)] forced scheduled event [src.name].") + SSgamemode.forced_next_events[src.track] = src + if("fire") + if(length(src.admin_setup)) + for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) + if(admin_setup_datum.prompt_admins() == ADMIN_CANCEL_EVENT) + return + message_admins("[key_name_admin(usr)] fired event [src.name].") + log_admin_private("[key_name(usr)] fired event [src.name].") + run_event(random = FALSE, admin_forced = TRUE) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm deleted file mode 100644 index 8346f54101a2f..0000000000000 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_antagonist_event.dm +++ /dev/null @@ -1,188 +0,0 @@ -/datum/round_event_control/antagonist - reoccurence_penalty_multiplier = 0 - track = EVENT_TRACK_CREWSET - /// Protected roles from the antag roll. People will not get those roles if a config is enabled - var/protected_roles = list( - JOB_CAPTAIN, - - // Heads of staff - JOB_HEAD_OF_PERSONNEL, - JOB_HEAD_OF_SECURITY, - JOB_CHIEF_ENGINEER, - JOB_CHIEF_MEDICAL_OFFICER, - JOB_RESEARCH_DIRECTOR, - JOB_QUARTERMASTER, - - // Seccies - JOB_DETECTIVE, - JOB_SECURITY_OFFICER, - JOB_WARDEN, - JOB_PRISONER, - ) - - /// Restricted roles from the antag roll - var/restricted_roles = list(JOB_AI, JOB_CYBORG) - - /// How many baseline antags do we spawn - var/base_antags = 1 - /// How many maximum antags can we spawn - var/maximum_antags = 2 - /// Strict limit on how many antagonists of this type that should be in this round. 0 to ignore. - var/maximum_antags_global = 0 - /// For this many players we'll add 1 up to the maximum antag amount - var/denominator = 20 - /// The antag flag to be used - var/antag_flag - /// The antag datum to be applied - var/antag_datum - - var/minimum_candidate_base = 1 - - var/list/ruleset_lazy_templates - -/datum/round_event_control/antagonist/New() - . = ..() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_roles |= protected_roles - restricted_roles |= SSstation.antag_restricted_roles - restricted_roles |= SSstation.antag_protected_roles - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_roles |= JOB_ASSISTANT - -/datum/round_event_control/antagonist/can_spawn_event(players_amt, allow_magic = FALSE, popchecks = TRUE) - . = ..() - if(!.) - return - if(roundstart && SSticker.HasRoundStarted()) - return FALSE - if(!SSgamemode.can_inject_antags()) - return FALSE - if(!get_antag_amount()) - return FALSE - var/list/candidates = get_candidates() - if(length(candidates) < get_minimum_candidates()) - return FALSE - -/datum/round_event_control/antagonist/can_spawn_event_error_reason(players_amt, allow_magic = FALSE, popchecks = TRUE) - . = ..() - var/message = . - if(roundstart && SSticker.HasRoundStarted()) - message = "Storyteller event: [name] was unable to run due event is roundstart and round started." - if(!SSgamemode.can_inject_antags()) - message = "Storyteller event: [name] was unable to run due event can't inject antags over sec cap - cap/antags [SSgamemode.sec_crew]/[SSgamemode.get_antag_cap()]/[length(GLOB.current_living_antags)]." - if(!get_antag_amount()) - message = "Storyteller event: [name] was unable to run due no antags count to spawn." - var/list/candidates = get_candidates() - if(candidates.len < get_minimum_candidates()) - message = "Storyteller event: [name] was unable to run due too low candidates count." - - return message - - -/datum/round_event_control/antagonist/proc/get_minimum_candidates() - return minimum_candidate_base - -/datum/round_event_control/antagonist/proc/get_candidates() - var/round_started = SSticker.HasRoundStarted() - var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = !round_started, restricted_roles = restricted_roles) - return candidates - -/datum/round_event_control/antagonist/solo - typepath = /datum/round_event/antagonist/solo - -/datum/round_event_control/antagonist/proc/get_antag_amount() - - var/people = SSgamemode.get_correct_popcount() - var/amount = base_antags + FLOOR(people / denominator, 1) - - if(antag_datum && maximum_antags_global > 0) - var/antag_slots_left = maximum_antags_global - for(var/datum/antagonist/existing_antagonist as anything in GLOB.antagonists) - if(QDELETED(existing_antagonist) || QDELETED(existing_antagonist.owner) || QDELETED(existing_antagonist.owner.current)) //This feels messy, but it just werks. - continue - if(!istype(existing_antagonist, antag_datum)) //Obviously ignore other antagonists. - continue - antag_slots_left-- //Slot is occupied. - if(antag_slots_left <= 0) //No point in checking anymore. - break - amount = min(amount, antag_slots_left) - - return min(amount, maximum_antags) - -/datum/round_event/antagonist - fakeable = FALSE - end_when = 60 //This is so prompted picking events have time to run //TODO: refactor events so they can be the masters of themselves, instead of relying on some weirdly timed vars - // ALL of those variables are internal. Check the control event to change them - /// The antag flag passed from control - var/antag_flag - /// The antag datum passed from control - var/antag_datum - /// The antag count passed from control - var/antag_count - /// The restricted roles (jobs) passed from control - var/list/restricted_roles - /// The minds we've setup in setup() and need to finalize in start() - var/list/setup_minds = list() - -/datum/round_event/antagonist/solo - -/datum/round_event/antagonist/setup() - load_vars(control) - candidate_setup(control) - template_setup(control) - -/datum/round_event/antagonist/proc/load_vars(datum/round_event_control/antagonist/cast_control) - // Set up all the different variables on the round_event. God isn't it ugly - // Maybe move this to New() if possible? ~Waterpig - antag_flag = cast_control.antag_flag - antag_datum = cast_control.antag_datum - antag_count = cast_control.get_antag_amount() - restricted_roles = cast_control.restricted_roles - -/datum/round_event/antagonist/proc/candidate_setup(datum/round_event_control/antagonist/cast_control) - var/list/candidates = cast_control.get_candidates() - for(var/i in 1 to antag_count) - if(!candidates.len) - break - var/mob/candidate = pick_n_take(candidates) - setup_minds += candidate.mind - candidate_roles_setup(candidate) - -/datum/round_event/antagonist/proc/candidate_roles_setup(mob/candidate) - SHOULD_CALL_PARENT(FALSE) - - candidate.mind.special_role = antag_flag - candidate.mind.restricted_roles = restricted_roles - -/datum/round_event/antagonist/proc/template_setup(datum/round_event_control/antagonist/cast_control) - for(var/template in cast_control.ruleset_lazy_templates) - SSmapping.lazy_load_template(template) - -/datum/round_event/antagonist/solo/start() - for(var/datum/mind/antag_mind as anything in setup_minds) - add_datum_to_mind(antag_mind) - -/datum/round_event/antagonist/proc/add_datum_to_mind(datum/mind/antag_mind, team) - antag_mind.add_antag_datum(antag_datum, team) - -/datum/round_event_control/antagonist/team - typepath = /datum/round_event/antagonist/team - minimum_candidate_base = 1 - - var/antag_leader_datum - -/datum/round_event_control/antagonist/team/New() - . = ..() - if(isnull(antag_leader_datum)) - antag_leader_datum = antag_datum - -/datum/round_event/antagonist/team - var/antag_leader_datum - -/datum/round_event/antagonist/team/start() - for(var/datum/mind/antag_mind as anything in setup_minds) - add_datum_to_mind(antag_mind) - -/datum/round_event/antagonist/team/load_vars(datum/round_event_control/antagonist/team/cast_control) - . = ..() - antag_leader_datum = cast_control.antag_leader_datum diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm new file mode 100644 index 0000000000000..2a16027847ec3 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm @@ -0,0 +1,16 @@ +/datum/round_event_control/spider_infestation + track = EVENT_TRACK_ROLESET + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_ALIEN) + weight = 2 + +/datum/round_event_control/alien_infestation + track = EVENT_TRACK_ROLESET + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_ALIEN) + earliest_start = 60 MINUTES + weight = 2 + +/datum/round_event_control/blob + track = EVENT_TRACK_ROLESET + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_EXTERNAL, TAG_ALIEN) + earliest_start = 60 MINUTES + checks_antag_cap = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 99ee38316aa6e..4a6881e805cad 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -1,26 +1,53 @@ -/datum/round_event_control/antagonist/solo/blood_brothers - name = "Blood Brother" - roundstart = 1 - earliest_start = 0 SECONDS - - track = EVENT_TRACK_CREWSET +/datum/round_event_control/antagonist/solo/brother antag_flag = ROLE_BROTHER antag_datum = /datum/antagonist/brother - - weight = 6 - tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) - - base_antags = 1 - maximum_antags_global = 4 - - restricted_roles = list( - JOB_AI, - JOB_CYBORG, - ) + typepath = /datum/round_event/antagonist/solo/brother + tags = list(TAG_COMBAT, TAG_TEAM_ANTAG) protected_roles = list( JOB_CAPTAIN, + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, + JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, ) + restricted_roles = list( + JOB_AI, + JOB_CYBORG + ) + enemy_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_SECURITY, + JOB_DETECTIVE, + JOB_WARDEN, + JOB_SECURITY_OFFICER, + ) + required_enemies = 1 + weight = 12 + maximum_antags = 2 + denominator = 30 + cost = 0.45 // so it doesn't eat up threat for a relatively low-threat antag + +/datum/round_event_control/antagonist/solo/brother/roundstart + name = "Blood Brothers" + roundstart = TRUE + earliest_start = 0 SECONDS + extra_spawned_events = list( + /datum/round_event_control/antagonist/solo/traitor/roundstart = 12, + /datum/round_event_control/antagonist/solo/heretic/roundstart = 2, + ) + +/datum/round_event_control/antagonist/solo/brother/midround + name = "Sleeper Agents (Blood Brothers)" + prompted_picking = TRUE + required_enemies = 2 + +/datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) + var/datum/team/brother_team/team = new + team.add_member(antag_mind) + team.forge_brother_objectives() + antag_mind.add_antag_datum(/datum/antagonist/brother, team) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 73561202b2248..9825ab7f68f37 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -1,13 +1,30 @@ /datum/round_event_control/antagonist/solo/changeling - name = "Changelings" - roundstart = 1.9 - earliest_start = 0 SECONDS - antag_flag = ROLE_CHANGELING + tags = list(TAG_COMBAT, TAG_ALIEN) antag_datum = /datum/antagonist/changeling - weight = 8 - min_players = 15 - maximum_antags_global = 4 - category = EVENT_CATEGORY_INVASION - tags = list(TAG_COMBAT, TAG_CREW_ANTAG) - protected_roles = list() + protected_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ) + min_players = 20 + +/datum/round_event_control/antagonist/solo/changeling/roundstart + name = "Changelings" + roundstart = TRUE + earliest_start = 0 + +/datum/round_event_control/antagonist/solo/changeling/midround + name = "Genome Awakening (Changelings)" + prompted_picking = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 4d6b9184ef9fd..ac861fa28ea36 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,47 +1,116 @@ -/datum/round_event_control/antagonist/team/clown_ops - name = "Clown Operatives" - roundstart = 2 - earliest_start = 0 SECONDS - - track = EVENT_TRACK_CREWSET +/datum/round_event_control/antagonist/solo/clown_operative + name = "Roundstart Clown Operative" + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG, TAG_EXTERNAL) antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop - antag_leader_datum = /datum/antagonist/nukeop/leader/clownop - - weight = 0 - tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) - - base_antags = 2 + typepath = /datum/round_event/antagonist/solo/clown_operative + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_RESEARCH_DIRECTOR, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + base_antags = 3 maximum_antags = 5 - maximum_antags_global = 5 - min_players = 40 - - typepath = /datum/round_event/antagonist/team/clown_ops + enemy_roles = list( + JOB_AI, + JOB_CYBORG, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + // I give up, just there should be enough heads with 35 players... + min_players = 35 + roundstart = TRUE + earliest_start = 0 SECONDS + weight = 1 + max_occurrences = 1 - ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) - category = EVENT_CATEGORY_INVASION +/datum/round_event/antagonist/solo/clown_operative + excute_round_end_reports = TRUE + end_when = 60000 /// we will end on our own when revs win + var/static/datum/team/nuclear/nuke_team + var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader + var/set_leader = FALSE + var/required_role = ROLE_CLOWN_OPERATIVE -/datum/round_event/antagonist/team/clown_ops - var/datum/job/job_type = /datum/job/clown_operative - var/required_role = ROLE_NUCLEAR_OPERATIVE +/datum/round_event/antagonist/solo/clown_operative/setup() + . = ..() + var/obj/machinery/nuclearbomb/syndicate/syndicate_nuke = locate() in GLOB.nuke_list + if(syndicate_nuke) + var/turf/nuke_turf = get_turf(syndicate_nuke) + if(nuke_turf) + new /obj/machinery/nuclearbomb/syndicate/bananium(nuke_turf) + qdel(syndicate_nuke) - var/datum/team/nuclear/nuke_team +/datum/round_event/antagonist/solo/clown_operative/add_datum_to_mind(datum/mind/antag_mind) + var/mob/living/current_mob = antag_mind.current + SSjob.FreeRole(antag_mind.assigned_role.title) + var/list/items = current_mob.get_equipped_items(TRUE) + current_mob.unequip_everything() + for(var/obj/item/item as anything in items) + qdel(item) -/datum/round_event/antagonist/team/clown_ops/candidate_roles_setup(mob/candidate) - candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) - candidate.mind.special_role = required_role + antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/clown_operative)) + antag_mind.special_role = ROLE_CLOWN_OPERATIVE -/datum/round_event/antagonist/team/clown_ops/start() - // Get our nukie leader var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) if(!most_experienced) - most_experienced = setup_minds[1] - var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) - nuke_team = leader.nuke_team - - // Setup everyone else - for(var/datum/mind/assigned_player in setup_minds) - if(assigned_player == most_experienced) - continue - add_datum_to_mind(assigned_player) - return TRUE + most_experienced = antag_mind + + if(!set_leader) + set_leader = TRUE + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) + nuke_team = leader.nuke_team + + if(antag_mind == most_experienced) + return + + var/datum/antagonist/nukeop/new_op = new antag_datum() + antag_mind.add_antag_datum(new_op) + + +/datum/round_event/antagonist/solo/clown_operative/round_end_report() + var/result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 460931ba419ff..06798c01949d5 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -1,45 +1,75 @@ -/datum/round_event_control/antagonist/team/Cult - name = "Cult" - roundstart = 3 - earliest_start = 0 SECONDS - - track = EVENT_TRACK_CREWSET +/datum/round_event_control/antagonist/solo/bloodcult + name = "Blood Cult" + tags = list(TAG_SPOOKY, TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG, TAG_MAGICAL) antag_flag = ROLE_CULTIST antag_datum = /datum/antagonist/cult + typepath = /datum/round_event/antagonist/solo/bloodcult + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHAPLAIN, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + maximum_antags = 3 + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + base_antags = 2 + // I give up, just there should be enough heads with 35 players... + min_players = 30 + roundstart = TRUE + earliest_start = 0 SECONDS + weight = 4 + max_occurrences = 3 - weight = 6 - tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC, TAG_COMBAT) +/datum/round_event/antagonist/solo/bloodcult + excute_round_end_reports = TRUE + end_when = 60000 + var/static/datum/team/cult/main_cult - base_antags = 3 - maximum_antags = 6 - maximum_antags_global = 6 - min_players = 40 +/datum/round_event/antagonist/solo/bloodcult/setup() + . = ..() + if(!main_cult) + main_cult = new() - restricted_roles = list( - JOB_AI, - JOB_CAPTAIN, - JOB_CHAPLAIN, - JOB_CYBORG, - JOB_DETECTIVE, - JOB_HEAD_OF_PERSONNEL, - JOB_HEAD_OF_SECURITY, - JOB_PRISONER, - JOB_SECURITY_OFFICER, - JOB_WARDEN, - ) - - category = EVENT_CATEGORY_INVASION - -/datum/round_event/antagonist/team/cult - var/required_role = ROLE_CULTIST - - var/datum/team/nuclear/nuke_team - -/datum/round_event/antagonist/team/cult/candidate_roles_setup(mob/candidate) - candidate.mind.special_role = required_role - -/datum/round_event/antagonist/team/cult/start() - // Setup everyone else - for(var/datum/mind/assigned_player in setup_minds) - add_datum_to_mind(assigned_player) - return TRUE +/datum/round_event/antagonist/solo/bloodcult/start() + . = ..() + main_cult.setup_objectives() + +/datum/round_event/antagonist/solo/bloodcult/add_datum_to_mind(datum/mind/antag_mind) + var/datum/antagonist/cult/new_cultist = new antag_datum() + new_cultist.cult_team = main_cult + new_cultist.give_equipment = TRUE + antag_mind.add_antag_datum(new_cultist) + +/datum/round_event/antagonist/solo/bloodcult/round_end_report() + if(main_cult.check_cult_victory()) + SSticker.mode_result = "win - cult win" + SSticker.news_report = CULT_SUMMON + return + + SSticker.mode_result = "loss - staff stopped the cult" + + if(main_cult.size_at_maximum == 0) + CRASH("Cult team existed with a size_at_maximum of 0 at round end!") + + // If more than a certain ratio of our cultists have escaped, give the "cult escape" resport. + // Otherwise, give the "cult failure" report. + var/ratio_to_be_considered_escaped = 0.5 + var/escaped_cultists = 0 + for(var/datum/mind/escapee as anything in main_cult.members) + if(considered_escaped(escapee)) + escaped_cultists++ + + SSticker.news_report = (escaped_cultists / main_cult.size_at_maximum) >= ratio_to_be_considered_escaped ? CULT_ESCAPE : CULT_FAILURE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 2d34fc991f81f..54189f3e9c5ec 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -1,21 +1,32 @@ /datum/round_event_control/antagonist/solo/heretic - name = "Heretics" - roundstart = 1.5 - earliest_start = 0 SECONDS - antag_flag = ROLE_HERETIC + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_MAGICAL) antag_datum = /datum/antagonist/heretic - weight = 3 - min_players = 30 + protected_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ) + weight = 4 + min_players = 20 - maximum_antags_global = 2 - category = EVENT_CATEGORY_INVASION - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CREW_ANTAG) - -/datum/round_event_control/antagonist/solo/heretic/New() - protected_roles |= JOB_CHAPLAIN // Would be silly to get chaplain heretics - . = ..() +/datum/round_event_control/antagonist/solo/heretic/roundstart + name = "Heretics" + roundstart = TRUE + earliest_start = 0 /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" - roundstart = FALSE + prompted_picking = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 2342dea16c5ae..bfa65fc7134ba 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -1,58 +1,42 @@ - /datum/round_event_control/antagonist/solo/malf - name = "Malfunctioning AI Midround" - - base_antags = 1 - maximum_antags = 1 - maximum_antags_global = 1 - min_players = 20 - - min_players = TRUE - roundstart = FALSE - antag_datum = /datum/antagonist/malf_ai + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_ALIEN) //not exactly alien but close enough antag_flag = ROLE_MALF - weight = 1 - tags = list(TAG_CREW_ANTAG, TAG_COMBAT, TAG_DESTRUCTIVE, TAG_CHAOTIC) - restricted_roles = list() - category = EVENT_CATEGORY_AI - -/datum/round_event_control/antagonist/solo/malf/get_candidates() - return GLOB.ai_list + enemy_roles = list( + JOB_CHEMIST, + JOB_CHIEF_ENGINEER, + JOB_HEAD_OF_SECURITY, + JOB_RESEARCH_DIRECTOR, + JOB_SCIENTIST, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + exclusive_roles = list(JOB_AI) + required_enemies = 4 + weight = 2 + min_players = 35 + max_occurrences = 1 + +/datum/round_event_control/antagonist/solo/malf/trim_candidates(list/candidates) + for(var/mob/living/player in candidates) + if(!isAI(player)) + candidates -= player + continue + + if(is_centcom_level(player.z)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) + candidates -= player + + return candidates + +/datum/round_event_control/antagonist/solo/malf/midround + name = "Malfunctioning AI Midround" + antag_flag = ROLE_MALF_MIDROUND /datum/round_event_control/antagonist/solo/malf/roundstart - name = "Malfunctioning AI" - earliest_start = 0 SECONDS - - roundstart = 1.8 - min_players = 20 - - typepath = /datum/round_event/antagonist/solo/malf_ai/roundstart - weight = 10 - -// God has abandoned us -/datum/round_event_control/antagonist/solo/malf/roundstart/get_candidates() - var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = TRUE) - . = list() - var/datum/job/aijob = SSjob.get_job(JOB_AI) - for(var/mob/candidate as anything in candidates) - if(SSjob.check_job_eligibility(candidate, aijob) == JOB_AVAILABLE) - . += candidate - return . - -/datum/round_event_control/antagonist/solo/malf/roundstart/can_spawn_event(popchecks, allow_magic) - . = ..() - if(!.) - return . - - var/datum/job/ai_job = SSjob.get_job_type(/datum/job/ai) - if(!(ai_job.total_positions - ai_job.current_positions && ai_job.spawn_positions)) - return FALSE - else - return TRUE - -/datum/round_event/antagonist/solo/malf_ai/roundstart/setup() - . = ..() - for(var/datum/mind/new_malf in setup_minds) - GLOB.pre_setup_antags += new_malf - LAZYADDASSOC(SSjob.dynamic_forced_occupations, new_malf.current, "AI") + name = "Roundstart Malf AI" + roundstart = TRUE + earliest_start = 0 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 314275002ce9e..679415548e20a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -1,46 +1,104 @@ -/datum/round_event_control/antagonist/team/nuke_ops - name = "Nuclear Operatives" - roundstart = 2 - earliest_start = 0 SECONDS - +/datum/round_event_control/antagonist/solo/nuclear_operative + name = "Roundstart Nuclear Operative" + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG, TAG_EXTERNAL) antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop - antag_leader_datum = /datum/antagonist/nukeop/leader + typepath = /datum/round_event/antagonist/solo/nuclear_operative + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_RESEARCH_DIRECTOR, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + base_antags = 3 + maximum_antags = 5 + enemy_roles = list( + JOB_AI, + JOB_CYBORG, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + // I give up, just there should be enough heads with 35 players... + min_players = 35 + roundstart = TRUE + earliest_start = 0 SECONDS + weight = 4 + max_occurrences = 3 - weight = 6 - tags = list(TAG_CREW_ANTAG, TAG_CHAOTIC) +/datum/round_event/antagonist/solo/nuclear_operative + excute_round_end_reports = TRUE + end_when = 60000 /// we will end on our own when revs win + var/static/datum/team/nuclear/nuke_team + var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader + var/set_leader = FALSE + var/required_role = ROLE_NUCLEAR_OPERATIVE - base_antags = 2 - maximum_antags = 5 - maximum_antags_global = 5 - min_players = 40 +/datum/round_event/antagonist/solo/nuclear_operative/add_datum_to_mind(datum/mind/antag_mind) + var/mob/living/current_mob = antag_mind.current + SSjob.FreeRole(antag_mind.assigned_role.title) + var/list/items = current_mob.get_equipped_items(TRUE) + current_mob.unequip_everything() + for(var/obj/item/item as anything in items) + qdel(item) - typepath = /datum/round_event/antagonist/team/nukie + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) + if(!most_experienced) + most_experienced = antag_mind - ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) - category = EVENT_CATEGORY_INVASION + if(!set_leader) + set_leader = TRUE + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) + nuke_team = leader.nuke_team -/datum/round_event/antagonist/team/nukie - var/datum/job/job_type = /datum/job/nuclear_operative - var/required_role = ROLE_NUCLEAR_OPERATIVE + if(antag_mind == most_experienced) + return - var/datum/team/nuclear/nuke_team + var/datum/antagonist/nukeop/new_op = new antag_datum() + antag_mind.add_antag_datum(new_op) -/datum/round_event/antagonist/team/nukie/candidate_roles_setup(mob/candidate) - candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) - candidate.mind.special_role = required_role -/datum/round_event/antagonist/team/nukie/start() - // Get our nukie leader - var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) - if(!most_experienced) - most_experienced = setup_minds[1] - var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) - nuke_team = leader.nuke_team - - // Setup everyone else - for(var/datum/mind/assigned_player in setup_minds) - if(assigned_player == most_experienced) - continue - add_datum_to_mind(assigned_player) - return TRUE +/datum/round_event/antagonist/solo/nuclear_operative/round_end_report() + var/result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index d02936b4554a1..fea5ec4c14f4f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -1,21 +1,16 @@ /datum/round_event_control/antagonist/solo/obsessed - name = "Obseesed" - roundstart = FALSE - antag_flag = ROLE_OBSESSED + tags = list(TAG_COMBAT) antag_datum = /datum/antagonist/obsessed - weight = 10 - maximum_antags_global = 4 - typepath = /datum/round_event/antagonist/solo/obsessed - category = EVENT_CATEGORY_INVASION - tags = list(TAG_CREW_ANTAG) - protected_roles = list() - -/datum/round_event/antagonist/solo/obsessed/start() - var/datum/round_event_control/antagonist/re_control = control - var/candidate_list = re_control.get_candidates() - var/mob/living/carbon/human/obsessed = pick_n_take(candidate_list) - obsessed.gain_trauma(/datum/brain_trauma/special/obsessed) + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ROLE_POSITRONIC_BRAIN, + ) + weight = 4 + max_occurrences = 3 -/datum/round_event/antagonist/solo/obsessed/candidate_setup(datum/round_event_control/antagonist/cast_control, no_restricts = TRUE, antag_token = null) - return +/datum/round_event_control/antagonist/solo/obsessed/midround + name = "Compulsive Obsession" + prompted_picking = TRUE + maximum_antags = 4 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 622a7b87e132b..b0a5bf53680ff 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -1,24 +1,9 @@ -/datum/round_event_control/antagonist/team/revolution - name = "revolution" - roundstart = 2 - earliest_start = 0 SECONDS - - track = EVENT_TRACK_MAJOR - antag_flag = ROLE_REV - antag_datum = /datum/antagonist/rev/ - antag_leader_datum = /datum/antagonist/rev/head - - weight = 0 - tags = list(TAG_CREW_ANTAG, TAG_COMMUNAL) - - base_antags = 3 - maximum_antags_global = 6 - min_players = 40 - - restricted_roles = list( - JOB_AI, - JOB_CYBORG, - ) +/datum/round_event_control/antagonist/solo/revolutionary + name = "Roundstart Revolution" + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG) + antag_flag = ROLE_REV_HEAD + antag_datum = /datum/antagonist/rev/head/event_trigger + typepath = /datum/round_event/antagonist/solo/revolutionary restricted_roles = list( JOB_AI, JOB_CAPTAIN, @@ -29,35 +14,52 @@ JOB_HEAD_OF_PERSONNEL, JOB_HEAD_OF_SECURITY, JOB_PRISONER, - JOB_QUARTERMASTER, JOB_RESEARCH_DIRECTOR, JOB_SECURITY_OFFICER, JOB_WARDEN, ) + base_antags = 2 + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 6 + // I give up, just there should be enough heads with 35 players... + min_players = 35 + roundstart = TRUE + earliest_start = 0 SECONDS + weight = 0 //value was 3, we need to manually test if this works or not before allowing it normally + max_occurrences = 1 - typepath = /datum/team/revolution +/datum/antagonist/rev/head/event_trigger + remove_clumsy = TRUE + give_flash = TRUE -/datum/round_event/antagonist/team/revolution - var/datum/job/job_type = /datum/job/clown_operative - var/required_role = ROLE_REV +/datum/round_event/antagonist/solo/revolutionary + excute_round_end_reports = TRUE + end_when = 60000 /// we will end on our own when revs win + var/static/datum/team/revolution/revolution + var/static/finished = FALSE - var/datum/team/revolution/rev_team +/datum/round_event/antagonist/solo/revolutionary/setup() + . = ..() + if(!revolution) + revolution = new() -/datum/round_event/antagonist/team/revolution/candidate_roles_setup(mob/candidate) - candidate.mind.set_assigned_role(SSjob.get_job_type(job_type)) - candidate.mind.special_role = required_role +/datum/round_event/antagonist/solo/revolutionary/add_datum_to_mind(datum/mind/antag_mind) + antag_mind.add_antag_datum(antag_datum, revolution) + if(length(revolution.members)) + revolution.update_objectives() + revolution.update_rev_heads() + SSshuttle.registerHostileEnvironment(revolution) -/datum/round_event/antagonist/team/revolution/start() - // Get our nukie leader - var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) - if(!most_experienced) - most_experienced = setup_minds[1] - var/datum/antagonist/rev/head/leader = most_experienced.add_antag_datum(antag_leader_datum) - rev_team = leader.rev_team - // Setup everyone else - for(var/datum/mind/assigned_player in setup_minds) - if(assigned_player == most_experienced) - continue - add_datum_to_mind(assigned_player) - return TRUE +/datum/round_event/antagonist/solo/revolutionary/round_end_report() + var/winner = revolution.process_victory() + if(isnull(winner)) + return + finished = TRUE + end() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index 7803fb0d0d4a7..2231b09f25032 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -6,7 +6,6 @@ antag_flag = ROLE_SPY antag_datum = /datum/antagonist/spy weight = 0 - maximum_antags_global = 4 category = EVENT_CATEGORY_INVASION tags = list(TAG_CREW_ANTAG) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 018b376fa4846..653e572694213 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,15 +1,33 @@ /datum/round_event_control/antagonist/solo/traitor - name = "Traitors" - roundstart = 1.3 - earliest_start = 0 SECONDS - antag_flag = ROLE_TRAITOR + tags = list(TAG_COMBAT) + antag_datum = /datum/antagonist/traitor/infiltrator + protected_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + restricted_roles = list( + JOB_AI, + JOB_CYBORG, + ) + +/datum/round_event_control/antagonist/solo/traitor/roundstart + name = "Traitors" + antag_flag = ROLE_SYNDICATE_INFILTRATOR antag_datum = /datum/antagonist/traitor - weight = 16 - maximum_antags_global = 6 - category = EVENT_CATEGORY_INVASION - tags = list(TAG_CREW_ANTAG) + roundstart = TRUE + earliest_start = 0 SECONDS /datum/round_event_control/antagonist/solo/traitor/midround name = "Sleeper Agents (Traitors)" - roundstart = FALSE + antag_flag = ROLE_SLEEPER_AGENT + antag_datum = /datum/antagonist/traitor/infiltrator/sleeper_agent + prompted_picking = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm new file mode 100644 index 0000000000000..3a70119ed5540 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -0,0 +1,44 @@ +/datum/round_event_control/antagonist/solo/wizard + name = "Wizard" + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_MAGICAL) + typepath = /datum/round_event/antagonist/solo/wizard + antag_flag = ROLE_WIZARD + antag_datum = /datum/antagonist/wizard + restricted_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_SECURITY, + ) // Just to be sure that a wizard getting picked won't ever imply a Captain or HoS not getting drafted + maximum_antags = 1 + enemy_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + roundstart = TRUE + earliest_start = 0 SECONDS + weight = 2 + min_players = 35 + max_occurrences = 1 + +/datum/round_event_control/antagonist/solo/wizard/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) + . = ..() + if(!.) + return + if(GLOB.wizardstart.len == 0) + return FALSE + +/datum/round_event/antagonist/solo/wizard + +/datum/round_event/antagonist/solo/wizard/add_datum_to_mind(datum/mind/antag_mind) + var/mob/living/current_mob = antag_mind.current + SSjob.FreeRole(antag_mind.assigned_role.title) + var/list/items = current_mob.get_equipped_items(TRUE) + current_mob.unequip_everything() + for(var/obj/item/item as anything in items) + qdel(item) + + antag_mind.make_wizard() diff --git a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm b/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm deleted file mode 100644 index ebc38b5904f22..0000000000000 --- a/modular_bandastation/storyteller/code/event_defines/disabled_event_overrides.dm +++ /dev/null @@ -1,21 +0,0 @@ -/datum/round_event_control/slaughter - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_CHAOTIC) - weight = 0 - max_occurrences = 0 - -/datum/round_event_control/sandstorm // it's a shittier meteor wave that kills the server trying to process all the debris - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) - weight = 0 - max_occurrences = 0 - -/datum/round_event_control/sandstorm_classic // it's a shittier meteor wave that kills the server trying to process all the debris - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) - weight = 0 - max_occurrences = 0 - -/datum/round_event_control/dark_matteor - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm new file mode 100644 index 0000000000000..edb3e3551c868 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -0,0 +1,106 @@ +/datum/round_event_control/antagonist/solo/from_ghosts/nuclear_operative + name = "Nuclear Assault" + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG, TAG_EXTERNAL) + antag_flag = ROLE_OPERATIVE_MIDROUND + antag_datum = /datum/antagonist/nukeop + typepath = /datum/round_event/antagonist/solo/ghost/nuclear_operative + restricted_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_CYBORG, + JOB_DETECTIVE, + JOB_HEAD_OF_PERSONNEL, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_RESEARCH_DIRECTOR, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + base_antags = 3 + maximum_antags = 4 + enemy_roles = list( + JOB_AI, + JOB_CYBORG, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + // I give up, just there should be enough heads with 35 players... + min_players = 35 + earliest_start = 45 MINUTES + weight = 4 + max_occurrences = 1 + prompted_picking = TRUE + +/datum/round_event/antagonist/solo/ghost/nuclear_operative + excute_round_end_reports = TRUE + end_when = 60000 /// we will end on our own when revs win + var/static/datum/team/nuclear/nuke_team + var/set_leader = FALSE + var/required_role = ROLE_NUCLEAR_OPERATIVE + +/datum/round_event/antagonist/solo/ghost/nuclear_operative/add_datum_to_mind(datum/mind/antag_mind) + var/mob/living/current_mob = antag_mind.current + var/list/items = current_mob.get_equipped_items(TRUE) + current_mob.unequip_everything() + for(var/obj/item/item as anything in items) + qdel(item) + + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) + antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/nuclear_operative)) + antag_mind.special_role = ROLE_NUCLEAR_OPERATIVE + + if(!most_experienced) + most_experienced = antag_mind + + if(!set_leader) + set_leader = TRUE + var/datum/antagonist/nukeop/leader/leader_antag_datum = new() + nuke_team = leader_antag_datum.nuke_team + most_experienced.add_antag_datum(leader_antag_datum) + + if(antag_mind == most_experienced) + return + + var/datum/antagonist/nukeop/new_op = new antag_datum() + antag_mind.add_antag_datum(new_op) + +//this might be able to be kept as just calling parent +/datum/round_event/antagonist/solo/ghost/nuclear_operative/round_end_report() + var/result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_DESTROYED_NUKE + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm index a2ec235be0ef8..0ea28c8207aca 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/override.dm @@ -1,30 +1,14 @@ /datum/round_event_control/nightmare - track = EVENT_TRACK_GHOSTSET + track = EVENT_TRACK_ROLESET tags = list(TAG_COMBAT, TAG_SPOOKY) weight = 4 /datum/round_event_control/space_dragon - track = EVENT_TRACK_GHOSTSET - tags = list(TAG_COMBAT, TAG_CHAOTIC) - weight = 2 + track = EVENT_TRACK_ROLESET + tags = list(TAG_COMBAT, TAG_SPACE, TAG_EXTERNAL, TAG_ALIEN, TAG_MAGICAL) + checks_antag_cap = TRUE /datum/round_event_control/space_ninja - track = EVENT_TRACK_GHOSTSET + track = EVENT_TRACK_ROLESET tags = list(TAG_COMBAT) - weight = 4 - -/datum/round_event_control/changeling - track = EVENT_TRACK_GHOSTSET - tags = list(TAG_COMBAT, TAG_CREW_ANTAG) - min_players = 20 - weight = 6 - -/datum/round_event_control/alien_infestation - track = EVENT_TRACK_GHOSTSET - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CHAOTIC) - weight = 2 - -/datum/round_event_control/spider_infestation - track = EVENT_TRACK_GHOSTSET - tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_CHAOTIC) - weight = 2 + checks_antag_cap = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm new file mode 100644 index 0000000000000..eccc3e4944640 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -0,0 +1,102 @@ +/datum/round_event_control/antagonist/solo/from_ghosts/paradox_clone + name = "Paradox Clone" + tags = list(TAG_OUTSIDER_ANTAG, TAG_SPOOKY, TAG_TARGETED) + typepath = /datum/round_event/antagonist/solo/ghost/paradox_clone + antag_flag = ROLE_PARADOX_CLONE + track = EVENT_TRACK_MAJOR + antag_datum = /datum/antagonist/paradox_clone + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + ) + maximum_antags = 1 + required_enemies = 2 + weight = 6 + max_occurrences = 2 + prompted_picking = TRUE + +/datum/round_event/antagonist/solo/ghost/paradox_clone + var/list/possible_spawns = list() ///places the antag can spawn + var/mob/living/carbon/human/clone_victim + var/mob/living/carbon/human/new_human + +/datum/round_event/antagonist/solo/ghost/paradox_clone/setup() + possible_spawns += find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE) + if(!possible_spawns.len) + return + var/datum/round_event_control/antagonist/solo/cast_control = control + antag_count = cast_control.get_antag_amount() + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + restricted_roles = cast_control.restricted_roles + prompted_picking = cast_control.prompted_picking + var/list/candidates = cast_control.get_candidates() + + var/list/cliented_list = list() + for(var/mob/living/mob as anything in candidates) + cliented_list += mob.client + if(length(cliented_list)) + mass_adjust_antag_rep(cliented_list, 1) + + + if(prompted_picking) + candidates = SSpolling.poll_ghost_candidates( + "Would you like to be a paradox clone?", + check_jobban = ROLE_PARADOX_CLONE, + poll_time = 20 SECONDS, + alert_pic = /datum/antagonist/paradox_clone, + role_name_text = "paradox clone", + chat_text_border_icon = /datum/antagonist/paradox_clone, + ) + + var/list/weighted_candidates = return_antag_rep_weight(candidates) + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + candidate_client.prefs?.reset_antag_rep() + if(!candidate.mind) + candidate.mind = new /datum/mind(candidate.key) + + clone_victim = find_original() + new_human = duplicate_object(clone_victim, pick(possible_spawns)) + new_human.ckey = candidate_ckey + new_human.mind.special_role = antag_flag + new_human.mind.restricted_roles = restricted_roles + setup_minds += new_human.mind + selected_count++ + setup = TRUE + + +/datum/round_event/antagonist/solo/ghost/paradox_clone/add_datum_to_mind(datum/mind/antag_mind) + var/datum/antagonist/paradox_clone/new_datum = antag_mind.add_antag_datum(/datum/antagonist/paradox_clone) + new_datum.original_ref = WEAKREF(clone_victim.mind) + new_datum.setup_clone() + new /obj/item/storage/toolbox/mechanical(new_human.loc) //so they dont get stuck in maints + + message_admins("[ADMIN_LOOKUPFLW(new_human)] has been made into a Paradox Clone by the midround ruleset.") + new_human.log_message("was spawned as a Paradox Clone of [key_name(new_human)] by the midround ruleset.", LOG_GAME) + + +/** + * Trims through GLOB.player_list and finds a target + * Returns a single human victim, if none is possible then returns null. + */ +/datum/round_event/antagonist/solo/ghost/paradox_clone/proc/find_original() + var/list/possible_targets = list() + + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(!player.client || !player.mind || player.stat) + continue + if(!(player.mind.assigned_role.job_flags & JOB_CREW_MEMBER)) + continue + possible_targets += player + + if(possible_targets.len) + return pick(possible_targets) + return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm index 5e36b107d18c7..84f30ebce3e9d 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm @@ -11,8 +11,7 @@ category = EVENT_CATEGORY_ENTITIES description = "A Void Walker that drags people out of the station and into the abyss" map_flags = EVENT_SPACE_ONLY - - track = EVENT_TRACK_GHOSTSET + track = EVENT_TRACK_ROLESET /datum/round_event/ghost_role/void_walker minimum_required = 30 diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm new file mode 100644 index 0000000000000..a581c1150da38 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm @@ -0,0 +1,37 @@ +/datum/round_event_control/antagonist/solo/from_ghosts/wizard + name = "Ghost Wizard" + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_MAGICAL) + typepath = /datum/round_event/antagonist/solo/ghost/wizard + antag_flag = ROLE_WIZARD + antag_datum = /datum/antagonist/wizard + restricted_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_SECURITY, + ) // Just to be sure that a wizard getting picked won't ever imply a Captain or HoS not getting drafted + maximum_antags = 1 + enemy_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 5 + weight = 2 + min_players = 35 + max_occurrences = 1 + prompted_picking = TRUE + +/datum/round_event_control/antagonist/solo/ghost/wizard/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) + . = ..() + if(!.) + return + if(GLOB.wizardstart.len == 0) + return FALSE + +/datum/round_event/antagonist/solo/ghost/wizard + +/datum/round_event/antagonist/solo/ghost/wizard/add_datum_to_mind(datum/mind/antag_mind) + . = ..() + antag_mind.current.forceMove(pick(GLOB.wizardstart)) diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index cc6ce26307c0e..ee4367ba69c9c 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -1,55 +1,31 @@ +/datum/round_event_control/bureaucratic_error + track = EVENT_TRACK_MAJOR // if you've ever dealt with 10 mimes you understand why. + tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/error + weight = 5 + max_occurrences = 1 + head_required_power = 3 + /datum/round_event_control/earthquake track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) - eng_required_crew = 2 - -/datum/round_event_control/blob - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_CHAOTIC) - weight = 10 - min_players = 50 + eng_required_power = 2 /datum/round_event_control/meteor_wave track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE, TAG_CHAOTIC) - weight = 10 - max_occurrences = 1 - eng_required_crew = 3 - -/datum/round_event_control/meteor_wave/meaty - weight = 15 - max_occurrences = 1 - -/datum/round_event_control/meteor_wave/threatening - weight = 3 - -/datum/round_event_control/meteor_wave/catastrophic - weight = 0 - -/datum/round_event_control/radiation_storm - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL) - med_required_crew = 3 - -/datum/round_event_control/wormholes - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL) - -/datum/round_event_control/immovable_rod - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE) - weight = 20 - eng_required_crew = 2 + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE) + event_group = /datum/event_group/meteors + eng_required_power = 3 /datum/round_event_control/anomaly/anomaly_vortex track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) - rnd_required_crew = 3 + rnd_required_power = 3 /datum/round_event_control/anomaly/anomaly_pyro track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) - rnd_required_crew = 3 + rnd_required_power = 3 /datum/round_event_control/revenant min_players = 20 @@ -58,11 +34,13 @@ /datum/round_event_control/abductor track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_CHAOTIC) + tags = list(TAG_TARGETED, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) + checks_antag_cap = TRUE /datum/round_event_control/fugitives track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT) + checks_antag_cap = TRUE /datum/round_event_control/voidwalker track = EVENT_TRACK_MAJOR @@ -70,14 +48,56 @@ /datum/round_event_control/pirates track = EVENT_TRACK_MAJOR - tags = list(TAG_COMMUNAL, TAG_COMBAT) + tags = list(TAG_COMBAT, TAG_COMMUNAL) + checks_antag_cap = TRUE /datum/round_event_control/operative - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_CHAOTIC, TAG_CREW_ANTAG) + track = EVENT_TRACK_MAJOR //this is a safe guard and does not trigger normally(technically it can but not really) so no tags + checks_antag_cap = TRUE /datum/round_event_control/wizard/round_start track = EVENT_TRACK_MAJOR weight = 5 - tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) + tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE) roundstart = TRUE + +/datum/round_event_control/changeling + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPACE, TAG_EXTERNAL, TAG_ALIEN) + event_group = /datum/event_group/comms + checks_antag_cap = TRUE + +/datum/round_event_control/slaughter + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) + checks_antag_cap = TRUE + +/datum/round_event_control/portal_storm_syndicate + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT) + event_group = /datum/event_group/guests + +/datum/round_event_control/spacevine + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_ALIEN) + checks_antag_cap = TRUE + event_group = /datum/event_group/guests + med_required_power = 2 + +/datum/round_event_control/morph + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) + checks_antag_cap = TRUE + +/datum/round_event_control/nightmare + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) + checks_antag_cap = TRUE + +/datum/round_event_control/revenant + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) + checks_antag_cap = TRUE + +/datum/round_event_control/portal_storm_monkey + track = EVENT_TRACK_MAJOR diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index d6994e5264b41..0689144185b89 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -1,61 +1,92 @@ /datum/round_event_control/brand_intelligence - tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL, TAG_CHAOTIC) - head_required_crew = 1 + tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL) + event_group = /datum/event_group/bsod + head_required_power = 1 /datum/round_event_control/carp_migration - tags = list(TAG_COMMUNAL) + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_SPACE, TAG_EXTERNAL, TAG_ALIEN) + max_occurrences = 3 + event_group = /datum/event_group/guests /datum/round_event_control/communications_blackout tags = list(TAG_COMMUNAL, TAG_SPOOKY) + eng_required_power = 1 /datum/round_event_control/ion_storm - tags = list(TAG_TARGETED) + tags = list(TAG_TARGETED, TAG_ALIEN) + event_group = /datum/event_group/bsod /datum/round_event_control/processor_overload + max_occurrences = 2 tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/comms /datum/round_event_control/radiation_leak tags = list(TAG_COMMUNAL) - eng_required_crew = 2 - med_required_crew = 1 + max_occurrences = 2 + eng_required_power = 2 + med_required_power = 1 + +/datum/round_event_control/radiation_storm + weight = 5 + max_occurrences = 1 + tags = list(TAG_COMMUNAL) /datum/round_event_control/supermatter_surge - tags = list(TAG_TARGETED) - eng_required_crew = 2 + tags = list(TAG_DESTRUCTIVE, TAG_COMMUNAL) + event_group = /datum/event_group/error + eng_required_power = 2 /datum/round_event_control/stray_meteor tags = list(TAG_DESTRUCTIVE, TAG_SPACE) - weight = 25 - eng_required_crew = 2 + event_group = /datum/event_group/debris + eng_required_power = 2 /datum/round_event_control/shuttle_catastrophe tags = list(TAG_COMMUNAL) - head_required_crew = 2 + head_required_power = 1 + +/datum/round_event_control/shuttle_insurance + tags = list(TAG_COMMUNAL) /datum/round_event_control/vent_clog tags = list(TAG_COMMUNAL) - head_required_crew = 1 /datum/round_event_control/anomaly weight = 10 // Lower from original 15 because it KEEPS SPAWNING THEM - tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE) - rnd_required_crew = 1 - -/datum/round_event_control/spacevine - tags = list(TAG_COMMUNAL, TAG_COMBAT, TAG_CHAOTIC) - med_required_crew = 2 - -/datum/round_event_control/portal_storm_syndicate - tags = list(TAG_COMBAT, TAG_CHAOTIC) + tags = list(TAG_DESTRUCTIVE, TAG_MAGICAL) + event_group = /datum/event_group/anomalies + rnd_required_power = 1 /datum/round_event_control/portal_storm_narsie - tags = list(TAG_COMBAT, TAG_CHAOTIC) + tags = list(TAG_COMBAT) /datum/round_event_control/obsessed - tags = list(TAG_TARGETED) + weight = 0 // use storyteller variants instead -/datum/round_event_control/bureaucratic_error - tags = list(TAG_COMMUNAL) - weight = 5 - max_occurrences = 1 - head_required_crew = 3 +/datum/round_event_control/gravity_generator_blackout + tags = list(TAG_COMMUNAL, TAG_SPACE) + event_group = /datum/event_group/bsod + weight = 8 + max_occurrences = 2 + eng_required_power = 1 + +/datum/round_event_control/grey_tide + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) + event_group = /datum/event_group/meteors + +/datum/round_event_control/heart_attack + tags = list(TAG_TARGETED, TAG_MAGICAL) + med_required_power = 1 + +/datum/round_event_control/sandstorm + tags = list(TAG_DESTRUCTIVE, TAG_EXTERNAL) + event_group = /datum/event_group/debris + +/datum/round_event_control/wormholes + tags = list(TAG_COMMUNAL, TAG_MAGICAL) + event_group = /datum/event_group/anomalies + +/datum/round_event_control/immovable_rod + tags = list(TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_MAGICAL) + eng_required_power = 2 diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index d188d3ac728c2..41903991d3fc2 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -1,13 +1,14 @@ /datum/round_event_control/space_dust track = EVENT_TRACK_MUNDANE weight = 10 - tags = list(TAG_SPACE) + max_occurrences = 10 + tags = list(TAG_DESTRUCTIVE, TAG_SPACE) /datum/round_event_control/camera_failure track = EVENT_TRACK_MUNDANE weight = 10 tags = list(TAG_COMMUNAL, TAG_SPOOKY) - eng_required_crew = 1 + eng_required_power = 1 /datum/round_event_control/aurora_caelus track = EVENT_TRACK_MUNDANE @@ -15,27 +16,24 @@ /datum/round_event_control/brain_trauma track = EVENT_TRACK_MUNDANE - tags = list(TAG_TARGETED) - med_required_crew = 1 - -/datum/round_event_control/heart_attack - track = EVENT_TRACK_MUNDANE - tags = list(TAG_TARGETED) - med_required_crew = 2 + tags = list(TAG_TARGETED, TAG_MAGICAL) //im putting magical on this because I think this can give the magic brain traumas + med_required_power = 1 /datum/round_event_control/grid_check - track = EVENT_TRACK_MUNDANE + track = EVENT_TRACK_MODERATE tags = list(TAG_COMMUNAL, TAG_SPOOKY) /datum/round_event_control/disease_outbreak + max_occurrences = 2 track = EVENT_TRACK_MUNDANE - tags = list(TAG_TARGETED) - med_required_crew = 1 + tags = list(TAG_TARGETED, TAG_COMMUNAL, TAG_EXTERNAL, TAG_ALIEN, TAG_MAGICAL) + med_required_power = 1 /datum/round_event_control/electrical_storm track = EVENT_TRACK_MUNDANE tags = list(TAG_SPOOKY) - eng_required_crew = 1 + event_group = /datum/event_group/error + eng_required_power = 1 /datum/round_event_control/fake_virus track = EVENT_TRACK_MUNDANE @@ -44,6 +42,7 @@ /datum/round_event_control/falsealarm track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/error /datum/round_event_control/market_crash track = EVENT_TRACK_MUNDANE @@ -51,52 +50,33 @@ /datum/round_event_control/mice_migration track = EVENT_TRACK_MUNDANE - tags = list(TAG_DESTRUCTIVE) + tags = list(TAG_DESTRUCTIVE, TAG_ALIEN) //not really alien but rat lords kind of are + event_group = /datum/event_group/guests /datum/round_event_control/wisdomcow track = EVENT_TRACK_MUNDANE - tags = list(TAG_COMMUNAL, TAG_POSITIVE) + tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_MAGICAL) + event_group = /datum/event_group/guests /datum/round_event_control/shuttle_loan - var/list/run_situations = list() - track = EVENT_TRACK_MUNDANE - tags = list(TAG_COMMUNAL) - -/datum/round_event_control/mass_hallucination track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL) /datum/round_event_control/stray_cargo track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL) - eng_required_crew = 1 - -/datum/round_event_control/grey_tide - track = EVENT_TRACK_MUNDANE - tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) - -/datum/round_event_control/gravity_generator_blackout - track = EVENT_TRACK_MUNDANE - tags = list(TAG_COMMUNAL, TAG_SPACE) - eng_required_crew = 1 - -/datum/round_event_control/shuttle_insurance - track = EVENT_TRACK_MUNDANE - tags = list(TAG_COMMUNAL) + eng_required_power = 1 /datum/round_event_control/tram_malfunction track = EVENT_TRACK_MUNDANE - tags = list(TAG_TARGETED, TAG_SPOOKY) - eng_required_crew = 1 + tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/error + eng_required_power = 1 /datum/round_event_control/bitrunning_glitch track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED) -/datum/round_event_control/sentience - track = EVENT_TRACK_MUNDANE - tags = list(TAG_TARGETED, TAG_POSITIVE) - /datum/round_event_control/easter track = EVENT_TRACK_MUNDANE roundstart = TRUE @@ -126,20 +106,28 @@ max_occurrences = 0 tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_SPOOKY) +/datum/round_event_control/mass_hallucination + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_MAGICAL) + +/datum/round_event_control/sentience + track = EVENT_TRACK_MUNDANE + tags = list(TAG_COMMUNAL, TAG_SPOOKY, TAG_MAGICAL) + //SCRUBBER OVERRIDES /datum/round_event_control/scrubber_overflow - track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/scrubber_overflow /datum/round_event_control/scrubber_overflow/threatening weight = 0 - med_required_crew = 1 + med_required_power = 1 /datum/round_event_control/scrubber_overflow/catastrophic weight = 0 - med_required_crew = 1 - eng_required_crew = 1 + med_required_power = 1 + eng_required_power = 1 /datum/round_event_control/scrubber_overflow/every_vent weight = 0 - head_required_crew = 1 + head_required_power = 1 diff --git a/modular_bandastation/storyteller/code/event_defines/override_events.dm b/modular_bandastation/storyteller/code/event_defines/override_events.dm index 96a5f126fda4d..451e96d5ac9d4 100644 --- a/modular_bandastation/storyteller/code/event_defines/override_events.dm +++ b/modular_bandastation/storyteller/code/event_defines/override_events.dm @@ -41,9 +41,3 @@ /datum/reagent/water/salt, /datum/reagent/yuck, ) - -/datum/round_event_control/wizard/round_start - track = EVENT_TRACK_CREWSET - weight = 1 - tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE, TAG_CHAOTIC) - roundstart = TRUE diff --git a/modular_bandastation/storyteller/code/events/group/_event_group.dm b/modular_bandastation/storyteller/code/events/group/_event_group.dm new file mode 100644 index 0000000000000..7872629f42781 --- /dev/null +++ b/modular_bandastation/storyteller/code/events/group/_event_group.dm @@ -0,0 +1,66 @@ +/// An associative list of singleton event groups, in the format of [type] = instance. +GLOBAL_LIST_INIT_TYPED(event_groups, /datum/event_group, initialize_event_groups()) + +/datum/event_group + /// The name of the event group. + var/name + /// If set, this will limit the amount of times events in this group can run. + var/max_occurrences + /// If set, whenever an event in this group runs, no other events in this group + /// will be able to run for the specified amount of time. + /// Can be either a number for a static cooldown, or a list containing 2 numbers, + /// for a random cooldown between the given numbers, which will bias towards the upper bound + /// the more the event group has occured. + var/cooldown_time + /// The amount of time events in this group have ran. + VAR_FINAL/occurrences = 0 + /// If [cooldown_time] is set, this will be set to the minimum world.time where the next event in this group can run. + COOLDOWN_DECLARE(event_cooldown) + +/datum/event_group/Destroy(force) + if(!force && GLOB.event_groups[type] == src) + stack_trace("Something is trying to destroy the event group ([type]), which is a singleton! This is super duper bad!") + return QDEL_HINT_LETMELIVE + return ..() + +/datum/event_group/proc/get_cooldown_time() as num + if(isnum(cooldown_time)) + return cooldown_time + var/min_cooldown = cooldown_time[1] + var/max_cooldown = cooldown_time[2] + + if (max_occurrences) + var/occurrence_ratio = min(1, occurrences / max_occurrences) + return min_cooldown + (max_cooldown - min_cooldown) * occurrence_ratio + else + // If max_occurrences is not set, use a simple exponential increase + return min_cooldown + (max_cooldown - min_cooldown) * (occurrences / (occurrences + 1)) + +/datum/event_group/proc/can_run() as num + . = TRUE + if(cooldown_time && !COOLDOWN_FINISHED(src, event_cooldown)) + return FALSE + if(max_occurrences && occurrences >= max_occurrences) + return FALSE + +/datum/event_group/proc/on_run(datum/round_event_control/running_event) + if(cooldown_time) + var/cooldown = get_cooldown_time() + COOLDOWN_START(src, event_cooldown, cooldown) + for(var/datum/scheduled_event/scheduled_event in SSgamemode.scheduled_events) + if(scheduled_event.event == running_event || scheduled_event.event?.event_group != type || !scheduled_event.start_time || (scheduled_event.start_time > src.event_cooldown) || (scheduled_event.start_time <= world.time)) + continue + var/old_start_time = scheduled_event.start_time + scheduled_event.start_time += cooldown + message_admins("Scheduled event [scheduled_event.event.name] start time pushed back by [DisplayTimeText(cooldown)] ([DisplayTimeText(COOLDOWN_TIMELEFT(scheduled_event, start_time))] from now) due to event group [name] running.") + log_storyteller("Scheduled event [scheduled_event.event.name] start time pushed back by [DisplayTimeText(cooldown)] ([old_start_time] -> [scheduled_event.start_time]) due to event group [name] running.", list("group" = "[name]", "cooldown" = cooldown)) + occurrences++ + SSblackbox.record_feedback("tally", "event_group_ran", 1, "[name]") + +/proc/initialize_event_groups() as /list + RETURN_TYPE(/list) + . = list() + for(var/datum/event_group/event_group as anything in subtypesof(/datum/event_group)) + if(!event_group::name) + continue + .[event_group] = new event_group diff --git a/modular_bandastation/storyteller/code/events/group/groups.dm b/modular_bandastation/storyteller/code/events/group/groups.dm new file mode 100644 index 0000000000000..a6952f8e0e0ec --- /dev/null +++ b/modular_bandastation/storyteller/code/events/group/groups.dm @@ -0,0 +1,44 @@ +/datum/event_group/anomalies + name = "Anomalies" + cooldown_time = list(10 MINUTES, 25 MINUTES) + +/datum/event_group/comms + name = "Communications" + cooldown_time = list(15 MINUTES, 45 MINUTES) + max_occurrences = 3 + +/// Represents small-scale technical difficulties - might annoy some people, but not everyone will notice or be affected, +/// If the event directly affects the entire crew, use [/datum/event_group/bsod]. +/// If the main effect involves telecommunications, use [/datum/event_group/comms]. +/datum/event_group/error + name = "Technical Difficulties (small scale)" + cooldown_time = list(2.5 MINUTES, 7.5 MINUTES) + +/// Represents large-scale technical difficulties - stuff that affects the whole crew. +/// If the main effect involves telecommunications, use [/datum/event_group/comms]. +/datum/event_group/bsod + name = "Technical Difficulties (large scale)" + cooldown_time = list(15 MINUTES, 25 MINUTES) + max_occurrences = 5 + +/datum/event_group/debris + name = "Space Debris" + cooldown_time = list(2 MINUTES, 10 MINUTES) + +/datum/event_group/meteors + name = "Meteors" + cooldown_time = 20 MINUTES + max_occurrences = 3 + +// needs a better name - this is basically for events focused around spawning some sort of NPCs, +// i.e vines, wisdom cow, carp, etc. +/datum/event_group/guests + name = "Guests" + cooldown_time = list(7.5 MINUTES, 20 MINUTES) + +// These event groups are somewhat specific to a single event, +// but we're using event groups to share cooldowns/occurrences between SSevents and storytellers +/datum/event_group/scrubber_overflow + name = "Scrubber Overflows" + cooldown_time = list(25 MINUTES, 45 MINUTES) + max_occurrences = 2 diff --git a/modular_bandastation/storyteller/code/events/object/anomalies_dimensional.dm b/modular_bandastation/storyteller/code/events/object/anomalies_dimensional.dm new file mode 100644 index 0000000000000..01cb702613c19 --- /dev/null +++ b/modular_bandastation/storyteller/code/events/object/anomalies_dimensional.dm @@ -0,0 +1,30 @@ +/obj/effect/anomaly/dimensional + /// How many remaining times this anomaly will relocate, before its detonation. + var/relocations_left + +/obj/effect/anomaly/dimensional/Initialize(mapload, new_lifespan, drops_core) + . = ..() + if(!isnum(relocations_left)) + relocations_left = rand(3, 5) + +/obj/effect/anomaly/dimensional/detonate() + . = ..() + if(!theme) + return + visible_message(span_bolddanger("[src] explodes, distorting the space around it in surreal ways!")) + var/detonate_range = range + rand(5, 7) + var/list/turf/target_turfs = spiral_range_turfs(detonate_range, src) + for(var/turf/target in target_turfs) + if(prob(15) || QDELING(target)) // the prob is so it looks more erratic + continue + theme.apply_theme(target) + +/obj/effect/anomaly/dimensional/relocate() + if(relocations_left == -1) + return ..() + if(relocations_left < 1) + detonate() + qdel(src) + return + . = ..() + relocations_left -= 1 diff --git a/modular_bandastation/storyteller/code/events/summon_wizard.dm b/modular_bandastation/storyteller/code/events/summon_wizard.dm new file mode 100644 index 0000000000000..23686f45a312c --- /dev/null +++ b/modular_bandastation/storyteller/code/events/summon_wizard.dm @@ -0,0 +1,31 @@ +/datum/round_event_control/summon_wizard_event + name = "Summon Wizard Event" + typepath = /datum/round_event/summon_wizard_event + weight = 0 + category = EVENT_CATEGORY_WIZARD + description = "Trigger a random wizard event that meets its normal conditions." + track = EVENT_TRACK_MAJOR + tags = list(TAG_SPOOKY, TAG_MAGICAL) + allowed_storytellers = /datum/storyteller/mystic + +/datum/round_event/summon_wizard_event + ///the event we have actually chosen to run + var/datum/round_event_control/triggered_event + +/datum/round_event/summon_wizard_event/setup() + var/list/possible_events = list() + var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + for(var/datum/round_event_control/possible_event as anything in SSevents.control) + if(!possible_event.wizardevent || !possible_event.can_spawn_event(player_count, allow_magic = TRUE)) + continue + possible_events[possible_event] = possible_event.weight + + if(!length(possible_events)) + kill() + return + + triggered_event = pick_weight(possible_events) + setup = TRUE + +/datum/round_event/summon_wizard_event/start() + triggered_event.run_event() diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 9ea9d808250d2..9815fa04097c7 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -1,18 +1,25 @@ #define INIT_ORDER_GAMEMODE 70 +///how many storytellers can be voted for along with always_votable ones +#define DEFAULT_STORYTELLER_VOTE_OPTIONS 4 +///amount of players we can have before no longer running votes for storyteller +#define MAX_POP_FOR_STORYTELLER_VOTE 25 +///the duration into the round for which roundstart events are still valid to run +#define ROUNDSTART_VALID_TIMEFRAME 3 MINUTES SUBSYSTEM_DEF(gamemode) name = "Gamemode" init_order = INIT_ORDER_GAMEMODE runlevels = RUNLEVEL_GAME flags = SS_BACKGROUND | SS_KEEP_TIMING + priority = 20 wait = 2 SECONDS /// List of our event tracks for fast access during for loops. var/list/event_tracks = EVENT_TRACKS - /// Our storyteller. He progresses our trackboards and picks out events - var/datum/storyteller/storyteller - /// Result of the storyteller vote. Defaults to the guide. - var/voted_storyteller = /datum/storyteller/default + /// Our storyteller. They progresses our trackboards and picks out events + var/datum/storyteller/current_storyteller + /// Result of the storyteller vote/pick. Defaults to the guide. + var/selected_storyteller = /datum/storyteller/default /// List of all the storytellers. Populated at init. Associative from type var/list/storytellers = list() /// Next process for our storyteller. The wait time is STORYTELLER_WAIT_TIME @@ -22,24 +29,24 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_MUNDANE = 0, EVENT_TRACK_MODERATE = 0, EVENT_TRACK_MAJOR = 0, - EVENT_TRACK_CREWSET = 0, - EVENT_TRACK_GHOSTSET = 0 + EVENT_TRACK_ROLESET = 0, + EVENT_TRACK_OBJECTIVES = 0 ) /// Last point amount gained of each track. Those are recorded for purposes of estimating how long until next event. var/list/last_point_gains = list( EVENT_TRACK_MUNDANE = 0, EVENT_TRACK_MODERATE = 0, EVENT_TRACK_MAJOR = 0, - EVENT_TRACK_CREWSET = 0, - EVENT_TRACK_GHOSTSET = 0 + EVENT_TRACK_ROLESET = 0, + EVENT_TRACK_OBJECTIVES = 0 ) /// Point thresholds at which the events are supposed to be rolled, it is also the base cost for events. var/list/point_thresholds = list( - EVENT_TRACK_MUNDANE = 100, - EVENT_TRACK_MODERATE = 100, - EVENT_TRACK_MAJOR = 100, - EVENT_TRACK_CREWSET = 100, - EVENT_TRACK_GHOSTSET = 100 + EVENT_TRACK_MUNDANE = MUNDANE_POINT_THRESHOLD, + EVENT_TRACK_MODERATE = MODERATE_POINT_THRESHOLD, + EVENT_TRACK_MAJOR = MAJOR_POINT_THRESHOLD, + EVENT_TRACK_ROLESET = ROLESET_POINT_THRESHOLD, + EVENT_TRACK_OBJECTIVES = OBJECTIVES_POINT_THRESHOLD ) /// Minimum population thresholds for the tracks to fire off events. @@ -47,8 +54,8 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_MUNDANE = MUNDANE_MIN_POP, EVENT_TRACK_MODERATE = MODERATE_MIN_POP, EVENT_TRACK_MAJOR = MAJOR_MIN_POP, - EVENT_TRACK_CREWSET = CREWSET_MIN_POP, - EVENT_TRACK_GHOSTSET = GHOSTSET_MIN_POP + EVENT_TRACK_ROLESET = ROLESET_MIN_POP, + EVENT_TRACK_OBJECTIVES = OBJECTIVES_MIN_POP ) /// Configurable multipliers for point gain over time. @@ -56,16 +63,16 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_MUNDANE = 1, EVENT_TRACK_MODERATE = 1, EVENT_TRACK_MAJOR = 1, - EVENT_TRACK_CREWSET = 1, - EVENT_TRACK_GHOSTSET = 1 + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 ) /// Configurable multipliers for roundstart points. var/list/roundstart_point_multipliers = list( EVENT_TRACK_MUNDANE = 1, EVENT_TRACK_MODERATE = 1, EVENT_TRACK_MAJOR = 1, - EVENT_TRACK_CREWSET = 1, - EVENT_TRACK_GHOSTSET = 1 + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 ) /// Whether we allow pop scaling. This is configured by config, or the storyteller UI var/allow_pop_scaling = TRUE @@ -75,8 +82,8 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_MUNDANE = MUNDANE_POP_SCALE_THRESHOLD, EVENT_TRACK_MODERATE = MODERATE_POP_SCALE_THRESHOLD, EVENT_TRACK_MAJOR = MAJOR_POP_SCALE_THRESHOLD, - EVENT_TRACK_CREWSET = CREWSET_POP_SCALE_THRESHOLD, - EVENT_TRACK_GHOSTSET = GHOSTSET_POP_SCALE_THRESHOLD + EVENT_TRACK_ROLESET = ROLESET_POP_SCALE_THRESHOLD, + EVENT_TRACK_OBJECTIVES = OBJECTIVES_POP_SCALE_THRESHOLD ) /// Associative list of pop scale penalties. @@ -84,8 +91,17 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_MUNDANE = MUNDANE_POP_SCALE_PENALTY, EVENT_TRACK_MODERATE = MODERATE_POP_SCALE_PENALTY, EVENT_TRACK_MAJOR = MAJOR_POP_SCALE_PENALTY, - EVENT_TRACK_CREWSET = CREWSET_POP_SCALE_PENALTY, - EVENT_TRACK_GHOSTSET = GHOSTSET_POP_SCALE_PENALTY + EVENT_TRACK_ROLESET = ROLESET_POP_SCALE_PENALTY, + EVENT_TRACK_OBJECTIVES = OBJECTIVES_POP_SCALE_PENALTY + ) + + /// Associative list of active multipliers from pop scale penalty. + var/list/current_pop_scale_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1, ) @@ -101,13 +117,11 @@ SUBSYSTEM_DEF(gamemode) var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences. var/list/running = list() //list of all existing /datum/round_event - var/list/currentrun = list() + var/list/round_end_data = list() //list of all reports that need to add round end reports /// List of all uncategorized events, because they were wizard or holiday events var/list/uncategorized = list() - var/list/holidays //List of all holidays occuring today or null if no holidays - /// Event frequency multiplier, it exists because wizard, eugh. var/event_frequency_multiplier = 1 @@ -124,19 +138,34 @@ SUBSYSTEM_DEF(gamemode) /// Ready players for roundstart events. var/ready_players = 0 var/active_players = 0 + var/sec_crew = 0 var/head_crew = 0 var/eng_crew = 0 - var/sec_crew = 0 var/med_crew = 0 var/rnd_crew = 0 + var/current_head_power = 0 + var/current_eng_power = 0 + var/current_med_power = 0 + var/current_rnd_power = 0 + + /// Is storyteller secret or not + var/secret_storyteller = FALSE - var/wizardmode = FALSE + /// List of new player minds we currently want to give our roundstart antag to + var/list/roundstart_antag_minds = list() - var/storyteller_voted = FALSE - var/roundstart_secs = 0 + var/wizardmode = FALSE //refactor this into just being a unique storyteller + + /// What is our currently desired/selected roundstart event + var/datum/round_event_control/antagonist/solo/current_roundstart_event + var/list/last_round_events = list() + /// Has a roundstart event been run + var/ran_roundstart = FALSE + /// Are we able to run roundstart events + var/can_run_roundstart = TRUE + var/list/triggered_round_events = list() /datum/controller/subsystem/gamemode/Initialize(time, zlevel) - . = ..() // Populate event pools for(var/track in event_tracks) event_pools[track] = list() @@ -145,12 +174,15 @@ SUBSYSTEM_DEF(gamemode) for(var/type in subtypesof(/datum/storyteller)) storytellers[type] = new type() - for(var/type in typesof(/datum/round_event_control)) - var/datum/round_event_control/event = new type() - if(!event.typepath || !event.name || !event.valid_for_map()) - continue //don't want this one! leave it for the garbage collector + for(var/datum/round_event_control/event_type as anything in typesof(/datum/round_event_control)) + if(!event_type::typepath || !event_type::name) + continue + + var/datum/round_event_control/event = new event_type + if(!event.valid_for_map()) + qdel(event) + continue // event isn't good for this map no point in trying to add it to the list control += event //add it to the list of all events (controls) - getHoliday() load_config_vars() load_event_config_vars() @@ -161,12 +193,40 @@ SUBSYSTEM_DEF(gamemode) uncategorized += event continue event_pools[event.track] += event //Add it to the categorized event pools - return SS_INIT_SUCCESS + load_roundstart_data() + if(CONFIG_GET(flag/disable_storyteller)) // we're just gonna disable firing but still initialize, so we don't have any weird runtimes + flags |= SS_NO_FIRE + return SS_INIT_NO_NEED + return SS_INIT_SUCCESS /datum/controller/subsystem/gamemode/fire(resumed = FALSE) - if(!resumed) - src.currentrun = running.Copy() + if(SSticker.round_start_time && (world.time - SSticker.round_start_time) >= ROUNDSTART_VALID_TIMEFRAME) + can_run_roundstart = FALSE + else if(current_roundstart_event && length(current_roundstart_event.preferred_events)) //note that this implementation is made for preferred_events being other roundstart events + var/list/preferred_copy = current_roundstart_event.preferred_events.Copy() + var/datum/round_event_control/selected_event = pick_weight(preferred_copy) + var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + if(ispath(selected_event)) //get the instances if we dont have them + current_roundstart_event.preferred_events = list() + for(var/datum/round_event_control/e_control as anything in preferred_copy) + current_roundstart_event.preferred_events[new e_control] = preferred_copy[e_control] + preferred_copy = current_roundstart_event.preferred_events.Copy() + selected_event = null + else if(!selected_event.can_spawn_event(player_count)) + preferred_copy -= selected_event + selected_event = null + + var/sanity = 0 + while(!selected_event && length(preferred_copy) && sanity < 100) + sanity++ + selected_event = pick_weight(preferred_copy) + if(!selected_event.can_spawn_event(player_count)) + preferred_copy -= selected_event + selected_event = null + + if(selected_event) + current_storyteller.try_buy_event(selected_event) ///Handle scheduled events for(var/datum/scheduled_event/sch_event in scheduled_events) @@ -175,126 +235,104 @@ SUBSYSTEM_DEF(gamemode) else if(!sch_event.alerted_admins && world.time >= sch_event.start_time - 1 MINUTES) ///Alert admins 1 minute before running and allow them to cancel or refund the event, once again. sch_event.alerted_admins = TRUE - message_admins("Scheduled Event: [sch_event.event] will run in [(sch_event.start_time - world.time) / 10] seconds. (CANCEL) (REFUND)") + message_admins("Scheduled Event: [sch_event.event] will run in [(sch_event.start_time - world.time) / 10] seconds. (CANCEL) (REFUND)") - if(!halted_storyteller && next_storyteller_process <= world.time && storyteller) - // We update crew information here to adjust population scalling and event thresholds for the storyteller. + if(!halted_storyteller && next_storyteller_process <= world.time && current_storyteller) + // We update crew information here to adjust population scalling and event thresholds for the storyteller. update_crew_infos() next_storyteller_process = world.time + STORYTELLER_WAIT_TIME - storyteller.process(STORYTELLER_WAIT_TIME * 0.1) - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while(currentrun.len) - var/datum/thing = currentrun[currentrun.len] - currentrun.len-- - if(thing) - thing.process(wait * 0.1) - else - running.Remove(thing) - if (MC_TICK_CHECK) - return - -/datum/controller/subsystem/gamemode/proc/storyteller_desc(storyteller_name) - for(var/storyteller_type in storytellers) - var/datum/storyteller/storyboy = storytellers[storyteller_type] - if(storyboy.name != storyteller_name) - continue - return storyboy.desc + current_storyteller.process(STORYTELLER_WAIT_TIME * 0.1) /// Gets the number of antagonists the antagonist injection events will stop rolling after. /datum/controller/subsystem/gamemode/proc/get_antag_cap() - if(isnull(storyteller)) - return 0 - if(!storyteller.antag_divisor) - return 0 - //var/max_antags = sec_crew * storyteller.max_sec_mult - //var/min_antags = min(sec_crew, ANTAG_CAP_FLAT) - //var/calculated_cap = (get_correct_popcount() / storyteller.antag_divisor) + sec_crew - //var/clamped_cap = clamp(calculated_cap, min_antags, max_antags) - var/result = sec_crew // round(clamped_cap) - return result + var/total_number = get_correct_popcount() + (sec_crew * 2) + var/cap = FLOOR((total_number / ANTAG_CAP_DENOMINATOR), 1) + ANTAG_CAP_FLAT + return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() - var/a_count = 0 - if(SSticker.HasRoundStarted()) - a_count = length(GLOB.current_living_antags) - else - for(var/mob/player_mob as anything in GLOB.player_list) - if(!player_mob.client) - continue - if(player_mob.stat) - continue - if(player_mob.client.is_afk()) - continue - if(!ishuman(player_mob)) - continue - if(player_mob.mind?.special_role) - a_count++ - return a_count + . = 0 + var/list/already_counted = list() // Never count the same mind twice + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(QDELETED(antag) || QDELETED(antag.owner) || already_counted[antag.owner]) + continue + if(!antag.count_against_dynamic_roll_chance || (antag.antag_flags & (FLAG_FAKE_ANTAG | FLAG_ANTAG_CAP_IGNORE))) + continue + if(antag.antag_flags & FLAG_ANTAG_CAP_TEAM) + var/datum/team/antag_team = antag.get_team() + if(antag_team) + if(already_counted[antag_team]) + continue + already_counted[antag_team] = TRUE + var/mob/antag_mob = antag.owner.current + if(QDELETED(antag_mob) || !antag_mob.key || antag_mob.stat == DEAD || antag_mob.client?.is_afk()) + continue + already_counted[antag.owner] = TRUE + .++ /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() - return get_antag_cap() > get_antag_count() + return (get_antag_cap() > get_antag_count()) /// Gets candidates for antagonist roles. - -/// Todo: Split into get_candidates and post_get_candidates -/datum/controller/subsystem/gamemode/proc/get_candidates( - special_role_flag, - pick_observers, - pick_roundstart_players, - required_time, - inherit_required_time = TRUE, - no_antags = TRUE, - list/restricted_roles, - ) - - +/datum/controller/subsystem/gamemode/proc/get_candidates(be_special, job_ban, observers, ready_newplayers, living_players, required_time, inherit_required_time = TRUE, midround_antag_pref, no_antags = TRUE, list/restricted_roles, list/required_roles) var/list/candidates = list() var/list/candidate_candidates = list() //lol - if(pick_roundstart_players) - for(var/mob/dead/new_player/player in GLOB.new_player_list) - if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) + + for(var/mob/player as anything in GLOB.player_list) + if(QDELETED(player) || player.mind?.picking) + continue + if(ready_newplayers && isnewplayer(player)) + var/mob/dead/new_player/new_player = player + if(new_player.ready == PLAYER_READY_TO_PLAY && new_player.mind && new_player.check_preferences()) candidate_candidates += player - else if(pick_observers) - candidate_candidates += GLOB.dead_mob_list - else - for(var/datum/record/locked/manifest_log as anything in GLOB.manifest.locked) - var/datum/mind/player_mind = manifest_log.mind_ref.resolve() - var/mob/living/player = player_mind.current - if(isnull(player)) + else if(observers && isobserver(player)) + candidate_candidates += player + else if(living_players && isliving(player)) + if(!ishuman(player) && !isAI(player)) + continue + // I split these checks up to make the code more readable + var/is_on_station = is_station_level(player.z) + if(!is_on_station && !is_late_arrival(player)) continue candidate_candidates += player - for(var/mob/candidate as anything in candidate_candidates) - if(QDELETED(candidate) || !candidate.key || !candidate.client || !candidate.mind) + if(QDELETED(candidate) || !candidate.key || !candidate.client || (!observers && !candidate.mind)) continue - if(no_antags && candidate.mind.special_role) - continue - if(restricted_roles && (candidate.mind.assigned_role.title in restricted_roles)) - continue - if(special_role_flag) - if(!(candidate.client.prefs) || !(special_role_flag in candidate.client.prefs.be_special)) + if(!observers) + if(!ready_players && !isliving(candidate)) + continue + if(no_antags && !isnull(candidate.mind.antag_datums)) + var/real = FALSE + for(var/datum/antagonist/antag_datum as anything in candidate.mind.antag_datums) + if(antag_datum.count_against_dynamic_roll_chance && !(antag_datum.antag_flags & FLAG_FAKE_ANTAG)) + real = TRUE + break + if(real) + continue + if(restricted_roles && (candidate.mind.assigned_role.title in restricted_roles)) + continue + if(length(required_roles) && !(candidate.mind.assigned_role.title in required_roles)) + continue + + if(be_special) + if(!(candidate.client.prefs) || !(be_special in candidate.client.prefs.be_special)) continue var/time_to_check if(required_time) time_to_check = required_time - else if (inherit_required_time) - time_to_check = GLOB.special_roles[special_role_flag] + else if(inherit_required_time) + time_to_check = GLOB.special_roles[be_special] if(time_to_check && candidate.client.get_remaining_days(time_to_check) > 0) continue - if(special_role_flag && is_banned_from(candidate.ckey, list(special_role_flag, ROLE_SYNDICATE))) - continue - /* if(is_banned_from(candidate.client.ckey, BAN_ANTAGONIST)) + //if(midround_antag_pref) + //continue + + if(job_ban && is_banned_from(candidate.ckey, list(job_ban, ROLE_SYNDICATE))) continue - if(!candidate.client?.prefs?.read_preference(/datum/preference/toggle/be_antag)) - continue */ // Закоменчено, так как требует расширения системы банов и настроек - ввод банов на любых антагов и настроек на то, чтобы вообще быть антагом. candidates += candidate return candidates @@ -303,9 +341,9 @@ SUBSYSTEM_DEF(gamemode) if(SSticker.HasRoundStarted()) update_crew_infos() return active_players - - calculate_ready_players() - return ready_players + else + calculate_ready_players() + return ready_players /// Refunds and removes a scheduled event. /datum/controller/subsystem/gamemode/proc/refund_scheduled_event(datum/scheduled_event/refunded) @@ -314,10 +352,6 @@ SUBSYSTEM_DEF(gamemode) event_track_points[track_type] += refunded.cost remove_scheduled_event(refunded) -/// Schedules an event. -/datum/controller/subsystem/gamemode/proc/force_event(datum/round_event_control/event) - forced_next_events[event.track] = event - /// Removes a scheduled event. /datum/controller/subsystem/gamemode/proc/remove_scheduled_event(datum/scheduled_event/removed) scheduled_events -= removed @@ -332,47 +366,58 @@ SUBSYSTEM_DEF(gamemode) /// We roll points to be spent for roundstart events, including antagonists. /datum/controller/subsystem/gamemode/proc/roll_pre_setup_points() - if(storyteller.disable_distribution || halted_storyteller) + if(current_storyteller.disable_distribution || halted_storyteller) return /// Distribute points for(var/track in event_track_points) var/base_amt + var/gain_amt switch(track) if(EVENT_TRACK_MUNDANE) base_amt = ROUNDSTART_MUNDANE_BASE + gain_amt = ROUNDSTART_MUNDANE_GAIN if(EVENT_TRACK_MODERATE) base_amt = ROUNDSTART_MODERATE_BASE + gain_amt = ROUNDSTART_MODERATE_GAIN if(EVENT_TRACK_MAJOR) base_amt = ROUNDSTART_MAJOR_BASE - if(EVENT_TRACK_CREWSET) - base_amt = ROUNDSTART_CREWSET_BASE - if(EVENT_TRACK_GHOSTSET) - base_amt = ROUNDSTART_GHOSTSET_BASE - var/calc_value = base_amt + gain_amt = ROUNDSTART_MAJOR_GAIN + if(EVENT_TRACK_ROLESET) + base_amt = ROUNDSTART_ROLESET_BASE + gain_amt = ROUNDSTART_ROLESET_GAIN + if(EVENT_TRACK_OBJECTIVES) + base_amt = ROUNDSTART_OBJECTIVES_BASE + gain_amt = ROUNDSTART_OBJECTIVES_GAIN + var/calc_value = base_amt + (gain_amt * ready_players) calc_value *= roundstart_point_multipliers[track] - calc_value *= storyteller.starting_point_multipliers[track] - calc_value *= (1 + (rand(-storyteller.roundstart_points_variance, storyteller.roundstart_points_variance) / 100)) - event_track_points[track] = max(0, round(calc_value)) + calc_value *= current_storyteller.starting_point_multipliers[track] + calc_value *= (rand(100 - current_storyteller.roundstart_points_variance,100 + current_storyteller.roundstart_points_variance)/100) + event_track_points[track] = round(calc_value) /// If the storyteller guarantees an antagonist roll, add points to make it so. - if(storyteller.guarantees_roundstart_crewset) - event_track_points[EVENT_TRACK_CREWSET] = point_thresholds[EVENT_TRACK_CREWSET] - storyteller.ready_cost_modifier = SSgamemode.get_correct_popcount() / storyteller.antag_divisor + if(current_storyteller.guarantees_roundstart_roleset && event_track_points[EVENT_TRACK_ROLESET] < point_thresholds[EVENT_TRACK_ROLESET]) + event_track_points[EVENT_TRACK_ROLESET] = point_thresholds[EVENT_TRACK_ROLESET] /// If we have any forced events, ensure we get enough points for them for(var/track in event_tracks) if(forced_next_events[track] && event_track_points[track] < point_thresholds[track]) event_track_points[track] = point_thresholds[track] +/// At this point we've rolled roundstart events and antags and we handle leftover points here. +/datum/controller/subsystem/gamemode/proc/handle_post_setup_points() +// for(var/track in event_track_points) //Just halve the points for now. +// event_track_points[track] *= 0.5 TESTING HOW THINGS GO WITHOUT THIS HALVING OF POINTS + return + /// Because roundstart events need 2 steps of firing for purposes of antags, here is the first step handled, happening before occupation division. /datum/controller/subsystem/gamemode/proc/handle_pre_setup_roundstart_events() - if(storyteller.disable_distribution) + if(current_storyteller.disable_distribution) return if(halted_storyteller) message_admins("WARNING: Didn't roll roundstart events (including antagonists) due to the storyteller being halted.") return while(TRUE) - if(!storyteller.handle_tracks()) + if(!current_storyteller.handle_tracks()) break /// Second step of handlind roundstart events, happening after people spawn. @@ -381,32 +426,45 @@ SUBSYSTEM_DEF(gamemode) for(var/datum/round_event/event as anything in running) if(!event.control.roundstart) continue + ASYNC + event.try_start() INVOKE_ASYNC(event, TYPE_PROC_REF(/datum/round_event, try_start)) /// Schedules an event to run later. -/datum/controller/subsystem/gamemode/proc/schedule_event(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) +/datum/controller/subsystem/gamemode/proc/schedule_event(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce, _forced = FALSE) + if(_forced) + passed_ignore = TRUE var/datum/scheduled_event/scheduled = new (passed_event, world.time + passed_time, passed_cost, passed_ignore, passed_announce) var/round_started = SSticker.HasRoundStarted() if(round_started) - message_admins("Event: [passed_event] has been scheduled to run in [passed_time / 10] seconds. (CANCEL) (REFUND)") + message_admins("Event: [passed_event] has been scheduled to run in [passed_time / 10] seconds. (CANCEL) (REFUND)") else //Only roundstart events can be scheduled before round start - message_admins("Event: [passed_event] has been scheduled to run on roundstart. (CANCEL)") + message_admins("Event: [passed_event] has been scheduled to run on roundstart. (CANCEL)") scheduled_events += scheduled /datum/controller/subsystem/gamemode/proc/update_crew_infos() // Very similar logic to `get_active_player_count()` active_players = 0 head_crew = 0 + current_head_power = 0 eng_crew = 0 + current_eng_power = 0 med_crew = 0 - sec_crew = 0 + current_med_power = 0 rnd_crew = 0 + current_rnd_power = 0 + sec_crew = 0 + var/intern_threshold = (CONFIG_GET(number/use_low_living_hour_intern_hours) * 60) || (CONFIG_GET(number/use_exp_restrictions_heads_hours) * 60) + var/is_intern = FALSE + for(var/mob/player_mob as anything in GLOB.player_list) if(!player_mob.client) continue - if(player_mob.stat) + var/playtime = player_mob.client.get_exp_living(pure_numeric = TRUE) + is_intern = (intern_threshold >= playtime) && (player_mob.mind?.assigned_role.job_flags & JOB_CAN_BE_INTERN) + if(player_mob.stat) //If they're alive continue - if(player_mob.client.is_afk()) + if(player_mob.client.is_afk()) //If afk continue if(!ishuman(player_mob)) continue @@ -415,87 +473,73 @@ SUBSYSTEM_DEF(gamemode) var/datum/job/player_role = player_mob.mind.assigned_role if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) head_crew++ + current_head_power = is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_ENGINEERING) eng_crew++ + current_eng_power = is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_MEDICAL) med_crew++ - if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) - sec_crew++ + current_med_power = is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) rnd_crew++ + current_rnd_power = is_intern ? 0 : (playtime / 100) + if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) + sec_crew++ + update_pop_scaling() -/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, admin_forced = FALSE) - . = event.preRunEvent(admin_forced) +/datum/controller/subsystem/gamemode/proc/update_pop_scaling() + for(var/track in event_tracks) + var/low_pop_bound = min_pop_thresholds[track] + var/high_pop_bound = pop_scale_thresholds[track] + var/scale_penalty = pop_scale_penalties[track] + + var/perceived_pop = min(max(low_pop_bound, active_players), high_pop_bound) + + var/divisor = high_pop_bound - low_pop_bound + /// If the bounds are equal, we'd be dividing by zero or worse, if upper is smaller than lower, we'd be increasing the factor, just make it 1 and continue. + /// this is only a problem for bad configs + if(divisor <= 0) + current_pop_scale_multipliers[track] = 1 + continue + var/scalar = (perceived_pop - low_pop_bound) / divisor + var/penalty = scale_penalty - (scale_penalty * scalar) + var/calculated_multiplier = 1 - (penalty / 100) + + current_pop_scale_multipliers[track] = calculated_multiplier + +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, forced = FALSE) + . = event.preRunEvent(forced) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event.max_occurrences = 0 else if(. == EVENT_READY) - event.run_event(random = TRUE) // fallback to dynamic + event.run_event(random = TRUE, admin_forced = forced) // fallback to dynamic ///Resets frequency multiplier. /datum/controller/subsystem/gamemode/proc/resetFrequency() event_frequency_multiplier = 1 -/* /client/proc/forceEvent() +/client/proc/forceEvent() set name = "Trigger Event" set category = "Admin.Events" - if(!holder ||!check_rights(R_FUN)) return + holder.forceEvent(usr) - holder.forceEvent(usr) */ - -/* /datum/admins/forceEvent(mob/user) - SSgamemode.event_panel(user) */ - - -////////////// -// HOLIDAYS // -////////////// -//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays - -//It's easy to add stuff. Just add a holiday datum in code/modules/holiday/holidays.dm -//You can then check if it's a special day in any code in the game by doing if(SSgamemode.holidays["Groundhog Day"]) - -//You can also make holiday random events easily thanks to Pete/Gia's system. -//simply make a random event normally, then assign it a holidayID string which matches the holiday's name. -//Anything with a holidayID, which isn't in the holidays list, will never occur. - -//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc), -//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed! - -////////////////////////////////////////////////////////////////////////////////////////////////////////// -//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!// -////////////////////////////////////////////////////////////////////////////////////////////////////////// - - -//sets up the holidays and holidays list -/datum/controller/subsystem/gamemode/proc/getHoliday() - if(!CONFIG_GET(flag/allow_holidays)) - return // Holiday stuff was not enabled in the config! - for(var/H in subtypesof(/datum/holiday)) - var/datum/holiday/holiday = new H() - var/delete_holiday = TRUE - for(var/timezone in holiday.timezones) - var/time_in_timezone = world.realtime + timezone HOURS +/datum/admins/forceEvent() + if(!check_rights(R_FUN)) + return - var/YYYY = text2num(time2text(time_in_timezone, "YYYY")) // get the current year - var/MM = text2num(time2text(time_in_timezone, "MM")) // get the current month - var/DD = text2num(time2text(time_in_timezone, "DD")) // get the current day - var/DDD = time2text(time_in_timezone, "DDD") // get the current weekday + SSgamemode.event_panel(usr) - if(holiday.shouldCelebrate(DD, MM, YYYY, DDD)) - holiday.celebrate() - LAZYSET(holidays, holiday.name, holiday) - delete_holiday = FALSE - break - if(delete_holiday) - qdel(holiday) +/client/proc/forceGamemode() + set name = "Open Gamemode Panel" + set category = "Admin.Events" + if(!holder ||!check_rights(R_FUN)) + return + holder.forceGamemode(usr) - if(holidays) - holidays = shuffle(holidays) - // regenerate station name because holiday prefixes. - set_station_name(new_station_name()) - world.update_status() +/datum/admins/proc/forceGamemode(mob/user) + SSgamemode.admin_panel(user) /datum/controller/subsystem/gamemode/proc/toggleWizardmode() wizardmode = !wizardmode //TODO: decide what to do with wiz events @@ -504,46 +548,31 @@ SUBSYSTEM_DEF(gamemode) ///Attempts to select players for special roles the mode might have. /datum/controller/subsystem/gamemode/proc/pre_setup() - // We need to do this to prevent some niche fuckery... and make dep. orders work. Lol - - recalculate_secs() - SSjob.reset_occupations() calculate_ready_players() roll_pre_setup_points() - handle_pre_setup_roundstart_events() + //handle_pre_setup_roundstart_events() return TRUE -/datum/controller/subsystem/gamemode/proc/recalculate_secs() - sec_crew = 0 - SSjob.divide_occupations(pure = TRUE, allow_all = TRUE) - for(var/i in GLOB.new_player_list) - var/mob/dead/new_player/player = i - if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) - if(is_unassigned_job(player.mind.assigned_role)) - var/list/job_data = list() - var/job_prefs = player.client.prefs.job_preferences - for(var/job in job_prefs) - var/priority = job_prefs[job] - job_data += "[job]: [SSjob.job_priority_level_to_string(priority)]" - to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role this round because your job preferences presented a high chance of all of your selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled. Increase the number of roles set to medium or low priority to reduce the chances of this happening.")) - log_admin("[player.ckey] failed to qualify for any roundstart antagonist role because their job preferences presented a high chance of all of their selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]") - else - if(player.mind?.assigned_role?.departments_list?.Find(/datum/job_department/security) && (!player.mind?.special_role)) - sec_crew++ - ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/controller/subsystem/gamemode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) report = !CONFIG_GET(flag/no_intercept_report) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(display_roundstart_logout_report)), ROUNDSTART_LOGOUT_REPORT_TIME) - addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) + if(CONFIG_GET(flag/reopen_roundstart_suicide_roles)) + var/delay = CONFIG_GET(number/reopen_roundstart_suicide_roles_delay) + if(delay) + delay = (delay SECONDS) + else + delay = (4 MINUTES) //default to 4 minutes if the delay isn't defined. + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(reopen_roundstart_suicide_roles)), delay) if(SSdbcore.Connect()) var/list/to_set = list() var/arguments = list() - if(storyteller) + if(current_storyteller) to_set += "game_mode = :game_mode" - arguments["game_mode"] = storyteller.name + arguments["game_mode"] = current_storyteller.name if(GLOB.revdata.originmastercommit) to_set += "commit_hash = :commit_hash" arguments["commit_hash"] = GLOB.revdata.originmastercommit @@ -555,8 +584,9 @@ SUBSYSTEM_DEF(gamemode) ) query_round_game_mode.Execute() qdel(query_round_game_mode) - addtimer(CALLBACK(src, PROC_REF(send_trait_report)), rand(1 MINUTES, 5 MINUTES)) + SSstation.generate_station_goals(INFINITY) handle_post_setup_roundstart_events() + handle_post_setup_points() roundstart_event_view = FALSE return TRUE @@ -568,7 +598,73 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/check_finished(force_ending) //to be called by SSticker if(!SSticker.setup_done) return FALSE - return force_ending || GLOB.station_was_nuked || SSshuttle?.emergency?.mode == SHUTTLE_ENDGAME + if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) + return TRUE + if(GLOB.station_was_nuked) + return TRUE + if(force_ending) + return TRUE + +/* + * Generate a list of station goals available to purchase to report to the crew. + * + * Returns a formatted string all station goals that are available to the station. + */ +/datum/controller/subsystem/gamemode/proc/generate_station_goal_report() + var/goals = SSstation.get_station_goals() + if(!length(goals)) + return + . = "
Special Orders for [station_name()]:
" + for(var/datum/station_goal/station_goal as anything in goals) + station_goal.on_report() + . += station_goal.get_report() + return + +/* + * Generate a list of active station traits to report to the crew. + * + * Returns a formatted string of all station traits (that are shown) affecting the station. + */ +/datum/controller/subsystem/gamemode/proc/generate_station_trait_report() + if(!SSstation.station_traits.len) + return + . = "
Identified shift divergencies:
" + for(var/datum/station_trait/station_trait as anything in SSstation.station_traits) + if(!station_trait.show_in_report) + continue + . += "[station_trait.get_report()]
" + return + +/* /proc/reopen_roundstart_suicide_roles() + var/include_command = CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_positions) + var/list/reopened_jobs = list() + for(var/mob/living/quitter in GLOB.suicided_mob_list) + var/datum/job/job = SSjob.GetJob(quitter.job) + if(!job || !(job.job_flags & JOB_REOPEN_ON_ROUNDSTART_LOSS)) + continue + if(!include_command && job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) + continue + job.current_positions = max(job.current_positions - 1, 0) + reopened_jobs += quitter.job + if(CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_report)) + if(reopened_jobs.len) + var/reopened_job_report_positions + for(var/dead_dudes_job in reopened_jobs) + reopened_job_report_positions = "[reopened_job_report_positions ? "[reopened_job_report_positions]\n":""][dead_dudes_job]" + var/suicide_command_report = "Central Command Human Resources Board
\ + Notice of Personnel Change

\ + To personnel management staff aboard [station_name()]:

\ + Our medical staff have detected a series of anomalies in the vital sensors \ + of some of the staff aboard your station.

\ + Further investigation into the situation on our end resulted in us discovering \ + a series of rather... unforturnate decisions that were made on the part of said staff.

\ + As such, we have taken the liberty to automatically reopen employment opportunities for the positions of the crew members \ + who have decided not to partake in our research. We will be forwarding their cases to our employment review board \ + to determine their eligibility for continued service with the company (and of course the \ + continued storage of cloning records within the central medical backup server.)

\ + The following positions have been reopened on our behalf:

\ + [reopened_job_report_positions]
" + print_command_report(suicide_command_report, "Central Command Personnel Update") */ ////////////////////////// //Reports player logouts// @@ -578,7 +674,6 @@ SUBSYSTEM_DEF(gamemode) for(var/i in GLOB.mob_living_list) var/mob/living/L = i var/mob/living/carbon/C = L - //var/mob/living/carbon/human/H = C - не требуется без функций гет_днр if (istype(C) && !C.last_mind) continue // never had a client @@ -588,14 +683,13 @@ SUBSYSTEM_DEF(gamemode) if(L.ckey && L.client) var/failed = FALSE - if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) + if(L.client.inactivity >= ROUNDSTART_LOGOUT_AFK_THRESHOLD) //Connected, but inactive (alt+tabbed or something) msg += "[L.name] ([L.key]), the [L.job] (Connected, Inactive)\n" failed = TRUE //AFK client if(!failed && L.stat) - /* if(H.get_dnr()) //Suicider + if(HAS_TRAIT(L, TRAIT_SUICIDED)) //Suicider msg += "[L.name] ([L.key]), the [L.job] ([span_boldannounce("Suicide")])\n" failed = TRUE //Disconnected client - */ // - нет функции гет_днр и вызывающих днр состояний if(!failed && (L.stat == UNCONSCIOUS || L.stat == HARD_CRIT)) msg += "[L.name] ([L.key]), the [L.job] (Dying)\n" failed = TRUE //Unconscious @@ -607,14 +701,12 @@ SUBSYSTEM_DEF(gamemode) for(var/mob/dead/observer/D in GLOB.dead_mob_list) if(D.mind && D.mind.current == L) if(L.stat == DEAD) - /* if(H.get_dnr()) //Suicider + if(HAS_TRAIT(L, TRAIT_SUICIDED)) //Suicider msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Suicide")])\n" continue //Disconnected client else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" - continue */ // - нет функции гет_днр и вызывающих днр состояний - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" - continue //Dead mob, ghost abandoned + continue //Dead mob, ghost abandoned else if(D.can_reenter_corpse) continue //Adminghost, or cult/wizard ghost @@ -622,9 +714,9 @@ SUBSYSTEM_DEF(gamemode) msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] ([span_boldannounce("Ghosted")])\n" continue //Ghosted while alive - - for (var/C in GLOB.admins) - to_chat(C, msg.Join()) + var/concatenated_message = msg.Join() + log_admin(concatenated_message) + to_chat(GLOB.admins, concatenated_message) //Set result and news report here /datum/controller/subsystem/gamemode/proc/set_round_result() @@ -638,13 +730,10 @@ SUBSYSTEM_DEF(gamemode) /// Loads json event config values from events.txt /datum/controller/subsystem/gamemode/proc/load_event_config_vars() - var/file_path = "[global.config.directory]/bandastation/events.toml" - var/toml_file = file(file_path) - if(!fexists(toml_file)) - return - var/list/decoded = rustg_read_toml_file(file_path) - if(!length(decoded )) + var/json_file = file("[global.config.directory]/events.json") + if(!fexists(json_file)) return + var/list/decoded = json_decode(file2text(json_file)) for(var/event_text_path in decoded) var/event_path = text2path(event_text_path) var/datum/round_event_control/event @@ -674,124 +763,143 @@ SUBSYSTEM_DEF(gamemode) if("reoccurence_penalty_multiplier") event.reoccurence_penalty_multiplier = value if("shared_occurence_type") - event.shared_occurence_type= !isnull(value) ? text2path(value) : null + if(!isnull(value)) + value = "[value]" + event.shared_occurence_type = value /// Loads config values from game_options.txt /datum/controller/subsystem/gamemode/proc/load_config_vars() point_gain_multipliers[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_point_gain_multiplier) point_gain_multipliers[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_point_gain_multiplier) point_gain_multipliers[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_point_gain_multiplier) - point_gain_multipliers[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_point_gain_multiplier) - point_gain_multipliers[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_gain_multiplier) + point_gain_multipliers[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_gain_multiplier) roundstart_point_multipliers[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_roundstart_point_multiplier) roundstart_point_multipliers[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_roundstart_point_multiplier) roundstart_point_multipliers[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_roundstart_point_multiplier) + roundstart_point_multipliers[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_roundstart_point_multiplier) min_pop_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_min_pop) min_pop_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_min_pop) min_pop_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_min_pop) - min_pop_thresholds[EVENT_TRACK_CREWSET] = CONFIG_GET(number/crewset_min_pop) - min_pop_thresholds[EVENT_TRACK_GHOSTSET] = CONFIG_GET(number/ghostset_min_pop) + min_pop_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_min_pop) + min_pop_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_min_pop) + + point_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_point_threshold) + point_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_point_threshold) + point_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_point_threshold) + point_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_threshold) + point_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_threshold) + +/datum/controller/subsystem/gamemode/proc/handle_picking_storyteller() + if(CONFIG_GET(flag/disable_storyteller)) + return + if(length(GLOB.clients) > MAX_POP_FOR_STORYTELLER_VOTE) + secret_storyteller = TRUE + selected_storyteller = pick_weight(get_valid_storytellers(TRUE)) + return + //SSvote.initiate_vote(/datum/vote/storyteller, "pick round storyteller", forced = TRUE) /datum/controller/subsystem/gamemode/proc/storyteller_vote_choices() - var/client_amount = GLOB.clients.len - var/list/choices = list() + var/list/final_choices = list() + var/list/pick_from = list() + for(var/datum/storyteller/storyboy in get_valid_storytellers()) + if(storyboy.always_votable) + final_choices[storyboy.name] = 0 + else + pick_from[storyboy.name] = storyboy.weight //might be able to refactor this to be slightly better due to get_valid_storytellers returning a weighted list + + var/added_storytellers = 0 + while(added_storytellers < DEFAULT_STORYTELLER_VOTE_OPTIONS && length(pick_from)) + added_storytellers++ + var/picked_storyteller = pick_weight(pick_from) + final_choices[picked_storyteller] = 0 + pick_from -= picked_storyteller + return final_choices + +/datum/controller/subsystem/gamemode/proc/storyteller_desc(storyteller_name) for(var/storyteller_type in storytellers) var/datum/storyteller/storyboy = storytellers[storyteller_type] - /// Prevent repeating storytellers - if(storyboy.storyteller_type && storyboy.storyteller_type == SSpersistence.last_storyteller_type) - continue - if(!storyboy.votable) - continue - if((storyboy.population_min && storyboy.population_min > client_amount) || (storyboy.population_max && storyboy.population_max < client_amount)) + if(storyboy.name != storyteller_name) continue - choices += storyboy.name - ///Because the vote subsystem is dumb and does not support any descriptions, we dump them into world. - to_chat(world, span_notice("[storyboy.name]")) - to_chat(world, span_notice("[storyboy.desc]")) - return choices + return storyboy.desc + /datum/controller/subsystem/gamemode/proc/storyteller_vote_result(winner_name) - /// Find the winner - voted_storyteller = winner_name - if(storyteller) - return for(var/storyteller_type in storytellers) var/datum/storyteller/storyboy = storytellers[storyteller_type] if(storyboy.name == winner_name) - voted_storyteller = storyteller_type + selected_storyteller = storyteller_type break +///return a weighted list of all storytellers that are currently valid to roll, if return_types is set then we will return types instead of instances +/datum/controller/subsystem/gamemode/proc/get_valid_storytellers(return_types = FALSE) + var/client_amount = length(GLOB.clients) + var/list/valid_storytellers = list() + for(var/storyteller_type in storytellers) + var/datum/storyteller/storyboy = storytellers[storyteller_type] + if(storyboy.restricted || (storyboy.population_min && storyboy.population_min > client_amount) || (storyboy.population_max && storyboy.population_max < client_amount)) + continue + + valid_storytellers[return_types ? storyboy.type : storyboy] = storyboy.weight + return valid_storytellers + /datum/controller/subsystem/gamemode/proc/init_storyteller() - var/datum/storyteller/storyteller_pick - if(!voted_storyteller) - storyteller_pick = pick(storytellers) - message_admins("We picked [storyteller_pick] for this rounds storyteller, randomly.") - voted_storyteller = storyteller_pick - if(storyteller) // If this is true, then an admin bussed one, don't overwrite it - return - set_storyteller(voted_storyteller) + set_storyteller(selected_storyteller) /datum/controller/subsystem/gamemode/proc/set_storyteller(passed_type) if(!storytellers[passed_type]) - message_admins("Attempted to set an invalid storyteller type: [passed_type].") + message_admins("Attempted to set an invalid storyteller type: [passed_type], force setting to guide instead.") + current_storyteller = storytellers[/datum/storyteller/default] //if we dont have any then we brick, lets not do that CRASH("Attempted to set an invalid storyteller type: [passed_type].") - storyteller = storytellers[passed_type] - - var/datum/storyteller_data/tracks/track_data = storyteller.track_data - var/config_sec_mult = CONFIG_GET(number/max_sec_mult) - storyteller.max_sec_mult = storyteller.max_sec_mult * config_sec_mult - point_thresholds[EVENT_TRACK_MUNDANE] = track_data.threshold_mundane * CONFIG_GET(number/mundane_point_threshold) - point_thresholds[EVENT_TRACK_MODERATE] = track_data.threshold_moderate * CONFIG_GET(number/moderate_point_threshold) - point_thresholds[EVENT_TRACK_MAJOR] = track_data.threshold_major * CONFIG_GET(number/major_point_threshold) - point_thresholds[EVENT_TRACK_CREWSET] = track_data.threshold_crewset * CONFIG_GET(number/crewset_point_threshold) - point_thresholds[EVENT_TRACK_GHOSTSET] = track_data.threshold_ghostset * CONFIG_GET(number/ghostset_point_threshold) - - to_chat(world, span_notice("Storyteller is [storyteller.name]!")) - to_chat(world, span_notice("[storyteller.welcome_text]")) + current_storyteller = storytellers[passed_type] + if(!secret_storyteller) + send_to_playing_players(span_notice("Storyteller is [current_storyteller.name]!")) + send_to_playing_players(span_notice("[current_storyteller.welcome_text]")) + else + send_to_observers(span_boldbig("Storyteller is [current_storyteller.name]!")) //observers still get to know /// Panel containing information, variables and controls about the gamemode and scheduled event /datum/controller/subsystem/gamemode/proc/admin_panel(mob/user) update_crew_infos() var/round_started = SSticker.HasRoundStarted() var/list/dat = list() - var/active_pop = get_correct_popcount() - dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " - dat += " HALT Storyteller Event Panel Set Storyteller Refresh" + dat += "Storyteller: [current_storyteller ? "[current_storyteller.name]" : "None"] " + dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." - dat += "
Active Players: [active_pop] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew], Rnd: [rnd_crew]) - Antag Cap: [get_antag_cap()], Antag Count: [length(GLOB.current_living_antags)]" + dat += "
Active Players: [active_players] (Head: [head_crew]/[current_head_power], Sec: [sec_crew], Eng: [eng_crew]/[current_eng_power], Med: [med_crew]/[current_med_power], RnD: [med_crew]/[current_rnd_power])" + dat += "
Antagonist Count vs Maximum: [get_antag_count()] / [get_antag_cap()]" dat += "
" - dat += "Main" - dat += " Variables" + dat += "Main" + dat += " Variables" dat += "
" switch(panel_page) if(GAMEMODE_PANEL_VARIABLES) - dat += "Reload Config Vars Configs located in game_options.txt." + dat += "Reload Config Vars Configs located in game_options.txt." dat += "
Point Gains Multipliers (only over time):" dat += "
This affects points gained over time towards scheduling new events of the tracks." for(var/track in event_tracks) - dat += "
[track]: [point_gain_multipliers[track]]" + dat += "
[track]: [point_gain_multipliers[track]]" dat += "
" dat += "Roundstart Points Multipliers:" dat += "
This affects points generated for roundstart events and antagonists." for(var/track in event_tracks) - dat += "
[track]: [roundstart_point_multipliers[track]]" + dat += "
[track]: [roundstart_point_multipliers[track]]" dat += "
" dat += "Minimum Population for Tracks:" dat += "
This are the minimum population caps for events to be able to run." for(var/track in event_tracks) - dat += "
[track]: [min_pop_thresholds[track]]" + dat += "
[track]: [min_pop_thresholds[track]]" dat += "
" dat += "Point Thresholds:" dat += "
Those are thresholds the tracks require to reach with points to make an event." for(var/track in event_tracks) - dat += "
[track]: [point_thresholds[track]]" + dat += "
[track]: [point_thresholds[track]]" if(GAMEMODE_PANEL_MAIN) var/even = TRUE @@ -814,15 +922,15 @@ SUBSYSTEM_DEF(gamemode) var/next = 0 var/last_points = last_point_gains[track] if(last_points) - next = round((upper - lower) / last_points / STORYTELLER_WAIT_TIME * 40 / 6) / 10 + next = round(((upper - lower) / last_points / STORYTELLER_WAIT_TIME)) dat += "" - dat += "[track]" //Track + dat += "[track] - [last_points] per process." //Track dat += "[percent]% ([lower]/[upper])" //Progress - dat += "~[next] m." //Next + dat += "~[next] seconds" //Next var/datum/round_event_control/forced_event = forced_next_events[track] - var/forced = forced_event ? "[forced_event.name] X" : "" + var/forced = forced_event ? "[forced_event.name] X" : "" dat += "[forced]" //Forced - dat += "Set Pts. Next Event" //Actions + dat += "Set Pts. Next Event" //Actions dat += "" dat += "" @@ -874,26 +982,29 @@ SUBSYSTEM_DEF(gamemode) /// Panel containing information and actions regarding events /datum/controller/subsystem/gamemode/proc/event_panel(mob/user) var/list/dat = list() - if(storyteller) - dat += "Storyteller: [storyteller.name]" - dat += "
Repetition penalty multiplier: [storyteller.event_repetition_multiplier]" - dat += "
Cost variance: [storyteller.cost_variance]" - if(storyteller.tag_multipliers) + if(current_storyteller) + dat += "Storyteller: [current_storyteller.name]" + dat += "
Repetition penalty multiplier: [current_storyteller.event_repetition_multiplier]" + dat += "
Cost variance: [current_storyteller.cost_variance]" + if(current_storyteller.tag_multipliers) dat += "
Tag multipliers:" - for(var/tag in storyteller.tag_multipliers) - dat += "[tag]:[storyteller.tag_multipliers[tag]] | " - storyteller.calculate_weights(statistics_track_page) + for(var/tag in current_storyteller.tag_multipliers) + dat += "[tag]:[current_storyteller.tag_multipliers[tag]] | " + current_storyteller.calculate_weights(statistics_track_page) else dat += "Storyteller: None
Weight and chance statistics will be inaccurate due to the present lack of a storyteller." - dat += "
Roundstart Events Forced Roundstart events will use rolled points, and are guaranteed to trigger (even if the used points are not enough)" + dat += "
Roundstart Events Forced Roundstart events will use rolled points, and are guaranteed to trigger (even if the used points are not enough)" dat += "
Avg. event intervals: " for(var/track in event_tracks) if(last_point_gains[track]) - var/est_time = round(point_thresholds[track] / last_point_gains[track] / STORYTELLER_WAIT_TIME * 40 / 6) / 10 - dat += "[track]: ~[est_time] m. | " + var/lower = event_track_points[track] + var/upper = point_thresholds[track] + var/last_points = last_point_gains[track] + var/est_time = round(((upper - lower) / last_points / STORYTELLER_WAIT_TIME)) + dat += "[track]: ~[est_time] secs. | " dat += "
" for(var/track in EVENT_PANEL_TRACKS) - dat += "[track]" + dat += "[track]" dat += "
" /// Create event info and stats table dat += "" @@ -901,9 +1012,11 @@ SUBSYSTEM_DEF(gamemode) dat += "" dat += "" dat += "" + dat += "" dat += "" dat += "" dat += "" + dat += "" dat += "" dat += "" dat += "" @@ -918,11 +1031,11 @@ SUBSYSTEM_DEF(gamemode) else event_lookup = event_pools[statistics_track_page] var/list/assoc_spawn_weight = list() - var/active_pop = get_correct_popcount() for(var/datum/round_event_control/event as anything in event_lookup) - if((!roundstart_event_view && event.roundstart) || (roundstart_event_view && !event.roundstart)) + var/players_amt = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) + if(event.roundstart != roundstart_event_view) continue - if(event.can_spawn_event(active_pop)) + if(event.can_spawn_event(players_amt)) total_weight += event.calculated_weight assoc_spawn_weight[event] = event.calculated_weight else @@ -940,11 +1053,14 @@ SUBSYSTEM_DEF(gamemode) var/occurence_string = "[event.occurrences]" if(event.shared_occurence_type) occurence_string += " (shared: [event.get_occurences()])" + var/max_occurence_string = "[event.max_occurrences]" dat += "" //Occurences + dat += "" //Max Occurences dat += "" //Minimum pop dat += "" //Minimum time dat += "" //Can happen? - var/weight_string = "([event.calculated_weight] /raw.[event.weight])" + dat += "" //Why can't happen? + var/weight_string = "(new.[event.calculated_weight] /raw.[event.weight])" if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) weight_string = "[percent]% - [weight_string]" @@ -952,7 +1068,7 @@ SUBSYSTEM_DEF(gamemode) dat += "" //Actions dat += "" dat += "
NameTagsOccurencesMax OccurencesM.PopM.TimeCan OccurFailure ReasonWeightActions
[occurence_string][max_occurence_string][event.min_players][event.earliest_start / (1 MINUTES)] m.[assoc_spawn_weight[event] ? "Yes" : "No"][event.return_failure_string(active_players)][event.get_href_actions()]
" - var/datum/browser/popup = new(user, "gamemode_event_panel", "Event Panel", 1000, 600) + var/datum/browser/popup = new(user, "gamemode_event_panel", "Event Panel", 1100, 600) popup.set_content(dat.Join()) popup.open() @@ -1037,8 +1153,8 @@ SUBSYSTEM_DEF(gamemode) message_admins("[key_name_admin(usr)] invoked next event for [track] track.") log_admin_private("[key_name(usr)] invoked next event for [track] track.") event_track_points[track] = point_thresholds[track] - if(storyteller) - storyteller.handle_tracks() + if(current_storyteller) + current_storyteller.handle_tracks() admin_panel(user) if("stats") switch(href_list["action"]) @@ -1049,3 +1165,40 @@ SUBSYSTEM_DEF(gamemode) if(new_category in EVENT_PANEL_TRACKS) statistics_track_page = new_category event_panel(user) + +/datum/controller/subsystem/gamemode/proc/round_end_report() + if(!length(round_end_data)) + return + for(var/datum/round_event/event as anything in round_end_data) + if(!istype(event)) + continue + event.round_end_report() + + +/datum/controller/subsystem/gamemode/proc/store_roundend_data() + var/congealed_string = "" + for(var/event_name as anything in triggered_round_events) + congealed_string += event_name + congealed_string += "," + text2file(congealed_string, "data/last_round_events.txt") + +/datum/controller/subsystem/gamemode/proc/load_roundstart_data() + var/massive_string = trim(file2text("data/last_round_events.txt")) + if(fexists("data/last_round_events.txt")) + fdel("data/last_round_events.txt") + if(!massive_string) + return + last_round_events = splittext(massive_string, ",") + + if(!length(last_round_events)) + return + for(var/event_name as anything in last_round_events) + for(var/datum/round_event_control/listed as anything in control) + if(listed.name != event_name) + continue + listed.occurrences++ + listed.occurrences++ + +#undef DEFAULT_STORYTELLER_VOTE_OPTIONS +#undef MAX_POP_FOR_STORYTELLER_VOTE +#undef ROUNDSTART_VALID_TIMEFRAME diff --git a/modular_bandastation/storyteller/code/readme.md b/modular_bandastation/storyteller/code/readme.md new file mode 100644 index 0000000000000..d8f40256bd553 --- /dev/null +++ b/modular_bandastation/storyteller/code/readme.md @@ -0,0 +1,44 @@ +## Title: + + +MODULE ID: STORYTELLERS + +### Description: + +This PR adds adds on to the current dynamic system by having events be guided by storytellers, this also caches the events ran last round and depending on severity cuts their weights by x % to make rounds not repeat as often. + + + + +### TG Proc/File Changes: + + + - N/A + +### Defines: + + + - code\__DEFINES\~monkestation\storytellers.dm + +### Master file additions + +- code\modules\events\_event.dm +- code\modules\admin\topic.dm +- code\controllers\subsystem\ticker.dm +- code\controllers\subsystem\statpanel.dm +- all event files + + + +### Included files that are not contained in this module: + +- N/A + + +### Credits: + + + +Made by Unknown Coders on Horizon (Horizon's Repo atleast as of 10/14/2023 no longer exists if this changes please let me know on discord #Borbop) + +Ported by KageIIte diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index 1d9797a8e48c4..cfb67a2dcf725 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -14,7 +14,6 @@ var/ignores_checks /// Whether the scheduled event will override the announcement change. If null it won't. TRUE = force yes. FALSE = force no. var/announce_change - /// Ивент должен учитывать себя как ивент в начале раунда и не проходить проверки, связанные с этим /datum/scheduled_event/New(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce) . = ..() @@ -46,22 +45,19 @@ return "Cancel" /// Try and fire off the scheduled event -/datum/scheduled_event/proc/try_fire(admin_forced = FALSE) +/datum/scheduled_event/proc/try_fire() /// Remove our fake occurence pre-emptively for the checks. remove_occurence() - var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = FALSE) - ///If we can't spawn the scheduled event, refund it. - if(!ignores_checks && !event.can_spawn_event(players_amt) && !admin_forced) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. - var/message = event.can_spawn_event_error_reason(players_amt) - message_admins("Scheduled Event: [event] was unable to run and has been refunded. REASON: [message]") - log_admin("Scheduled Event: [event] was unable to run and has been refunded. REASON: [message]") + ///If we can't spawn the scheduled event, refund it. + if(!ignores_checks && !event.can_spawn_event(1000)) //FALSE argument to ignore popchecks, to prevent scheduled events from failing from people dying/cryoing etc. + message_admins("Scheduled Event: [event] was unable to run and has been refunded.") SSgamemode.refund_scheduled_event(src) return ///Trigger the event and remove the scheduled datum - message_admins("Scheduled Event: [event] successfully triggered.") - SSgamemode.TriggerEvent(event, admin_forced) + message_admins("Scheduled Event: [event] successfully triggered.") + SSgamemode.TriggerEvent(event, ignores_checks) SSgamemode.remove_scheduled_event(src) /datum/scheduled_event/Destroy() @@ -95,5 +91,4 @@ return message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") - event.run_event(admin_forced = TRUE) - SSgamemode.remove_scheduled_event(src) + try_fire() diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm new file mode 100644 index 0000000000000..ae6abe2d33f50 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -0,0 +1,201 @@ + +///The storyteller datum. He operates with the SSgamemode data to run events +/datum/storyteller + /// Name of our storyteller. + var/name = "Badly coded storyteller" + /// Description of our storyteller. + var/desc = "Report this to the coders." + /// Text that the players will be greeted with when this storyteller is chosen. + var/welcome_text = "Set your eyes on the horizon." + /// This is the multiplier for repetition penalty in event weight. The lower the harsher it is + var/event_repetition_multiplier = 0.6 + /// Multipliers for starting points. + var/list/starting_point_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) + /// Multipliers for point gains. + var/list/point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) + /// Multipliers of weight to apply for each tag of an event. + var/list/tag_multipliers + + /// Variance in cost of the purchased events. Effectively affects frequency of events + var/cost_variance = 15 + + /// Variance in the budget of roundstart points. + var/roundstart_points_variance = 15 + + /// Whether the storyteller guaranteed a roleset roll (antag) on roundstart. (Still needs to pass pop check) + var/guarantees_roundstart_roleset = TRUE + + /// Whether the storyteller has the distributions disabled. Important for ghost storytellers + var/disable_distribution = FALSE + + /// Whether a storyteller is pickable/can be voted for + var/restricted = FALSE + /// If defined, will need a minimum of population to be votable + var/population_min + /// If defined, it will not be votable if exceeding the population + var/population_max + /// has the round gotten to the point where jobs are pre-created? + var/round_started = FALSE + ///have we done roundstart checks? + var/roundstart_checks = FALSE + ///prob of roundstart antag + var/roundstart_prob = 25 + ///do we ignore ran_roundstart + var/ignores_roundstart = FALSE + ///is a storyteller always able to be voted for(also does not count for the amount of storytellers to pick from) + var/always_votable = FALSE + ///weight this has of being picked for random storyteller/showing up in the vote if not always_votable + var/weight = 0 + +/datum/storyteller/process(seconds_per_tick) + if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff + return + + if(!guarantees_roundstart_roleset && prob(roundstart_prob) && !roundstart_checks) + roundstart_checks = TRUE + + if(SSgamemode.current_roundstart_event && !SSgamemode.ran_roundstart && (guarantees_roundstart_roleset || roundstart_checks)) + buy_event(SSgamemode.current_roundstart_event, EVENT_TRACK_ROLESET, TRUE) + if(EVENT_TRACK_ROLESET in SSgamemode.forced_next_events) + SSgamemode.forced_next_events[EVENT_TRACK_ROLESET] = null + SSgamemode.forced_next_events -= EVENT_TRACK_ROLESET + + log_storyteller("Running SSgamemode.current_roundstart_event\[[SSgamemode.current_roundstart_event]\]") + SSgamemode.ran_roundstart = TRUE + + add_points(seconds_per_tick) + handle_tracks() + +/// Add points to all tracks while respecting the multipliers. +/datum/storyteller/proc/add_points(seconds_per_tick) + var/datum/controller/subsystem/gamemode/mode = SSgamemode + var/base_point = EVENT_POINT_GAINED_PER_SECOND * seconds_per_tick * mode.event_frequency_multiplier + for(var/track in mode.event_track_points) + var/point_gain = base_point * point_gains_multipliers[track] * mode.point_gain_multipliers[track] + if(mode.allow_pop_scaling) + point_gain *= mode.current_pop_scale_multipliers[track] + mode.event_track_points[track] += point_gain + mode.last_point_gains[track] = point_gain + +/// Goes through every track of the gamemode and checks if it passes a threshold to buy an event, if does, buys one. +/datum/storyteller/proc/handle_tracks() + . = FALSE //Has return value for the roundstart loop + var/datum/controller/subsystem/gamemode/mode = SSgamemode + for(var/track in mode.event_track_points) + var/points = mode.event_track_points[track] + if(points >= mode.point_thresholds[track] && find_and_buy_event_from_track(track)) + . = TRUE + +/// Find and buy a valid event from a track. +/datum/storyteller/proc/find_and_buy_event_from_track(track) + . = FALSE + var/are_forced = FALSE + var/datum/controller/subsystem/gamemode/mode = SSgamemode + var/datum/round_event_control/picked_event + if(mode.forced_next_events[track]) //Forced event by admin + /// Dont check any prerequisites, it has been forced by an admin + picked_event = mode.forced_next_events[track] + mode.forced_next_events -= track + are_forced = TRUE + else + mode.update_crew_infos() + var/pop_required = mode.min_pop_thresholds[track] + if(mode.active_players < pop_required) + message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [mode.active_players])") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + calculate_weights(track) + var/list/valid_events = list() + // Determine which events are valid to pick + for(var/datum/round_event_control/event as anything in mode.event_pools[track]) + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + if(event.can_spawn_event(players_amt)) + if(QDELETED(event)) + message_admins("[event.name] was deleted!") + continue + valid_events[event] = round(event.calculated_weight * 10) //multiply weight by 10 to get first decimal value + ///If we didn't get any events, remove the points inform admins and dont do anything + if(!length(valid_events)) + message_admins("Storyteller failed to pick an event for track of [track].") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + picked_event = pick_weight(valid_events) + if(!picked_event) + if(length(valid_events)) + var/added_string = "" + for(var/datum/round_event_control/item as anything in valid_events) + added_string += "[item.name]:[valid_events[item]]; " + stack_trace("WARNING: Storyteller picked a null from event pool, defaulting to option 1, look at weights:[added_string]") + shuffle_inplace(valid_events) + picked_event = valid_events[1] + else + message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + stack_trace("WARNING: Storyteller picked a null from event pool.") + SSgamemode.event_track_points[track] = 0 + return + buy_event(picked_event, track, are_forced) + . = TRUE + +///Attempt to buy a specific event if we can afford it, otherwise returns FALSE, note this does NOT take cost variance into account +/datum/storyteller/proc/try_buy_event(datum/round_event_control/bought_event) + if(ispath(bought_event)) + bought_event = locate(bought_event) in SSevents.control //might be able to make this slightly cheaper by searching in the track sorted list + var/track = bought_event.track + if(!track || (bought_event in SSgamemode.uncategorized)) + return FALSE //trackless events cant be bought + + var/datum/controller/subsystem/gamemode/mode = SSgamemode + if(mode.event_track_points[track] - (bought_event.cost * mode.point_thresholds[track]) < 0) + return FALSE + + buy_event(bought_event, track) + return TRUE + +/// Find and buy a valid event from a track. +/datum/storyteller/proc/buy_event(datum/round_event_control/bought_event, track, forced = FALSE) + if(!track) + track = bought_event.track + + var/datum/controller/subsystem/gamemode/mode = SSgamemode + // Perhaps use some bell curve instead of a flat variance? + var/total_cost = bought_event.cost * mode.point_thresholds[track] + if(!bought_event.roundstart) + total_cost *= (1 + (rand(-cost_variance, cost_variance)/100)) //Apply cost variance if not roundstart event + mode.event_track_points[track] = max(mode.event_track_points[track] - total_cost, 0) + message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") + if(bought_event.roundstart) + SSgamemode.ran_roundstart = TRUE + mode.TriggerEvent(bought_event, forced) + else + mode.schedule_event(bought_event, 3 MINUTES, total_cost, _forced = forced) + SSgamemode.triggered_round_events |= bought_event.name + +/// Calculates the weights of the events from a passed track. +/datum/storyteller/proc/calculate_weights(track) + var/datum/controller/subsystem/gamemode/mode = SSgamemode + for(var/datum/round_event_control/event as anything in mode.event_pools[track]) + var/weight_total = event.weight + /// Apply tag multipliers if able + if(tag_multipliers) + for(var/tag in tag_multipliers) + if(tag in event.tags) + weight_total *= tag_multipliers[tag] + /// Apply occurence multipliers if able + var/occurences = event.get_occurences() + if(occurences) + ///If the event has occured already, apply a penalty multiplier based on amount of occurences + weight_total -= event.reoccurence_penalty_multiplier * weight_total * (1 - (event_repetition_multiplier ** occurences)) + /// Write it + event.calculated_weight = weight_total diff --git a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm b/modular_bandastation/storyteller/code/storytellers/data/tracks.dm deleted file mode 100644 index 7ae58b66d2aa6..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/data/tracks.dm +++ /dev/null @@ -1,15 +0,0 @@ -// A point is added every second, adjust new track threshold overrides accordingly - -/// Storyteller track data, for easy overriding of tracks without having to copypaste -/// thresholds - Used to show how many points the track has to collect before it triggers, lower means faster -/datum/storyteller_data/tracks - ///События категории Mundane - скруберы, валентинки, т.е. мелочь - var/threshold_mundane = 1200 - ///События категории Moderate - аномалии, лозы, утечка радейки - var/threshold_moderate = 1800 - ///События категории Major - пираты, рад-шторм, бюрократическая ошибка - var/threshold_major = 4000 - ///События категории Crewset - еретики, генокрады, шпионы, трейторы, нюак, малф (когда активный член экипажа становится антагом (спящий агент)) - var/threshold_crewset = 1200 - ///События категории Ghostset - ниндзя, дракон (когда гостам предлагается роль антага) - var/threshold_ghostset = 4000 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_black_orbit.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_black_orbit.dm new file mode 100644 index 0000000000000..0e4a491553e5d --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_black_orbit.dm @@ -0,0 +1,8 @@ +/datum/storyteller/black_orbit + name = "Black Orbit" + desc = "Black Orbit exist only for one purpose. To make you suffer." + welcome_text = "Suffer, b*tch!" + weight = 0 + disable_distribution = TRUE + population_max = 25 + tag_multipliers = list(TAG_COMBAT = 5, TAG_DESTRUCTIVE = 5, TAG_TARGETED = 5) diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm new file mode 100644 index 0000000000000..ec81de240ee32 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm @@ -0,0 +1,13 @@ +/datum/storyteller/bomb + name = "The Bomb" + desc = "The Bomb enjoys a good fight but abhors senseless destruction. Prefers heavy hits on single targets." + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1.2, + EVENT_TRACK_MAJOR = 1.15, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) + tag_multipliers = list(TAG_COMBAT = 1.4, TAG_DESTRUCTIVE = 2, TAG_TARGETED = 1.2) + population_min = 25 //combat based so we should have some kind of min pop(even if low) + weight = 3 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_chill.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_chill.dm new file mode 100644 index 0000000000000..073a566df487c --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_chill.dm @@ -0,0 +1,16 @@ +/datum/storyteller/chill + name = "The Chill" + desc = "The Chill will be light on events compared to other storytellers, especially so on ones involving combat, destruction, or chaos. Best for more chill rounds." + welcome_text = "The day is going slowly." + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 0.7, + EVENT_TRACK_MAJOR = 0.7, + EVENT_TRACK_ROLESET = 0.7, + EVENT_TRACK_OBJECTIVES = 1 + ) + guarantees_roundstart_roleset = FALSE + tag_multipliers = list(TAG_COMBAT = 0.6, TAG_DESTRUCTIVE = 0.7) + always_votable = TRUE //good for low pop + population_max = 45 + weight = 2 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_clown.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_clown.dm new file mode 100644 index 0000000000000..0ba6750acbd39 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_clown.dm @@ -0,0 +1,17 @@ +/datum/storyteller/clown + name = "The Clown" + desc = "The clown creates only harmless events(citation needed), its all fun and games with this one!" + welcome_text = "HONKHONKHONKHONKHONK!" + event_repetition_multiplier = 1 //can repeat things freely + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 5, //admin only, welcome to hell + EVENT_TRACK_MODERATE = 4, + EVENT_TRACK_MAJOR = 0.3, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1, + ) + tag_multipliers = list(TAG_COMMUNAL = 1.1, TAG_SPOOKY = 1.2) + guarantees_roundstart_roleset = FALSE + restricted = TRUE //admins can still use this if they want the crew to really suffer, for that reason im going all in + roundstart_prob = 75 + ignores_roundstart = TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm similarity index 59% rename from modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm rename to modular_bandastation/storyteller/code/storytellers/storyteller_default.dm index 7a994db6b64e6..07c49fb6d64eb 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_default.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm @@ -1,6 +1,5 @@ /datum/storyteller/default name = "Default Andy" desc = "Default Andy is the default Storyteller, and the comparison point for every other Storyteller. Best for an average, varied experience." - welcome_text = "If I chopped you up in a meat grinder..." - antag_divisor = 8 - storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE + always_votable = TRUE + weight = 6 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_extended.dm similarity index 64% rename from modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm rename to modular_bandastation/storyteller/code/storytellers/storyteller_extended.dm index a50398af3c7b4..a2645ed0a8907 100644 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_extended.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_extended.dm @@ -1,8 +1,8 @@ /datum/storyteller/extended name = "Extended" desc = "Extended is the absence of a Storyteller. It will not spawn a single event of any sort, or run any Antagonists. Best for rounds where the population is so low that not even peaceful storytellers are low enough." - welcome_text = "How is dorms already full? The shift hasn't even started yet." + welcome_text = "The station feels invisible to outside influence." + weight = 1 disable_distribution = TRUE - population_max = 40 - antag_divisor = 32 - storyteller_type = STORYTELLER_TYPE_CALM + population_max = 25 + diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_fragile.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_fragile.dm new file mode 100644 index 0000000000000..50e25a6dcbf72 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_fragile.dm @@ -0,0 +1,13 @@ +/datum/storyteller/fragile + name = "The Fragile" + desc = "The Fragile will create mostly internal conflict around the station, and rarely any external threats." + event_repetition_multiplier = 0.7 //Hermit has a smaller event pool, let it repeat a bit more + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1.2, + EVENT_TRACK_MODERATE = 1.1, + EVENT_TRACK_MAJOR = 0.9, + EVENT_TRACK_ROLESET = 0.9, + EVENT_TRACK_OBJECTIVES = 1 + ) + tag_multipliers = list(TAG_EXTERNAL = 0.2) + weight = 3 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_gamer.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_gamer.dm new file mode 100644 index 0000000000000..7ea1addb20f7a --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_gamer.dm @@ -0,0 +1,14 @@ +/datum/storyteller/gamer + name = "The Gamer" + desc = "The Gamer will try to create the most combat focused events, while trying to avoid purely destructive ones." + welcome_text = "You feel like a fight is brewing." + weight = 1 + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1.3, + EVENT_TRACK_MAJOR = 1.3, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) + tag_multipliers = list(TAG_COMBAT = 1.5) + population_min = 40 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_jester.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_jester.dm new file mode 100644 index 0000000000000..f330d68b91418 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_jester.dm @@ -0,0 +1,14 @@ +/datum/storyteller/jester + name = "The Jester" + desc = "The Jester will create much more events, with higher possibilities of them repeating." + event_repetition_multiplier = 0.8 + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1.2, + EVENT_TRACK_MODERATE = 1.3, + EVENT_TRACK_MAJOR = 1.3, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) + population_min = 40 + ignores_roundstart = TRUE + weight = 2 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_mystic.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_mystic.dm new file mode 100644 index 0000000000000..cf42c6bce029a --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_mystic.dm @@ -0,0 +1,6 @@ +/datum/storyteller/mystic + name = "The Mystic" + desc = "The Mystic gives events from beyond the veil, some of which may even be magic in nature." + tag_multipliers = list(TAG_SPOOKY = 1.2, TAG_MAGICAL = 1.5, TAG_SPACE = 1.1) + weight = 2 + population_min = 40 //all current magic antags are very murder and/or pop-based (eg: cult, wizard, heretic) change if we get less murdery magic antags diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_operative.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_operative.dm new file mode 100644 index 0000000000000..4a1a10d8287c1 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_operative.dm @@ -0,0 +1,23 @@ +/datum/storyteller/operative + name = "The Operative" + desc = "The Operative tries to create more direct confrontation with human threats." + welcome_text = "The eyes of multiple organizations have been set on the station." + starting_point_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1.1, + EVENT_TRACK_OBJECTIVES = 1 + ) + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 0.8, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1.2, + EVENT_TRACK_OBJECTIVES = 1 + ) + tag_multipliers = list(TAG_ALIEN = 0.4, TAG_CREW_ANTAG = 1.1) + population_min = 45 + ignores_roundstart = TRUE + weight = 1 + restricted = TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_phantom.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_phantom.dm new file mode 100644 index 0000000000000..34cb9865e3568 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_phantom.dm @@ -0,0 +1,27 @@ +/datum/storyteller/pups + name = "Poops x10" + desc = "It's super friendly storyteller, to make your game more fun." + welcome_text = "Friendship is a magic!" + + event_repetition_multiplier = 0.1 + + starting_point_multipliers = list( + EVENT_TRACK_MUNDANE = 10, + EVENT_TRACK_MODERATE = 10, + EVENT_TRACK_MAJOR = 10, + EVENT_TRACK_ROLESET = 10, + EVENT_TRACK_OBJECTIVES = 10 + ) + point_gains_multipliers = list( + EVENT_TRACK_MUNDANE = 10, + EVENT_TRACK_MODERATE = 10, + EVENT_TRACK_MAJOR = 10, + EVENT_TRACK_ROLESET = 10, + EVENT_TRACK_OBJECTIVES = 10 + ) + tag_multipliers = list(TAG_DESTRUCTIVE = 2, TAG_COMMUNAL = 2, TAG_POSITIVE = 2, TAG_MAGICAL = 2) + population_min = 15 + ignores_roundstart = TRUE + weight = 1 + restricted = TRUE + guarantees_roundstart_roleset = TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm deleted file mode 100644 index fba00f5a00d94..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/_storyteller.dm +++ /dev/null @@ -1,152 +0,0 @@ -///The storyteller datum. He operates with the SSgamemode data to run events -/datum/storyteller - /// Name of our storyteller. - var/name = "Badly coded storyteller" - /// Description of our storyteller. - var/desc = "Report this to the coders." - /// Text that the players will be greeted with when this storyteller is chosen. - var/welcome_text = "The storyteller has been selected. Get ready!" - /// This is the multiplier for repetition penalty in event weight. The lower the harsher it is - var/event_repetition_multiplier = 0.6 - /// Multipliers for starting points. // TODO - Rewrite into some variation - var/list/starting_point_multipliers = list( - EVENT_TRACK_MUNDANE = 1, - EVENT_TRACK_MODERATE = 1, - EVENT_TRACK_MAJOR = 1, - EVENT_TRACK_CREWSET = 1, - EVENT_TRACK_GHOSTSET = 1, - ) - /// The datum containing track size data - var/datum/storyteller_data/tracks/track_data = /datum/storyteller_data/tracks - - /// Percentual variance in the budget of roundstart points. - var/roundstart_points_variance = 30 - - /// Multipliers of weight to apply for each tag of an event. - var/list/tag_multipliers - - /// Percentual variance in cost of the purchased events. Effectively affects frequency of events - var/cost_variance = 30 - - /// Whether the storyteller guaranteed a crewset roll (crew antag) on roundstart. (Still needs to pass pop check) - var/guarantees_roundstart_crewset = TRUE - /// Whether the storyteller has the distributions disabled. Important for ghost storytellers - var/disable_distribution = FALSE - - /// Whether people can vote for the storyteller - var/votable = TRUE - /// If defined, will need a minimum of population to be votable - var/population_min - /// If defined, it will not be votable if exceeding the population - var/population_max - /// The antag divisor, the higher it is the lower the antag cap gets. Basically means "for every antag_divisor crew, spawn 1 antag". - var/antag_divisor = 8 - /// Указывает множитель, который используется для максимального количества антагов относительно активного состава СБ, умноженного на этот множитель - var/max_sec_mult = 1 - /// Two tellers of the same intensity group can't run in 2 consecutive rounds - var/storyteller_type = STORYTELLER_TYPE_ALWAYS_AVAILABLE - var/round_start_multiplier = 10 - var/ready_cost_modifier = 1 - -/datum/storyteller/process(delta_time) - if(disable_distribution) - return - add_points(delta_time) - handle_tracks() - -/// Add points to all tracks while respecting the multipliers. -/datum/storyteller/proc/add_points(delta_time) - for(var/track in SSgamemode.event_track_points) - var/point_gain = delta_time - SSgamemode.event_track_points[track] += point_gain - SSgamemode.last_point_gains[track] = point_gain - -/// Goes through every track of the gamemode and checks if it passes a threshold to buy an event, if does, buys one. -/datum/storyteller/proc/handle_tracks() - . = FALSE //Has return value for the roundstart loop - for(var/track in SSgamemode.event_track_points) - var/points = SSgamemode.event_track_points[track] - if(points >= SSgamemode.point_thresholds[track] && find_and_buy_event_from_track(track)) - . = TRUE - -/// Find and buy a valid event from a track. -/datum/storyteller/proc/find_and_buy_event_from_track(track) - . = FALSE - var/datum/round_event_control/picked_event - if(SSgamemode.forced_next_events[track]) //Forced event by admin - /// Dont check any prerequisites, it has been forced by an admin - picked_event = SSgamemode.forced_next_events[track] - SSgamemode.forced_next_events -= track - else - var/player_pop = SSgamemode.get_correct_popcount() - var/pop_required = SSgamemode.min_pop_thresholds[track] - if(player_pop < pop_required) - message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") - log_admin("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [player_pop])") - SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - calculate_weights(track) - var/list/valid_events = list() - // Determine which events are valid to pick - for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) - if(isnull(event)) - continue - if(event.can_spawn_event(player_pop)) - valid_events[event] = event.calculated_weight - ///If we didn't get any events, remove the points inform admins and dont do anything - if(SSticker.HasRoundStarted()) - if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track] due to no valid events.") - log_admin("Storyteller failed to pick an event for track of [track] due to no valid events.") - SSgamemode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - else - if(!length(valid_events)) - return - picked_event = pick_weight(valid_events) - if(!picked_event) - message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - log_admin("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - stack_trace("WARNING: Storyteller [src] picked a null from event pool at track [track].") - return - buy_event(picked_event, track) - . = TRUE - -/// Find and buy a valid event from a track. -/datum/storyteller/proc/buy_event(datum/round_event_control/bought_event, track) - // Perhaps use some bell curve instead of a flat variance? - var/total_cost = bought_event.cost * SSgamemode.point_thresholds[track] - if(!bought_event.roundstart) - total_cost *= (1 - (rand(0, cost_variance) / 100)) //Apply cost variance if not roundstart event - else - total_cost = (total_cost / ready_cost_modifier) * bought_event.roundstart //antag_divisor / SSgamemode.get_correct_popcount() * bought_event.roundstart //Цена на покупку варьируется от количество игроков и вида ивента - - message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") - log_admin("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") - - SSgamemode.event_track_points[track] = max(0, SSgamemode.event_track_points[track] - total_cost) - - if(!SSticker.HasRoundStarted()) - SSgamemode.TriggerEvent(bought_event) - SSgamemode.recalculate_secs() - if(SSgamemode.event_track_points[track] > 0) - find_and_buy_event_from_track(track) - else - SSgamemode.schedule_event(bought_event, (rand(3, 4) MINUTES), total_cost) - -/// Calculates the weights of the events from a passed track. -/datum/storyteller/proc/calculate_weights(track) - for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) - var/weight_total = event.weight - /// Apply tag multipliers if able - if(tag_multipliers) - for(var/tag in tag_multipliers) - if(tag in event.tags) - weight_total *= tag_multipliers[tag] - /// Apply occurence multipliers if able - var/occurences = event.get_occurences() - if(occurences) - ///If the event has occured already, apply a penalty multiplier based on amount of occurences - weight_total -= event.reoccurence_penalty_multiplier * weight_total * (1 - (event_repetition_multiplier ** occurences)) - /// Write it - event.calculated_weight = round(weight_total, 1) diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm deleted file mode 100644 index b98453202967a..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_black_orbit.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/storyteller/black_orbit - name = "Black Orbit" - desc = "Black Orbit exist only for one purpose. To make you suffer." - welcome_text = "Suffer, b*tch!" - - event_repetition_multiplier = 0.1 - - track_data = /datum/storyteller_data/tracks/black_orbit - - guarantees_roundstart_crewset = FALSE - antag_divisor = 100 //Чтобы было больше антагов - population_min = 10 - - tag_multipliers = list( - TAG_COMBAT = 10, - TAG_DESTRUCTIVE = 10, - TAG_CHAOTIC = 10 - ) - storyteller_type = STORYTELLER_TYPE_INTENSE - -/datum/storyteller_data/tracks/black_orbit - threshold_mundane = 12000000 - threshold_moderate = 18000000 - threshold_major = 80000000 - threshold_crewset = 30000000 - threshold_ghostset = 80000000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm deleted file mode 100644 index 94044e9938216..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_bomb.dm +++ /dev/null @@ -1,17 +0,0 @@ -/datum/storyteller/bomb - name = "The Bomb" - desc = "The Bomb will try to make as many destructive events as possible. For when you have a full engineering team. Or not, because they all cryo'd." - welcome_text = "Somebody set up us the bomb." - track_data = /datum/storyteller_data/tracks/bomb - - tag_multipliers = list( - TAG_DESTRUCTIVE = 2 - ) - population_min = 25 - antag_divisor = 10 - storyteller_type = STORYTELLER_TYPE_INTENSE - -/datum/storyteller_data/tracks/bomb - threshold_mundane = 1800 - threshold_moderate = 1400 - threshold_major = 5500 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm deleted file mode 100644 index 28fe9254f60d1..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_chill.dm +++ /dev/null @@ -1,22 +0,0 @@ -/datum/storyteller/chill - name = "The Chill" - desc = "The Chill will be light on events compared to other storytellers, especially so on ones involving combat, destruction, or chaos. Best for more chill rounds." - welcome_text = "If you vote for this storyteller on Ice Box, you have no originality." - - track_data = /datum/storyteller_data/tracks/chill - - guarantees_roundstart_crewset = FALSE - tag_multipliers = list( - TAG_COMBAT = 0.3, - TAG_DESTRUCTIVE = 0.3, - TAG_CHAOTIC = 0.1 - ) - antag_divisor = 32 - storyteller_type = STORYTELLER_TYPE_CALM - -/datum/storyteller_data/tracks/chill - threshold_mundane = 1800 - threshold_moderate = 2700 - threshold_major = 16000 - threshold_crewset = 3600 - threshold_ghostset = 9000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm deleted file mode 100644 index 251e5fc3a429a..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_clown.dm +++ /dev/null @@ -1,24 +0,0 @@ -/datum/storyteller/clown - name = "The Clown" - desc = "The Clown will try to create the most events and antagonists out of all the storytellers, not caring for their weight. \ - As such, it can be truly chaotic and even end rounds prematurely." - welcome_text = "honk" - - track_data = /datum/storyteller_data/tracks/clown - - population_min = 50 - antag_divisor = 4 - storyteller_type = STORYTELLER_TYPE_INTENSE - -/datum/storyteller_data/tracks/clown - threshold_mundane = 700 - threshold_moderate = 1600 - threshold_major = 3200 - threshold_crewset = 1000 - threshold_ghostset = 3200 - -// All the weights are the same to the clown -/datum/storyteller/clown/calculate_weights(track) - for(var/datum/round_event_control/event as anything in SSgamemode.event_pools[track]) - if(event.weight) - event.calculated_weight = 1 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm deleted file mode 100644 index 26760d4ea2fb3..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_fragile.dm +++ /dev/null @@ -1,22 +0,0 @@ -/datum/storyteller/fragile - name = "The Fragile" - desc = "The Fragile will limit destructive, combat-focused, and chaotic events. You'll rarely see midround antagonist roles that usually cause it." - welcome_text = "Handle with care!" - - event_repetition_multiplier = 0.5 - - track_data = /datum/storyteller_data/tracks/fragile - - tag_multipliers = list( - TAG_COMBAT = 0.5, - TAG_DESTRUCTIVE = 0.1, - TAG_CHAOTIC = 0.1 - ) - storyteller_type = STORYTELLER_TYPE_CALM - -/datum/storyteller_data/tracks/fragile - threshold_mundane = 1200 - threshold_moderate = 1800 - threshold_major = 8000 - threshold_crewset = 3000 - threshold_ghostset = 8000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm deleted file mode 100644 index cdc428cbd7910..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_gamer.dm +++ /dev/null @@ -1,20 +0,0 @@ -/datum/storyteller/gamer - name = "The Gamer" - desc = "The Gamer will try to create the most combat focused events, while trying to avoid purely destructive ones." - welcome_text = "Welcome to the Gamer storyteller. Now with 50% more ahelps!" - - track_data = /datum/storyteller_data/tracks/gamer - - tag_multipliers = list( - TAG_COMBAT = 1.5, - TAG_DESTRUCTIVE = 0.7, - TAG_CHAOTIC = 1.3 - ) - population_min = 35 - antag_divisor = 5 - storyteller_type = STORYTELLER_TYPE_INTENSE - -/datum/storyteller_data/tracks/gamer - threshold_moderate = 1300 - threshold_major = 6150 - threshold_ghostset = 6000 diff --git a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm b/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm deleted file mode 100644 index 0d2395c2f5240..0000000000000 --- a/modular_bandastation/storyteller/code/storytellers/tellers/storyteller_phantom.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/storyteller/black_orbit - name = "Poops x10" - desc = "It's super friendly storyteller, to make your game more fun." - welcome_text = "Friendship is a magic!" - - event_repetition_multiplier = 0.1 - - track_data = /datum/storyteller_data/tracks/black_orbit - - guarantees_roundstart_crewset = FALSE - antag_divisor = 1 //Чтобы было больше антагов - population_min = 1000 - - tag_multipliers = list( - TAG_COMBAT = 10, - TAG_DESTRUCTIVE = 10, - TAG_CHAOTIC = 10 - ) - storyteller_type = STORYTELLER_TYPE_INTENSE - -/datum/storyteller_data/tracks/black_orbit - threshold_mundane = 60 - threshold_moderate = 120 - threshold_major = 180 - threshold_crewset = 240 - threshold_ghostset = 300 diff --git a/modular_bandastation/storyteller/code/vote.dm b/modular_bandastation/storyteller/code/vote.dm index 32e4bfa7976f4..4eddcab85642f 100644 --- a/modular_bandastation/storyteller/code/vote.dm +++ b/modular_bandastation/storyteller/code/vote.dm @@ -8,61 +8,26 @@ name = "Storyteller" default_message = "Vote for the storyteller!" has_desc = TRUE - count_method = VOTE_COUNT_METHOD_MULTI - winner_method = VOTE_WINNER_METHOD_SIMPLE + player_startable = FALSE + /datum/vote/storyteller/New() . = ..() default_choices = list() default_choices = SSgamemode.storyteller_vote_choices() + /datum/vote/storyteller/return_desc(vote_name) return SSgamemode.storyteller_desc(vote_name) /datum/vote/storyteller/create_vote() . = ..() - if((length(choices) == 1)) // Only one choice, no need to vote. + if((length(choices) == 1)) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining storyteller because it would just happen anyways. var/de_facto_winner = choices[1] SSgamemode.storyteller_vote_result(de_facto_winner) - to_chat(world, span_boldannounce("The storyteller vote has been skipped because there is only one storyteller left to vote for. The storyteller has been changed to [de_facto_winner].")) - return FALSE - -/datum/vote/storyteller/can_be_initiated(mob/by_who, forced = FALSE) - . = ..() - if(forced) - return TRUE - - if(SSgamemode.storyteller_voted) - default_message = "The next Storyteller has already been selected." + to_chat(world, span_boldannounce("The storyteller vote has been skipped because there is only one storyteller left to vote for. \ + The storyteller has been changed to [de_facto_winner].")) return FALSE /datum/vote/storyteller/finalize_vote(winning_option) SSgamemode.storyteller_vote_result(winning_option) - SSgamemode.storyteller_voted = TRUE - -/* -### PERSISTENCE SUBSYSTEM TRACKING BELOW ### -Basically, this keeps track of what we voted last time to prevent it being voted on again. -For this, we use the SSpersistence.last_storyteller_type variable - -We then just check what the last one is in SSgamemode.storyteller_vote_choices() -*/ - -#define STORYTELLER_LAST_FILEPATH "data/storyteller_last_round.txt" - -/// Extends collect_data -/datum/controller/subsystem/persistence/collect_data() - . = ..() - collect_storyteller_type() - -/// Loads last storyteller into last_storyteller_type -/datum/controller/subsystem/persistence/proc/load_storyteller_type() - if(!fexists(STORYTELLER_LAST_FILEPATH)) - return - last_storyteller_type = text2num(file2text(STORYTELLER_LAST_FILEPATH)) - -/// Collects current storyteller and stores it -/datum/controller/subsystem/persistence/proc/collect_storyteller_type() - rustg_file_write("[SSgamemode.storyteller.storyteller_type]", STORYTELLER_LAST_FILEPATH) - -#undef STORYTELLER_LAST_FILEPATH From 92331788467914dc38aaa007c0b3c54a8ce73376 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 14:19:06 +0300 Subject: [PATCH 049/135] =?UTF-8?q?=D0=A2=D1=80=D0=B0=D0=BD=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B9=D1=82=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/anomaly/anomaly_vortex.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/anomaly/anomaly_vortex.dm b/code/modules/events/anomaly/anomaly_vortex.dm index 06a91f52b0126..2801f61bca94a 100644 --- a/code/modules/events/anomaly/anomaly_vortex.dm +++ b/code/modules/events/anomaly/anomaly_vortex.dm @@ -4,7 +4,7 @@ min_players = 20 max_occurrences = 2 - weight = 4 //BANDASTATION EDIT - STORYTELLER: 10 ==> 4 + weight = 10 description = "This anomaly sucks in and detonates items." min_wizard_trigger_potency = 3 max_wizard_trigger_potency = 7 From dd9b21c9d8231467935c81e493b24e4fa6fcbb01 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 18:04:45 +0300 Subject: [PATCH 050/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/job.dm | 26 ++++++------------- .../event_defines/_round_event_control.dm | 2 +- .../code/event_defines/crewset/clown_ops.dm | 2 +- .../code/event_defines/ghostset/nuke_ops.dm | 2 +- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index f2d2ce05bbf3e..0437c5b02da00 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -985,16 +985,14 @@ SUBSYSTEM_DEF(job) return FALSE /// BANDASTATION EDIT START - STORYTELLER -/datum/controller/subsystem/job/proc/GetJob(rank) - if(!length(all_occupations)) - SetupOccupations() - return name_occupations[rank] - -/datum/controller/subsystem/job/proc/GetJobType(jobtype) - RETURN_TYPE(/datum/job) - if(!length(all_occupations)) - SetupOccupations() - return type_occupations[jobtype] +/datum/controller/subsystem/job/proc/FreeRole(rank) + if(!rank) + return + job_debug("Freeing role: [rank]") + var/datum/job/job = get_job(rank) + if(!job) + return FALSE + job.current_positions = max(0, job.current_positions - 1) /datum/controller/subsystem/job/proc/SetupOccupations() name_occupations = list() @@ -1064,14 +1062,6 @@ SUBSYSTEM_DEF(job) return TRUE -/datum/controller/subsystem/job/proc/FreeRole(rank) - if(!rank) - return - var/datum/job/job = GetJob(rank) - if(!job) - return FALSE - job.current_positions = max(0, job.current_positions - 1) - /datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE) var/atom/destination diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index ef956a879ecdc..d17b4b454f6c6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -99,7 +99,7 @@ var/list/enemy_players = list() if(roundstart) for(var/enemy in enemy_roles) - var/datum/job/enemy_job = SSjob.GetJob(enemy) + var/datum/job/enemy_job = SSjob.get_job(enemy) if(enemy_job && SSjob.assigned_players_by_job[enemy_job.type]) job_check += length(SSjob.assigned_players_by_job[enemy_job.type]) enemy_players += SSjob.assigned_players_by_job[enemy_job.type] diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index ac861fa28ea36..95ae22b8dec28 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -62,7 +62,7 @@ for(var/obj/item/item as anything in items) qdel(item) - antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/clown_operative)) + antag_mind.set_assigned_role(SSjob.get_job_type(/datum/job/clown_operative)) antag_mind.special_role = ROLE_CLOWN_OPERATIVE var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm index edb3e3551c868..96e6b434d51b4 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -52,7 +52,7 @@ qdel(item) var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) - antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/nuclear_operative)) + antag_mind.set_assigned_role(SSjob.get_job_type(/datum/job/nuclear_operative)) antag_mind.special_role = ROLE_NUCLEAR_OPERATIVE if(!most_experienced) From 9cbf9da4a69ea2891e0c39efa57fe106b4221631 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 19:01:41 +0300 Subject: [PATCH 051/135] =?UTF-8?q?=D0=97=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=BB=D1=8C=20=D0=B2=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 9815fa04097c7..4f1eaab7c55a7 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -920,7 +920,7 @@ SUBSYSTEM_DEF(gamemode) var/upper = point_thresholds[track] var/percent = round((lower/upper)*100) var/next = 0 - var/last_points = last_point_gains[track] + var/last_points = last_point_gains[track] != 0 ? last_point_gains[track] : 1 if(last_points) next = round(((upper - lower) / last_points / STORYTELLER_WAIT_TIME)) dat += "" From cd7c5d1f12a616e3764225cc54715795b151e249 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 19:06:15 +0300 Subject: [PATCH 052/135] =?UTF-8?q?=D0=97=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=BD=D1=83=D0=BB=D1=8F=20=D0=B2=20=D0=BF=D0=B0?= =?UTF-8?q?=D0=BD=D0=B5=D0=BB=D0=B8=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 4f1eaab7c55a7..fcfaf9c04ddf9 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -999,7 +999,7 @@ SUBSYSTEM_DEF(gamemode) if(last_point_gains[track]) var/lower = event_track_points[track] var/upper = point_thresholds[track] - var/last_points = last_point_gains[track] + var/last_points = last_point_gains[track] != 0 ? last_point_gains[track] : 1 var/est_time = round(((upper - lower) / last_points / STORYTELLER_WAIT_TIME)) dat += "[track]: ~[est_time] secs. | " dat += "
" From dd15ba019587e1a53d2c1cc3405c2a7305dcd823 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 19:20:54 +0300 Subject: [PATCH 053/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 0ccec476964a9..c026c80e0c06c 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -38,7 +38,7 @@ OBJECTIVES_ROUNDSTART_POINT_MULTIPLIER 1 ## Minimum population caps for event tracks to run their events. MUNDANE_MIN_POP 0 MODERATE_MIN_POP 0 -MAJOR_MIN_POP 0 +MAJOR_MIN_POP 20 ROLESET_MIN_POP 0 OBJECTIVES_MIN_POP 0 From 157deb915e40cede7e27b1db164ca96e0a83aae9 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 19:48:43 +0300 Subject: [PATCH 054/135] =?UTF-8?q?=D0=9E=D1=82=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=20=D0=BD=D0=B0=20=D1=81=D0=BE=D0=B3=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D0=B8=D0=B5=20=D0=B1=D1=8B=D1=82=D1=8C=20=D0=B0=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D0=B3=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 1 - .../storyteller/code/event_defines/_round_event.dm | 2 +- .../storyteller/code/event_defines/crewset/blood_brothers.dm | 2 +- .../storyteller/code/event_defines/crewset/changeling.dm | 2 +- .../storyteller/code/event_defines/crewset/heretic.dm | 2 +- .../storyteller/code/event_defines/crewset/obsessed.dm | 2 +- .../storyteller/code/event_defines/crewset/traitors.dm | 2 +- .../storyteller/code/event_defines/ghostset/nuke_ops.dm | 2 +- .../storyteller/code/event_defines/ghostset/paradox_clone.dm | 2 +- .../storyteller/code/event_defines/ghostset/wizard.dm | 2 +- 10 files changed, 9 insertions(+), 10 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index bd88060c8013c..51c73080bf8e9 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -117,7 +117,6 @@ return FALSE return TRUE - /datum/round_event_control/proc/preRunEvent(forced = FALSE) /// BANDASTATION EDIT - STORYTELLER if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 279f033a07bca..54d66bc91acb9 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -43,7 +43,7 @@ /// The minds we've setup in setup() and need to finalize in start() var/list/setup_minds = list() /// Whether we prompt the players before picking them. - var/prompted_picking = FALSE //TODO: Implement this + var/prompted_picking = FALSE /// DO NOT SET THIS MANUALLY, THIS IS INHERITED FROM THE EVENT CONTROLLER ON NEW var/list/extra_spawned_events /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 4a6881e805cad..dfc29d2d20895 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -43,7 +43,7 @@ /datum/round_event_control/antagonist/solo/brother/midround name = "Sleeper Agents (Blood Brothers)" - prompted_picking = TRUE + prompted_picking = FALSE required_enemies = 2 /datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 9825ab7f68f37..609dd7c977a80 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -27,4 +27,4 @@ /datum/round_event_control/antagonist/solo/changeling/midround name = "Genome Awakening (Changelings)" - prompted_picking = TRUE + prompted_picking = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 54189f3e9c5ec..f547a93e9a0ee 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -29,4 +29,4 @@ /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" - prompted_picking = TRUE + prompted_picking = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index fea5ec4c14f4f..96ec6d0ee7511 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -12,5 +12,5 @@ /datum/round_event_control/antagonist/solo/obsessed/midround name = "Compulsive Obsession" - prompted_picking = TRUE + prompted_picking = FALSE maximum_antags = 4 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 653e572694213..0d34b87bcefd3 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -30,4 +30,4 @@ name = "Sleeper Agents (Traitors)" antag_flag = ROLE_SLEEPER_AGENT antag_datum = /datum/antagonist/traitor/infiltrator/sleeper_agent - prompted_picking = TRUE + prompted_picking = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm index 96e6b434d51b4..520ca53ad2dc8 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -35,7 +35,7 @@ earliest_start = 45 MINUTES weight = 4 max_occurrences = 1 - prompted_picking = TRUE + prompted_picking = FALSE /datum/round_event/antagonist/solo/ghost/nuclear_operative excute_round_end_reports = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index eccc3e4944640..9516598c28f86 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -15,7 +15,7 @@ required_enemies = 2 weight = 6 max_occurrences = 2 - prompted_picking = TRUE + prompted_picking = FALSE /datum/round_event/antagonist/solo/ghost/paradox_clone var/list/possible_spawns = list() ///places the antag can spawn diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm index a581c1150da38..41b92c6033305 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm @@ -21,7 +21,7 @@ weight = 2 min_players = 35 max_occurrences = 1 - prompted_picking = TRUE + prompted_picking = FALSE /datum/round_event_control/antagonist/solo/ghost/wizard/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) . = ..() From 0816d08ca06f4084c2eed10e86e86f78227d443c Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 20:39:09 +0300 Subject: [PATCH 055/135] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=D0=B9=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=20?= =?UTF-8?q?=D0=BD=D0=B5=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= =?UTF-8?q?,=20=D1=84=D0=B8=D0=BA=D1=81=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=A1=D0=A2=20?= =?UTF-8?q?=D0=BC=D0=B8=D0=B4=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 4 +- .../event_defines/_round_event_control.dm | 37 ++++++++++++++++++- .../storyteller/code/gamemode.dm | 5 +++ .../code/storytellers/storyteller_bomb.dm | 1 + 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 51c73080bf8e9..7db5c5e819e25 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -102,6 +102,8 @@ return FALSE if(allowed_storytellers && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) return FALSE + if(allowed_storytellers && SSgamemode.current_storyteller && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) + return FALSE if(eng_required_power < SSgamemode.current_eng_power) return FALSE if(med_required_power < SSgamemode.current_med_power) @@ -110,8 +112,6 @@ return FALSE if(head_required_power < SSgamemode.current_head_power) return FALSE - if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) - return FALSE /// BANDASTATION EDIT END - STORYTELLER if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index d17b4b454f6c6..85b5c7507e869 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -29,13 +29,22 @@ /datum/round_event_control/proc/return_failure_string(players_amt) var/string + if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) + string += "Storyteller halted" + if(event_group && !GLOB.event_groups[event_group].can_run()) + if(string) + string += "," + string += "Group runing" if(roundstart && (world.time-SSticker.round_start_time >= 2 MINUTES)) + if(string) + string += "," string += "Roundstart" + /// BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) if(string) string += "," string += "Cap Reached" - if(earliest_start >= world.time-SSticker.round_start_time) + if(earliest_start >= (world.time - SSticker.round_start_time)) if(string) string += "," string +="Too Soon" @@ -51,11 +60,37 @@ if(string) string += "," string += "Round End" + if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) + return FALSE if(checks_antag_cap) if(!roundstart && !SSgamemode.can_inject_antags()) if(string) string += "," string += "Too Many Antags" + if(allowed_storytellers && SSgamemode.current_storyteller && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) + if(string) + string += "," + string += "Wrong Storyteller" + if(eng_required_power < SSgamemode.current_eng_power) + if(string) + string += "," + string += "Too low eng power" + if(med_required_power < SSgamemode.current_med_power) + if(string) + string += "," + string += "Too low med power" + if(rnd_required_power < SSgamemode.current_rnd_power) + if(string) + string += "," + string += "Too low rnd power" + if(head_required_power < SSgamemode.current_head_power) + if(string) + string += "," + string += "Too low head power" + if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) + if(string) + string += "," + string += "Hijack mission" return string /datum/round_event_control/antagonist/return_failure_string(players_amt) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index fcfaf9c04ddf9..7d02117c5e950 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -854,7 +854,12 @@ SUBSYSTEM_DEF(gamemode) message_admins("Attempted to set an invalid storyteller type: [passed_type], force setting to guide instead.") current_storyteller = storytellers[/datum/storyteller/default] //if we dont have any then we brick, lets not do that CRASH("Attempted to set an invalid storyteller type: [passed_type].") + var/passed_state = FALSE + if (current_storyteller) + passed_state = current_storyteller.round_started + current_storyteller.round_started = FALSE current_storyteller = storytellers[passed_type] + current_storyteller.round_started = passed_state if(!secret_storyteller) send_to_playing_players(span_notice("Storyteller is [current_storyteller.name]!")) send_to_playing_players(span_notice("[current_storyteller.welcome_text]")) diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm index ec81de240ee32..643b88dbff583 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_bomb.dm @@ -1,6 +1,7 @@ /datum/storyteller/bomb name = "The Bomb" desc = "The Bomb enjoys a good fight but abhors senseless destruction. Prefers heavy hits on single targets." + welcome_text = "GLA! GLA! GLA!" point_gains_multipliers = list( EVENT_TRACK_MUNDANE = 1, EVENT_TRACK_MODERATE = 1.2, From c6210063ad131c2d7784fe4e6930f74abffa09f3 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 6 Dec 2024 21:24:36 +0300 Subject: [PATCH 056/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D1=82=D0=B0=20(=D1=80=D0=B0=D0=B7=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=BE=D1=80=D1=81?= =?UTF-8?q?=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BA=D0=B0=D0=BA=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D1=83)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 6 +++--- .../storyteller/code/event_defines/_round_event_control.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 2 ++ .../storyteller/code/storytellers/_storyteller.dm | 4 +++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 1a532d89d173f..352bc62d1bf3f 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -229,12 +229,12 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/setup() to_chat(world, span_boldannounce("Starting game...")) var/init_start = world.timeofday - + // BANDASTATION EDIT BEGIN - STORYTELLER + SSgamemode.init_storyteller() CHECK_TICK //Configure mode and assign player to antagonists var/can_continue = FALSE - // BANDASTATION EDIT BEGIN - STORYTELLER - SSgamemode.init_storyteller() + CHECK_TICK can_continue = SSgamemode.pre_setup() // BANDASTATION EDIT END - STORYTELLER diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 85b5c7507e869..275446ec43a23 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -301,7 +301,7 @@ if("schedule") message_admins("[key_name_admin(usr)] scheduled event [src.name].") log_admin_private("[key_name(usr)] scheduled [src.name].") - SSgamemode.current_storyteller.buy_event(src, src.track) + SSgamemode.schedule_event(src, 1 SECONDS, 0, _forced = FALSE) if("force_next") if(length(src.admin_setup)) for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 7d02117c5e950..e73df4019a1a1 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -868,6 +868,8 @@ SUBSYSTEM_DEF(gamemode) /// Panel containing information, variables and controls about the gamemode and scheduled event /datum/controller/subsystem/gamemode/proc/admin_panel(mob/user) + if(!current_storyteller) + set_storyteller(selected_storyteller) update_crew_infos() var/round_started = SSticker.HasRoundStarted() var/list/dat = list() diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index ae6abe2d33f50..d8b9973684e7d 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -145,7 +145,9 @@ stack_trace("WARNING: Storyteller picked a null from event pool.") SSgamemode.event_track_points[track] = 0 return - buy_event(picked_event, track, are_forced) + + if(picked_event) + buy_event(picked_event, track, are_forced) . = TRUE ///Attempt to buy a specific event if we can afford it, otherwise returns FALSE, note this does NOT take cost variance into account From a936d2d203721e7c5dade663f7830d855f7394e2 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 7 Dec 2024 17:24:05 +0300 Subject: [PATCH 057/135] =?UTF-8?q?=D0=A7=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BC=D0=B5=D1=80=D0=B4=D0=B6?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=B0=D0=B2=D1=82=D0=BE=D1=88=D0=B0=D1=82?= =?UTF-8?q?=D1=82=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 8 -------- .../game/code/_game_options.dm | 18 ------------------ 2 files changed, 26 deletions(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 91944eeac366d..6fd7c5a0a6f5c 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -66,14 +66,6 @@ MAJOR_POP_SCALE_PENALTY 30 ROLESET_POP_SCALE_PENALTY 30 OBJECTIVES_POP_SCALE_PENALTY 30 -## How long (in minutes) after roundstart should the server start an automatic crew transfer vote? -## Defaults to 90 minutes. Set to 0 to completely disable automatic crew transfer votes. -TRANSFER_VOTE_TIME 90 - -## If players vote against a crew transfer, how long (in minutes) until another automatic transfer vote will be initiated? -## Defaults to 30 minutes. Set to 0 to completely disable subsequent crew transfer votes. -SUBSEQUENT_TRANSFER_VOTE_TIME 30 - ## Automatic crew transfer ## Time after the roundstart the automatic crew transfer will run. 1.5 hours by default diff --git a/modular_bandastation/game/code/_game_options.dm b/modular_bandastation/game/code/_game_options.dm index 9857758ee641a..8d4c8e7d896e1 100644 --- a/modular_bandastation/game/code/_game_options.dm +++ b/modular_bandastation/game/code/_game_options.dm @@ -3,21 +3,3 @@ /datum/config_entry/flag/disable_storyteller /datum/config_entry/flag/log_antag_rep - -/datum/config_entry/number/transfer_vote_time - default = 90 MINUTES - min_val = 0 - -/datum/config_entry/number/transfer_vote_time/ValidateAndSet(str_val) - . = ..() - if(.) - config_entry_value *= 600 // documented as minutes - -/datum/config_entry/number/subsequent_transfer_vote_time - default = 30 MINUTES - min_val = 0 - -/datum/config_entry/number/subsequent_transfer_vote_time/ValidateAndSet(str_val) - . = ..() - if(.) - config_entry_value *= 600 // documented as minutes From 1384cf8dedbec75ac2253ff914893b810c9d0377 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 8 Dec 2024 19:23:58 +0300 Subject: [PATCH 058/135] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE?= =?UTF-8?q?=D0=BA=20=D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=BA=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 7db5c5e819e25..3d8180e514351 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -104,13 +104,13 @@ return FALSE if(allowed_storytellers && SSgamemode.current_storyteller && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) return FALSE - if(eng_required_power < SSgamemode.current_eng_power) + if(eng_required_power > SSgamemode.current_eng_power) return FALSE - if(med_required_power < SSgamemode.current_med_power) + if(med_required_power > SSgamemode.current_med_power) return FALSE - if(rnd_required_power < SSgamemode.current_rnd_power) + if(rnd_required_power > SSgamemode.current_rnd_power) return FALSE - if(head_required_power < SSgamemode.current_head_power) + if(head_required_power > SSgamemode.current_head_power) return FALSE /// BANDASTATION EDIT END - STORYTELLER if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) From 575c83d0f326be4d2636d6e5f45cb4ae42c59128 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 8 Dec 2024 19:29:25 +0300 Subject: [PATCH 059/135] =?UTF-8?q?=D0=9A=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE=D0=BA?= =?UTF-8?q?=D0=B0=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0=B9=20=D0=A0=D0=9D?= =?UTF-8?q?=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/_round_event_control.dm | 8 ++++---- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 275446ec43a23..ce46318549c30 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -71,19 +71,19 @@ if(string) string += "," string += "Wrong Storyteller" - if(eng_required_power < SSgamemode.current_eng_power) + if(eng_required_power > SSgamemode.current_eng_power) if(string) string += "," string += "Too low eng power" - if(med_required_power < SSgamemode.current_med_power) + if(med_required_power > SSgamemode.current_med_power) if(string) string += "," string += "Too low med power" - if(rnd_required_power < SSgamemode.current_rnd_power) + if(rnd_required_power > SSgamemode.current_rnd_power) if(string) string += "," string += "Too low rnd power" - if(head_required_power < SSgamemode.current_head_power) + if(head_required_power > SSgamemode.current_head_power) if(string) string += "," string += "Too low head power" diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index e73df4019a1a1..b6e01e5a73b40 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -876,7 +876,7 @@ SUBSYSTEM_DEF(gamemode) dat += "Storyteller: [current_storyteller ? "[current_storyteller.name]" : "None"] " dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." - dat += "
Active Players: [active_players] (Head: [head_crew]/[current_head_power], Sec: [sec_crew], Eng: [eng_crew]/[current_eng_power], Med: [med_crew]/[current_med_power], RnD: [med_crew]/[current_rnd_power])" + dat += "
Active Players: [active_players] (Head: [head_crew]/[current_head_power], Sec: [sec_crew], Eng: [eng_crew]/[current_eng_power], Med: [med_crew]/[current_med_power], RnD: [rnd_crew]/[current_rnd_power])" dat += "
Antagonist Count vs Maximum: [get_antag_count()] / [get_antag_cap()]" dat += "
" dat += "Main" From 4ca9716b93a47bd5d31b54b922134d48ee343e28 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 8 Dec 2024 20:24:25 +0300 Subject: [PATCH 060/135] =?UTF-8?q?SSEvents=20=D0=B1=D1=83=D0=B4=D0=B5?= =?UTF-8?q?=D1=82=20=D0=BF=D1=8B=D1=82=D0=B0=D1=82=D1=8C=D1=81=D1=8F=20?= =?UTF-8?q?=D0=BA=D1=83=D0=BF=D0=B8=D1=82=D1=8C=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B5=20=D0=B0=20=D0=BD=D0=B5=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=BA=D0=B0=D1=82=D1=8C=20=D0=B5=D0=B3=D0=BE.=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=84=D0=B5=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B2=20?= =?UTF-8?q?=D0=BF=D1=83=D0=BB=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= =?UTF-8?q?.=20=D0=A1=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F,=20=D0=BA=D0=BE=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=20=D1=81=D1=82=D1=80=D0=B5=D0=BB=D1=8C=D0=BD=D1=83?= =?UTF-8?q?=D0=BB=D0=BE=20=D0=BD=D0=B0=D1=81=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=B8=D0=B7=20=D1=80=D0=B0=D1=81=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D0=A1=D0=A2=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9,=20=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=B0=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D1=8B=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F.=20=D0=92=D1=8B=D0=BD=D0=BE=D1=81=20=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8=D1=82=D0=B5=D0=BB=D1=8F=20=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D1=8F=D0=BC=D0=BE=D0=B3=D0=BE=20=D0=B7=D0=BD=D0=B0=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=D0=BB=D0=BB=D0=B5=D1=80=D0=B0.=20=D0=A4?= =?UTF-8?q?=D0=B8=D0=BA=D1=81=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0=D1=81=D1=87?= =?UTF-8?q?=D0=B5=D1=82=D0=B0=20=D1=81=D0=B8=D0=BB=20=D0=BE=D1=82=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=BE=D0=B2.=20=D0=A4=D0=B8=D0=BA=D1=81=20=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D1=82=D0=B0=D0=B9=D0=BC=D0=B0=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BA=D1=83=D0=BF=D0=BA=D0=B5=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=83=D1=81=D1=82=D0=BE=D0=BC=20=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=B5=20(SSEvents)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/events.dm | 10 +++++++--- modular_bandastation/storyteller/_storyteller.dme | 1 + .../code/event_defines/crewset/blob_infection.dm | 12 ++++++++++++ modular_bandastation/storyteller/code/gamemode.dm | 15 +++++++++------ .../storyteller/code/scheduled_event.dm | 1 + .../storyteller/code/storytellers/_storyteller.dm | 8 +++++++- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index d87c86a78da81..edf1fbee78ac9 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -106,9 +106,13 @@ SUBSYSTEM_DEF(events) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) - message_admins("SSevents runs a event: [event_to_trigger.name]!") - log_game("SSevents runs a event: [event_to_trigger.name]!") - event_to_trigger.run_event(random = TRUE) + /// BANDASTATION EDIT START - STORYTELLER + //event_to_trigger.run_event(random = TRUE) + message_admins("SSevents runs and try to buy a event: [event_to_trigger.name]!") + log_game("SSevents runs and try to buy a event: [event_to_trigger.name]!") + SSgamemode.current_storyteller.try_buy_event(src) + /// BANDASTATION EDIT END - STORYTELLER + ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. /datum/controller/subsystem/events/proc/toggleWizardmode() diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index fa99b05c6fee1..d9322e5dd6784 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -13,6 +13,7 @@ #include "code\events\summon_wizard.dm" #include "code\event_defines\crewset\_override.dm" +#include "code\event_defines\crewset\blob_infection.dm" #include "code\event_defines\crewset\changeling.dm" #include "code\event_defines\crewset\heretic.dm" #include "code\event_defines\crewset\malf.dm" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm new file mode 100644 index 0000000000000..14887ff82b389 --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm @@ -0,0 +1,12 @@ +/datum/round_event_control/antagonist/solo/blob + track = EVENT_TRACK_ROLESET + tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_EXTERNAL, TAG_ALIEN) + earliest_start = 60 MINUTES + checks_antag_cap = TRUE + antag_flag = ROLE_BLOB_INFECTION + min_players = 20 + antag_datum = /datum/antagonist/blob/infection + +/datum/round_event_control/antagonist/solo/blob/midround + name = "Blob infection (Blob)" + prompted_picking = FALSE diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index b6e01e5a73b40..82a6e5ad68442 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -245,8 +245,11 @@ SUBSYSTEM_DEF(gamemode) /// Gets the number of antagonists the antagonist injection events will stop rolling after. /datum/controller/subsystem/gamemode/proc/get_antag_cap() - var/total_number = get_correct_popcount() + (sec_crew * 2) - var/cap = FLOOR((total_number / ANTAG_CAP_DENOMINATOR), 1) + ANTAG_CAP_FLAT + var/pop_count = get_correct_popcount() + if(pop_count < current_storyteller.min_antag_popcount) + return 0 + var/total_number = pop_count + (sec_crew * 2) + var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) + current_storyteller.antag_flat_cap return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() @@ -473,16 +476,16 @@ SUBSYSTEM_DEF(gamemode) var/datum/job/player_role = player_mob.mind.assigned_role if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) head_crew++ - current_head_power = is_intern ? 0 : (playtime / 100) + current_head_power += is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_ENGINEERING) eng_crew++ - current_eng_power = is_intern ? 0 : (playtime / 100) + current_eng_power += is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_MEDICAL) med_crew++ - current_med_power = is_intern ? 0 : (playtime / 100) + current_med_power += is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SCIENCE) rnd_crew++ - current_rnd_power = is_intern ? 0 : (playtime / 100) + current_rnd_power += is_intern ? 0 : (playtime / 100) if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) sec_crew++ update_pop_scaling() diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index cfb67a2dcf725..8bfc18087fedb 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -92,3 +92,4 @@ message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") try_fire() + SSgamemode.remove_scheduled_event(src) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index d8b9973684e7d..5cd5a469f9eb8 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -58,6 +58,12 @@ var/always_votable = FALSE ///weight this has of being picked for random storyteller/showing up in the vote if not always_votable var/weight = 0 + ///Количество игроков на сервере, чтобы сторителлер начинал расчеты максимального количества антагов + var/min_antag_popcount = 20 + ///Количество игроков на сервере, которое требуется чтобы появился хотя бы один антаг (по умолчанию 30) + var/antag_denominator = ANTAG_CAP_DENOMINATOR + ///Количество антагов, которое СТ может добавить сверх расчетов + var/antag_flat_cap = ANTAG_CAP_FLAT /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff @@ -146,7 +152,7 @@ SSgamemode.event_track_points[track] = 0 return - if(picked_event) + if(picked_event && track) buy_event(picked_event, track, are_forced) . = TRUE From c19987208cda40df157f10baa2f1e69515780bfb Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 8 Dec 2024 21:01:17 +0300 Subject: [PATCH 061/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20=D1=88=D0=B5=D0=B4=D1=83=D0=BB?= =?UTF-8?q?=D0=BB=D0=B5=D1=80=D0=B0,=20=D0=BF=D0=BB=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D1=8C=20=D0=B2=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81?= =?UTF-8?q?=D1=8F.=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B0=20?= =?UTF-8?q?-=20=D1=83=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D1=8F=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=BE=20=D0=B3?= =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B2=D1=8B=D1=85=20=D0=B8=D0=B3=D1=80=D0=BE?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20=D1=80=D0=B0=D1=83?= =?UTF-8?q?=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/pirate/pirate_event.dm | 2 +- code/modules/events/_event.dm | 8 ++++---- code/modules/events/wizard/petsplosion.dm | 2 +- .../code/event_defines/_round_event_control.dm | 9 ++++++--- modular_bandastation/storyteller/code/gamemode.dm | 6 +++--- modular_bandastation/storyteller/code/scheduled_event.dm | 3 +-- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm index 5ecefa3094d45..a8613cb54cbe2 100644 --- a/code/modules/antagonists/pirate/pirate_event.dm +++ b/code/modules/antagonists/pirate/pirate_event.dm @@ -14,7 +14,7 @@ admin_setup = list(/datum/event_admin_setup/listed_options/pirates) map_flags = EVENT_SPACE_ONLY -/datum/round_event_control/pirates/preRunEvent() +/datum/round_event_control/pirates/preRunEvent(scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER if (SSmapping.is_planetary()) return EVENT_CANT_RUN return ..() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 3d8180e514351..b7507d79f2942 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -117,7 +117,7 @@ return FALSE return TRUE -/datum/round_event_control/proc/preRunEvent(forced = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/proc/preRunEvent(forced = FALSE, scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN @@ -126,10 +126,10 @@ triggering = TRUE - // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. - message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") /// BANDASTATION EDIT START - STORYTELLER - if(!roundstart) + if(!roundstart && !scheduled) + // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. + message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) /// BANDASTATION EDIT END - STORYTELLER var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index 58d463ab9dfd7..db85c29b7bea0 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /// Number of mobs we're going to duplicate var/mobs_to_dupe = 0 -/datum/round_event_control/wizard/petsplosion/preRunEvent() +/datum/round_event_control/wizard/petsplosion/preRunEvent(scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER for(var/mob/living/basic/dupe_animal in GLOB.alive_mob_list) count_mob(dupe_animal) for(var/mob/living/simple_animal/dupe_animal in GLOB.alive_mob_list) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index ce46318549c30..7ee8df7ec71da 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -299,9 +299,12 @@ return switch(href_list["action"]) if("schedule") - message_admins("[key_name_admin(usr)] scheduled event [src.name].") - log_admin_private("[key_name(usr)] scheduled [src.name].") - SSgamemode.schedule_event(src, 1 SECONDS, 0, _forced = FALSE) + var/new_schedule = input(usr, "New schedule time (in seconds):", "Reschedule Event") as num|null + if(isnull(new_schedule) || QDELETED(src)) + return + message_admins("[key_name_admin(usr)] scheduled event [src.name] in [new_schedule] seconds.") + log_admin_private("[key_name(usr)] scheduled [src.name] in [new_schedule] seconds.") + SSgamemode.schedule_event(src, new_schedule SECONDS, 0, _forced = FALSE) if("force_next") if(length(src.admin_setup)) for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 82a6e5ad68442..77d3da478eda1 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -398,7 +398,7 @@ SUBSYSTEM_DEF(gamemode) event_track_points[track] = round(calc_value) /// If the storyteller guarantees an antagonist roll, add points to make it so. - if(current_storyteller.guarantees_roundstart_roleset && event_track_points[EVENT_TRACK_ROLESET] < point_thresholds[EVENT_TRACK_ROLESET]) + if(current_storyteller.guarantees_roundstart_roleset && event_track_points[EVENT_TRACK_ROLESET] < point_thresholds[EVENT_TRACK_ROLESET] && current_storyteller.min_antag_popcount <= get_correct_popcount()) event_track_points[EVENT_TRACK_ROLESET] = point_thresholds[EVENT_TRACK_ROLESET] /// If we have any forced events, ensure we get enough points for them @@ -510,8 +510,8 @@ SUBSYSTEM_DEF(gamemode) current_pop_scale_multipliers[track] = calculated_multiplier -/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, forced = FALSE) - . = event.preRunEvent(forced) +/datum/controller/subsystem/gamemode/proc/TriggerEvent(datum/round_event_control/event, forced = FALSE, from_schedule = FALSE) + . = event.preRunEvent(forced, scheduled = from_schedule) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event.max_occurrences = 0 else if(. == EVENT_READY) diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index 8bfc18087fedb..2b0c8e5009115 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -57,7 +57,7 @@ ///Trigger the event and remove the scheduled datum message_admins("Scheduled Event: [event] successfully triggered.") - SSgamemode.TriggerEvent(event, ignores_checks) + SSgamemode.TriggerEvent(event, ignores_checks, from_schedule = TRUE) SSgamemode.remove_scheduled_event(src) /datum/scheduled_event/Destroy() @@ -92,4 +92,3 @@ message_admins("[key_name_admin(usr)] has fired scheduled event [event.name].") log_admin_private("[key_name(usr)] has fired scheduled event [event.name].") try_fire() - SSgamemode.remove_scheduled_event(src) From 24df45b66023c63bd2f8459516d39b906bb86e76 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 9 Dec 2024 19:46:37 +0300 Subject: [PATCH 062/135] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D1=82=D1=83=D0=BC?= =?UTF-8?q?=D0=BE=D0=B2=20=D1=82=D1=80=D0=B5=D0=B9=D1=82=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/traitors.dm | 4 ++-- modular_bandastation/storyteller/code/gamemode.dm | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 0d34b87bcefd3..10d315a2669c6 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -1,5 +1,5 @@ /datum/round_event_control/antagonist/solo/traitor - antag_flag = ROLE_TRAITOR + antag_flag = ROLE_SYNDICATE_INFILTRATOR tags = list(TAG_COMBAT) antag_datum = /datum/antagonist/traitor/infiltrator protected_roles = list( @@ -21,7 +21,7 @@ /datum/round_event_control/antagonist/solo/traitor/roundstart name = "Traitors" - antag_flag = ROLE_SYNDICATE_INFILTRATOR + antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor roundstart = TRUE earliest_start = 0 SECONDS diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 77d3da478eda1..15299d01bd95c 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -331,9 +331,6 @@ SUBSYSTEM_DEF(gamemode) if(time_to_check && candidate.client.get_remaining_days(time_to_check) > 0) continue - //if(midround_antag_pref) - //continue - if(job_ban && is_banned_from(candidate.ckey, list(job_ban, ROLE_SYNDICATE))) continue candidates += candidate @@ -463,8 +460,6 @@ SUBSYSTEM_DEF(gamemode) for(var/mob/player_mob as anything in GLOB.player_list) if(!player_mob.client) continue - var/playtime = player_mob.client.get_exp_living(pure_numeric = TRUE) - is_intern = (intern_threshold >= playtime) && (player_mob.mind?.assigned_role.job_flags & JOB_CAN_BE_INTERN) if(player_mob.stat) //If they're alive continue if(player_mob.client.is_afk()) //If afk @@ -473,6 +468,8 @@ SUBSYSTEM_DEF(gamemode) continue active_players++ if(player_mob.mind?.assigned_role) + var/playtime = player_mob.client.get_exp_living(pure_numeric = TRUE) + is_intern = (intern_threshold >= playtime) && (player_mob.mind?.assigned_role.job_flags & JOB_CAN_BE_INTERN) var/datum/job/player_role = player_mob.mind.assigned_role if(player_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) head_crew++ From ee69e2957a259d54ff96b69687257f28e5e8f69e Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 9 Dec 2024 22:40:23 +0300 Subject: [PATCH 063/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B1=D0=BB?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0,=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__HELPERS/roundend.dm | 8 ++++++-- code/modules/events/_event.dm | 1 + .../storyteller/code/event_defines/_round_event.dm | 1 + .../code/event_defines/crewset/blob_infection.dm | 1 + modular_bandastation/storyteller/code/gamemode.dm | 12 +++++++++++- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index c92b69acac1f3..8b09235255176 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -310,7 +310,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) var/list/parts = list() //might want to make this a full section - parts += "
[("Storyteller: [SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "N/A"]")]
" //BANDASTATION EDIT - STORYTELLER + parts += SSgamemode.create_roundend_score() //BANDASTATION EDIT - STORYTELLER //AI laws parts += law_report() @@ -361,8 +361,11 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) else parts += "[FOURSPACES]Nobody died this shift!" + // BANDASTATION EDIT START - STORYTELLER + /* parts += "[FOURSPACES]Threat level: [SSdynamic.threat_level]" parts += "[FOURSPACES]Threat left: [SSdynamic.mid_round_budget]" + if(SSdynamic.roundend_threat_log.len) parts += "[FOURSPACES]Threat edits:" for(var/entry as anything in SSdynamic.roundend_threat_log) @@ -370,7 +373,8 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) parts += "[FOURSPACES]Executed rules:" for(var/datum/dynamic_ruleset/rule in SSdynamic.executed_rules) parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - [rule.name]: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat" - + */ + // BANDASTATION EDIT END - STORYTELLER return parts.Join("
") /client/proc/roundend_report_file() diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index b7507d79f2942..fffbaf70d6a88 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -347,6 +347,7 @@ Runs the event // Everything is done, let's clean up. if(activeFor >= end_when && activeFor >= announce_when && activeFor >= start_when) processing = FALSE + SSgamemode.runned_events += control.name // BANDASTATION EDIT - STORYTELLER kill() activeFor++ diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 54d66bc91acb9..4bddd26989632 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -3,6 +3,7 @@ var/has_started = FALSE ///have we finished setup? var/setup = FALSE + ///Записывать ли событие в лог СТ для вывода в конце раунда? var/excute_round_end_reports = FALSE /// This section of event processing is in a proc because roundstart events may get their start invoked. diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm index 14887ff82b389..e465b7abcaff9 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm @@ -6,6 +6,7 @@ antag_flag = ROLE_BLOB_INFECTION min_players = 20 antag_datum = /datum/antagonist/blob/infection + maximum_antags = 1 /datum/round_event_control/antagonist/solo/blob/midround name = "Blob infection (Blob)" diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 15299d01bd95c..a5b7ab1f04eb5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -164,6 +164,7 @@ SUBSYSTEM_DEF(gamemode) /// Are we able to run roundstart events var/can_run_roundstart = TRUE var/list/triggered_round_events = list() + var/runned_events = list() /datum/controller/subsystem/gamemode/Initialize(time, zlevel) // Populate event pools @@ -1181,7 +1182,6 @@ SUBSYSTEM_DEF(gamemode) continue event.round_end_report() - /datum/controller/subsystem/gamemode/proc/store_roundend_data() var/congealed_string = "" for(var/event_name as anything in triggered_round_events) @@ -1206,6 +1206,16 @@ SUBSYSTEM_DEF(gamemode) listed.occurrences++ listed.occurrences++ +/datum/controller/subsystem/gamemode/proc/create_roundend_score() + var/list/parts = list() + parts += "
[("Storyteller: [SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "N/A"]")]

" + parts += "Spawned durning this round events:
" + for(var/i in SSgamemode.runned_events) + parts += "[i]
" + + parts += "
" + return parts + #undef DEFAULT_STORYTELLER_VOTE_OPTIONS #undef MAX_POP_FOR_STORYTELLER_VOTE #undef ROUNDSTART_VALID_TIMEFRAME From 5600928375125ddbde157dfe984504b1aa58d241 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 9 Dec 2024 23:50:19 +0300 Subject: [PATCH 064/135] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=BC=D0=B8=D0=BD=D0=B0=D1=82=D0=BE=D1=80=20=D0=B8?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=B0=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/gamemode.dm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index a5b7ab1f04eb5..23c03250ffe63 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -886,6 +886,12 @@ SUBSYSTEM_DEF(gamemode) switch(panel_page) if(GAMEMODE_PANEL_VARIABLES) dat += "Reload Config Vars Configs located in game_options.txt." + dat += "
Storyteller Basic Variables:" + dat += "
Storyteller Antag Cap Formula: ((pop_count + secs * 2) / denominator) + addiction " + dat += "
Storyteller Antag Cap result: (([get_correct_popcount()] + [sec_crew] * 2) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" + dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" + dat += "
Antag denominator: [current_storyteller.antag_denominator]" + dat += "
Point Gains Multipliers (only over time):" dat += "
This affects points gained over time towards scheduling new events of the tracks." for(var/track in event_tracks) @@ -1131,6 +1137,18 @@ SUBSYSTEM_DEF(gamemode) return message_admins("[key_name_admin(usr)] set point threshold of [track] track to [new_value].") point_thresholds[track] = new_value + if("vars_addiction") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set addictive antags to [new_value].") + current_storyteller.antag_flat_cap = new_value + if("vars_denominator") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set antags denominator to [new_value].") + current_storyteller.antag_denominator = new_value if("reload_config_vars") message_admins("[key_name_admin(usr)] reloaded gamemode config vars.") load_config_vars() From 1ef468a3b1d961656aeefef370e7cd6b7fcdcc96 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 10 Dec 2024 00:12:41 +0300 Subject: [PATCH 065/135] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B4=D0=BB=D1=8F=20=D1=80?= =?UTF-8?q?=D1=83=D1=87=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=83=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B5=D0=BC=D0=BE=D0=B9=20=D0=A1=D0=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 10 ++++----- .../code/_defines/storyteller_defines.dm | 10 ++++----- .../storyteller/code/gamemode.dm | 21 +++++++++++++++++-- .../code/storytellers/_storyteller.dm | 4 +++- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 6fd7c5a0a6f5c..3b3e515004f6b 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -43,11 +43,11 @@ ROLESET_MIN_POP 0 OBJECTIVES_MIN_POP 0 ## Point thresholds for tracks to run events. The lesser the more frequent events will be. -MUNDANE_POINT_THRESHOLD 25 -MODERATE_POINT_THRESHOLD 50 -MAJOR_POINT_THRESHOLD 90 -ROLESET_POINT_THRESHOLD 120 -OBJECTIVES_POINT_THRESHOLD 130 +MUNDANE_POINT_THRESHOLD 500 +MODERATE_POINT_THRESHOLD 750 +MAJOR_POINT_THRESHOLD 1150 +ROLESET_POINT_THRESHOLD 1450 +OBJECTIVES_POINT_THRESHOLD 8000 ## Allows the storyteller to scale event frequencies based on population ALLOW_STORYTELLER_POP_SCALING diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 060ed3b636235..da9fe14a2d60d 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -49,11 +49,11 @@ #define GAMEMODE_PANEL_MAIN "Main" #define GAMEMODE_PANEL_VARIABLES "Variables" -#define MUNDANE_POINT_THRESHOLD 40 -#define MODERATE_POINT_THRESHOLD 70 -#define MAJOR_POINT_THRESHOLD 130 -#define ROLESET_POINT_THRESHOLD 150 -#define OBJECTIVES_POINT_THRESHOLD 170 +#define MUNDANE_POINT_THRESHOLD 500 +#define MODERATE_POINT_THRESHOLD 750 +#define MAJOR_POINT_THRESHOLD 1150 +#define ROLESET_POINT_THRESHOLD 1450 +#define OBJECTIVES_POINT_THRESHOLD 8000 #define MUNDANE_MIN_POP 4 #define MODERATE_MIN_POP 6 diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 23c03250ffe63..a4687954627aa 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -887,12 +887,17 @@ SUBSYSTEM_DEF(gamemode) if(GAMEMODE_PANEL_VARIABLES) dat += "Reload Config Vars Configs located in game_options.txt." dat += "
Storyteller Basic Variables:" - dat += "
Storyteller Antag Cap Formula: ((pop_count + secs * 2) / denominator) + addiction " - dat += "
Storyteller Antag Cap result: (([get_correct_popcount()] + [sec_crew] * 2) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" + dat += "
Storyteller Antag Low pop:[current_storyteller.min_antag_popcount]" + dat += "
This value affects how many players count as low pop and makes the antag cap value to zero if it is below." + dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * 2) / denominator) + addiction" + dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * 2) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" dat += "
Antag denominator: [current_storyteller.antag_denominator]" + dat += "
This affects how many antagonist can system spawn." + dat += "
" dat += "
Point Gains Multipliers (only over time):" + dat += "
Basic all tracks multiplayer: [current_storyteller.point_gain_base_mult]" dat += "
This affects points gained over time towards scheduling new events of the tracks." for(var/track in event_tracks) dat += "
[track]: [point_gain_multipliers[track]]" @@ -1149,6 +1154,18 @@ SUBSYSTEM_DEF(gamemode) return message_admins("[key_name_admin(usr)] set antags denominator to [new_value].") current_storyteller.antag_denominator = new_value + if("vars_lowpop") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set low pop count to [new_value].") + current_storyteller.min_antag_popcount = new_value + if("vars_basemult") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") + current_storyteller.point_gain_base_mult = new_value if("reload_config_vars") message_admins("[key_name_admin(usr)] reloaded gamemode config vars.") load_config_vars() diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 5cd5a469f9eb8..49d05b1874b2a 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -64,6 +64,8 @@ var/antag_denominator = ANTAG_CAP_DENOMINATOR ///Количество антагов, которое СТ может добавить сверх расчетов var/antag_flat_cap = ANTAG_CAP_FLAT + ///Общий множитель всех треков сторителлера (для коректировок) + var/point_gain_base_mult = 10 /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff @@ -89,7 +91,7 @@ var/datum/controller/subsystem/gamemode/mode = SSgamemode var/base_point = EVENT_POINT_GAINED_PER_SECOND * seconds_per_tick * mode.event_frequency_multiplier for(var/track in mode.event_track_points) - var/point_gain = base_point * point_gains_multipliers[track] * mode.point_gain_multipliers[track] + var/point_gain = base_point * point_gains_multipliers[track] * mode.point_gain_multipliers[track] * point_gain_base_mult if(mode.allow_pop_scaling) point_gain *= mode.current_pop_scale_multipliers[track] mode.event_track_points[track] += point_gain From 230ceb6e23d7468222894c4675c5115d37318218 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 11 Dec 2024 20:01:31 +0300 Subject: [PATCH 066/135] =?UTF-8?q?=D0=9E=D1=82=D1=86=D0=B5=D0=BF=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=87=D0=BA=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D0=B0,=20?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= =?UTF-8?q?=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=B0,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=BE=D0=B2=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B6=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 2 +- code/modules/events/_event.dm | 9 ++++--- config/bandastation/bandastation_config.txt | 4 +-- .../code/_defines/storyteller_defines.dm | 7 ++++-- .../event_defines/_round_event_control.dm | 25 +++++++++++++------ .../code/event_defines/crewset/spies.dm | 2 +- .../storyteller/code/gamemode.dm | 10 ++++---- .../code/storytellers/_storyteller.dm | 6 ++--- 8 files changed, 40 insertions(+), 25 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 352bc62d1bf3f..013d924b0a2a8 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -192,6 +192,7 @@ SUBSYSTEM_DEF(ticker) SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP) current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) + SSgamemode.init_storyteller() // BANDASTATION EDIT - STORYTELLER if(start_immediately) fire() @@ -230,7 +231,6 @@ SUBSYSTEM_DEF(ticker) to_chat(world, span_boldannounce("Starting game...")) var/init_start = world.timeofday // BANDASTATION EDIT BEGIN - STORYTELLER - SSgamemode.init_storyteller() CHECK_TICK //Configure mode and assign player to antagonists var/can_continue = FALSE diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index fffbaf70d6a88..4cfdfe476497d 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -79,6 +79,8 @@ return FALSE if(roundstart && (!SSgamemode.can_run_roundstart || (SSgamemode.ran_roundstart && !fake_check && !SSgamemode.current_storyteller?.ignores_roundstart))) return FALSE + if(!roundstart && (SSgamemode.can_run_roundstart)) + return FALSE /// BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) return FALSE @@ -95,9 +97,10 @@ if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) return FALSE /// BANDASTATION EDIT START - STORYTELLER - if(checks_antag_cap) - if(!roundstart && !SSgamemode.can_inject_antags()) - return FALSE + if(checks_antag_cap && !SSgamemode.can_inject_antags()) + return FALSE + if(!weight) + return FALSE if(!check_enemies()) return FALSE if(allowed_storytellers && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 3b3e515004f6b..2e5a817cec2f6 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -45,8 +45,8 @@ OBJECTIVES_MIN_POP 0 ## Point thresholds for tracks to run events. The lesser the more frequent events will be. MUNDANE_POINT_THRESHOLD 500 MODERATE_POINT_THRESHOLD 750 -MAJOR_POINT_THRESHOLD 1150 -ROLESET_POINT_THRESHOLD 1450 +MAJOR_POINT_THRESHOLD 1950 +ROLESET_POINT_THRESHOLD 1650 OBJECTIVES_POINT_THRESHOLD 8000 ## Allows the storyteller to scale event frequencies based on population diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index da9fe14a2d60d..56d2f222cd2b0 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -51,8 +51,8 @@ #define MUNDANE_POINT_THRESHOLD 500 #define MODERATE_POINT_THRESHOLD 750 -#define MAJOR_POINT_THRESHOLD 1150 -#define ROLESET_POINT_THRESHOLD 1450 +#define MAJOR_POINT_THRESHOLD 1950 +#define ROLESET_POINT_THRESHOLD 1650 #define OBJECTIVES_POINT_THRESHOLD 8000 #define MUNDANE_MIN_POP 4 @@ -75,6 +75,9 @@ #define ROLESET_POP_SCALE_PENALTY 35 #define OBJECTIVES_POP_SCALE_PENALTY 35 +#define STORYTELLER_BASIC_MULT 10 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 + #define STORYTELLER_VOTE "storyteller" #define EVENT_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_ROLESET, EVENT_TRACK_OBJECTIVES) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 7ee8df7ec71da..b0297ca633153 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -35,10 +35,14 @@ if(string) string += "," string += "Group runing" - if(roundstart && (world.time-SSticker.round_start_time >= 2 MINUTES)) + if(roundstart && (!SSgamemode.can_run_roundstart)) if(string) string += "," - string += "Roundstart" + string += "Roundstart only" + if(!roundstart && (SSgamemode.can_run_roundstart)) + if(string) + string += "," + string += "Not roundstart" /// BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) if(string) @@ -61,12 +65,13 @@ string += "," string += "Round End" if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) - return FALSE - if(checks_antag_cap) - if(!roundstart && !SSgamemode.can_inject_antags()) - if(string) - string += "," - string += "Too Many Antags" + if(string) + string += "," + string += "No ghost candidates" + if(checks_antag_cap && !SSgamemode.can_inject_antags()) + if(string) + string += "," + string += "Too Many Antags" if(allowed_storytellers && SSgamemode.current_storyteller && ((islist(allowed_storytellers) && !is_type_in_list(SSgamemode.current_storyteller, allowed_storytellers)) || SSgamemode.current_storyteller.type != allowed_storytellers)) if(string) string += "," @@ -75,6 +80,10 @@ if(string) string += "," string += "Too low eng power" + if(!weight) + if(string) + string += "," + string += "Can't be selected" if(med_required_power > SSgamemode.current_med_power) if(string) string += "," diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index 2231b09f25032..c66eaefaa3e1e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -1,6 +1,6 @@ /datum/round_event_control/antagonist/solo/spy name = "Spies" - roundstart = 10 + roundstart = TRUE earliest_start = 0 SECONDS antag_flag = ROLE_SPY diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index a4687954627aa..7c52e0e6bee70 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -788,11 +788,11 @@ SUBSYSTEM_DEF(gamemode) min_pop_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_min_pop) min_pop_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_min_pop) - point_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_point_threshold) - point_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_point_threshold) - point_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_point_threshold) - point_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_threshold) - point_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_threshold) + //point_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_point_threshold) + //point_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_point_threshold) + //point_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_point_threshold) + //point_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_threshold) + //point_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_threshold) /datum/controller/subsystem/gamemode/proc/handle_picking_storyteller() if(CONFIG_GET(flag/disable_storyteller)) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 49d05b1874b2a..563f38ce0dc2a 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -59,13 +59,13 @@ ///weight this has of being picked for random storyteller/showing up in the vote if not always_votable var/weight = 0 ///Количество игроков на сервере, чтобы сторителлер начинал расчеты максимального количества антагов - var/min_antag_popcount = 20 + var/min_antag_popcount = STORYTELLER_MIN_ANTAG_POPCOUNT ///Количество игроков на сервере, которое требуется чтобы появился хотя бы один антаг (по умолчанию 30) var/antag_denominator = ANTAG_CAP_DENOMINATOR ///Количество антагов, которое СТ может добавить сверх расчетов var/antag_flat_cap = ANTAG_CAP_FLAT ///Общий множитель всех треков сторителлера (для коректировок) - var/point_gain_base_mult = 10 + var/point_gain_base_mult = STORYTELLER_BASIC_MULT /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff @@ -154,7 +154,7 @@ SSgamemode.event_track_points[track] = 0 return - if(picked_event && track) + if(picked_event?.can_spawn_event(get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)) && track) buy_event(picked_event, track, are_forced) . = TRUE From 72f31ad9f712cbcdf0b52e1690a7e8458da98d35 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 00:05:04 +0300 Subject: [PATCH 067/135] =?UTF-8?q?=D0=A7=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=BD=D0=B0=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D1=8F?= =?UTF-8?q?=D0=B8=20=D0=9C=D0=BE=D0=BD=D0=BA=D0=B5,=20=D1=81=D0=BC=D0=B5?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80?= =?UTF-8?q?=D1=82-=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=BE=D0=B2,=20=D0=B2?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=20=D0=BF=D1=83=D1=81=D1=82=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=82=D0=BA=D0=B5,=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=BE=D0=BC,=20=D0=B2=D1=8B=D0=BD=D0=BE=D1=81=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82?= =?UTF-8?q?=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/game/code/_defines.dm | 1 - .../game/code/_game_options.dm | 2 - modular_bandastation/game/code/_procs.dm | 3 - .../game/code/log_categories.dm | 4 - .../code/modules/client/preferences.dm | 2 - .../code/_defines/storyteller_defines.dm | 8 +- .../storyteller/code/_helpers.dm | 49 +--- .../code/event_defines/_round_event.dm | 22 +- .../event_defines/_round_event_control.dm | 4 + .../code/event_defines/crewset/clown_ops.dm | 1 + .../code/event_defines/crewset/nuke_ops.dm | 3 +- .../code/event_defines/crewset/wizard.dm | 1 + .../event_defines/ghostset/paradox_clone.dm | 9 +- .../storyteller/code/gamemode.dm | 221 ++++++++++++++---- .../code/storytellers/_storyteller.dm | 33 ++- 15 files changed, 220 insertions(+), 143 deletions(-) diff --git a/modular_bandastation/game/code/_defines.dm b/modular_bandastation/game/code/_defines.dm index f5ae307009b61..d8bffe73c04c7 100644 --- a/modular_bandastation/game/code/_defines.dm +++ b/modular_bandastation/game/code/_defines.dm @@ -1,2 +1 @@ #define LOG_CATEGORY_STORYTELLER "storyteller" -#define LOG_CATEGORY_ANTAG_REP "antag-rep" diff --git a/modular_bandastation/game/code/_game_options.dm b/modular_bandastation/game/code/_game_options.dm index 8d4c8e7d896e1..2875224b6bf4b 100644 --- a/modular_bandastation/game/code/_game_options.dm +++ b/modular_bandastation/game/code/_game_options.dm @@ -1,5 +1,3 @@ /datum/config_entry/flag/log_storyteller /datum/config_entry/flag/disable_storyteller - -/datum/config_entry/flag/log_antag_rep diff --git a/modular_bandastation/game/code/_procs.dm b/modular_bandastation/game/code/_procs.dm index b1cb75dae0169..58e0a4d6e69ed 100644 --- a/modular_bandastation/game/code/_procs.dm +++ b/modular_bandastation/game/code/_procs.dm @@ -1,5 +1,2 @@ /proc/log_storyteller(text, list/data) logger.Log(LOG_CATEGORY_STORYTELLER, text, data) - -/proc/log_antag_rep(text, list/data) - logger.Log(LOG_CATEGORY_ANTAG_REP, text, data) diff --git a/modular_bandastation/game/code/log_categories.dm b/modular_bandastation/game/code/log_categories.dm index f2a8a5fc63171..4ced1de2423d9 100644 --- a/modular_bandastation/game/code/log_categories.dm +++ b/modular_bandastation/game/code/log_categories.dm @@ -1,7 +1,3 @@ /datum/log_category/storyteller category = LOG_CATEGORY_STORYTELLER config_flag = /datum/config_entry/flag/log_storyteller - -/datum/log_category/antag_rep - category = LOG_CATEGORY_ANTAG_REP - config_flag = /datum/config_entry/flag/log_antag_rep diff --git a/modular_bandastation/preferences/code/modules/client/preferences.dm b/modular_bandastation/preferences/code/modules/client/preferences.dm index fb515193c3727..e9111b6725e98 100644 --- a/modular_bandastation/preferences/code/modules/client/preferences.dm +++ b/modular_bandastation/preferences/code/modules/client/preferences.dm @@ -4,8 +4,6 @@ /datum/preferences max_save_slots = 5 var/loadout_points = 0 - ///our current antag rep (base is 10) - var/antag_rep = 10 /datum/preferences/proc/get_loadout_points() var/donation_level = parent.donator_level diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 56d2f222cd2b0..dd1497abeb842 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,9 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 1//20 +#define STORYTELLER_SEC_ANTAG_MODIFIER 2 +#define STORYTELLER_BASIC_MODIFIER 1 #define STORYTELLER_VOTE "storyteller" @@ -84,8 +86,8 @@ #define EVENT_PANEL_TRACKS list(EVENT_TRACK_MUNDANE, EVENT_TRACK_MODERATE, EVENT_TRACK_MAJOR, EVENT_TRACK_ROLESET, EVENT_TRACK_OBJECTIVES, UNCATEGORIZED_EVENTS, ALL_EVENTS) /// Defines for the antag cap to prevent midround injections. -#define ANTAG_CAP_FLAT 3 -#define ANTAG_CAP_DENOMINATOR 30 +#define ANTAG_CAP_FLAT 1 +#define ANTAG_CAP_DENOMINATOR 10 ///Below are defines for roundstart point pool. The GAIN ones are multiplied by ready population #define ROUNDSTART_MUNDANE_BASE 20 diff --git a/modular_bandastation/storyteller/code/_helpers.dm b/modular_bandastation/storyteller/code/_helpers.dm index 40f4a95673279..f627d4bb2ce07 100644 --- a/modular_bandastation/storyteller/code/_helpers.dm +++ b/modular_bandastation/storyteller/code/_helpers.dm @@ -1,47 +1,4 @@ -GLOBAL_LIST_INIT(blessed_ckeys, list( - "taocat" = list(3, 25), -)) //this is a lmao moment should be a json but its being left here because lol it goes ckey = list(multiplier, base) - -///adjusts antag rep by {VALUE} keeping the value above 0 -/datum/preferences/proc/adjust_antag_rep(value, multiplier = TRUE) - if(multiplier) - value *= return_rep_multiplier() - log_antag_rep("[parent]'s antag rep was adjusted by [value]") - antag_rep += value - if(antag_rep < 1) - log_antag_rep("[parent]'s antag rep was adjusted below 1 resetting to 1") - antag_rep = 1 - save_preferences() - -/datum/preferences/proc/reset_antag_rep() - var/default = return_default_antag_rep() - log_antag_rep("[parent]'s antag rep was reset to default ([default])") - antag_rep = default - save_preferences() - -/datum/preferences/proc/return_default_antag_rep() - if(!parent) - return 10 - if(!(parent.ckey in GLOB.blessed_ckeys)) - return 10 - return GLOB.blessed_ckeys[parent.ckey][2] - -/datum/preferences/proc/return_rep_multiplier() - if(!parent) - return 1 - if(!(parent.ckey in GLOB.blessed_ckeys)) - return 1 - return GLOB.blessed_ckeys[parent.ckey][1] - - -///give it a list of clients and the value aswell if it should be affected by multipliers and let er rip -/proc/mass_adjust_antag_rep(list/clients, value, mulitplier = TRUE) - for(var/client/listed_client as anything in clients) - if(!IS_CLIENT_OR_MOCK(listed_client) || QDELETED(listed_client) || QDELETED(listed_client.prefs)) - continue - listed_client.prefs.adjust_antag_rep(value, mulitplier) - -/proc/return_antag_rep_weight(list/candidates) +/proc/return_antag_weight(list/candidates) . = list() for(var/anything in candidates) var/client/client_source @@ -52,9 +9,7 @@ GLOBAL_LIST_INIT(blessed_ckeys, list( client_source = anything if(QDELETED(client_source) || !client_source.ckey) continue - .[client_source.ckey] = client_source.prefs?.antag_rep || 10 - - log_antag_rep("Returned Weighted List of [length(.)]", list("before_weight" = candidates, "after_weight" = .)) + .[client_source.ckey] = 10 /// Pick a random element from the list and remove it from the list. /proc/pick_n_take_weighted(list/list_to_pick) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 4bddd26989632..4385905f02eee 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -69,25 +69,13 @@ prompted_picking = cast_control.prompted_picking var/list/possible_candidates = cast_control.get_candidates() var/list/candidates = list() - if(cast_control == SSgamemode.current_roundstart_event && length(SSgamemode.roundstart_antag_minds)) - log_storyteller("Running roundstart antagonist assignment, event: [src], roundstart_antag_minds: [english_list(SSgamemode.roundstart_antag_minds)]") - for(var/datum/mind/antag_mind in SSgamemode.roundstart_antag_minds) - if(!antag_mind.current) - log_storyteller("Roundstart antagonist setup error: antag_mind([antag_mind]) in roundstart_antag_minds without a set mob") - continue - candidates += antag_mind.current - SSgamemode.roundstart_antag_minds -= antag_mind - log_storyteller("Roundstart antag_mind, [antag_mind]") //guh var/list/cliented_list = list() for(var/mob/living/mob as anything in possible_candidates) cliented_list += mob.client - if(length(cliented_list)) - mass_adjust_antag_rep(cliented_list, 1) - - var/list/weighted_candidates = return_antag_rep_weight(possible_candidates) + var/list/weighted_candidates = return_antag_weight(possible_candidates) while(length(weighted_candidates) && length(candidates) < antag_count) //both of these pick_n_take from weighted_candidates so this should be fine if(prompted_picking) @@ -127,8 +115,6 @@ var/mob/candidate = pick_n_take(candidates) log_storyteller("Antag event spawned mob: [candidate], special role: [candidate.mind?.special_role ? candidate.mind.special_role : "none"]") - candidate.client?.prefs.reset_antag_rep() - if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) @@ -192,8 +178,6 @@ var/list/cliented_list = list() for(var/mob/living/mob as anything in candidates) cliented_list += mob.client - if(length(cliented_list)) - mass_adjust_antag_rep(cliented_list, 1) if(prompted_picking) candidates = SSpolling.poll_candidates( @@ -207,7 +191,7 @@ chat_text_border_icon = antag_datum, ) - var/list/weighted_candidates = return_antag_rep_weight(candidates) + var/list/weighted_candidates = return_antag_weight(candidates) var/selected_count = 0 while(length(weighted_candidates) && selected_count < antag_count) var/candidate_ckey = pick_n_take_weighted(weighted_candidates) @@ -216,8 +200,6 @@ continue var/mob/candidate = candidate_client.mob - candidate_client.prefs?.reset_antag_rep() - if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) var/mob/living/carbon/human/new_human = make_body(candidate) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index b0297ca633153..6796b2e7ad4ef 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -26,6 +26,10 @@ var/med_required_power = 0 var/rnd_required_power = 0 var/head_required_power = 0 + /// Является ли событие эксклюзивным (не допускающим другие) в случае раундстарта + var/exclusive_roundstart_event = FALSE + /// Значение, которое используется при расчете стоимости покупки из раундстарт бюджета. Считается если значение 0. + var/roundstart_cost = 0 /datum/round_event_control/proc/return_failure_string(players_amt) var/string diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 95ae22b8dec28..87f174df96fff 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -36,6 +36,7 @@ earliest_start = 0 SECONDS weight = 1 max_occurrences = 1 + exclusive_roundstart_event = TRUE /datum/round_event/antagonist/solo/clown_operative excute_round_end_reports = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 679415548e20a..fc76e574ba8ae 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -36,10 +36,11 @@ earliest_start = 0 SECONDS weight = 4 max_occurrences = 3 + exclusive_roundstart_event = TRUE /datum/round_event/antagonist/solo/nuclear_operative excute_round_end_reports = TRUE - end_when = 60000 /// we will end on our own when revs win + end_when = 60000 var/static/datum/team/nuclear/nuke_team var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader var/set_leader = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index 3a70119ed5540..6bdc0352c9378 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -23,6 +23,7 @@ weight = 2 min_players = 35 max_occurrences = 1 + exclusive_roundstart_event = TRUE /datum/round_event_control/antagonist/solo/wizard/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) . = ..() diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index 9516598c28f86..5a19b5f4fed47 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -37,9 +37,6 @@ var/list/cliented_list = list() for(var/mob/living/mob as anything in candidates) cliented_list += mob.client - if(length(cliented_list)) - mass_adjust_antag_rep(cliented_list, 1) - if(prompted_picking) candidates = SSpolling.poll_ghost_candidates( @@ -51,15 +48,13 @@ chat_text_border_icon = /datum/antagonist/paradox_clone, ) - var/list/weighted_candidates = return_antag_rep_weight(candidates) var/selected_count = 0 - while(length(weighted_candidates) && selected_count < antag_count) - var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) + while(length(candidates) && selected_count < antag_count) + var/client/candidate_ckey = pick_n_take_weighted(candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) continue var/mob/candidate = candidate_client.mob - candidate_client.prefs?.reset_antag_rep() if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 7c52e0e6bee70..5635e24c8a6ba 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -138,6 +138,7 @@ SUBSYSTEM_DEF(gamemode) /// Ready players for roundstart events. var/ready_players = 0 var/active_players = 0 + var/full_sec_crew = 0 var/sec_crew = 0 var/head_crew = 0 var/eng_crew = 0 @@ -156,8 +157,6 @@ SUBSYSTEM_DEF(gamemode) var/wizardmode = FALSE //refactor this into just being a unique storyteller - /// What is our currently desired/selected roundstart event - var/datum/round_event_control/antagonist/solo/current_roundstart_event var/list/last_round_events = list() /// Has a roundstart event been run var/ran_roundstart = FALSE @@ -165,6 +164,11 @@ SUBSYSTEM_DEF(gamemode) var/can_run_roundstart = TRUE var/list/triggered_round_events = list() var/runned_events = list() + /// Список ролей перед их сбросом в начале раунда + var/list/presetuped_ocupations = list() + var/empty_event_chance = 0 + var/roundstart_budget = 0 + var/roundstart_budget_set = 0 /datum/controller/subsystem/gamemode/Initialize(time, zlevel) // Populate event pools @@ -204,30 +208,6 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/fire(resumed = FALSE) if(SSticker.round_start_time && (world.time - SSticker.round_start_time) >= ROUNDSTART_VALID_TIMEFRAME) can_run_roundstart = FALSE - else if(current_roundstart_event && length(current_roundstart_event.preferred_events)) //note that this implementation is made for preferred_events being other roundstart events - var/list/preferred_copy = current_roundstart_event.preferred_events.Copy() - var/datum/round_event_control/selected_event = pick_weight(preferred_copy) - var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) - if(ispath(selected_event)) //get the instances if we dont have them - current_roundstart_event.preferred_events = list() - for(var/datum/round_event_control/e_control as anything in preferred_copy) - current_roundstart_event.preferred_events[new e_control] = preferred_copy[e_control] - preferred_copy = current_roundstart_event.preferred_events.Copy() - selected_event = null - else if(!selected_event.can_spawn_event(player_count)) - preferred_copy -= selected_event - selected_event = null - - var/sanity = 0 - while(!selected_event && length(preferred_copy) && sanity < 100) - sanity++ - selected_event = pick_weight(preferred_copy) - if(!selected_event.can_spawn_event(player_count)) - preferred_copy -= selected_event - selected_event = null - - if(selected_event) - current_storyteller.try_buy_event(selected_event) ///Handle scheduled events for(var/datum/scheduled_event/sch_event in scheduled_events) @@ -249,7 +229,7 @@ SUBSYSTEM_DEF(gamemode) var/pop_count = get_correct_popcount() if(pop_count < current_storyteller.min_antag_popcount) return 0 - var/total_number = pop_count + (sec_crew * 2) + var/total_number = pop_count + (sec_crew * current_storyteller.sec_antag_modifier) var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) + current_storyteller.antag_flat_cap return cap @@ -343,7 +323,7 @@ SUBSYSTEM_DEF(gamemode) update_crew_infos() return active_players else - calculate_ready_players() + recalculate_ready_pop() return ready_players /// Refunds and removes a scheduled event. @@ -358,13 +338,6 @@ SUBSYSTEM_DEF(gamemode) scheduled_events -= removed qdel(removed) -/// We need to calculate ready players for the sake of roundstart events becoming eligible. -/datum/controller/subsystem/gamemode/proc/calculate_ready_players() - ready_players = 0 - for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) - if(player.ready == PLAYER_READY_TO_PLAY) - ready_players++ - /// We roll points to be spent for roundstart events, including antagonists. /datum/controller/subsystem/gamemode/proc/roll_pre_setup_points() if(current_storyteller.disable_distribution || halted_storyteller) @@ -417,10 +390,34 @@ SUBSYSTEM_DEF(gamemode) if(halted_storyteller) message_admins("WARNING: Didn't roll roundstart events (including antagonists) due to the storyteller being halted.") return + handle_pre_setup_occupations() + SSjob.reset_occupations() while(TRUE) if(!current_storyteller.handle_tracks()) break +/// Прок который сохраняет список ролей перед их сбросом. Важно, так позволяет более тонко настраивать количество СБ/Антагов +/datum/controller/subsystem/gamemode/proc/handle_pre_setup_occupations() + for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) + if(!player?.mind) + continue + var/datum/job/job_datum = get_preferenced_job(player) + var/client/client_source = player.client + presetuped_ocupations[client_source.ckey] = job_datum + +/// Прок, который пытается получить предпочтительную роль для игрока (и назначить в дальнейшем вес для нее) +/datum/controller/subsystem/gamemode/proc/get_preferenced_job(mob/dead/new_player/check_player) + var/list/available_occupations = SSjob.joinable_occupations + for(var/level in SSjob.level_order) + for(var/datum/job/job in available_occupations) + // Filter any job that doesn't fit the current level. + var/player_job_level = check_player.client?.prefs.job_preferences[job.title] + if(isnull(player_job_level)) + continue + if(player_job_level != level) + continue + return job + /// Second step of handlind roundstart events, happening after people spawn. /datum/controller/subsystem/gamemode/proc/handle_post_setup_roundstart_events() /// Start all roundstart events on post_setup immediately @@ -514,6 +511,7 @@ SUBSYSTEM_DEF(gamemode) event.max_occurrences = 0 else if(. == EVENT_READY) event.run_event(random = TRUE, admin_forced = forced) // fallback to dynamic + triggered_round_events |= event.name ///Resets frequency multiplier. /datum/controller/subsystem/gamemode/proc/resetFrequency() @@ -549,9 +547,9 @@ SUBSYSTEM_DEF(gamemode) ///Attempts to select players for special roles the mode might have. /datum/controller/subsystem/gamemode/proc/pre_setup() - calculate_ready_players() + recalculate_ready_pop() roll_pre_setup_points() - //handle_pre_setup_roundstart_events() + handle_pre_setup_roundstart_events() return TRUE ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things @@ -621,6 +619,94 @@ SUBSYSTEM_DEF(gamemode) . += station_goal.get_report() return +/datum/controller/subsystem/gamemode/proc/recalculate_ready_pop() + ready_players = 0 + sec_crew = 0 + for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) + if(player.ready == PLAYER_READY_TO_PLAY) + ready_players++ + var/client/client_source = player.client + if(QDELETED(client_source) || !client_source.ckey) + continue + var/datum/job/player_role = presetuped_ocupations[client_source.ckey] + if(player_role?.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY && !player.mind.special_role) + sec_crew++ + + roundstart_budget = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + +/datum/controller/subsystem/gamemode/proc/round_start_handle() + recalculate_ready_pop() + + if(!get_antag_cap()) + message_admins("Storyteller failed to pick an events for roundstart due low population.") + return + + var/track = EVENT_TRACK_ROLESET + var/list/valid_events = recalculate_roundstart_costs(track) + if(!length(valid_events)) + message_admins("Storyteller failed to pick an events for roundstart.") + event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + + var/list/triggered_events = list() + var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + if(pop_count < current_storyteller.min_antag_popcount) + message_admins("Not enough ready players to run roundstart events.") + return + + message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") + while(length(valid_events)) + recalculate_ready_pop() + pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count + for(var/datum/round_event_control/triggered_event as anything in triggered_events) + roundstart_budget -= triggered_event.roundstart_cost + + var/datum/round_event_control/picked_event = pick_weight(valid_events) + if(picked_event.can_spawn_event(ready_players) && roundstart_budget >= picked_event.roundstart_cost) + message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget - picked_event.roundstart_cost].") + TriggerEvent(picked_event, forced = FALSE) + // Если первое событие эксклюзивное, то отчищаем список + if(picked_event.exclusive_roundstart_event) + valid_events = list() + else + // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные + for(var/datum/round_event_control/event as anything in valid_events) + if(event.exclusive_roundstart_event) + valid_events -= event + triggered_events += picked_event + else + valid_events -= picked_event + +/datum/controller/subsystem/gamemode/proc/recalculate_roundstart_costs(track) + full_sec_crew = 0 + for(var/datum/job/job as anything in SSjob.all_occupations) + if(job.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) + full_sec_crew += job.total_positions + + /// Получить количество доступных раундстартом событий + current_storyteller.calculate_weights(track) + var/list/valid_events = list() + // Determine which events are valid to pick + for(var/datum/round_event_control/event as anything in event_pools[track]) + if(event.can_spawn_event(ready_players)) + if(QDELETED(event)) + message_admins("[event.name] was deleted!") + continue + valid_events[event] = round(event.calculated_weight * 10) + if(!length(valid_events)) + return + + for(var/datum/round_event_control/event as anything in valid_events) + var/sec_miss_crew = full_sec_crew - sec_crew + var/avg_power = full_sec_crew / current_storyteller.sec_antag_modifier + var/sec_miss_penalty = max((sec_miss_crew / avg_power), 1) + var/modified_cost = current_storyteller.antag_denominator - event.weight + var/basic_cost = ready_players / get_antag_cap() * sec_miss_penalty * current_storyteller.storyteller_basic_modifier + event.roundstart_cost = basic_cost + modified_cost + + return valid_events + /* * Generate a list of active station traits to report to the crew. * @@ -886,16 +972,43 @@ SUBSYSTEM_DEF(gamemode) switch(panel_page) if(GAMEMODE_PANEL_VARIABLES) dat += "Reload Config Vars Configs located in game_options.txt." + dat += "
" + dat += "
Storyteller Basic Variables:" dat += "
Storyteller Antag Low pop:[current_storyteller.min_antag_popcount]" dat += "
This value affects how many players count as low pop and makes the antag cap value to zero if it is below." - dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * 2) / denominator) + addiction" - dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * 2) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" + dat += "
Guarantees Roundstart Roleset: [current_storyteller.guarantees_roundstart_roleset ? "TRUE" : "FALSE" ]" + dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator) + addiction" + dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" + dat += "
Sec antag modifier: [current_storyteller.sec_antag_modifier]" dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" dat += "
Antag denominator: [current_storyteller.antag_denominator]" dat += "
This affects how many antagonist can system spawn." dat += "
" + if(!SSticker.HasRoundStarted()) + handle_pre_setup_occupations() + recalculate_ready_pop() + recalculate_roundstart_costs(EVENT_TRACK_ROLESET) + var/avg_power = full_sec_crew / current_storyteller.sec_antag_modifier + var/sec_miss_crew = full_sec_crew - sec_crew + var/sec_miss_penalty = max((sec_miss_crew / avg_power), 1) + + dat += "
Storyteller Roundstart Values:" + dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew], sec_miss_crew = [sec_miss_crew]" + dat += "
Отображает максимальное количество ролей с пометкой СБ, у скольких игроков эти должности в высоком приоритете и сколько нехватка." + dat += "
Multiplier info: Average power = full_sec_crew ([full_sec_crew]) / current_storyteller.sec_antag_modifier ([current_storyteller.sec_antag_modifier]) = [avg_power]" + dat += "
Отображает среденее значение для СБ зависящее от сторителлера." + dat += "
Multiplier info: Sec Miss Penalty = max(sec_miss_crew([sec_miss_crew]) / avg_power([avg_power]), 1) = [sec_miss_penalty]" + dat += "
Отображает штраф вызванный нехваткой СБ." + dat += "
Basic cost info: Basic cost = ready_players([ready_players]) / get_antag_cap([get_antag_cap()]) * sec_miss_penalty([sec_miss_penalty]) * current_storyteller.storyteller_basic_modifier([current_storyteller.storyteller_basic_modifier]) = [get_antag_cap() ? ready_players / get_antag_cap() * sec_miss_penalty * current_storyteller.storyteller_basic_modifier : "No ready players"]" + dat += "
Отображает базовое значение цен антагов в связи с переменными выше." + dat += "
Roundstart info: Roundstart budget = ready_players([ready_players]) + (sec_crew([sec_crew]) * current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier])) = [roundstart_budget]" + dat += "
Раундстартовый бюджет для событий, расчитанный с помощью формулы выше." + dat += "
Roundstart info: Forced Roundstart budget = [roundstart_budget_set]" + dat += "
Зафоршенный андминами раундстарт бюджет." + dat += "
" + dat += "
Point Gains Multipliers (only over time):" dat += "
Basic all tracks multiplayer: [current_storyteller.point_gain_base_mult]" dat += "
This affects points gained over time towards scheduling new events of the tracks." @@ -1004,7 +1117,7 @@ SUBSYSTEM_DEF(gamemode) if(current_storyteller) dat += "Storyteller: [current_storyteller.name]" dat += "
Repetition penalty multiplier: [current_storyteller.event_repetition_multiplier]" - dat += "
Cost variance: [current_storyteller.cost_variance]" + dat += "
Cost variance: [current_storyteller.cost_variance][SSticker.HasRoundStarted()? "" : ", roundstart_budget = [roundstart_budget_set ? roundstart_budget_set : roundstart_budget]"]" if(current_storyteller.tag_multipliers) dat += "
Tag multipliers:" for(var/tag in current_storyteller.tag_multipliers) @@ -1012,6 +1125,10 @@ SUBSYSTEM_DEF(gamemode) current_storyteller.calculate_weights(statistics_track_page) else dat += "Storyteller: None
Weight and chance statistics will be inaccurate due to the present lack of a storyteller." + + handle_pre_setup_occupations() + recalculate_ready_pop() + recalculate_roundstart_costs(EVENT_TRACK_ROLESET) dat += "
Roundstart Events Forced Roundstart events will use rolled points, and are guaranteed to trigger (even if the used points are not enough)" dat += "
Avg. event intervals: " for(var/track in event_tracks) @@ -1083,7 +1200,7 @@ SUBSYSTEM_DEF(gamemode) if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) weight_string = "[percent]% - [weight_string]" - dat += "[weight_string]" //Weight + dat += "[SSticker.HasRoundStarted() && event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight dat += "[event.get_href_actions()]" //Actions dat += "" dat += "" @@ -1148,6 +1265,12 @@ SUBSYSTEM_DEF(gamemode) return message_admins("[key_name_admin(usr)] set addictive antags to [new_value].") current_storyteller.antag_flat_cap = new_value + if("vars_sec_antag") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set sec antag modifier to [new_value].") + current_storyteller.sec_antag_modifier = new_value if("vars_denominator") var/new_value = input(usr, "New value:", "Set new value") as num|null if(isnull(new_value) || new_value < 0) @@ -1166,6 +1289,22 @@ SUBSYSTEM_DEF(gamemode) return message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") current_storyteller.point_gain_base_mult = new_value + if("vars_guarante_roundstart") + var/new_value = !current_storyteller.guarantees_roundstart_roleset + message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") + current_storyteller.guarantees_roundstart_roleset = new_value + if("vars_roundstart_budget") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set forced roundstart budget to [new_value].") + roundstart_budget_set = new_value + if("vars_storyteller_basic_modifier") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set storyteller basic cost modifier to [new_value].") + current_storyteller.storyteller_basic_modifier = new_value if("reload_config_vars") message_admins("[key_name_admin(usr)] reloaded gamemode config vars.") load_config_vars() diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 563f38ce0dc2a..1b5440812565a 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -66,6 +66,10 @@ var/antag_flat_cap = ANTAG_CAP_FLAT ///Общий множитель всех треков сторителлера (для коректировок) var/point_gain_base_mult = STORYTELLER_BASIC_MULT + ///Множитель силы СБ + var/sec_antag_modifier = STORYTELLER_SEC_ANTAG_MODIFIER + ///Множитель цен антагов + var/storyteller_basic_modifier = STORYTELLER_BASIC_MODIFIER /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff @@ -74,15 +78,6 @@ if(!guarantees_roundstart_roleset && prob(roundstart_prob) && !roundstart_checks) roundstart_checks = TRUE - if(SSgamemode.current_roundstart_event && !SSgamemode.ran_roundstart && (guarantees_roundstart_roleset || roundstart_checks)) - buy_event(SSgamemode.current_roundstart_event, EVENT_TRACK_ROLESET, TRUE) - if(EVENT_TRACK_ROLESET in SSgamemode.forced_next_events) - SSgamemode.forced_next_events[EVENT_TRACK_ROLESET] = null - SSgamemode.forced_next_events -= EVENT_TRACK_ROLESET - - log_storyteller("Running SSgamemode.current_roundstart_event\[[SSgamemode.current_roundstart_event]\]") - SSgamemode.ran_roundstart = TRUE - add_points(seconds_per_tick) handle_tracks() @@ -103,9 +98,24 @@ var/datum/controller/subsystem/gamemode/mode = SSgamemode for(var/track in mode.event_track_points) var/points = mode.event_track_points[track] - if(points >= mode.point_thresholds[track] && find_and_buy_event_from_track(track)) + if(points >= mode.point_thresholds[track]) + if(SSgamemode.can_run_roundstart) + SSgamemode.round_start_handle() + SSgamemode.can_run_roundstart = TRUE + return + if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) + calculate_empty_event(TRUE) + mode.event_track_points[track] = 0 + else if(find_and_buy_event_from_track(track)) + calculate_empty_event(FALSE) . = TRUE +/datum/storyteller/proc/calculate_empty_event(reset = FALSE) + if(reset) + SSgamemode.empty_event_chance = 5 + else + SSgamemode.empty_event_chance += SSgamemode.get_antag_count() + /// Find and buy a valid event from a track. /datum/storyteller/proc/find_and_buy_event_from_track(track) . = FALSE @@ -186,11 +196,10 @@ mode.event_track_points[track] = max(mode.event_track_points[track] - total_cost, 0) message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") if(bought_event.roundstart) - SSgamemode.ran_roundstart = TRUE mode.TriggerEvent(bought_event, forced) + SSgamemode.can_run_roundstart = FALSE else mode.schedule_event(bought_event, 3 MINUTES, total_cost, _forced = forced) - SSgamemode.triggered_round_events |= bought_event.name /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) From abdde95ceb4046a35c27a40bd2c154af0ad20a6a Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 00:07:18 +0300 Subject: [PATCH 068/135] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=82=20=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=BE=D0=B2=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B0=D0=B7=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/_defines/storyteller_defines.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index dd1497abeb842..a5d0650afce29 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,7 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 1//20 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 #define STORYTELLER_SEC_ANTAG_MODIFIER 2 #define STORYTELLER_BASIC_MODIFIER 1 @@ -87,7 +87,7 @@ /// Defines for the antag cap to prevent midround injections. #define ANTAG_CAP_FLAT 1 -#define ANTAG_CAP_DENOMINATOR 10 +#define ANTAG_CAP_DENOMINATOR 20 ///Below are defines for roundstart point pool. The GAIN ones are multiplied by ready population #define ROUNDSTART_MUNDANE_BASE 20 From 27309850b5ef4777439093dfdef9b4124534c2e4 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 16:23:08 +0300 Subject: [PATCH 069/135] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D0=BE=D0=B2=D0=B0=20?= =?UTF-8?q?=D1=81=D0=B0=D0=B4=D0=BE=D0=B2=D0=B0=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/storytellers/_storyteller.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 1b5440812565a..2a83c6271f4e9 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -101,7 +101,7 @@ if(points >= mode.point_thresholds[track]) if(SSgamemode.can_run_roundstart) SSgamemode.round_start_handle() - SSgamemode.can_run_roundstart = TRUE + SSgamemode.can_run_roundstart = FALSE return if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) calculate_empty_event(TRUE) From b5d8ab437ae8df5595a9503fd8594961dc31def4 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 17:40:14 +0300 Subject: [PATCH 070/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D1=82=20=D0=B1=D1=8E=D0=B4=D0=B6=D0=B5=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/gamemode.dm | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 5635e24c8a6ba..feb780a06419b 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -654,9 +654,11 @@ SUBSYSTEM_DEF(gamemode) message_admins("Not enough ready players to run roundstart events.") return + roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") while(length(valid_events)) recalculate_ready_pop() + recalculate_roundstart_costs(track) pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count for(var/datum/round_event_control/triggered_event as anything in triggered_events) @@ -697,13 +699,18 @@ SUBSYSTEM_DEF(gamemode) if(!length(valid_events)) return - for(var/datum/round_event_control/event as anything in valid_events) - var/sec_miss_crew = full_sec_crew - sec_crew - var/avg_power = full_sec_crew / current_storyteller.sec_antag_modifier - var/sec_miss_penalty = max((sec_miss_crew / avg_power), 1) - var/modified_cost = current_storyteller.antag_denominator - event.weight - var/basic_cost = ready_players / get_antag_cap() * sec_miss_penalty * current_storyteller.storyteller_basic_modifier - event.roundstart_cost = basic_cost + modified_cost + var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) + + for(var/datum/round_event_control/antagonist/solo/event as anything in valid_events) + + var/sec_miss_penalty = (full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier + var/dynamic_cost = 0 + for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) + if(ruleset.antag_datum == event.antag_datum) + dynamic_cost = ruleset.cost + break + var/new_cost = dynamic_cost * sec_miss_penalty + event.roundstart_cost = event.roundstart_cost ? event.roundstart_cost : new_cost return valid_events @@ -990,19 +997,14 @@ SUBSYSTEM_DEF(gamemode) handle_pre_setup_occupations() recalculate_ready_pop() recalculate_roundstart_costs(EVENT_TRACK_ROLESET) - var/avg_power = full_sec_crew / current_storyteller.sec_antag_modifier - var/sec_miss_crew = full_sec_crew - sec_crew - var/sec_miss_penalty = max((sec_miss_crew / avg_power), 1) + var/sec_miss_penalty = full_sec_crew - sec_crew dat += "
Storyteller Roundstart Values:" - dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew], sec_miss_crew = [sec_miss_crew]" + + dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew]" dat += "
Отображает максимальное количество ролей с пометкой СБ, у скольких игроков эти должности в высоком приоритете и сколько нехватка." - dat += "
Multiplier info: Average power = full_sec_crew ([full_sec_crew]) / current_storyteller.sec_antag_modifier ([current_storyteller.sec_antag_modifier]) = [avg_power]" - dat += "
Отображает среденее значение для СБ зависящее от сторителлера." - dat += "
Multiplier info: Sec Miss Penalty = max(sec_miss_crew([sec_miss_crew]) / avg_power([avg_power]), 1) = [sec_miss_penalty]" + dat += "
Multiplier info: Sec Miss Penalty = (full_sec_crew([full_sec_crew]) - sec_crew([sec_crew])) / current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier]) = [sec_miss_penalty]" dat += "
Отображает штраф вызванный нехваткой СБ." - dat += "
Basic cost info: Basic cost = ready_players([ready_players]) / get_antag_cap([get_antag_cap()]) * sec_miss_penalty([sec_miss_penalty]) * current_storyteller.storyteller_basic_modifier([current_storyteller.storyteller_basic_modifier]) = [get_antag_cap() ? ready_players / get_antag_cap() * sec_miss_penalty * current_storyteller.storyteller_basic_modifier : "No ready players"]" - dat += "
Отображает базовое значение цен антагов в связи с переменными выше." dat += "
Roundstart info: Roundstart budget = ready_players([ready_players]) + (sec_crew([sec_crew]) * current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier])) = [roundstart_budget]" dat += "
Раундстартовый бюджет для событий, расчитанный с помощью формулы выше." dat += "
Roundstart info: Forced Roundstart budget = [roundstart_budget_set]" From 88e6b251cfead26dac130f2ca214faf5d127cc39 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 17:42:16 +0300 Subject: [PATCH 071/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index feb780a06419b..f5beb2795e495 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -703,7 +703,7 @@ SUBSYSTEM_DEF(gamemode) for(var/datum/round_event_control/antagonist/solo/event as anything in valid_events) - var/sec_miss_penalty = (full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier + var/sec_miss_penalty = max((full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier, 0) var/dynamic_cost = 0 for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == event.antag_datum) @@ -997,13 +997,13 @@ SUBSYSTEM_DEF(gamemode) handle_pre_setup_occupations() recalculate_ready_pop() recalculate_roundstart_costs(EVENT_TRACK_ROLESET) - var/sec_miss_penalty = full_sec_crew - sec_crew + var/sec_miss_penalty = full_sec_crew - sec_crew / current_storyteller.sec_antag_modifier dat += "
Storyteller Roundstart Values:" dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew]" dat += "
Отображает максимальное количество ролей с пометкой СБ, у скольких игроков эти должности в высоком приоритете и сколько нехватка." - dat += "
Multiplier info: Sec Miss Penalty = (full_sec_crew([full_sec_crew]) - sec_crew([sec_crew])) / current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier]) = [sec_miss_penalty]" + dat += "
Multiplier info: Sec Miss Penalty = (full_sec_crew([full_sec_crew]) - sec_crew([sec_crew])) / current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier]) = [max(sec_miss_penalty, 0)]" dat += "
Отображает штраф вызванный нехваткой СБ." dat += "
Roundstart info: Roundstart budget = ready_players([ready_players]) + (sec_crew([sec_crew]) * current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier])) = [roundstart_budget]" dat += "
Раундстартовый бюджет для событий, расчитанный с помощью формулы выше." From 5e09f51c17fea1bf0d783ae6c0b1bb17021d6d96 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 17:47:05 +0300 Subject: [PATCH 072/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=B2=20=D0=BE=D1=82=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D1=83=D0=BB=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index f5beb2795e495..cfb0ba6c41f5d 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -997,7 +997,7 @@ SUBSYSTEM_DEF(gamemode) handle_pre_setup_occupations() recalculate_ready_pop() recalculate_roundstart_costs(EVENT_TRACK_ROLESET) - var/sec_miss_penalty = full_sec_crew - sec_crew / current_storyteller.sec_antag_modifier + var/sec_miss_penalty = (full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier dat += "
Storyteller Roundstart Values:" From a651abcbeea7fc084e910233050ba51586c0c5b6 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 18:05:34 +0300 Subject: [PATCH 073/135] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D1=81=D0=B0=D0=B4=D0=BA=D0=B0=20=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BD=D0=B0=20=D0=B4=D0=B8=D0=BD=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index cfb0ba6c41f5d..6da936878a400 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -702,15 +702,11 @@ SUBSYSTEM_DEF(gamemode) var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) for(var/datum/round_event_control/antagonist/solo/event as anything in valid_events) - - var/sec_miss_penalty = max((full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier, 0) - var/dynamic_cost = 0 for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == event.antag_datum) - dynamic_cost = ruleset.cost + event.roundstart_cost = event.roundstart_cost ? event.roundstart_cost : ruleset.cost break - var/new_cost = dynamic_cost * sec_miss_penalty - event.roundstart_cost = event.roundstart_cost ? event.roundstart_cost : new_cost + return valid_events @@ -997,14 +993,11 @@ SUBSYSTEM_DEF(gamemode) handle_pre_setup_occupations() recalculate_ready_pop() recalculate_roundstart_costs(EVENT_TRACK_ROLESET) - var/sec_miss_penalty = (full_sec_crew - sec_crew) / current_storyteller.sec_antag_modifier dat += "
Storyteller Roundstart Values:" dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew]" dat += "
Отображает максимальное количество ролей с пометкой СБ, у скольких игроков эти должности в высоком приоритете и сколько нехватка." - dat += "
Multiplier info: Sec Miss Penalty = (full_sec_crew([full_sec_crew]) - sec_crew([sec_crew])) / current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier]) = [max(sec_miss_penalty, 0)]" - dat += "
Отображает штраф вызванный нехваткой СБ." dat += "
Roundstart info: Roundstart budget = ready_players([ready_players]) + (sec_crew([sec_crew]) * current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier])) = [roundstart_budget]" dat += "
Раундстартовый бюджет для событий, расчитанный с помощью формулы выше." dat += "
Roundstart info: Forced Roundstart budget = [roundstart_budget_set]" From a3184331fbb45dcf721240b5fc53a2bfb7b597b0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 13 Dec 2024 18:50:05 +0300 Subject: [PATCH 074/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B1=D1=8E?= =?UTF-8?q?=D0=B4=D0=B6=D0=B5=D1=82=D0=B0=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/gamemode.dm | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 6da936878a400..55f3a7058907d 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -660,23 +660,26 @@ SUBSYSTEM_DEF(gamemode) recalculate_ready_pop() recalculate_roundstart_costs(track) pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count - for(var/datum/round_event_control/triggered_event as anything in triggered_events) - roundstart_budget -= triggered_event.roundstart_cost var/datum/round_event_control/picked_event = pick_weight(valid_events) - if(picked_event.can_spawn_event(ready_players) && roundstart_budget >= picked_event.roundstart_cost) - message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget - picked_event.roundstart_cost].") - TriggerEvent(picked_event, forced = FALSE) - // Если первое событие эксклюзивное, то отчищаем список - if(picked_event.exclusive_roundstart_event) - valid_events = list() - else - // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные - for(var/datum/round_event_control/event as anything in valid_events) - if(event.exclusive_roundstart_event) - valid_events -= event + if(picked_event.can_spawn_event(ready_players)) + roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count + for(var/datum/round_event_control/triggered_event as anything in triggered_events) + roundstart_budget -= triggered_event.roundstart_cost + if((roundstart_budget >= picked_event.roundstart_cost)) + message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget - picked_event.roundstart_cost].") triggered_events += picked_event + TriggerEvent(picked_event, forced = FALSE) + // Если первое событие эксклюзивное, то отчищаем список + if(picked_event.exclusive_roundstart_event) + valid_events = list() + else + // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные + for(var/datum/round_event_control/event as anything in valid_events) + if(event.exclusive_roundstart_event) + valid_events -= event + else + valid_events -= picked_event else valid_events -= picked_event @@ -1195,7 +1198,7 @@ SUBSYSTEM_DEF(gamemode) if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) weight_string = "[percent]% - [weight_string]" - dat += "[SSticker.HasRoundStarted() && event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight + dat += "[!SSticker.HasRoundStarted() && event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight dat += "[event.get_href_actions()]" //Actions dat += "" dat += "" From 5b64ae4988e723d31b2895df21e552963607c979 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 14 Dec 2024 09:12:30 +0300 Subject: [PATCH 075/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/_defines/storyteller_defines.dm | 2 +- .../event_defines/_round_event_control.dm | 8 +++ .../storyteller/code/gamemode.dm | 53 ++++++++++--------- .../code/storytellers/_storyteller.dm | 3 +- .../code/storytellers/storyteller_default.dm | 1 + 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index a5d0650afce29..9c9eb68d8b091 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,7 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 1 #define STORYTELLER_SEC_ANTAG_MODIFIER 2 #define STORYTELLER_BASIC_MODIFIER 1 diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 6796b2e7ad4ef..e9a16a4fb2165 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -198,6 +198,14 @@ return TRUE /datum/round_event_control/antagonist/proc/trim_candidates(list/candidates) + if(!roundstart) + for(var/mob/candidate in candidates) + //Если событие призраков, то проверить. что кандидат - призрак + if(ispath(typepath, /datum/round_event/ghost_role) && candidate.stat != DEAD) + candidates -= candidate + //Если событие живых, то проверить. что кандидат - жив или без сознания (не мертв, не в софт крите и не в хард крите) + if(!ispath(typepath, /datum/round_event/ghost_role) && !(candidate.stat == CONSCIOUS || candidate.stat == UNCONSCIOUS)) + candidates -= candidate return candidates /datum/round_event_control/antagonist/New() diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 55f3a7058907d..81ec89b453d24 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -315,6 +315,7 @@ SUBSYSTEM_DEF(gamemode) if(job_ban && is_banned_from(candidate.ckey, list(job_ban, ROLE_SYNDICATE))) continue candidates += candidate + return candidates /// Gets the correct popcount, returning READY people if roundstart, and active people if not. @@ -632,8 +633,6 @@ SUBSYSTEM_DEF(gamemode) if(player_role?.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY && !player.mind.special_role) sec_crew++ - roundstart_budget = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - /datum/controller/subsystem/gamemode/proc/round_start_handle() recalculate_ready_pop() @@ -648,13 +647,12 @@ SUBSYSTEM_DEF(gamemode) event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER return - var/list/triggered_events = list() var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) if(pop_count < current_storyteller.min_antag_popcount) message_admins("Not enough ready players to run roundstart events.") return - roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count + recalculate_roundstart_budget() message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") while(length(valid_events)) recalculate_ready_pop() @@ -662,26 +660,26 @@ SUBSYSTEM_DEF(gamemode) pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) var/datum/round_event_control/picked_event = pick_weight(valid_events) - if(picked_event.can_spawn_event(ready_players)) - roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count - for(var/datum/round_event_control/triggered_event as anything in triggered_events) - roundstart_budget -= triggered_event.roundstart_cost - if((roundstart_budget >= picked_event.roundstart_cost)) - message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget - picked_event.roundstart_cost].") - triggered_events += picked_event - TriggerEvent(picked_event, forced = FALSE) - // Если первое событие эксклюзивное, то отчищаем список - if(picked_event.exclusive_roundstart_event) - valid_events = list() - else - // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные - for(var/datum/round_event_control/event as anything in valid_events) - if(event.exclusive_roundstart_event) - valid_events -= event + if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.roundstart_cost)) + roundstart_budget -= picked_event.roundstart_cost + message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget].") + TriggerEvent(picked_event, forced = FALSE) + // Если первое событие эксклюзивное, то отчищаем список + if(picked_event.exclusive_roundstart_event) + valid_events = list() else - valid_events -= picked_event + // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные + for(var/datum/round_event_control/event as anything in valid_events) + if(event.exclusive_roundstart_event) + valid_events -= event else valid_events -= picked_event + event_track_points[track] = 0 + message_admins("Storyteller finished to get roundstart events with points left - [roundstart_budget].") + +/datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() + var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_costs(track) full_sec_crew = 0 @@ -996,7 +994,7 @@ SUBSYSTEM_DEF(gamemode) handle_pre_setup_occupations() recalculate_ready_pop() recalculate_roundstart_costs(EVENT_TRACK_ROLESET) - + recalculate_roundstart_budget() dat += "
Storyteller Roundstart Values:" dat += "
Sec info: Full sec crew = [full_sec_crew], Players with High Sec = [sec_crew]" @@ -1112,10 +1110,16 @@ SUBSYSTEM_DEF(gamemode) /// Panel containing information and actions regarding events /datum/controller/subsystem/gamemode/proc/event_panel(mob/user) var/list/dat = list() + if(!SSticker.HasRoundStarted()) + handle_pre_setup_occupations() + recalculate_ready_pop() + recalculate_roundstart_costs(EVENT_TRACK_ROLESET) + recalculate_roundstart_budget() + if(current_storyteller) dat += "Storyteller: [current_storyteller.name]" dat += "
Repetition penalty multiplier: [current_storyteller.event_repetition_multiplier]" - dat += "
Cost variance: [current_storyteller.cost_variance][SSticker.HasRoundStarted()? "" : ", roundstart_budget = [roundstart_budget_set ? roundstart_budget_set : roundstart_budget]"]" + dat += "
Cost variance: [current_storyteller.cost_variance][SSticker.HasRoundStarted() ? "" : ", roundstart_budget = [roundstart_budget]"]" if(current_storyteller.tag_multipliers) dat += "
Tag multipliers:" for(var/tag in current_storyteller.tag_multipliers) @@ -1124,9 +1128,6 @@ SUBSYSTEM_DEF(gamemode) else dat += "Storyteller: None
Weight and chance statistics will be inaccurate due to the present lack of a storyteller." - handle_pre_setup_occupations() - recalculate_ready_pop() - recalculate_roundstart_costs(EVENT_TRACK_ROLESET) dat += "
Roundstart Events Forced Roundstart events will use rolled points, and are guaranteed to trigger (even if the used points are not enough)" dat += "
Avg. event intervals: " for(var/track in event_tracks) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 2a83c6271f4e9..ae9d32e9bbe18 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -101,8 +101,7 @@ if(points >= mode.point_thresholds[track]) if(SSgamemode.can_run_roundstart) SSgamemode.round_start_handle() - SSgamemode.can_run_roundstart = FALSE - return + SSgamemode.can_run_roundstart = FALSE if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) calculate_empty_event(TRUE) mode.event_track_points[track] = 0 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm index 07c49fb6d64eb..52389b9531b9b 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm @@ -2,4 +2,5 @@ name = "Default Andy" desc = "Default Andy is the default Storyteller, and the comparison point for every other Storyteller. Best for an average, varied experience." always_votable = TRUE + welcome_text = "I am not Randy!" weight = 6 From f86da0c3c63829254eb7927871c4c273bef76cf9 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 14 Dec 2024 16:20:04 +0300 Subject: [PATCH 076/135] SSevents.no_more --- code/controllers/subsystem/events.dm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index edf1fbee78ac9..58c0fadca86ad 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -73,7 +73,7 @@ SUBSYSTEM_DEF(events) */ /datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event) set waitfor = FALSE //for the admin prompt - if(!CONFIG_GET(flag/allow_random_events)) + if(!CONFIG_GET(flag/allow_random_events) || !excluded_event) /// BANDASTATION EDIT START - STORYTELLER - No SSevents spawn except rerolling return var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) @@ -97,7 +97,10 @@ SUBSYSTEM_DEF(events) var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - TriggerEvent(event_to_run) + /// BANDASTATION EDIT START - STORYTELLER + /// TriggerEvent(event_to_run) + SSgamemode.TriggerEvent(event_to_run, forced = FALSE) + /// BANDASTATION EDIT END - STORYTELLER ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. From 93334b3cfcb1c5c867ba18648806b7ecb3fb2148 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 15 Dec 2024 02:48:39 +0300 Subject: [PATCH 077/135] =?UTF-8?q?=D0=9A=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BD=D0=BE=D0=B5=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D0=B8=D0=B2=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=20=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D0=B8=20=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D0=B2=D0=B5=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=BF=D1=80=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B5,=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D0=B5=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D1=89?= =?UTF-8?q?=D0=B8=D1=82=D1=81=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event_defines/_round_event_control.dm | 2 +- .../storyteller/code/gamemode.dm | 47 ++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index e9a16a4fb2165..c2376f34b5079 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -320,7 +320,7 @@ return switch(href_list["action"]) if("schedule") - var/new_schedule = input(usr, "New schedule time (in seconds):", "Reschedule Event") as num|null + var/new_schedule = roundstart ? 0 : input(usr, "New schedule time (in seconds):", "Reschedule Event") as num|null if(isnull(new_schedule) || QDELETED(src)) return message_admins("[key_name_admin(usr)] scheduled event [src.name] in [new_schedule] seconds.") diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 81ec89b453d24..00253921a545b 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -654,11 +654,47 @@ SUBSYSTEM_DEF(gamemode) recalculate_roundstart_budget() message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") + + message_admins("Storyteller purchased and triggered forced event [forced_next_events[track]].") + TriggerEvent(forced_next_events[track], forced = TRUE) + forced_next_events[track] = 0 + + var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) while(length(valid_events)) recalculate_ready_pop() recalculate_roundstart_costs(track) pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + while(length(scheduled_events)) + var/list/scheduled_events_roleset = list() + for(var/datum/scheduled_event/scheduled_pre_event in scheduled_events) + scheduled_events_roleset += scheduled_pre_event.event + scheduled_events_roleset[scheduled_pre_event.event] = scheduled_pre_event.event.weight + + var/datum/round_event_control/antagonist/solo/scheduled_event = pick_weight(scheduled_events_roleset) + for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) + if(ruleset.antag_datum == scheduled_event.antag_datum) + scheduled_event.roundstart_cost = scheduled_event.roundstart_cost ? scheduled_event.roundstart_cost : ruleset.cost + break + + if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.roundstart_cost)) + roundstart_budget -= scheduled_event.roundstart_cost + message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") + TriggerEvent(scheduled_event, forced = FALSE) + scheduled_events -= scheduled_event + if(scheduled_event.exclusive_roundstart_event) + scheduled_event = list() + valid_events = list() + else + // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные + for(var/datum/round_event_control/exclude_event as anything in scheduled_events_roleset) + if(exclude_event.exclusive_roundstart_event) + scheduled_events -= exclude_event + + for(var/datum/round_event_control/exclude_event as anything in valid_events) + if(exclude_event.exclusive_roundstart_event) + valid_events -= exclude_event + var/datum/round_event_control/picked_event = pick_weight(valid_events) if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.roundstart_cost)) roundstart_budget -= picked_event.roundstart_cost @@ -669,9 +705,9 @@ SUBSYSTEM_DEF(gamemode) valid_events = list() else // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные - for(var/datum/round_event_control/event as anything in valid_events) - if(event.exclusive_roundstart_event) - valid_events -= event + for(var/datum/round_event_control/exclude_event as anything in valid_events) + if(exclude_event.exclusive_roundstart_event) + valid_events -= exclude_event else valid_events -= picked_event event_track_points[track] = 0 @@ -701,7 +737,6 @@ SUBSYSTEM_DEF(gamemode) return var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) - for(var/datum/round_event_control/antagonist/solo/event as anything in valid_events) for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == event.antag_datum) @@ -1152,7 +1187,7 @@ SUBSYSTEM_DEF(gamemode) dat += "M.Time" dat += "Can Occur" dat += "Failure Reason" - dat += "Weight" + dat += "[!SSticker.HasRoundStarted() ? "Cost/" : ""]Weight" dat += "Actions" dat += "" var/even = TRUE @@ -1199,7 +1234,7 @@ SUBSYSTEM_DEF(gamemode) if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) weight_string = "[percent]% - [weight_string]" - dat += "[!SSticker.HasRoundStarted() && event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight + dat += "[SSticker.HasRoundStarted() && !event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight dat += "[event.get_href_actions()]" //Actions dat += "" dat += "" From a7b134bc6f8c98f18e5733602ec7f391a17b3f88 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 15 Dec 2024 17:48:35 +0300 Subject: [PATCH 078/135] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE?= =?UTF-8?q?=D0=BA=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B0,=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BD=D1=8E=D0=BA=20=D0=B8=20=D0=B2=D0=B8=D0=B7=D0=B0=D1=80?= =?UTF-8?q?=D0=B4=D0=B0=20=D0=B4=D0=BE=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8F=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ambience.dm | 7 +- code/modules/antagonists/wizard/wizard.dm | 2 +- .../code/_defines/storyteller_defines.dm | 2 +- .../storyteller/code/_helpers.dm | 8 ++ .../code/event_defines/crewset/clown_ops.dm | 120 ++---------------- .../code/event_defines/crewset/nuke_ops.dm | 52 ++++---- .../code/event_defines/crewset/wizard.dm | 11 +- .../storyteller/code/gamemode.dm | 27 ++-- 8 files changed, 75 insertions(+), 154 deletions(-) diff --git a/code/controllers/subsystem/ambience.dm b/code/controllers/subsystem/ambience.dm index 4aacf3802cf5d..402fd43360452 100644 --- a/code/controllers/subsystem/ambience.dm +++ b/code/controllers/subsystem/ambience.dm @@ -114,7 +114,12 @@ SUBSYSTEM_DEF(ambience) return var/area/my_area = get_area(src) - var/sound_to_use = my_area.ambient_buzz + /// BANDASTATION EDIT START - STORYTELLERS + var/sound_to_use + if(my_area) + sound_to_use= my_area.ambient_buzz + /// BANDASTATION EDIT END - STORYTELLERS + var/volume_modifier = client.prefs.read_preference(/datum/preference/numeric/sound_ship_ambience_volume) if(!sound_to_use || !(client.prefs.read_preference(/datum/preference/numeric/sound_ship_ambience_volume))) diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index ba9d843974788..617908b5ba617 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) /datum/antagonist/wizard/proc/send_to_lair() // And now we ensure that its loaded - //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) /// BANDASTATION EDIT - STORYTELLER + SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) if(!owner.current) return diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 9c9eb68d8b091..a5d0650afce29 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,7 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 1 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 #define STORYTELLER_SEC_ANTAG_MODIFIER 2 #define STORYTELLER_BASIC_MODIFIER 1 diff --git a/modular_bandastation/storyteller/code/_helpers.dm b/modular_bandastation/storyteller/code/_helpers.dm index f627d4bb2ce07..f485fb29adb80 100644 --- a/modular_bandastation/storyteller/code/_helpers.dm +++ b/modular_bandastation/storyteller/code/_helpers.dm @@ -27,3 +27,11 @@ if(QDELETED(player) || !istype(get_area(player), /area/shuttle/arrival)) return FALSE return TRUE + +/mob/living/proc/clear_inventory(include_pockets = TRUE, include_held_items = TRUE) + var/list/items = get_equipped_items(include_pockets) + if(include_held_items) + items |= held_items + for(var/item in items) + dropItemToGround(item, force = TRUE, silent = TRUE, invdrop = FALSE) + qdel(item) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 87f174df96fff..7e097c15cd070 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -1,117 +1,15 @@ -/datum/round_event_control/antagonist/solo/clown_operative +/datum/round_event_control/antagonist/solo/nuclear_operative/clown name = "Roundstart Clown Operative" tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_TEAM_ANTAG, TAG_EXTERNAL) antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop - typepath = /datum/round_event/antagonist/solo/clown_operative - restricted_roles = list( - JOB_AI, - JOB_CAPTAIN, - JOB_CHIEF_ENGINEER, - JOB_CHIEF_MEDICAL_OFFICER, - JOB_CYBORG, - JOB_DETECTIVE, - JOB_HEAD_OF_PERSONNEL, - JOB_HEAD_OF_SECURITY, - JOB_PRISONER, - JOB_RESEARCH_DIRECTOR, - JOB_SECURITY_OFFICER, - JOB_WARDEN, - ) - base_antags = 3 - maximum_antags = 5 - enemy_roles = list( - JOB_AI, - JOB_CYBORG, - JOB_CAPTAIN, - JOB_DETECTIVE, - JOB_HEAD_OF_SECURITY, - JOB_SECURITY_OFFICER, - JOB_WARDEN, - ) - required_enemies = 5 - // I give up, just there should be enough heads with 35 players... - min_players = 35 - roundstart = TRUE - earliest_start = 0 SECONDS - weight = 1 + typepath = /datum/round_event/antagonist/solo/nuclear_operative/clown + weight = 0 //these are meant to be very rare max_occurrences = 1 - exclusive_roundstart_event = TRUE + event_icon_state = "flukeops" -/datum/round_event/antagonist/solo/clown_operative - excute_round_end_reports = TRUE - end_when = 60000 /// we will end on our own when revs win - var/static/datum/team/nuclear/nuke_team - var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader - var/set_leader = FALSE - var/required_role = ROLE_CLOWN_OPERATIVE - -/datum/round_event/antagonist/solo/clown_operative/setup() - . = ..() - var/obj/machinery/nuclearbomb/syndicate/syndicate_nuke = locate() in GLOB.nuke_list - if(syndicate_nuke) - var/turf/nuke_turf = get_turf(syndicate_nuke) - if(nuke_turf) - new /obj/machinery/nuclearbomb/syndicate/bananium(nuke_turf) - qdel(syndicate_nuke) - -/datum/round_event/antagonist/solo/clown_operative/add_datum_to_mind(datum/mind/antag_mind) - var/mob/living/current_mob = antag_mind.current - SSjob.FreeRole(antag_mind.assigned_role.title) - var/list/items = current_mob.get_equipped_items(TRUE) - current_mob.unequip_everything() - for(var/obj/item/item as anything in items) - qdel(item) - - antag_mind.set_assigned_role(SSjob.get_job_type(/datum/job/clown_operative)) - antag_mind.special_role = ROLE_CLOWN_OPERATIVE - - var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) - if(!most_experienced) - most_experienced = antag_mind - - if(!set_leader) - set_leader = TRUE - var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) - nuke_team = leader.nuke_team - - if(antag_mind == most_experienced) - return - - var/datum/antagonist/nukeop/new_op = new antag_datum() - antag_mind.add_antag_datum(new_op) - - -/datum/round_event/antagonist/solo/clown_operative/round_end_report() - var/result = nuke_team.get_result() - switch(result) - if(NUKE_RESULT_FLUKE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - SSticker.news_report = NUKE_SYNDICATE_BASE - if(NUKE_RESULT_NUKE_WIN) - SSticker.mode_result = "win - syndicate nuke" - SSticker.news_report = STATION_DESTROYED_NUKE - if(NUKE_RESULT_NOSURVIVORS) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - SSticker.news_report = STATION_DESTROYED_NUKE - if(NUKE_RESULT_WRONG_STATION) - SSticker.mode_result = "halfwin - blew wrong station" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_WRONG_STATION_DEAD) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_CREW_WIN) - SSticker.mode_result = "loss - evacuation - disk secured" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_DISK_LOST) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - SSticker.news_report = OPERATIVE_SKIRMISH - if(NUKE_RESULT_DISK_STOLEN) - SSticker.mode_result = "halfwin - detonation averted" - SSticker.news_report = OPERATIVE_SKIRMISH - else - SSticker.mode_result = "halfwin - interrupted" - SSticker.news_report = OPERATIVE_SKIRMISH +/datum/round_event/antagonist/solo/nuclear_operative/clown + required_role = ROLE_CLOWN_OPERATIVE + job_type = /datum/job/clown_operative + antag_type = /datum/antagonist/nukeop/clownop + leader_antag_type = /datum/antagonist/nukeop/leader/clownop diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index fc76e574ba8ae..a55049f211cfe 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -4,6 +4,7 @@ antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop typepath = /datum/round_event/antagonist/solo/nuclear_operative + shared_occurence_type = SHARED_HIGH_THREAT restricted_roles = list( JOB_AI, JOB_CAPTAIN, @@ -34,41 +35,40 @@ min_players = 35 roundstart = TRUE earliest_start = 0 SECONDS - weight = 4 + weight = 0 max_occurrences = 3 - exclusive_roundstart_event = TRUE + event_icon_state = "nukeops" /datum/round_event/antagonist/solo/nuclear_operative excute_round_end_reports = TRUE - end_when = 60000 - var/static/datum/team/nuclear/nuke_team - var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader - var/set_leader = FALSE var/required_role = ROLE_NUCLEAR_OPERATIVE + var/job_type = /datum/job/nuclear_operative + var/antag_type = /datum/antagonist/nukeop + var/leader_antag_type = /datum/antagonist/nukeop/leader + var/datum/team/nuclear/nuke_team -/datum/round_event/antagonist/solo/nuclear_operative/add_datum_to_mind(datum/mind/antag_mind) +/datum/round_event/antagonist/solo/nuclear_operative/start() + var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) || setup_minds[1] + prepare(most_experienced) + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(leader_antag_type) + nuke_team = leader.nuke_team + for(var/datum/mind/antag_mind as anything in setup_minds - most_experienced) + prepare(antag_mind) + var/datum/antagonist/nukeop/op = new antag_type + op.nuke_team = nuke_team + antag_mind.add_antag_datum(op) + +/// Frees the target mind's job slot, clears and deletes all their items, creates a fresh body for them, and sets +/datum/round_event/antagonist/solo/nuclear_operative/proc/prepare(datum/mind/antag_mind) var/mob/living/current_mob = antag_mind.current SSjob.FreeRole(antag_mind.assigned_role.title) - var/list/items = current_mob.get_equipped_items(TRUE) - current_mob.unequip_everything() - for(var/obj/item/item as anything in items) - qdel(item) - - var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) - if(!most_experienced) - most_experienced = antag_mind - - if(!set_leader) - set_leader = TRUE - var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(antag_leader_datum) - nuke_team = leader.nuke_team - - if(antag_mind == most_experienced) - return - - var/datum/antagonist/nukeop/new_op = new antag_datum() - antag_mind.add_antag_datum(new_op) + current_mob.clear_inventory() + create_human_mob_copy(get_turf(current_mob), current_mob) + antag_mind.set_assigned_role(SSjob.get_job_type(job_type)) + antag_mind.special_role = required_role +/datum/round_event/antagonist/solo/nuclear_operative/add_datum_to_mind(datum/mind/antag_mind) + CRASH("this should not be called") /datum/round_event/antagonist/solo/nuclear_operative/round_end_report() var/result = nuke_team.get_result() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index 6bdc0352c9378..d93d694fa2ff2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/antagonist/solo/wizard antag_flag = ROLE_WIZARD antag_datum = /datum/antagonist/wizard + shared_occurence_type = SHARED_HIGH_THREAT restricted_roles = list( JOB_CAPTAIN, JOB_HEAD_OF_SECURITY, @@ -16,20 +17,21 @@ JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_CHAPLAIN, ) required_enemies = 5 roundstart = TRUE earliest_start = 0 SECONDS - weight = 2 + weight = 0 min_players = 35 max_occurrences = 1 - exclusive_roundstart_event = TRUE + event_icon_state = "wizard" /datum/round_event_control/antagonist/solo/wizard/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) . = ..() if(!.) return - if(GLOB.wizardstart.len == 0) + if(!length(GLOB.wizardstart)) return FALSE /datum/round_event/antagonist/solo/wizard @@ -42,4 +44,7 @@ for(var/obj/item/item as anything in items) qdel(item) + var/mob/living/carbon/human/new_player_mob = new //while funny, it would kind of suck to be a blind criple wizard + antag_mind.transfer_to(new_player_mob) + qdel(current_mob) antag_mind.make_wizard() diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 00253921a545b..21f3008c86b18 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -655,9 +655,16 @@ SUBSYSTEM_DEF(gamemode) recalculate_roundstart_budget() message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") - message_admins("Storyteller purchased and triggered forced event [forced_next_events[track]].") - TriggerEvent(forced_next_events[track], forced = TRUE) - forced_next_events[track] = 0 + if(forced_next_events[track]) + message_admins("Storyteller purchased and triggered forced event [forced_next_events[track]].") + TriggerEvent(forced_next_events[track], forced = TRUE) + forced_next_events[track] = 0 + + var/list/scheduled_events_roleset = list() + for(var/datum/scheduled_event/scheduled_pre_event in scheduled_events) + scheduled_events_roleset += scheduled_pre_event.event + scheduled_events_roleset[scheduled_pre_event.event] = scheduled_pre_event.event.weight + scheduled_events -= scheduled_pre_event var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) while(length(valid_events)) @@ -665,12 +672,7 @@ SUBSYSTEM_DEF(gamemode) recalculate_roundstart_costs(track) pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - while(length(scheduled_events)) - var/list/scheduled_events_roleset = list() - for(var/datum/scheduled_event/scheduled_pre_event in scheduled_events) - scheduled_events_roleset += scheduled_pre_event.event - scheduled_events_roleset[scheduled_pre_event.event] = scheduled_pre_event.event.weight - + while(length(scheduled_events_roleset)) var/datum/round_event_control/antagonist/solo/scheduled_event = pick_weight(scheduled_events_roleset) for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == scheduled_event.antag_datum) @@ -681,7 +683,7 @@ SUBSYSTEM_DEF(gamemode) roundstart_budget -= scheduled_event.roundstart_cost message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") TriggerEvent(scheduled_event, forced = FALSE) - scheduled_events -= scheduled_event + scheduled_events_roleset -= scheduled_event if(scheduled_event.exclusive_roundstart_event) scheduled_event = list() valid_events = list() @@ -689,11 +691,14 @@ SUBSYSTEM_DEF(gamemode) // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные for(var/datum/round_event_control/exclude_event as anything in scheduled_events_roleset) if(exclude_event.exclusive_roundstart_event) - scheduled_events -= exclude_event + scheduled_events_roleset -= exclude_event for(var/datum/round_event_control/exclude_event as anything in valid_events) if(exclude_event.exclusive_roundstart_event) valid_events -= exclude_event + else + message_admins("Storyteller failed to purchase scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") + scheduled_events_roleset -= scheduled_event var/datum/round_event_control/picked_event = pick_weight(valid_events) if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.roundstart_cost)) From 26b5da02151c03b286cc5664a326742e1e4256fa Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 15 Dec 2024 19:14:23 +0300 Subject: [PATCH 079/135] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B8=20=D0=B2=D0=B8=D0=B7=D0=B0=D1=80=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/nukeop/outfits.dm | 2 +- code/modules/antagonists/wizard/wizard.dm | 2 +- .../storyteller/code/_defines/storyteller_defines.dm | 2 +- .../storyteller/code/event_defines/crewset/clown_ops.dm | 2 +- .../storyteller/code/event_defines/crewset/nuke_ops.dm | 4 ++-- .../storyteller/code/event_defines/crewset/wizard.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 3 +++ 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 29cba691d99b8..32fe7dfd5c0a6 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -45,7 +45,7 @@ return // We don't require the nukiebase be loaded to function, but lets go ahead and kick off loading just in case - // INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER + INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) var/obj/item/radio/radio = nukie.ears radio.set_frequency(FREQ_SYNDICATE) radio.freqlock = RADIO_FREQENCY_LOCKED diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 617908b5ba617..284ee82b1003b 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) /datum/antagonist/wizard/proc/send_to_lair() // And now we ensure that its loaded - SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) + // SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) /// BANDASTATION EDIT - STORYTELLER if(!owner.current) return diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index a5d0650afce29..9c9eb68d8b091 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,7 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 1 #define STORYTELLER_SEC_ANTAG_MODIFIER 2 #define STORYTELLER_BASIC_MODIFIER 1 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 7e097c15cd070..34b66a876ec78 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -4,7 +4,7 @@ antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop typepath = /datum/round_event/antagonist/solo/nuclear_operative/clown - weight = 0 //these are meant to be very rare + weight = 1 //these are meant to be very rare max_occurrences = 1 event_icon_state = "flukeops" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index a55049f211cfe..4f8e78be96477 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -35,7 +35,7 @@ min_players = 35 roundstart = TRUE earliest_start = 0 SECONDS - weight = 0 + weight = 4 max_occurrences = 3 event_icon_state = "nukeops" @@ -50,7 +50,7 @@ /datum/round_event/antagonist/solo/nuclear_operative/start() var/datum/mind/most_experienced = get_most_experienced(setup_minds, required_role) || setup_minds[1] prepare(most_experienced) - var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(leader_antag_type) + var/datum/antagonist/nukeop/leader/leader = most_experienced.add_antag_datum(leader_antag_type, nuke_team) nuke_team = leader.nuke_team for(var/datum/mind/antag_mind as anything in setup_minds - most_experienced) prepare(antag_mind) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index d93d694fa2ff2..75810a7ca5600 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -22,7 +22,7 @@ required_enemies = 5 roundstart = TRUE earliest_start = 0 SECONDS - weight = 0 + weight = 2 min_players = 35 max_occurrences = 1 event_icon_state = "wizard" diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 21f3008c86b18..a981e2a21e4f1 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -1403,6 +1403,9 @@ SUBSYSTEM_DEF(gamemode) text2file(congealed_string, "data/last_round_events.txt") /datum/controller/subsystem/gamemode/proc/load_roundstart_data() + INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_NUKIEBASE) + INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, lazy_load_template), LAZY_TEMPLATE_KEY_WIZARDDEN) + var/massive_string = trim(file2text("data/last_round_events.txt")) if(fexists("data/last_round_events.txt")) fdel("data/last_round_events.txt") From 6eda1dd13b95cccd17d52b1ca799f4a1dac935e9 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 15 Dec 2024 19:28:52 +0300 Subject: [PATCH 080/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=D0=BB=D0=BB=D0=B5=D1=80=D0=B0=20=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index a981e2a21e4f1..88fde10d39c9e 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -978,7 +978,8 @@ SUBSYSTEM_DEF(gamemode) return valid_storytellers /datum/controller/subsystem/gamemode/proc/init_storyteller() - set_storyteller(selected_storyteller) + if(!current_storyteller) + set_storyteller(selected_storyteller) /datum/controller/subsystem/gamemode/proc/set_storyteller(passed_type) if(!storytellers[passed_type]) From 792e550e7c695085b9eadf5432f71d9c2f978097 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 17 Dec 2024 15:00:25 +0300 Subject: [PATCH 081/135] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=BE=D0=B9=20=D1=80=D0=B5=D0=B2=D0=BE=D1=80=D0=BA=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=D0=BC?= =?UTF-8?q?,=20=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F=20=D0=BE=D1=82=20?= =?UTF-8?q?=D1=85=D0=B0=D0=BA=D0=B0=20=D1=82=D0=B5=D0=BB=D0=B5=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dynamic/dynamic_unfavorable_situation.dm | 2 + .../code/_defines/storyteller_defines.dm | 2 +- .../storyteller/code/gamemode.dm | 136 ++++++++---------- 3 files changed, 61 insertions(+), 79 deletions(-) diff --git a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm index 994f2e3f5de78..ce5730bdf4935 100644 --- a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm +++ b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm @@ -36,11 +36,13 @@ if (ruleset.weight == 0) continue + /// BANDASTATION EDIT START - STORYTELLER if (ruleset.cost > max_threat_level) continue if (!ruleset.acceptable(GLOB.alive_player_list.len, threat_level)) continue + /// BANDASTATION EDIT END - STORYTELLER if (ruleset.minimum_round_time > world.time - SSticker.round_start_time) continue diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index 9c9eb68d8b091..a5d0650afce29 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -76,7 +76,7 @@ #define OBJECTIVES_POP_SCALE_PENALTY 35 #define STORYTELLER_BASIC_MULT 10 -#define STORYTELLER_MIN_ANTAG_POPCOUNT 1 +#define STORYTELLER_MIN_ANTAG_POPCOUNT 20 #define STORYTELLER_SEC_ANTAG_MODIFIER 2 #define STORYTELLER_BASIC_MODIFIER 1 diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 88fde10d39c9e..5798536851b17 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -640,13 +640,6 @@ SUBSYSTEM_DEF(gamemode) message_admins("Storyteller failed to pick an events for roundstart due low population.") return - var/track = EVENT_TRACK_ROLESET - var/list/valid_events = recalculate_roundstart_costs(track) - if(!length(valid_events)) - message_admins("Storyteller failed to pick an events for roundstart.") - event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) if(pop_count < current_storyteller.min_antag_popcount) message_admins("Not enough ready players to run roundstart events.") @@ -655,50 +648,35 @@ SUBSYSTEM_DEF(gamemode) recalculate_roundstart_budget() message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") + var/track = EVENT_TRACK_ROLESET if(forced_next_events[track]) message_admins("Storyteller purchased and triggered forced event [forced_next_events[track]].") TriggerEvent(forced_next_events[track], forced = TRUE) forced_next_events[track] = 0 - var/list/scheduled_events_roleset = list() - for(var/datum/scheduled_event/scheduled_pre_event in scheduled_events) - scheduled_events_roleset += scheduled_pre_event.event - scheduled_events_roleset[scheduled_pre_event.event] = scheduled_pre_event.event.weight - scheduled_events -= scheduled_pre_event + var/list/valid_events = recalculate_roundstart_costs(track) + + valid_events = rountstart_scheduled_events_run(valid_events) + + rountstart_general_events_run(valid_events, track) + + event_track_points[track] = 0 + message_admins("Storyteller finished to get roundstart events with points left - [roundstart_budget].") + +/datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() + var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count + +/datum/controller/subsystem/gamemode/proc/rountstart_general_events_run(valid_events, track) + + if(!length(valid_events)) + message_admins("Storyteller failed to pick an events for roundstart.") + event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return - var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) while(length(valid_events)) recalculate_ready_pop() recalculate_roundstart_costs(track) - pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - - while(length(scheduled_events_roleset)) - var/datum/round_event_control/antagonist/solo/scheduled_event = pick_weight(scheduled_events_roleset) - for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) - if(ruleset.antag_datum == scheduled_event.antag_datum) - scheduled_event.roundstart_cost = scheduled_event.roundstart_cost ? scheduled_event.roundstart_cost : ruleset.cost - break - - if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.roundstart_cost)) - roundstart_budget -= scheduled_event.roundstart_cost - message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") - TriggerEvent(scheduled_event, forced = FALSE) - scheduled_events_roleset -= scheduled_event - if(scheduled_event.exclusive_roundstart_event) - scheduled_event = list() - valid_events = list() - else - // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные - for(var/datum/round_event_control/exclude_event as anything in scheduled_events_roleset) - if(exclude_event.exclusive_roundstart_event) - scheduled_events_roleset -= exclude_event - - for(var/datum/round_event_control/exclude_event as anything in valid_events) - if(exclude_event.exclusive_roundstart_event) - valid_events -= exclude_event - else - message_admins("Storyteller failed to purchase scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") - scheduled_events_roleset -= scheduled_event var/datum/round_event_control/picked_event = pick_weight(valid_events) if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.roundstart_cost)) @@ -715,12 +693,45 @@ SUBSYSTEM_DEF(gamemode) valid_events -= exclude_event else valid_events -= picked_event - event_track_points[track] = 0 - message_admins("Storyteller finished to get roundstart events with points left - [roundstart_budget].") -/datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() - var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count +/datum/controller/subsystem/gamemode/proc/rountstart_scheduled_events_run(valid_events) + var/list/scheduled_events_roleset = list() + for(var/datum/scheduled_event/scheduled_pre_event in scheduled_events) + scheduled_events_roleset += scheduled_pre_event.event + scheduled_events_roleset[scheduled_pre_event.event] = scheduled_pre_event.event.weight + scheduled_events -= scheduled_pre_event + + var/list/dynamic_roundstart_rules = SSdynamic.init_rulesets(/datum/dynamic_ruleset/roundstart) + if(length(scheduled_events_roleset)) + var/datum/round_event_control/antagonist/solo/scheduled_event = pick_weight(scheduled_events_roleset) + for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) + if(ruleset.antag_datum == scheduled_event.antag_datum) + scheduled_event.roundstart_cost = scheduled_event.roundstart_cost ? scheduled_event.roundstart_cost : ruleset.cost + break + + while(length(scheduled_events_roleset)) + var/datum/round_event_control/scheduled_event = pick_weight(scheduled_events_roleset) + if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.roundstart_cost)) + roundstart_budget -= scheduled_event.roundstart_cost + message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") + TriggerEvent(scheduled_event, forced = FALSE) + scheduled_events_roleset -= scheduled_event + if(scheduled_event.exclusive_roundstart_event) + scheduled_event = list() + valid_events = list() + else + // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные + for(var/datum/round_event_control/exclude_event as anything in scheduled_events_roleset) + if(exclude_event.exclusive_roundstart_event) + scheduled_events_roleset -= exclude_event + + for(var/datum/round_event_control/exclude_event as anything in valid_events) + if(exclude_event.exclusive_roundstart_event) + valid_events -= exclude_event + else + message_admins("Storyteller failed to purchase scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") + scheduled_events_roleset -= scheduled_event + return valid_events /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_costs(track) full_sec_crew = 0 @@ -766,37 +777,6 @@ SUBSYSTEM_DEF(gamemode) . += "[station_trait.get_report()]
" return -/* /proc/reopen_roundstart_suicide_roles() - var/include_command = CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_positions) - var/list/reopened_jobs = list() - for(var/mob/living/quitter in GLOB.suicided_mob_list) - var/datum/job/job = SSjob.GetJob(quitter.job) - if(!job || !(job.job_flags & JOB_REOPEN_ON_ROUNDSTART_LOSS)) - continue - if(!include_command && job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) - continue - job.current_positions = max(job.current_positions - 1, 0) - reopened_jobs += quitter.job - if(CONFIG_GET(flag/reopen_roundstart_suicide_roles_command_report)) - if(reopened_jobs.len) - var/reopened_job_report_positions - for(var/dead_dudes_job in reopened_jobs) - reopened_job_report_positions = "[reopened_job_report_positions ? "[reopened_job_report_positions]\n":""][dead_dudes_job]" - var/suicide_command_report = "Central Command Human Resources Board
\ - Notice of Personnel Change

\ - To personnel management staff aboard [station_name()]:

\ - Our medical staff have detected a series of anomalies in the vital sensors \ - of some of the staff aboard your station.

\ - Further investigation into the situation on our end resulted in us discovering \ - a series of rather... unforturnate decisions that were made on the part of said staff.

\ - As such, we have taken the liberty to automatically reopen employment opportunities for the positions of the crew members \ - who have decided not to partake in our research. We will be forwarding their cases to our employment review board \ - to determine their eligibility for continued service with the company (and of course the \ - continued storage of cloning records within the central medical backup server.)

\ - The following positions have been reopened on our behalf:

\ - [reopened_job_report_positions]
" - print_command_report(suicide_command_report, "Central Command Personnel Update") */ - ////////////////////////// //Reports player logouts// ////////////////////////// From bc784b3e2b9b14ab825154af1269b42d0cdc163c Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 17 Dec 2024 18:45:40 +0300 Subject: [PATCH 082/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=87=D0=B5=D1=80=D0=B5=D0=B4=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D1=82=D0=B5,=20=D0=B2=D0=B2=D0=BE=D0=B4=20=D0=BE=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B4=D0=B8=20=D1=84=D0=BE=D1=80=D1=81=D0=B0?= =?UTF-8?q?,=20=D1=87=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=82=20=D0=B4=D1=83=D0=B1=D0=BB=D0=B8=D1=80?= =?UTF-8?q?=D1=83=D1=8E=D1=89=D0=B5=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event_defines/_round_event_control.dm | 2 +- .../storyteller/code/gamemode.dm | 44 ++++++----- .../code/storytellers/_storyteller.dm | 76 +++++++++---------- 3 files changed, 62 insertions(+), 60 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index c2376f34b5079..371d1f3ecc895 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -333,7 +333,7 @@ return message_admins("[key_name_admin(usr)] forced scheduled event [src.name].") log_admin_private("[key_name(usr)] forced scheduled event [src.name].") - SSgamemode.forced_next_events[src.track] = src + SSgamemode.forced_next_events[src.track] += src if("fire") if(length(src.admin_setup)) for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 5798536851b17..167d89ed6646e 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -113,7 +113,13 @@ SUBSYSTEM_DEF(gamemode) var/list/scheduled_events = list() /// Associative list of tracks to forced event controls. For admins to force events (though they can still invoke them freely outside of the track system) - var/list/forced_next_events = list() + var/list/forced_next_events = list( + EVENT_TRACK_MUNDANE = list(), + EVENT_TRACK_MODERATE = list(), + EVENT_TRACK_MAJOR = list(), + EVENT_TRACK_ROLESET = list(), + EVENT_TRACK_OBJECTIVES = list(), + ) var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences. var/list/running = list() //list of all existing /datum/round_event @@ -375,7 +381,7 @@ SUBSYSTEM_DEF(gamemode) /// If we have any forced events, ensure we get enough points for them for(var/track in event_tracks) - if(forced_next_events[track] && event_track_points[track] < point_thresholds[track]) + if(length(forced_next_events[track]) && event_track_points[track] < point_thresholds[track]) event_track_points[track] = point_thresholds[track] /// At this point we've rolled roundstart events and antags and we handle leftover points here. @@ -635,24 +641,23 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/round_start_handle() recalculate_ready_pop() - - if(!get_antag_cap()) - message_admins("Storyteller failed to pick an events for roundstart due low population.") - return - - var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - if(pop_count < current_storyteller.min_antag_popcount) - message_admins("Not enough ready players to run roundstart events.") - return - recalculate_roundstart_budget() message_admins("Storyteller begin to get roundstart events with budget [roundstart_budget].") var/track = EVENT_TRACK_ROLESET if(forced_next_events[track]) - message_admins("Storyteller purchased and triggered forced event [forced_next_events[track]].") - TriggerEvent(forced_next_events[track], forced = TRUE) - forced_next_events[track] = 0 + for(var/datum/round_event_control/forced_event in forced_next_events[track]) + message_admins("Storyteller purchased and triggered forced roundstart event [forced_event].") + TriggerEvent(forced_event, forced = TRUE) + + forced_next_events[track] = list() + + event_track_points[track] = 0 + var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) + if(pop_count < current_storyteller.min_antag_popcount) + message_admins("Not enough ready players to run general and scheduled roundstart events.") + message_admins("Storyteller finished to get roundstart events.") + return var/list/valid_events = recalculate_roundstart_costs(track) @@ -660,7 +665,6 @@ SUBSYSTEM_DEF(gamemode) rountstart_general_events_run(valid_events, track) - event_track_points[track] = 0 message_admins("Storyteller finished to get roundstart events with points left - [roundstart_budget].") /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() @@ -731,6 +735,7 @@ SUBSYSTEM_DEF(gamemode) else message_admins("Storyteller failed to purchase scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") scheduled_events_roleset -= scheduled_event + return valid_events /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_costs(track) @@ -759,7 +764,6 @@ SUBSYSTEM_DEF(gamemode) event.roundstart_cost = event.roundstart_cost ? event.roundstart_cost : ruleset.cost break - return valid_events /* @@ -1076,8 +1080,10 @@ SUBSYSTEM_DEF(gamemode) dat += "[track] - [last_points] per process." //Track dat += "[percent]% ([lower]/[upper])" //Progress dat += "~[next] seconds" //Next - var/datum/round_event_control/forced_event = forced_next_events[track] - var/forced = forced_event ? "[forced_event.name] X" : "" + var/list/forced_events = forced_next_events[track] + var/forced = "" + for(var/datum/round_event_control/forced_event in forced_events) + forced = forced + "[forced_event.name] X
" dat += "[forced]" //Forced dat += "Set Pts. Next Event" //Actions dat += "" diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index ae9d32e9bbe18..be7d64dc941b4 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -101,6 +101,7 @@ if(points >= mode.point_thresholds[track]) if(SSgamemode.can_run_roundstart) SSgamemode.round_start_handle() + SSgamemode.can_run_roundstart = FALSE if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) calculate_empty_event(TRUE) @@ -121,47 +122,42 @@ var/are_forced = FALSE var/datum/controller/subsystem/gamemode/mode = SSgamemode var/datum/round_event_control/picked_event - if(mode.forced_next_events[track]) //Forced event by admin - /// Dont check any prerequisites, it has been forced by an admin - picked_event = mode.forced_next_events[track] - mode.forced_next_events -= track - are_forced = TRUE - else - mode.update_crew_infos() - var/pop_required = mode.min_pop_thresholds[track] - if(mode.active_players < pop_required) - message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [mode.active_players])") - mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - calculate_weights(track) - var/list/valid_events = list() - // Determine which events are valid to pick - for(var/datum/round_event_control/event as anything in mode.event_pools[track]) - var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) - if(event.can_spawn_event(players_amt)) - if(QDELETED(event)) - message_admins("[event.name] was deleted!") - continue - valid_events[event] = round(event.calculated_weight * 10) //multiply weight by 10 to get first decimal value - ///If we didn't get any events, remove the points inform admins and dont do anything - if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track].") - mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + + mode.update_crew_infos() + var/pop_required = mode.min_pop_thresholds[track] + if(mode.active_players < pop_required) + message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [mode.active_players])") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + calculate_weights(track) + var/list/valid_events = list() + // Determine which events are valid to pick + for(var/datum/round_event_control/event as anything in mode.event_pools[track]) + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + if(event.can_spawn_event(players_amt)) + if(QDELETED(event)) + message_admins("[event.name] was deleted!") + continue + valid_events[event] = round(event.calculated_weight * 10) //multiply weight by 10 to get first decimal value + ///If we didn't get any events, remove the points inform admins and dont do anything + if(!length(valid_events)) + message_admins("Storyteller failed to pick an event for track of [track].") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + picked_event = pick_weight(valid_events) + if(!picked_event) + if(length(valid_events)) + var/added_string = "" + for(var/datum/round_event_control/item as anything in valid_events) + added_string += "[item.name]:[valid_events[item]]; " + stack_trace("WARNING: Storyteller picked a null from event pool, defaulting to option 1, look at weights:[added_string]") + shuffle_inplace(valid_events) + picked_event = valid_events[1] + else + message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + stack_trace("WARNING: Storyteller picked a null from event pool.") + SSgamemode.event_track_points[track] = 0 return - picked_event = pick_weight(valid_events) - if(!picked_event) - if(length(valid_events)) - var/added_string = "" - for(var/datum/round_event_control/item as anything in valid_events) - added_string += "[item.name]:[valid_events[item]]; " - stack_trace("WARNING: Storyteller picked a null from event pool, defaulting to option 1, look at weights:[added_string]") - shuffle_inplace(valid_events) - picked_event = valid_events[1] - else - message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - stack_trace("WARNING: Storyteller picked a null from event pool.") - SSgamemode.event_track_points[track] = 0 - return if(picked_event?.can_spawn_event(get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)) && track) buy_event(picked_event, track, are_forced) From c8fd3635f349999641e3d8693f098a2e293fad96 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 20 Dec 2024 19:47:20 +0300 Subject: [PATCH 083/135] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=82=20=D0=BE=D1=87=D0=BA=D0=BE=D0=B2=20=D0=B2=20=D1=81=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B0=D0=B5=20=D0=BD=D0=B5=D1=85=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B8=D0=B3=D1=80=D0=BE=D0=BA=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BA=D1=83=D0=BF=D0=BB=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=B3=D0=BE=D1=81=D1=82=20=D0=B8=D0=B2?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/ghost_role/_ghost_role.dm | 1 + modular_bandastation/storyteller/code/gamemode.dm | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/code/modules/events/ghost_role/_ghost_role.dm b/code/modules/events/ghost_role/_ghost_role.dm index 336fb4c03bbda..00decbc25a089 100644 --- a/code/modules/events/ghost_role/_ghost_role.dm +++ b/code/modules/events/ghost_role/_ghost_role.dm @@ -59,6 +59,7 @@ if(NOT_ENOUGH_PLAYERS) message_admins("[role_name] cannot be spawned due to lack of players signing up.") deadchat_broadcast(" did not get enough candidates ([minimum_required]) to spawn.", "[role_name]", message_type=DEADCHAT_ANNOUNCEMENT) + SSgamemode.refill_roleset() kill() return if(SUCCESSFUL_SPAWN) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 167d89ed6646e..b8c9ea12dc9f8 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -435,6 +435,10 @@ SUBSYSTEM_DEF(gamemode) event.try_start() INVOKE_ASYNC(event, TYPE_PROC_REF(/datum/round_event, try_start)) +/// Для восполнения очков ролсета +/datum/controller/subsystem/gamemode/proc/refill_roleset() + event_track_points[EVENT_TRACK_ROLESET] = point_thresholds[EVENT_TRACK_ROLESET] + /// Schedules an event to run later. /datum/controller/subsystem/gamemode/proc/schedule_event(datum/round_event_control/passed_event, passed_time, passed_cost, passed_ignore, passed_announce, _forced = FALSE) if(_forced) From c88d61f9cecacafa9576aa2aee0f8daeddbe7875 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 20 Dec 2024 20:30:21 +0300 Subject: [PATCH 084/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=87=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B7=D0=BC=D0=B5=D1=80=D0=BD=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=81=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D1=82?= =?UTF-8?q?=D0=B8=D0=B2=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=B2=D1=8B=D1=88?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=B0=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event.dm | 6 ++++++ .../code/event_defines/_round_event_control.dm | 10 +++++++--- .../code/event_defines/ghostset/paradox_clone.dm | 4 ++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 4385905f02eee..f9d372b451268 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -63,6 +63,9 @@ /datum/round_event/antagonist/solo/setup() var/datum/round_event_control/antagonist/solo/cast_control = control antag_count = cast_control.get_antag_amount() + if(!antag_count) + return + antag_flag = cast_control.antag_flag antag_datum = cast_control.antag_datum restricted_roles = cast_control.restricted_roles @@ -168,6 +171,9 @@ /datum/round_event/antagonist/solo/ghost/setup() var/datum/round_event_control/antagonist/solo/cast_control = control antag_count = cast_control.get_antag_amount() + if(!antag_count) + return + antag_flag = cast_control.antag_flag antag_datum = cast_control.antag_datum restricted_roles = cast_control.restricted_roles diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 371d1f3ecc895..7955ea3480a31 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -259,9 +259,13 @@ return FALSE /datum/round_event_control/antagonist/solo/proc/get_antag_amount() - var/people = SSgamemode.get_correct_popcount() - var/amount = base_antags + FLOOR(people / denominator, 1) - return min(amount, maximum_antags) + var/decided_count = rand(base_antags, maximum_antags) + + var/gamemode_antags_left = SSgamemode.get_antag_cap() - SSgamemode.get_antag_count() + var/maximum_to_spawn = min(gamemode_antags_left, maximum_antags) + + var/clamped_value = clamp(decided_count, 0, maximum_to_spawn) + return clamped_value /datum/round_event_control/antagonist/solo/proc/get_candidates() var/round_started = SSticker.HasRoundStarted() diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index 5a19b5f4fed47..c1279b4151458 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -26,8 +26,12 @@ possible_spawns += find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE) if(!possible_spawns.len) return + var/datum/round_event_control/antagonist/solo/cast_control = control antag_count = cast_control.get_antag_amount() + if(!antag_count) + return + antag_flag = cast_control.antag_flag antag_datum = cast_control.antag_datum restricted_roles = cast_control.restricted_roles From ed0b927d560bdb0db9f92ca9e746cb81081428cf Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 20 Dec 2024 21:41:17 +0300 Subject: [PATCH 085/135] =?UTF-8?q?=D0=92=D1=8B=D0=B2=D0=BE=D0=B4=20=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=20=D0=B8?= =?UTF-8?q?=D0=B2=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20=D0=B2=20=D1=81=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index b8c9ea12dc9f8..3484456f28b16 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -653,6 +653,7 @@ SUBSYSTEM_DEF(gamemode) for(var/datum/round_event_control/forced_event in forced_next_events[track]) message_admins("Storyteller purchased and triggered forced roundstart event [forced_event].") TriggerEvent(forced_event, forced = TRUE) + runned_events += "Runned forced roundstart: [forced_event.name]" forced_next_events[track] = list() @@ -691,6 +692,7 @@ SUBSYSTEM_DEF(gamemode) roundstart_budget -= picked_event.roundstart_cost message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget].") TriggerEvent(picked_event, forced = FALSE) + runned_events += "Runned roundstart: [picked_event.name]" // Если первое событие эксклюзивное, то отчищаем список if(picked_event.exclusive_roundstart_event) valid_events = list() @@ -723,6 +725,7 @@ SUBSYSTEM_DEF(gamemode) roundstart_budget -= scheduled_event.roundstart_cost message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") TriggerEvent(scheduled_event, forced = FALSE) + runned_events += "Runned scheduled roundstart: [scheduled_event.name]" scheduled_events_roleset -= scheduled_event if(scheduled_event.exclusive_roundstart_event) scheduled_event = list() From f768952c5418fde3e472acaeb63e9316936be603 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 23 Dec 2024 22:16:21 +0300 Subject: [PATCH 086/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=83=D0=B4?= =?UTF-8?q?=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BD=D0=B0=D1=81=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D1=8F.=20=D0=A4=D0=B8=D0=BA=D1=81=20=D1=87=D1=83?= =?UTF-8?q?=D0=B6=D0=B8=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/vote.dm | 2 +- .../storyteller/_storyteller.dme | 1 + .../storyteller/code/_defines/_ticker.dm | 1 + .../code/event_defines/crewset/_override.dm | 6 - .../ghostset/alien_infestation.dm | 103 ++++++++++++++++++ .../storyteller/code/gamemode.dm | 16 ++- .../code/storytellers/_storyteller.dm | 8 +- 7 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 7278cdadf30af..764b1c01de8c5 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -240,7 +240,7 @@ SUBSYSTEM_DEF(vote) log_vote(to_display) to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[span_bold(to_display)]\n\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // monkestation edit: wrap in examine block, use MESSAGE_TYPE_OOC + You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT: wrap in examine block, use MESSAGE_TYPE_OOC // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) diff --git a/modular_bandastation/storyteller/_storyteller.dme b/modular_bandastation/storyteller/_storyteller.dme index d9322e5dd6784..df1ab552e9341 100644 --- a/modular_bandastation/storyteller/_storyteller.dme +++ b/modular_bandastation/storyteller/_storyteller.dme @@ -32,6 +32,7 @@ #include "code\event_defines\ghostset\nuke_ops.dm" #include "code\event_defines\ghostset\wizard.dm" #include "code\event_defines\ghostset\paradox_clone.dm" +#include "code\event_defines\ghostset\alien_infestation.dm" #include "code\event_defines\major\override.dm" #include "code\event_defines\moderate\override.dm" diff --git a/modular_bandastation/storyteller/code/_defines/_ticker.dm b/modular_bandastation/storyteller/code/_defines/_ticker.dm index 161e16844e584..f863ec38edbce 100644 --- a/modular_bandastation/storyteller/code/_defines/_ticker.dm +++ b/modular_bandastation/storyteller/code/_defines/_ticker.dm @@ -1,4 +1,5 @@ /datum/controller/subsystem/ticker/PostSetup() . = .. () + SSgamemode.init_storyteller() SSgamemode.current_storyteller.process(STORYTELLER_WAIT_TIME * 0.1) // we want this asap SSgamemode.current_storyteller.round_started = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm index 2a16027847ec3..acc47c0ca873c 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm @@ -3,12 +3,6 @@ tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_ALIEN) weight = 2 -/datum/round_event_control/alien_infestation - track = EVENT_TRACK_ROLESET - tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_ALIEN) - earliest_start = 60 MINUTES - weight = 2 - /datum/round_event_control/blob track = EVENT_TRACK_ROLESET tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_EXTERNAL, TAG_ALIEN) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm new file mode 100644 index 0000000000000..ced2ea626627b --- /dev/null +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -0,0 +1,103 @@ +/datum/round_event_control/antagonist/solo/from_ghosts/alien_infestation + name = "Alien Infestation" + typepath = /datum/round_event/antagonist/solo/ghost/alien_infestation + weight = 3 + track = EVENT_TRACK_ROLESET + + min_players = 15 + + earliest_start = 60 MINUTES + + category = EVENT_CATEGORY_ENTITIES + description = "A xenomorph larva spawns on a random vent." + + maximum_antags = 1 + antag_flag = ROLE_ALIEN + enemy_roles = list( + JOB_AI, + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + ) + required_enemies = 3 + prompted_picking = TRUE + +/datum/round_event/antagonist/solo/ghost/alien_infestation + announce_when = 400 + fakeable = TRUE + + +/datum/round_event/antagonist/solo/ghost/alien_infestation/setup() + announce_when = rand(announce_when, announce_when + 50) + var/datum/round_event_control/antagonist/solo/cast_control = control + antag_count = cast_control.get_antag_amount() + + if(prob(50)) + antag_count++ + + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + restricted_roles = cast_control.restricted_roles + prompted_picking = cast_control.prompted_picking + var/list/candidates = cast_control.get_candidates() + + //guh + var/list/cliented_list = list() + for(var/mob/living/mob as anything in candidates) + cliented_list += mob.client + + candidates = SSpolling.poll_ghost_candidates(check_jobban = ROLE_ALIEN, role = ROLE_ALIEN, alert_pic = /mob/living/carbon/alien/larva, role_name_text = lowertext(cast_control.name)) + + if(!length(candidates)) + return NOT_ENOUGH_PLAYERS + + var/list/weighted_candidates = return_antag_weight(candidates) + + var/list/vents = list() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue//no parent vent + //Stops Aliens getting stuck in small networks. + //See: Security, Virology + if(temp_vent_parent.other_atmos_machines.len > 20) + vents += temp_vent + + if(!length(vents)) + message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.") + return MAP_ERROR + + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + if(!candidate.mind) + candidate.mind = new /datum/mind(candidate.key) + + var/obj/vent = pick_n_take(vents) + var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) + new_xeno.ckey = candidate_ckey + new_xeno.move_into_vent(vent) + selected_count++ + + message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.") + new_xeno.log_message("was spawned as an alien by an event.", LOG_GAME) + + setup = TRUE + +/datum/round_event/antagonist/solo/ghost/alien_infestation/announce(fake) + var/living_aliens = FALSE + for(var/mob/living/carbon/alien/A in GLOB.player_list) + if(A.stat != DEAD) + living_aliens = TRUE + + if(living_aliens || fake) + priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 3484456f28b16..f02f80247be19 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -209,6 +209,7 @@ SUBSYSTEM_DEF(gamemode) if(CONFIG_GET(flag/disable_storyteller)) // we're just gonna disable firing but still initialize, so we don't have any weird runtimes flags |= SS_NO_FIRE return SS_INIT_NO_NEED + return SS_INIT_SUCCESS /datum/controller/subsystem/gamemode/fire(resumed = FALSE) @@ -975,7 +976,7 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/set_storyteller(passed_type) if(!storytellers[passed_type]) message_admins("Attempted to set an invalid storyteller type: [passed_type], force setting to guide instead.") - current_storyteller = storytellers[/datum/storyteller/default] //if we dont have any then we brick, lets not do that + current_storyteller = /datum/storyteller/default //if we dont have any then we brick, lets not do that CRASH("Attempted to set an invalid storyteller type: [passed_type].") var/passed_state = FALSE if (current_storyteller) @@ -1090,7 +1091,7 @@ SUBSYSTEM_DEF(gamemode) var/list/forced_events = forced_next_events[track] var/forced = "" for(var/datum/round_event_control/forced_event in forced_events) - forced = forced + "[forced_event.name] X
" + forced = forced + "[forced_event.name] X
" dat += "[forced]" //Forced dat += "Set Pts. Next Event" //Actions dat += "" @@ -1354,9 +1355,14 @@ SUBSYSTEM_DEF(gamemode) switch(href_list["track_action"]) if("remove_forced") if(forced_next_events[track]) - var/datum/round_event_control/event = forced_next_events[track] - message_admins("[key_name_admin(usr)] removed forced event [event.name] from track [track].") - forced_next_events -= track + var/datum/round_event_control/forced_event_to_remove + for(var/datum/round_event_control/forced_event_to_check in forced_next_events[track]) + if(forced_event_to_check.name == href_list["forced_event_to_remove"]) + forced_event_to_remove = forced_event_to_check + if(!forced_event_to_remove) + return + message_admins("[key_name_admin(usr)] removed forced event [forced_event_to_remove.name] from track [forced_event_to_remove.track].") + forced_next_events[track] -= forced_event_to_remove if("set_pts") var/set_pts = input(usr, "New point amount ([point_thresholds[track]]+ invokes event):", "Set points for [track]") as num|null if(isnull(set_pts)) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index be7d64dc941b4..415a0b978fb32 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -98,11 +98,11 @@ var/datum/controller/subsystem/gamemode/mode = SSgamemode for(var/track in mode.event_track_points) var/points = mode.event_track_points[track] - if(points >= mode.point_thresholds[track]) - if(SSgamemode.can_run_roundstart) - SSgamemode.round_start_handle() - + if(SSgamemode.can_run_roundstart && track == EVENT_TRACK_ROLESET) + SSgamemode.round_start_handle() SSgamemode.can_run_roundstart = FALSE + + if(points >= mode.point_thresholds[track]) if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) calculate_empty_event(TRUE) mode.event_track_points[track] = 0 From 11b80d7fef0d2974094e7c0995d2d62f52ce5181 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 24 Dec 2024 12:31:53 +0300 Subject: [PATCH 087/135] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20?= =?UTF-8?q?dj-34?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/anomaly.dm | 2 +- code/__DEFINES/antagonists.dm | 4 +-- code/__HELPERS/roundend.dm | 6 ++--- code/_globalvars/lists/objects.dm | 2 +- code/controllers/master.dm | 2 +- code/controllers/subsystem/ambience.dm | 4 +-- code/controllers/subsystem/dynamic/dynamic.dm | 2 +- .../dynamic/dynamic_rulesets_midround.dm | 2 +- .../dynamic/dynamic_rulesets_roundstart.dm | 2 +- .../dynamic/dynamic_unfavorable_situation.dm | 4 +-- code/controllers/subsystem/events.dm | 10 +++---- code/controllers/subsystem/job.dm | 8 +++--- code/controllers/subsystem/statpanel.dm | 2 +- code/controllers/subsystem/ticker.dm | 6 ++--- code/controllers/subsystem/vote.dm | 6 ++--- code/datums/mind/_mind.dm | 4 +-- code/modules/admin/admin.dm | 4 +-- code/modules/admin/topic.dm | 4 +-- .../modules/antagonists/_common/antag_team.dm | 4 +-- code/modules/antagonists/brother/brother.dm | 4 +-- .../antagonists/nukeop/datums/operative.dm | 2 +- .../equipment/nuclear_bomb/_nuclear_bomb.dm | 4 +-- .../antagonists/pirate/pirate_event.dm | 2 +- code/modules/antagonists/wizard/wizard.dm | 2 +- code/modules/bitrunning/event.dm | 2 +- code/modules/events/_event.dm | 26 +++++++++---------- code/modules/events/anomaly/_anomaly.dm | 2 +- code/modules/events/aurora_caelus.dm | 2 +- code/modules/events/brand_intelligence.dm | 2 +- code/modules/events/bureaucratic_error.dm | 6 ++--- code/modules/events/carp_migration.dm | 2 +- code/modules/events/disease_outbreak.dm | 2 +- code/modules/events/false_alarm.dm | 2 +- code/modules/events/ghost_role/_ghost_role.dm | 2 +- .../events/ghost_role/alien_infestation.dm | 2 +- code/modules/events/ghost_role/blob.dm | 2 +- .../events/gravity_generator_blackout.dm | 2 +- code/modules/events/grey_tide.dm | 2 +- code/modules/events/heart_attack.dm | 2 +- code/modules/events/portal_storm.dm | 4 +-- code/modules/events/radiation_leak.dm | 2 +- code/modules/events/radiation_storm.dm | 2 +- code/modules/events/sandstorm.dm | 2 +- code/modules/events/scrubber_overflow.dm | 4 +-- code/modules/events/shuttle_catastrophe.dm | 4 +-- code/modules/events/shuttle_insurance.dm | 4 +-- .../events/shuttle_loan/shuttle_loan_event.dm | 2 +- code/modules/events/space_vines/vine_event.dm | 2 +- code/modules/events/spider_infestation.dm | 2 +- code/modules/events/stray_cargo.dm | 2 +- code/modules/events/supermatter_surge.dm | 2 +- code/modules/events/tram_malfunction.dm | 4 +-- code/modules/events/vent_clog.dm | 2 +- code/modules/events/wizard/embeddies.dm | 2 +- code/modules/events/wizard/identity_spoof.dm | 2 +- code/modules/events/wizard/petsplosion.dm | 2 +- code/modules/events/wormholes.dm | 2 +- code/modules/mob/dead/new_player/login.dm | 2 +- .../event_defines/_round_event_control.dm | 2 +- 59 files changed, 100 insertions(+), 100 deletions(-) diff --git a/code/__DEFINES/anomaly.dm b/code/__DEFINES/anomaly.dm index cf07b3b7e615c..0cafbe77c20b1 100644 --- a/code/__DEFINES/anomaly.dm +++ b/code/__DEFINES/anomaly.dm @@ -4,7 +4,7 @@ */ ///Time in ticks before the anomaly goes poof/explodes depending on type. -#define ANOMALY_COUNTDOWN_TIMER (200 SECONDS) // BANDASTATION EDIT - STORYTELLER: 99 seconds -> 200 seconds +#define ANOMALY_COUNTDOWN_TIMER (200 SECONDS) // BANDASTATION EDIT - STORYTELLER: 120 seconds -> 200 seconds /** * Nuisance/funny anomalies diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 05a9e92ca7f29..7643f0c63d86b 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -392,12 +392,12 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( // This flag disables certain checks that presume antagonist datums mean 'baddie'. #define FLAG_FAKE_ANTAG (1 << 0) -/// BANDASTATION EDIT START - STORYTELLER +// BANDASTATION EDIT START - STORYTELLER // The storyteller will ignore this antag datum as counting against the antag cap. #define FLAG_ANTAG_CAP_IGNORE (1 << 1) // The storyteller will count everyone on this antag's team as a singular antag instead. #define FLAG_ANTAG_CAP_TEAM (1 << 2) -/// BANDASTATION EDIT END - STORYTELLER +// BANDASTATION EDIT END - STORYTELLER #define HUNTER_PACK_COPS "Spacepol Fugitive Hunters" #define HUNTER_PACK_RUSSIAN "Russian Fugitive Hunters" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 8b09235255176..6b5ba04d49dd1 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -243,10 +243,10 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) //Set news report and mode result SSdynamic.set_round_result() - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER SSgamemode.round_end_report() SSgamemode.store_roundend_data() // store data on roundend for next round - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER to_chat(world, span_infoplain(span_big(span_bold("


The round has ended.")))) log_game("The round has ended.") @@ -310,7 +310,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) var/list/parts = list() //might want to make this a full section - parts += SSgamemode.create_roundend_score() //BANDASTATION EDIT - STORYTELLER + parts += SSgamemode.create_roundend_score() // BANDASTATION EDIT - STORYTELLER //AI laws parts += law_report() diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index f2abe575ca5b1..9c3e93144bc97 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -104,4 +104,4 @@ GLOBAL_LIST_INIT(prototype_organs, typecacheof(list( /obj/item/organ/eyes/dullahan, ), only_root_path = TRUE)) -GLOBAL_LIST_EMPTY(nuke_list) /// BANDASTATION EDIT - STORYTELLER +GLOBAL_LIST_EMPTY(nuke_list) // BANDASTATION EDIT - STORYTELLER diff --git a/code/controllers/master.dm b/code/controllers/master.dm index db0f455ca76d5..6a7ce6e0252f5 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -388,7 +388,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie if(sleep_offline_after_initializations && CONFIG_GET(flag/resume_after_initializations)) world.sleep_offline = FALSE initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 - SSgamemode.handle_picking_storyteller() //BANDASTATION EDIT - STORYTELLER + SSgamemode.handle_picking_storyteller() // BANDASTATION EDIT - STORYTELLER /** * Initialize a given subsystem and handle the results. diff --git a/code/controllers/subsystem/ambience.dm b/code/controllers/subsystem/ambience.dm index 402fd43360452..3c824e6bd5ab7 100644 --- a/code/controllers/subsystem/ambience.dm +++ b/code/controllers/subsystem/ambience.dm @@ -114,11 +114,11 @@ SUBSYSTEM_DEF(ambience) return var/area/my_area = get_area(src) - /// BANDASTATION EDIT START - STORYTELLERS + // BANDASTATION EDIT START - STORYTELLERS var/sound_to_use if(my_area) sound_to_use= my_area.ambient_buzz - /// BANDASTATION EDIT END - STORYTELLERS + // BANDASTATION EDIT END - STORYTELLERS var/volume_modifier = client.prefs.read_preference(/datum/preference/numeric/sound_ship_ambience_volume) diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index 450dc05818cd1..a7d4e9070bcb4 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -149,7 +149,7 @@ SUBSYSTEM_DEF(dynamic) var/waittime_h = 1800 /// A number between 0 and 100. The maximum amount of threat allowed to generate. - var/max_threat_level = 0 /// BANDASTATION EDIT - STORYTELLER + var/max_threat_level = 0 // BANDASTATION EDIT - STORYTELLER /// The extra chance multiplier that a heavy impact midround ruleset will run next time. /// For example, if this is set to 50, then the next heavy roll will be about 50% more likely to happen. diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm index 0e99e02da4ff6..1742b88e090a3 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm @@ -387,7 +387,7 @@ cost = 7 minimum_round_time = 70 MINUTES requirements = REQUIREMENTS_VERY_HIGH_THREAT_NEEDED - //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER + //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) // BANDASTATION EDIT - STORYTELLER flags = HIGH_IMPACT_RULESET signup_item_path = /obj/machinery/nuclearbomb diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm index 55529270fd4ae..facb56f315bd8 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm @@ -410,7 +410,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) requirements = list(90,90,90,80,60,40,30,20,10,10) flags = HIGH_IMPACT_RULESET antag_cap = list("denominator" = 18, "offset" = 1) - //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER + //ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) // BANDASTATION EDIT - STORYTELLER var/required_role = ROLE_NUCLEAR_OPERATIVE var/datum/team/nuclear/nuke_team ///The job type to dress up our nuclear operative as. diff --git a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm index ce5730bdf4935..2fd759f15e6e1 100644 --- a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm +++ b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm @@ -36,13 +36,13 @@ if (ruleset.weight == 0) continue - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if (ruleset.cost > max_threat_level) continue if (!ruleset.acceptable(GLOB.alive_player_list.len, threat_level)) continue - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if (ruleset.minimum_round_time > world.time - SSticker.round_start_time) continue diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 58c0fadca86ad..443d873297f7e 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -73,7 +73,7 @@ SUBSYSTEM_DEF(events) */ /datum/controller/subsystem/events/proc/spawnEvent(datum/round_event_control/excluded_event) set waitfor = FALSE //for the admin prompt - if(!CONFIG_GET(flag/allow_random_events) || !excluded_event) /// BANDASTATION EDIT START - STORYTELLER - No SSevents spawn except rerolling + if(!CONFIG_GET(flag/allow_random_events) || !excluded_event) // BANDASTATION EDIT START - STORYTELLER - No SSevents spawn except rerolling return var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) @@ -97,10 +97,10 @@ SUBSYSTEM_DEF(events) var/datum/round_event_control/event_to_run = pick_weight(event_roster) if(event_to_run) - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER /// TriggerEvent(event_to_run) SSgamemode.TriggerEvent(event_to_run, forced = FALSE) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER ///Does the last pre-flight checks for the passed event, and runs it if the event is ready. @@ -109,12 +109,12 @@ SUBSYSTEM_DEF(events) if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0 event_to_trigger.max_occurrences = 0 else if(. == EVENT_READY) - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER //event_to_trigger.run_event(random = TRUE) message_admins("SSevents runs and try to buy a event: [event_to_trigger.name]!") log_game("SSevents runs and try to buy a event: [event_to_trigger.name]!") SSgamemode.current_storyteller.try_buy_event(src) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER ///Toggles whether or not wizard events will be in the event pool, and sends a notification to the admins. diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 0437c5b02da00..2915b43bfbdee 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -84,10 +84,10 @@ SUBSYSTEM_DEF(job) ## The game will not read any line that is commented out with a '#', as to allow you to defer to codebase defaults.\n## If you want to override the codebase values, add the value and then uncomment that line by removing the # from the job key's name.\n\ ## Ensure that the key is flush, do not introduce any whitespaces when you uncomment a key. For example:\n## \"# Total Positions\" should always be changed to \"Total Positions\", no additional spacing.\n\ ## Best of luck editing!\n" - /// BANDASTATIONE EDIT START - STORYTELLER + // BANDASTATIONE EDIT START - STORYTELLER /// Assoc list of new players keyed to the type of job they will currently get var/list/assigned_players_by_job = list() - /// BANDASTATIONE EDIT END - STORYTELLER + // BANDASTATIONE EDIT END - STORYTELLER /datum/controller/subsystem/job/Initialize() setup_job_lists() @@ -984,7 +984,7 @@ SUBSYSTEM_DEF(job) return FALSE -/// BANDASTATION EDIT START - STORYTELLER +// BANDASTATION EDIT START - STORYTELLER /datum/controller/subsystem/job/proc/FreeRole(rank) if(!rank) return @@ -1077,4 +1077,4 @@ SUBSYSTEM_DEF(job) destination = get_last_resort_spawn_points() destination.JoinPlayerHere(M, buckle) -/// BANDASTATION EDIT END - STORYTELLER +// BANDASTATION EDIT END - STORYTELLER diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 086e75ba364d3..a7bed27196bf1 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -26,7 +26,7 @@ SUBSYSTEM_DEF(statpanels) global_data = list( "Map: [SSmapping.current_map?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, - "Storyteller: [!SSgamemode.secret_storyteller && SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "Secret"]", // BANDASTATION EDIT ADDITION + "Storyteller: [!SSgamemode.secret_storyteller && SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "Secret"]", // BANDASTATION ADDITION - STORYTELLER "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Players Connected: [LAZYLEN(GLOB.clients)]", // BANDASTATION ADD "Players in Lobby: [LAZYLEN(GLOB.new_player_list)]", // BANDASTATION ADD diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 013d924b0a2a8..931049f893f76 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(ticker) to_chat(world, span_notice("Welcome to [station_name()]!")) send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.current_map.map_name]!"), CONFIG_GET(string/channel_announce_new_game)) current_state = GAME_STATE_PREGAME - //SSvote.initiate_vote(/datum/vote/storyteller, "Storyteller Vote", forced = TRUE) // BANDASTATION EDIT ADDITION + //SSvote.initiate_vote(/datum/vote/storyteller, "Storyteller Vote", forced = TRUE) // BANDASTATION EDIT - STORYTELLER SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) fire() @@ -230,7 +230,7 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/setup() to_chat(world, span_boldannounce("Starting game...")) var/init_start = world.timeofday - // BANDASTATION EDIT BEGIN - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER CHECK_TICK //Configure mode and assign player to antagonists var/can_continue = FALSE @@ -303,7 +303,7 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE - //SSdynamic.post_setup() /// BANDASTATION EDIT STORYTELLER - отключение пост-сетапа динамика + //SSdynamic.post_setup() // BANDASTATION EDIT STORYTELLER - отключение пост-сетапа динамика GLOB.start_state = new /datum/station_state() GLOB.start_state.count() diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 764b1c01de8c5..89ddb42a32607 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -240,7 +240,7 @@ SUBSYSTEM_DEF(vote) log_vote(to_display) to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[span_bold(to_display)]\n\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT: wrap in examine block, use MESSAGE_TYPE_OOC + You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT - STORYTELLER: wrap in examine block, use MESSAGE_TYPE_OOC // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) @@ -338,10 +338,10 @@ SUBSYSTEM_DEF(vote) "message" = can_vote == VOTE_AVAILABLE ? vote.default_message : can_vote, ) - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(vote.has_desc) vote_data += list("desc" = vote.return_desc(vote_name)) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if(vote == current_vote) var/list/choices = list() diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index 4d27df326e1c3..78d009aa2cf29 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -102,10 +102,10 @@ var/list/failed_special_equipment /// A list to keep track of which books a person has read (to prevent people from reading the same book again and again for positive mood events) var/list/book_titles_read - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER /// Variable that lets the event picker see if someones getting chosen or not var/picking = FALSE - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER /datum/mind/New(_key) key = _key diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 78557cd929b5f..81b76c087d3a1 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -20,7 +20,7 @@ return var/dat = "
Game Panel

" - /// BANDASTATION EDIT START- STORYTELLER + // BANDASTATION EDIT START- STORYTELLER /* if(SSticker.current_state <= GAME_STATE_PREGAME) @@ -36,7 +36,7 @@ dat += "(Manage Dynamic Rulesets)
" */ dat += "(Game Mode Panel)
" - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER dat += {"
Create Object
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1cc1bac9cdfd6..4adefa98f2b4b 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -69,10 +69,10 @@ else if(href_list["gamemode_panel"]) if(!check_rights(R_ADMIN)) return - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER //SSdynamic.admin_panel() SSgamemode.admin_panel(usr) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER else if(href_list["call_shuttle"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm index 96f8b4391fa97..66e1693c2d646 100644 --- a/code/modules/antagonists/_common/antag_team.dm +++ b/code/modules/antagonists/_common/antag_team.dm @@ -44,13 +44,13 @@ GLOBAL_LIST_EMPTY(antagonist_teams) new_objective.find_target(dupe_search_range = list(src)) new_objective.update_explanation_text() objectives += new_objective - /// BANDASTATION EDIT START - STORYTELLER. Я удивлен, почему это в Сторителлере, но Окэээй. + // BANDASTATION EDIT START - STORYTELLER. Я удивлен, почему это в Сторителлере, но Окэээй. for(var/datum/mind/member as anything in members) for(var/datum/antagonist/antag in member.antag_datums) if(antag.get_team() == src) antag.objectives |= new_objective antag.update_static_data_for_all_viewers()\ - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER //Display members/victory/failure/objectives for the team /datum/team/proc/roundend_report() diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm index 3b0e6e2a5fffc..1b2028ef7977d 100644 --- a/code/modules/antagonists/brother/brother.dm +++ b/code/modules/antagonists/brother/brother.dm @@ -24,12 +24,12 @@ return team /datum/antagonist/brother/on_gain() - /// BANDASTATION EDIT START - STORYTELLER - фикс ББ на отсутствие задач и команды + // BANDASTATION EDIT START - STORYTELLER - фикс ББ на отсутствие задач и команды if(!team) var/datum/team/brother_team/brother_team = new /datum/team/brother_team brother_team.add_member(owner) create_team(brother_team) - /// BANDASTATION EDIT END - STORYTELLER - фикс ББ на отсутствие задач и команды + // BANDASTATION EDIT END - STORYTELLER - фикс ББ на отсутствие задач и команды objectives += team.objectives owner.special_role = special_role finalize_brother() diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index 031d745aaf90c..17df2aac07f39 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -198,7 +198,7 @@ /// Actually moves our nukie to where they should be /datum/antagonist/nukeop/proc/move_to_spawnpoint() // Ensure that the nukiebase is loaded, and wait for it if required - //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) /// BANDASTATION EDIT - STORYTELLER + //SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) // BANDASTATION EDIT - STORYTELLER var/turf/destination = get_spawnpoint() owner.current.forceMove(destination) if(!owner.current.onSyndieBase()) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm index a7ee7a97e8160..4c87d2a20ffe2 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm @@ -57,7 +57,7 @@ GLOBAL_VAR(station_nuke_source) /obj/machinery/nuclearbomb/Initialize(mapload) . = ..() countdown = new(src) - GLOB.nuke_list += src /// BANDASTATION EDIT - STORYTELLER + GLOB.nuke_list += src // BANDASTATION EDIT - STORYTELLER core = new /obj/item/nuke_core(src) STOP_PROCESSING(SSobj, core) update_appearance() @@ -69,7 +69,7 @@ GLOBAL_VAR(station_nuke_source) if(!exploding) // If we're not exploding, set the alert level back to normal toggle_nuke_safety() - GLOB.nuke_list -= src /// BANDASTATION EDIT - STORYTELLER + GLOB.nuke_list -= src // BANDASTATION EDIT - STORYTELLER QDEL_NULL(countdown) QDEL_NULL(core) return ..() diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm index a8613cb54cbe2..6c6949eaeb6e2 100644 --- a/code/modules/antagonists/pirate/pirate_event.dm +++ b/code/modules/antagonists/pirate/pirate_event.dm @@ -14,7 +14,7 @@ admin_setup = list(/datum/event_admin_setup/listed_options/pirates) map_flags = EVENT_SPACE_ONLY -/datum/round_event_control/pirates/preRunEvent(scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/pirates/preRunEvent(scheduled = FALSE) // BANDASTATION EDIT - STORYTELLER if (SSmapping.is_planetary()) return EVENT_CANT_RUN return ..() diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 284ee82b1003b..78e26ffa1c73b 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) /datum/antagonist/wizard/proc/send_to_lair() // And now we ensure that its loaded - // SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) /// BANDASTATION EDIT - STORYTELLER + // SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_WIZARDDEN) // BANDASTATION EDIT - STORYTELLER if(!owner.current) return diff --git a/code/modules/bitrunning/event.dm b/code/modules/bitrunning/event.dm index c53c97b1dba75..fa6c83c1bd1a9 100644 --- a/code/modules/bitrunning/event.dm +++ b/code/modules/bitrunning/event.dm @@ -14,7 +14,7 @@ /// List of servers on the station var/list/datum/weakref/active_servers = list() -/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 4cfdfe476497d..97a79c1dee421 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -70,9 +70,9 @@ // Checks if the event can be spawned. Used by event controller and "false alarm" event. // Admin-created events override this. -/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/proc/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER SHOULD_CALL_PARENT(TRUE) - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) return FALSE if(event_group && !GLOB.event_groups[event_group].can_run()) @@ -81,7 +81,7 @@ return FALSE if(!roundstart && (SSgamemode.can_run_roundstart)) return FALSE - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) return FALSE if(earliest_start >= (world.time - SSticker.round_start_time)) @@ -96,7 +96,7 @@ return FALSE if(ispath(typepath, /datum/round_event/ghost_role) && !(GLOB.ghost_role_flags & GHOSTROLE_MIDROUND_EVENT)) return FALSE - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(checks_antag_cap && !SSgamemode.can_inject_antags()) return FALSE if(!weight) @@ -115,12 +115,12 @@ return FALSE if(head_required_power > SSgamemode.current_head_power) return FALSE - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) return FALSE return TRUE -/datum/round_event_control/proc/preRunEvent(forced = FALSE, scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/proc/preRunEvent(forced = FALSE, scheduled = FALSE) // BANDASTATION EDIT - STORYTELLER if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN @@ -129,22 +129,22 @@ triggering = TRUE - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(!roundstart && !scheduled) // We sleep HERE, in pre-event setup (because there's no sense doing it in run_event() since the event is already running!) for the given amount of time to make an admin has enough time to cancel an event un-fitting of the present round or at least reroll it. message_admins("Random Event triggering in [DisplayTimeText(RANDOM_EVENT_ADMIN_INTERVENTION_TIME)]: [name]. (CANCEL) (SOMETHING ELSE)") sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!can_spawn_event(players_amt, fake_check = TRUE) && !forced) /// BANDSTATION EDIT - STORYTELLER message_admins("Second pre-condition check for [name] failed, rerolling...") SSevents.spawnEvent(excluded_event = src) return EVENT_INTERRUPTED - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(!can_spawn_event(players_amt, fake_check = TRUE) && forced) message_admins("Second pre-condition check for [name] failed, but event forced, running event regardless this may have issues...") - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if(!triggering) return EVENT_CANCELLED //admin cancelled @@ -261,7 +261,7 @@ Runs the event //This is really only for setting defaults which can be overridden later when New() finishes. /datum/round_event/proc/setup() SHOULD_CALL_PARENT(FALSE) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER return ///Announces the event name to deadchat, override this if what an event should show to deadchat is different to its event name. @@ -315,10 +315,10 @@ Runs the event //This proc will handle the calls to the appropriate procs. /datum/round_event/process() SHOULD_NOT_OVERRIDE(TRUE) - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER if(!setup) return - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if(!processing) return diff --git a/code/modules/events/anomaly/_anomaly.dm b/code/modules/events/anomaly/_anomaly.dm index 53cfde92faeff..9f4e5c427394b 100644 --- a/code/modules/events/anomaly/_anomaly.dm +++ b/code/modules/events/anomaly/_anomaly.dm @@ -24,7 +24,7 @@ impact_area = get_area(spawn_location) else impact_area = placer.findValidArea() - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/anomaly/announce(fake) if(isnull(impact_area)) diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index 7089ede474cd3..f3b07a485c628 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -7,7 +7,7 @@ category = EVENT_CATEGORY_FRIENDLY description = "A colourful display can be seen through select windows. And the kitchen." -/datum/round_event_control/aurora_caelus/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/aurora_caelus/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER if(!SSmapping.empty_space) return FALSE return ..() diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index d092747b47835..d5528ecd07258 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -46,7 +46,7 @@ kill() return origin_machine = pick_n_take(vending_machines) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/brand_intelligence/announce(fake) var/machine_name = initial(origin_machine.name) diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 0228fdfd18899..8a4123427580f 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -20,11 +20,11 @@ overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it. for(var/job in jobs) var/datum/job/current = job - /// BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER //current.total_positions = 0 current.total_positions = max(current.total_positions + rand(-2,4), 1) - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER return // Adds/removes a random amount of job slots from all jobs. for(var/datum/job/current as anything in jobs) - current.total_positions = max(current.total_positions + rand(-2,4), 1) /// BANDASTATION EDIT - STORYTELLER + current.total_positions = max(current.total_positions + rand(-2,4), 1) // BANDASTATION EDIT - STORYTELLER diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 7a2911d6322b3..b3ec1001ff526 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -35,7 +35,7 @@ /datum/round_event/carp_migration/setup() start_when = rand(40, 60) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/carp_migration/announce(fake) priority_announce("[fluff_signal] have been detected near [station_name()], please stand-by.", "Lifesign Alert") diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 2355b16c2ae5c..5854aafeb1f87 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -37,7 +37,7 @@ ///Disease recipient candidates var/list/disease_candidates = list() -/datum/round_event_control/disease_outbreak/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/disease_outbreak/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/false_alarm.dm b/code/modules/events/false_alarm.dm index 3e5978c916ed1..59898bfaf5df4 100644 --- a/code/modules/events/false_alarm.dm +++ b/code/modules/events/false_alarm.dm @@ -7,7 +7,7 @@ description = "Fakes an event announcement." admin_setup = list(/datum/event_admin_setup/listed_options/false_alarm) -/datum/round_event_control/falsealarm/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/falsealarm/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/ghost_role/_ghost_role.dm b/code/modules/events/ghost_role/_ghost_role.dm index 00decbc25a089..e9651c1f74ff6 100644 --- a/code/modules/events/ghost_role/_ghost_role.dm +++ b/code/modules/events/ghost_role/_ghost_role.dm @@ -59,7 +59,7 @@ if(NOT_ENOUGH_PLAYERS) message_admins("[role_name] cannot be spawned due to lack of players signing up.") deadchat_broadcast(" did not get enough candidates ([minimum_required]) to spawn.", "[role_name]", message_type=DEADCHAT_ANNOUNCEMENT) - SSgamemode.refill_roleset() + SSgamemode.refill_roleset() // BANDASTATION ADDITION - STORYTELLER kill() return if(SUCCESSFUL_SPAWN) diff --git a/code/modules/events/ghost_role/alien_infestation.dm b/code/modules/events/ghost_role/alien_infestation.dm index 151be3d964452..0be5d9f3ff4f6 100644 --- a/code/modules/events/ghost_role/alien_infestation.dm +++ b/code/modules/events/ghost_role/alien_infestation.dm @@ -9,7 +9,7 @@ category = EVENT_CATEGORY_ENTITIES description = "A xenomorph larva spawns on a random vent." -/datum/round_event_control/alien_infestation/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/alien_infestation/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/ghost_role/blob.dm b/code/modules/events/ghost_role/blob.dm index 774dde389bf06..8146f96b76baf 100644 --- a/code/modules/events/ghost_role/blob.dm +++ b/code/modules/events/ghost_role/blob.dm @@ -10,7 +10,7 @@ category = EVENT_CATEGORY_ENTITIES description = "Spawns a new blob overmind." -/datum/round_event_control/blob/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/blob/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER if(EMERGENCY_PAST_POINT_OF_NO_RETURN) // no blobs if the shuttle is past the point of no return return FALSE diff --git a/code/modules/events/gravity_generator_blackout.dm b/code/modules/events/gravity_generator_blackout.dm index 08c2a271df600..e8503565e8877 100644 --- a/code/modules/events/gravity_generator_blackout.dm +++ b/code/modules/events/gravity_generator_blackout.dm @@ -7,7 +7,7 @@ min_wizard_trigger_potency = 0 max_wizard_trigger_potency = 4 -/datum/round_event_control/gravity_generator_blackout/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/gravity_generator_blackout/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/grey_tide.dm b/code/modules/events/grey_tide.dm index b7024c64e10f5..508ad1c7533b9 100644 --- a/code/modules/events/grey_tide.dm +++ b/code/modules/events/grey_tide.dm @@ -20,7 +20,7 @@ announce_when = rand(50, 60) end_when = rand(20, 30) severity = rand(1,3) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER var/list/potential_areas = list(/area/station/command, /area/station/engineering, diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 000f480b2f062..54144a3672763 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -12,7 +12,7 @@ ///Candidates for receiving a healthy dose of heart disease var/list/heart_attack_candidates = list() -/datum/round_event_control/heart_attack/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/heart_attack/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index c6530c7aff586..a94e6caf0689a 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -3,7 +3,7 @@ typepath = /datum/round_event/portal_storm/syndicate_shocktroop weight = 2 min_players = 15 - max_occurrences = 1 //BANDASTATION EDIT - STORYTELLER + max_occurrences = 1 // BANDASTATION EDIT - STORYTELLER earliest_start = 30 MINUTES category = EVENT_CATEGORY_ENTITIES description = "Syndicate troops pour out of portals." @@ -70,7 +70,7 @@ hostiles_spawn += get_random_station_turf() next_boss_spawn = start_when + CEILING(2 * number_of_hostiles / number_of_bosses, 1) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/portal_storm/announce(fake) set waitfor = 0 diff --git a/code/modules/events/radiation_leak.dm b/code/modules/events/radiation_leak.dm index e835a14dd9120..53ea16b226bd7 100644 --- a/code/modules/events/radiation_leak.dm +++ b/code/modules/events/radiation_leak.dm @@ -47,7 +47,7 @@ // We found something, we can just return now picked_machine_ref = WEAKREF(sick_device) return - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/radiation_leak/announce(fake) var/obj/machinery/the_source_of_our_problems = picked_machine_ref?.resolve() diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 95e7f3224be10..d61c49e3cec8d 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -14,7 +14,7 @@ start_when = 3 end_when = start_when + 1 announce_when = 1 - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /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", ANNOUNCER_RADIATION) diff --git a/code/modules/events/sandstorm.dm b/code/modules/events/sandstorm.dm index f44276e9ca90c..71eeeb46ee68b 100644 --- a/code/modules/events/sandstorm.dm +++ b/code/modules/events/sandstorm.dm @@ -30,7 +30,7 @@ /datum/round_event/sandstorm/setup() start_when = rand(70, 90) end_when = rand(110, 140) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/sandstorm/announce(fake) if(!start_side) diff --git a/code/modules/events/scrubber_overflow.dm b/code/modules/events/scrubber_overflow.dm index 7c670a4508014..6624ed375fb15 100644 --- a/code/modules/events/scrubber_overflow.dm +++ b/code/modules/events/scrubber_overflow.dm @@ -84,9 +84,9 @@ if(!scrubbers.len) return kill() - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER -/datum/round_event_control/scrubber_overflow/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/scrubber_overflow/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return diff --git a/code/modules/events/shuttle_catastrophe.dm b/code/modules/events/shuttle_catastrophe.dm index df87d2ecdae4a..189250ad30394 100644 --- a/code/modules/events/shuttle_catastrophe.dm +++ b/code/modules/events/shuttle_catastrophe.dm @@ -7,7 +7,7 @@ description = "Replaces the emergency shuttle with a random one." admin_setup = list(/datum/event_admin_setup/warn_admin/shuttle_catastrophe, /datum/event_admin_setup/listed_options/shuttle_catastrophe) -/datum/round_event_control/shuttle_catastrophe/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/shuttle_catastrophe/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . @@ -46,7 +46,7 @@ if(!isnull(template.who_can_purchase) && template.credit_cost < INFINITY) //if we could get it from the communications console, it's cool for us to get it here valid_shuttle_templates += template new_shuttle = pick(valid_shuttle_templates) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/shuttle_catastrophe/start() if(SSshuttle.shuttle_insurance) diff --git a/code/modules/events/shuttle_insurance.dm b/code/modules/events/shuttle_insurance.dm index fe2f433634c98..37942f14e4226 100644 --- a/code/modules/events/shuttle_insurance.dm +++ b/code/modules/events/shuttle_insurance.dm @@ -7,7 +7,7 @@ category = EVENT_CATEGORY_BUREAUCRATIC description = "A sketchy but legit insurance offer." -/datum/round_event_control/shuttle_insurance/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/shuttle_insurance/can_spawn_event(players, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . @@ -39,7 +39,7 @@ break if(!insurance_evaluation) insurance_evaluation = 5000 //gee i dunno - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/shuttle_insurance/start() insurance_message = new("Shuttle Insurance", "Hey, pal, this is the [ship_name]. Can't help but notice you're rocking a wild and crazy shuttle there with NO INSURANCE! Crazy. What if something happened to it, huh?! We've done a quick evaluation on your rates in this sector and we're offering [insurance_evaluation] to cover for your shuttle in case of any disaster.", list("Purchase Insurance.","Reject Offer.")) diff --git a/code/modules/events/shuttle_loan/shuttle_loan_event.dm b/code/modules/events/shuttle_loan/shuttle_loan_event.dm index c3c5c869ccbb8..f20eba9e48ef3 100644 --- a/code/modules/events/shuttle_loan/shuttle_loan_event.dm +++ b/code/modules/events/shuttle_loan/shuttle_loan_event.dm @@ -11,7 +11,7 @@ ///A list of normally unavailable (or already run) situations datums var/list/unavailable_situations = list(/datum/shuttle_loan_situation/mail_strike) -/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() for(var/datum/round_event/running_event in SSevents.running) if(istype(running_event, /datum/round_event/shuttle_loan)) //Make sure two of these don't happen at once. diff --git a/code/modules/events/space_vines/vine_event.dm b/code/modules/events/space_vines/vine_event.dm index 195e22b2f94b4..04e73d17c663e 100644 --- a/code/modules/events/space_vines/vine_event.dm +++ b/code/modules/events/space_vines/vine_event.dm @@ -3,7 +3,7 @@ typepath = /datum/round_event/spacevine weight = 15 max_occurrences = 3 - min_players = 25 //BANDASTATION EDIT - STORYTELLER: 10 ==> 25 + min_players = 25 // BANDASTATION EDIT - STORYTELLER: 10 ==> 25 category = EVENT_CATEGORY_ENTITIES description = "Kudzu begins to overtake the station. Might spawn man-traps." min_wizard_trigger_potency = 4 diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 35a9100942d38..c2d9c625959b7 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -16,7 +16,7 @@ /datum/round_event/spider_infestation/setup() announce_when = rand(announce_when, announce_when + 50) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/spider_infestation/announce(fake) priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index 3f140e5511235..ec45485be20f8 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -66,7 +66,7 @@ var/datum/supply_pack/pack_type = pack if(initial(pack_type.special)) stray_spawnable_supply_packs -= pack - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER ///Spawns a random supply pack, puts it in a pod, and spawns it on a random tile of the selected area /datum/round_event/stray_cargo/start() diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm index bd0222d8d45d4..e1477307c3d8d 100644 --- a/code/modules/events/supermatter_surge.dm +++ b/code/modules/events/supermatter_surge.dm @@ -37,7 +37,7 @@ /datum/event_admin_setup/input_number/surge_spiciness, ) -/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/supermatter_surge/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!SSjob.has_minimum_jobs(crew_threshold = 3, jobs = JOB_GROUP_ENGINEERS, head_jobs = list(JOB_CHIEF_ENGINEER))) diff --git a/code/modules/events/tram_malfunction.dm b/code/modules/events/tram_malfunction.dm index 3b67a105f0fd6..cdbe4a14d7d3d 100644 --- a/code/modules/events/tram_malfunction.dm +++ b/code/modules/events/tram_malfunction.dm @@ -13,7 +13,7 @@ max_wizard_trigger_potency = 3 //Check if there's a tram we can cause to malfunction. -/datum/round_event_control/tram_malfunction/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/tram_malfunction/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if (!.) return FALSE @@ -33,7 +33,7 @@ /datum/round_event/tram_malfunction/setup() end_when = rand(TRAM_MALFUNCTION_TIME_LOWER, TRAM_MALFUNCTION_TIME_UPPER) - setup = TRUE /// BANDASTATION EDIT - STORYTELLER + setup = TRUE // BANDASTATION EDIT - STORYTELLER /datum/round_event/tram_malfunction/start() for(var/datum/transport_controller/linear/tram/malfunctioning_controller as anything in SStransport.transports_by_type[TRANSPORT_TYPE_TRAM]) diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index cf0aa7a7d3ec3..28175251da16e 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -8,7 +8,7 @@ category = EVENT_CATEGORY_JANITORIAL description = "Harmless mobs climb out of a vent." -/datum/round_event_control/vent_clog/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/vent_clog/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return diff --git a/code/modules/events/wizard/embeddies.dm b/code/modules/events/wizard/embeddies.dm index 075e3c8064384..3f33d9717f795 100644 --- a/code/modules/events/wizard/embeddies.dm +++ b/code/modules/events/wizard/embeddies.dm @@ -9,7 +9,7 @@ max_wizard_trigger_potency = 7 ///behold... the only reason sticky is a subtype... -/datum/round_event_control/wizard/embedpocalypse/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/wizard/embedpocalypse/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/wizard/identity_spoof.dm b/code/modules/events/wizard/identity_spoof.dm index f54cf4d88d260..5aab6e7866e7f 100644 --- a/code/modules/events/wizard/identity_spoof.dm +++ b/code/modules/events/wizard/identity_spoof.dm @@ -5,7 +5,7 @@ max_occurrences = 1 description = "Makes everyone dressed up like a wizard." -/datum/round_event_control/wizard/identity_spoof/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/wizard/identity_spoof/can_spawn_event(players_amt, allow_magic = FALSE, fake_check = FALSE) // BANDASTATION EDIT - STORYTELLER . = ..() if(!.) return . diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index db85c29b7bea0..1feff87fbd0e8 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /// Number of mobs we're going to duplicate var/mobs_to_dupe = 0 -/datum/round_event_control/wizard/petsplosion/preRunEvent(scheduled = FALSE) /// BANDASTATION EDIT - STORYTELLER +/datum/round_event_control/wizard/petsplosion/preRunEvent(scheduled = FALSE) // BANDASTATION EDIT - STORYTELLER for(var/mob/living/basic/dupe_animal in GLOB.alive_mob_list) count_mob(dupe_animal) for(var/mob/living/simple_animal/dupe_animal in GLOB.alive_mob_list) diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index ac01dc271700b..ca74d702df897 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to /datum/round_event/wormholes/setup() announce_when = rand(0, 20) end_when = rand(40, 80) - setup = TRUE + setup = TRUE // BANDASTATION ADDITION - STORYTELLER /datum/round_event/wormholes/start() for(var/turf/open/floor/valid in GLOB.station_turfs) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 4cbd2ee859fe6..251ada377a194 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -21,7 +21,7 @@ if (required_living_minutes >= living_minutes) client.interviewee = TRUE - check_whitelist_or_make_interviewee() /// Bandastation Add + check_whitelist_or_make_interviewee() // BANDASTATION Add . = ..() if(!. || !client) return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 7955ea3480a31..290de7c275a98 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -47,7 +47,7 @@ if(string) string += "," string += "Not roundstart" - /// BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER if(occurrences >= max_occurrences) if(string) string += "," From 7a10299a7b70c239f63c226898bed101b6fd4b77 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 24 Dec 2024 19:05:42 +0300 Subject: [PATCH 088/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BB=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D0=B0=20=D0=B8=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D1=8B=20?= =?UTF-8?q?=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__HELPERS/roundend.dm | 4 +- .../storyteller/code/gamemode.dm | 45 ++++++++++++------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 6b5ba04d49dd1..f22bb89420ab4 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -243,10 +243,10 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) //Set news report and mode result SSdynamic.set_round_result() - // BANDASTATION EDIT START - STORYTELLER + // BANDASTATION EDIT START - STORYTELLER SSgamemode.round_end_report() SSgamemode.store_roundend_data() // store data on roundend for next round - // BANDASTATION EDIT END - STORYTELLER + // BANDASTATION EDIT END - STORYTELLER to_chat(world, span_infoplain(span_big(span_bold("


The round has ended.")))) log_game("The round has ended.") diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index f02f80247be19..007a03e52a997 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -241,24 +241,35 @@ SUBSYSTEM_DEF(gamemode) return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() - . = 0 + var/count = 0 var/list/already_counted = list() // Never count the same mind twice - for(var/datum/antagonist/antag as anything in GLOB.antagonists) - if(QDELETED(antag) || QDELETED(antag.owner) || already_counted[antag.owner]) - continue - if(!antag.count_against_dynamic_roll_chance || (antag.antag_flags & (FLAG_FAKE_ANTAG | FLAG_ANTAG_CAP_IGNORE))) - continue - if(antag.antag_flags & FLAG_ANTAG_CAP_TEAM) - var/datum/team/antag_team = antag.get_team() - if(antag_team) - if(already_counted[antag_team]) - continue - already_counted[antag_team] = TRUE - var/mob/antag_mob = antag.owner.current - if(QDELETED(antag_mob) || !antag_mob.key || antag_mob.stat == DEAD || antag_mob.client?.is_afk()) - continue - already_counted[antag.owner] = TRUE - .++ + if(SSticker.HasRoundStarted()) + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(QDELETED(antag) || QDELETED(antag.owner) || already_counted[antag.owner]) + continue + if(!antag.count_against_dynamic_roll_chance || (antag.antag_flags & (FLAG_FAKE_ANTAG | FLAG_ANTAG_CAP_IGNORE))) + continue + if(antag.antag_flags & FLAG_ANTAG_CAP_TEAM) + var/datum/team/antag_team = antag.get_team() + if(antag_team) + if(already_counted[antag_team]) + continue + already_counted[antag_team] = TRUE + var/mob/antag_mob = antag.owner.current + if(QDELETED(antag_mob) || !antag_mob.key || antag_mob.stat == DEAD || antag_mob.client?.is_afk()) + continue + already_counted[antag.owner] = TRUE + count++ + else + for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) + if(player.ready != PLAYER_READY_TO_PLAY) + continue + var/client/client_source = player.client + if(QDELETED(client_source) || !client_source.ckey) + continue + if(player.mind.picking) + count++ + return count /// Whether events can inject more antagonists into the round /datum/controller/subsystem/gamemode/proc/can_inject_antags() From 2fe6797cff68ef9ff7c5252b45a0e0ec16d5216d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 24 Dec 2024 20:20:35 +0300 Subject: [PATCH 089/135] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=84=D0=B8=D0=BA=D1=81=D0=B0=20=D0=BB=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/_common/antag_team.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm index 66e1693c2d646..a53ef2ff19071 100644 --- a/code/modules/antagonists/_common/antag_team.dm +++ b/code/modules/antagonists/_common/antag_team.dm @@ -49,7 +49,7 @@ GLOBAL_LIST_EMPTY(antagonist_teams) for(var/datum/antagonist/antag in member.antag_datums) if(antag.get_team() == src) antag.objectives |= new_objective - antag.update_static_data_for_all_viewers()\ + antag.update_static_data_for_all_viewers() // BANDASTATION EDIT END - STORYTELLER //Display members/victory/failure/objectives for the team From ba4f4006263c8e63c05c4ec3d200b0a1dc5fa8e7 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 25 Dec 2024 21:50:09 +0300 Subject: [PATCH 090/135] =?UTF-8?q?=D0=A7=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BC=D0=B5=D1=80=D0=B4=D0=B6?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/admin/admin.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 459a7e933ffb2..b6c481fdc74d8 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -32,9 +32,11 @@ dat += "(Dynamic mode options)
" dat += "
" if(SSticker.IsRoundInProgress()) - dat += "(Game Mode Panel)
" dat += "(Manage Dynamic Rulesets)
" dat += {" + */ + dat += "(Game Mode Panel)
" + // BANDASTATION EDIT END - STORYTELLER
Create Object
Quick Create Object
From 06252e3f83895c5ff4dffaef98b0b1f60bcdd7cd Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 25 Dec 2024 21:51:44 +0300 Subject: [PATCH 091/135] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=20=D0=BE=D0=B1=D1=89=D0=B5?= =?UTF-8?q?=D0=BC=D1=83=20=D0=B2=D0=B8=D0=B4=D1=83=20=D0=BF=D0=BE=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8?= =?UTF-8?q?=D1=85=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/scheduled_event.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/scheduled_event.dm b/modular_bandastation/storyteller/code/scheduled_event.dm index 2b0c8e5009115..f79130b9cffc2 100644 --- a/modular_bandastation/storyteller/code/scheduled_event.dm +++ b/modular_bandastation/storyteller/code/scheduled_event.dm @@ -40,9 +40,9 @@ /datum/scheduled_event/proc/get_href_actions() var/round_started = SSticker.HasRoundStarted() if(round_started) - return "Fire Reschedule Cancel Refund" + return "Fire Reschedule Cancel Refund" else - return "Cancel" + return "Cancel" /// Try and fire off the scheduled event /datum/scheduled_event/proc/try_fire() From d28113456a77bcc2c0b9f756e525623565e4128a Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 25 Dec 2024 22:06:14 +0300 Subject: [PATCH 092/135] =?UTF-8?q?=D0=9B=D0=B8=D0=BD=D1=82=D0=B5=D1=80=20?= =?UTF-8?q?=D0=9A=D0=B0=D0=B3=D0=B8=20-=201:0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/vote.dm | 6 +++--- code/modules/admin/admin.dm | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 89ddb42a32607..80eff00900a57 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -119,7 +119,7 @@ SUBSYSTEM_DEF(vote) ) log_vote("vote finalized", vote_log_data) if(to_display) - to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[to_display]"))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT - STORYTELLER: wrap in examine block, use MESSAGE_TYPE_OOC + to_chat(world, span_infoplain(vote_font("[to_display]"))) // Finally, doing any effects on vote completion current_vote.finalize_vote(final_winner) @@ -238,9 +238,9 @@ SUBSYSTEM_DEF(vote) var/to_display = current_vote.initiate_vote(vote_initiator_name, duration) log_vote(to_display) - to_chat(world, "\n" + examine_block(span_infoplain(vote_font("[span_bold(to_display)]\n\ + to_chat(world, custom_boxed_message("purple_box center", span_infoplain(vote_font("[span_bold(to_display)]
\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + "\n", type = MESSAGE_TYPE_OOC) // BANDASTATION EDIT - STORYTELLER: wrap in examine block, use MESSAGE_TYPE_OOC + You have [DisplayTimeText(duration)] to vote.")))) // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b6c481fdc74d8..fda2e32b92331 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -33,11 +33,10 @@ dat += "
" if(SSticker.IsRoundInProgress()) dat += "(Manage Dynamic Rulesets)
" - dat += {" */ - dat += "(Game Mode Panel)
" - // BANDASTATION EDIT END - STORYTELLER -
+ dat += "(Game Mode Panel)
" + // BANDASTATION EDIT END - STORYTELLER + dat += {" Create Object
Quick Create Object
Create Turf
From be9d6abaf52ad161b9c47914d21d21e4eda7ec81 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 27 Dec 2024 17:52:52 +0300 Subject: [PATCH 093/135] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D0=B1=D0=BB=D0=BE?= =?UTF-8?q?=D0=BA=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=A1=D0=A2=20(?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D1=80=D0=B5=D0=BC=D1=8F=20=D0=B0=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B1=D0=B0=D1=86=D0=B8=D0=B8=20=D1=81=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B5=D0=BC=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 007a03e52a997..c7d0b506ba7a8 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -931,8 +931,8 @@ SUBSYSTEM_DEF(gamemode) if(CONFIG_GET(flag/disable_storyteller)) return if(length(GLOB.clients) > MAX_POP_FOR_STORYTELLER_VOTE) - secret_storyteller = TRUE - selected_storyteller = pick_weight(get_valid_storytellers(TRUE)) + secret_storyteller = FALSE + //selected_storyteller = pick_weight(get_valid_storytellers(TRUE)) return //SSvote.initiate_vote(/datum/vote/storyteller, "pick round storyteller", forced = TRUE) From baa47ebb7a8d696e488ae37e21826b0319b0eba8 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 27 Dec 2024 22:04:22 +0300 Subject: [PATCH 094/135] =?UTF-8?q?=D0=92=D1=81=D0=B5=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F=20=D1=81=20=D0=BA=D0=BE=D0=BD=D1=81?= =?UTF-8?q?=D0=BE=D0=BB=D0=B8=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B3=D1=83=D1=82=20=D0=B1=D1=8B=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D1=83=D1=89=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subsystem/dynamic/dynamic_unfavorable_situation.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm index 2fd759f15e6e1..02baccf8a100a 100644 --- a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm +++ b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm @@ -37,11 +37,13 @@ continue // BANDASTATION EDIT START - STORYTELLER + /* if (ruleset.cost > max_threat_level) continue if (!ruleset.acceptable(GLOB.alive_player_list.len, threat_level)) continue + */ // BANDASTATION EDIT END - STORYTELLER if (ruleset.minimum_round_time > world.time - SSticker.round_start_time) From 42c493c55fa275e548835c9937392435c2df5f38 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 29 Dec 2024 23:49:27 +0300 Subject: [PATCH 095/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D1=81=20=D0=B1=D1=8E=D0=B4=D0=B6=D0=B5=D1=82=D0=B0=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=BF=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BE=D0=BA=20?= =?UTF-8?q?=D1=81=20=D1=84=D0=BE=D1=80=D1=88=D0=B5=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=BE=D0=B2,=20=D0=BA=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D1=8B=D0=B5=20=D0=BC=D0=BE=D0=B3=D0=BB=D0=B8?= =?UTF-8?q?=20=D0=B8=D1=85=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B5?= =?UTF-8?q?=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BA=D0=B5=20=D0=B8=D0=B3?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 1 + .../storyteller/code/event_defines/_round_event.dm | 6 ++++-- .../code/event_defines/_round_event_control.dm | 4 ++-- .../code/event_defines/ghostset/alien_infestation.dm | 2 +- .../code/event_defines/ghostset/paradox_clone.dm | 2 +- modular_bandastation/storyteller/code/gamemode.dm | 11 ++++++----- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index c18b15c537fb4..9cbfde67cdde7 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -193,6 +193,7 @@ Runs the event for(var/datum/event_admin_setup/admin_setup_datum in admin_setup) admin_setup_datum.apply_to_event(round_event) SEND_SIGNAL(src, COMSIG_CREATED_ROUND_EVENT, round_event) + round_event.forced = admin_forced round_event.setup() round_event.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) occurrences++ diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index f9d372b451268..2b43fe3756c0c 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -5,6 +5,8 @@ var/setup = FALSE ///Записывать ли событие в лог СТ для вывода в конце раунда? var/excute_round_end_reports = FALSE + ///Ивент считается форшеным? + var/forced = FALSE /// This section of event processing is in a proc because roundstart events may get their start invoked. /datum/round_event/proc/try_start() @@ -62,7 +64,7 @@ /datum/round_event/antagonist/solo/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount() + antag_count = cast_control.get_antag_amount(forced) if(!antag_count) return @@ -170,7 +172,7 @@ /datum/round_event/antagonist/solo/ghost/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount() + antag_count = cast_control.get_antag_amount(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 290de7c275a98..d063d337f8d77 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -258,10 +258,10 @@ if(length(candidates) < antag_amt) return FALSE -/datum/round_event_control/antagonist/solo/proc/get_antag_amount() +/datum/round_event_control/antagonist/solo/proc/get_antag_amount(forced_event = FALSE) var/decided_count = rand(base_antags, maximum_antags) - var/gamemode_antags_left = SSgamemode.get_antag_cap() - SSgamemode.get_antag_count() + var/gamemode_antags_left = SSgamemode.get_antag_cap(forced_event) - SSgamemode.get_antag_count() var/maximum_to_spawn = min(gamemode_antags_left, maximum_antags) var/clamped_value = clamp(decided_count, 0, maximum_to_spawn) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index ced2ea626627b..643634158f577 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -32,7 +32,7 @@ /datum/round_event/antagonist/solo/ghost/alien_infestation/setup() announce_when = rand(announce_when, announce_when + 50) var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount() + antag_count = cast_control.get_antag_amount(forced) if(prob(50)) antag_count++ diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index c1279b4151458..edc2e8c7aaa05 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -28,7 +28,7 @@ return var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount() + antag_count = cast_control.get_antag_amount(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index c7d0b506ba7a8..937077600b1a5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -174,7 +174,7 @@ SUBSYSTEM_DEF(gamemode) var/list/presetuped_ocupations = list() var/empty_event_chance = 0 var/roundstart_budget = 0 - var/roundstart_budget_set = 0 + var/roundstart_budget_set = -1 /datum/controller/subsystem/gamemode/Initialize(time, zlevel) // Populate event pools @@ -232,9 +232,9 @@ SUBSYSTEM_DEF(gamemode) current_storyteller.process(STORYTELLER_WAIT_TIME * 0.1) /// Gets the number of antagonists the antagonist injection events will stop rolling after. -/datum/controller/subsystem/gamemode/proc/get_antag_cap() +/datum/controller/subsystem/gamemode/proc/get_antag_cap(forced = FALSE) var/pop_count = get_correct_popcount() - if(pop_count < current_storyteller.min_antag_popcount) + if(pop_count < current_storyteller.min_antag_popcount && !forced) return 0 var/total_number = pop_count + (sec_crew * current_storyteller.sec_antag_modifier) var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) + current_storyteller.antag_flat_cap @@ -686,7 +686,8 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) - roundstart_budget = roundstart_budget_set ? roundstart_budget_set : pop_count + var/calculated_roundstart_budget = pop_count + roundstart_budget = roundstart_budget_set == -1 ? calculated_roundstart_budget : roundstart_budget_set /datum/controller/subsystem/gamemode/proc/rountstart_general_events_run(valid_events, track) @@ -1046,7 +1047,7 @@ SUBSYSTEM_DEF(gamemode) dat += "
Roundstart info: Roundstart budget = ready_players([ready_players]) + (sec_crew([sec_crew]) * current_storyteller.sec_antag_modifier([current_storyteller.sec_antag_modifier])) = [roundstart_budget]" dat += "
Раундстартовый бюджет для событий, расчитанный с помощью формулы выше." dat += "
Roundstart info: Forced Roundstart budget = [roundstart_budget_set]" - dat += "
Зафоршенный андминами раундстарт бюджет." + dat += "
Зафоршенный андминами раундстарт бюджет. Установите -1 для автоматического расчета." dat += "
" dat += "
Point Gains Multipliers (only over time):" From 2c3a8154525ea8cfb1b41a2abdb3868aeeda0b26 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 30 Dec 2024 00:29:55 +0300 Subject: [PATCH 096/135] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=A2:=20Andy=20Prime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/modular_bandastation.dme | 1 + .../storyteller/code/storytellers/storyteller_prime.dm | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme index a38a43dc7cf17..63a28177ad1dc 100644 --- a/modular_bandastation/modular_bandastation.dme +++ b/modular_bandastation/modular_bandastation.dme @@ -54,4 +54,5 @@ // Модпаки включены по умолчанию для запуска всех тестов и для этого кода тоже. #ifndef DISABLE_PRIME_MODPACKS #include "prime_only/_prime_only.dme" +#include "storyteller/code/storytellers/storyteller_prime.dm" #endif diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm new file mode 100644 index 0000000000000..9ebb7ec132e74 --- /dev/null +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -0,0 +1,10 @@ +/datum/controller/subsystem/gamemode/Initialize(time, zlevel) + . = ..() + selected_storyteller = /datum/storyteller/prime + +/datum/storyteller/prime + name = "Andy Prime" + desc = "Andy Prime is the default Storyteller, and the comparison point for every other Storyteller. Best for an average, varied experience." + always_votable = TRUE + welcome_text = "I am not your Andy!" + weight = 6 From 2a1f59fa04b584e557d6dd62279651cf996f0607 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 7 Jan 2025 00:21:50 +0300 Subject: [PATCH 097/135] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8,?= =?UTF-8?q?=20=D0=BE=D1=82=D1=81=D0=BB=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subsystem/dynamic/dynamic_unfavorable_situation.dm | 5 ++++- code/modules/events/_event.dm | 4 +++- .../storyteller/code/storytellers/_storyteller.dm | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm index 02baccf8a100a..06b5a1d7626f9 100644 --- a/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm +++ b/code/controllers/subsystem/dynamic/dynamic_unfavorable_situation.dm @@ -29,7 +29,10 @@ return list() var/list/possible_heavies = list() - for (var/datum/dynamic_ruleset/midround/ruleset as anything in midround_rules) + // BANDASTATION EDIT START - STORYTELLER + var/list/generated_midround_rules = init_rulesets(/datum/dynamic_ruleset/midround) + for (var/datum/dynamic_ruleset/midround/ruleset as anything in generated_midround_rules) + // BANDASTATION EDIT END - STORYTELLER if (ruleset.midround_ruleset_style != MIDROUND_RULESET_STYLE_HEAVY) continue diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 9cbfde67cdde7..793c5bf0f1507 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -136,14 +136,16 @@ sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME) // BANDASTATION EDIT END - STORYTELLER var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) - if(!can_spawn_event(players_amt, fake_check = TRUE) && !forced) /// BANDSTATION EDIT - STORYTELLER + if(!can_spawn_event(players_amt, fake_check = TRUE) && !forced && !roundstart) /// BANDSTATION EDIT - STORYTELLER message_admins("Second pre-condition check for [name] failed, rerolling...") + message_admins("REASON: [return_failure_string(players_amt)]")/// BANDSTATION EDIT - STORYTELLER SSevents.spawnEvent(excluded_event = src) return EVENT_INTERRUPTED // BANDASTATION EDIT START - STORYTELLER if(!can_spawn_event(players_amt, fake_check = TRUE) && forced) message_admins("Second pre-condition check for [name] failed, but event forced, running event regardless this may have issues...") + message_admins("REASON: [return_failure_string(players_amt)]") // BANDASTATION EDIT END - STORYTELLER if(!triggering) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 415a0b978fb32..02995c84d881d 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -192,7 +192,6 @@ message_admins("Storyteller purchased and triggered [bought_event] event, on [track] track, for [total_cost] cost.") if(bought_event.roundstart) mode.TriggerEvent(bought_event, forced) - SSgamemode.can_run_roundstart = FALSE else mode.schedule_event(bought_event, 3 MINUTES, total_cost, _forced = forced) From 33ed7185ddbde18591e444234a33ff5aa83deb7d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 8 Jan 2025 00:33:57 +0300 Subject: [PATCH 098/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=81=D0=B5=D1=81=D1=81?= =?UTF-8?q?=D0=B5=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/obsessed.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index 96ec6d0ee7511..0feb9ad3e1b39 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -1,7 +1,8 @@ /datum/round_event_control/antagonist/solo/obsessed antag_flag = ROLE_OBSESSED tags = list(TAG_COMBAT) - antag_datum = /datum/antagonist/obsessed + antag_datum // потому-что антаг выдается через событие + typepath = /datum/round_event/obsessed restricted_roles = list( JOB_AI, JOB_CYBORG, @@ -14,3 +15,4 @@ name = "Compulsive Obsession" prompted_picking = FALSE maximum_antags = 4 + From 0c6be169a09ca27c3d28923dd6d328d6e16831cc Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 8 Jan 2025 01:00:01 +0300 Subject: [PATCH 099/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B=20=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D1=87=D0=B5=D1=82=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/space_dragon/space_carp.dm | 1 + code/modules/bitrunning/antagonists/ghost_role.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/code/modules/antagonists/space_dragon/space_carp.dm b/code/modules/antagonists/space_dragon/space_carp.dm index 0d06ea3991d99..58133b42d30cd 100644 --- a/code/modules/antagonists/space_dragon/space_carp.dm +++ b/code/modules/antagonists/space_dragon/space_carp.dm @@ -5,6 +5,7 @@ show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE + antag_flags = FLAG_ANTAG_CAP_IGNORE // BANDASTATION EDIT - STORYTELLER /// The rift to protect var/datum/weakref/rift diff --git a/code/modules/bitrunning/antagonists/ghost_role.dm b/code/modules/bitrunning/antagonists/ghost_role.dm index 3bf88e16dfb21..e2cf2ad761b53 100644 --- a/code/modules/bitrunning/antagonists/ghost_role.dm +++ b/code/modules/bitrunning/antagonists/ghost_role.dm @@ -1,6 +1,7 @@ /datum/antagonist/domain_ghost_actor name = "Virtual Domain Actor" antagpanel_category = ANTAG_GROUP_GLITCH + antag_flags = FLAG_FAKE_ANTAG |FLAG_ANTAG_CAP_IGNORE // BANDASTATION EDIT - STORYTELLER job_rank = ROLE_GLITCH show_to_ghosts = TRUE suicide_cry = "FATAL ERROR" From b366a56c2bcbbe97ebf58a1235580be8878e9ab0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 12 Jan 2025 01:25:23 +0300 Subject: [PATCH 100/135] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=B5=D0=B9=D0=BA-=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=B3=20=D1=84=D0=BB=D0=B0=D0=B3=D0=B0=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=81=D0=B5=D1=81=D1=81=D0=B5=D0=B4=D1=83=20(?= =?UTF-8?q?=D1=80=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1=8E)=20=D0=B8=20?= =?UTF-8?q?=D0=B3=D0=BB=D0=B8=D1=87=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/obsessed/obsessed.dm | 4 +++- code/modules/bitrunning/antagonists/_parent.dm | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm index cd58d6fec5d9a..134d4006e21f8 100644 --- a/code/modules/antagonists/obsessed/obsessed.dm +++ b/code/modules/antagonists/obsessed/obsessed.dm @@ -23,6 +23,8 @@ var/objectives_to_generate = 3 /// Brain trauma that causes the obsession var/datum/brain_trauma/special/obsessed/trauma + antag_flags = FLAG_FAKE_ANTAG // BANDASTATION EDIT - STORYTELLER + /// Dummy antag datum that will show the cured obsessed to admins /datum/antagonist/former_obsessed @@ -34,7 +36,7 @@ count_against_dynamic_roll_chance = FALSE silent = TRUE can_elimination_hijack = ELIMINATION_PREVENT - antag_flags = FLAG_FAKE_ANTAG + antag_flags = FLAG_FAKE_ANTAG | FLAG_ANTAG_CAP_IGNORE // BANDASTATION EDIT - STORYTELLER /datum/antagonist/obsessed/admin_add(datum/mind/new_owner,mob/admin) var/mob/living/carbon/C = new_owner.current diff --git a/code/modules/bitrunning/antagonists/_parent.dm b/code/modules/bitrunning/antagonists/_parent.dm index 8bd061d72a1df..9e23f46ab14f6 100644 --- a/code/modules/bitrunning/antagonists/_parent.dm +++ b/code/modules/bitrunning/antagonists/_parent.dm @@ -12,6 +12,7 @@ show_to_ghosts = TRUE suicide_cry = "ALT F4!" ui_name = "AntagInfoGlitch" + antag_flags = FLAG_FAKE_ANTAG // BANDASTATION EDIT - STORYTELLER /// Minimum Qserver threat required to spawn this mob. This is subtracted (x/2) from the server thereafter. var/threat = 0 From cd96b83944b7f13cfdced5bc38c723ac5ce1aa74 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 12 Jan 2025 02:55:07 +0300 Subject: [PATCH 101/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B4=D0=BE=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event.dm | 1 + .../storyteller/code/event_defines/crewset/blood_brothers.dm | 1 + .../storyteller/code/event_defines/crewset/cult.dm | 1 + .../storyteller/code/event_defines/crewset/revolution.dm | 1 + .../storyteller/code/event_defines/crewset/wizard.dm | 1 + .../storyteller/code/event_defines/ghostset/nuke_ops.dm | 1 + .../storyteller/code/event_defines/ghostset/paradox_clone.dm | 1 + .../storyteller/code/event_defines/ghostset/wizard.dm | 1 + modular_bandastation/storyteller/code/gamemode.dm | 2 ++ 9 files changed, 10 insertions(+) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 2b43fe3756c0c..84cf5def18275 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -144,6 +144,7 @@ /datum/round_event/antagonist/solo/proc/add_datum_to_mind(datum/mind/antag_mind) antag_mind.add_antag_datum(antag_datum) + GLOB.pre_setup_antags -= antag_mind /datum/round_event/antagonist/solo/proc/spawn_extra_events() if(!LAZYLEN(extra_spawned_events)) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index dfc29d2d20895..e1f6c778c06fb 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -51,3 +51,4 @@ team.add_member(antag_mind) team.forge_brother_objectives() antag_mind.add_antag_datum(/datum/antagonist/brother, team) + GLOB.pre_setup_antags -= antag_mind diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 06798c01949d5..76900557c0b4d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -52,6 +52,7 @@ new_cultist.cult_team = main_cult new_cultist.give_equipment = TRUE antag_mind.add_antag_datum(new_cultist) + GLOB.pre_setup_antags -= antag_mind /datum/round_event/antagonist/solo/bloodcult/round_end_report() if(main_cult.check_cult_victory()) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index b0a5bf53680ff..31476e5ac696a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -55,6 +55,7 @@ revolution.update_objectives() revolution.update_rev_heads() SSshuttle.registerHostileEnvironment(revolution) + GLOB.pre_setup_antags -= antag_mind /datum/round_event/antagonist/solo/revolutionary/round_end_report() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index 75810a7ca5600..b9af47aa8202b 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -48,3 +48,4 @@ antag_mind.transfer_to(new_player_mob) qdel(current_mob) antag_mind.make_wizard() + GLOB.pre_setup_antags -= antag_mind diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm index 520ca53ad2dc8..d7f82fc89e45b 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -69,6 +69,7 @@ var/datum/antagonist/nukeop/new_op = new antag_datum() antag_mind.add_antag_datum(new_op) + GLOB.pre_setup_antags -= antag_mind //this might be able to be kept as just calling parent /datum/round_event/antagonist/solo/ghost/nuclear_operative/round_end_report() diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index edc2e8c7aaa05..bd556d07f4952 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -80,6 +80,7 @@ message_admins("[ADMIN_LOOKUPFLW(new_human)] has been made into a Paradox Clone by the midround ruleset.") new_human.log_message("was spawned as a Paradox Clone of [key_name(new_human)] by the midround ruleset.", LOG_GAME) + GLOB.pre_setup_antags -= antag_mind /** diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm index 41b92c6033305..f5f4dcfc32357 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/wizard.dm @@ -35,3 +35,4 @@ /datum/round_event/antagonist/solo/ghost/wizard/add_datum_to_mind(datum/mind/antag_mind) . = ..() antag_mind.current.forceMove(pick(GLOB.wizardstart)) + GLOB.pre_setup_antags -= antag_mind diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 937077600b1a5..b497fa41be7f4 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -268,6 +268,8 @@ SUBSYSTEM_DEF(gamemode) if(QDELETED(client_source) || !client_source.ckey) continue if(player.mind.picking) + if(!(player.mind in GLOB.pre_setup_antags)) + GLOB.pre_setup_antags += player.mind count++ return count From cc71d7150709897bda07e64fb9d72805c38afa11 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 12 Jan 2025 16:17:31 +0300 Subject: [PATCH 102/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D0=A1=D0=A2=20=D0=B2=20=D0=B1=D0=BE=D0=BB?= =?UTF-8?q?=D0=B5=D0=B5=20=D1=80=D0=B0=D0=BD=D1=8E=D1=8E=20=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=B4=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 2 +- modular_bandastation/storyteller/code/_defines/_ticker.dm | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 83b84851d4447..2a83f90b0bf8f 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -168,6 +168,7 @@ SUBSYSTEM_DEF(ticker) fire() if(GAME_STATE_PREGAME) //lobby stats for statpanels + SSgamemode.init_storyteller() // BANDASTATION EDIT - STORYTELLER if(isnull(timeLeft)) timeLeft = max(0,start_at - world.time) totalPlayers = LAZYLEN(GLOB.new_player_list) @@ -195,7 +196,6 @@ SUBSYSTEM_DEF(ticker) SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP) current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) - SSgamemode.init_storyteller() // BANDASTATION EDIT - STORYTELLER if(start_immediately) fire() diff --git a/modular_bandastation/storyteller/code/_defines/_ticker.dm b/modular_bandastation/storyteller/code/_defines/_ticker.dm index f863ec38edbce..161e16844e584 100644 --- a/modular_bandastation/storyteller/code/_defines/_ticker.dm +++ b/modular_bandastation/storyteller/code/_defines/_ticker.dm @@ -1,5 +1,4 @@ /datum/controller/subsystem/ticker/PostSetup() . = .. () - SSgamemode.init_storyteller() SSgamemode.current_storyteller.process(STORYTELLER_WAIT_TIME * 0.1) // we want this asap SSgamemode.current_storyteller.round_started = TRUE From 023f66d4dd079e62fd28912d7767752a1cfc14d3 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 12 Jan 2025 22:11:01 +0300 Subject: [PATCH 103/135] =?UTF-8?q?=D0=94=D0=BB=D1=8F=20=D1=81=D0=BF=D0=B0?= =?UTF-8?q?=D0=B2=D0=BD=D0=B0=20=D0=B5=D1=80=D0=B5=D1=82=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=BB=D0=B8=D1=87=D0=B8=D0=B5=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=82=D0=B8=D0=B2=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=A1=D0=91,=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20?= =?UTF-8?q?=D0=B3=D0=BB=D0=B0=D0=B2,=20=D0=BF=D0=BE=D0=BF=D1=8B=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=84=D0=B8=D0=BA=D1=81=D0=B0=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=B0=D0=BF?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/_round_event.dm | 4 ++-- .../event_defines/_round_event_control.dm | 21 ++++++++++++------- .../event_defines/crewset/blood_brothers.dm | 2 ++ .../code/event_defines/crewset/changeling.dm | 2 ++ .../code/event_defines/crewset/cult.dm | 2 ++ .../code/event_defines/crewset/heretic.dm | 10 +++++++++ .../code/event_defines/crewset/malf.dm | 2 ++ .../code/event_defines/crewset/nuke_ops.dm | 2 ++ .../code/event_defines/crewset/revolution.dm | 2 ++ .../code/event_defines/crewset/traitors.dm | 2 ++ .../code/event_defines/crewset/wizard.dm | 2 ++ .../ghostset/alien_infestation.dm | 4 +++- .../event_defines/ghostset/paradox_clone.dm | 2 +- .../storyteller/code/gamemode.dm | 2 +- .../code/storytellers/_storyteller.dm | 1 + 15 files changed, 47 insertions(+), 13 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 84cf5def18275..7daf3d0cd936e 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -64,7 +64,7 @@ /datum/round_event/antagonist/solo/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount(forced) + antag_count = cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return @@ -173,7 +173,7 @@ /datum/round_event/antagonist/solo/ghost/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount(forced) + antag_count = cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index d063d337f8d77..f50e4df29afdb 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -121,9 +121,9 @@ /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() - var/antag_amt = get_antag_amount() + var/antag_amt = get_antag_count_to_spawn() var/list/candidates = get_candidates() //we should optimize this - if(length(candidates) < antag_amt) + if((length(candidates) < antag_amt) || !antag_amt) if(.) . += ", " . += "Not Enough Candidates!" @@ -253,18 +253,23 @@ . = ..() if(!.) return - var/antag_amt = get_antag_amount() + var/antag_amt = get_antag_count_to_spawn() var/list/candidates = get_candidates() - if(length(candidates) < antag_amt) + if((length(candidates) < antag_amt) || !antag_amt) return FALSE -/datum/round_event_control/antagonist/solo/proc/get_antag_amount(forced_event = FALSE) +/datum/round_event_control/antagonist/solo/proc/get_antag_count_to_spawn(forced_event = FALSE) var/decided_count = rand(base_antags, maximum_antags) - - var/gamemode_antags_left = SSgamemode.get_antag_cap(forced_event) - SSgamemode.get_antag_count() + var/current_cap = SSgamemode.get_antag_cap(forced_event) + var/gamemode_antags_left = current_cap - SSgamemode.get_antag_count() var/maximum_to_spawn = min(gamemode_antags_left, maximum_antags) - var/clamped_value = clamp(decided_count, 0, maximum_to_spawn) + + //double check + var/predicted_count = clamped_value + SSgamemode.get_antag_count() + while(predicted_count > current_cap && clamped_value > 0) + clamped_value-- + return clamped_value /datum/round_event_control/antagonist/solo/proc/get_candidates() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index e1f6c778c06fb..d1339b81a3b16 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -11,6 +11,8 @@ JOB_RESEARCH_DIRECTOR, JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 609dd7c977a80..80587d056dbe1 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -13,6 +13,8 @@ JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) restricted_roles = list( JOB_AI, diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 76900557c0b4d..8bc4c4e3eefb5 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -15,6 +15,8 @@ JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) maximum_antags = 3 enemy_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index f547a93e9a0ee..11bcdc65944d3 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -8,6 +8,8 @@ JOB_CHIEF_ENGINEER, JOB_CHIEF_MEDICAL_OFFICER, JOB_RESEARCH_DIRECTOR, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, JOB_DETECTIVE, JOB_HEAD_OF_PERSONNEL, JOB_HEAD_OF_SECURITY, @@ -19,6 +21,13 @@ JOB_AI, JOB_CYBORG, ) + enemy_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_SECURITY, + JOB_DETECTIVE, + JOB_WARDEN, + JOB_SECURITY_OFFICER, + ) weight = 4 min_players = 20 @@ -30,3 +39,4 @@ /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" prompted_picking = FALSE + required_enemies = 3 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index bfa65fc7134ba..51fa982fbfff5 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -10,6 +10,8 @@ JOB_SCIENTIST, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) exclusive_roles = list(JOB_AI) required_enemies = 4 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 4f8e78be96477..5061626e1c37d 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -18,6 +18,8 @@ JOB_RESEARCH_DIRECTOR, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) base_antags = 3 maximum_antags = 5 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 31476e5ac696a..8b4393bfd13f8 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -17,6 +17,8 @@ JOB_RESEARCH_DIRECTOR, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) base_antags = 2 enemy_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 10d315a2669c6..879ac672ec199 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -13,6 +13,8 @@ JOB_PRISONER, JOB_SECURITY_OFFICER, JOB_WARDEN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) restricted_roles = list( JOB_AI, diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index b9af47aa8202b..c36a654fad1e0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -18,6 +18,8 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_CHAPLAIN, + JOB_BLUESHIELD, + JOB_NANOTRASEN_REPRESENTATIVE, ) required_enemies = 5 roundstart = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index 643634158f577..50f9bf7d7aa00 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -32,7 +32,9 @@ /datum/round_event/antagonist/solo/ghost/alien_infestation/setup() announce_when = rand(announce_when, announce_when + 50) var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount(forced) + antag_count = cast_control.get_antag_count_to_spawn(forced) + if(!antag_count) + return if(prob(50)) antag_count++ diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index bd556d07f4952..7886458aeccdb 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -28,7 +28,7 @@ return var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_amount(forced) + antag_count = cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index b497fa41be7f4..cb905d70a4cf5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -215,6 +215,7 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/fire(resumed = FALSE) if(SSticker.round_start_time && (world.time - SSticker.round_start_time) >= ROUNDSTART_VALID_TIMEFRAME) can_run_roundstart = FALSE + roundstart_event_view = FALSE ///Handle scheduled events for(var/datum/scheduled_event/sch_event in scheduled_events) @@ -611,7 +612,6 @@ SUBSYSTEM_DEF(gamemode) SSstation.generate_station_goals(INFINITY) handle_post_setup_roundstart_events() handle_post_setup_points() - roundstart_event_view = FALSE return TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 02995c84d881d..16c3d1db9d8d9 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -101,6 +101,7 @@ if(SSgamemode.can_run_roundstart && track == EVENT_TRACK_ROLESET) SSgamemode.round_start_handle() SSgamemode.can_run_roundstart = FALSE + SSgamemode.roundstart_event_view = FALSE if(points >= mode.point_thresholds[track]) if(prob(SSgamemode.empty_event_chance) && track == EVENT_TRACK_ROLESET) From b5671ca788711e7f78dc9b991e7f667089f04d91 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 13 Jan 2025 00:54:53 +0300 Subject: [PATCH 104/135] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=BE=D1=82=D1=87=D0=B5=D1=82=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/controllers/subsystem/ticker.dm | 3 +- config/game_options.txt | 2 +- .../storyteller/code/dynamic_report.dm | 2 - .../storyteller/code/gamemode.dm | 51 ++++++++++++++++--- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 2a83f90b0bf8f..cf6ec92d25442 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -306,7 +306,8 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE - //SSdynamic.post_setup() // BANDASTATION EDIT STORYTELLER - отключение пост-сетапа динамика + //SSdynamic.post_setup() // BANDASTATION EDIT - STORYTELLER + SSgamemode.post_setup() // BANDASTATION EDIT - STORYTELLER GLOB.start_state = new /datum/station_state() GLOB.start_state.count() diff --git a/config/game_options.txt b/config/game_options.txt index 689c0328a2ee4..6cd05e95a6bd8 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -85,7 +85,7 @@ STATION_GOAL_BUDGET 1 ## GAME MODES ### ## Uncomment to not send a roundstart intercept report. Gamemodes may override this. -NO_INTERCEPT_REPORT +## NO_INTERCEPT_REPORT ## Percent weight reductions for three of the most recent modes diff --git a/modular_bandastation/storyteller/code/dynamic_report.dm b/modular_bandastation/storyteller/code/dynamic_report.dm index a37394a9d8c1b..a832d7e14ae03 100644 --- a/modular_bandastation/storyteller/code/dynamic_report.dm +++ b/modular_bandastation/storyteller/code/dynamic_report.dm @@ -1,8 +1,6 @@ /// Generate the advisory level depending on the shown threat level. /datum/controller/subsystem/dynamic/generate_advisory_level() var/advisory_string = "" - //monkestation edit start: - //switch(round(shown_threat)) var/list/green_nebula_storytellers = list(/datum/storyteller/extended, /datum/storyteller/chill) //list for calmer storytellers for a greenshift var/list/midnight_sun_storytellers = list(/datum/storyteller/jester, /datum/storyteller/clown) var/list/orange_star_storytellers = list(/datum/storyteller/default, /datum/storyteller/fragile, /datum/storyteller/mystic) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index cb905d70a4cf5..0d18e9081c9a2 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -582,7 +582,9 @@ SUBSYSTEM_DEF(gamemode) /datum/controller/subsystem/gamemode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) report = !CONFIG_GET(flag/no_intercept_report) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(display_roundstart_logout_report)), ROUNDSTART_LOGOUT_REPORT_TIME) + + if (!CONFIG_GET(flag/no_intercept_report)) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(display_roundstart_logout_report)), ROUNDSTART_LOGOUT_REPORT_TIME) if(CONFIG_GET(flag/reopen_roundstart_suicide_roles)) var/delay = CONFIG_GET(number/reopen_roundstart_suicide_roles_delay) @@ -610,6 +612,8 @@ SUBSYSTEM_DEF(gamemode) query_round_game_mode.Execute() qdel(query_round_game_mode) SSstation.generate_station_goals(INFINITY) + if(report) + generate_station_goal_report() handle_post_setup_roundstart_events() handle_post_setup_points() return TRUE @@ -635,14 +639,45 @@ SUBSYSTEM_DEF(gamemode) * Returns a formatted string all station goals that are available to the station. */ /datum/controller/subsystem/gamemode/proc/generate_station_goal_report() - var/goals = SSstation.get_station_goals() - if(!length(goals)) + if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready + addtimer(CALLBACK(src, PROC_REF(generate_station_goal_report)), 10 SECONDS) return - . = "
Special Orders for [station_name()]:
" - for(var/datum/station_goal/station_goal as anything in goals) - station_goal.on_report() - . += station_goal.get_report() - return + + . = "Департамент разведки и оценки угроз Nanotrasen, Текущий сектор, Дата и время: [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR]:
" + //. += SSdynamic.generate_advisory_level() - генерация псевдо-орбит + + var/list/datum/station_goal/goals = SSstation.get_station_goals() + if(length(goals)) + var/list/texts = list("
Особые заказы для станции: [station_name()]:
") + for(var/datum/station_goal/station_goal as anything in goals) + station_goal.on_report() + texts += station_goal.get_report() + . += texts.Join("
") + + var/list/trait_list_strings = list() + for(var/datum/station_trait/station_trait as anything in SSstation.station_traits) + if(!station_trait.show_in_report) + continue + trait_list_strings += "[station_trait.get_report()]
" + if(trait_list_strings.len > 0) + . += "
Отчет отдела учета отклонений:
" + trait_list_strings.Join() + + if(length(GLOB.communications_controller.command_report_footnotes)) + var/footnote_pile = "" + + for(var/datum/command_footnote/footnote in GLOB.communications_controller.command_report_footnotes) + footnote_pile += "[footnote.message]
" + footnote_pile += "[footnote.signature]
" + footnote_pile += "
" + + . += "
Дополнительная информация:

" + footnote_pile + +#ifndef MAP_TEST + print_command_report(., "[command_name()] Status Summary", announce=FALSE) + priority_announce("Отчет был скопирован и распечатан на всех консолях связи.", "Отчет о безопасности", SSstation.announcer.get_rand_report_sound()) +#endif + + return . /datum/controller/subsystem/gamemode/proc/recalculate_ready_pop() ready_players = 0 From e3662668f5474d64bb22cd226e6a977968515856 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 13 Jan 2025 21:47:57 +0300 Subject: [PATCH 105/135] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B0=20=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=87=D0=B8=D1=82=D1=8C=20=D1=81=D0=BF=D0=B0=D0=B2?= =?UTF-8?q?=D0=BD=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2=20=D1=81?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=85=20=D0=BA=D0=B0=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event.dm | 11 ++++++++++- .../code/event_defines/ghostset/alien_infestation.dm | 3 +++ .../code/event_defines/ghostset/paradox_clone.dm | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 7daf3d0cd936e..3318e52ff087f 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -82,7 +82,8 @@ var/list/weighted_candidates = return_antag_weight(possible_candidates) - while(length(weighted_candidates) && length(candidates) < antag_count) //both of these pick_n_take from weighted_candidates so this should be fine + var/valid_to_spawn = TRUE + while(length(weighted_candidates) && length(candidates) < antag_count && valid_to_spawn) //both of these pick_n_take from weighted_candidates so this should be fine if(prompted_picking) var/picked_ckey = pick_n_take_weighted(weighted_candidates) var/client/picked_client = GLOB.directory[picked_ckey] @@ -111,7 +112,9 @@ log_storyteller("Picked antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") candidates |= picked_mob + var/list/picked_mobs = list() + var/spawned_count = 0 for(var/i in 1 to antag_count) if(!length(candidates)) message_admins("A roleset event got fewer antags then its antag_count and may not function correctly.") @@ -127,6 +130,9 @@ candidate.mind.special_role = antag_flag candidate.mind.restricted_roles = restricted_roles picked_mobs += WEAKREF(candidate.client) + spawned_count++ + if(spawned_count++ > SSgamemode.get_antag_cap(forced)) + antag_count-- setup = TRUE control.generate_image(picked_mobs) @@ -216,4 +222,7 @@ new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind selected_count++ + if(selected_count++ > SSgamemode.get_antag_cap(forced)) + selected_count-- + setup = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index 50f9bf7d7aa00..e78c355198715 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -90,6 +90,9 @@ new_xeno.move_into_vent(vent) selected_count++ + if(selected_count++ > SSgamemode.get_antag_cap(forced)) + selected_count-- + message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.") new_xeno.log_message("was spawned as an alien by an event.", LOG_GAME) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index 7886458aeccdb..7b1ca904c7a59 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -69,6 +69,10 @@ new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind selected_count++ + + if(selected_count++ > SSgamemode.get_antag_cap(forced)) + selected_count-- + setup = TRUE From c4712e37bc4030cdcc43e25888c209a79806e36d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 15 Jan 2025 08:59:59 +0300 Subject: [PATCH 106/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=20=D0=B2=20=D0=A1=D0=A2=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D1=85=20=D0=BC=D0=BD=D0=BE=D0=B6=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 7 ------- .../storyteller/code/gamemode.dm | 20 +++---------------- .../code/storytellers/_storyteller.dm | 14 ++++++++++--- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 871e6401426b4..8a22279cfa7d8 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -31,13 +31,6 @@ MAJOR_POINT_GAIN_MULTIPLIER 1 ROLESET_POINT_GAIN_MULTIPLIER 1 OBJECTIVES_POINT_GAIN_MULTIPLIER 1 -## Multipliers for points to spend on roundstart events. -MUNDANE_ROUNDSTART_POINT_MULTIPLIER 1 -MODERATE_ROUNDSTART_POINT_MULTIPLIER 1 -MAJOR_ROUNDSTART_POINT_MULTIPLIER 1 -ROLESET_ROUNDSTART_POINT_MULTIPLIER 1 -OBJECTIVES_ROUNDSTART_POINT_MULTIPLIER 1 - ## Minimum population caps for event tracks to run their events. MUNDANE_MIN_POP 0 MODERATE_MIN_POP 0 diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 0d18e9081c9a2..9d7d26d28d597 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -66,14 +66,6 @@ SUBSYSTEM_DEF(gamemode) EVENT_TRACK_ROLESET = 1, EVENT_TRACK_OBJECTIVES = 1 ) - /// Configurable multipliers for roundstart points. - var/list/roundstart_point_multipliers = list( - EVENT_TRACK_MUNDANE = 1, - EVENT_TRACK_MODERATE = 1, - EVENT_TRACK_MAJOR = 1, - EVENT_TRACK_ROLESET = 1, - EVENT_TRACK_OBJECTIVES = 1 - ) /// Whether we allow pop scaling. This is configured by config, or the storyteller UI var/allow_pop_scaling = TRUE @@ -385,7 +377,7 @@ SUBSYSTEM_DEF(gamemode) base_amt = ROUNDSTART_OBJECTIVES_BASE gain_amt = ROUNDSTART_OBJECTIVES_GAIN var/calc_value = base_amt + (gain_amt * ready_players) - calc_value *= roundstart_point_multipliers[track] + calc_value *= current_storyteller.roundstart_point_multipliers[track] calc_value *= current_storyteller.starting_point_multipliers[track] calc_value *= (rand(100 - current_storyteller.roundstart_points_variance,100 + current_storyteller.roundstart_points_variance)/100) event_track_points[track] = round(calc_value) @@ -947,12 +939,6 @@ SUBSYSTEM_DEF(gamemode) point_gain_multipliers[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_gain_multiplier) point_gain_multipliers[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_gain_multiplier) - roundstart_point_multipliers[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_roundstart_point_multiplier) - roundstart_point_multipliers[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_roundstart_point_multiplier) - min_pop_thresholds[EVENT_TRACK_MUNDANE] = CONFIG_GET(number/mundane_min_pop) min_pop_thresholds[EVENT_TRACK_MODERATE] = CONFIG_GET(number/moderate_min_pop) min_pop_thresholds[EVENT_TRACK_MAJOR] = CONFIG_GET(number/major_min_pop) @@ -1097,7 +1083,7 @@ SUBSYSTEM_DEF(gamemode) dat += "Roundstart Points Multipliers:" dat += "
This affects points generated for roundstart events and antagonists." for(var/track in event_tracks) - dat += "
[track]: [roundstart_point_multipliers[track]]" + dat += "
[track]: [current_storyteller.roundstart_point_multipliers[track]]" dat += "
" dat += "Minimum Population for Tracks:" @@ -1329,7 +1315,7 @@ SUBSYSTEM_DEF(gamemode) if(isnull(new_value) || new_value < 0) return message_admins("[key_name_admin(usr)] set roundstart pts multiplier for [track] track to [new_value].") - roundstart_point_multipliers[track] = new_value + current_storyteller.roundstart_point_multipliers[track] = new_value if("min_pop") var/new_value = input(usr, "New value:", "Set new value") as num|null if(isnull(new_value) || new_value < 0) diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 16c3d1db9d8d9..95a71a91d1ad5 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -25,6 +25,14 @@ EVENT_TRACK_ROLESET = 1, EVENT_TRACK_OBJECTIVES = 1 ) + /// Configurable multipliers for roundstart points. + var/list/roundstart_point_multipliers = list( + EVENT_TRACK_MUNDANE = 1, + EVENT_TRACK_MODERATE = 1, + EVENT_TRACK_MAJOR = 1, + EVENT_TRACK_ROLESET = 1, + EVENT_TRACK_OBJECTIVES = 1 + ) /// Multipliers of weight to apply for each tag of an event. var/list/tag_multipliers @@ -84,11 +92,11 @@ /// Add points to all tracks while respecting the multipliers. /datum/storyteller/proc/add_points(seconds_per_tick) var/datum/controller/subsystem/gamemode/mode = SSgamemode - var/base_point = EVENT_POINT_GAINED_PER_SECOND * seconds_per_tick * mode.event_frequency_multiplier + var/base_point = EVENT_POINT_GAINED_PER_SECOND * seconds_per_tick * mode.event_frequency_multiplier //w = 0.08*y*1 = 0.4 => y = 5 for(var/track in mode.event_track_points) - var/point_gain = base_point * point_gains_multipliers[track] * mode.point_gain_multipliers[track] * point_gain_base_mult + var/point_gain = base_point * point_gains_multipliers[track] * mode.point_gain_multipliers[track] * point_gain_base_mult // p = w*1*1*10=4 => w = 0.4 if(mode.allow_pop_scaling) - point_gain *= mode.current_pop_scale_multipliers[track] + point_gain *= mode.current_pop_scale_multipliers[track] //p*1 = 4 mode.event_track_points[track] += point_gain mode.last_point_gains[track] = point_gain From 2c4ac8d8b445afaa6362304d5dbac94fa6e70df2 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 16 Jan 2025 00:17:25 +0300 Subject: [PATCH 107/135] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=B2=20=D0=A1=D0=A2=20=D0=B8?= =?UTF-8?q?=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D1=82=D1=8C=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D0=B8=D1=8F,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=BC?= =?UTF-8?q?=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D1=83=D0=BA=D0=B0?= =?UTF-8?q?=D0=B7=D1=8B=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BA=D0=BE=D0=BB=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=BE=20=D0=B0=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D0=BF=D1=80=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D1=81=D0=B5,=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BE=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=B7=D0=B0=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D1=88=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B9=20=D0=B2=20=D0=BC=D0=B8=D0=B4-=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/_event.dm | 2 + .../code/event_defines/_round_event.dm | 4 +- .../event_defines/_round_event_control.dm | 44 ++++++---- .../ghostset/alien_infestation.dm | 2 +- .../event_defines/ghostset/paradox_clone.dm | 2 +- .../storyteller/code/gamemode.dm | 6 +- .../code/storytellers/_storyteller.dm | 83 ++++++++++--------- .../code/storytellers/storyteller_prime.dm | 10 +++ 8 files changed, 97 insertions(+), 56 deletions(-) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 793c5bf0f1507..5c94656dfc4e0 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -115,6 +115,8 @@ return FALSE if(head_required_power > SSgamemode.current_head_power) return FALSE + if(type in SSgamemode.current_storyteller.exclude_events) + return FALSE // BANDASTATION EDIT END - STORYTELLER if (dynamic_should_hijack && SSdynamic.random_event_hijacked != HIJACKED_NOTHING) return FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 3318e52ff087f..6c2804ee43ca6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -64,7 +64,7 @@ /datum/round_event/antagonist/solo/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_count_to_spawn(forced) + antag_count = forced && cast_control.forced_antags_count > 0 ? cast_control.forced_antags_count : cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return @@ -179,7 +179,7 @@ /datum/round_event/antagonist/solo/ghost/setup() var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_count_to_spawn(forced) + antag_count = forced && cast_control.forced_antags_count > 0 ? cast_control.forced_antags_count : cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index f50e4df29afdb..8bd68af9f10c8 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -104,6 +104,10 @@ if(string) string += "," string += "Hijack mission" + if (type in SSgamemode.current_storyteller.exclude_events) + if(string) + string += "," + string += "Disabled by choosen storyteller" return string /datum/round_event_control/antagonist/return_failure_string(players_amt) @@ -118,6 +122,19 @@ . += "No Required" return . +/datum/round_event_control/antagonist + checks_antag_cap = TRUE + track = EVENT_TRACK_ROLESET + ///list of required roles, needed for this to form + var/list/exclusive_roles + /// Protected roles from the antag roll. People will not get those roles if a config is enabled + var/list/protected_roles + /// Restricted roles from the antag roll + var/list/restricted_roles + var/event_icon_state + //The number of forced antags to spawn with the event if it forced + var/forced_antags_count = 0 + /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() @@ -177,17 +194,6 @@ if(!.) return -/datum/round_event_control/antagonist - checks_antag_cap = TRUE - track = EVENT_TRACK_ROLESET - ///list of required roles, needed for this to form - var/list/exclusive_roles - /// Protected roles from the antag roll. People will not get those roles if a config is enabled - var/list/protected_roles - /// Restricted roles from the antag roll - var/list/restricted_roles - var/event_icon_state - /datum/round_event_control/antagonist/proc/check_required() if(!length(exclusive_roles)) return TRUE @@ -340,9 +346,19 @@ for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) if(admin_setup_datum.prompt_admins() == ADMIN_CANCEL_EVENT) return - message_admins("[key_name_admin(usr)] forced scheduled event [src.name].") - log_admin_private("[key_name(usr)] forced scheduled event [src.name].") - SSgamemode.forced_next_events[src.track] += src + if(ispath(type, /datum/round_event_control/antagonist)) + var/new_value = input(usr, "How many players affected:", "Set value") as num|null + if(isnull(new_value) || new_value < 1) + return + message_admins("[key_name_admin(usr)] forced scheduled event [src.name] with count [new_value].") + log_admin_private("[key_name(usr)] forced scheduled event [src.name] with count [new_value].") + var/datum/round_event_control/antagonist/forced_antag_event = src + forced_antag_event.forced_antags_count = new_value + SSgamemode.forced_next_events[forced_antag_event.track] += forced_antag_event + else + message_admins("[key_name_admin(usr)] forced scheduled event [src.name].") + log_admin_private("[key_name(usr)] forced scheduled event [src.name].") + SSgamemode.forced_next_events[src.track] += src if("fire") if(length(src.admin_setup)) for(var/datum/event_admin_setup/admin_setup_datum in src.admin_setup) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index e78c355198715..d8200c1b4a804 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -32,7 +32,7 @@ /datum/round_event/antagonist/solo/ghost/alien_infestation/setup() announce_when = rand(announce_when, announce_when + 50) var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_count_to_spawn(forced) + antag_count = forced && cast_control.forced_antags_count > 0 ? cast_control.forced_antags_count : cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index 7b1ca904c7a59..d8c7649b35f63 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -28,7 +28,7 @@ return var/datum/round_event_control/antagonist/solo/cast_control = control - antag_count = cast_control.get_antag_count_to_spawn(forced) + antag_count = forced && cast_control.forced_antags_count > 0 ? cast_control.forced_antags_count : cast_control.get_antag_count_to_spawn(forced) if(!antag_count) return diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 9d7d26d28d597..df05dba07f475 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -1126,7 +1126,11 @@ SUBSYSTEM_DEF(gamemode) var/list/forced_events = forced_next_events[track] var/forced = "" for(var/datum/round_event_control/forced_event in forced_events) - forced = forced + "[forced_event.name] X
" + var/event_data = "[forced_event.name] X
" + if(ispath(forced_event.type, /datum/round_event_control/antagonist)) + var/datum/round_event_control/antagonist/forced_antag_event = forced_event + event_data = "[forced_antag_event.name][forced_antag_event?.forced_antags_count > 0 ? "([forced_antag_event?.forced_antags_count])": ""] X
" + forced = forced + event_data dat += "[forced]" //Forced dat += "Set Pts. Next Event" //Actions dat += "" diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 95a71a91d1ad5..5ec1c2c19944a 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -78,6 +78,8 @@ var/sec_antag_modifier = STORYTELLER_SEC_ANTAG_MODIFIER ///Множитель цен антагов var/storyteller_basic_modifier = STORYTELLER_BASIC_MODIFIER + ///Список событий на исключение + var/list/exclude_events = list() /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff @@ -128,47 +130,54 @@ /// Find and buy a valid event from a track. /datum/storyteller/proc/find_and_buy_event_from_track(track) . = FALSE + var/are_forced = FALSE var/datum/controller/subsystem/gamemode/mode = SSgamemode var/datum/round_event_control/picked_event - - mode.update_crew_infos() - var/pop_required = mode.min_pop_thresholds[track] - if(mode.active_players < pop_required) - message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [mode.active_players])") - mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - calculate_weights(track) - var/list/valid_events = list() - // Determine which events are valid to pick - for(var/datum/round_event_control/event as anything in mode.event_pools[track]) - var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) - if(event.can_spawn_event(players_amt)) - if(QDELETED(event)) - message_admins("[event.name] was deleted!") - continue - valid_events[event] = round(event.calculated_weight * 10) //multiply weight by 10 to get first decimal value - ///If we didn't get any events, remove the points inform admins and dont do anything - if(!length(valid_events)) - message_admins("Storyteller failed to pick an event for track of [track].") - mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER - return - picked_event = pick_weight(valid_events) - if(!picked_event) - if(length(valid_events)) - var/added_string = "" - for(var/datum/round_event_control/item as anything in valid_events) - added_string += "[item.name]:[valid_events[item]]; " - stack_trace("WARNING: Storyteller picked a null from event pool, defaulting to option 1, look at weights:[added_string]") - shuffle_inplace(valid_events) - picked_event = valid_events[1] - else - message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") - stack_trace("WARNING: Storyteller picked a null from event pool.") - SSgamemode.event_track_points[track] = 0 + if(length(SSgamemode.forced_next_events[track])) + picked_event = pick(SSgamemode.forced_next_events[track]) + SSgamemode.forced_next_events[track] -= picked_event + are_forced = TRUE + else + mode.update_crew_infos() + var/pop_required = mode.min_pop_thresholds[track] + if(mode.active_players < pop_required) + message_admins("Storyteller failed to pick an event for track of [track] due to insufficient population. (required: [pop_required] active pop for [track]. Current: [mode.active_players])") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER return - - if(picked_event?.can_spawn_event(get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)) && track) + calculate_weights(track) + var/list/valid_events = list() + // Determine which events are valid to pick + for(var/datum/round_event_control/event as anything in mode.event_pools[track]) + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + if(event.can_spawn_event(players_amt)) + if(QDELETED(event)) + message_admins("[event.name] was deleted!") + continue + valid_events[event] = round(event.calculated_weight * 10) //multiply weight by 10 to get first decimal value + ///If we didn't get any events, remove the points inform admins and dont do anything + if(!length(valid_events)) + message_admins("Storyteller failed to pick an event for track of [track].") + mode.event_track_points[track] *= TRACK_FAIL_POINT_PENALTY_MULTIPLIER + return + picked_event = pick_weight(valid_events) + if(!picked_event) + if(length(valid_events)) + var/added_string = "" + for(var/datum/round_event_control/item as anything in valid_events) + added_string += "[item.name]:[valid_events[item]]; " + stack_trace("WARNING: Storyteller picked a null from event pool, defaulting to option 1, look at weights:[added_string]") + shuffle_inplace(valid_events) + picked_event = valid_events[1] + else + message_admins("WARNING: Storyteller picked a null from event pool. Aborting event roll.") + stack_trace("WARNING: Storyteller picked a null from event pool.") + SSgamemode.event_track_points[track] = 0 + return + + if(picked_event?.can_spawn_event(get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)) && track && !are_forced) + buy_event(picked_event, track, are_forced) + else if(are_forced) buy_event(picked_event, track, are_forced) . = TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index 9ebb7ec132e74..d9152d3cd898c 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -8,3 +8,13 @@ always_votable = TRUE welcome_text = "I am not your Andy!" weight = 6 + exclude_events = list( + /datum/round_event_control/stray_meteor, + /datum/round_event_control/meteor_wave, + /datum/round_event_control/earthquake, + /datum/round_event_control/stray_cargo, + /datum/round_event_control/meteor_wave/threatening, + /datum/round_event_control/meteor_wave/catastrophic, + /datum/round_event_control/meteor_wave/meaty, + /datum/round_event_control/stray_cargo/syndicate, + ) From 444b2310309a2a80be13588b22016330cc587760 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 17 Jan 2025 00:09:29 +0300 Subject: [PATCH 108/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B8=D0=B7=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/bandastation/bandastation_config.txt | 10 +++---- .../code/_defines/storyteller_config.dm | 30 ++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt index 8a22279cfa7d8..0b520b650917a 100644 --- a/config/bandastation/bandastation_config.txt +++ b/config/bandastation/bandastation_config.txt @@ -25,11 +25,11 @@ ROUNDSTART_RACES vulpkanin ## Gamemode configurations ## Multipliers for points gained over time for event tracks. -MUNDANE_POINT_GAIN_MULTIPLIER 1 -MODERATE_POINT_GAIN_MULTIPLIER 1 -MAJOR_POINT_GAIN_MULTIPLIER 1 -ROLESET_POINT_GAIN_MULTIPLIER 1 -OBJECTIVES_POINT_GAIN_MULTIPLIER 1 +MUNDANE_POINT_GAIN_MULTIPLIER 0.5 +MODERATE_POINT_GAIN_MULTIPLIER 0.5 +MAJOR_POINT_GAIN_MULTIPLIER 0.5 +ROLESET_POINT_GAIN_MULTIPLIER 0.5 +OBJECTIVES_POINT_GAIN_MULTIPLIER 0.5 ## Minimum population caps for event tracks to run their events. MUNDANE_MIN_POP 0 diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm index 121a512099d13..10629b32db087 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_config.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_config.dm @@ -1,44 +1,54 @@ ///Gamemode related configs below // Point Gain Multipliers /datum/config_entry/number/mundane_point_gain_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/moderate_point_gain_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/major_point_gain_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/roleset_point_gain_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/objectives_point_gain_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 // Roundstart points Multipliers /datum/config_entry/number/mundane_roundstart_point_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/moderate_roundstart_point_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/major_roundstart_point_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/roleset_roundstart_point_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 /datum/config_entry/number/objectives_roundstart_point_multiplier - config_entry_value = 1 + integer = FALSE + default = 1 min_val = 0 // Minimum population From 70832cdc8a010cc90055471cca759c3f9021281b Mon Sep 17 00:00:00 2001 From: Gaxeer <44334376+Gaxeer@users.noreply.github.com> Date: Sun, 19 Jan 2025 20:35:56 +0200 Subject: [PATCH 109/135] Update modular_bandastation/modular_bandastation.dme --- modular_bandastation/modular_bandastation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme index 8c8e676931005..a7956b3c1662c 100644 --- a/modular_bandastation/modular_bandastation.dme +++ b/modular_bandastation/modular_bandastation.dme @@ -53,6 +53,7 @@ #include "whitelist220/_whitelist220.dme" #include "world_topics/_world_topics.dme" #include "storyteller/_storyteller.dme" +#include "game/_game.dme" // --- MODULES END --- // // --- PRIME --- // From f696149243e8a93fd04650e46ce419408e549045 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 19 Jan 2025 21:59:29 +0300 Subject: [PATCH 110/135] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=BF=D0=BE=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B4=D0=BD=D0=B5=D0=BC=D1=83=20=D1=80=D0=B0=D1=83=D0=BD?= =?UTF-8?q?=D0=B4=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/events/creep_awakening.dm | 4 +++- .../code/event_defines/crewset/blood_brothers.dm | 6 +----- .../code/event_defines/crewset/changeling.dm | 1 + .../code/event_defines/crewset/cult.dm | 1 + .../code/event_defines/crewset/heretic.dm | 1 + .../code/event_defines/crewset/nuke_ops.dm | 1 + .../code/event_defines/crewset/obsessed.dm | 16 ++++++++++++++++ .../code/event_defines/crewset/revolution.dm | 1 + .../code/event_defines/crewset/traitors.dm | 1 + .../code/event_defines/crewset/wizard.dm | 1 + 10 files changed, 27 insertions(+), 6 deletions(-) diff --git a/code/modules/events/creep_awakening.dm b/code/modules/events/creep_awakening.dm index 0dfa87ddfa333..e11bf773a82bb 100644 --- a/code/modules/events/creep_awakening.dm +++ b/code/modules/events/creep_awakening.dm @@ -1,7 +1,7 @@ /datum/round_event_control/obsessed name = "Obsession Awakening" typepath = /datum/round_event/obsessed - max_occurrences = 1 + max_occurrences = 2 //BANDASTATION EDIT - STORYTELLER min_players = 20 category = EVENT_CATEGORY_HEALTH description = "A random crewmember becomes obsessed with another." @@ -17,6 +17,8 @@ continue if(!(H.mind.assigned_role.job_flags & JOB_CREW_MEMBER)) //only station jobs sans nonhuman roles, prevents ashwalkers trying to stalk with crewmembers they never met continue + if((H.mind.assigned_role in protected_roles)) //BANDASTATION EDIT - STORYTELLER + continue if(H.mind.has_antag_datum(/datum/antagonist/obsessed)) continue if(!H.get_organ_by_type(/obj/item/organ/brain)) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index d1339b81a3b16..ec459a5644d7c 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -15,6 +15,7 @@ JOB_NANOTRASEN_REPRESENTATIVE, JOB_PRISONER, JOB_SECURITY_OFFICER, + JOB_MAGISTRATE, JOB_WARDEN, ) restricted_roles = list( @@ -43,11 +44,6 @@ /datum/round_event_control/antagonist/solo/heretic/roundstart = 2, ) -/datum/round_event_control/antagonist/solo/brother/midround - name = "Sleeper Agents (Blood Brothers)" - prompted_picking = FALSE - required_enemies = 2 - /datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) var/datum/team/brother_team/team = new team.add_member(antag_mind) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 80587d056dbe1..0b7480b3bd964 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -14,6 +14,7 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) restricted_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index 8bc4c4e3eefb5..c6eec1172269e 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -16,6 +16,7 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) maximum_antags = 3 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 11bcdc65944d3..72453443b2543 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -15,6 +15,7 @@ JOB_HEAD_OF_SECURITY, JOB_PRISONER, JOB_SECURITY_OFFICER, + JOB_MAGISTRATE, JOB_WARDEN, ) restricted_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 5061626e1c37d..830bb01f5e0db 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -19,6 +19,7 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) base_antags = 3 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index 0feb9ad3e1b39..f3bc80015e368 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -16,3 +16,19 @@ prompted_picking = FALSE maximum_antags = 4 +/datum/round_event/obsessed + var/protected_roles = list( + JOB_CAPTAIN, + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_PRISONER, + JOB_SECURITY_OFFICER, + JOB_WARDEN, + JOB_BLUESHIELD, + JOB_MAGISTRATE, + JOB_NANOTRASEN_REPRESENTATIVE, + ) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index 8b4393bfd13f8..af46a2f81eaea 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -18,6 +18,7 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) base_antags = 2 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 879ac672ec199..5c3adc1e4bf7b 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -14,6 +14,7 @@ JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) restricted_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index c36a654fad1e0..55bcd458c9b78 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -19,6 +19,7 @@ JOB_WARDEN, JOB_CHAPLAIN, JOB_BLUESHIELD, + JOB_MAGISTRATE, JOB_NANOTRASEN_REPRESENTATIVE, ) required_enemies = 5 From 0fc079948d0172d81204d16177cfb791e524aa12 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 02:10:33 +0300 Subject: [PATCH 111/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/mob/living/brain/brain_item.dm | 2 ++ .../reagents/chemistry/reagents/medicine_reagents.dm | 10 ++++++++++ code/modules/surgery/brain_surgery.dm | 7 ++++++- config/game_options.txt | 2 +- modular_bandastation/medical/code/organs/_brain.dm | 7 +++++++ 5 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 modular_bandastation/medical/code/organs/_brain.dm diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 7086298c19f3b..9d67953f780f0 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -44,6 +44,8 @@ var/can_smoothen_out = TRUE /// We got smooth from being washed var/smooth_brain = FALSE + /// BANDASTATION EDIT - PERMADEATH + var/perma_death = FALSE /obj/item/organ/brain/Initialize(mapload) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 180d9dbb7e8d3..33846559dfaf1 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1002,10 +1002,20 @@ if(exposed_mob.stat != DEAD || !(exposed_mob.mob_biotypes & MOB_ORGANIC)) return ..() + // BANDASTATION EDIT START - PERMADEATH + if(ishuman(exposed_mob)) + var/obj/item/organ/brain/brain = exposed_mob.get_organ_slot(ORGAN_SLOT_BRAIN) + if(brain) + if(!(brain.organ_flags & ORGAN_FAILING) && !brain.perma_death) + exposed_mob.visible_message(span_warning("[exposed_mob] have a criticaly damaged brain, and not react...")) + return + // BANDASTATION EDIT END - PERMADEATH + if(HAS_TRAIT(exposed_mob, TRAIT_SUICIDED)) //they are never coming back exposed_mob.visible_message(span_warning("[exposed_mob]'s body does not react...")) return + if(iscarbon(exposed_mob) && !(methods & (INGEST|INHALE))) //simplemobs can still be splashed return ..() diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index c3a9baafde10f..60c14e51bad8f 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -46,7 +46,12 @@ success_sound = 'sound/items/taperecorder/taperecorder_close.ogg' /datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target) - return target.get_organ_slot(ORGAN_SLOT_BRAIN) && ..() + // BANDASTATION EDIT START - PERMADEATH + var/obj/item/organ/brain/brain = target.get_organ_slot(ORGAN_SLOT_BRAIN) + if(brain) + var/not_dead = !(brain.organ_flags & ORGAN_FAILING) && !brain.perma_death + return brain && not_dead && ..() + // BANDASTATION EDIT END - PERMADEATH /datum/surgery_step/fix_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( diff --git a/config/game_options.txt b/config/game_options.txt index 6cd05e95a6bd8..fab491f4c9043 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -9,7 +9,7 @@ DAMAGE_MULTIPLIER 1 REVIVAL_POD_PLANTS ## amount of time (in hundredths of seconds) for which a brain retains the "spark of life" after the person's death (set to -1 for infinite) -REVIVAL_BRAIN_LIFE -1 +REVIVAL_BRAIN_LIFE 100 ## OOC DURING ROUND ### ## Comment this out if you want OOC to be automatically disabled during the round, it will be enabled during the lobby and after the round end results. diff --git a/modular_bandastation/medical/code/organs/_brain.dm b/modular_bandastation/medical/code/organs/_brain.dm new file mode 100644 index 0000000000000..439c5f30c361f --- /dev/null +++ b/modular_bandastation/medical/code/organs/_brain.dm @@ -0,0 +1,7 @@ +/obj/item/organ/brain/Initialize(mapload) + . = ..() + var/config_value = CONFIG_GET(number/revival_brain_life) + if(config_value > 0) + perma_death = TRUE + if(perma_death) + decay_factor = STANDARD_ORGAN_DECAY * config_value From 32a49de927a3639ca77a2ab53af6a33027d8d59d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 02:17:02 +0300 Subject: [PATCH 112/135] =?UTF-8?q?=D0=A3=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=20=D1=84=D0=B0=D0=BA=D0=B0=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/mob/living/brain/brain_item.dm | 2 -- .../reagents/chemistry/reagents/medicine_reagents.dm | 9 --------- code/modules/surgery/brain_surgery.dm | 7 +------ config/game_options.txt | 2 +- modular_bandastation/medical/code/organs/_brain.dm | 7 ------- 5 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 modular_bandastation/medical/code/organs/_brain.dm diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 9d67953f780f0..7086298c19f3b 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -44,8 +44,6 @@ var/can_smoothen_out = TRUE /// We got smooth from being washed var/smooth_brain = FALSE - /// BANDASTATION EDIT - PERMADEATH - var/perma_death = FALSE /obj/item/organ/brain/Initialize(mapload) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 33846559dfaf1..51913172f1095 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1002,15 +1002,6 @@ if(exposed_mob.stat != DEAD || !(exposed_mob.mob_biotypes & MOB_ORGANIC)) return ..() - // BANDASTATION EDIT START - PERMADEATH - if(ishuman(exposed_mob)) - var/obj/item/organ/brain/brain = exposed_mob.get_organ_slot(ORGAN_SLOT_BRAIN) - if(brain) - if(!(brain.organ_flags & ORGAN_FAILING) && !brain.perma_death) - exposed_mob.visible_message(span_warning("[exposed_mob] have a criticaly damaged brain, and not react...")) - return - // BANDASTATION EDIT END - PERMADEATH - if(HAS_TRAIT(exposed_mob, TRAIT_SUICIDED)) //they are never coming back exposed_mob.visible_message(span_warning("[exposed_mob]'s body does not react...")) return diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index 60c14e51bad8f..3736028db06b2 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -46,12 +46,7 @@ success_sound = 'sound/items/taperecorder/taperecorder_close.ogg' /datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target) - // BANDASTATION EDIT START - PERMADEATH - var/obj/item/organ/brain/brain = target.get_organ_slot(ORGAN_SLOT_BRAIN) - if(brain) - var/not_dead = !(brain.organ_flags & ORGAN_FAILING) && !brain.perma_death - return brain && not_dead && ..() - // BANDASTATION EDIT END - PERMADEATH + return target.get_organ_slot(ORGAN_SLOT_BRAIN) && not_dead && ..() /datum/surgery_step/fix_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( diff --git a/config/game_options.txt b/config/game_options.txt index fab491f4c9043..6cd05e95a6bd8 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -9,7 +9,7 @@ DAMAGE_MULTIPLIER 1 REVIVAL_POD_PLANTS ## amount of time (in hundredths of seconds) for which a brain retains the "spark of life" after the person's death (set to -1 for infinite) -REVIVAL_BRAIN_LIFE 100 +REVIVAL_BRAIN_LIFE -1 ## OOC DURING ROUND ### ## Comment this out if you want OOC to be automatically disabled during the round, it will be enabled during the lobby and after the round end results. diff --git a/modular_bandastation/medical/code/organs/_brain.dm b/modular_bandastation/medical/code/organs/_brain.dm deleted file mode 100644 index 439c5f30c361f..0000000000000 --- a/modular_bandastation/medical/code/organs/_brain.dm +++ /dev/null @@ -1,7 +0,0 @@ -/obj/item/organ/brain/Initialize(mapload) - . = ..() - var/config_value = CONFIG_GET(number/revival_brain_life) - if(config_value > 0) - perma_death = TRUE - if(perma_death) - decay_factor = STANDARD_ORGAN_DECAY * config_value From 74ec8bdfee65aaf288b89fa0efabe4bdb8fd0bcd Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 02:19:33 +0300 Subject: [PATCH 113/135] =?UTF-8?q?=D0=9D=D0=B5=D0=B4=D0=BE=D1=83=D0=B1?= =?UTF-8?q?=D0=B8=D1=80=D0=B0=D0=BB=D0=B8=20=D1=84=D0=B0=D0=BA=D0=B0=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/surgery/brain_surgery.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index 3736028db06b2..c3a9baafde10f 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -46,7 +46,7 @@ success_sound = 'sound/items/taperecorder/taperecorder_close.ogg' /datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target) - return target.get_organ_slot(ORGAN_SLOT_BRAIN) && not_dead && ..() + return target.get_organ_slot(ORGAN_SLOT_BRAIN) && ..() /datum/surgery_step/fix_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( From 9f74866dc52cfe1ac62dd6673196bf5d759ecead Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 02:24:30 +0300 Subject: [PATCH 114/135] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D1=8C=D0=B1=D0=B0=D0=BC=20=D0=BF=D1=80=D0=B0=D0=B9=D0=BC?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/nuke_ops.dm | 1 + .../storyteller/code/storytellers/_storyteller.dm | 2 +- .../storyteller/code/storytellers/storyteller_prime.dm | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 830bb01f5e0db..c2f132c3c89ea 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -41,6 +41,7 @@ weight = 4 max_occurrences = 3 event_icon_state = "nukeops" + exclusive_roundstart_event = TRUE /datum/round_event/antagonist/solo/nuclear_operative excute_round_end_reports = TRUE diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 5ec1c2c19944a..c83b8c4319a3b 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -68,7 +68,7 @@ var/weight = 0 ///Количество игроков на сервере, чтобы сторителлер начинал расчеты максимального количества антагов var/min_antag_popcount = STORYTELLER_MIN_ANTAG_POPCOUNT - ///Количество игроков на сервере, которое требуется чтобы появился хотя бы один антаг (по умолчанию 30) + ///Количество игроков на сервере, которое требуется чтобы появился хотя бы один антаг (по умолчанию 20) var/antag_denominator = ANTAG_CAP_DENOMINATOR ///Количество антагов, которое СТ может добавить сверх расчетов var/antag_flat_cap = ANTAG_CAP_FLAT diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index d9152d3cd898c..c4e78d28b8391 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -18,3 +18,4 @@ /datum/round_event_control/meteor_wave/meaty, /datum/round_event_control/stray_cargo/syndicate, ) + antag_denominator = 10 From 24a2df51a497ce41854506941bef503c11667e3d Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 22:31:03 +0300 Subject: [PATCH 115/135] =?UTF-8?q?=D0=9A=D0=B0=D0=BF=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=20=D0=BD=D0=B5=20=D0=BC=D0=BE=D0=B6=D0=B5=D1=82=20=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D1=8C=20=D0=B5=D1=80=D0=B5=D1=82=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC,=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=84=D0=BE=D1=80=D1=81-=D0=B8=D0=B2=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event_control.dm | 2 +- .../storyteller/code/event_defines/crewset/heretic.dm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 8bd68af9f10c8..f22adec0aa6b6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -352,7 +352,7 @@ return message_admins("[key_name_admin(usr)] forced scheduled event [src.name] with count [new_value].") log_admin_private("[key_name(usr)] forced scheduled event [src.name] with count [new_value].") - var/datum/round_event_control/antagonist/forced_antag_event = src + var/datum/round_event_control/antagonist/forced_antag_event = new type() forced_antag_event.forced_antags_count = new_value SSgamemode.forced_next_events[forced_antag_event.track] += forced_antag_event else diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 72453443b2543..f3d553b61d7d3 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -17,6 +17,7 @@ JOB_SECURITY_OFFICER, JOB_MAGISTRATE, JOB_WARDEN, + JOB_CHAPLAIN, ) restricted_roles = list( JOB_AI, From 887b5d415f052986f718197f4683e673a634d262 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Tue, 21 Jan 2025 22:55:35 +0300 Subject: [PATCH 116/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D1=8C=20=D1=84=D0=BE=D1=80=D1=81=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=84=D0=BE=D1=80=D1=81=D0=B5=20=D1=82=D0=B0?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=BE=20=D0=B6=D0=B5=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event_control.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index f22adec0aa6b6..5f75ea63472db 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -353,6 +353,11 @@ message_admins("[key_name_admin(usr)] forced scheduled event [src.name] with count [new_value].") log_admin_private("[key_name(usr)] forced scheduled event [src.name] with count [new_value].") var/datum/round_event_control/antagonist/forced_antag_event = new type() + for(var/datum/round_event_control/antagonist/rec in SSgamemode.forced_next_events[forced_antag_event.track]) + if(istype(rec, type)) + forced_antag_event = src + SSgamemode.forced_next_events[forced_antag_event.track] -= rec + break forced_antag_event.forced_antags_count = new_value SSgamemode.forced_next_events[forced_antag_event.track] += forced_antag_event else From 5eb3e6cb396f7543f6cabf20dea7ae690b91f863 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 22 Jan 2025 00:56:32 +0300 Subject: [PATCH 117/135] =?UTF-8?q?=D0=9E=D1=82=D0=BA=D0=B0=D1=82=20=D1=84?= =?UTF-8?q?=D0=B8=D1=87=D0=B8=20=D1=81=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=84=D0=B0=D0=B5=D1=80=D0=BE=D0=B2=20=D0=BE?= =?UTF-8?q?=D0=B4=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=82=D0=B8=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/_round_event_control.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 5f75ea63472db..f22adec0aa6b6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -353,11 +353,6 @@ message_admins("[key_name_admin(usr)] forced scheduled event [src.name] with count [new_value].") log_admin_private("[key_name(usr)] forced scheduled event [src.name] with count [new_value].") var/datum/round_event_control/antagonist/forced_antag_event = new type() - for(var/datum/round_event_control/antagonist/rec in SSgamemode.forced_next_events[forced_antag_event.track]) - if(istype(rec, type)) - forced_antag_event = src - SSgamemode.forced_next_events[forced_antag_event.track] -= rec - break forced_antag_event.forced_antags_count = new_value SSgamemode.forced_next_events[forced_antag_event.track] += forced_antag_event else From 4bcaac971e857238511a2b4ee711e8d4545f74ba Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 24 Jan 2025 01:22:18 +0300 Subject: [PATCH 118/135] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20-=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=BE=D0=B2,=20=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B1=D0=B8=D1=80=D0=B0=D1=82=D1=8C=20=D0=BA=D0=BE=D0=BB?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=BE=20=D0=B0=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=D0=B3=D0=BE=D0=B2=20=D0=B2=20=D0=BC=D0=B8=D0=B4=D1=80?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/_round_event_control.dm | 12 +++++++++++- .../code/event_defines/crewset/blood_brothers.dm | 1 + .../code/event_defines/crewset/changeling.dm | 2 ++ .../code/event_defines/crewset/heretic.dm | 1 + .../code/event_defines/crewset/obsessed.dm | 1 + .../storyteller/code/event_defines/crewset/spies.dm | 1 + .../code/event_defines/crewset/traitors.dm | 2 ++ .../code/event_defines/mundane/override.dm | 1 + 8 files changed, 20 insertions(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index f22adec0aa6b6..43b87700af9a4 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -134,6 +134,7 @@ var/event_icon_state //The number of forced antags to spawn with the event if it forced var/forced_antags_count = 0 + var/can_change_count = FALSE /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() @@ -366,4 +367,13 @@ return message_admins("[key_name_admin(usr)] fired event [src.name].") log_admin_private("[key_name(usr)] fired event [src.name].") - run_event(random = FALSE, admin_forced = TRUE) + if(ispath(type, /datum/round_event_control/antagonist)) + var/datum/round_event_control/antagonist/forced_antag_event = src + if(forced_antag_event.can_change_count) + var/new_value = input(usr, "How many players affected:", "Set value") as num|null + if(isnull(new_value) || new_value < 1) + return + forced_antag_event.forced_antags_count = new_value + forced_antag_event.run_event(random = FALSE, admin_forced = TRUE) + else + run_event(random = FALSE, admin_forced = TRUE) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index ec459a5644d7c..f0aa8a6f9dd00 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -43,6 +43,7 @@ /datum/round_event_control/antagonist/solo/traitor/roundstart = 12, /datum/round_event_control/antagonist/solo/heretic/roundstart = 2, ) + maximum_antags = 1 /datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) var/datum/team/brother_team/team = new diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 0b7480b3bd964..489ea561148a2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -27,7 +27,9 @@ name = "Changelings" roundstart = TRUE earliest_start = 0 + maximum_antags = 1 /datum/round_event_control/antagonist/solo/changeling/midround name = "Genome Awakening (Changelings)" prompted_picking = FALSE + can_change_count = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index f3d553b61d7d3..5a36901ae1df3 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -42,3 +42,4 @@ name = "Midround Heretics" prompted_picking = FALSE required_enemies = 3 + can_change_count = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm index f3bc80015e368..8e0d6b520174f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/obsessed.dm @@ -15,6 +15,7 @@ name = "Compulsive Obsession" prompted_picking = FALSE maximum_antags = 4 + can_change_count = TRUE /datum/round_event/obsessed var/protected_roles = list( diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm index c66eaefaa3e1e..418d41e76c3e5 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/spies.dm @@ -12,3 +12,4 @@ /datum/round_event_control/antagonist/solo/spy/midround name = "Spies (Midround)" roundstart = FALSE + can_change_count = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 5c3adc1e4bf7b..dbf5801ebc5b1 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -28,9 +28,11 @@ antag_datum = /datum/antagonist/traitor roundstart = TRUE earliest_start = 0 SECONDS + maximum_antags = 1 /datum/round_event_control/antagonist/solo/traitor/midround name = "Sleeper Agents (Traitors)" antag_flag = ROLE_SLEEPER_AGENT antag_datum = /datum/antagonist/traitor/infiltrator/sleeper_agent prompted_picking = FALSE + can_change_count = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index 41903991d3fc2..02c58c315b2e1 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -57,6 +57,7 @@ track = EVENT_TRACK_MUNDANE tags = list(TAG_COMMUNAL, TAG_POSITIVE, TAG_MAGICAL) event_group = /datum/event_group/guests + weight = 0 /datum/round_event_control/shuttle_loan track = EVENT_TRACK_MUNDANE From 3b114f8a88615a36188c3083bed7c8bd4c038432 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 24 Jan 2025 01:42:10 +0300 Subject: [PATCH 119/135] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=AD=D0=BD=D0=B4=D0=B8-=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B9=D0=BC=20=D0=B4=D0=B8=D0=B2=D0=B8=D0=B7=D0=BE=D1=80?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/storytellers/storyteller_prime.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index c4e78d28b8391..e3cf04e0902ab 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -18,4 +18,4 @@ /datum/round_event_control/meteor_wave/meaty, /datum/round_event_control/stray_cargo/syndicate, ) - antag_denominator = 10 + antag_denominator = 12 From b4386730ef2596e8134ad813f4d8e98efa8dd4a0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 24 Jan 2025 23:58:48 +0300 Subject: [PATCH 120/135] =?UTF-8?q?=D0=92=D0=B2=D0=BE=D0=B4=20=D0=BC=D0=B0?= =?UTF-8?q?=D0=BA=D1=81=D0=B8=D0=BC=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=B0=20=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85=20?= =?UTF-8?q?=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=BD=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=BD=D0=B0=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/_round_event_control.dm | 15 ++++++++++----- .../code/event_defines/crewset/blood_brothers.dm | 1 + .../code/event_defines/crewset/changeling.dm | 1 + .../code/event_defines/crewset/heretic.dm | 1 + modular_bandastation/storyteller/code/gamemode.dm | 12 ++++++++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 43b87700af9a4..bb71bed3cb07c 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -234,6 +234,7 @@ var/base_antags = 1 /// How many maximum antags can we spawn var/maximum_antags = 3 + var/maximum_antags_per_round = 3 /// For this many players we'll add 1 up to the maximum antag amount var/denominator = 20 /// The antag flag to be used @@ -271,13 +272,17 @@ var/gamemode_antags_left = current_cap - SSgamemode.get_antag_count() var/maximum_to_spawn = min(gamemode_antags_left, maximum_antags) var/clamped_value = clamp(decided_count, 0, maximum_to_spawn) - + //Maximum antags per round left to spawn + //Получить уже количество антагов в раунде + var/typed_antags_in_round = SSgamemode.get_antag_count_by_type(antag_datum) + var/left_to_spawn = maximum_antags_per_round - typed_antags_in_round + var/final_value = clamp(clamped_value, 0, left_to_spawn) //double check - var/predicted_count = clamped_value + SSgamemode.get_antag_count() - while(predicted_count > current_cap && clamped_value > 0) - clamped_value-- + var/predicted_count = final_value + SSgamemode.get_antag_count() + while(predicted_count > current_cap && final_value > 0) + final_value-- - return clamped_value + return final_value /datum/round_event_control/antagonist/solo/proc/get_candidates() var/round_started = SSticker.HasRoundStarted() diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index f0aa8a6f9dd00..4b1dd4f5e85b6 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -32,6 +32,7 @@ required_enemies = 1 weight = 12 maximum_antags = 2 + maximum_antags_per_round = 2 denominator = 30 cost = 0.45 // so it doesn't eat up threat for a relatively low-threat antag diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 489ea561148a2..6f7d64d7ac503 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -22,6 +22,7 @@ JOB_CYBORG, ) min_players = 20 + maximum_antags_per_round = 3 /datum/round_event_control/antagonist/solo/changeling/roundstart name = "Changelings" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 5a36901ae1df3..fd3c3990d3842 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -32,6 +32,7 @@ ) weight = 4 min_players = 20 + maximum_antags_per_round = 3 /datum/round_event_control/antagonist/solo/heretic/roundstart name = "Heretics" diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index df05dba07f475..f617490142b1d 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -1461,6 +1461,18 @@ SUBSYSTEM_DEF(gamemode) listed.occurrences++ listed.occurrences++ +/datum/controller/subsystem/gamemode/proc/get_antag_count_by_type(type) + var/count = 0 + if(!type) + return count + + + for(var/datum/antagonist/antag_datum_element in GLOB.antagonists) + if(antag_datum_element.type == type) + count++ + + return count + /datum/controller/subsystem/gamemode/proc/create_roundend_score() var/list/parts = list() parts += "
[("Storyteller: [SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "N/A"]")]

" From 6806def7b96db428098999fcbc21f39c1b15616f Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 25 Jan 2025 00:01:09 +0300 Subject: [PATCH 121/135] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=B0=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event_defines/_round_event_control.dm | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index bb71bed3cb07c..e7af3ec1c919c 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -136,6 +136,27 @@ var/forced_antags_count = 0 var/can_change_count = FALSE +/datum/round_event_control/antagonist/solo + typepath = /datum/round_event/antagonist/solo + /// How many baseline antags do we spawn + var/base_antags = 1 + /// How many maximum antags can we spawn + var/maximum_antags = 3 + var/maximum_antags_per_round = 10 + /// For this many players we'll add 1 up to the maximum antag amount + var/denominator = 20 + /// The antag flag to be used + var/antag_flag + /// The antag datum to be applied + var/antag_datum + /// Prompt players for consent to turn them into antags before doing so. Dont allow this for roundstart. + var/prompted_picking = FALSE + /// A list of extra events to force whenever this one is chosen by the storyteller. + /// Can either be normal list or a weighted list. + var/list/extra_spawned_events + /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so + var/list/preferred_events + /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() @@ -228,27 +249,6 @@ if(!.) return -/datum/round_event_control/antagonist/solo - typepath = /datum/round_event/antagonist/solo - /// How many baseline antags do we spawn - var/base_antags = 1 - /// How many maximum antags can we spawn - var/maximum_antags = 3 - var/maximum_antags_per_round = 3 - /// For this many players we'll add 1 up to the maximum antag amount - var/denominator = 20 - /// The antag flag to be used - var/antag_flag - /// The antag datum to be applied - var/antag_datum - /// Prompt players for consent to turn them into antags before doing so. Dont allow this for roundstart. - var/prompted_picking = FALSE - /// A list of extra events to force whenever this one is chosen by the storyteller. - /// Can either be normal list or a weighted list. - var/list/extra_spawned_events - /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so - var/list/preferred_events - /datum/round_event_control/antagonist/solo/from_ghosts/get_candidates() var/round_started = SSticker.HasRoundStarted() var/midround_antag_pref_arg = round_started ? FALSE : TRUE From 223a9c6c8c2dedc2175ad7148e05f52862912537 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 25 Jan 2025 00:40:04 +0300 Subject: [PATCH 122/135] =?UTF-8?q?=D0=9F=D0=BE=D0=B2=D1=8B=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B5=D0=BD=D0=BE=D0=BC=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D0=B0=20=D0=A1=D0=A2=20=D0=AD=D0=BD?= =?UTF-8?q?=D0=B4=D0=B8=20=D0=9F=D1=80=D0=B0=D0=B9=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/storytellers/storyteller_prime.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index e3cf04e0902ab..4fafd1085a4e2 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -18,4 +18,4 @@ /datum/round_event_control/meteor_wave/meaty, /datum/round_event_control/stray_cargo/syndicate, ) - antag_denominator = 12 + antag_denominator = 15 From 44ec639770b62107368b0a3ca5def043a6c22076 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 25 Jan 2025 01:10:26 +0300 Subject: [PATCH 123/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B1=D1=80?= =?UTF-8?q?=D0=BE=D1=81=20=D1=87=D0=B0=D1=81=D1=82=D0=B8=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20=D1=81=20=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20"=D0=9C=D0=B0=D0=B6=D0=BE=D1=80"=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=82=D0=BA=D1=83=20"=D0=A1=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=BD=D0=B5=D0=B5"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event_defines/ghostset/paradox_clone.dm | 2 +- .../code/event_defines/major/override.dm | 20 ------------------- .../code/event_defines/moderate/override.dm | 20 +++++++++++++++++++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index d8c7649b35f63..2cc36b21359b4 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -3,7 +3,7 @@ tags = list(TAG_OUTSIDER_ANTAG, TAG_SPOOKY, TAG_TARGETED) typepath = /datum/round_event/antagonist/solo/ghost/paradox_clone antag_flag = ROLE_PARADOX_CLONE - track = EVENT_TRACK_MAJOR + track = EVENT_TRACK_MODERATE antag_datum = /datum/antagonist/paradox_clone enemy_roles = list( JOB_CAPTAIN, diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index ee4367ba69c9c..78df727e706e2 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -42,10 +42,6 @@ tags = list(TAG_COMBAT) checks_antag_cap = TRUE -/datum/round_event_control/voidwalker - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) - /datum/round_event_control/pirates track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_COMMUNAL) @@ -61,12 +57,6 @@ tags = list(TAG_COMMUNAL, TAG_DESTRUCTIVE) roundstart = TRUE -/datum/round_event_control/changeling - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_SPACE, TAG_EXTERNAL, TAG_ALIEN) - event_group = /datum/event_group/comms - checks_antag_cap = TRUE - /datum/round_event_control/slaughter track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) @@ -89,15 +79,5 @@ tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) checks_antag_cap = TRUE -/datum/round_event_control/nightmare - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) - checks_antag_cap = TRUE - -/datum/round_event_control/revenant - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) - checks_antag_cap = TRUE - /datum/round_event_control/portal_storm_monkey track = EVENT_TRACK_MAJOR diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 0689144185b89..5ac13de0f6249 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -90,3 +90,23 @@ /datum/round_event_control/immovable_rod tags = list(TAG_DESTRUCTIVE, TAG_EXTERNAL, TAG_MAGICAL) eng_required_power = 2 + +/datum/round_event_control/changeling + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT, TAG_SPACE, TAG_EXTERNAL, TAG_ALIEN) + event_group = /datum/event_group/comms + checks_antag_cap = TRUE + +/datum/round_event_control/nightmare + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) + checks_antag_cap = TRUE + +/datum/round_event_control/revenant + track = EVENT_TRACK_MODERATE + tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) + checks_antag_cap = TRUE + +/datum/round_event_control/voidwalker + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) From af60a54c581c810d4171cca3fd951636518b0c68 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 26 Jan 2025 20:17:04 +0300 Subject: [PATCH 124/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BD=D0=B4=D0=B8=D0=B4=D1=82=D0=BE=D0=B2=20=D0=B2=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event_defines/_round_event_control.dm | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index e7af3ec1c919c..59255171d9ae6 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -159,15 +159,15 @@ /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() + if(istype(src, /datum/round_event_control/antagonist/solo/from_ghosts/nuclear_operative)) + var/antag_amt = get_antag_count_to_spawn() + var/list/candidates = get_candidates() //we should optimize this + if((length(candidates) < antag_amt) || !antag_amt) + if(.) + . += ", " + . += "Not Enough Candidates!" - var/antag_amt = get_antag_count_to_spawn() - var/list/candidates = get_candidates() //we should optimize this - if((length(candidates) < antag_amt) || !antag_amt) - if(.) - . += ", " - . += "Not Enough Candidates!" - - return . + return . /datum/round_event_control/proc/generate_image(list/mobs) return @@ -229,10 +229,10 @@ if(!roundstart) for(var/mob/candidate in candidates) //Если событие призраков, то проверить. что кандидат - призрак - if(ispath(typepath, /datum/round_event/ghost_role) && candidate.stat != DEAD) + if((ispath(typepath, /datum/round_event/ghost_role) || ispath(typepath, /datum/round_event/antagonist/solo/ghost/)) && candidate.stat != DEAD) candidates -= candidate //Если событие живых, то проверить. что кандидат - жив или без сознания (не мертв, не в софт крите и не в хард крите) - if(!ispath(typepath, /datum/round_event/ghost_role) && !(candidate.stat == CONSCIOUS || candidate.stat == UNCONSCIOUS)) + if(!(ispath(typepath, /datum/round_event/ghost_role) || ispath(typepath, /datum/round_event/antagonist/solo/ghost/)) && !(candidate.stat == CONSCIOUS || candidate.stat == UNCONSCIOUS)) candidates -= candidate return candidates From 85b7315873b199ee8016a8d565db4a064fa69658 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sun, 26 Jan 2025 21:50:39 +0300 Subject: [PATCH 125/135] =?UTF-8?q?=D0=9A=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/major/override.dm | 17 ---------------- .../code/event_defines/moderate/override.dm | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 78df727e706e2..45a19b94b3b3f 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -17,16 +17,6 @@ event_group = /datum/event_group/meteors eng_required_power = 3 -/datum/round_event_control/anomaly/anomaly_vortex - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE) - rnd_required_power = 3 - -/datum/round_event_control/anomaly/anomaly_pyro - track = EVENT_TRACK_MAJOR - tags = list(TAG_DESTRUCTIVE) - rnd_required_power = 3 - /datum/round_event_control/revenant min_players = 20 track = EVENT_TRACK_MAJOR @@ -67,13 +57,6 @@ tags = list(TAG_COMBAT) event_group = /datum/event_group/guests -/datum/round_event_control/spacevine - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_ALIEN) - checks_antag_cap = TRUE - event_group = /datum/event_group/guests - med_required_power = 2 - /datum/round_event_control/morph track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 5ac13de0f6249..b01056d5534d4 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -110,3 +110,23 @@ /datum/round_event_control/voidwalker track = EVENT_TRACK_MODERATE tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) + +/datum/round_event_control/anomaly/anomaly_vortex + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + rnd_required_power = 3 + weight = 5 + +/datum/round_event_control/anomaly/anomaly_pyro + track = EVENT_TRACK_MAJOR + tags = list(TAG_DESTRUCTIVE) + rnd_required_power = 3 + weight = 5 + +/datum/round_event_control/spacevine + track = EVENT_TRACK_MAJOR + tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_ALIEN) + checks_antag_cap = TRUE + event_group = /datum/event_group/guests + med_required_power = 2 + weight = 5 From adf7ccdc8f0c097cf085329193fa08a4e9eee4bb Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 27 Jan 2025 00:00:23 +0300 Subject: [PATCH 126/135] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20-=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=B5=D0=B8=D0=B5=20=D1=81=D0=B8=D0=BB=D1=8B=20=D0=A1=D0=91=20?= =?UTF-8?q?=D0=BD=D0=B0=201,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BE=20=D0=BD=D0=B5=D1=85=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D0=BA=D0=B5=20=D0=BA=D0=B0=D0=BD=D0=B4=D0=B8=D0=B4=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D0=B2,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D1=82=20=D1=86=D0=B5=D0=BD=20=D0=BD=D0=B5=D0=BA=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D1=8B=D1=85=20=D0=B0=D0=BD=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20(=D0=B5=D1=80=D0=B5=D1=82=D0=B8=D0=BA,=20?= =?UTF-8?q?=D1=82=D1=80=D0=B5=D0=B9=D1=82=D0=BE=D1=80,=20=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=BA=D1=80=D0=B0=D0=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/_defines/storyteller_defines.dm | 2 +- .../storyteller/code/event_defines/_round_event_control.dm | 6 +++--- .../storyteller/code/event_defines/crewset/changeling.dm | 1 + .../storyteller/code/event_defines/crewset/heretic.dm | 1 + .../storyteller/code/event_defines/crewset/traitors.dm | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index a5d0650afce29..e1b564f6942ad 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -77,7 +77,7 @@ #define STORYTELLER_BASIC_MULT 10 #define STORYTELLER_MIN_ANTAG_POPCOUNT 20 -#define STORYTELLER_SEC_ANTAG_MODIFIER 2 +#define STORYTELLER_SEC_ANTAG_MODIFIER 1 #define STORYTELLER_BASIC_MODIFIER 1 #define STORYTELLER_VOTE "storyteller" diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 59255171d9ae6..fddefddecd8ee 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -160,12 +160,12 @@ /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() if(istype(src, /datum/round_event_control/antagonist/solo/from_ghosts/nuclear_operative)) - var/antag_amt = get_antag_count_to_spawn() var/list/candidates = get_candidates() //we should optimize this - if((length(candidates) < antag_amt) || !antag_amt) + var/ghost_event = ispath(typepath, /datum/round_event/antagonist/solo/ghost) || ispath(typepath, /datum/round_event/ghost_role) + if((length(candidates) < base_antags)) if(.) . += ", " - . += "Not Enough Candidates!" + . += get_antag_count_to_spawn() ? "Not Enough [ghost_event ? "ghost" : ""] candidates!" : "No empty antag-slots" return . diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 6f7d64d7ac503..885182a02f6b0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -29,6 +29,7 @@ roundstart = TRUE earliest_start = 0 maximum_antags = 1 + roundstart_cost = 24 /datum/round_event_control/antagonist/solo/changeling/midround name = "Genome Awakening (Changelings)" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index fd3c3990d3842..927a36d5d447a 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -38,6 +38,7 @@ name = "Heretics" roundstart = TRUE earliest_start = 0 + roundstart_cost = 12 /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index dbf5801ebc5b1..2f098a72bfd07 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -29,6 +29,7 @@ roundstart = TRUE earliest_start = 0 SECONDS maximum_antags = 1 + roundstart_cost = 12 /datum/round_event_control/antagonist/solo/traitor/midround name = "Sleeper Agents (Traitors)" From f9ffc289a5bf9a42897b9ec0fcf68db9f01b3aba Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 27 Jan 2025 18:24:22 +0300 Subject: [PATCH 127/135] =?UTF-8?q?=D0=90=D0=BF=20=D1=86=D0=B5=D0=BD=D1=8B?= =?UTF-8?q?=20=D1=82=D1=80=D0=B5=D0=B9=D1=82=D0=BE=D1=80=D0=B0=20=D0=B8=20?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D1=82=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/crewset/heretic.dm | 2 +- .../storyteller/code/event_defines/crewset/traitors.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 927a36d5d447a..744dfe843ccd0 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -38,7 +38,7 @@ name = "Heretics" roundstart = TRUE earliest_start = 0 - roundstart_cost = 12 + roundstart_cost = 15 /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 2f098a72bfd07..8b4984242b955 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -29,7 +29,7 @@ roundstart = TRUE earliest_start = 0 SECONDS maximum_antags = 1 - roundstart_cost = 12 + roundstart_cost = 15 /datum/round_event_control/antagonist/solo/traitor/midround name = "Sleeper Agents (Traitors)" From 285c3f20b1a7468444b2dfdd8b8bfbe93a8d4c8b Mon Sep 17 00:00:00 2001 From: KageIIte Date: Mon, 27 Jan 2025 23:30:00 +0300 Subject: [PATCH 128/135] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=20=D0=B0=D0=B1=D0=B4=D1=83=D0=BA=D1=82=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/major/override.dm | 5 ----- .../code/event_defines/moderate/override.dm | 11 ++++++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 45a19b94b3b3f..58d045dd64821 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -22,11 +22,6 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) -/datum/round_event_control/abductor - track = EVENT_TRACK_MAJOR - tags = list(TAG_TARGETED, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) - checks_antag_cap = TRUE - /datum/round_event_control/fugitives track = EVENT_TRACK_MAJOR tags = list(TAG_COMBAT) diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index b01056d5534d4..07645e0226213 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -112,21 +112,26 @@ tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) /datum/round_event_control/anomaly/anomaly_vortex - track = EVENT_TRACK_MAJOR + track = EVENT_TRACK_MODERATE tags = list(TAG_DESTRUCTIVE) rnd_required_power = 3 weight = 5 /datum/round_event_control/anomaly/anomaly_pyro - track = EVENT_TRACK_MAJOR + track = EVENT_TRACK_MODERATE tags = list(TAG_DESTRUCTIVE) rnd_required_power = 3 weight = 5 /datum/round_event_control/spacevine - track = EVENT_TRACK_MAJOR + track = EVENT_TRACK_MODERATE tags = list(TAG_COMBAT, TAG_DESTRUCTIVE, TAG_ALIEN) checks_antag_cap = TRUE event_group = /datum/event_group/guests med_required_power = 2 weight = 5 + +/datum/round_event_control/abductor + track = EVENT_TRACK_MODERATE + tags = list(TAG_TARGETED, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) + checks_antag_cap = TRUE From 9811ec2c7e5e0bcb24d09de3e9b288607ed13b34 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 29 Jan 2025 02:00:47 +0300 Subject: [PATCH 129/135] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D1=83=20=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B1=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BC=D0=B0=D0=BC=20=D0=B8=D0=B7=20=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../events/ghost_role/alien_infestation.dm | 1 + .../code/event_defines/_round_event.dm | 21 +++++---- .../event_defines/_round_event_control.dm | 20 ++++---- .../event_defines/crewset/blood_brothers.dm | 1 + .../code/event_defines/crewset/clown_ops.dm | 2 +- .../code/event_defines/crewset/cult.dm | 7 ++- .../code/event_defines/crewset/malf.dm | 1 + .../code/event_defines/crewset/nuke_ops.dm | 4 +- .../code/event_defines/crewset/revolution.dm | 1 + .../code/event_defines/crewset/wizard.dm | 3 +- .../ghostset/alien_infestation.dm | 18 +++---- .../code/event_defines/ghostset/nuke_ops.dm | 47 ++++++++++++++++++- .../event_defines/ghostset/paradox_clone.dm | 12 +++-- .../code/event_defines/major/override.dm | 8 ---- .../code/event_defines/moderate/override.dm | 14 ++++++ .../storyteller/code/gamemode.dm | 37 ++++++++++----- .../code/storytellers/_storyteller.dm | 2 + .../code/storytellers/storyteller_default.dm | 1 + .../code/storytellers/storyteller_prime.dm | 1 + 19 files changed, 142 insertions(+), 59 deletions(-) diff --git a/code/modules/events/ghost_role/alien_infestation.dm b/code/modules/events/ghost_role/alien_infestation.dm index 0be5d9f3ff4f6..54f6562f03a23 100644 --- a/code/modules/events/ghost_role/alien_infestation.dm +++ b/code/modules/events/ghost_role/alien_infestation.dm @@ -33,6 +33,7 @@ announce_when = rand(announce_when, announce_when + 50) if(prob(50)) spawncount++ + setup = TRUE /datum/round_event/ghost_role/alien_infestation/announce(fake) var/living_aliens = FALSE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 6c2804ee43ca6..21f513fada319 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -115,11 +115,15 @@ var/list/picked_mobs = list() var/spawned_count = 0 - for(var/i in 1 to antag_count) + while(spawned_count < antag_count) if(!length(candidates)) message_admins("A roleset event got fewer antags then its antag_count and may not function correctly.") break + spawned_count++ + if(spawned_count > SSgamemode.get_antag_cap(forced) || spawned_count > SSgamemode.left_antag_count_by_type(cast_control)) + break + var/mob/candidate = pick_n_take(candidates) log_storyteller("Antag event spawned mob: [candidate], special role: [candidate.mind?.special_role ? candidate.mind.special_role : "none"]") @@ -130,9 +134,6 @@ candidate.mind.special_role = antag_flag candidate.mind.restricted_roles = restricted_roles picked_mobs += WEAKREF(candidate.client) - spawned_count++ - if(spawned_count++ > SSgamemode.get_antag_cap(forced)) - antag_count-- setup = TRUE control.generate_image(picked_mobs) @@ -195,6 +196,7 @@ cliented_list += mob.client if(prompted_picking) + //candidates = SSpolling.poll_ghost_candidates(check_jobban = antag_flag, role = antag_flag, alert_pic = /mob/living/carbon/alien/larva, role_name_text = lowertext(cast_control.name)) candidates = SSpolling.poll_candidates( question = "Would you like to be a [cast_control.name]?", check_jobban = antag_flag, @@ -207,22 +209,23 @@ ) var/list/weighted_candidates = return_antag_weight(candidates) - var/selected_count = 0 - while(length(weighted_candidates) && selected_count < antag_count) + var/spawned_count = 0 + while(length(weighted_candidates) && spawned_count < antag_count) var/candidate_ckey = pick_n_take_weighted(weighted_candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) continue var/mob/candidate = candidate_client.mob + spawned_count++ + if(spawned_count > SSgamemode.get_antag_cap(forced) || spawned_count > SSgamemode.left_antag_count_by_type(cast_control)) + break + if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) var/mob/living/carbon/human/new_human = make_body(candidate) new_human.mind.special_role = antag_flag new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind - selected_count++ - if(selected_count++ > SSgamemode.get_antag_cap(forced)) - selected_count-- setup = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index fddefddecd8ee..6e708832407c9 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -31,6 +31,9 @@ /// Значение, которое используется при расчете стоимости покупки из раундстарт бюджета. Считается если значение 0. var/roundstart_cost = 0 +/datum/round_event_control/proc/get_pre_cost() + return roundstart_cost + /datum/round_event_control/proc/return_failure_string(players_amt) var/string if(SSgamemode.current_storyteller?.disable_distribution || SSgamemode.halted_storyteller) @@ -159,15 +162,14 @@ /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() - if(istype(src, /datum/round_event_control/antagonist/solo/from_ghosts/nuclear_operative)) - var/list/candidates = get_candidates() //we should optimize this - var/ghost_event = ispath(typepath, /datum/round_event/antagonist/solo/ghost) || ispath(typepath, /datum/round_event/ghost_role) - if((length(candidates) < base_antags)) - if(.) - . += ", " - . += get_antag_count_to_spawn() ? "Not Enough [ghost_event ? "ghost" : ""] candidates!" : "No empty antag-slots" + var/list/candidates = get_candidates() //we should optimize this + var/ghost_event = ispath(typepath, /datum/round_event/antagonist/solo/ghost) || ispath(typepath, /datum/round_event/ghost_role) + if((length(candidates) < base_antags)) + if(.) + . += ", " + . += get_antag_count_to_spawn() ? "Not Enough [ghost_event ? "ghost" : ""] candidates!" : "No empty antag-slots" - return . + return . /datum/round_event_control/proc/generate_image(list/mobs) return @@ -379,6 +381,6 @@ if(isnull(new_value) || new_value < 1) return forced_antag_event.forced_antags_count = new_value - forced_antag_event.run_event(random = FALSE, admin_forced = TRUE) + forced_antag_event.run_event(random = FALSE, admin_forced = TRUE) else run_event(random = FALSE, admin_forced = TRUE) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index 4b1dd4f5e85b6..cc4fb064d61f1 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -45,6 +45,7 @@ /datum/round_event_control/antagonist/solo/heretic/roundstart = 2, ) maximum_antags = 1 + roundstart_cost = 20 /datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) var/datum/team/brother_team/team = new diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm index 34b66a876ec78..7e097c15cd070 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/clown_ops.dm @@ -4,7 +4,7 @@ antag_flag = ROLE_CLOWN_OPERATIVE antag_datum = /datum/antagonist/nukeop/clownop typepath = /datum/round_event/antagonist/solo/nuclear_operative/clown - weight = 1 //these are meant to be very rare + weight = 0 //these are meant to be very rare max_occurrences = 1 event_icon_state = "flukeops" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm index c6eec1172269e..c5933c8c34f22 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/cult.dm @@ -33,9 +33,14 @@ min_players = 30 roundstart = TRUE earliest_start = 0 SECONDS - weight = 4 + weight = 1 max_occurrences = 3 +/datum/round_event_control/antagonist/solo/bloodcult/get_pre_cost() + var/candidates = get_candidates() + roundstart_cost = 20 * length(candidates) + return roundstart_cost + /datum/round_event/antagonist/solo/bloodcult excute_round_end_reports = TRUE end_when = 60000 diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm index 51fa982fbfff5..ae520771673bf 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/malf.dm @@ -17,6 +17,7 @@ required_enemies = 4 weight = 2 min_players = 35 + roundstart_cost = 35 max_occurrences = 1 /datum/round_event_control/antagonist/solo/malf/trim_candidates(list/candidates) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index c2f132c3c89ea..3638180d3e078 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -38,10 +38,12 @@ min_players = 35 roundstart = TRUE earliest_start = 0 SECONDS - weight = 4 + weight = 1 + roundstart_cost = 50 max_occurrences = 3 event_icon_state = "nukeops" exclusive_roundstart_event = TRUE + can_change_count = TRUE /datum/round_event/antagonist/solo/nuclear_operative excute_round_end_reports = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm index af46a2f81eaea..55e6fd9cb050f 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/revolution.dm @@ -35,6 +35,7 @@ roundstart = TRUE earliest_start = 0 SECONDS weight = 0 //value was 3, we need to manually test if this works or not before allowing it normally + roundstart_cost = 40 max_occurrences = 1 /datum/antagonist/rev/head/event_trigger diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm index 55bcd458c9b78..b4ee7d267ae58 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/wizard.dm @@ -24,8 +24,9 @@ ) required_enemies = 5 roundstart = TRUE + roundstart_cost = 30 earliest_start = 0 SECONDS - weight = 2 + weight = 1 min_players = 35 max_occurrences = 1 event_icon_state = "wizard" diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index d8200c1b4a804..27f4b97a766cc 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -28,7 +28,6 @@ announce_when = 400 fakeable = TRUE - /datum/round_event/antagonist/solo/ghost/alien_infestation/setup() announce_when = rand(announce_when, announce_when + 50) var/datum/round_event_control/antagonist/solo/cast_control = control @@ -50,13 +49,11 @@ for(var/mob/living/mob as anything in candidates) cliented_list += mob.client - candidates = SSpolling.poll_ghost_candidates(check_jobban = ROLE_ALIEN, role = ROLE_ALIEN, alert_pic = /mob/living/carbon/alien/larva, role_name_text = lowertext(cast_control.name)) + candidates = SSpolling.poll_ghost_candidates(check_jobban = antag_flag, role = antag_flag, alert_pic = /mob/living/carbon/alien/larva, role_name_text = lowertext(cast_control.name)) if(!length(candidates)) return NOT_ENOUGH_PLAYERS - var/list/weighted_candidates = return_antag_weight(candidates) - var/list/vents = list() for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) if(QDELETED(temp_vent)) @@ -74,12 +71,18 @@ message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.") return MAP_ERROR - var/selected_count = 0 - while(length(weighted_candidates) && selected_count < antag_count) + var/list/weighted_candidates = return_antag_weight(candidates) + var/spawned_count = 0 + while(length(weighted_candidates) && spawned_count < antag_count) var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) continue + + spawned_count++ + if(spawned_count > SSgamemode.get_antag_cap(forced) || spawned_count > SSgamemode.left_antag_count_by_type(cast_control)) + break + var/mob/candidate = candidate_client.mob if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) @@ -88,10 +91,7 @@ var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) new_xeno.ckey = candidate_ckey new_xeno.move_into_vent(vent) - selected_count++ - if(selected_count++ > SSgamemode.get_antag_cap(forced)) - selected_count-- message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.") new_xeno.log_message("was spawned as an alien by an event.", LOG_GAME) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm index d7f82fc89e45b..eccaa1d3fb8d2 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -35,7 +35,8 @@ earliest_start = 45 MINUTES weight = 4 max_occurrences = 1 - prompted_picking = FALSE + prompted_picking = TRUE + can_change_count = TRUE /datum/round_event/antagonist/solo/ghost/nuclear_operative excute_round_end_reports = TRUE @@ -43,6 +44,7 @@ var/static/datum/team/nuclear/nuke_team var/set_leader = FALSE var/required_role = ROLE_NUCLEAR_OPERATIVE + var/job_type = /datum/job/nuclear_operative /datum/round_event/antagonist/solo/ghost/nuclear_operative/add_datum_to_mind(datum/mind/antag_mind) var/mob/living/current_mob = antag_mind.current @@ -69,7 +71,6 @@ var/datum/antagonist/nukeop/new_op = new antag_datum() antag_mind.add_antag_datum(new_op) - GLOB.pre_setup_antags -= antag_mind //this might be able to be kept as just calling parent /datum/round_event/antagonist/solo/ghost/nuclear_operative/round_end_report() @@ -105,3 +106,45 @@ else SSticker.mode_result = "halfwin - interrupted" SSticker.news_report = OPERATIVE_SKIRMISH + +/datum/round_event/antagonist/solo/ghost/nuclear_operative/setup() + var/datum/round_event_control/antagonist/solo/cast_control = control + antag_count = forced && cast_control.forced_antags_count > 0 ? cast_control.forced_antags_count : cast_control.get_antag_count_to_spawn(forced) + if(!antag_count) + return + + antag_flag = cast_control.antag_flag + antag_datum = cast_control.antag_datum + restricted_roles = cast_control.restricted_roles + prompted_picking = cast_control.prompted_picking + var/list/candidates = cast_control.get_candidates() + + //guh + var/list/cliented_list = list() + for(var/mob/living/mob as anything in candidates) + cliented_list += mob.client + + if(prompted_picking) + candidates = SSpolling.poll_ghost_candidates(check_jobban = antag_flag, role = antag_flag, alert_pic = /obj/structure/sign/poster/contraband/syndicate_recruitment, role_name_text = lowertext(cast_control.name)) + + var/list/weighted_candidates = return_antag_weight(candidates) + var/spawned_count = 0 + while(length(weighted_candidates) && spawned_count < antag_count) + var/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + + spawned_count++ + if(spawned_count > SSgamemode.get_antag_cap(forced) || spawned_count > SSgamemode.left_antag_count_by_type(cast_control)) + break + + if(!candidate.mind) + candidate.mind = new /datum/mind(candidate.key) + var/mob/living/carbon/human/new_human = make_body(candidate) + new_human.mind.special_role = antag_flag + new_human.mind.restricted_roles = restricted_roles + setup_minds += new_human.mind + + setup = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index 2cc36b21359b4..d92b9fd77f038 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -52,12 +52,17 @@ chat_text_border_icon = /datum/antagonist/paradox_clone, ) - var/selected_count = 0 - while(length(candidates) && selected_count < antag_count) + var/spawned_count = 0 + while(length(candidates) && spawned_count < antag_count) var/client/candidate_ckey = pick_n_take_weighted(candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) continue + + spawned_count++ + if(spawned_count > SSgamemode.get_antag_cap(forced) || spawned_count > SSgamemode.left_antag_count_by_type(cast_control)) + break + var/mob/candidate = candidate_client.mob if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) @@ -68,10 +73,7 @@ new_human.mind.special_role = antag_flag new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind - selected_count++ - if(selected_count++ > SSgamemode.get_antag_cap(forced)) - selected_count-- setup = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 58d045dd64821..0bd1db46da734 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -1,11 +1,3 @@ -/datum/round_event_control/bureaucratic_error - track = EVENT_TRACK_MAJOR // if you've ever dealt with 10 mimes you understand why. - tags = list(TAG_COMMUNAL) - event_group = /datum/event_group/error - weight = 5 - max_occurrences = 1 - head_required_power = 3 - /datum/round_event_control/earthquake track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE) diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 07645e0226213..13be66a4c009d 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -135,3 +135,17 @@ track = EVENT_TRACK_MODERATE tags = list(TAG_TARGETED, TAG_SPOOKY, TAG_EXTERNAL, TAG_ALIEN) checks_antag_cap = TRUE + +/datum/round_event_control/meteor_wave/dust_storm + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMMUNAL, TAG_SPACE, TAG_DESTRUCTIVE) + event_group = /datum/event_group/meteors + eng_required_power = 3 + +/datum/round_event_control/bureaucratic_error + track = EVENT_TRACK_MODERATE // if you've ever dealt with 10 mimes you understand why. + tags = list(TAG_COMMUNAL) + event_group = /datum/event_group/error + weight = 5 + max_occurrences = 1 + head_required_power = 3 diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index f617490142b1d..e17ad01b25012 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -230,7 +230,7 @@ SUBSYSTEM_DEF(gamemode) if(pop_count < current_storyteller.min_antag_popcount && !forced) return 0 var/total_number = pop_count + (sec_crew * current_storyteller.sec_antag_modifier) - var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) + current_storyteller.antag_flat_cap + var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) * current_storyteller.final_cap_multiplier + current_storyteller.antag_flat_cap return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() @@ -730,9 +730,9 @@ SUBSYSTEM_DEF(gamemode) recalculate_roundstart_costs(track) var/datum/round_event_control/picked_event = pick_weight(valid_events) - if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.roundstart_cost)) - roundstart_budget -= picked_event.roundstart_cost - message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.roundstart_cost]. Left balance: [roundstart_budget].") + if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.get_pre_cost())) + roundstart_budget -= picked_event.get_pre_cost() + message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.get_pre_cost()]. Left balance: [roundstart_budget].") TriggerEvent(picked_event, forced = FALSE) runned_events += "Runned roundstart: [picked_event.name]" // Если первое событие эксклюзивное, то отчищаем список @@ -758,14 +758,14 @@ SUBSYSTEM_DEF(gamemode) var/datum/round_event_control/antagonist/solo/scheduled_event = pick_weight(scheduled_events_roleset) for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == scheduled_event.antag_datum) - scheduled_event.roundstart_cost = scheduled_event.roundstart_cost ? scheduled_event.roundstart_cost : ruleset.cost + scheduled_event.roundstart_cost = scheduled_event.get_pre_cost() ? scheduled_event.get_pre_cost() : ruleset.cost break while(length(scheduled_events_roleset)) var/datum/round_event_control/scheduled_event = pick_weight(scheduled_events_roleset) - if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.roundstart_cost)) - roundstart_budget -= scheduled_event.roundstart_cost - message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") + if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.get_pre_cost())) + roundstart_budget -= scheduled_event.get_pre_cost() + message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.get_pre_cost()]. Left balance: [roundstart_budget].") TriggerEvent(scheduled_event, forced = FALSE) runned_events += "Runned scheduled roundstart: [scheduled_event.name]" scheduled_events_roleset -= scheduled_event @@ -810,7 +810,7 @@ SUBSYSTEM_DEF(gamemode) for(var/datum/round_event_control/antagonist/solo/event as anything in valid_events) for(var/datum/dynamic_ruleset/ruleset as anything in dynamic_roundstart_rules) if(ruleset.antag_datum == event.antag_datum) - event.roundstart_cost = event.roundstart_cost ? event.roundstart_cost : ruleset.cost + event.roundstart_cost = event.get_pre_cost() ? event.get_pre_cost() : ruleset.cost break return valid_events @@ -1050,10 +1050,11 @@ SUBSYSTEM_DEF(gamemode) dat += "
Storyteller Antag Low pop:[current_storyteller.min_antag_popcount]" dat += "
This value affects how many players count as low pop and makes the antag cap value to zero if it is below." dat += "
Guarantees Roundstart Roleset: [current_storyteller.guarantees_roundstart_roleset ? "TRUE" : "FALSE" ]" - dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator) + addiction" - dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) + [current_storyteller.antag_flat_cap]" + dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator) * cap_multiplier + addiction" + dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) * [current_storyteller.final_cap_multiplier] + [current_storyteller.antag_flat_cap]" dat += "
Sec antag modifier: [current_storyteller.sec_antag_modifier]" dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" + dat += "
Antag cap multiplier: [current_storyteller.final_cap_multiplier]" dat += "
Antag denominator: [current_storyteller.antag_denominator]" dat += "
This affects how many antagonist can system spawn." dat += "
" @@ -1273,7 +1274,7 @@ SUBSYSTEM_DEF(gamemode) if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) weight_string = "[percent]% - [weight_string]" - dat += "[SSticker.HasRoundStarted() && !event.roundstart_cost ? weight_string : event.roundstart_cost]" //Weight + dat += "[SSticker.HasRoundStarted() && !event.get_pre_cost() ? weight_string : "[event.get_pre_cost()]/[weight_string]"]" //Weight dat += "[event.get_href_actions()]" //Actions dat += "" dat += "" @@ -1362,6 +1363,12 @@ SUBSYSTEM_DEF(gamemode) return message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") current_storyteller.point_gain_base_mult = new_value + if("vars_cap_mult") + var/new_value = input(usr, "New value:", "Set new value") as num|null + if(isnull(new_value) || new_value < 0) + return + message_admins("[key_name_admin(usr)] set basic storyteller cap multiplier to [new_value].") + current_storyteller.final_cap_multiplier = new_value if("vars_guarante_roundstart") var/new_value = !current_storyteller.guarantees_roundstart_roleset message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") @@ -1466,13 +1473,17 @@ SUBSYSTEM_DEF(gamemode) if(!type) return count - for(var/datum/antagonist/antag_datum_element in GLOB.antagonists) if(antag_datum_element.type == type) count++ return count +/datum/controller/subsystem/gamemode/proc/left_antag_count_by_type(control) + var/datum/round_event_control/antagonist/solo/cast_control = control + var/left = cast_control.maximum_antags_per_round - get_antag_count_by_type(cast_control.antag_datum) + return left + /datum/controller/subsystem/gamemode/proc/create_roundend_score() var/list/parts = list() parts += "
[("Storyteller: [SSgamemode.current_storyteller ? SSgamemode.current_storyteller.name : "N/A"]")]

" diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index c83b8c4319a3b..1baaf44c04068 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -80,6 +80,8 @@ var/storyteller_basic_modifier = STORYTELLER_BASIC_MODIFIER ///Список событий на исключение var/list/exclude_events = list() + ///Финальный множитель антаг-капа (до ручного добавления) + var/final_cap_multiplier = 1 /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm index 52389b9531b9b..d086e64d4531c 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm @@ -4,3 +4,4 @@ always_votable = TRUE welcome_text = "I am not Randy!" weight = 6 + final_cap_multiplier = 0.7 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index 4fafd1085a4e2..89fbe60df88f8 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -19,3 +19,4 @@ /datum/round_event_control/stray_cargo/syndicate, ) antag_denominator = 15 + final_cap_multiplier = 0.7 From eceb65b8ffb418819df028207ee84a17ed5a61f0 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Wed, 29 Jan 2025 08:13:09 +0300 Subject: [PATCH 130/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/antagonists/pirate/pirate_event.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm index 6c6949eaeb6e2..a3ff1ad274ede 100644 --- a/code/modules/antagonists/pirate/pirate_event.dm +++ b/code/modules/antagonists/pirate/pirate_event.dm @@ -27,6 +27,8 @@ send_pirate_threat(gang_list) /proc/send_pirate_threat(list/pirate_selection) + if(!pirate_selection) + pirate_selection = GLOB.light_pirate_gangs + GLOB.heavy_pirate_gangs var/datum/pirate_gang/chosen_gang = pick_n_take(pirate_selection) ///If there was nothing to pull from our requested list, stop here. if(!chosen_gang) From aca757ff766fd261afd6c9b1f96025d9c1abc023 Mon Sep 17 00:00:00 2001 From: larentoun <31931237+larentoun@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:35:33 +0300 Subject: [PATCH 131/135] disable for now --- .../storyteller/code/event_defines/ghostset/voidwalker.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm index 84f30ebce3e9d..c1288a35ce564 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm @@ -1,5 +1,6 @@ // TG did not cook this antag into the event system. So I had to make my own +/* /datum/round_event_control/voidwalker name = "Spawn Void Walker" typepath = /datum/round_event/ghost_role/void_walker @@ -39,3 +40,4 @@ walker.log_message("[key_name(walker)] was spawned as a Voidwalker by an event.", LOG_GAME) spawned_mobs += walker return SUCCESSFUL_SPAWN +*/ From adbf3cff83692391171240844c2d0e24619add96 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Thu, 30 Jan 2025 23:56:27 +0300 Subject: [PATCH 132/135] =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=B0=D1=80=D0=B0=D0=B4=D0=BE?= =?UTF-8?q?=D0=BA=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../storyteller/code/event_defines/ghostset/paradox_clone.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index d92b9fd77f038..c36af8f0aad6b 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -1,3 +1,4 @@ +/* /datum/round_event_control/antagonist/solo/from_ghosts/paradox_clone name = "Paradox Clone" tags = list(TAG_OUTSIDER_ANTAG, TAG_SPOOKY, TAG_TARGETED) @@ -106,3 +107,5 @@ if(possible_targets.len) return pick(possible_targets) return FALSE + +*/ From b6d18bc3c6b368322f10bc96bebb10a55fee5445 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Fri, 31 Jan 2025 01:17:22 +0300 Subject: [PATCH 133/135] =?UTF-8?q?=D0=92=D0=BE=D1=81=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0?= =?UTF-8?q?=D1=80=D0=B0=D0=B4=D0=BE=D0=BA=D1=81=D0=B0,=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=B1=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=20=D0=B3=D0=BE=D1=81=D1=82-=D1=80=D0=BE=D0=BB=D0=B5=D0=B9,=20?= =?UTF-8?q?=D1=83=D1=81=D0=BA=D0=BE=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=D0=B1=D0=BE=D1=80=D0=B0=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=B8=D1=80=D0=B0=D1=82=D0=B0=D1=85,=20=D0=B2=D0=BE?= =?UTF-8?q?=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B8=D0=B4=D0=B0,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D1=81=D1=82=D1=80=D0=B5=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= =?UTF-8?q?,=20=D0=BE=D0=BA=D1=80=D1=83=D0=B3=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=B0=20=D0=B0=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=BD=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../antagonists/pirate/pirate_event.dm | 5 +- .../code/_defines/storyteller_defines.dm | 2 + .../code/event_defines/_round_event.dm | 4 +- .../event_defines/_round_event_control.dm | 3 + .../event_defines/crewset/blood_brothers.dm | 20 +++++-- .../code/event_defines/crewset/changeling.dm | 11 +++- .../code/event_defines/crewset/heretic.dm | 12 +++- .../code/event_defines/crewset/nuke_ops.dm | 2 + .../code/event_defines/crewset/traitors.dm | 13 ++++- .../ghostset/alien_infestation.dm | 4 +- .../code/event_defines/ghostset/nuke_ops.dm | 4 +- .../event_defines/ghostset/paradox_clone.dm | 16 +++--- .../code/event_defines/ghostset/voidwalker.dm | 8 +-- .../code/event_defines/moderate/override.dm | 4 -- .../code/event_defines/mundane/override.dm | 1 + .../storyteller/code/gamemode.dm | 56 +++++++++++++++---- .../code/storytellers/_storyteller.dm | 4 ++ 17 files changed, 130 insertions(+), 39 deletions(-) diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm index a3ff1ad274ede..627e31a37d541 100644 --- a/code/modules/antagonists/pirate/pirate_event.dm +++ b/code/modules/antagonists/pirate/pirate_event.dm @@ -43,7 +43,10 @@ //send message priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound()) threat.answer_callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(pirates_answered), threat, chosen_gang, payoff, world.time) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_pirates), threat, chosen_gang), RESPONSE_MAX_TIME) + // BANDASTATION EDIT START - STORYTELLER + //addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_pirates), threat, chosen_gang), RESPONSE_MAX_TIME) + spawn_pirates(threat, chosen_gang) + // BANDASTATION EDIT END - STORYTELLER GLOB.communications_controller.send_message(threat, unique = TRUE) /proc/pirates_answered(datum/comm_message/threat, datum/pirate_gang/chosen_gang, payoff, initial_send_time) diff --git a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm index e1b564f6942ad..bc4b8119fa6b3 100644 --- a/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm +++ b/modular_bandastation/storyteller/code/_defines/storyteller_defines.dm @@ -30,6 +30,8 @@ #define TAG_ALIEN "alien" /// When the event is magical in nature #define TAG_MAGICAL "magical" +/// Сколько раз сторителлер будет пытаться переподбирать сикей для гост-ролей в случае ошибки +#define STORYTELLER_MAXIMUM_RETRIES 10 #define EVENT_TRACK_MUNDANE "Mundane" #define EVENT_TRACK_MODERATE "Moderate" diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event.dm b/modular_bandastation/storyteller/code/event_defines/_round_event.dm index 21f513fada319..600919cff3352 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event.dm @@ -83,11 +83,13 @@ var/list/weighted_candidates = return_antag_weight(possible_candidates) var/valid_to_spawn = TRUE - while(length(weighted_candidates) && length(candidates) < antag_count && valid_to_spawn) //both of these pick_n_take from weighted_candidates so this should be fine + var/failed_retries = 0 + while(length(weighted_candidates) && length(candidates) < antag_count && valid_to_spawn && failed_retries < STORYTELLER_MAXIMUM_RETRIES) //both of these pick_n_take from weighted_candidates so this should be fine if(prompted_picking) var/picked_ckey = pick_n_take_weighted(weighted_candidates) var/client/picked_client = GLOB.directory[picked_ckey] if(QDELETED(picked_client)) + failed_retries++ continue var/mob/picked_mob = picked_client.mob log_storyteller("Prompted antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 6e708832407c9..9d6196f90e296 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -8,6 +8,7 @@ var/track = EVENT_TRACK_MODERATE /// Last calculated weight that the storyteller assigned this event var/calculated_weight = 0 + var/calculated_on_track_weight = 0 var/tags = list() /// Tags of the event /// List of the shared occurence types. var/static/list/shared_occurences = list() @@ -160,6 +161,8 @@ /// Similar to extra_spawned_events however these are only used by roundstart events and will only try and run if we have the points to do so var/list/preferred_events + var/price_to_buy_adds = 20 + /datum/round_event_control/antagonist/solo/return_failure_string(players_amt) . =..() var/list/candidates = get_candidates() //we should optimize this diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm index cc4fb064d61f1..5bc1fe671c00c 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blood_brothers.dm @@ -30,23 +30,33 @@ JOB_SECURITY_OFFICER, ) required_enemies = 1 - weight = 12 + weight = 15 maximum_antags = 2 maximum_antags_per_round = 2 denominator = 30 cost = 0.45 // so it doesn't eat up threat for a relatively low-threat antag /datum/round_event_control/antagonist/solo/brother/roundstart - name = "Blood Brothers" + name = "Antag-mix" roundstart = TRUE earliest_start = 0 SECONDS extra_spawned_events = list( - /datum/round_event_control/antagonist/solo/traitor/roundstart = 12, - /datum/round_event_control/antagonist/solo/heretic/roundstart = 2, + /datum/round_event_control/antagonist/solo/traitor/adds = 12, + /datum/round_event_control/antagonist/solo/heretic/adds = 10, + /datum/round_event_control/antagonist/solo/changeling/adds = 8, ) - maximum_antags = 1 roundstart_cost = 20 +/datum/round_event_control/antagonist/solo/brother/midround + name = "Blood Brothers (Admin spawn)" + earliest_start = 0 SECONDS + extra_spawned_events = list( + /datum/round_event_control/antagonist/solo/traitor/adds = 12, + /datum/round_event_control/antagonist/solo/heretic/adds = 10, + /datum/round_event_control/antagonist/solo/changeling/adds = 8, + ) + weight = 0 + /datum/round_event/antagonist/solo/brother/add_datum_to_mind(datum/mind/antag_mind) var/datum/team/brother_team/team = new team.add_member(antag_mind) diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm index 885182a02f6b0..e858da3e9f690 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/changeling.dm @@ -24,12 +24,21 @@ min_players = 20 maximum_antags_per_round = 3 -/datum/round_event_control/antagonist/solo/changeling/roundstart +/datum/round_event_control/antagonist/solo/changeling/adds name = "Changelings" roundstart = TRUE earliest_start = 0 + roundstart_cost = 20 + +/datum/round_event_control/antagonist/solo/changeling/solomode + name = "Changelings" + roundstart = TRUE + earliest_start = 0 + base_antags = 1 maximum_antags = 1 roundstart_cost = 24 + exclusive_roundstart_event = TRUE + price_to_buy_adds = 30 /datum/round_event_control/antagonist/solo/changeling/midround name = "Genome Awakening (Changelings)" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm index 744dfe843ccd0..a305c5e5ee296 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/heretic.dm @@ -34,11 +34,21 @@ min_players = 20 maximum_antags_per_round = 3 -/datum/round_event_control/antagonist/solo/heretic/roundstart +/datum/round_event_control/antagonist/solo/heretic/adds + name = "Heretics" + weight = 0 + earliest_start = 0 + roundstart_cost = 15 + +/datum/round_event_control/antagonist/solo/heretic/solomode name = "Heretics" roundstart = TRUE earliest_start = 0 roundstart_cost = 15 + exclusive_roundstart_event = TRUE + price_to_buy_adds = 20 + base_antags = 1 + maximum_antags = 1 /datum/round_event_control/antagonist/solo/heretic/midround name = "Midround Heretics" diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm index 3638180d3e078..25e14464dc1bf 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/nuke_ops.dm @@ -41,6 +41,8 @@ weight = 1 roundstart_cost = 50 max_occurrences = 3 + base_antags = 2 + maximum_antags = 2 event_icon_state = "nukeops" exclusive_roundstart_event = TRUE can_change_count = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm index 8b4984242b955..67d54dc9f0fcd 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/traitors.dm @@ -22,14 +22,25 @@ JOB_CYBORG, ) -/datum/round_event_control/antagonist/solo/traitor/roundstart +/datum/round_event_control/antagonist/solo/traitor/adds + name = "Traitors" + weight = 0 + antag_flag = ROLE_TRAITOR + antag_datum = /datum/antagonist/traitor + earliest_start = 0 SECONDS + roundstart_cost = 15 + +/datum/round_event_control/antagonist/solo/traitor/solomode name = "Traitors" antag_flag = ROLE_TRAITOR antag_datum = /datum/antagonist/traitor roundstart = TRUE earliest_start = 0 SECONDS + base_antags = 1 maximum_antags = 1 roundstart_cost = 15 + exclusive_roundstart_event = TRUE + price_to_buy_adds = 20 /datum/round_event_control/antagonist/solo/traitor/midround name = "Sleeper Agents (Traitors)" diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm index 27f4b97a766cc..91f5a5ffdd769 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/alien_infestation.dm @@ -73,10 +73,12 @@ var/list/weighted_candidates = return_antag_weight(candidates) var/spawned_count = 0 - while(length(weighted_candidates) && spawned_count < antag_count) + var/failed_retries = 0 + while(length(weighted_candidates) && spawned_count < antag_count && failed_retries <= STORYTELLER_MAXIMUM_RETRIES) var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + failed_retries++ continue spawned_count++ diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm index eccaa1d3fb8d2..0c0f8b7336688 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/nuke_ops.dm @@ -129,10 +129,12 @@ var/list/weighted_candidates = return_antag_weight(candidates) var/spawned_count = 0 - while(length(weighted_candidates) && spawned_count < antag_count) + var/failed_retries = 0 + while(length(weighted_candidates) && spawned_count < antag_count && failed_retries < STORYTELLER_MAXIMUM_RETRIES) var/candidate_ckey = pick_n_take_weighted(weighted_candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + failed_retries++ continue var/mob/candidate = candidate_client.mob diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm index c36af8f0aad6b..2d36893eb294c 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/paradox_clone.dm @@ -1,4 +1,3 @@ -/* /datum/round_event_control/antagonist/solo/from_ghosts/paradox_clone name = "Paradox Clone" tags = list(TAG_OUTSIDER_ANTAG, TAG_SPOOKY, TAG_TARGETED) @@ -16,7 +15,7 @@ required_enemies = 2 weight = 6 max_occurrences = 2 - prompted_picking = FALSE + prompted_picking = TRUE /datum/round_event/antagonist/solo/ghost/paradox_clone var/list/possible_spawns = list() ///places the antag can spawn @@ -48,16 +47,19 @@ "Would you like to be a paradox clone?", check_jobban = ROLE_PARADOX_CLONE, poll_time = 20 SECONDS, - alert_pic = /datum/antagonist/paradox_clone, + alert_pic = /mob/living/carbon/human, role_name_text = "paradox clone", chat_text_border_icon = /datum/antagonist/paradox_clone, ) + var/list/weighted_candidates = return_antag_weight(candidates) var/spawned_count = 0 - while(length(candidates) && spawned_count < antag_count) - var/client/candidate_ckey = pick_n_take_weighted(candidates) + var/failed_retries = 0 + while(length(weighted_candidates) && spawned_count < antag_count && failed_retries < STORYTELLER_MAXIMUM_RETRIES) + var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) var/client/candidate_client = GLOB.directory[candidate_ckey] if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + failed_retries++ continue spawned_count++ @@ -70,6 +72,8 @@ clone_victim = find_original() new_human = duplicate_object(clone_victim, pick(possible_spawns)) + if(!candidate_ckey) + continue new_human.ckey = candidate_ckey new_human.mind.special_role = antag_flag new_human.mind.restricted_roles = restricted_roles @@ -107,5 +111,3 @@ if(possible_targets.len) return pick(possible_targets) return FALSE - -*/ diff --git a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm index c1288a35ce564..2135da3a58f7f 100644 --- a/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm +++ b/modular_bandastation/storyteller/code/event_defines/ghostset/voidwalker.dm @@ -1,6 +1,6 @@ // TG did not cook this antag into the event system. So I had to make my own -/* + /datum/round_event_control/voidwalker name = "Spawn Void Walker" typepath = /datum/round_event/ghost_role/void_walker @@ -12,7 +12,8 @@ category = EVENT_CATEGORY_ENTITIES description = "A Void Walker that drags people out of the station and into the abyss" map_flags = EVENT_SPACE_ONLY - track = EVENT_TRACK_ROLESET + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) /datum/round_event/ghost_role/void_walker minimum_required = 30 @@ -24,7 +25,7 @@ if(isnull(spawn_location)) return MAP_ERROR - var/mob/chosen_one = SSpolling.poll_ghost_candidates(check_jobban = ROLE_VOIDWALKER, role = ROLE_VOIDWALKER, alert_pic = /obj/item/cosmic_skull, jump_target = spawn_location, role_name_text = "Void Walker", amount_to_pick = 1) + var/mob/chosen_one = SSpolling.poll_ghost_candidates(check_jobban = ROLE_VOIDWALKER, role = ROLE_VOIDWALKER, alert_pic = /obj/item/void_eater, jump_target = spawn_location, role_name_text = "Void Walker", amount_to_pick = 1) if(isnull(chosen_one)) return NOT_ENOUGH_PLAYERS var/datum/mind/player_mind = new /datum/mind(chosen_one.key) @@ -40,4 +41,3 @@ walker.log_message("[key_name(walker)] was spawned as a Voidwalker by an event.", LOG_GAME) spawned_mobs += walker return SUCCESSFUL_SPAWN -*/ diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index 13be66a4c009d..f38580156d045 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -107,10 +107,6 @@ tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY, TAG_EXTERNAL, TAG_MAGICAL) checks_antag_cap = TRUE -/datum/round_event_control/voidwalker - track = EVENT_TRACK_MODERATE - tags = list(TAG_COMBAT, TAG_SPOOKY, TAG_SPACE) - /datum/round_event_control/anomaly/anomaly_vortex track = EVENT_TRACK_MODERATE tags = list(TAG_DESTRUCTIVE) diff --git a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm index 02c58c315b2e1..bd6871e6d17cf 100644 --- a/modular_bandastation/storyteller/code/event_defines/mundane/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/mundane/override.dm @@ -38,6 +38,7 @@ /datum/round_event_control/fake_virus track = EVENT_TRACK_MUNDANE tags = list(TAG_TARGETED) + weight = 0 /datum/round_event_control/falsealarm track = EVENT_TRACK_MUNDANE diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index e17ad01b25012..c21f220ef94c5 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -217,7 +217,6 @@ SUBSYSTEM_DEF(gamemode) ///Alert admins 1 minute before running and allow them to cancel or refund the event, once again. sch_event.alerted_admins = TRUE message_admins("Scheduled Event: [sch_event.event] will run in [(sch_event.start_time - world.time) / 10] seconds. (CANCEL) (REFUND)") - if(!halted_storyteller && next_storyteller_process <= world.time && current_storyteller) // We update crew information here to adjust population scalling and event thresholds for the storyteller. update_crew_infos() @@ -230,7 +229,7 @@ SUBSYSTEM_DEF(gamemode) if(pop_count < current_storyteller.min_antag_popcount && !forced) return 0 var/total_number = pop_count + (sec_crew * current_storyteller.sec_antag_modifier) - var/cap = FLOOR((total_number / current_storyteller.antag_denominator), 1) * current_storyteller.final_cap_multiplier + current_storyteller.antag_flat_cap + var/cap = FLOOR((total_number / current_storyteller.antag_denominator) * current_storyteller.final_cap_multiplier, 1) + current_storyteller.antag_flat_cap return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() @@ -692,12 +691,14 @@ SUBSYSTEM_DEF(gamemode) var/track = EVENT_TRACK_ROLESET if(forced_next_events[track]) for(var/datum/round_event_control/forced_event in forced_next_events[track]) + if(forced_event.exclusive_roundstart_event) + forced_event = exclusives_add_antags(forced_event, forced = TRUE) message_admins("Storyteller purchased and triggered forced roundstart event [forced_event].") TriggerEvent(forced_event, forced = TRUE) runned_events += "Runned forced roundstart: [forced_event.name]" - forced_next_events[track] = list() + event_track_points[track] = 0 var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) if(pop_count < current_storyteller.min_antag_popcount) @@ -733,16 +734,18 @@ SUBSYSTEM_DEF(gamemode) if(picked_event.can_spawn_event(ready_players) && (roundstart_budget >= picked_event.get_pre_cost())) roundstart_budget -= picked_event.get_pre_cost() message_admins("Storyteller purchased and triggered [picked_event] event for [picked_event.get_pre_cost()]. Left balance: [roundstart_budget].") - TriggerEvent(picked_event, forced = FALSE) - runned_events += "Runned roundstart: [picked_event.name]" - // Если первое событие эксклюзивное, то отчищаем список if(picked_event.exclusive_roundstart_event) valid_events = list() + picked_event = exclusives_add_antags(picked_event, forced = FALSE) else // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные for(var/datum/round_event_control/exclude_event as anything in valid_events) if(exclude_event.exclusive_roundstart_event) valid_events -= exclude_event + TriggerEvent(picked_event, forced = FALSE) + runned_events += "Runned roundstart: [picked_event.name]" + // Если первое событие эксклюзивное, то отчищаем список + else valid_events -= picked_event @@ -766,27 +769,42 @@ SUBSYSTEM_DEF(gamemode) if(scheduled_event.can_spawn_event(ready_players) && (roundstart_budget >= scheduled_event.get_pre_cost())) roundstart_budget -= scheduled_event.get_pre_cost() message_admins("Storyteller purchased and triggered scheduled event [scheduled_event] for [scheduled_event.get_pre_cost()]. Left balance: [roundstart_budget].") - TriggerEvent(scheduled_event, forced = FALSE) - runned_events += "Runned scheduled roundstart: [scheduled_event.name]" - scheduled_events_roleset -= scheduled_event if(scheduled_event.exclusive_roundstart_event) - scheduled_event = list() valid_events = list() + scheduled_event = exclusives_add_antags(scheduled_event, forced = FALSE) else // Если первое событие не-эксклюзивное, то удаляем из списка все эксклюзивные for(var/datum/round_event_control/exclude_event as anything in scheduled_events_roleset) if(exclude_event.exclusive_roundstart_event) scheduled_events_roleset -= exclude_event - for(var/datum/round_event_control/exclude_event as anything in valid_events) if(exclude_event.exclusive_roundstart_event) valid_events -= exclude_event + TriggerEvent(scheduled_event, forced = FALSE) + runned_events += "Runned scheduled roundstart: [scheduled_event.name]" + scheduled_events_roleset -= scheduled_event + else message_admins("Storyteller failed to purchase scheduled event [scheduled_event] for [scheduled_event.roundstart_cost]. Left balance: [roundstart_budget].") scheduled_events_roleset -= scheduled_event return valid_events +/datum/controller/subsystem/gamemode/proc/exclusives_add_antags(datum/round_event_control/antagonist/solo/exclusive_event, forced = FALSE) + //Получить бюджет + var/addition_antags = 0 + if(forced) + addition_antags = exclusive_event.forced_antags_count + else + while(exclusive_event.price_to_buy_adds <= roundstart_budget) + roundstart_budget -= exclusive_event.price_to_buy_adds + addition_antags++ + //Расчитать новый максимум и минимум антагов + exclusive_event.base_antags += addition_antags + exclusive_event.maximum_antags += addition_antags + roundstart_budget = 0 + return exclusive_event + /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_costs(track) full_sec_crew = 0 for(var/datum/job/job as anything in SSjob.all_occupations) @@ -1178,6 +1196,20 @@ SUBSYSTEM_DEF(gamemode) dat += "" dat += "" + dat += "

Runned Events:

" + dat += "" + dat += "" + dat += "" + dat += "" + even = TRUE + for(var/event as anything in runned_events) + even = !even + var/background_cl = even ? "#17191C" : "#23273C" + dat += "" + dat += "" //Name + dat += "" + dat += "
Name
[event]
" + var/datum/browser/popup = new(user, "gamemode_admin_panel", "Gamemode Panel", 670, 650) popup.set_content(dat.Join()) popup.open() @@ -1273,7 +1305,7 @@ SUBSYSTEM_DEF(gamemode) var/weight_string = "(new.[event.calculated_weight] /raw.[event.weight])" if(assoc_spawn_weight[event]) var/percent = round((event.calculated_weight / total_weight) * 100) - weight_string = "[percent]% - [weight_string]" + weight_string = "[event.calculated_on_track_weight]% - [percent]% - [weight_string]" dat += "[SSticker.HasRoundStarted() && !event.get_pre_cost() ? weight_string : "[event.get_pre_cost()]/[weight_string]"]" //Weight dat += "[event.get_href_actions()]" //Actions dat += "" diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 1baaf44c04068..8671dcc7dc36d 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -218,6 +218,9 @@ /// Calculates the weights of the events from a passed track. /datum/storyteller/proc/calculate_weights(track) var/datum/controller/subsystem/gamemode/mode = SSgamemode + var/track_weight = 0 + for(var/datum/round_event_control/event as anything in mode.event_pools[track]) + track_weight += event.weight for(var/datum/round_event_control/event as anything in mode.event_pools[track]) var/weight_total = event.weight /// Apply tag multipliers if able @@ -232,3 +235,4 @@ weight_total -= event.reoccurence_penalty_multiplier * weight_total * (1 - (event_repetition_multiplier ** occurences)) /// Write it event.calculated_weight = weight_total + event.calculated_on_track_weight = weight_total/track_weight //Получить все веса всего трека и разделить на количество событий в треке From ccd86cf9aaa0f4f6cc383637af90083b38cd52f6 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 1 Feb 2025 02:14:51 +0300 Subject: [PATCH 134/135] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0=D1=80=D1=82=20=D0=BC=D0=BD?= =?UTF-8?q?=D0=BE=D0=B6=D0=B8=D1=82=D0=B5=D0=BB=D1=8F,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B0=D0=B2=D0=B1=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=BB?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=20=D0=B2=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF?= =?UTF-8?q?=D1=8B,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B1=D1=80=D0=BE=D1=81=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/event_defines/_round_event_control.dm | 4 +++- .../code/event_defines/crewset/_override.dm | 1 + .../code/event_defines/crewset/blob_infection.dm | 1 + .../code/event_defines/major/override.dm | 10 ---------- .../code/event_defines/moderate/override.dm | 10 ++++++++++ .../storyteller/code/events/group/groups.dm | 5 +++++ modular_bandastation/storyteller/code/gamemode.dm | 13 +++++++++---- .../storyteller/code/storytellers/_storyteller.dm | 2 +- .../code/storytellers/storyteller_default.dm | 2 +- .../code/storytellers/storyteller_prime.dm | 2 +- 10 files changed, 32 insertions(+), 18 deletions(-) diff --git a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm index 9d6196f90e296..aa6563be86103 100644 --- a/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm +++ b/modular_bandastation/storyteller/code/event_defines/_round_event_control.dm @@ -275,7 +275,9 @@ var/decided_count = rand(base_antags, maximum_antags) var/current_cap = SSgamemode.get_antag_cap(forced_event) var/gamemode_antags_left = current_cap - SSgamemode.get_antag_count() - var/maximum_to_spawn = min(gamemode_antags_left, maximum_antags) + var/maximum_to_spawn_on_calculation = min(gamemode_antags_left, maximum_antags) + var/maximum_to_spawn_on_population = FLOOR(SSgamemode.get_correct_popcount() / denominator, 1) + var/maximum_to_spawn = min(maximum_to_spawn_on_calculation, maximum_to_spawn_on_population) var/clamped_value = clamp(decided_count, 0, maximum_to_spawn) //Maximum antags per round left to spawn //Получить уже количество антагов в раунде diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm index acc47c0ca873c..88edd216b0ff2 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/_override.dm @@ -8,3 +8,4 @@ tags = list(TAG_DESTRUCTIVE, TAG_COMBAT, TAG_EXTERNAL, TAG_ALIEN) earliest_start = 60 MINUTES checks_antag_cap = TRUE + event_group = /datum/event_group/blobs diff --git a/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm index e465b7abcaff9..1ff936b5a9aa6 100644 --- a/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm +++ b/modular_bandastation/storyteller/code/event_defines/crewset/blob_infection.dm @@ -7,6 +7,7 @@ min_players = 20 antag_datum = /datum/antagonist/blob/infection maximum_antags = 1 + event_group = /datum/event_group/blobs /datum/round_event_control/antagonist/solo/blob/midround name = "Blob infection (Blob)" diff --git a/modular_bandastation/storyteller/code/event_defines/major/override.dm b/modular_bandastation/storyteller/code/event_defines/major/override.dm index 0bd1db46da734..b84845bad652b 100644 --- a/modular_bandastation/storyteller/code/event_defines/major/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/major/override.dm @@ -14,16 +14,6 @@ track = EVENT_TRACK_MAJOR tags = list(TAG_DESTRUCTIVE, TAG_SPOOKY) -/datum/round_event_control/fugitives - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT) - checks_antag_cap = TRUE - -/datum/round_event_control/pirates - track = EVENT_TRACK_MAJOR - tags = list(TAG_COMBAT, TAG_COMMUNAL) - checks_antag_cap = TRUE - /datum/round_event_control/operative track = EVENT_TRACK_MAJOR //this is a safe guard and does not trigger normally(technically it can but not really) so no tags checks_antag_cap = TRUE diff --git a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm index f38580156d045..900612ad705dd 100644 --- a/modular_bandastation/storyteller/code/event_defines/moderate/override.dm +++ b/modular_bandastation/storyteller/code/event_defines/moderate/override.dm @@ -12,6 +12,16 @@ tags = list(TAG_COMMUNAL, TAG_SPOOKY) eng_required_power = 1 +/datum/round_event_control/fugitives + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT) + checks_antag_cap = TRUE + +/datum/round_event_control/pirates + track = EVENT_TRACK_MODERATE + tags = list(TAG_COMBAT, TAG_COMMUNAL) + checks_antag_cap = TRUE + /datum/round_event_control/ion_storm tags = list(TAG_TARGETED, TAG_ALIEN) event_group = /datum/event_group/bsod diff --git a/modular_bandastation/storyteller/code/events/group/groups.dm b/modular_bandastation/storyteller/code/events/group/groups.dm index a6952f8e0e0ec..06d8abba3d1d5 100644 --- a/modular_bandastation/storyteller/code/events/group/groups.dm +++ b/modular_bandastation/storyteller/code/events/group/groups.dm @@ -42,3 +42,8 @@ name = "Scrubber Overflows" cooldown_time = list(25 MINUTES, 45 MINUTES) max_occurrences = 2 + +/datum/event_group/blobs + name = "Blobs" + max_occurrences = 1 + cooldown_time = list(7.5 MINUTES, 20 MINUTES) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index c21f220ef94c5..23064bbc6f767 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -229,7 +229,7 @@ SUBSYSTEM_DEF(gamemode) if(pop_count < current_storyteller.min_antag_popcount && !forced) return 0 var/total_number = pop_count + (sec_crew * current_storyteller.sec_antag_modifier) - var/cap = FLOOR((total_number / current_storyteller.antag_denominator) * current_storyteller.final_cap_multiplier, 1) + current_storyteller.antag_flat_cap + var/cap = FLOOR((total_number / current_storyteller.antag_denominator) * current_storyteller.roundstart_cap_multiplier, 1) + current_storyteller.antag_flat_cap return cap /datum/controller/subsystem/gamemode/proc/get_antag_count() @@ -713,6 +713,7 @@ SUBSYSTEM_DEF(gamemode) rountstart_general_events_run(valid_events, track) message_admins("Storyteller finished to get roundstart events with points left - [roundstart_budget].") + current_storyteller.roundstart_cap_multiplier = 1 /datum/controller/subsystem/gamemode/proc/recalculate_roundstart_budget() var/pop_count = ready_players + (sec_crew * current_storyteller.sec_antag_modifier) @@ -1032,11 +1033,14 @@ SUBSYSTEM_DEF(gamemode) current_storyteller = /datum/storyteller/default //if we dont have any then we brick, lets not do that CRASH("Attempted to set an invalid storyteller type: [passed_type].") var/passed_state = FALSE + var/passed_multiplayer if (current_storyteller) passed_state = current_storyteller.round_started + passed_multiplayer = current_storyteller.roundstart_cap_multiplier current_storyteller.round_started = FALSE current_storyteller = storytellers[passed_type] current_storyteller.round_started = passed_state + current_storyteller.round_started = passed_multiplayer if(!secret_storyteller) send_to_playing_players(span_notice("Storyteller is [current_storyteller.name]!")) send_to_playing_players(span_notice("[current_storyteller.welcome_text]")) @@ -1069,10 +1073,11 @@ SUBSYSTEM_DEF(gamemode) dat += "
This value affects how many players count as low pop and makes the antag cap value to zero if it is below." dat += "
Guarantees Roundstart Roleset: [current_storyteller.guarantees_roundstart_roleset ? "TRUE" : "FALSE" ]" dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator) * cap_multiplier + addiction" - dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) * [current_storyteller.final_cap_multiplier] + [current_storyteller.antag_flat_cap]" + dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) * [SSticker.HasRoundStarted() ? current_storyteller.roundstart_cap_multiplier : ""] + [current_storyteller.antag_flat_cap]" dat += "
Sec antag modifier: [current_storyteller.sec_antag_modifier]" dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" - dat += "
Antag cap multiplier: [current_storyteller.final_cap_multiplier]" + if(!SSticker.HasRoundStarted()) + dat += "
Antag roundstart cap multiplier: [current_storyteller.roundstart_cap_multiplier]" dat += "
Antag denominator: [current_storyteller.antag_denominator]" dat += "
This affects how many antagonist can system spawn." dat += "
" @@ -1400,7 +1405,7 @@ SUBSYSTEM_DEF(gamemode) if(isnull(new_value) || new_value < 0) return message_admins("[key_name_admin(usr)] set basic storyteller cap multiplier to [new_value].") - current_storyteller.final_cap_multiplier = new_value + current_storyteller.roundstart_cap_multiplier = new_value if("vars_guarante_roundstart") var/new_value = !current_storyteller.guarantees_roundstart_roleset message_admins("[key_name_admin(usr)] set basic storyteller multiplier to [new_value].") diff --git a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm index 8671dcc7dc36d..e814d17395ff9 100644 --- a/modular_bandastation/storyteller/code/storytellers/_storyteller.dm +++ b/modular_bandastation/storyteller/code/storytellers/_storyteller.dm @@ -81,7 +81,7 @@ ///Список событий на исключение var/list/exclude_events = list() ///Финальный множитель антаг-капа (до ручного добавления) - var/final_cap_multiplier = 1 + var/roundstart_cap_multiplier = 1 /datum/storyteller/process(seconds_per_tick) if(!round_started || disable_distribution) // we are differing roundstarted ones until base roundstart so we can get cooler stuff diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm index d086e64d4531c..93036b1bbfe80 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_default.dm @@ -4,4 +4,4 @@ always_votable = TRUE welcome_text = "I am not Randy!" weight = 6 - final_cap_multiplier = 0.7 + roundstart_cap_multiplier = 0.7 diff --git a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm index 89fbe60df88f8..9ca170d9462ad 100644 --- a/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm +++ b/modular_bandastation/storyteller/code/storytellers/storyteller_prime.dm @@ -19,4 +19,4 @@ /datum/round_event_control/stray_cargo/syndicate, ) antag_denominator = 15 - final_cap_multiplier = 0.7 + roundstart_cap_multiplier = 0.7 From cace563bc1177cf8126d7bbcb3c2056ecd936db4 Mon Sep 17 00:00:00 2001 From: KageIIte Date: Sat, 1 Feb 2025 02:35:24 +0300 Subject: [PATCH 135/135] =?UTF-8?q?=D0=A3=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=20=D0=BC=D0=BD=D0=BE=D0=B6=D0=B8=D1=82=D0=B5=D0=BB=D1=8F?= =?UTF-8?q?,=20=D0=B5=D1=81=D0=BB=D0=B8=20=D1=80=D0=B0=D1=83=D0=BD=D0=B4?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=81=D1=8F,=20=D0=BB=D0=B5?= =?UTF-8?q?=D0=B3=D0=BA=D0=B8=D0=B9=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modular_bandastation/storyteller/code/gamemode.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modular_bandastation/storyteller/code/gamemode.dm b/modular_bandastation/storyteller/code/gamemode.dm index 23064bbc6f767..86863b41b0593 100644 --- a/modular_bandastation/storyteller/code/gamemode.dm +++ b/modular_bandastation/storyteller/code/gamemode.dm @@ -1070,16 +1070,16 @@ SUBSYSTEM_DEF(gamemode) dat += "
Storyteller Basic Variables:" dat += "
Storyteller Antag Low pop:[current_storyteller.min_antag_popcount]" - dat += "
This value affects how many players count as low pop and makes the antag cap value to zero if it is below." + dat += "
Это значение устанавливает то, сколько игроков считается минимально-необходимым для спавна антагонистов" dat += "
Guarantees Roundstart Roleset: [current_storyteller.guarantees_roundstart_roleset ? "TRUE" : "FALSE" ]" - dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator) * cap_multiplier + addiction" - dat += "
Storyteller Antag Cap result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator]) * [SSticker.HasRoundStarted() ? current_storyteller.roundstart_cap_multiplier : ""] + [current_storyteller.antag_flat_cap]" + dat += "
Storyteller Antag Cap Formula: floor((pop_count + secs * sec_antag_modifier) / denominator)[!SSticker.HasRoundStarted() ? " * roundstart cap multiplier" : ""] + addiction" + dat += "
Storyteller Antag Cap Result: floor(([get_correct_popcount()] + [sec_crew] * [current_storyteller.sec_antag_modifier]) / [current_storyteller.antag_denominator])[!SSticker.HasRoundStarted() ? " * [current_storyteller.roundstart_cap_multiplier]" : ""] + [current_storyteller.antag_flat_cap]" dat += "
Sec antag modifier: [current_storyteller.sec_antag_modifier]" dat += "
Antag addiction: [current_storyteller.antag_flat_cap]" if(!SSticker.HasRoundStarted()) dat += "
Antag roundstart cap multiplier: [current_storyteller.roundstart_cap_multiplier]" dat += "
Antag denominator: [current_storyteller.antag_denominator]" - dat += "
This affects how many antagonist can system spawn." + dat += "
Эта настройка влияет на то, сколько антагонистов может заспавниться максимум на 1 члена экипажа." dat += "
" if(!SSticker.HasRoundStarted())