diff --git a/code/__DEFINES/~ff_defines/dynamic.dm b/code/__DEFINES/~ff_defines/dynamic.dm new file mode 100644 index 00000000000..622b7d6e79a --- /dev/null +++ b/code/__DEFINES/~ff_defines/dynamic.dm @@ -0,0 +1,12 @@ + +// Названия типов раунда +/// Обычная зеленая смена, экста +#define ROUND_LIGHT_SHIFT_STRING "Green Shift" +/// Обычная смена, 50% между Yellow Star и Red Star +#define ROUND_MID_SHIFT_STRING "Blue Shift" +/// Black Star +#define ROUND_HEAVY_SHIFT_STRING "Red Shift" +/// Midnight Sun +#define ROUND_TOTALLY_HELL_SHIFT_STRING "TOTALLY HELL" + +GLOBAL_VAR(shift_intensity_level) diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index 77bc951761e..e08eb0c43f0 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -613,6 +613,7 @@ SUBSYSTEM_DEF(dynamic) if(num_dead + num_alive <= 0) return 0 + /* // FLUFFY FRONTIER EDIT START - dynamic changes - ORIGINAL: chance += 100 - (200 * (num_dead / (num_alive + num_dead))) if(num_antags < 0) chance += 50 @@ -620,6 +621,13 @@ SUBSYSTEM_DEF(dynamic) // Reduced chance before lights start if(!COOLDOWN_FINISHED(src, light_ruleset_start)) chance *= 0.2 + */ + // У нас мало людей с включенными префами на антагов, поэтому каждый подобный человек на вес золота и ваниальная формула не подходит + var/num_sec_alive = length(SSjob.get_living_sec()) + chance = clamp(100 - 40 * (2 * num_antags - num_sec_alive), 0, 100) + if(num_antags <= 0) + chance = 100 + // FLUFFY FRONTIER EDIT END return chance diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 0bb5e2c4f8e..6b130aeebeb 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -72,6 +72,20 @@ SUBSYSTEM_DEF(statpanels) ) // NOVA EDIT CHANGE END + // FLUFFY FRONTIER ADDITION START - shift intensity system + if(!isnull(GLOB.shift_intensity_level)) + global_data += list( + " ", + "Shift Intensity: [GLOB.shift_intensity_level]", + " ", + ) + else if(istype(SSvote.current_vote, /datum/vote/shift_intensity)) + global_data += list( + " ", + "Shift Intensity: Voting in progress", + " ", + ) + // FLUFFY FRONTIER ADDITION END if(SSshuttle.emergency) var/ETA = SSshuttle.emergency.getModeStr() if(ETA) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 96139298d0c..658d95f168c 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -61,4 +61,11 @@ if(SSticker.current_state < GAME_STATE_SETTING_UP) var/tl = SSticker.GetTimeLeft() to_chat(src, "Please set up your character and select \"Ready\". The game will start [tl > 0 ? "in about [DisplayTimeText(tl)]" : "soon"].") + // FLUFFY FRONTIER ADDITION START - shift intensity system + if(istype(SSvote.current_vote, /datum/vote/shift_intensity)) + to_chat(src, custom_boxed_message("purple_box center", span_infoplain( + "[span_bold("Shift intensity vote is in progress right now")]
\ + Type vote or click here to place your votes.\n\ + You have [DisplayTimeText(SSvote.current_vote.time_remaining SECONDS)] to vote.
"))) + // FLUFFY FRONTIER ADDITION END diff --git a/config/admins.txt b/config/admins.txt index 0fe8baadb78..e52730bb5ec 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -4,7 +4,7 @@ #Ranks will match to those with the same name in admin_ranks.txt, if a match isn't found the user won't be adminned. #If SQL-based admin loading is enabled, admins listed here will always be loaded first and will override any duplicate entries in the database. -Optimumtact = Host +Comka = Host LemonInTheDark = Host CitrusGender = Game Master NewSta = Game Master diff --git a/config/config.txt b/config/config.txt index 7027e9fd8e2..432a9248c89 100644 --- a/config/config.txt +++ b/config/config.txt @@ -10,6 +10,7 @@ $include interviews.txt $include lua.txt $include auxtools.txt $include map_vote.txt +$include tff/config_tff.txt # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: diff --git a/config/dynamic.toml b/config/dynamic.toml index 73f3d03948b..d116ad88031 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -56,7 +56,7 @@ ruleset_type_settings.latejoin.low = 0 ruleset_type_settings.latejoin.high = 1 ruleset_type_settings.latejoin.half_range_pop_threshold = 25 ruleset_type_settings.latejoin.full_range_pop_threshold = 40 -ruleset_type_settings.latejoin.time_threshold = 5 +ruleset_type_settings.latejoin.time_threshold = 0.1 ruleset_type_settings.latejoin.execution_cooldown_low = 10 ruleset_type_settings.latejoin.execution_cooldown_high = 20 @@ -87,7 +87,7 @@ ruleset_type_settings.latejoin.low = 1 ruleset_type_settings.latejoin.high = 2 ruleset_type_settings.latejoin.half_range_pop_threshold = 25 ruleset_type_settings.latejoin.full_range_pop_threshold = 40 -ruleset_type_settings.latejoin.time_threshold = 5 +ruleset_type_settings.latejoin.time_threshold = 0.1 ruleset_type_settings.latejoin.execution_cooldown_low = 10 ruleset_type_settings.latejoin.execution_cooldown_high = 20 @@ -118,7 +118,7 @@ ruleset_type_settings.latejoin.low = 1 ruleset_type_settings.latejoin.high = 3 ruleset_type_settings.latejoin.half_range_pop_threshold = 25 ruleset_type_settings.latejoin.full_range_pop_threshold = 40 -ruleset_type_settings.latejoin.time_threshold = 5 +ruleset_type_settings.latejoin.time_threshold = 0.1 ruleset_type_settings.latejoin.execution_cooldown_low = 10 ruleset_type_settings.latejoin.execution_cooldown_high = 20 @@ -149,7 +149,7 @@ ruleset_type_settings.latejoin.low = 2 ruleset_type_settings.latejoin.high = 3 ruleset_type_settings.latejoin.half_range_pop_threshold = 25 ruleset_type_settings.latejoin.full_range_pop_threshold = 40 -ruleset_type_settings.latejoin.time_threshold = 5 +ruleset_type_settings.latejoin.time_threshold = 0.1 ruleset_type_settings.latejoin.execution_cooldown_low = 10 ruleset_type_settings.latejoin.execution_cooldown_high = 20 diff --git a/config/tff/config_tff.txt b/config/tff/config_tff.txt new file mode 100644 index 00000000000..5a6db71d154 --- /dev/null +++ b/config/tff/config_tff.txt @@ -0,0 +1,11 @@ +## Включает систему голосования за тип раунда +#SHIFT_INTENSITY + +## Включает возможность начать голосование за тип раунда +#ALLOW_SHIFT_INTENSITY_VOTE + +## Время до начала раунда (в децисекундах), в которое запускается голосование за тип раунда +SHIFT_INTENSITY_VOTE_STARTTIME 2000 + +## Количество игроков, необходимое для старта голосования за тип раунда +SHIFT_INTENSITY_VOTE_MINIMUM_PLAYERS 20 diff --git a/tff_modular/modules/shift_intensity/shift_intensity.dm b/tff_modular/modules/shift_intensity/shift_intensity.dm new file mode 100644 index 00000000000..9384b63110e --- /dev/null +++ b/tff_modular/modules/shift_intensity/shift_intensity.dm @@ -0,0 +1,78 @@ +#define LAST_ATTEMPT_DEADLINE 120 SECONDS + +SUBSYSTEM_DEF(shift_intensity) + name = "Shift Intensity Vote" + flags = SS_BACKGROUND + runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP + dependencies = list( + /datum/controller/subsystem/vote, + ) + + /// Время до начала раунда, после которого подсистема будет пытаться запустить голосование + var/start_time + /// Количество игроков, необходимое для старта голосования + var/minimum_players + /// Будет ли в воуте самый сложный тип смены + var/enable_hell_shift = FALSE + +/datum/controller/subsystem/shift_intensity/Initialize() + start_time = CONFIG_GET(number/shift_intensity_vote_starttime) + minimum_players = CONFIG_GET(number/shift_intensity_vote_minimum_players) + + if(!CONFIG_GET(flag/shift_intensity)) + can_fire = FALSE + return SS_INIT_NO_NEED + + log_game("SSshift_intensity was enabled in config. Vote will start [start_time/10] seconds before the start of the round.") + message_admins("SSshift_intensity was enabled in config. Vote will start [start_time/10] seconds before the start of the round.") + return SS_INIT_SUCCESS + +/datum/controller/subsystem/shift_intensity/Recover() + start_time = SSshift_intensity.start_time + minimum_players = SSshift_intensity.minimum_players + +/datum/controller/subsystem/shift_intensity/fire() + if(SSticker.current_state > GAME_STATE_PREGAME) + can_fire = FALSE + return + + if(!isnull(SSvote.current_vote)) + if(istype(SSvote.current_vote, /datum/vote/shift_intensity)) + can_fire = FALSE + return + + if(SSticker.GetTimeLeft() <= start_time) + if(SSticker.totalPlayers < minimum_players) + if(SSticker.GetTimeLeft() > LAST_ATTEMPT_DEADLINE) // Будет пытаться начать воут вплоть до 120 секунд доя старта раунда и потом отключится, если все еще не набрались люди + return + + can_fire = FALSE + log_game("The vote for shift intensity was cancelled due to insufficient number of players.") + message_admins("The vote for shift intensity was cancelled due to insufficient number of players.") + return + + can_fire = FALSE + SSvote.initiate_vote(/datum/vote/shift_intensity, "server", forced = TRUE) + +/datum/controller/subsystem/shift_intensity/proc/set_intensity(intensity_level) + + switch(intensity_level) + if(ROUND_LIGHT_SHIFT_STRING) + SSdynamic.set_tier(/datum/dynamic_tier/greenshift) + if(ROUND_MID_SHIFT_STRING) + if(prob(50)) + SSdynamic.set_tier(/datum/dynamic_tier/low) + else + SSdynamic.set_tier(/datum/dynamic_tier/lowmedium) + if(ROUND_HEAVY_SHIFT_STRING) + SSdynamic.set_tier(/datum/dynamic_tier/mediumhigh) + if(ROUND_TOTALLY_HELL_SHIFT_STRING) + SSdynamic.set_tier(/datum/dynamic_tier/high) + + GLOB.shift_intensity_level = intensity_level + + message_admins("The type of round will be: [intensity_level].") + log_admin("The type of round will be: [intensity_level].") + + +#undef LAST_ATTEMPT_DEADLINE diff --git a/tff_modular/modules/shift_intensity/shift_intensity_config.dm b/tff_modular/modules/shift_intensity/shift_intensity_config.dm new file mode 100644 index 00000000000..99daa4e9c95 --- /dev/null +++ b/tff_modular/modules/shift_intensity/shift_intensity_config.dm @@ -0,0 +1,14 @@ +/// Определяет, работает ли [SSshift_intensity] или нет +/datum/config_entry/flag/shift_intensity + +/// Определяет, может ли голосование за [SSshift_intensity] быть начато кем-либо или нет +/datum/config_entry/flag/allow_shift_intensity_vote + +/// Время (в децисекундах) до начала раунда, после которого SSshiftcolorvote будет пытаться запустить голосование +/datum/config_entry/number/shift_intensity_vote_starttime + min_val = 50 + default = 1000 + +/// Количество игроков, необходимое для старта голосования +/datum/config_entry/number/shift_intensity_vote_minimum_players + default = 20 diff --git a/tff_modular/modules/shift_intensity/shift_intensity_toggle.dm b/tff_modular/modules/shift_intensity/shift_intensity_toggle.dm new file mode 100644 index 00000000000..ad6bdbb2c26 --- /dev/null +++ b/tff_modular/modules/shift_intensity/shift_intensity_toggle.dm @@ -0,0 +1,11 @@ +ADMIN_VERB(disable_shift_intensity, R_ADMIN, "Disable Intensity Vote", "Turn Off the Shift Intensity Vote.", ADMIN_CATEGORY_SERVER) + SSshift_intensity.can_fire = 0; + if(istype(SSvote.current_vote, /datum/vote/shift_intensity)) + SSvote.reset() + log_admin("[key_name(user)] turned off Shift Intensity Vote.") + message_admins("[key_name_admin(user)] turned off Shift Intensity Vote.") + +ADMIN_VERB(toggle_hell_intensity, R_ADMIN, "Toggle Hell Intensity", "Toggle Hell option in Shift Intensity Vote.", ADMIN_CATEGORY_SERVER) + SSshift_intensity.enable_hell_shift = !SSshift_intensity.enable_hell_shift + log_admin("[key_name(user)] turned [SSshift_intensity.enable_hell_shift ? "On" : "Off"] Hell option in Shift Intensity Vote.") + message_admins("[key_name_admin(user)] turned [SSshift_intensity.enable_hell_shift ? "On" : "Off"] Hell option in Shift Intensity Vote.") diff --git a/tff_modular/modules/shift_intensity/shift_intensity_vote.dm b/tff_modular/modules/shift_intensity/shift_intensity_vote.dm new file mode 100644 index 00000000000..a99e25ef2bc --- /dev/null +++ b/tff_modular/modules/shift_intensity/shift_intensity_vote.dm @@ -0,0 +1,58 @@ +/datum/vote/shift_intensity + name = "Intensity" + default_choices = list( + ROUND_LIGHT_SHIFT_STRING, + ROUND_MID_SHIFT_STRING, + ROUND_HEAVY_SHIFT_STRING, + ) + +/datum/vote/shift_intensity/toggle_votable() + CONFIG_SET(flag/allow_shift_intensity_vote, !CONFIG_GET(flag/allow_shift_intensity_vote)) + +/datum/vote/shift_intensity/is_config_enabled() + return CONFIG_GET(flag/shift_intensity) && CONFIG_GET(flag/allow_shift_intensity_vote) + +/datum/vote/shift_intensity/can_be_initiated(forced) + . = ..() + if(. != VOTE_AVAILABLE) + return + + if(!forced && SSticker.current_state != GAME_STATE_PREGAME) + return "It's too late for that, the round is already starting." + + return VOTE_AVAILABLE + +/datum/vote/shift_intensity/initiate_vote(initiator, duration) + . = ..() + // Необходимо продлить время до старта раунда, если до него меньше 90 секунд (60 секунд сам воут + 30 на то, чтобы игроки успели понять тип раунда) + if(SSticker.GetTimeLeft() < 90 SECONDS) + SSticker.SetTimeLeft(90 SECONDS) + +/datum/vote/shift_intensity/create_vote(mob/vote_creator) + if(SSshift_intensity.enable_hell_shift) + default_choices += ROUND_TOTALLY_HELL_SHIFT_STRING + return ..() + +/datum/vote/shift_intensity/tiebreaker(list/winners) + // Если никто не проголосовал - смена будет *обычная* + if(choices_by_ckey.len == 0) + return ROUND_LIGHT_SHIFT_STRING + // Если ничья между грином и редом - будет блю + if((ROUND_LIGHT_SHIFT_STRING in winners) && (ROUND_HEAVY_SHIFT_STRING in winners)) + return ROUND_MID_SHIFT_STRING + return ..() + +/datum/vote/shift_intensity/finalize_vote(winning_option) + if(SSticker.current_state != GAME_STATE_PREGAME) + message_admins("Shift type vote ended after the round started. No changes to the round type.") + log_admin("Shift type vote ended after the round started. No changes to the round type.") + return + + message_admins("Shift type vote ended.") + log_admin("Shift type vote ended.") + + switch(winning_option) + if(ROUND_LIGHT_SHIFT_STRING, ROUND_MID_SHIFT_STRING, ROUND_HEAVY_SHIFT_STRING, ROUND_TOTALLY_HELL_SHIFT_STRING) + SSshift_intensity.set_intensity(winning_option) + else + CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])") diff --git a/tgstation.dme b/tgstation.dme index ac4da0f72a0..8d92952db61 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -413,6 +413,7 @@ #include "code\__DEFINES\traits\sources.dm" #include "code\__DEFINES\~ff_defines\barsigns.dm" #include "code\__DEFINES\~ff_defines\DNA.dm" +#include "code\__DEFINES\~ff_defines\dynamic.dm" #include "code\__DEFINES\~ff_defines\flavor_misc.dm" #include "code\__DEFINES\~ff_defines\nabber_clothes_pathes.dm" #include "code\__DEFINES\~ff_defines\say.dm" @@ -9468,6 +9469,10 @@ #include "tff_modular\modules\shadekin\organs\_eyes.dm" #include "tff_modular\modules\shadekin\sprites\ears.dm" #include "tff_modular\modules\shadekin\sprites\tails.dm" +#include "tff_modular\modules\shift_intensity\shift_intensity.dm" +#include "tff_modular\modules\shift_intensity\shift_intensity_config.dm" +#include "tff_modular\modules\shift_intensity\shift_intensity_toggle.dm" +#include "tff_modular\modules\shift_intensity\shift_intensity_vote.dm" #include "tff_modular\modules\silicon_laws_tweaks\code\upload.dm" #include "tff_modular\modules\snowfall\snowfall.dm" #include "tff_modular\modules\spiderbuff\giant_spiders.dm"