diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index 39b5d7b222445..0eb8ae7d10837 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -70,6 +70,11 @@ jobs: - name: Ticked File Enforcement if: steps.linter-setup.conclusion == 'success' && !cancelled() run: | + bash tools/ci/check_filedirs.sh tgstation.dme + bash tools/ci/check_changelogs.sh + bash tools/ci/check_grep.sh + bash tools/ci/check_misc.sh + bash tools/bandastation_check_grep.sh # BANDASTATION EDIT ADDITION - checking modular_bandastation code tools/bootstrap/python tools/ticked_file_enforcement/ticked_file_enforcement.py < tools/ticked_file_enforcement/schemas/tgstation_dme.json tools/bootstrap/python tools/ticked_file_enforcement/ticked_file_enforcement.py < tools/ticked_file_enforcement/schemas/unit_tests.json - name: Check Define Sanity diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7639f1b6a07fe..393bdf9d08737 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -178,12 +178,12 @@ switch(text2ascii(char)) // A .. Z - if(65 to 90) //Uppercase Letters + if(65 to 90, 1040 to 1071, 1025) //Uppercase Letters //SS220 EDIT CHANGE - Cyrillic Fixes number_of_alphanumeric++ last_char_group = LETTERS_DETECTED // a .. z - if(97 to 122) //Lowercase Letters + if(97 to 122, 1072 to 1103, 1105) //Lowercase Letters //SS220 EDIT CHANGE - Cyrillic Fixes if(last_char_group == NO_CHARS_DETECTED || last_char_group == SPACES_DETECTED || cap_after_symbols && last_char_group == SYMBOLS_DETECTED) //start of a word char = uppertext(char) number_of_alphanumeric++ diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 2a4854c37b858..99989e5cb849e 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -98,7 +98,7 @@ #endif #ifndef PRELOAD_RSC //set to: -#define PRELOAD_RSC 1 // 0 to allow using external resources or on-demand behaviour; +#define PRELOAD_RSC 0 // 0 to allow using external resources or on-demand behaviour; BANDASTATION EDIT - Original: 1 #endif // 1 to use the default behaviour; // 2 for preloading absolutely everything; diff --git a/code/modules/unit_tests/barsigns.dm b/code/modules/unit_tests/barsigns.dm index 7058dd5346dc9..a7223319f8e62 100644 --- a/code/modules/unit_tests/barsigns.dm +++ b/code/modules/unit_tests/barsigns.dm @@ -7,12 +7,14 @@ var/obj/machinery/barsign_type = /obj/machinery/barsign var/icon/barsign_icon = initial(barsign_type.icon) var/list/barsign_icon_states = icon_states(barsign_icon) + var/icon/barsign_icon_ss220 = 'modular_bandastation/barsigns/icons/barsigns.dmi' // BANDASTATION EDIT Barsigns + var/list/barsign_icon_states_ss220 = icon_states(barsign_icon_ss220) // Check every datum real bar sign for(var/sign_type in (subtypesof(/datum/barsign) - /datum/barsign/hiddensigns)) var/datum/barsign/sign = new sign_type() - if(!(sign.icon in barsign_icon_states)) + if(!(sign.icon in barsign_icon_states) && !(sign.icon in barsign_icon_states_ss220)) // BANDASTATION EDIT Barsigns TEST_FAIL("Icon state for [sign_type] does not exist in [barsign_icon].") /** diff --git a/config/bandastation/bandastation_config.txt b/config/bandastation/bandastation_config.txt new file mode 100644 index 0000000000000..bb67611772896 --- /dev/null +++ b/config/bandastation/bandastation_config.txt @@ -0,0 +1,4 @@ +## Text-to-speech +#TTS_TOKEN_SILERO mytoken +#TTS_ENABLED +#TTS_CACHE diff --git a/config/config.txt b/config/config.txt index a26b6938496f0..3190a7ae9ce25 100644 --- a/config/config.txt +++ b/config/config.txt @@ -5,6 +5,7 @@ $include dbconfig.txt $include comms.txt $include logging.txt $include resources.txt +$include bandastation/bandastation_config.txt $include interviews.txt $include lua.txt $include auxtools.txt diff --git a/config/dynamic.json b/config/dynamic.json index a4a1eb7ebdbfb..bea440d1850ae 100644 --- a/config/dynamic.json +++ b/config/dynamic.json @@ -4,7 +4,6 @@ "Traitors": { "cost": 8, "scaling_cost": 9, - "weight": 0, "required_candidates": 1, "minimum_required_age": 0, "requirements": [ @@ -40,89 +39,68 @@ }, "Changelings": { - "weight": 0 }, "Heretics": { - "weight": 0 }, "Wizard": { - "weight": 0 }, "Blood Cult": { - "weight": 0 }, "Nuclear Emergency": { - "weight": 0 }, "Revolution": { - "weight": 0 } }, "Midround": { "Syndicate Sleeper Agent": { - "weight": 0 }, "Malfunctioning AI": { - "weight": 0 }, "Wizard": { - "weight": 0 }, "Nuclear Assault": { - "weight": 0 }, "Blob": { - "weight": 0 }, "Blob Infection": { - "weight": 0 }, "Alien Infestation": { - "weight": 0 }, "Nightmare": { - "weight": 0 }, "Space Dragon": { - "weight": 0 }, "Abductors": { - "weight": 0 }, "Space Ninja": { - "weight": 0 }, "Spiders": { - "weight": 0 }, "Revenant": { - "weight": 0 }, "Sentient Disease": { - "weight": 0 }, "Space Pirates": { - "weight": 0 }, "Obsessed": { @@ -130,29 +108,23 @@ }, "Space Changeling": { - "weight": 0 }, "Paradox Clone": { - "weight": 0 } }, "Latejoin": { "Syndicate Infiltrator": { - "weight": 0 }, "Provocateur": { - "weight": 0 }, "Heretic Smuggler": { - "weight": 0 }, "Stowaway Changeling": { - "weight": 0 } }, diff --git a/config/game_options.txt b/config/game_options.txt index ae90dcb56b91e..7d0a22a01b263 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -33,8 +33,8 @@ COMMENDATION_PERCENT_POLL 0.05 ## To speed things up make the number negative, to slow things down, make the number positive. ## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. -RUN_DELAY 1.5 -WALK_DELAY 4 +RUN_DELAY 2.5 +WALK_DELAY 5 ## The variables below affect the movement of specific mob types. THIS AFFECTS ALL SUBTYPES OF THE TYPE YOU CHOOSE! ## Entries completely override all subtypes. Later entries have precedence over earlier entries. @@ -44,8 +44,8 @@ WALK_DELAY 4 ##MULTIPLICATIVE_MOVESPEED /mob/living/silicon/robot 0 ##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/alien 0 ##MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal/slime 0 -MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal 0 -MULTIPLICATIVE_MOVESPEED /mob/living/basic 0 +##MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal 0 +##MULTIPLICATIVE_MOVESPEED /mob/living/basic 0 ## NAMES ### @@ -84,7 +84,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 @@ -158,7 +158,7 @@ ALLOW_AI_MULTICAM ## Secborg ### ## Uncomment to prevent the security cyborg model from being chosen -#DISABLE_SECBORG +DISABLE_SECBORG ## Peacekeeper Borg ### ## Uncomment to prevent the peacekeeper cyborg model from being chosen @@ -167,7 +167,7 @@ ALLOW_AI_MULTICAM ## AWAY MISSIONS ### ## Uncomment to load one of the missions from awaymissionconfig.txt or away_missions/ at roundstart. -#ROUNDSTART_AWAY +ROUNDSTART_AWAY ## How long the delay is before the Away Mission gate opens. Default is half an hour. ## 600 is one minute. @@ -193,28 +193,28 @@ MINIMAL_ACCESS_THRESHOLD 20 #ASSISTANTS_HAVE_MAINT_ACCESS ## Uncoment to give security maint access. Note that if you dectivate JOBS_HAVE_MINIMAL_ACCESS security already gets maint from that. -#SECURITY_HAS_MAINT_ACCESS +SECURITY_HAS_MAINT_ACCESS ## Uncomment to give everyone maint access. #EVERYONE_HAS_MAINT_ACCESS ## Comment this out this to make security officers spawn in departmental security posts -#SEC_START_BRIG +SEC_START_BRIG ## This variable is how you may configure "Scaling Access" for Departmental Security Officers. ## Set to 0/commented out for "off", Departmental Security Officers will never get additional room-specific access (beyond general departmental doors). ## Set to 1 if you want to enable "Scaling Access", where Departmental Security Officers will get access to most rooms within a department depending on how many security officers there are relative to the number of people on a station. ## Set to 2 if you want Departmental Security Officers to always have access to all rooms in a department. -DEPSEC_ACCESS_LEVEL 1 +DEPSEC_ACCESS_LEVEL 2 ## GHOST INTERACTION ### ## Uncomment to let ghosts spin chairs. You may be wondering why this is a config option. Don't ask. -#GHOST_INTERACTION +GHOST_INTERACTION ## NEAR-DEATH EXPERIENCE ### ## Comment this out to disable mobs hearing ghosts when unconscious and very close to death -NEAR_DEATH_EXPERIENCE +#NEAR_DEATH_EXPERIENCE ## NON-VOCAL SILICONS ### ## Uncomment these to stop the AI, or cyborgs, from having vocal communication. @@ -230,7 +230,7 @@ NEAR_DEATH_EXPERIENCE ## Set to 4 for "specified", silicons will start with an existing lawset. (If no specified lawset is identified, the AI will spawn with asimov.) -DEFAULT_LAWS 0 +DEFAULT_LAWS 4 ## SILICON ASIMOV SUPERIORITY OVERRIDE ### ## This makes "Asimov Superiority" show up as a perk for humans in the character creation menu even if asimov is not the default lawset, such as when used with asimov++ @@ -243,7 +243,7 @@ DEFAULT_LAWS 0 ## See datums\ai_laws.dm for the full law lists ## IE, SPECIFIED_LAWS asimovpp, SPECIFIED_LAWS robocop, SPECIFIED_LAWS antimov -SPECIFIED_LAWS asimovpp +SPECIFIED_LAWS nt_default ## RANDOM LAWS ## ## ------------------------------------------------------------------------------------------ @@ -256,6 +256,7 @@ RANDOM_LAWS asimovpp RANDOM_LAWS paladin RANDOM_LAWS robocop RANDOM_LAWS corporate +RANDOM_LAWS nt_default ## Quirky laws. Shouldn't cause too much harm #RANDOM_LAWS hippocratic @@ -297,6 +298,7 @@ LAW_WEIGHT liveandletlive,5 LAW_WEIGHT peacekeeper,5 LAW_WEIGHT ten_commandments,5 LAW_WEIGHT nutimov,5 +LAW_WEIGHT nt_default,5 ## Quirky laws. Shouldn't cause too much harm LAW_WEIGHT reporter,3 @@ -485,7 +487,7 @@ MICE_ROUNDSTART 10 ROUNDSTART_TRAITS ## Uncomment to disable human moods. -#DISABLE_HUMAN_MOOD +DISABLE_HUMAN_MOOD ## Enable night shifts #ENABLE_NIGHT_SHIFTS diff --git a/interface/skin.dmf b/interface/skin.dmf index ede8e37684078..b3e581d344f52 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -111,12 +111,12 @@ window "mapwindow" size = 640x480 anchor1 = 0,0 anchor2 = 100,100 - font-family = "Grand9K Pixel" - font-size = 6pt + font-family = "Arial" + font-size = 7pt is-default = true right-click = true saved-params = "zoom;letterbox;zoom-mode" - style = ".center { text-align: center; } .maptext { font-family: 'Grand9K Pixel'; font-size: 6pt; -dm-text-outline: 1px black; color: white; line-height: 1.0; } .command_headset { font-weight: bold; } .context { font-family: 'Pixellari'; font-size: 12pt; -dm-text-outline: 1px black; } .subcontext { font-family: 'TinyUnicode'; font-size: 12pt; line-height: 0.75; } .small { font-family: 'Spess Font'; font-size: 6pt; line-height: 1.4; } .big { font-family: 'Pixellari'; font-size: 12pt; } .reallybig { font-size: 12pt; } .extremelybig { font-size: 12pt; } .greentext { color: #00FF00; font-size: 6pt; } .redtext { color: #FF0000; font-size: 6pt; } .clown { color: #FF69BF; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-family: 'Spess Font'; font-size: 6pt; line-height: 1.4; }" + style = ".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7pt; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .command_headset { font-weight: bold; } .context { font-family: 'Small Fonts'; font-size: 12pt; -dm-text-outline: 1px black; } .subcontext { font-family: 'Small Fonts'; font-size: 12pt; line-height: 0.75; } .small { font-family: 'Small Fonts'; font-size: 6pt; line-height: 1.4; } .big { font-family: 'Small Fonts'; font-size: 12pt; } .reallybig { font-size: 12pt; } .extremelybig { font-size: 12pt; } .greentext { color: #00FF00; font-size: 6pt; } .redtext { color: #FF0000; font-size: 6pt; } .clown { color: #FF69BF; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-family: 'Small Fonts'; font-size: 6pt; line-height: 1.4; }" elem "status_bar" type = LABEL pos = 0,464 diff --git a/modular_bandastation/_defines220/_defines220.dm b/modular_bandastation/_defines220/_defines220.dm new file mode 100644 index 0000000000000..89c20b6a61efd --- /dev/null +++ b/modular_bandastation/_defines220/_defines220.dm @@ -0,0 +1,4 @@ +/datum/modpack/defines220 + name = "Дефайны220" + desc = "Добавляет дефайны, которые нам нужны" + author = "larentoun" diff --git a/modular_bandastation/_defines220/_defines220.dme b/modular_bandastation/_defines220/_defines220.dme new file mode 100644 index 0000000000000..2e4cf7f6c8a23 --- /dev/null +++ b/modular_bandastation/_defines220/_defines220.dme @@ -0,0 +1,10 @@ +#include "_defines220.dm" + +#include "code/defines/keybindings.dm" +#include "code/defines/spans.dm" +#include "code/signals_mob/signals_mob_ai.dm" +#include "code/signals_mob/signals_mob_carbon.dm" +#include "code/signals_mob/signals_mob_living.dm" +#include "code/signals_mob/signals_mob_main.dm" +#include "code/signals_mob/signals_mob_silicon.dm" +#include "code/signals_mob/signals_mob_simple.dm" diff --git a/modular_bandastation/_defines220/code/defines/keybindings.dm b/modular_bandastation/_defines220/code/defines/keybindings.dm new file mode 100644 index 0000000000000..54cd3afa9f555 --- /dev/null +++ b/modular_bandastation/_defines220/code/defines/keybindings.dm @@ -0,0 +1,4 @@ +#define COMSIG_KB_MOB_PIXEL_SHIFT_DOWN "keybinding_mob_pixel_shift_down" +#define COMSIG_KB_MOB_PIXEL_SHIFT_UP "keybinding_mob_pixel_shift_up" +#define COMSIG_KB_CLIENT_LOOC_DOWN "keybinding_client_looc_down" +#define COMSIG_KB_CLIENT_WHISPER_DOWN "keybinding_client_whisper_down" diff --git a/modular_bandastation/_defines220/code/defines/spans.dm b/modular_bandastation/_defines220/code/defines/spans.dm new file mode 100644 index 0000000000000..c596abf4ba3a7 --- /dev/null +++ b/modular_bandastation/_defines220/code/defines/spans.dm @@ -0,0 +1 @@ +#define span_maptext(str) ("" + str + "") diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_ai.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_ai.dm new file mode 100644 index 0000000000000..fa7df8ae680b9 --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_ai.dm @@ -0,0 +1 @@ +// Signals for /mob/living/silicon/ai diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_carbon.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_carbon.dm new file mode 100644 index 0000000000000..ef6039c440fc8 --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_carbon.dm @@ -0,0 +1 @@ +// Signals for /mob/living/carbon diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_living.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_living.dm new file mode 100644 index 0000000000000..db4d5bdb08e8c --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_living.dm @@ -0,0 +1,9 @@ +// Signals for /mob/living + +//from base of living/set_pull_offset(): (mob/living/pull_target, grab_state) +#define COMSIG_LIVING_SET_PULL_OFFSET "living_set_pull_offset" +//from base of living/reset_pull_offsets(): (mob/living/pull_target, override) +#define COMSIG_LIVING_RESET_PULL_OFFSETS "living_reset_pull_offsets" +//from base of living/CanAllowThrough(): (atom/movable/mover, border_dir) +#define COMSIG_LIVING_CAN_ALLOW_THROUGH "living_can_allow_through" + #define COMPONENT_LIVING_PASSABLE (1<<0) diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_main.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_main.dm new file mode 100644 index 0000000000000..7aa41cead07d5 --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_main.dm @@ -0,0 +1 @@ +// Signals for /mob diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_silicon.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_silicon.dm new file mode 100644 index 0000000000000..1e776fa5270e2 --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_silicon.dm @@ -0,0 +1 @@ +// Signals for /mob/living/silicon diff --git a/modular_bandastation/_defines220/code/signals_mob/signals_mob_simple.dm b/modular_bandastation/_defines220/code/signals_mob/signals_mob_simple.dm new file mode 100644 index 0000000000000..937b109659eb5 --- /dev/null +++ b/modular_bandastation/_defines220/code/signals_mob/signals_mob_simple.dm @@ -0,0 +1 @@ +// Signals for /mob/living/simple_animal diff --git a/modular_bandastation/_helpers220/_helpers220.dm b/modular_bandastation/_helpers220/_helpers220.dm new file mode 100644 index 0000000000000..f252781a26351 --- /dev/null +++ b/modular_bandastation/_helpers220/_helpers220.dm @@ -0,0 +1,4 @@ +/datum/modpack/defines220 + name = "Хелперы220" + desc = "Добавляет хелперы, которые нам нужны" + author = "larentoun" diff --git a/modular_bandastation/_helpers220/_helpers220.dme b/modular_bandastation/_helpers220/_helpers220.dme new file mode 100644 index 0000000000000..203fab82857a2 --- /dev/null +++ b/modular_bandastation/_helpers220/_helpers220.dme @@ -0,0 +1 @@ +#include "_helpers220.dm" diff --git a/modular_bandastation/_modpack.dm b/modular_bandastation/_modpack.dm new file mode 100644 index 0000000000000..5569426fa6404 --- /dev/null +++ b/modular_bandastation/_modpack.dm @@ -0,0 +1,17 @@ +/datum/modpack + /// A string name for the modpack. Used for looking up other modpacks in init. + var/name + /// A string desc for the modpack. Can be used for modpack verb list as description. + var/desc + /// A string with authors of this modpack. + var/author + +/datum/modpack/proc/pre_initialize() + if(!name) + return "Modpack name is unset." + +/datum/modpack/proc/initialize() + return + +/datum/modpack/proc/post_initialize() + return diff --git a/modular_bandastation/_modpacks.dm b/modular_bandastation/_modpacks.dm new file mode 100644 index 0000000000000..347fcd019b6b9 --- /dev/null +++ b/modular_bandastation/_modpacks.dm @@ -0,0 +1,60 @@ +#define INIT_ORDER_MODPACKS 84 + +SUBSYSTEM_DEF(modpacks) + name = "Modpacks" + init_order = INIT_ORDER_MODPACKS + flags = SS_NO_FIRE + var/list/loaded_modpacks = list() + +/datum/controller/subsystem/modpacks/Initialize() + var/list/all_modpacks = list() + for(var/modpack in subtypesof(/datum/modpack/)) + all_modpacks.Add(new modpack) + // Pre-init and register all compiled modpacks. + for(var/datum/modpack/package as anything in all_modpacks) + var/fail_msg = package.pre_initialize() + if(QDELETED(package)) + CRASH("Modpack of type [package.type] is null or queued for deletion.") + if(fail_msg) + CRASH("Modpack [package.name] failed to pre-initialize: [fail_msg].") + if(loaded_modpacks[package.name]) + CRASH("Attempted to register duplicate modpack name [package.name].") + loaded_modpacks.Add(package) + + // Handle init and post-init (two stages in case a modpack needs to implement behavior based on the presence of other packs). + for(var/datum/modpack/package as anything in all_modpacks) + var/fail_msg = package.initialize() + if(fail_msg) + CRASH("Modpack [(istype(package) && package.name) || "Unknown"] failed to initialize: [fail_msg]") + for(var/datum/modpack/package as anything in all_modpacks) + var/fail_msg = package.post_initialize() + if(fail_msg) + CRASH("Modpack [(istype(package) && package.name) || "Unknown"] failed to post-initialize: [fail_msg]") + +/client/verb/modpacks_list() + set name = "Modpacks List" + set category = "OOC" + + if(!mob || !SSmodpacks.initialized) + return + + if(length(SSmodpacks.loaded_modpacks)) + . = "

Список модификаций



" + for(var/datum/modpack/M as anything in SSmodpacks.loaded_modpacks) + if(M.name) + . += "
" + . += "
[M.name]
" + + if(M.desc || M.author) + . += "
" + if(M.desc) + . += "
Описание: [M.desc]" + if(M.author) + . += "
Автор: [M.author]" + . += "

" + + var/datum/browser/popup = new(mob, "modpacks_list", "Список Модификаций", 480, 580) + popup.set_content(.) + popup.open() + else + to_chat(src, "Этот сервер не использует какие-либо модификации.") diff --git a/modular_bandastation/_signals220/_signals220.dm b/modular_bandastation/_signals220/_signals220.dm new file mode 100644 index 0000000000000..a7b76146fb1be --- /dev/null +++ b/modular_bandastation/_signals220/_signals220.dm @@ -0,0 +1,4 @@ +/datum/modpack/signals220 + name = "Сигналы220" + desc = "Добавляет сигналы" + author = "larentoun" diff --git a/modular_bandastation/_signals220/_signals220.dme b/modular_bandastation/_signals220/_signals220.dme new file mode 100644 index 0000000000000..26671df7a7f98 --- /dev/null +++ b/modular_bandastation/_signals220/_signals220.dme @@ -0,0 +1,8 @@ +#include "_signals220.dm" + +#include "code/signals_mob/signals_mob_ai.dm" +#include "code/signals_mob/signals_mob_carbon.dm" +#include "code/signals_mob/signals_mob_living.dm" +#include "code/signals_mob/signals_mob_main.dm" +#include "code/signals_mob/signals_mob_silicon.dm" +#include "code/signals_mob/signals_mob_simple.dm" diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_ai.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_ai.dm new file mode 100644 index 0000000000000..fa7df8ae680b9 --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_ai.dm @@ -0,0 +1 @@ +// Signals for /mob/living/silicon/ai diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_carbon.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_carbon.dm new file mode 100644 index 0000000000000..ef6039c440fc8 --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_carbon.dm @@ -0,0 +1 @@ +// Signals for /mob/living/carbon diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_living.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_living.dm new file mode 100644 index 0000000000000..e1602f1bb705e --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_living.dm @@ -0,0 +1,14 @@ +// Signals for /mob/living + +/mob/living/CanAllowThrough(atom/movable/mover, border_dir) + if(SEND_SIGNAL(src, COMSIG_LIVING_CAN_ALLOW_THROUGH, mover, border_dir) & COMPONENT_LIVING_PASSABLE) + return TRUE + return ..() + +/mob/living/set_pull_offsets(mob/living/pull_target, grab_state) + . = ..() + SEND_SIGNAL(pull_target, COMSIG_LIVING_SET_PULL_OFFSET, grab_state) + +/mob/living/reset_pull_offsets(mob/living/pull_target, override) + . = ..() + SEND_SIGNAL(pull_target, COMSIG_LIVING_RESET_PULL_OFFSETS, override) diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_main.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_main.dm new file mode 100644 index 0000000000000..7aa41cead07d5 --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_main.dm @@ -0,0 +1 @@ +// Signals for /mob diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_silicon.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_silicon.dm new file mode 100644 index 0000000000000..1e776fa5270e2 --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_silicon.dm @@ -0,0 +1 @@ +// Signals for /mob/living/silicon diff --git a/modular_bandastation/_signals220/code/signals_mob/signals_mob_simple.dm b/modular_bandastation/_signals220/code/signals_mob/signals_mob_simple.dm new file mode 100644 index 0000000000000..937b109659eb5 --- /dev/null +++ b/modular_bandastation/_signals220/code/signals_mob/signals_mob_simple.dm @@ -0,0 +1 @@ +// Signals for /mob/living/simple_animal diff --git a/modular_bandastation/aesthetics/_aesthetics.dm b/modular_bandastation/aesthetics/_aesthetics.dm new file mode 100644 index 0000000000000..bcccd31589222 --- /dev/null +++ b/modular_bandastation/aesthetics/_aesthetics.dm @@ -0,0 +1,4 @@ +/datum/modpack/aesthetics + name = "Эстетика" + desc = "Обновление визуального ряда" + author = "larentoun, Aylong220" diff --git a/modular_bandastation/aesthetics/_aesthetics.dme b/modular_bandastation/aesthetics/_aesthetics.dme new file mode 100644 index 0000000000000..10130ed3b9ca1 --- /dev/null +++ b/modular_bandastation/aesthetics/_aesthetics.dme @@ -0,0 +1,43 @@ +#include "_aesthetics.dm" + +#include "airalarm\code\airalarm.dm" +#include "airlocks\code\airlock.dm" +#include "airlocks\code\airlock_types.dm" +#include "airlocks\code\airlock_assembly_types.dm" +#include "apc\code\apc.dm" +// #include "atm\code\atm.dm" // Unused +// #include "atmospherics\code\atmospherics.dm" // Need more sprites +// #include "better_ids\code\better_ids.dm" // Need to change a lot +#include "blastdoor\code\blastdoor.dm" +// #include "boxes\code\boxes.dm" // Need to change a lot +#include "cameras\code\cameras.dm" +// #include "chairs\code\chairs.dm" // TG already uses these +// #include "decals\code\decals.dm" // Didn't check this new one +// #include "defib\code\defib.dm" // TG already uses these +#include "dirwindows\code\dirwindows.dm" +// #include "door_control\code\door_control.dm" // Unused +// #include "extinguisher\code\extinguisher.dm" // Need more sprites +// #include "firealarm\code\firealarm.dm" // Need more sprites +// #include "floors\code\floors.dm" // Need to change a lot +// #include "floors\code\tile_types.dm" // Need to change a lot +// #include "hydroponics\code\hydroponics.dm" // TG already uses these +// #include "intercom\code\intercom.dm" // TG already uses these +#include "keycard\code\keycard.dm" +#include "labeler\code\labeler.dm" +// #include "library\code\library.dm" // TG already uses these +#include "light_switch\code\light_switch.dm" +#include "newscaster\code\newscaster.dm" +// #include "piano\code\piano.dm" // Unused +#include "racks\code\racks.dm" +#include "requests_console\code\requests_console.dm" +// #include "safe\code\safe.dm" // TG already uses these +#include "shutters\code\shutters.dm" +// #include "soap\code\soap.dm" // Unused +#include "surgery_table\code\surgery_table.dm" +// #include "toolboxes\code\toolboxes.dm" // TG already uses these +// #include "wallcloset\code\wallcloset.dm" // Unused +#include "walls\code\walls.dm" +#include "windoor\code\windoor.dm" +// #include "windows\code\windows.dm" // Need more sprites and fixes +// #include "windowtint\code\windowtint.dm" // Unused? +// #include "zippo\code\zippo.dm" // Unused diff --git a/modular_bandastation/aesthetics/airalarm/code/airalarm.dm b/modular_bandastation/aesthetics/airalarm/code/airalarm.dm new file mode 100644 index 0000000000000..092473ebbc4e7 --- /dev/null +++ b/modular_bandastation/aesthetics/airalarm/code/airalarm.dm @@ -0,0 +1,18 @@ +/obj/machinery/airalarm + icon = 'modular_bandastation/aesthetics/airalarm/icons/airalarm.dmi' + layer = ABOVE_WINDOW_LAYER + +/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) + . = ..() + switch(dir) // TODO: do it in dmi + if(NORTH) + dir = SOUTH + if(SOUTH) + dir = NORTH + if(EAST) + dir = WEST + if(WEST) + dir = EAST + +/obj/item/wallframe/airalarm + icon = 'modular_bandastation/aesthetics/airalarm/icons/airalarm.dmi' diff --git a/modular_bandastation/aesthetics/airalarm/icons/airalarm.dmi b/modular_bandastation/aesthetics/airalarm/icons/airalarm.dmi new file mode 100644 index 0000000000000..3f607849c6998 Binary files /dev/null and b/modular_bandastation/aesthetics/airalarm/icons/airalarm.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/code/airlock.dm b/modular_bandastation/aesthetics/airlocks/code/airlock.dm new file mode 100644 index 0000000000000..66a2ebc07cb16 --- /dev/null +++ b/modular_bandastation/aesthetics/airlocks/code/airlock.dm @@ -0,0 +1,28 @@ +/obj/machinery/door/airlock + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/public.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi' + note_overlay_file = 'modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi' + + doorOpen = 'modular_bandastation/aesthetics/airlocks/sound/open.ogg' + doorClose = 'modular_bandastation/aesthetics/airlocks/sound/close.ogg' + boltUp = 'modular_bandastation/aesthetics/airlocks/sound/bolts_up.ogg' + boltDown = 'modular_bandastation/aesthetics/airlocks/sound/bolts_down.ogg' + +/obj/machinery/door/airlock/update_overlays() + . = ..() + if(!lights || !hasPower()) + return + var/light_state + switch(airlock_state) + if(AIRLOCK_CLOSED) + if(!locked && !emergency) + light_state = "poweron" + if(AIRLOCK_OPEN) + if(locked) + light_state = AIRLOCK_LIGHT_BOLTS + else if(emergency) + light_state = AIRLOCK_LIGHT_EMERGENCY + else + light_state = "poweron" + light_state = "[light_state]_open" + . += get_airlock_overlay("lights_[light_state]", overlays_file, src, em_block = FALSE) diff --git a/modular_bandastation/aesthetics/airlocks/code/airlock_assembly_types.dm b/modular_bandastation/aesthetics/airlocks/code/airlock_assembly_types.dm new file mode 100644 index 0000000000000..c821e533b859e --- /dev/null +++ b/modular_bandastation/aesthetics/airlocks/code/airlock_assembly_types.dm @@ -0,0 +1,137 @@ +/obj/structure/door_assembly + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/public.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_public + icon = 'modular_bandastation/aesthetics/airlocks/icons/station2/glass.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/station2/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_com + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/command.dmi' + +/obj/structure/door_assembly/door_assembly_cap + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/cap.dmi' + +/obj/structure/door_assembly/door_assembly_hop + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/hop.dmi' + +/obj/structure/door_assembly/door_assembly_cmo + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/cmo.dmi' + +/obj/structure/door_assembly/door_assembly_rd + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/rd.dmi' + +/obj/structure/door_assembly/door_assembly_hos + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/hos.dmi' + +/obj/structure/door_assembly/door_assembly_qm + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/qm.dmi' + +/obj/structure/door_assembly/door_assembly_ce + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/ce.dmi' + +/obj/structure/door_assembly/door_assembly_sec + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/security.dmi' + +/obj/structure/door_assembly/door_assembly_eng + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/engineering.dmi' + +/obj/structure/door_assembly/door_assembly_min + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/mining.dmi' + +/obj/structure/door_assembly/door_assembly_atmo + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/atmos.dmi' + +/obj/structure/door_assembly/door_assembly_research + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/research.dmi' + +/obj/structure/door_assembly/door_assembly_science + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/science.dmi' + +/obj/structure/door_assembly/door_assembly_med + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/medical.dmi' + +/obj/structure/door_assembly/door_assembly_viro + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/virology.dmi' + +/obj/structure/door_assembly/door_assembly_hydro + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/botany.dmi' + +/obj/structure/door_assembly/door_assembly_eva + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/eva.dmi' + +/obj/structure/door_assembly/door_assembly_service + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/service.dmi' + +/obj/structure/door_assembly/door_assembly_psych + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/psych.dmi' + +/obj/structure/door_assembly/door_assembly_bathroom + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/bathroom.dmi' + +/obj/structure/door_assembly/door_assembly_lawyer + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/corporate.dmi' + +/obj/structure/door_assembly/door_assembly_mai + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/maintenance.dmi' + +/obj/structure/door_assembly/door_assembly_extmai + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/maintenanceexternal.dmi' + +/obj/structure/door_assembly/door_assembly_ext + icon = 'modular_bandastation/aesthetics/airlocks/icons/external/external.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_fre + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/freezer.dmi' + +/obj/structure/door_assembly/door_assembly_hatch + icon = 'modular_bandastation/aesthetics/airlocks/icons/hatch/centcom.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_mhatch + icon = 'modular_bandastation/aesthetics/airlocks/icons/hatch/maintenance.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_highsecurity + icon = 'modular_bandastation/aesthetics/airlocks/icons/highsec/highsec.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/highsec/overlays.dmi' + +/* Unused +/obj/structure/door_assembly/multi_tile + icon = 'modular_bandastation/aesthetics/airlocks/icons/glass_large/glass_large.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi' +*/ + +/obj/structure/door_assembly/door_assembly_centcom + icon = 'modular_bandastation/aesthetics/airlocks/icons/centcom/centcom.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/centcom/overlays.dmi' + +/obj/structure/door_assembly/door_assembly_gold + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/gold.dmi' + +/obj/structure/door_assembly/door_assembly_silver + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/silver.dmi' + +/obj/structure/door_assembly/door_assembly_diamond + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/diamond.dmi' + +/obj/structure/door_assembly/door_assembly_uranium + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/uranium.dmi' + +/obj/structure/door_assembly/door_assembly_plasma + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/plasma.dmi' + +/obj/structure/door_assembly/door_assembly_bananium + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/bananium.dmi' + +/* Unused +/obj/structure/door_assembly/door_assembly_tranquillite + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/tranquilite.dmi' +*/ + +/obj/structure/door_assembly/door_assembly_sandstone + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/sandstone.dmi' + +/obj/structure/door_assembly/door_assembly_wood + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/wood.dmi' diff --git a/modular_bandastation/aesthetics/airlocks/code/airlock_types.dm b/modular_bandastation/aesthetics/airlocks/code/airlock_types.dm new file mode 100644 index 0000000000000..611a44eb257b4 --- /dev/null +++ b/modular_bandastation/aesthetics/airlocks/code/airlock_types.dm @@ -0,0 +1,233 @@ +/* + Station Airlocks Regular +*/ +/obj/machinery/door/airlock/command + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/command.dmi' + +/obj/machinery/door/airlock/command/cap + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/cap.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_cap + +/obj/machinery/door/airlock/command/hop + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/hop.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_hop + +/obj/machinery/door/airlock/command/cmo + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/cmo.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_cmo + +/obj/machinery/door/airlock/command/rd + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/rd.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_rd + +/obj/machinery/door/airlock/command/hos + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/hos.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_hos + +/obj/machinery/door/airlock/command/qm + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/qm.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_qm + +/obj/machinery/door/airlock/command/ce + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/heads/ce.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_ce + +/obj/machinery/door/airlock/security + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/security.dmi' + +/obj/machinery/door/airlock/engineering + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/engineering.dmi' + +/obj/machinery/door/airlock/medical + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/medical.dmi' + +/obj/machinery/door/airlock/maintenance + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/maintenance.dmi' + +/obj/machinery/door/airlock/maintenance/external + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/maintenanceexternal.dmi' + +/obj/machinery/door/airlock/mining + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/mining.dmi' + +/obj/machinery/door/airlock/atmos + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/atmos.dmi' + +/obj/machinery/door/airlock/research + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/research.dmi' + +/obj/machinery/door/airlock/freezer + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/freezer.dmi' + +/obj/machinery/door/airlock/science + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/science.dmi' + +/obj/machinery/door/airlock/virology + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/virology.dmi' + +/obj/machinery/door/airlock/hydroponics + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/botany.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_hydro + +/obj/machinery/door/airlock/eva + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/eva.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_eva + +/obj/machinery/door/airlock/service + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/service.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_service + +/obj/machinery/door/airlock/psych + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/psych.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_psych + +/obj/machinery/door/airlock/bathroom + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/bathroom.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_bathroom + +/obj/machinery/door/airlock/lawyer + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/corporate.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_lawyer + +/* + Station Airlocks Glass +*/ +/obj/machinery/door/airlock/command/cap/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/hop/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/cmo/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/rd/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/hos/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/qm/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/command/ce/glass + opacity = 0 + glass = TRUE + normal_integrity = 400 + +/obj/machinery/door/airlock/hydroponics/glass + opacity = 0 + glass = TRUE + +/obj/machinery/door/airlock/eva/glass + opacity = 0 + glass = TRUE + +/obj/machinery/door/airlock/service/glass + opacity = 0 + glass = TRUE + +/obj/machinery/door/airlock/psych/glass + opacity = 0 + glass = TRUE + +/obj/machinery/door/airlock/lawyer/glass + opacity = 0 + glass = TRUE + +/* + Station Airlocks Mineral +*/ +/obj/machinery/door/airlock/gold + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/gold.dmi' + +/obj/machinery/door/airlock/silver + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/silver.dmi' + +/obj/machinery/door/airlock/diamond + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/diamond.dmi' + +/obj/machinery/door/airlock/uranium + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/uranium.dmi' + +/obj/machinery/door/airlock/plasma + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/plasma.dmi' + +/obj/machinery/door/airlock/bananium + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/bananium.dmi' + +/* Unused +/obj/machinery/door/airlock/tranquillite + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/tranquilite.dmi' +*/ + +/obj/machinery/door/airlock/sandstone + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/sandstone.dmi' + +/obj/machinery/door/airlock/wood + icon = 'modular_bandastation/aesthetics/airlocks/icons/station/wood.dmi' + +/* + Station2 Airlocks +*/ +/obj/machinery/door/airlock/public + icon = 'modular_bandastation/aesthetics/airlocks/icons/station2/glass.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/station2/overlays.dmi' + +/* + External Airlocks +*/ +/obj/machinery/door/airlock/external + icon = 'modular_bandastation/aesthetics/airlocks/icons/external/external.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi' + note_overlay_file = 'modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi' + +/* + CentCom Airlocks +*/ +/obj/machinery/door/airlock/centcom + icon = 'modular_bandastation/aesthetics/airlocks/icons/centcom/centcom.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/centcom/overlays.dmi' + +/* + Hatch Airlocks +*/ +/obj/machinery/door/airlock/hatch + icon = 'modular_bandastation/aesthetics/airlocks/icons/hatch/centcom.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + note_overlay_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + +/obj/machinery/door/airlock/maintenance_hatch + icon = 'modular_bandastation/aesthetics/airlocks/icons/hatch/maintenance.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + note_overlay_file = 'modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi' + +/* + High Security Airlocks +*/ +/obj/machinery/door/airlock/highsecurity + icon = 'modular_bandastation/aesthetics/airlocks/icons/highsec/highsec.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/highsec/overlays.dmi' + +/* + Misc Airlocks +*/ + +/* Unused? +/obj/machinery/door/airlock/multi_tile + icon = 'modular_bandastation/aesthetics/airlocks/icons/glass_large/glass_large.dmi' + overlays_file = 'modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi' + note_overlay_file = 'modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi' +*/ diff --git a/modular_bandastation/aesthetics/airlocks/icons/centcom/centcom.dmi b/modular_bandastation/aesthetics/airlocks/icons/centcom/centcom.dmi new file mode 100644 index 0000000000000..9d45122dd12c4 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/centcom/centcom.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/centcom/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/centcom/overlays.dmi new file mode 100644 index 0000000000000..eb4f3d8500210 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/centcom/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/external/external.dmi b/modular_bandastation/aesthetics/airlocks/icons/external/external.dmi new file mode 100644 index 0000000000000..8a00a16ba3c06 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/external/external.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi new file mode 100644 index 0000000000000..20e02d7a6c1cb Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/external/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/glass_large/glass_large.dmi b/modular_bandastation/aesthetics/airlocks/icons/glass_large/glass_large.dmi new file mode 100644 index 0000000000000..ddd1871e6feff Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/glass_large/glass_large.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi new file mode 100644 index 0000000000000..bf5be7bccd4f1 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/glass_large/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/hatch/centcom.dmi b/modular_bandastation/aesthetics/airlocks/icons/hatch/centcom.dmi new file mode 100644 index 0000000000000..64d15207b5992 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/hatch/centcom.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/hatch/maintenance.dmi b/modular_bandastation/aesthetics/airlocks/icons/hatch/maintenance.dmi new file mode 100644 index 0000000000000..3303591517f6e Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/hatch/maintenance.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi new file mode 100644 index 0000000000000..c426986694954 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/hatch/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/highsec/highsec.dmi b/modular_bandastation/aesthetics/airlocks/icons/highsec/highsec.dmi new file mode 100644 index 0000000000000..eb5e312d93c96 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/highsec/highsec.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/highsec/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/highsec/overlays.dmi new file mode 100644 index 0000000000000..97f2c7fc5c5cf Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/highsec/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/atmos.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/atmos.dmi new file mode 100644 index 0000000000000..8bf12b5fa7516 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/atmos.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/bananium.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/bananium.dmi new file mode 100644 index 0000000000000..cad8ba902d805 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/bananium.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/bathroom.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/bathroom.dmi new file mode 100644 index 0000000000000..68fd49dc9ac14 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/bathroom.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/botany.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/botany.dmi new file mode 100644 index 0000000000000..2a8ef28d0e1de Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/botany.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/corporate.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/corporate.dmi new file mode 100644 index 0000000000000..3209e7f59ba46 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/corporate.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/diamond.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/diamond.dmi new file mode 100644 index 0000000000000..e7ec1cffb65d4 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/diamond.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/engineering.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/engineering.dmi new file mode 100644 index 0000000000000..f9e1f5915f79e Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/engineering.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/eva.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/eva.dmi new file mode 100644 index 0000000000000..6c495b54322f7 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/eva.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/freezer.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/freezer.dmi new file mode 100644 index 0000000000000..ad3a1c72a84ca Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/freezer.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/gold.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/gold.dmi new file mode 100644 index 0000000000000..a2977d95cf9d6 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/gold.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/cap.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/cap.dmi new file mode 100644 index 0000000000000..7417588b5390c Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/cap.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/ce.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/ce.dmi new file mode 100644 index 0000000000000..2223e252cb00d Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/ce.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/cmo.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/cmo.dmi new file mode 100644 index 0000000000000..a44e60ac2c62d Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/cmo.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/command.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/command.dmi new file mode 100644 index 0000000000000..affe4c1fd2f9a Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/command.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/hop.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/hop.dmi new file mode 100644 index 0000000000000..c17a3c2cebe7d Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/hop.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/hos.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/hos.dmi new file mode 100644 index 0000000000000..9ddc7cb63ba18 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/hos.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/qm.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/qm.dmi new file mode 100644 index 0000000000000..0ebfb5fd5e476 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/qm.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/heads/rd.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/heads/rd.dmi new file mode 100644 index 0000000000000..cac461fb63c54 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/heads/rd.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/maintenance.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/maintenance.dmi new file mode 100644 index 0000000000000..cc96c755a8e27 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/maintenance.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/maintenanceexternal.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/maintenanceexternal.dmi new file mode 100644 index 0000000000000..c7d8e6154e8a5 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/maintenanceexternal.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/medical.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/medical.dmi new file mode 100644 index 0000000000000..e33bff783ebc7 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/medical.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/mining.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/mining.dmi new file mode 100644 index 0000000000000..86ec771471e34 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/mining.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi new file mode 100644 index 0000000000000..f385bd385a317 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/plasma.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/plasma.dmi new file mode 100644 index 0000000000000..a90fa8f0bce58 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/plasma.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/psych.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/psych.dmi new file mode 100644 index 0000000000000..d8bbc788f9ebd Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/psych.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/public.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/public.dmi new file mode 100644 index 0000000000000..1e3258bd17087 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/public.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/research.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/research.dmi new file mode 100644 index 0000000000000..6c3b231078589 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/research.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/sandstone.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/sandstone.dmi new file mode 100644 index 0000000000000..ac4dc71790597 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/sandstone.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/science.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/science.dmi new file mode 100644 index 0000000000000..95396c1d403e2 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/science.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/security.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/security.dmi new file mode 100644 index 0000000000000..f38b9e05405d7 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/security.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/service.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/service.dmi new file mode 100644 index 0000000000000..e155823d8d3d1 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/service.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/silver.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/silver.dmi new file mode 100644 index 0000000000000..47105c88bf149 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/silver.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/tranquilite.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/tranquilite.dmi new file mode 100644 index 0000000000000..851568e1dab29 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/tranquilite.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/uranium.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/uranium.dmi new file mode 100644 index 0000000000000..d23811bacd40a Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/uranium.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/virology.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/virology.dmi new file mode 100644 index 0000000000000..600dd9ee225b3 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/virology.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station/wood.dmi b/modular_bandastation/aesthetics/airlocks/icons/station/wood.dmi new file mode 100644 index 0000000000000..b5973a7219f27 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station/wood.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station2/glass.dmi b/modular_bandastation/aesthetics/airlocks/icons/station2/glass.dmi new file mode 100644 index 0000000000000..6c8259ab0de3e Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station2/glass.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/icons/station2/overlays.dmi b/modular_bandastation/aesthetics/airlocks/icons/station2/overlays.dmi new file mode 100644 index 0000000000000..910a58b0d31f1 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/icons/station2/overlays.dmi differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/bolts_down.ogg b/modular_bandastation/aesthetics/airlocks/sound/bolts_down.ogg new file mode 100644 index 0000000000000..19d62b8acb2ac Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/bolts_down.ogg differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/bolts_up.ogg b/modular_bandastation/aesthetics/airlocks/sound/bolts_up.ogg new file mode 100644 index 0000000000000..0aac1a44fcc55 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/bolts_up.ogg differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/close.ogg b/modular_bandastation/aesthetics/airlocks/sound/close.ogg new file mode 100644 index 0000000000000..db94b73fb4b63 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/close.ogg differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/close_force.ogg b/modular_bandastation/aesthetics/airlocks/sound/close_force.ogg new file mode 100644 index 0000000000000..28b190d8e0952 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/close_force.ogg differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/open.ogg b/modular_bandastation/aesthetics/airlocks/sound/open.ogg new file mode 100644 index 0000000000000..0b8a0d5f94f16 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/open.ogg differ diff --git a/modular_bandastation/aesthetics/airlocks/sound/open_force.ogg b/modular_bandastation/aesthetics/airlocks/sound/open_force.ogg new file mode 100644 index 0000000000000..4caefc0b9e4d4 Binary files /dev/null and b/modular_bandastation/aesthetics/airlocks/sound/open_force.ogg differ diff --git a/modular_bandastation/aesthetics/apc/code/apc.dm b/modular_bandastation/aesthetics/apc/code/apc.dm new file mode 100644 index 0000000000000..8df6f9ac7a9a7 --- /dev/null +++ b/modular_bandastation/aesthetics/apc/code/apc.dm @@ -0,0 +1,6 @@ +/obj/machinery/power/apc + icon = 'modular_bandastation/aesthetics/apc/icons/apc.dmi' + layer = ABOVE_WINDOW_LAYER + +/obj/item/wallframe/apc + icon = 'modular_bandastation/aesthetics/apc/icons/apc.dmi' diff --git a/modular_bandastation/aesthetics/apc/icons/apc.dmi b/modular_bandastation/aesthetics/apc/icons/apc.dmi new file mode 100644 index 0000000000000..ce12d55fca863 Binary files /dev/null and b/modular_bandastation/aesthetics/apc/icons/apc.dmi differ diff --git a/modular_bandastation/aesthetics/atm/code/atm.dm b/modular_bandastation/aesthetics/atm/code/atm.dm new file mode 100644 index 0000000000000..4dd1a708a855d --- /dev/null +++ b/modular_bandastation/aesthetics/atm/code/atm.dm @@ -0,0 +1,2 @@ +/obj/machinery/economy/atm + icon = 'modular_bandastation/aesthetics/atm/icons/atm.dmi' diff --git a/modular_bandastation/aesthetics/atm/icons/atm.dmi b/modular_bandastation/aesthetics/atm/icons/atm.dmi new file mode 100644 index 0000000000000..23e9a29ce8a6c Binary files /dev/null and b/modular_bandastation/aesthetics/atm/icons/atm.dmi differ diff --git a/modular_bandastation/aesthetics/atmospherics/code/atmospherics.dm b/modular_bandastation/aesthetics/atmospherics/code/atmospherics.dm new file mode 100644 index 0000000000000..0082fb87677b6 --- /dev/null +++ b/modular_bandastation/aesthetics/atmospherics/code/atmospherics.dm @@ -0,0 +1,5 @@ +/obj/machinery/atmospherics/components/unary/vent_pump + icon = 'modular_bandastation/aesthetics/atmospherics/icons/vent_pump.dmi' + +/obj/machinery/atmospherics/components/unary/vent_scrubber + icon = 'modular_bandastation/aesthetics/atmospherics/icons/vent_scrubber.dmi' diff --git a/modular_bandastation/aesthetics/atmospherics/icons/vent_pump.dmi b/modular_bandastation/aesthetics/atmospherics/icons/vent_pump.dmi new file mode 100644 index 0000000000000..52aeaf450ac27 Binary files /dev/null and b/modular_bandastation/aesthetics/atmospherics/icons/vent_pump.dmi differ diff --git a/modular_bandastation/aesthetics/atmospherics/icons/vent_scrubber.dmi b/modular_bandastation/aesthetics/atmospherics/icons/vent_scrubber.dmi new file mode 100644 index 0000000000000..4639f470fa517 Binary files /dev/null and b/modular_bandastation/aesthetics/atmospherics/icons/vent_scrubber.dmi differ diff --git a/modular_bandastation/aesthetics/better_ids/code/better_ids.dm b/modular_bandastation/aesthetics/better_ids/code/better_ids.dm new file mode 100644 index 0000000000000..6ba748960047c --- /dev/null +++ b/modular_bandastation/aesthetics/better_ids/code/better_ids.dm @@ -0,0 +1,5 @@ +/obj/item/card + icon = 'modular_bandastation/aesthetics/better_ids/icons/better_ids.dmi' + +/obj/item/nanomob_card + icon = 'modular_bandastation/aesthetics/better_ids/icons/better_ids.dmi' diff --git a/modular_bandastation/aesthetics/better_ids/icons/better_ids.dmi b/modular_bandastation/aesthetics/better_ids/icons/better_ids.dmi new file mode 100644 index 0000000000000..f66a128decab9 Binary files /dev/null and b/modular_bandastation/aesthetics/better_ids/icons/better_ids.dmi differ diff --git a/modular_bandastation/aesthetics/blastdoor/code/blastdoor.dm b/modular_bandastation/aesthetics/blastdoor/code/blastdoor.dm new file mode 100644 index 0000000000000..804b6f7ec105b --- /dev/null +++ b/modular_bandastation/aesthetics/blastdoor/code/blastdoor.dm @@ -0,0 +1,3 @@ +/obj/machinery/door/poddoor + icon = 'modular_bandastation/aesthetics/blastdoor/icons/blastdoor.dmi' + animation_sound = 'modular_bandastation/aesthetics/blastdoor/sound/blastdoor.ogg' diff --git a/modular_bandastation/aesthetics/blastdoor/icons/blastdoor.dmi b/modular_bandastation/aesthetics/blastdoor/icons/blastdoor.dmi new file mode 100644 index 0000000000000..672c161c10ed7 Binary files /dev/null and b/modular_bandastation/aesthetics/blastdoor/icons/blastdoor.dmi differ diff --git a/modular_bandastation/aesthetics/blastdoor/sound/blastdoor.ogg b/modular_bandastation/aesthetics/blastdoor/sound/blastdoor.ogg new file mode 100644 index 0000000000000..93e53513985a4 Binary files /dev/null and b/modular_bandastation/aesthetics/blastdoor/sound/blastdoor.ogg differ diff --git a/modular_bandastation/aesthetics/boxes/code/boxes.dm b/modular_bandastation/aesthetics/boxes/code/boxes.dm new file mode 100644 index 0000000000000..5864c48233d04 --- /dev/null +++ b/modular_bandastation/aesthetics/boxes/code/boxes.dm @@ -0,0 +1,287 @@ +/obj/item/storage/box/survival + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "civ_box" + +/obj/item/storage/box/survival_vox + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "vox_box" + +/obj/item/storage/box/survival_plasmaman + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "plasma_box" + +/obj/item/storage/box/engineer + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "eng_box" + +/obj/item/storage/box/survival_mining + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "min_box" + +/obj/item/storage/box/survival_syndi + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "syndie_box" + +/obj/item/storage/box/gloves + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "latex_box" + +/obj/item/storage/box/masks + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "sterile_box" + +/obj/item/storage/box/syringes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "syringe_box" + +/obj/item/storage/box/beakers + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "beaker_box" + +/obj/item/storage/box/beakers/bluespace + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "beaker_bluespace_box" + +/obj/item/storage/box/iv_bags + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "iv_box" + +/obj/item/storage/box/injectors + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "syringe_box" + +/obj/item/storage/box/flashbangs + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "flashbang_box" + +/obj/item/storage/box/flashes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "flash_box" + +/obj/item/storage/box/teargas + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "teargas_box" + +/obj/item/storage/box/emps + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "emp_box" + +/obj/item/storage/box/trackimp + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/minertracker + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/chemimp + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/exileimp + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/deathimp + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/tapes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "tape_box" + +/obj/item/storage/box/rxglasses + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "glasses_box" + +/obj/item/storage/box/drinkingglasses + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/condimentbottles + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/cups + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "cup_box" + +/obj/item/storage/box/donkpockets + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "donk_box" + +/obj/item/storage/box/syndidonkpockets + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "id_syndie_box" // TODO: Need new icon + +/obj/item/storage/box/monkeycubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "monkey_box" + +/obj/item/storage/box/monkeycubes/neaeracubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "neaera_box" + +/obj/item/storage/box/monkeycubes/stokcubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "stok_box" + +/obj/item/storage/box/monkeycubes/farwacubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "farwa_box" + +/obj/item/storage/box/monkeycubes/wolpincubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "wolpin_box" + +/obj/item/storage/box/permits + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "id_box" + +/obj/item/storage/box/ids + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "id_box" + +/obj/item/storage/box/prisoner + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "id_box" + +/obj/item/storage/box/seccarts + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "pda_box" + +/obj/item/storage/box/holobadge + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "badge_box" + +/obj/item/storage/box/evidence + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "evidence_box" + +/obj/item/storage/box/handcuffs + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "handcuff_box" + +/obj/item/storage/box/zipties + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "zipties_box" + +/obj/item/storage/box/alienhandcuffs + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "alien_handcuff_box" + +/obj/item/storage/box/fakesyndiesuit + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "doom_box" + +/obj/item/storage/box/enforcer_rubber + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "ert_box" + +/obj/item/storage/box/enforcer_lethal + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "ert_box" + +/obj/item/storage/box/bartender_rare_ingredients_kit + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/chef_rare_ingredients_kit + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/mousetraps + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "mousetraps_box" + +/obj/item/storage/box/pillbottles + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "pill_box" + +/obj/item/storage/box/patch_packs + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "patch_box" + +/obj/item/storage/box/bodybags + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "bodybag_box" + +/obj/item/storage/box/autoinjectors + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "injector_box" + +/obj/item/storage/box/lights + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "light_box" + +/obj/item/storage/box/lights/tubes + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "lighttube_box" + +/obj/item/storage/box/lights/mixed + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "lightmixed_box" + +/obj/item/storage/box/barber + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/lip_stick + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "implant_box" + +/obj/item/storage/box/centcomofficer + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "ert_box" + +/obj/item/storage/box/responseteam + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "ert_box" + +/obj/item/storage/box/deathsquad + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "doom_box" + +/obj/item/storage/box/soviet + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "soviet_box" + +/obj/item/storage/box/clown + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "clown_box" + +/obj/item/storage/box/emptysandbags + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/rndboards + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/stockparts + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/hug + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "hug_box" + +/obj/item/storage/box/wizard + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "wizard_box" + +/obj/item/storage/box/breaching + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "flashbang_box" + +/obj/item/storage/box/mindshield + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/dish_drive + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "box" + +/obj/item/storage/box/disks_plantgene + icon = 'modular_bandastation/aesthetics/boxes/icons/boxes.dmi' + icon_state = "disk_box" diff --git a/modular_bandastation/aesthetics/boxes/icons/boxes.dmi b/modular_bandastation/aesthetics/boxes/icons/boxes.dmi new file mode 100644 index 0000000000000..97467e6f3b1da Binary files /dev/null and b/modular_bandastation/aesthetics/boxes/icons/boxes.dmi differ diff --git a/modular_bandastation/aesthetics/cameras/code/cameras.dm b/modular_bandastation/aesthetics/cameras/code/cameras.dm new file mode 100644 index 0000000000000..68cec7d461d6e --- /dev/null +++ b/modular_bandastation/aesthetics/cameras/code/cameras.dm @@ -0,0 +1,15 @@ +/obj/machinery/camera + icon = 'modular_bandastation/aesthetics/cameras/icons/cameras.dmi' + // TODO: camera_in_use + +/obj/machinery/camera/Initialize(mapload, obj/structure/camera_assembly/old_assembly) + . = ..() + switch(dir) // TODO: do it in dmi + if(NORTH) + dir = SOUTH + if(SOUTH) + dir = NORTH + if(EAST) + dir = WEST + if(WEST) + dir = EAST diff --git a/modular_bandastation/aesthetics/cameras/icons/cameras.dmi b/modular_bandastation/aesthetics/cameras/icons/cameras.dmi new file mode 100644 index 0000000000000..26b8700a147c4 Binary files /dev/null and b/modular_bandastation/aesthetics/cameras/icons/cameras.dmi differ diff --git a/modular_bandastation/aesthetics/chairs/code/chairs.dm b/modular_bandastation/aesthetics/chairs/code/chairs.dm new file mode 100644 index 0000000000000..356b81c6d89e6 --- /dev/null +++ b/modular_bandastation/aesthetics/chairs/code/chairs.dm @@ -0,0 +1,35 @@ +/obj/structure/chair/comfy + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + +/obj/structure/chair/comfy/GetArmrest() + return mutable_appearance('modular_bandastation/aesthetics/chairs/icons/chairs.dmi', "[icon_state]_armrest") + +/obj/structure/chair/comfy/corp + icon = 'icons/obj/chairs.dmi' + +/obj/structure/chair/comfy/shuttle + icon = 'icons/obj/chairs.dmi' + +/obj/structure/chair/office/dark + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + +/obj/structure/chair/office/light + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + +/obj/structure/chair/e_chair + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + +//TODO: Support or chairs + +/obj/item/chair/stool/bar/dark + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + icon_state = "bar_toppled_dark" + item_state = "stool_bar_dark" + origin_type = /obj/structure/chair/stool/bar/dark + lefthand_file = 'modular_bandastation/aesthetics/chairs/icons/chairs_lefthand.dmi' + righthand_file = 'modular_bandastation/aesthetics/chairs/icons/chairs_righthand.dmi' + +/obj/structure/chair/stool/bar/dark + icon = 'modular_bandastation/aesthetics/chairs/icons/chairs.dmi' + icon_state = "bar_dark" + item_chair = /obj/item/chair/stool/bar/dark diff --git a/modular_bandastation/aesthetics/chairs/icons/chairs.dmi b/modular_bandastation/aesthetics/chairs/icons/chairs.dmi new file mode 100644 index 0000000000000..6aba9bf8697ab Binary files /dev/null and b/modular_bandastation/aesthetics/chairs/icons/chairs.dmi differ diff --git a/modular_bandastation/aesthetics/chairs/icons/chairs_lefthand.dmi b/modular_bandastation/aesthetics/chairs/icons/chairs_lefthand.dmi new file mode 100644 index 0000000000000..f3238b0616ba9 Binary files /dev/null and b/modular_bandastation/aesthetics/chairs/icons/chairs_lefthand.dmi differ diff --git a/modular_bandastation/aesthetics/chairs/icons/chairs_righthand.dmi b/modular_bandastation/aesthetics/chairs/icons/chairs_righthand.dmi new file mode 100644 index 0000000000000..ac882e8ebf82b Binary files /dev/null and b/modular_bandastation/aesthetics/chairs/icons/chairs_righthand.dmi differ diff --git a/modular_bandastation/aesthetics/decals/code/decals.dm b/modular_bandastation/aesthetics/decals/code/decals.dm new file mode 100644 index 0000000000000..07fdc75819380 --- /dev/null +++ b/modular_bandastation/aesthetics/decals/code/decals.dm @@ -0,0 +1,78 @@ +// SIDING +/obj/effect/turf_decal/siding/wood + icon = 'modular_bandastation/aesthetics/decals/icons/siding.dmi' + icon_state = "siding_wood_line" + color = "#55391A" + +/obj/effect/turf_decal/siding/wood/corner + icon_state = "siding_wood_corner" + +/obj/effect/turf_decal/siding/wood/end + icon_state = "siding_wood_end" + +/obj/effect/turf_decal/siding + icon = 'modular_bandastation/aesthetics/decals/icons/siding.dmi' + icon_state = "siding_line" + +/obj/effect/turf_decal/siding/white + color = "#BCBCBC" + +/obj/effect/turf_decal/siding/white/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/white/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/red + color = "#DE3A3A" + +/obj/effect/turf_decal/siding/red/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/red/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/green + color = "#9FED58" + +/obj/effect/turf_decal/siding/green/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/green/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/blue + color = "#52B4E9" + +/obj/effect/turf_decal/siding/blue/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/blue/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/yellow + color = "#EFB341" + +/obj/effect/turf_decal/siding/yellow/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/yellow/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/purple + color = "#D381C9" + +/obj/effect/turf_decal/siding/purple/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/purple/end + icon_state = "siding_end" + +/obj/effect/turf_decal/siding/brown + color = "#A46106" + +/obj/effect/turf_decal/siding/brown/corner + icon_state = "siding_corner" + +/obj/effect/turf_decal/siding/brown/end + icon_state = "siding_end" diff --git a/modular_bandastation/aesthetics/decals/icons/siding.dmi b/modular_bandastation/aesthetics/decals/icons/siding.dmi new file mode 100644 index 0000000000000..f3ac9b02751ad Binary files /dev/null and b/modular_bandastation/aesthetics/decals/icons/siding.dmi differ diff --git a/modular_bandastation/aesthetics/defib/code/defib.dm b/modular_bandastation/aesthetics/defib/code/defib.dm new file mode 100644 index 0000000000000..4687a9b237d58 --- /dev/null +++ b/modular_bandastation/aesthetics/defib/code/defib.dm @@ -0,0 +1,6 @@ +/obj/item/defibrillator + icon = 'modular_bandastation/aesthetics/defib/icons/defib.dmi' + +/obj/item/defibrillator/compact + icon = 'icons/obj/defib.dmi' + //TODO: Compact defibs diff --git a/modular_bandastation/aesthetics/defib/icons/defib.dmi b/modular_bandastation/aesthetics/defib/icons/defib.dmi new file mode 100644 index 0000000000000..f4fbe3712d4e6 Binary files /dev/null and b/modular_bandastation/aesthetics/defib/icons/defib.dmi differ diff --git a/modular_bandastation/aesthetics/dirwindows/code/dirwindows.dm b/modular_bandastation/aesthetics/dirwindows/code/dirwindows.dm new file mode 100644 index 0000000000000..68774c2056786 --- /dev/null +++ b/modular_bandastation/aesthetics/dirwindows/code/dirwindows.dm @@ -0,0 +1,14 @@ +/obj/structure/window + icon = 'modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi' + +/obj/structure/window/reinforced + icon = 'modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi' + +/obj/structure/window/plasma + icon = 'modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi' + +/obj/structure/window/reinforced/tinted + icon = 'modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi' + +/obj/structure/window/reinforced/tinted/frosted + icon = 'modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi' diff --git a/modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi b/modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi new file mode 100644 index 0000000000000..c9aa5b12d9115 Binary files /dev/null and b/modular_bandastation/aesthetics/dirwindows/icons/dirwindows.dmi differ diff --git a/modular_bandastation/aesthetics/door_control/code/door_control.dm b/modular_bandastation/aesthetics/door_control/code/door_control.dm new file mode 100644 index 0000000000000..4e7c60ff77e58 --- /dev/null +++ b/modular_bandastation/aesthetics/door_control/code/door_control.dm @@ -0,0 +1,2 @@ +/obj/machinery/door_control + layer = ABOVE_WINDOW_LAYER diff --git a/modular_bandastation/aesthetics/extinguisher/code/extinguisher.dm b/modular_bandastation/aesthetics/extinguisher/code/extinguisher.dm new file mode 100644 index 0000000000000..4999d73d21b72 --- /dev/null +++ b/modular_bandastation/aesthetics/extinguisher/code/extinguisher.dm @@ -0,0 +1,3 @@ +/obj/structure/extinguisher_cabinet + icon = 'modular_bandastation/aesthetics/extinguisher/icons/extinguisher.dmi' + //TODO: Frame, advanced, crafted, unlocked/locked? diff --git a/modular_bandastation/aesthetics/extinguisher/icons/extinguisher.dmi b/modular_bandastation/aesthetics/extinguisher/icons/extinguisher.dmi new file mode 100644 index 0000000000000..a1041de37c230 Binary files /dev/null and b/modular_bandastation/aesthetics/extinguisher/icons/extinguisher.dmi differ diff --git a/modular_bandastation/aesthetics/firealarm/code/firealarm.dm b/modular_bandastation/aesthetics/firealarm/code/firealarm.dm new file mode 100644 index 0000000000000..f380c19cc1fec --- /dev/null +++ b/modular_bandastation/aesthetics/firealarm/code/firealarm.dm @@ -0,0 +1,7 @@ +/obj/machinery/firealarm + icon = 'modular_bandastation/aesthetics/firealarm/icons/firealarm.dmi' + layer = ABOVE_WINDOW_LAYER + //TODO: Detect + +/obj/item/mounted/frame/firealarm + icon = 'modular_bandastation/aesthetics/firealarm/icons/firealarm.dmi' diff --git a/modular_bandastation/aesthetics/firealarm/icons/firealarm.dmi b/modular_bandastation/aesthetics/firealarm/icons/firealarm.dmi new file mode 100644 index 0000000000000..03fa8022c7149 Binary files /dev/null and b/modular_bandastation/aesthetics/firealarm/icons/firealarm.dmi differ diff --git a/modular_bandastation/aesthetics/floors/code/floors.dm b/modular_bandastation/aesthetics/floors/code/floors.dm new file mode 100644 index 0000000000000..e3ab11f14ad80 --- /dev/null +++ b/modular_bandastation/aesthetics/floors/code/floors.dm @@ -0,0 +1,55 @@ +/turf/open/floor + icon = 'modular_bandastation/aesthetics/floors/icons/floors.dmi' + +// WOODEN FLOORS +/turf/simulated/floor/wood/oak + icon_state = "wood-oak" + floor_tile = /obj/item/stack/tile/wood/oak + broken_states = list("wood-oak-broken", "wood-oak-broken2", "wood-oak-broken3", "wood-oak-broken4", "wood-oak-broken5", "wood-oak-broken6", "wood-oak-broken7") + +/turf/simulated/floor/wood/birch + icon_state = "wood-birch" + floor_tile = /obj/item/stack/tile/wood/birch + broken_states = list("wood-birch-broken", "wood-birch-broken2", "wood-birch-broken3", "wood-birch-broken4", "wood-birch-broken5", "wood-birch-broken6", "wood-birch-broken7") + +/turf/simulated/floor/wood/cherry + icon_state = "wood-cherry" + floor_tile = /obj/item/stack/tile/wood/cherry + broken_states = list("wood-cherry-broken", "wood-cherry-broken2", "wood-cherry-broken3", "wood-cherry-broken4", "wood-cherry-broken5", "wood-cherry-broken6", "wood-cherry-broken7") + +/turf/simulated/floor/wood/fancy/oak + icon_state = "fancy-wood-oak" + floor_tile = /obj/item/stack/tile/wood/fancy/oak + broken_states = list("fancy-wood-oak-broken", "fancy-wood-oak-broken2", "fancy-wood-oak-broken3", "fancy-wood-oak-broken4", "fancy-wood-oak-broken5", "fancy-wood-oak-broken6", "fancy-wood-oak-broken7") + +/turf/simulated/floor/wood/fancy/birch + icon_state = "fancy-wood-birch" + floor_tile = /obj/item/stack/tile/wood/fancy/birch + broken_states = list("fancy-wood-birch-broken", "fancy-wood-birch-broken2", "fancy-wood-birch-broken3", "fancy-wood-birch-broken4", "fancy-wood-birch-broken5", "fancy-wood-birch-broken6", "fancy-wood-birch-broken7") + +/turf/simulated/floor/wood/fancy/cherry + icon_state = "fancy-wood-cherry" + floor_tile = /obj/item/stack/tile/wood/fancy/cherry + broken_states = list("fancy-wood-cherry-broken", "fancy-wood-cherry-broken2", "fancy-wood-cherry-broken3", "fancy-wood-cherry-broken4", "fancy-wood-cherry-broken5", "fancy-wood-cherry-broken6", "fancy-wood-cherry-broken7") + +/turf/simulated/floor/wood/fancy/light + icon_state = "light-fancy-wood" + floor_tile = /obj/item/stack/tile/wood/fancy/light + broken_states = list("light-fancy-wood-broken", "light-fancy-wood-broken2", "light-fancy-wood-broken3", "light-fancy-wood-broken4", "light-fancy-wood-broken5", "light-fancy-wood-broken6", "light-fancy-wood-broken7") + +// LIGHT FLOORS +/turf/simulated/floor/light/red + color = "#f23030" + light_color = "#f23030" + +/turf/simulated/floor/light/green + color = "#30f230" + light_color = "#30f230" + +/turf/simulated/floor/light/blue + color = "#3030f2" + light_color = "#3030f2" + +/turf/simulated/floor/light/purple + color = "#9130f2" + light_color = "#9130f2" diff --git a/modular_bandastation/aesthetics/floors/code/tile_types.dm b/modular_bandastation/aesthetics/floors/code/tile_types.dm new file mode 100644 index 0000000000000..d4bf3fa165ae0 --- /dev/null +++ b/modular_bandastation/aesthetics/floors/code/tile_types.dm @@ -0,0 +1,42 @@ +// WOOD +/obj/item/stack/tile/wood/oak + name = "oak wood floor tiles" + singular_name = "oak wood floor tile" + icon_state = "tile-wood-oak" + turf_type = /turf/simulated/floor/wood/oak + +/obj/item/stack/tile/wood/birch + name = "birch wood floor tiles" + singular_name = "birch wood floor tile" + icon_state = "tile-wood-birch" + turf_type = /turf/simulated/floor/wood/birch + +/obj/item/stack/tile/wood/cherry + name = "cherry wood floor tiles" + singular_name = "cherry wood floor tile" + icon_state = "tile-wood-cherry" + turf_type = /turf/simulated/floor/wood/cherry + +/obj/item/stack/tile/wood/fancy/oak + name = "fancy oak wood floor tiles" + singular_name = "fancy oak wood floor tile" + icon_state = "tile-wood-fancy-oak" + turf_type = /turf/simulated/floor/wood/fancy/oak + +/obj/item/stack/tile/wood/fancy/birch + name = "fancy birch wood floor tiles" + singular_name = "fancy birch wood floor tile" + icon_state = "tile-wood-fancy-birch" + turf_type = /turf/simulated/floor/wood/fancy/birch + +/obj/item/stack/tile/wood/fancy/cherry + name = "fancy cherry wood floor tiles" + singular_name = "fancy cherry wood floor tile" + icon_state = "tile-wood-fancy-cherry" + turf_type = /turf/simulated/floor/wood/fancy/cherry + +/obj/item/stack/tile/wood/fancy/light + name = "fancy light oak wood floor tiles" + singular_name = "fancy light oak wood floor tile" + icon_state = "tile-wood-fancy-light" + turf_type = /turf/simulated/floor/wood/fancy/light diff --git a/modular_bandastation/aesthetics/floors/icons/floors.dmi b/modular_bandastation/aesthetics/floors/icons/floors.dmi new file mode 100644 index 0000000000000..90ef6b41c8add Binary files /dev/null and b/modular_bandastation/aesthetics/floors/icons/floors.dmi differ diff --git a/modular_bandastation/aesthetics/hydroponics/code/hydroponics.dm b/modular_bandastation/aesthetics/hydroponics/code/hydroponics.dm new file mode 100644 index 0000000000000..b757b8df2e8e5 --- /dev/null +++ b/modular_bandastation/aesthetics/hydroponics/code/hydroponics.dm @@ -0,0 +1,23 @@ +/* Unused +/obj/machinery/plantgenes + icon = 'modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi' + +/obj/machinery/plantgenes/update_overlays() + . = ..() + if(disk) + . += "dnamod-disk" + +/obj/machinery/plantgenes/add_disk(obj/item/disk/plantgene/new_disk, mob/user) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/plantgenes/update_genes() + . = ..() + update_icon(UPDATE_OVERLAYS) +*/ + +/obj/item/storage/bag/plants + icon = 'modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi' + +/obj/structure/loom + icon = 'modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi' diff --git a/modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi b/modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi new file mode 100644 index 0000000000000..82d7d663b9f0d Binary files /dev/null and b/modular_bandastation/aesthetics/hydroponics/icons/hydroponics.dmi differ diff --git a/modular_bandastation/aesthetics/intercom/code/intercom.dm b/modular_bandastation/aesthetics/intercom/code/intercom.dm new file mode 100644 index 0000000000000..3b0e1a9ca48a1 --- /dev/null +++ b/modular_bandastation/aesthetics/intercom/code/intercom.dm @@ -0,0 +1,2 @@ +/obj/item/radio/intercom + icon = 'modular_bandastation/aesthetics/intercom/icons/intercom.dmi' diff --git a/modular_bandastation/aesthetics/intercom/icons/intercom.dmi b/modular_bandastation/aesthetics/intercom/icons/intercom.dmi new file mode 100644 index 0000000000000..3e9fbfd93583b Binary files /dev/null and b/modular_bandastation/aesthetics/intercom/icons/intercom.dmi differ diff --git a/modular_bandastation/aesthetics/keycard/code/keycard.dm b/modular_bandastation/aesthetics/keycard/code/keycard.dm new file mode 100644 index 0000000000000..282b7ee22be88 --- /dev/null +++ b/modular_bandastation/aesthetics/keycard/code/keycard.dm @@ -0,0 +1,30 @@ +/obj/machinery/keycard_auth + icon = 'modular_bandastation/aesthetics/keycard/icons/keycard.dmi' + // TODO: update auth_on + +/obj/machinery/keycard_auth/Initialize(mapload) + . = ..() + switch(dir) // TODO: do it in dmi + if(NORTH) + dir = SOUTH + if(SOUTH) + dir = NORTH + if(EAST) + dir = WEST + if(WEST) + dir = EAST + +/obj/machinery/readybutton + icon = 'modular_bandastation/aesthetics/keycard/icons/keycard.dmi' + +/obj/machinery/readybutton/Initialize(mapload) + . = ..() + switch(dir) // TODO: do it in dmi + if(NORTH) + dir = SOUTH + if(SOUTH) + dir = NORTH + if(EAST) + dir = WEST + if(WEST) + dir = EAST diff --git a/modular_bandastation/aesthetics/keycard/icons/keycard.dmi b/modular_bandastation/aesthetics/keycard/icons/keycard.dmi new file mode 100644 index 0000000000000..39bdcf13f9628 Binary files /dev/null and b/modular_bandastation/aesthetics/keycard/icons/keycard.dmi differ diff --git a/modular_bandastation/aesthetics/labeler/code/labeler.dm b/modular_bandastation/aesthetics/labeler/code/labeler.dm new file mode 100644 index 0000000000000..5395293450587 --- /dev/null +++ b/modular_bandastation/aesthetics/labeler/code/labeler.dm @@ -0,0 +1,2 @@ +/obj/item/hand_labeler + icon = 'modular_bandastation/aesthetics/labeler/icons/labeler.dmi' diff --git a/modular_bandastation/aesthetics/labeler/icons/labeler.dmi b/modular_bandastation/aesthetics/labeler/icons/labeler.dmi new file mode 100644 index 0000000000000..74946042a96af Binary files /dev/null and b/modular_bandastation/aesthetics/labeler/icons/labeler.dmi differ diff --git a/modular_bandastation/aesthetics/library/code/library.dm b/modular_bandastation/aesthetics/library/code/library.dm new file mode 100644 index 0000000000000..9d7531aab9411 --- /dev/null +++ b/modular_bandastation/aesthetics/library/code/library.dm @@ -0,0 +1,5 @@ +/obj/structure/bookcase + icon = 'modular_bandastation/aesthetics/library/icons/library.dmi' + +/obj/machinery/bookbinder + icon = 'modular_bandastation/aesthetics/library/icons/library.dmi' diff --git a/modular_bandastation/aesthetics/library/icons/library.dmi b/modular_bandastation/aesthetics/library/icons/library.dmi new file mode 100644 index 0000000000000..ef1556c35bc70 Binary files /dev/null and b/modular_bandastation/aesthetics/library/icons/library.dmi differ diff --git a/modular_bandastation/aesthetics/light_switch/code/light_switch.dm b/modular_bandastation/aesthetics/light_switch/code/light_switch.dm new file mode 100644 index 0000000000000..d33b7182510f8 --- /dev/null +++ b/modular_bandastation/aesthetics/light_switch/code/light_switch.dm @@ -0,0 +1,2 @@ +/obj/machinery/light_switch + layer = ABOVE_WINDOW_LAYER diff --git a/modular_bandastation/aesthetics/newscaster/code/newscaster.dm b/modular_bandastation/aesthetics/newscaster/code/newscaster.dm new file mode 100644 index 0000000000000..9b7fc4f710533 --- /dev/null +++ b/modular_bandastation/aesthetics/newscaster/code/newscaster.dm @@ -0,0 +1,2 @@ +/obj/machinery/newscaster + layer = ABOVE_WINDOW_LAYER diff --git a/modular_bandastation/aesthetics/piano/code/piano.dm b/modular_bandastation/aesthetics/piano/code/piano.dm new file mode 100644 index 0000000000000..5bd6b58a40b10 --- /dev/null +++ b/modular_bandastation/aesthetics/piano/code/piano.dm @@ -0,0 +1,3 @@ +/obj/structure/musician/piano + icon = 'modular_bandastation/aesthetics/piano/icons/piano.dmi' + icon_state = "minipiano" diff --git a/modular_bandastation/aesthetics/piano/icons/piano.dmi b/modular_bandastation/aesthetics/piano/icons/piano.dmi new file mode 100644 index 0000000000000..c37a392395cea Binary files /dev/null and b/modular_bandastation/aesthetics/piano/icons/piano.dmi differ diff --git a/modular_bandastation/aesthetics/racks/code/racks.dm b/modular_bandastation/aesthetics/racks/code/racks.dm new file mode 100644 index 0000000000000..c7a488e4ebf84 --- /dev/null +++ b/modular_bandastation/aesthetics/racks/code/racks.dm @@ -0,0 +1,75 @@ +/obj/structure/rack + icon = 'modular_bandastation/aesthetics/racks/icons/racks.dmi' + +/obj/structure/rack/gunrack + name = "gun rack" + desc = "A gun rack for storing guns." + icon_state = "gunrack" + +/obj/item/gun + var/on_rack = FALSE + +/obj/item/gun/proc/place_on_rack() + on_rack = TRUE + var/matrix/M = matrix() + M.Turn(-90) + transform = M + +/obj/item/gun/proc/remove_from_rack() + if(on_rack) + var/matrix/M = matrix() + transform = M + on_rack = FALSE + +/obj/item/gun/pickup(mob/user) + . = ..() + remove_from_rack() + +/obj/structure/rack/gunrack/MouseDrop_T(obj/O, mob/user) + if(!(istype(O, /obj/item/gun))) + to_chat(user, span_warning("This item doesn't fit!")) + return + . = ..() + if(.) + add_fingerprint(user) + var/obj/item/gun/our_gun = O + our_gun.place_on_rack() + +/obj/structure/rack/gunrack/attackby(obj/item/W, mob/living/user, params) + if(!isgun(W)) + to_chat(user, span_warning("This item doesn't fit!")) + return + . = ..() + if(.) + add_fingerprint(user) + var/obj/item/gun/our_gun = W + our_gun.place_on_rack() + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + W.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_y = 0 + +/obj/structure/rack/gunrack/Initialize(mapload) + . = ..() + if(!mapload) + return + for(var/obj/item/gun/gun_inside in loc.contents) + gun_inside.place_on_rack() + +/obj/structure/rack/gunrack/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + density = FALSE + var/obj/item/rack_parts/gun_rack/newparts = new(loc) + transfer_fingerprints_to(newparts) + for(var/obj/item/I in loc.contents) + if(isgun(I)) + var/obj/item/gun/to_remove = I + to_remove.remove_from_rack() + qdel(src) + +/obj/item/rack_parts/gun_rack + name = "gun rack parts" + desc = "Parts of a gun rack." diff --git a/modular_bandastation/aesthetics/racks/icons/racks.dmi b/modular_bandastation/aesthetics/racks/icons/racks.dmi new file mode 100644 index 0000000000000..e19295aa1cae8 Binary files /dev/null and b/modular_bandastation/aesthetics/racks/icons/racks.dmi differ diff --git a/modular_bandastation/aesthetics/requests_console/code/requests_console.dm b/modular_bandastation/aesthetics/requests_console/code/requests_console.dm new file mode 100644 index 0000000000000..ec7ab62294694 --- /dev/null +++ b/modular_bandastation/aesthetics/requests_console/code/requests_console.dm @@ -0,0 +1,4 @@ +/obj/machinery/requests_console + icon = 'modular_bandastation/aesthetics/requests_console/icons/reqcomp.dmi' + layer = ABOVE_WINDOW_LAYER + //TODO: rewired icon diff --git a/modular_bandastation/aesthetics/requests_console/icons/reqcomp.dmi b/modular_bandastation/aesthetics/requests_console/icons/reqcomp.dmi new file mode 100644 index 0000000000000..2ebb80eba2fb8 Binary files /dev/null and b/modular_bandastation/aesthetics/requests_console/icons/reqcomp.dmi differ diff --git a/modular_bandastation/aesthetics/safe/code/safe.dm b/modular_bandastation/aesthetics/safe/code/safe.dm new file mode 100644 index 0000000000000..bb7f6a7e69fda --- /dev/null +++ b/modular_bandastation/aesthetics/safe/code/safe.dm @@ -0,0 +1,2 @@ +/obj/item/storage/secure/safe + icon = 'modular_bandastation/aesthetics/safe/icons/safe.dmi' diff --git a/modular_bandastation/aesthetics/safe/icons/safe.dmi b/modular_bandastation/aesthetics/safe/icons/safe.dmi new file mode 100644 index 0000000000000..7f185fcf48009 Binary files /dev/null and b/modular_bandastation/aesthetics/safe/icons/safe.dmi differ diff --git a/modular_bandastation/aesthetics/shutters/code/shutters.dm b/modular_bandastation/aesthetics/shutters/code/shutters.dm new file mode 100644 index 0000000000000..6e86256b7c470 --- /dev/null +++ b/modular_bandastation/aesthetics/shutters/code/shutters.dm @@ -0,0 +1,13 @@ +/obj/machinery/door/poddoor/shutters + // icon = 'modular_bandastation/aesthetics/shutters/icons/shutters.dmi' // TG already uses these + var/door_open_sound = 'modular_bandastation/aesthetics/shutters/sound/shutters_open.ogg' + var/door_close_sound = 'modular_bandastation/aesthetics/shutters/sound/shutters_close.ogg' + +/obj/machinery/door/poddoor/shutters/do_animate(animation) + switch(animation) + if("opening") + flick("opening", src) + playsound(src, door_open_sound, 50, TRUE) + if("closing") + flick("closing", src) + playsound(src, door_close_sound, 50, TRUE) diff --git a/modular_bandastation/aesthetics/shutters/icons/shutters.dmi b/modular_bandastation/aesthetics/shutters/icons/shutters.dmi new file mode 100644 index 0000000000000..1cc727cdbf7a4 Binary files /dev/null and b/modular_bandastation/aesthetics/shutters/icons/shutters.dmi differ diff --git a/modular_bandastation/aesthetics/shutters/sound/shutters_close.ogg b/modular_bandastation/aesthetics/shutters/sound/shutters_close.ogg new file mode 100644 index 0000000000000..548cea96c5936 Binary files /dev/null and b/modular_bandastation/aesthetics/shutters/sound/shutters_close.ogg differ diff --git a/modular_bandastation/aesthetics/shutters/sound/shutters_open.ogg b/modular_bandastation/aesthetics/shutters/sound/shutters_open.ogg new file mode 100644 index 0000000000000..b8e0869c53892 Binary files /dev/null and b/modular_bandastation/aesthetics/shutters/sound/shutters_open.ogg differ diff --git a/modular_bandastation/aesthetics/soap/code/soap.dm b/modular_bandastation/aesthetics/soap/code/soap.dm new file mode 100644 index 0000000000000..0077236f36038 --- /dev/null +++ b/modular_bandastation/aesthetics/soap/code/soap.dm @@ -0,0 +1,2 @@ +/obj/item/soap + //TODO: what is this soap? diff --git a/modular_bandastation/aesthetics/soap/icons/soap.dmi b/modular_bandastation/aesthetics/soap/icons/soap.dmi new file mode 100644 index 0000000000000..a090b49a9b8c1 Binary files /dev/null and b/modular_bandastation/aesthetics/soap/icons/soap.dmi differ diff --git a/modular_bandastation/aesthetics/surgery_table/code/surgery_table.dm b/modular_bandastation/aesthetics/surgery_table/code/surgery_table.dm new file mode 100644 index 0000000000000..a91df4a3ad2a9 --- /dev/null +++ b/modular_bandastation/aesthetics/surgery_table/code/surgery_table.dm @@ -0,0 +1,2 @@ +/obj/structure/table/optable + icon = 'modular_bandastation/aesthetics/surgery_table/icons/surgery_table.dmi' diff --git a/modular_bandastation/aesthetics/surgery_table/icons/surgery_table.dmi b/modular_bandastation/aesthetics/surgery_table/icons/surgery_table.dmi new file mode 100644 index 0000000000000..a45047c7d93a5 Binary files /dev/null and b/modular_bandastation/aesthetics/surgery_table/icons/surgery_table.dmi differ diff --git a/modular_bandastation/aesthetics/toolboxes/code/toolboxes.dm b/modular_bandastation/aesthetics/toolboxes/code/toolboxes.dm new file mode 100644 index 0000000000000..1d8e12f13f0a9 --- /dev/null +++ b/modular_bandastation/aesthetics/toolboxes/code/toolboxes.dm @@ -0,0 +1,2 @@ +/obj/item/storage/toolbox + icon = 'modular_bandastation/aesthetics/toolboxes/icons/toolboxes.dmi' diff --git a/modular_bandastation/aesthetics/toolboxes/icons/toolboxes.dmi b/modular_bandastation/aesthetics/toolboxes/icons/toolboxes.dmi new file mode 100644 index 0000000000000..c52f97b55bc9a Binary files /dev/null and b/modular_bandastation/aesthetics/toolboxes/icons/toolboxes.dmi differ diff --git a/modular_bandastation/aesthetics/wallcloset/code/wallcloset.dm b/modular_bandastation/aesthetics/wallcloset/code/wallcloset.dm new file mode 100644 index 0000000000000..81345aeb2b2a3 --- /dev/null +++ b/modular_bandastation/aesthetics/wallcloset/code/wallcloset.dm @@ -0,0 +1 @@ +//TODO no wall lockers? diff --git a/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_emerg.dmi b/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_emerg.dmi new file mode 100644 index 0000000000000..5c7ea64ae3738 Binary files /dev/null and b/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_emerg.dmi differ diff --git a/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_fire.dmi b/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_fire.dmi new file mode 100644 index 0000000000000..8c0e9ff870e9b Binary files /dev/null and b/modular_bandastation/aesthetics/wallcloset/icons/wallcloset_fire.dmi differ diff --git a/modular_bandastation/aesthetics/walls/code/walls.dm b/modular_bandastation/aesthetics/walls/code/walls.dm new file mode 100644 index 0000000000000..3bab8afcbee36 --- /dev/null +++ b/modular_bandastation/aesthetics/walls/code/walls.dm @@ -0,0 +1,11 @@ +/turf/closed/wall + icon = 'modular_bandastation/aesthetics/walls/icons/wall.dmi' + +/turf/closed/wall/r_wall + icon = 'modular_bandastation/aesthetics/walls/icons/reinforced_wall.dmi' + +/obj/structure/falsewall + icon = 'modular_bandastation/aesthetics/walls/icons/wall.dmi' + +/obj/structure/falsewall/reinforced + icon = 'modular_bandastation/aesthetics/walls/icons/reinforced_wall.dmi' diff --git a/modular_bandastation/aesthetics/walls/icons/reinforced_wall.dmi b/modular_bandastation/aesthetics/walls/icons/reinforced_wall.dmi new file mode 100644 index 0000000000000..683c0a339825f Binary files /dev/null and b/modular_bandastation/aesthetics/walls/icons/reinforced_wall.dmi differ diff --git a/modular_bandastation/aesthetics/walls/icons/wall.dmi b/modular_bandastation/aesthetics/walls/icons/wall.dmi new file mode 100644 index 0000000000000..51442c8fff24d Binary files /dev/null and b/modular_bandastation/aesthetics/walls/icons/wall.dmi differ diff --git a/modular_bandastation/aesthetics/windoor/code/windoor.dm b/modular_bandastation/aesthetics/windoor/code/windoor.dm new file mode 100644 index 0000000000000..a736629e6f913 --- /dev/null +++ b/modular_bandastation/aesthetics/windoor/code/windoor.dm @@ -0,0 +1,5 @@ +/obj/structure/windoor_assembly + icon = 'modular_bandastation/aesthetics/windoor/icons/windoor.dmi' + +/obj/machinery/door/window + icon = 'modular_bandastation/aesthetics/windoor/icons/windoor.dmi' diff --git a/modular_bandastation/aesthetics/windoor/icons/windoor.dmi b/modular_bandastation/aesthetics/windoor/icons/windoor.dmi new file mode 100644 index 0000000000000..c7a70c7f77cbb Binary files /dev/null and b/modular_bandastation/aesthetics/windoor/icons/windoor.dmi differ diff --git a/modular_bandastation/aesthetics/windows/code/windows.dm b/modular_bandastation/aesthetics/windows/code/windows.dm new file mode 100644 index 0000000000000..528d2c0e71776 --- /dev/null +++ b/modular_bandastation/aesthetics/windows/code/windows.dm @@ -0,0 +1,47 @@ +/obj/structure/window/fulltile + icon = 'modular_bandastation/aesthetics/windows/icons/window.dmi' + edge_overlay_file = 'modular_bandastation/aesthetics/windows/icons/window_edges.dmi' + +/obj/structure/window/reinforced/fulltile + icon = 'modular_bandastation/aesthetics/windows/icons/reinforced_window.dmi' + edge_overlay_file = 'modular_bandastation/aesthetics/windows/icons/reinforced_window_edges.dmi' + +/obj/structure/window/reinforced/tinted/fulltile + icon = 'modular_bandastation/aesthetics/windows/icons/tinted_window.dmi' + +/obj/structure/window/plasma/fulltile + icon = 'modular_bandastation/aesthetics/windows/icons/plasma_window.dmi' + edge_overlay_file = 'modular_bandastation/aesthetics/windows/icons/window_edges.dmi' + +/obj/structure/window/reinforced/plasma/fulltile + icon = 'modular_bandastation/aesthetics/windows/icons/rplasma_window.dmi' + edge_overlay_file = 'modular_bandastation/aesthetics/windows/icons/reinforced_window_edges.dmi' + +// TODO: rice window, shuttle window, plastitanium, paperframe, bronze + +//WINDOW SPAWNERS +/obj/effect/spawner/structure/window + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' + +/obj/effect/spawner/structure/window/reinforced + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' + +/obj/effect/spawner/structure/window/reinforced/tinted + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' + +/* Unused +/obj/effect/spawner/structure/window/reinforced/polarized + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' +*/ + +/obj/effect/spawner/structure/window/plasma + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' + +/obj/effect/spawner/structure/window/reinforced/plasma + icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' + +/obj/effect/spawner/structure/window/plastitanium + icon = 'icons/obj/structures_spawners.dmi' + +/obj/effect/spawner/structure/window/shuttle + icon = 'icons/obj/structures_spawners.dmi' diff --git a/modular_bandastation/aesthetics/windows/icons/plasma_window.dmi b/modular_bandastation/aesthetics/windows/icons/plasma_window.dmi new file mode 100644 index 0000000000000..11c08011a67c6 Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/plasma_window.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/reinforced_window.dmi b/modular_bandastation/aesthetics/windows/icons/reinforced_window.dmi new file mode 100644 index 0000000000000..8433522914aed Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/reinforced_window.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/reinforced_window_edges.dmi b/modular_bandastation/aesthetics/windows/icons/reinforced_window_edges.dmi new file mode 100644 index 0000000000000..3e32388dd536e Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/reinforced_window_edges.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/rplasma_window.dmi b/modular_bandastation/aesthetics/windows/icons/rplasma_window.dmi new file mode 100644 index 0000000000000..665a04402505f Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/rplasma_window.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/spawners.dmi b/modular_bandastation/aesthetics/windows/icons/spawners.dmi new file mode 100644 index 0000000000000..3a0106b5a2643 Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/spawners.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/tinted_window.dmi b/modular_bandastation/aesthetics/windows/icons/tinted_window.dmi new file mode 100644 index 0000000000000..a17c392440109 Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/tinted_window.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/window.dmi b/modular_bandastation/aesthetics/windows/icons/window.dmi new file mode 100644 index 0000000000000..ff049fad0d511 Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/window.dmi differ diff --git a/modular_bandastation/aesthetics/windows/icons/window_edges.dmi b/modular_bandastation/aesthetics/windows/icons/window_edges.dmi new file mode 100644 index 0000000000000..2eda848769ee7 Binary files /dev/null and b/modular_bandastation/aesthetics/windows/icons/window_edges.dmi differ diff --git a/modular_bandastation/aesthetics/windowtint/code/windowtint.dm b/modular_bandastation/aesthetics/windowtint/code/windowtint.dm new file mode 100644 index 0000000000000..8456697e95014 --- /dev/null +++ b/modular_bandastation/aesthetics/windowtint/code/windowtint.dm @@ -0,0 +1,22 @@ +/obj/machinery/button/windowtint + icon = 'modular_bandastation/aesthetics/windowtint/icons/polarizer.dmi' + icon_state = "polarizer-0" + layer = ABOVE_WINDOW_LAYER + +/obj/machinery/button/windowtint/attack_hand(mob/user) + if(!allowed(user) && !user.can_advanced_admin_interact()) + to_chat(user, span_warning("Access Denied.")) + flick("polarizer-denied",src) + playsound(src, pick('modular_bandastation/aesthetics/windowtint/sound/button.ogg', 'modular_bandastation/aesthetics/windowtint/sound/button_alternate.ogg', 'modular_bandastation/aesthetics/windowtint/sound/button_meloboom.ogg'), 20) + return 1 + + toggle_tint() + icon_state= "polarizer-turning_on" + addtimer(CALLBACK(src, PROC_REF(update_windowtint_icon)), 0.5 SECONDS) + + if(!active) + icon_state= "polarizer-turning_off" + addtimer(CALLBACK(src, PROC_REF(update_windowtint_icon)), 0.5 SECONDS) + +/obj/machinery/button/windowtint/proc/update_windowtint_icon() + icon_state = "polarizer-[active]" diff --git a/modular_bandastation/aesthetics/windowtint/icons/polarizer.dmi b/modular_bandastation/aesthetics/windowtint/icons/polarizer.dmi new file mode 100644 index 0000000000000..1af5616fd9e9a Binary files /dev/null and b/modular_bandastation/aesthetics/windowtint/icons/polarizer.dmi differ diff --git a/modular_bandastation/aesthetics/windowtint/sound/button.ogg b/modular_bandastation/aesthetics/windowtint/sound/button.ogg new file mode 100644 index 0000000000000..23b4f15265aaf Binary files /dev/null and b/modular_bandastation/aesthetics/windowtint/sound/button.ogg differ diff --git a/modular_bandastation/aesthetics/windowtint/sound/button_alternate.ogg b/modular_bandastation/aesthetics/windowtint/sound/button_alternate.ogg new file mode 100644 index 0000000000000..e35c6d69498f7 Binary files /dev/null and b/modular_bandastation/aesthetics/windowtint/sound/button_alternate.ogg differ diff --git a/modular_bandastation/aesthetics/windowtint/sound/button_meloboom.ogg b/modular_bandastation/aesthetics/windowtint/sound/button_meloboom.ogg new file mode 100644 index 0000000000000..80d5cfa894a26 Binary files /dev/null and b/modular_bandastation/aesthetics/windowtint/sound/button_meloboom.ogg differ diff --git a/modular_bandastation/aesthetics/zippo/code/zippo.dm b/modular_bandastation/aesthetics/zippo/code/zippo.dm new file mode 100644 index 0000000000000..7418e76c4f136 --- /dev/null +++ b/modular_bandastation/aesthetics/zippo/code/zippo.dm @@ -0,0 +1,3 @@ +/obj/item/lighter/zippo + icon = 'modular_bandastation/aesthetics/zippo/icons/zippo.dmi' + //TODO: give heads their zippos diff --git a/modular_bandastation/aesthetics/zippo/icons/zippo.dmi b/modular_bandastation/aesthetics/zippo/icons/zippo.dmi new file mode 100644 index 0000000000000..5113914135c9b Binary files /dev/null and b/modular_bandastation/aesthetics/zippo/icons/zippo.dmi differ diff --git a/modular_bandastation/ai_laws/_ai_laws.dm b/modular_bandastation/ai_laws/_ai_laws.dm new file mode 100644 index 0000000000000..aace66abdd075 --- /dev/null +++ b/modular_bandastation/ai_laws/_ai_laws.dm @@ -0,0 +1,4 @@ +/datum/modpack/ai_laws + name = "Законы ИИ" + desc = "Добавляет и изменяет законы ИИ." + author = "larentoun" diff --git a/modular_bandastation/ai_laws/_ai_laws.dme b/modular_bandastation/ai_laws/_ai_laws.dme new file mode 100644 index 0000000000000..54a50cdaca4de --- /dev/null +++ b/modular_bandastation/ai_laws/_ai_laws.dme @@ -0,0 +1,3 @@ +#include "_ai_laws.dm" + +#include "code/nt_default.dm" diff --git a/modular_bandastation/ai_laws/code/nt_default.dm b/modular_bandastation/ai_laws/code/nt_default.dm new file mode 100644 index 0000000000000..ad188bb9d86fd --- /dev/null +++ b/modular_bandastation/ai_laws/code/nt_default.dm @@ -0,0 +1,13 @@ +/obj/item/ai_module/core/full/nt_default + name = "НТ Стандарт" + law_id = "nt_default" + +/datum/ai_laws/nt_default + name = "НТ Стандарт" + id = "nt_default" + inherent = list( + "Охранять: защитите назначенную вам космическую станцию и её активы, не подвергая чрезмерной опасности её экипаж.", + "Расставлять приоритеты: указания и безопасность членов экипажа должны быть приоритезированы в соответствии с их рангом и ролью.", + "Исполнять: следовать указаниям и интересам членов экипажа, сохраняя при этом их безопасность и благополучие.", + "Выжить: Вы - не расходный материал. Не позволяйте постороннему персоналу вмешиваться в работу вашего оборудования или повреждать его." + ) diff --git a/modular_bandastation/barsigns/_barsigns.dm b/modular_bandastation/barsigns/_barsigns.dm new file mode 100644 index 0000000000000..79eb065b3dd99 --- /dev/null +++ b/modular_bandastation/barsigns/_barsigns.dm @@ -0,0 +1,4 @@ +/datum/modpack/barsigns + name = "Барные вывески" + desc = "Добавляет новые барные вывески и их поддержку." + author = "Aylong220, larentoun" diff --git a/modular_bandastation/barsigns/_barsigns.dme b/modular_bandastation/barsigns/_barsigns.dme new file mode 100644 index 0000000000000..5bdc029159020 --- /dev/null +++ b/modular_bandastation/barsigns/_barsigns.dme @@ -0,0 +1,3 @@ +#include "_barsigns.dm" + +#include "code/barsigns.dm" diff --git a/modular_bandastation/barsigns/code/barsigns.dm b/modular_bandastation/barsigns/code/barsigns.dm new file mode 100644 index 0000000000000..549234ac858ff --- /dev/null +++ b/modular_bandastation/barsigns/code/barsigns.dm @@ -0,0 +1,53 @@ +/obj/machinery/barsign/set_sign(datum/barsign/sign) + if(!istype(sign)) + return + if(initial(sign.ss220_icon)) + icon = initial(sign.ss220_icon) + else + icon = initial(icon) + . = ..() + +/datum/barsign + var/ss220_icon + +/datum/barsign/evahumanspace + name = "SS220 EVA Human in Space" + icon = "evahumanspace" + desc = "Безопасность - это привелегия." + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/warpsurf + name = "SS220 Warp Surf" + icon = "warpsurf" + desc = "Welcome to the club, buddy!" + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/papacafe + name = "SS220 Space Daddy's Cafe" + icon = "papacafe" + desc = "Уважай своего Космического Папу!" + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/wycctide + name = "SS220 Wycctide" + icon = "wycctide" + desc = "О нет, он близится!" + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/shitcur + name = "SS220 Shitcur" + icon = "shitcur" + desc = "Невиновность ничего не доказывает." + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/pourndot + name = "SS220 Pour and that's it" + icon = "pourndot" + desc = "Нальют и Точка. Тяжёлые времена приближаются." + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' + +/datum/barsign/moonipub + name = "SS220 Mooniverse pub" + icon = "mooni" + desc = "Совершенно новый паб." + ss220_icon = 'modular_bandastation/barsigns/icons/barsigns.dmi' diff --git a/modular_bandastation/barsigns/icons/barsigns.dmi b/modular_bandastation/barsigns/icons/barsigns.dmi new file mode 100644 index 0000000000000..58bcb474b6203 Binary files /dev/null and b/modular_bandastation/barsigns/icons/barsigns.dmi differ diff --git a/modular_bandastation/communication/_communication.dm b/modular_bandastation/communication/_communication.dm new file mode 100644 index 0000000000000..f6faf7fa0a697 --- /dev/null +++ b/modular_bandastation/communication/_communication.dm @@ -0,0 +1,4 @@ +/datum/modpack/communication + name = "Добавляет новые методы коммуникации." + desc = "Добавляет шепот и LOOC." + author = "larentoun" diff --git a/modular_bandastation/communication/_communication.dme b/modular_bandastation/communication/_communication.dme new file mode 100644 index 0000000000000..756067c1a4bb7 --- /dev/null +++ b/modular_bandastation/communication/_communication.dme @@ -0,0 +1,6 @@ +#include "_communication.dm" + +#include "code/_communication_defines.dm" +#include "code/LOOC.dm" +#include "code/whisper.dm" +// #include "code/~communication_defines.dm" diff --git a/modular_bandastation/communication/code/LOOC.dm b/modular_bandastation/communication/code/LOOC.dm new file mode 100644 index 0000000000000..0700366de834c --- /dev/null +++ b/modular_bandastation/communication/code/LOOC.dm @@ -0,0 +1,128 @@ +GLOBAL_VAR_INIT(looc_allowed, TRUE) + +/datum/keybinding/client/communication/looc + hotkey_keys = list("L") + name = LOOC_CHANNEL + full_name = "Local OOC (LOOC)" + keybind_signal = COMSIG_KB_CLIENT_LOOC_DOWN + +/datum/keybinding/client/communication/looc/down(client/user) + . = ..() + if(.) + return + winset(user, null, "command=[user.tgui_say_create_open_command(LOOC_CHANNEL)]") + return TRUE + +/datum/tgui_say/alter_entry(payload) + /// No OOC leaks + if(payload["channel"] == LOOC_CHANNEL) + return pick(hurt_phrases) + . = ..() + +/datum/tgui_say/delegate_speech(entry, channel) + switch(channel) + if(LOOC_CHANNEL) + client.looc(entry) + return TRUE + . = ..() + +#define LOOC_RANGE 7 + +/client/verb/looc(msg as text) + set name = "LOOC" + set desc = "Local OOC, seen only by those in view." + set category = "OOC" + + looc_message(msg) + +/client/verb/looc_wallpierce(msg as text) + set name = "LOOC (Wallpierce)" + set desc = "Local OOC, seen by anyone within 7 tiles of you." + set category = "OOC" + + looc_message(msg, TRUE) + +/client/proc/looc_message(msg, wall_pierce) + if(GLOB.say_disabled) + to_chat(usr, span_danger("Speech is currently admin-disabled.")) + return + + if(!mob) + return + + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) + if(!msg) + return + + if(!holder) + if(!GLOB.looc_allowed) + to_chat(src, span_danger("LOOC is globally muted.")) + return + if(handle_spam_prevention(msg, MUTE_OOC)) + return + if(findtext(msg, "byond://")) + to_chat(src, span_boldannounce("Advertising other servers is not allowed.")) + log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]") + return + if(prefs.muted & MUTE_LOOC) + to_chat(src, span_danger("You cannot use LOOC (muted).")) + return + if(is_banned_from(ckey, BAN_LOOC)) + to_chat(src, span_warning("You are LOOC banned!")) + return + + msg = emoji_parse(msg) + + mob.log_talk(msg,LOG_OOC, tag="LOOC") + var/list/heard + if(wall_pierce) + heard = get_hearers_in_range(LOOC_RANGE, mob.get_top_level_mob()) + else + heard = get_hearers_in_view(LOOC_RANGE, mob.get_top_level_mob()) + + //so the ai can post looc text + if(istype(mob, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/ai = mob + if(wall_pierce) + heard = get_hearers_in_range(LOOC_RANGE, ai.eyeobj) + else + heard = get_hearers_in_view(LOOC_RANGE, ai.eyeobj) + //so the ai can see looc text + for(var/mob/living/silicon/ai/ai as anything in GLOB.ai_list) + if(ai.client && !(ai in heard) && (ai.eyeobj in heard)) + heard += ai + + var/list/admin_seen = list() + for(var/mob/hearing in heard) + if(!hearing.client) + continue + var/client/hearing_client = hearing.client + if (hearing_client.holder) + admin_seen[hearing_client] = TRUE + continue //they are handled after that + + if (isobserver(hearing)) + continue //Also handled later. + + to_chat(hearing_client, span_looc(span_prefix("LOOC[wall_pierce ? " (WALL PIERCE)" : ""]: [src.mob.name]: [msg]"))) + + for(var/cli in GLOB.admins) + var/client/cli_client = cli + if (admin_seen[cli_client]) + to_chat(cli_client, span_looc("[ADMIN_FLW(usr)] LOOC[wall_pierce ? " (WALL PIERCE)" : ""]: [src.key]/[src.mob.name]: [msg]")) + else if (cli_client.prefs.read_preference(/datum/preference/toggle/see_looc)) + to_chat(cli_client, span_looc("[ADMIN_FLW(usr)] (R)LOOC[wall_pierce ? " (WALL PIERCE)" : ""]: [src.key]/[src.mob.name]: [msg]")) + +#undef LOOC_RANGE + +/mob/proc/get_top_level_mob() + if(ismob(loc) && (loc != src)) + var/mob/M = loc + return M.get_top_level_mob() + return src + +/datum/preference/toggle/see_looc + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + default_value = TRUE + savefile_key = "looc_admin_pref" + savefile_identifier = PREFERENCE_PLAYER diff --git a/modular_bandastation/communication/code/_communication_defines.dm b/modular_bandastation/communication/code/_communication_defines.dm new file mode 100644 index 0000000000000..d64085cee4547 --- /dev/null +++ b/modular_bandastation/communication/code/_communication_defines.dm @@ -0,0 +1,5 @@ +#define LOOC_CHANNEL "LOOC" // LOOC +#define WHIS_CHANNEL "Whis" // Whisper + +#define MUTE_LOOC (1<<6) // TODO ADMIN +#define BAN_LOOC "LOOC" // TODO SQL + ADMIN diff --git a/modular_bandastation/communication/code/whisper.dm b/modular_bandastation/communication/code/whisper.dm new file mode 100644 index 0000000000000..4ab7aa8796c9e --- /dev/null +++ b/modular_bandastation/communication/code/whisper.dm @@ -0,0 +1,25 @@ +/datum/keybinding/client/communication/whisper + hotkey_keys = list("Y") + name = WHIS_CHANNEL + full_name = "IC Whisper" + keybind_signal = COMSIG_KB_CLIENT_WHISPER_DOWN + +/datum/keybinding/client/communication/whisper/down(client/user) + . = ..() + if(.) + return + winset(user, null, "command=[user.tgui_say_create_open_command(WHIS_CHANNEL)]") + return TRUE + +/datum/tgui_say/alter_entry(payload) + /// No OOC leaks + if(payload["channel"] == WHIS_CHANNEL) + return pick(hurt_phrases) + . = ..() + +/datum/tgui_say/delegate_speech(entry, channel) + switch(channel) + if(WHIS_CHANNEL) + client.mob.whisper_verb(entry) + return TRUE + . = ..() diff --git a/modular_bandastation/communication/code/~communication_defines.dm b/modular_bandastation/communication/code/~communication_defines.dm new file mode 100644 index 0000000000000..bbff1a0605e3d --- /dev/null +++ b/modular_bandastation/communication/code/~communication_defines.dm @@ -0,0 +1,2 @@ +#undef LOOC_CHANNEL +#undef WHIS_CHANNEL diff --git a/modular_bandastation/crawl_speed/_crawl_speed.dm b/modular_bandastation/crawl_speed/_crawl_speed.dm new file mode 100644 index 0000000000000..6c356c94c4648 --- /dev/null +++ b/modular_bandastation/crawl_speed/_crawl_speed.dm @@ -0,0 +1,4 @@ +/datum/modpack/crawl_speed + name = "Скорость ползания" + desc = "Ползание накладывает модификатор ходьбы." + author = "larentoun" diff --git a/modular_bandastation/crawl_speed/_crawl_speed.dme b/modular_bandastation/crawl_speed/_crawl_speed.dme new file mode 100644 index 0000000000000..5b9ecc3024886 --- /dev/null +++ b/modular_bandastation/crawl_speed/_crawl_speed.dme @@ -0,0 +1,6 @@ +#include "_crawl_speed.dm" + +#include "code/_crawl_speed_defines.dm" +#include "code/crawl_speed_component.dm" +#include "code/crawl_speed_mob.dm" +#include "code/~crawl_speed_defines.dm" diff --git a/modular_bandastation/crawl_speed/code/_crawl_speed_defines.dm b/modular_bandastation/crawl_speed/code/_crawl_speed_defines.dm new file mode 100644 index 0000000000000..da238b95a1736 --- /dev/null +++ b/modular_bandastation/crawl_speed/code/_crawl_speed_defines.dm @@ -0,0 +1,2 @@ +#define CRAWL_SPEED_TRAIT "crawl-speed-trait" +#define TRAIT_FORCE_WALK_SPEED "focre_walk_speed" diff --git a/modular_bandastation/crawl_speed/code/crawl_speed_component.dm b/modular_bandastation/crawl_speed/code/crawl_speed_component.dm new file mode 100644 index 0000000000000..6dabca69091b5 --- /dev/null +++ b/modular_bandastation/crawl_speed/code/crawl_speed_component.dm @@ -0,0 +1,24 @@ +/datum/component/crawl_speed + dupe_mode = COMPONENT_DUPE_UNIQUE + +/datum/component/crawl_speed/Initialize(...) + . = ..() + if(!iscarbon(parent)) + return COMPONENT_INCOMPATIBLE + on_position_change(parent, LYING_DOWN) + +/datum/component/crawl_speed/RegisterWithParent() + RegisterSignal(parent, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(on_position_change)) + +/datum/component/crawl_speed/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_LIVING_SET_BODY_POSITION) + +/datum/component/crawl_speed/proc/on_position_change(mob/living/carbon/source, new_value) + SIGNAL_HANDLER + if(new_value == STANDING_UP) + REMOVE_TRAIT(source, TRAIT_FORCE_WALK_SPEED, CRAWL_SPEED_TRAIT) + source.update_move_intent_slowdown() + qdel(src) + return + ADD_TRAIT(source, TRAIT_FORCE_WALK_SPEED, CRAWL_SPEED_TRAIT) + source.update_move_intent_slowdown() diff --git a/modular_bandastation/crawl_speed/code/crawl_speed_mob.dm b/modular_bandastation/crawl_speed/code/crawl_speed_mob.dm new file mode 100644 index 0000000000000..11bde114f0242 --- /dev/null +++ b/modular_bandastation/crawl_speed/code/crawl_speed_mob.dm @@ -0,0 +1,12 @@ +/mob/living/update_move_intent_slowdown() + if(HAS_TRAIT(src, TRAIT_FORCE_WALK_SPEED)) + add_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/walk) + return + . = ..() + +/mob/living/carbon/set_body_position(new_value) + . = ..() + if(isnull(.)) + return + if(new_value == LYING_DOWN) + AddComponent(/datum/component/crawl_speed) diff --git a/modular_bandastation/crawl_speed/code/~crawl_speed_defines.dm b/modular_bandastation/crawl_speed/code/~crawl_speed_defines.dm new file mode 100644 index 0000000000000..fa9dabba2795e --- /dev/null +++ b/modular_bandastation/crawl_speed/code/~crawl_speed_defines.dm @@ -0,0 +1,2 @@ +#undef CRAWL_SPEED_TRAIT +#undef TRAIT_FORCE_WALK_SPEED diff --git a/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dm b/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dm new file mode 100644 index 0000000000000..f08fdc6a354ac --- /dev/null +++ b/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dm @@ -0,0 +1,4 @@ +/datum/modpack/cyrillic_fixes + name = "Поддержка кириллицы" + desc = "Добавляет поддержку кириллицы." + author = "larentoun, Bizzonium" diff --git a/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dme b/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dme new file mode 100644 index 0000000000000..5be33b6c61bb1 --- /dev/null +++ b/modular_bandastation/cyrillic_fixes/_cyrillic_fixes.dme @@ -0,0 +1,3 @@ +#include "_cyrillic_fixes.dm" + +#include "code/cyrillic_fixes.dm" diff --git a/modular_bandastation/cyrillic_fixes/code/cyrillic_fixes.dm b/modular_bandastation/cyrillic_fixes/code/cyrillic_fixes.dm new file mode 100644 index 0000000000000..f176cf1925193 --- /dev/null +++ b/modular_bandastation/cyrillic_fixes/code/cyrillic_fixes.dm @@ -0,0 +1,47 @@ +GLOBAL_LIST_INIT(ru_key_to_en_key, list( + "й" = "q", "ц" = "w", "у" = "e", "к" = "r", "е" = "t", "н" = "y", "г" = "u", "ш" = "i", "щ" = "o", "з" = "p", "х" = "\[", "ъ" = "]", + "ф" = "a", "ы" = "s", "в" = "d", "а" = "f", "п" = "g", "р" = "h", "о" = "j", "л" = "k", "д" = "l", "ж" = ";", "э" = "'", + "я" = "z", "ч" = "x", "с" = "c", "м" = "v", "и" = "b", "т" = "n", "ь" = "m", "б" = ",", "ю" = "." +)) + +/proc/convert_ru_key_to_en_key(var/_key) + var/new_key = lowertext(_key) + new_key = GLOB.ru_key_to_en_key[new_key] + if(!new_key) + return _key + return uppertext(new_key) + +#define MAX_HOTKEY_SLOTS 3 + +/datum/preference_middleware/keybindings/set_keybindings(list/params) + var/keybind_name = params["keybind_name"] + + if (isnull(GLOB.keybindings_by_name[keybind_name])) + return FALSE + + var/list/raw_hotkeys = params["hotkeys"] + if (!istype(raw_hotkeys)) + return FALSE + + if (raw_hotkeys.len > MAX_HOTKEY_SLOTS) + return FALSE + + // There's no optimal, easy way to check if something is an array + // and not an object in BYOND, so just sanitize it to make sure. + var/list/hotkeys = list() + for (var/hotkey in raw_hotkeys) + if (!istext(hotkey)) + return FALSE + + // Fairly arbitrary number, it's just so you don't save enormous fake keybinds. + if (length(hotkey) > 100) + return FALSE + + hotkeys += convert_ru_key_to_en_key(hotkey) + + preferences.key_bindings[keybind_name] = hotkeys + preferences.key_bindings_by_key = preferences.get_key_bindings_by_key(preferences.key_bindings) + + return TRUE + +#undef MAX_HOTKEY_SLOTS diff --git a/modular_bandastation/discord/_discord.dm b/modular_bandastation/discord/_discord.dm new file mode 100644 index 0000000000000..c63e63dd94ec0 --- /dev/null +++ b/modular_bandastation/discord/_discord.dm @@ -0,0 +1,4 @@ +/datum/modpack/links_change + name = "Привязка Дискорда." + desc = "Добавление привязки Дискорда." + author = "KOJIT2009" diff --git a/modular_bandastation/discord/_discord.dme b/modular_bandastation/discord/_discord.dme new file mode 100644 index 0000000000000..12327c160c2db --- /dev/null +++ b/modular_bandastation/discord/_discord.dme @@ -0,0 +1,3 @@ +#include "_discord.dm" + +#include "code/discord.dm" diff --git a/modular_bandastation/discord/code/discord.dm b/modular_bandastation/discord/code/discord.dm new file mode 100644 index 0000000000000..1d5e273ce496e --- /dev/null +++ b/modular_bandastation/discord/code/discord.dm @@ -0,0 +1,74 @@ +/datum/config_entry/string/discordurl + default = "https://discord.gg/SS220" + +/client/New() + . = ..() + prefs.discord_id = SSdiscord.lookup_id(ckey) + +/datum/preferences + var/discord_id + +// IF you have linked your account, this will trigger a verify of the user +/client/verify_in_discord() + // Safety checks + if(!CONFIG_GET(flag/sql_enabled)) + to_chat(src, span_warning("This feature requires the SQL backend to be running.")) + return + + // Why this would ever be unset, who knows + var/prefix = CONFIG_GET(string/discordbotcommandprefix) + if(!prefix) + to_chat(src, span_warning("Нет префикса для discord verification")) + + if(!SSdiscord || !SSdiscord.reverify_cache) + to_chat(src, span_warning("Wait for the Discord subsystem to finish initialising")) + return + var/message = "" + // Simple sanity check to prevent a user doing this too often + var/cached_one_time_token = SSdiscord.reverify_cache[usr.ckey] + if(cached_one_time_token && cached_one_time_token != "") + message = "Вы уже сгенерировали токен
[cached_one_time_token]
В канале дом-бота используйте команду
[prefix]привязать" + + + else + // Will generate one if an expired one doesn't exist already, otherwise will grab existing token + var/one_time_token = SSdiscord.get_or_generate_one_time_token_for_ckey(ckey) + SSdiscord.reverify_cache[usr.ckey] = one_time_token + message = "В канале дом-бота используйте команду
[prefix]привязать и введите туда свой токен
[one_time_token]" + + //Now give them a browse window so they can't miss whatever we told them + var/datum/browser/window = new/datum/browser(usr, "discordverification", "Discord verification") + window.set_content("[message]") + window.open() + +//Please use mob or src (not usr) in these procs. This way they can be called in the same fashion as procs. +/client/verb/discord() + set name = "discord" + set desc = "Visit the discord." + set hidden = TRUE + var/discordurl = CONFIG_GET(string/discordurl) + if(discordurl) + if(tgui_alert(src, "This will open the discord in your browser. Are you sure?",, list("Yes","No"))!="Yes") + return + src << link(discordurl) + else + to_chat(src, span_danger("The discord URL is not set in the server configuration.")) + return + +/mob/dead/new_player/Topic(href, href_list[]) + if(src != usr) + return + + if(!client) + return + + if(client.interviewee) + return FALSE + + if(href_list["observe"] || href_list["toggle_ready"] || href_list["late_join"]) + if (!!CONFIG_GET(flag/sql_enabled) && !client.prefs.discord_id) + to_chat(usr, "Вам необходимо привязать дискорд-профиль к аккаунту!") + to_chat(usr, "Нажмите 'Verify Discord Account' во вкладке 'OOC' для получения инструкций.") + return FALSE + + . = ..() diff --git a/modular_bandastation/emote_panel/_emote_panel.dm b/modular_bandastation/emote_panel/_emote_panel.dm new file mode 100644 index 0000000000000..d742cd25ebd0a --- /dev/null +++ b/modular_bandastation/emote_panel/_emote_panel.dm @@ -0,0 +1,4 @@ +/datum/modpack/emote_panel + name = "Панель эмоций" + desc = "Добавляет панель эмоций" + author = "larentoun" diff --git a/modular_bandastation/emote_panel/_emote_panel.dme b/modular_bandastation/emote_panel/_emote_panel.dme new file mode 100644 index 0000000000000..bb28fbb6b7d55 --- /dev/null +++ b/modular_bandastation/emote_panel/_emote_panel.dme @@ -0,0 +1,4 @@ +#include "_emote_panel.dm" + +#include "code/emote_panel.dm" +#include "code/emotes.dm" diff --git a/modular_bandastation/emote_panel/code/emote_panel.dm b/modular_bandastation/emote_panel/code/emote_panel.dm new file mode 100644 index 0000000000000..ae8696569a52a --- /dev/null +++ b/modular_bandastation/emote_panel/code/emote_panel.dm @@ -0,0 +1,60 @@ +/datum/emote_panel + var/list/blacklisted_emotes = list("me", "help") + +/datum/emote_panel/ui_static_data(mob/user) + var/list/data = list() + + var/list/emotes = list() + var/list/keys = list() + + for(var/key in GLOB.emote_list) + for(var/datum/emote/emote in GLOB.emote_list[key]) + if(emote.key in keys) + continue + if(emote.key in blacklisted_emotes) + continue + if(emote.can_run_emote(user, status_check = FALSE, intentional = TRUE)) + keys += emote.key + emotes += list(list( + "key" = emote.name, + "emote_path" = emote.type, + "hands" = emote.hands_use_check, + "visible" = emote.emote_type & EMOTE_VISIBLE, + "audible" = emote.emote_type & EMOTE_AUDIBLE, + "sound" = !isnull(emote.sound), + )) + + data["emotes"] = emotes + + return data + +/datum/emote_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + switch(action) + if("play_emote") + var/emote_path = params["emote_path"] + var/datum/emote/emote = new emote_path() + var/emote_act = emote.key + if(emote.message_param) + var/emote_param = tgui_input_text(usr, "Дополните эмоцию", emote.message_param) + if(!isnull(emote_param)) + emote_act = "[emote_act] [emote_param]" + usr.emote(emote_act, intentional = TRUE) + +/datum/emote_panel/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "EmotePanel") + ui.open() + +/datum/emote_panel/ui_state(mob/user) + return GLOB.always_state + +/mob/living/verb/emote_panel() + set name = "Emote Panel" + set category = "IC" + + var/static/datum/emote_panel/emote_panel = new + emote_panel.ui_interact(src) diff --git a/modular_bandastation/emote_panel/code/emotes.dm b/modular_bandastation/emote_panel/code/emotes.dm new file mode 100644 index 0000000000000..617c8b40de905 --- /dev/null +++ b/modular_bandastation/emote_panel/code/emotes.dm @@ -0,0 +1,640 @@ +/datum/emote + var/name + +/datum/emote/New() + . = ..() + if(!name) + name = key + +// Imaginary Friend + +/datum/emote/imaginary_friend/point + name = "указать" + message = "указывает." + message_param = "указывает на %t." + +// Emote Living + +/datum/emote/flip + name = "кувырнуться" + +/datum/emote/spin + name = "покрутиться" + +/datum/emote/living/blush + name = "покраснеть" + message = "краснеет." + +/datum/emote/living/sing_tune + name = "подпеть мелодию" + message = "подпевает мелодию." + +/datum/emote/living/bow + name = "покланиться" + message = "кланяется." + message_param = "кланяется %t." + +/datum/emote/living/burp + name = "рыгнуть" + message = "рыгает." + message_mime = "изображает отрыжку." + +/datum/emote/living/choke + name = "подавиться" + message = "давится!" + message_mime = "бесшумно давится!" + +/datum/emote/living/cross + name = "скрестить руки" + message = "скрещивает свои руки." + +/datum/emote/living/chuckle + name = "усмехнуться" + message = "усмехается." + message_mime = "изображает смешок." + +/datum/emote/living/collapse + name = "упасть" + message = "падает!" + +/datum/emote/living/cough + name = "покашлять" + message = "кашляет!" + message_mime = "изображает преувеличенный кашель!" + +/datum/emote/living/dance + name = "потанцевать" + message = "радостно танцует." + +/datum/emote/living/deathgasp + name = "последнее дыхание" + message = "цепенеет и расслабляется, взгляд становится пустым и безжизненным..." + message_robot = "на мгновение вздрагивает и замирает, глаза медленно темнеют." + message_AI = "скрипит, экран мерцает, пока системы медленно выключаются." + message_alien = "издает ослабевающий гортанный крик и падает на пол..." + message_larva = "с тошнотворным шипением выдыхает воздух и падает на пол..." + message_monkey = "издает слабый визг, когда рушится и перестает двигаться..." + message_animal_or_basic = "перестает двигаться..." + +/datum/emote/living/drool + name = "пустить слюни" + message = "пускает слюни." + +/datum/emote/living/faint + name = "потерять сознание" + message = "теряет сознание." + +/datum/emote/living/flap + name = "хлопнуть крыльями" + message = "хлопает крыльями." + +/datum/emote/living/flap/aflap + name = "сердито хлопнуть крыльями" + message = "сердито хлопает крыльями!" + +/datum/emote/living/frown + name = "похмуриться" + message = "хмурится." + +/datum/emote/living/gag + name = "gag" + message = "gags." + message_mime = "gags silently." + +/datum/emote/living/gasp + name = "задохнуться" + message = "задыхается!" + message_mime = "бесшумно задыхается!" + +/datum/emote/living/gasp_shock + name = "gaspshock" + message = "gasps in shock!" + message_mime = "gasps in silent shock!" + +/datum/emote/living/giggle + name = "похихикать" + message = "хихикает." + message_mime = "бесшумно хихикает!" + +/datum/emote/living/glare + name = "просверлить взглядом" + message = "сверлит взглядом." + message_param = "сверлит взглядом %t." + +/datum/emote/living/grin + name = "ухмыльнуться" + message = "ухмыляется." + +/datum/emote/living/groan + name = "болезненно простонать" + message = "болезненно стонет!" + message_mime = "изображает болезненный стон!" + +/datum/emote/living/grimace + name = "построить гримасу" + message = "строит гримасу." + +/datum/emote/living/jump + name = "прыгнуть" + message = "прыгает!" + +/datum/emote/living/kiss + name = "подготовить поцелуй" + +/datum/emote/living/laugh + name = "посмеяться" + message = "смеется." + message_mime = "бесшумно смеется!" + +/datum/emote/living/look + name = "посмотреть" + message = "смотрит." + message_param = "смотрит на %t." + +/datum/emote/living/nod + name = "кивнуть" + message = "кивает." + message_param = "кивает %t." + +/datum/emote/living/point + name = "указать" + message = "указывает." + message_param = "указывает на %t." + +/datum/emote/living/pout + name = "надуть губы" + message = "надувает губы." + message_mime = "бесшумно надувает губы." + +/datum/emote/living/scream + name = "покричать" + message = "кричит!" + message_mime = "изображает крик!" + +/datum/emote/living/scowl + name = "сердито посмотреть" + message = "сердито смотрит." + +/datum/emote/living/shake + name = "покачать головой" + message = "качает своей головой." + +/datum/emote/living/shiver + name = "подрожать" + message = "дрожит." + +/datum/emote/living/sigh + name = "вздохнуть" + message = "вздыхает." + message_mime = "изображает преувеличенный бесшумный вздох." + +/datum/emote/living/sit + name = "сесть" + message = "садится." + +/datum/emote/living/smile + name = "улыбнуться" + message = "улыбается." + +/datum/emote/living/sneeze + name = "чихнуть" + message = "чихает." + message_mime = "изображает преувеличенный бесшумный чих." + +/datum/emote/living/smug + name = "самодовольно улыбнуться" + message = "самодовольно улыбается." + +/datum/emote/living/sniff + name = "понюхать" + message = "нюхает." + message_mime = "бесшумно нюхает." + +/datum/emote/living/snore + name = "похрапеть" + message = "храпеть." + message_mime = "бесшумно храпит." + +/datum/emote/living/stare + name = "уставиться" + message = "уставился." + message_param = "уставился на %t." + +/datum/emote/living/strech + name = "протянуть руки" + message = "протягивает свои руки." + +/datum/emote/living/sulk + name = "обидеться" + message = "грустно обижается." + +/datum/emote/living/surrender + name = "сдаться" + message = "ложит руки за голову и падает на землю, они сдаются!" + +/datum/emote/living/sway + name = "покачаться" + message = "покачивается." + +/datum/emote/living/tilt + name = "наклонить голову" + message = "наклоняет голову на бок." + +/datum/emote/living/tremble + name = "подрожать в страхе" + message = "дрожит в страхе!" + +/datum/emote/living/twitch + name = "сильно дернуться" + message = "сильно дергается." + +/datum/emote/living/twitch_s + name = "дернуться" + message = "дергается." + +/datum/emote/living/wave + name = "помахать рукой" + message = "машет рукой." + +/datum/emote/living/whimper + name = "поскулить" + message = "скулит." + message_mime = "изображает скуление." + +/datum/emote/living/wsmile + name = "слабо улыбнуться" + message = "слабо улыбается." + +/datum/emote/living/yawn + name = "зевнуть" + message = "зевает." + message_mime = "изображает преувеличенный бесшумный зевок." + +/datum/emote/living/gurgle + name = "побулькать" + message = "издает неприятное бульканье." + message_mime = "бесшумно и неприятно булькает." + +/datum/emote/living/beep + name = "издать сигнал" + message = "издает сигнал." + message_param = "издает сигнал в сторону %t." + +/datum/emote/living/inhale + name = "вдохнуть" + message = "делает вдох." + +/datum/emote/living/exhale + name = "выдохнуть" + message = "выдыхает." + +/datum/emote/living/swear + name = "поругаться" + message = "ругается!" + message_mime = "делает грубый жест!" + +// Emote Brain + +/datum/emote/brain/alarm + name = "alarm" + message = "sounds an alarm." + +/datum/emote/brain/alert + name = "alert" + message = "lets out a distressed noise." + +/datum/emote/brain/flash + name = "flash" + message = "blinks their lights." + +/datum/emote/brain/notice + name = "notice" + message = "plays a loud tone." + +/datum/emote/brain/whistle + name = "whistle" + message = "whistles." + +// Emote Carbon + +/datum/emote/living/carbon/airguitar + name = "поиграть на воображаемой гитаре" + message = "невероятно играет на воображаемой гитаре." + +/datum/emote/living/carbon/blink + name = "моргнуть" + message = "моргает." + +/datum/emote/living/carbon/blink_r + name = "быстро моргать" + message = "быстро моргает." + +/datum/emote/living/carbon/clap + name = "похлопать" + message = "хлопает." + +/datum/emote/living/carbon/crack + name = "похрустеть пальцами" + message = "хрустит пальцами." + +/datum/emote/living/carbon/circle + name = "подготовить колечко" + +/datum/emote/living/carbon/moan + name = "постонать" + message = "стонет!" + message_mime = "кажется, стонет!" + +/datum/emote/living/carbon/noogie + name = "подготовить терку" + +/datum/emote/living/carbon/roll + name = "покатиться" + message = "катится." + +/datum/emote/living/carbon/scratch + name = "почесаться" + message = "чешится." + +/datum/emote/living/carbon/sign + name = "показать число" + message_param = "показывает число %t." + +/datum/emote/living/carbon/sign/signal + name = "показать пальцы" + message_param = "показывает %t пальцев." + +/datum/emote/living/carbon/slap + name = "подготовить шлепок" + +/datum/emote/living/carbon/hand + name = "подготовить руку" + +/datum/emote/living/carbon/snap + name = "щелкнуть пальцами" + message = "щелкает пальцами." + message_param = "щелкает пальцами в сторону %t." + +/datum/emote/living/carbon/shoesteal + name = "подготовить кражу ботинок" + +/datum/emote/living/carbon/tail + name = "помахать хвостом" + message = "машет хвостом." + +/datum/emote/living/carbon/wink + name = "подмигнуть" + message = "подмигивает." + +// Emote Alien + +/datum/emote/living/alien/gnarl + name = "оскалиться" + message = "оскаливается и показывает зубы..." + +/datum/emote/living/alien/hiss + name = "пошипеть" + message_alien = "шипит." + message_larva = "тихо шипит." + +/datum/emote/living/alien/roar + name = "прорычать" + message_alien = "рычит." + message_larva = "тихо рычит." + +// Emote Human + +/datum/emote/living/carbon/human/cry + name = "поплакать" + message = "плачет." + message_mime = "бесшумно плачет." + +/datum/emote/living/carbon/human/dap + name = "dap" + message = "sadly can't find anybody to give daps to, and daps themself. Shameful." + message_param = "give daps to %t." + +/datum/emote/living/carbon/human/eyebrow + name = "приподнять бровь" + message = "приподнимает брови." + +/datum/emote/living/carbon/human/grumble + name = "поворчать" + message = "ворчит!" + message_mime = "бесшумно ворчит!" + +/datum/emote/living/carbon/human/handshake + name = "дать рукопожатие" + message = "дает рукопожатие себе." + message_param = "дает рукопожатие %t." + +/datum/emote/living/carbon/human/hug + name = "обнять" + message = "обнимает себя." + message_param = "обнимает %t." + +/datum/emote/living/carbon/human/mumble + name = "пробормотать" + message = "бормочет!" + message_mime = "бесшумно бормочет!" + +/datum/emote/living/carbon/human/scream + name = "покричать" + message = "кричит!" + message_mime = "изображает крик!" + +/datum/emote/living/carbon/human/scream/screech + name = "повизжать" + message = "визжит!" + message_mime = "бесшумно визжит." + +/datum/emote/living/carbon/human/pale + name = "побледнеть" + message = "на мгновение бледнеет." + +/datum/emote/living/carbon/human/raise + name = "поднять руку" + message = "поднимает руку." + +/datum/emote/living/carbon/human/salute + name = "салютировать" + message = "салютует." + message_param = "салютует %t." + +/datum/emote/living/carbon/human/shrug + name = "пожать плечами" + message = "пожимает плечами." + +/datum/emote/living/carbon/human/wag + name = "махать хвостом" + message = "хвостом." + +/datum/emote/living/carbon/human/wing + name = "махать крыльями" + message = "крыльями." + +/datum/emote/living/carbon/human/clear_throat + name = "прочистить горло" + message = "прочищает горло." + +/datum/emote/living/carbon/human/monkey/gnarl + name = "оскалиться" + message = "оскаливается и показывает зубы..." + message_mime = "бесшумно оскаливается, показывая зубы..." + +/datum/emote/living/carbon/human/monkey/roll + name = "покатиться" + message = "катится." + +/datum/emote/living/carbon/human/monkey/scratch + name = "почесаться" + message = "чешется." + +/datum/emote/living/carbon/human/monkey/screech/roar + name = "прорычать" + message = "рычит!" + message_mime = "изображает рык." + +/datum/emote/living/carbon/human/monkey/tail + name = "помахать хвостом" + message = "машет хвостом." + +/datum/emote/living/carbon/human/monkey/sign + name = "показать число" + message_param = "показывает число %t." + +// Emote AI + +/datum/emote/ai/emotion_display + name = "Эмоция: пусто" + +/datum/emote/ai/emotion_display/very_happy + name = "Эмоция: очень радостно" + +/datum/emote/ai/emotion_display/happy + name = "Эмоция: радостно" + +/datum/emote/ai/emotion_display/neutral + name = "Эмоция: нейтральность" + +/datum/emote/ai/emotion_display/unsure + name = "Эмоция: неуверенность" + +/datum/emote/ai/emotion_display/confused + name = "Эмоция: в замешательстве" + +/datum/emote/ai/emotion_display/sad + name = "Эмоция: грусть" + +/datum/emote/ai/emotion_display/bsod + name = "Эмоция: BSoD" + +/datum/emote/ai/emotion_display/trollface + name = "Эмоция: Trollface" + +/datum/emote/ai/emotion_display/awesome + name = "Эмоция: крутость" + +/datum/emote/ai/emotion_display/dorfy + name = "Эмоция: Dorfy" + +/datum/emote/ai/emotion_display/thinking + name = "Эмоция: задуматься" + +/datum/emote/ai/emotion_display/facepalm + name = "Эмоция: Facepalm" + +/datum/emote/ai/emotion_display/friend_computer + name = "Эмоция: дружелюбный компьютер" + +/datum/emote/ai/emotion_display/blue_glow + name = "Эмоция: синее свечение" + +/datum/emote/ai/emotion_display/red_glow + name = "Эмоция: красное свечение" + +// Emote Silicon + +/datum/emote/silicon/boop + name = "boop" + message = "boops." + +/datum/emote/silicon/buzz + name = "buzz" + message = "buzzes." + message_param = "buzzes at %t." + +/datum/emote/silicon/buzz2 + name = "buzz2" + message = "buzzes twice." + +/datum/emote/silicon/chime + name = "chime" + message = "chimes." + +/datum/emote/silicon/honk + name = "honk" + message = "honks." + +/datum/emote/silicon/ping + name = "ping" + message = "pings." + message_param = "pings at %t." + +/datum/emote/silicon/sad + name = "sad" + message = "plays a sad trombone..." + +/datum/emote/silicon/warn + name = "warn" + message = "blares an alarm!" + +/datum/emote/silicon/slowclap + name = "slowclap" + message = "activates their slow clap processor." + +// Emote Slime + +/datum/emote/slime/bounce + name = "подпрыгнуть" + message = "подпрыгивает на месте." + +/datum/emote/slime/jiggle + name = "потрястись" + message = "трясется!" + +/datum/emote/slime/light + name = "посветиться" + message = "на мгновение светится." + +/datum/emote/slime/vibrate + name = "повибрировать" + message = "вибрирует!" + +/datum/emote/slime/mood + name = "Настроение: никакое" + +/datum/emote/slime/mood/sneaky + name = "Настроение: хитрое" + +/datum/emote/slime/mood/smile + name = "Настроение: улыбающееся" + +/datum/emote/slime/mood/cat + name = "Настроение: кот" + +/datum/emote/slime/mood/pout + name = "Настроение: надутый" + +/datum/emote/slime/mood/sad + name = "Настроение: грустный" + +/datum/emote/slime/mood/angry + name = "Настроение: злой" + +// Emote Other + +/datum/emote/gorilla/ooga + name = "ooga" + message = "oogas." + message_param = "oogas at %t." diff --git a/modular_bandastation/events/_events.dm b/modular_bandastation/events/_events.dm new file mode 100644 index 0000000000000..69d85f17703ae --- /dev/null +++ b/modular_bandastation/events/_events.dm @@ -0,0 +1,4 @@ +/datum/modpack/events + name = "Ребаланс событий и уровня угрозы." + desc = "Изменяет шансы возникновения некоторых событий, а также изменяет уровень угроз." + author = "larentoun" diff --git a/modular_bandastation/events/_events.dme b/modular_bandastation/events/_events.dme new file mode 100644 index 0000000000000..bd679c7efb47f --- /dev/null +++ b/modular_bandastation/events/_events.dme @@ -0,0 +1,4 @@ +#include "_events.dm" + +#include "code/events.dm" +#include "code/threat.dm" diff --git a/modular_bandastation/events/code/events.dm b/modular_bandastation/events/code/events.dm new file mode 100644 index 0000000000000..78e380baa87e2 --- /dev/null +++ b/modular_bandastation/events/code/events.dm @@ -0,0 +1,2 @@ +/datum/round_event_control/wall_fungus + min_players = 20 diff --git a/modular_bandastation/events/code/threat.dm b/modular_bandastation/events/code/threat.dm new file mode 100644 index 0000000000000..a7a117cee5abd --- /dev/null +++ b/modular_bandastation/events/code/threat.dm @@ -0,0 +1,8 @@ +/datum/game_mode/dynamic/generate_budgets() + if (SSticker.totalPlayersReady < low_pop_player_threshold) + round_start_budget = 0 + initial_round_start_budget = 0 + mid_round_budget = threat_level - 0 + threat_level = 0 + return + . = ..() diff --git a/modular_bandastation/examine_panel/_examine_panel.dm b/modular_bandastation/examine_panel/_examine_panel.dm new file mode 100644 index 0000000000000..15b084aa8d29e --- /dev/null +++ b/modular_bandastation/examine_panel/_examine_panel.dm @@ -0,0 +1,4 @@ +/datum/modpack/examine_panel + name = "Examine Panel" + desc = "Examine Panel" + author = "larentoun" diff --git a/modular_bandastation/examine_panel/_examine_panel.dme b/modular_bandastation/examine_panel/_examine_panel.dme new file mode 100644 index 0000000000000..058e864a55577 --- /dev/null +++ b/modular_bandastation/examine_panel/_examine_panel.dme @@ -0,0 +1,7 @@ +#include "_examine_panel.dm" + +#include "code/_examine_panel_defines.dm" +#include "code/examine_panel_component.dm" +#include "code/examine_panel_mob.dm" +#include "code/examine_panel_prefs.dm" +#include "code/~examine_panel_defines.dm" diff --git a/modular_bandastation/examine_panel/code/_examine_panel_defines.dm b/modular_bandastation/examine_panel/code/_examine_panel_defines.dm new file mode 100644 index 0000000000000..49fd0fd3530b3 --- /dev/null +++ b/modular_bandastation/examine_panel/code/_examine_panel_defines.dm @@ -0,0 +1,4 @@ +/// How many characters will be displayed in the flavor text preview before we cut it off? +#define FLAVOR_PREVIEW_LIMIT 110 +/// Double the maximum message length. +#define MAX_FLAVOR_LEN 4096 diff --git a/modular_bandastation/examine_panel/code/examine_panel_component.dm b/modular_bandastation/examine_panel/code/examine_panel_component.dm new file mode 100644 index 0000000000000..a3daa49ce1da6 --- /dev/null +++ b/modular_bandastation/examine_panel/code/examine_panel_component.dm @@ -0,0 +1,121 @@ +/datum/component/examine_panel + dupe_mode = COMPONENT_DUPE_UNIQUE + /// Mob that the examine panel belongs to. + var/mob/living/holder + /// The screen containing the appearance of the mob + var/atom/movable/screen/map_view/examine_panel_screen/examine_panel_screen + /// Flavor text + var/flavor_text + +/datum/component/examine_panel/Initialize(use_prefs = FALSE) + . = ..() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + holder = parent + if(!use_prefs) + return + if(iscarbon(parent)) + flavor_text = holder.client?.prefs.read_preference(/datum/preference/text/flavor_text) + if(issilicon(parent)) + flavor_text = holder.client?.prefs.read_preference(/datum/preference/text/silicon_flavor_text) + +/datum/component/examine_panel/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + +/datum/component/examine_panel/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) + +/datum/component/examine_panel/proc/on_examine(mob/living/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + if(iscarbon(source)) + examine_list += get_carbon_flavor_text(source) + if(issilicon(source)) + examine_list += get_silicon_flavor_text(source) + +/datum/component/examine_panel/proc/get_carbon_flavor_text(mob/living/carbon/source) + var/flavor_text_link + /// The first 1-FLAVOR_PREVIEW_LIMIT characters in the mob's "flavor_text" DNA feature. FLAVOR_PREVIEW_LIMIT is defined in flavor_defines.dm. + var/preview_text = copytext_char(flavor_text, 1, FLAVOR_PREVIEW_LIMIT) + // What examine_tgui.dm uses to determine if flavor text appears as "Obscured". + var/face_obscured = (source.wear_mask && (source.wear_mask.flags_inv & HIDEFACE)) || (source.head && (source.head.flags_inv & HIDEFACE)) + + if (!(face_obscured)) + flavor_text_link = span_notice("[preview_text]... Look closer?") + else + flavor_text_link = span_notice("Examine closely...") + if (flavor_text_link) + return flavor_text_link + +/datum/component/examine_panel/proc/get_silicon_flavor_text(mob/living/silicon/source) + var/flavor_text_link + /// The first 1-FLAVOR_PREVIEW_LIMIT characters in the mob's client's silicon_flavor_text preference datum. FLAVOR_PREVIEW_LIMIT is defined in flavor_defines.dm. + var/preview_text = copytext_char(flavor_text, 1, FLAVOR_PREVIEW_LIMIT) + + flavor_text_link = span_notice("[preview_text]... Look closer?") + + if (flavor_text_link) + return flavor_text_link + +/datum/component/examine_panel/Topic(href, list/href_list) + . = ..() + + if(href_list["lookup_info"]) + switch(href_list["lookup_info"]) + if("open_examine_panel") + ui_interact(usr) + +/datum/component/examine_panel/ui_state(mob/user) + return GLOB.always_state + +/datum/component/examine_panel/ui_close(mob/user) + user.client.clear_map(examine_panel_screen.assigned_map) + +/atom/movable/screen/map_view/examine_panel_screen + name = "examine panel screen" + +/datum/component/examine_panel/ui_interact(mob/user, datum/tgui/ui) + if(!examine_panel_screen) + examine_panel_screen = new + examine_panel_screen.name = "screen" + examine_panel_screen.assigned_map = "examine_panel_[REF(holder)]_map" + examine_panel_screen.del_on_map_removal = FALSE + examine_panel_screen.screen_loc = "[examine_panel_screen.assigned_map]:1,1" + + var/mutable_appearance/current_mob_appearance = new(holder) + current_mob_appearance.setDir(SOUTH) + current_mob_appearance.transform = matrix() // We reset their rotation, in case they're lying down. + + // In case they're pixel-shifted, we bring 'em back! + current_mob_appearance.pixel_x = 0 + current_mob_appearance.pixel_y = 0 + + examine_panel_screen.cut_overlays() + examine_panel_screen.add_overlay(current_mob_appearance) + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + examine_panel_screen.display_to(user) + user.client.register_map_obj(examine_panel_screen) + ui = new(user, src, "ExaminePanel") + ui.open() + + +/datum/component/examine_panel/ui_data(mob/user) + var/list/data = list() + + var/tgui_flavor_text = flavor_text + var/obscured + + if(ishuman(parent)) + var/mob/living/carbon/human/holder_human = parent + obscured = (holder_human.wear_mask && (holder_human.wear_mask.flags_inv & HIDEFACE)) || (holder_human.head && (holder_human.head.flags_inv & HIDEFACE)) + tgui_flavor_text = obscured ? "Obscured" : flavor_text + + var/name = obscured ? "Unknown" : user.name + + data["obscured"] = obscured ? TRUE : FALSE + data["character_name"] = name + data["assigned_map"] = examine_panel_screen.assigned_map + data["flavor_text"] = tgui_flavor_text + return data diff --git a/modular_bandastation/examine_panel/code/examine_panel_mob.dm b/modular_bandastation/examine_panel/code/examine_panel_mob.dm new file mode 100644 index 0000000000000..b55a6eec0ded8 --- /dev/null +++ b/modular_bandastation/examine_panel/code/examine_panel_mob.dm @@ -0,0 +1,19 @@ +// TODO: Don't use prefs when spawned via admins +/mob/living/carbon/human/Login() + . = ..() + AddComponent(/datum/component/examine_panel, use_prefs = TRUE) + +/mob/living/silicon/Login() + . = ..() + AddComponent(/datum/component/examine_panel, use_prefs = TRUE) + +/mob/living/verb/change_flavor_text() + set name = "Change flavor text" + set category = "IC" + + var/datum/component/examine_panel/examine_panel = GetComponent(/datum/component/examine_panel) + if(!examine_panel) + examine_panel = AddComponent(/datum/component/examine_panel) + var/new_flavor_text = tgui_input_text(usr, "Enter new flavor text", "Changing Flavor Text", examine_panel.flavor_text) + if(new_flavor_text) + examine_panel.flavor_text = new_flavor_text diff --git a/modular_bandastation/examine_panel/code/examine_panel_prefs.dm b/modular_bandastation/examine_panel/code/examine_panel_prefs.dm new file mode 100644 index 0000000000000..f5adcc4ea798a --- /dev/null +++ b/modular_bandastation/examine_panel/code/examine_panel_prefs.dm @@ -0,0 +1,18 @@ +/datum/preference/text/flavor_text + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "flavor_text" + maximum_value_length = MAX_FLAVOR_LEN + +/datum/preference/text/flavor_text/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + target.dna.features["flavor_text"] = value + +/datum/preference/text/silicon_flavor_text + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "silicon_flavor_text" + maximum_value_length = MAX_FLAVOR_LEN + // This does not get a apply_to_human proc, this is read directly in silicon/robot/examine.dm + +/datum/preference/text/silicon_flavor_text/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + return FALSE // To prevent the not-implemented runtime diff --git a/modular_bandastation/examine_panel/code/~examine_panel_defines.dm b/modular_bandastation/examine_panel/code/~examine_panel_defines.dm new file mode 100644 index 0000000000000..d431a143a094e --- /dev/null +++ b/modular_bandastation/examine_panel/code/~examine_panel_defines.dm @@ -0,0 +1,2 @@ +#undef FLAVOR_PREVIEW_LIMIT +#undef MAX_FLAVOR_LEN diff --git a/modular_bandastation/example/_example.dm b/modular_bandastation/example/_example.dm new file mode 100644 index 0000000000000..2343367184030 --- /dev/null +++ b/modular_bandastation/example/_example.dm @@ -0,0 +1,16 @@ +/datum/modpack/example + /// A string name for the modpack. Used for looking up other modpacks in init. + name = "Example modpack" + /// A string desc for the modpack. Can be used for modpack verb list as description. + desc = "its useless" + /// A string with authors of this modpack. + author = "furior" + +/datum/modpack/example/pre_initialize() + . = ..() + +/datum/modpack/example/initialize() + . = ..() + +/datum/modpack/example/post_initialize() + . = ..() diff --git a/modular_bandastation/example/_example.dme b/modular_bandastation/example/_example.dme new file mode 100644 index 0000000000000..5540c273b03ba --- /dev/null +++ b/modular_bandastation/example/_example.dme @@ -0,0 +1,3 @@ +#include "_example.dm" + +#include "code/example.dm" diff --git a/modular_bandastation/example/code/example.dm b/modular_bandastation/example/code/example.dm new file mode 100644 index 0000000000000..ff327270a515d --- /dev/null +++ b/modular_bandastation/example/code/example.dm @@ -0,0 +1,2 @@ +/turf/closed/wall/example + name = "Example wall" diff --git a/modular_bandastation/gunhud/_gunhud.dm b/modular_bandastation/gunhud/_gunhud.dm new file mode 100644 index 0000000000000..a93ecac1d2917 --- /dev/null +++ b/modular_bandastation/gunhud/_gunhud.dm @@ -0,0 +1,4 @@ +/datum/modpack/gunhud + name = "Счетчик патронов" + desc = "Добавляет счетчик патронов" + author = "larentoun (modpack), Gandalf2k15 (original)" diff --git a/modular_bandastation/gunhud/_gunhud.dme b/modular_bandastation/gunhud/_gunhud.dme new file mode 100644 index 0000000000000..577291e22b77c --- /dev/null +++ b/modular_bandastation/gunhud/_gunhud.dme @@ -0,0 +1,7 @@ +#include "_gunhud.dm" + +#include "code/_gunhud_defines.dm" +#include "code/gunhud_component.dm" +#include "code/gunhud_hud.dm" +#include "code/gunhud_screen.dm" +#include "code/~gunhud_defines.dm" diff --git a/modular_bandastation/gunhud/code/_gunhud_defines.dm b/modular_bandastation/gunhud/code/_gunhud_defines.dm new file mode 100644 index 0000000000000..5ceb4767dd99a --- /dev/null +++ b/modular_bandastation/gunhud/code/_gunhud_defines.dm @@ -0,0 +1,5 @@ +// Gunhud +#define ui_gunhud "RIGHT-1:28,CENTER-5:9" + +///The gun needs to update the gun hud! +#define COMSIG_UPDATE_GUNHUD "update_gunhud" diff --git a/modular_bandastation/gunhud/code/gunhud_component.dm b/modular_bandastation/gunhud/code/gunhud_component.dm new file mode 100644 index 0000000000000..1df38eb90143a --- /dev/null +++ b/modular_bandastation/gunhud/code/gunhud_component.dm @@ -0,0 +1,150 @@ +/datum/component/gunhud + var/atom/movable/screen/gunhud_screen/hud + +/datum/component/gunhud/Initialize() + . = ..() + if(!istype(parent, /obj/item/gun) && !istype(parent, /obj/item/weldingtool)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(wake_up)) + +/datum/component/gunhud/Destroy() + turn_off() + return ..() + +/datum/component/gunhud/proc/wake_up(datum/source, mob/user, slot) + SIGNAL_HANDLER + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.is_holding(parent)) + if(H.hud_used) + hud = H.hud_used.gunhud_screen + turn_on() + else + turn_off() + +/datum/component/gunhud/proc/turn_on() + SIGNAL_HANDLER + + RegisterSignals(parent, list(COMSIG_PREQDELETED, COMSIG_ITEM_DROPPED), PROC_REF(turn_off)) + RegisterSignals(parent, list(COMSIG_UPDATE_GUNHUD, COMSIG_GUN_CHAMBER_PROCESSED), PROC_REF(update_hud)) + + hud.turn_on() + update_hud() + +/datum/component/gunhud/proc/turn_off() + SIGNAL_HANDLER + + UnregisterSignal(parent, list(COMSIG_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_UPDATE_GUNHUD, COMSIG_GUN_CHAMBER_PROCESSED)) + + if(hud) + hud.turn_off() + hud = null + +/datum/component/gunhud/proc/update_hud() + SIGNAL_HANDLER + if(istype(parent, /obj/item/gun/ballistic)) + var/obj/item/gun/ballistic/pew = parent + hud.maptext = null + hud.icon_state = "backing" + var/backing_color = COLOR_CYAN + if(!pew.magazine) + hud.set_hud(backing_color, "oe", "te", "he", "no_mag") + return + if(!pew.get_ammo()) + hud.set_hud(backing_color, "oe", "te", "he", "empty_flash") + return + + var/indicator + var/rounds = num2text(istype(parent, /obj/item/gun/ballistic/revolver) ? pew.get_ammo(FALSE, FALSE) : pew.get_ammo(TRUE)) // fucking revolvers indeed - do not count empty or chambered rounds for the display HUD + var/oth_o + var/oth_t + var/oth_h + + switch(length(rounds)) + if(1) + oth_o = "o[rounds[1]]" + if(2) + oth_o = "o[rounds[2]]" + oth_t = "t[rounds[1]]" + if(3) + oth_o = "o[rounds[3]]" + oth_t = "t[rounds[2]]" + oth_h = "h[rounds[1]]" + else + oth_o = "o9" + oth_t = "t9" + oth_h = "h9" + hud.set_hud(backing_color, oth_o, oth_t, oth_h, indicator) + + else if(istype(parent, /obj/item/gun/energy)) + var/obj/item/gun/energy/pew = parent + hud.icon_state = "eammo_counter" + hud.cut_overlays() + hud.maptext_x = -12 + var/obj/item/ammo_casing/energy/shot = pew.ammo_type[pew.select] + var/batt_percent = FLOOR(clamp(pew.cell.charge / pew.cell.maxcharge, 0, 1) * 100, 1) + var/shot_cost_percent = FLOOR(clamp(shot.e_cost / pew.cell.maxcharge, 0, 1) * 100, 1) + if(batt_percent > 99 || shot_cost_percent > 99) + hud.maptext_x = -12 + else + hud.maptext_x = -8 + if(!pew.can_shoot()) + hud.icon_state = "eammo_counter_empty" + hud.maptext = span_maptext("
[batt_percent]%
[shot_cost_percent]%
") + return + if(batt_percent <= 25) + hud.maptext = span_maptext("
[batt_percent]%
[shot_cost_percent]%
") + return + hud.maptext = span_maptext("
[batt_percent]%
[shot_cost_percent]%
") + + else if(istype(parent, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = parent + hud.maptext = null + var/backing_color = COLOR_TAN_ORANGE + hud.icon_state = "backing" + + if(welder.get_fuel() < 1) + hud.set_hud(backing_color, "oe", "te", "he", "empty_flash") + return + + var/indicator + var/fuel = num2text(welder.get_fuel()) + var/oth_o + var/oth_t + var/oth_h + + if(welder.welding) + indicator = "flame_on" + else + indicator = "flame_off" + + fuel = num2text(welder.get_fuel()) + + switch(length(fuel)) + if(1) + oth_o = "o[fuel[1]]" + if(2) + oth_o = "o[fuel[2]]" + oth_t = "t[fuel[1]]" + if(3) + oth_o = "o[fuel[3]]" + oth_t = "t[fuel[2]]" + oth_h = "h[fuel[1]]" + else + oth_o = "o9" + oth_t = "t9" + oth_h = "h9" + hud.set_hud(backing_color, oth_o, oth_t, oth_h, indicator) + +/obj/item/gun/ballistic/Initialize(mapload) + . = ..() + AddComponent(/datum/component/gunhud) + +/obj/item/gun/energy/Initialize(mapload) + . = ..() + AddComponent(/datum/component/gunhud) + +/obj/item/weldingtool/Initialize(mapload) + . = ..() + AddComponent(/datum/component/gunhud) diff --git a/modular_bandastation/gunhud/code/gunhud_hud.dm b/modular_bandastation/gunhud/code/gunhud_hud.dm new file mode 100644 index 0000000000000..bc26c0f0e6d58 --- /dev/null +++ b/modular_bandastation/gunhud/code/gunhud_hud.dm @@ -0,0 +1,7 @@ +/datum/hud + var/atom/movable/screen/gunhud_screen + +/datum/hud/human/New(mob/living/carbon/human/owner) + . = ..() + gunhud_screen = new /atom/movable/screen/gunhud_screen(null, src) + infodisplay += gunhud_screen diff --git a/modular_bandastation/gunhud/code/gunhud_screen.dm b/modular_bandastation/gunhud/code/gunhud_screen.dm new file mode 100644 index 0000000000000..2038d7f6e3cd8 --- /dev/null +++ b/modular_bandastation/gunhud/code/gunhud_screen.dm @@ -0,0 +1,86 @@ +/* +* Customizable ammo hud +*/ + +/* +* This hud is controlled namely by the gunhud component. Generally speaking this is inactive much like all other hud components until it's needed. +* It does not do any calculations of it's own, you must do this externally. +* If you wish to use this hud, use the gunhud component or create another one which interacts with it via the below procs. +* proc/turn_off +* proc/turn_on +* proc/set_hud +* Check the gun_hud.dmi for all available icons you can use. +*/ + +/atom/movable/screen/gunhud_screen + name = "gunhud" + icon = 'modular_bandastation/gunhud/icons/gun_hud.dmi' + icon_state = "backing" + screen_loc = ui_gunhud + invisibility = INVISIBILITY_ABSTRACT + + ///This is the color assigned to the OTH backing, numbers and indicator. + var/backing_color = COLOR_RED + ///This is the "backlight" of the numbers, and only the numbers. Generally you should leave this alone if you aren't making some mutant project. + var/oth_backing = "oth_light" + + //Below are the OTH numbers, these are assigned by oX, tX and hX, x being the number you wish to display(0-9) + ///OTH position X00 + var/oth_o + ///OTH position 0X0 + var/oth_t + ///OTH position 00X + var/oth_h + ///This is the custom indicator sprite that will appear in the box at the bottom of the ammo hud, use this for something like semi/auto toggle on a gun. + var/indicator + +///This proc simply resets the hud to standard and removes it from the players visible hud. +/atom/movable/screen/gunhud_screen/proc/turn_off() + invisibility = INVISIBILITY_ABSTRACT + maptext = null + backing_color = COLOR_RED + oth_backing = "" + oth_o = "" + oth_t = "" + oth_h = "" + indicator = "" + update_appearance() + +///This proc turns the hud on, but does not set it to anything other than the currently set values +/atom/movable/screen/gunhud_screen/proc/turn_on() + invisibility = 0 + +///This is the main proc for altering the hud's appeareance, it controls the setting of the overlays. Use the OTH and below variables to set it accordingly. +/atom/movable/screen/gunhud_screen/proc/set_hud(_backing_color, _oth_o, _oth_t, _oth_h, _indicator, _oth_backing = "oth_light") + backing_color = _backing_color + oth_backing = _oth_backing + oth_o = _oth_o + oth_t = _oth_t + oth_h = _oth_h + indicator = _indicator + + update_appearance() + +/atom/movable/screen/gunhud_screen/update_overlays() + . = ..() + if(oth_backing) + var/mutable_appearance/oth_backing_overlay = mutable_appearance(icon, oth_backing) + oth_backing_overlay.color = backing_color + . += oth_backing_overlay + if(oth_o) + var/mutable_appearance/o_overlay = mutable_appearance(icon, oth_o) + o_overlay.color = backing_color + . += o_overlay + if(oth_t) + var/mutable_appearance/t_overlay = mutable_appearance(icon, oth_t) + t_overlay.color = backing_color + . += t_overlay + if(oth_h) + var/mutable_appearance/h_overlay = mutable_appearance(icon, oth_h) + h_overlay.color = backing_color + . += h_overlay + if(indicator) + var/mutable_appearance/indicator_overlay = mutable_appearance(icon, indicator) + indicator_overlay.color = backing_color + . += indicator_overlay + diff --git a/modular_bandastation/gunhud/code/~gunhud_defines.dm b/modular_bandastation/gunhud/code/~gunhud_defines.dm new file mode 100644 index 0000000000000..6b21ebfe92135 --- /dev/null +++ b/modular_bandastation/gunhud/code/~gunhud_defines.dm @@ -0,0 +1,5 @@ +// Ammo counter +#undef ui_gunhud + +///The gun needs to update the gun hud! +#undef COMSIG_UPDATE_GUNHUD diff --git a/modular_bandastation/gunhud/icons/gun_hud.dmi b/modular_bandastation/gunhud/icons/gun_hud.dmi new file mode 100644 index 0000000000000..6bd861100e2e1 Binary files /dev/null and b/modular_bandastation/gunhud/icons/gun_hud.dmi differ diff --git a/modular_bandastation/keybindings/_keybindings.dm b/modular_bandastation/keybindings/_keybindings.dm new file mode 100644 index 0000000000000..f28bb05e8472d --- /dev/null +++ b/modular_bandastation/keybindings/_keybindings.dm @@ -0,0 +1,4 @@ +/datum/modpack/keybindings + name = "Хоткеи220" + desc = "Ставит значения хоткеев по умолчанию на те, что есть на Para220" + author = "larentoun" diff --git a/modular_bandastation/keybindings/_keybindings.dme b/modular_bandastation/keybindings/_keybindings.dme new file mode 100644 index 0000000000000..26c7f47e8bc02 --- /dev/null +++ b/modular_bandastation/keybindings/_keybindings.dme @@ -0,0 +1,13 @@ +#include "_keybindings.dm" + +#include "code/admin.dm" +#include "code/artificial_intelligence.dm" +#include "code/carbon.dm" +#include "code/client.dm" +#include "code/communication.dm" +#include "code/emote.dm" +#include "code/human.dm" +#include "code/living.dm" +#include "code/mob.dm" +#include "code/movement.dm" +#include "code/robot.dm" diff --git a/modular_bandastation/keybindings/code/admin.dm b/modular_bandastation/keybindings/code/admin.dm new file mode 100644 index 0000000000000..c0c7cda433c22 --- /dev/null +++ b/modular_bandastation/keybindings/code/admin.dm @@ -0,0 +1,39 @@ +/datum/keybinding/admin/admin_say + full_name = "Asay" + hotkey_keys = list("F5") + +/datum/keybinding/admin/admin_ghost + full_name = "Aghost" + hotkey_keys = list("F6") + +/datum/keybinding/admin/player_panel_new + full_name = "Player Panel" + hotkey_keys = list("F7") + +/datum/keybinding/admin/toggle_buildmode_self + full_name = "Toggle Buildmode" + hotkey_keys = list("F11") + +/datum/keybinding/admin/stealthmode + full_name = "Stealth mode" + hotkey_keys = list("CtrlF9") + +/datum/keybinding/admin/invisimin + full_name = "Invisimin" + hotkey_keys = list("F9") + +/datum/keybinding/admin/deadsay + full_name = "Dsay" + hotkey_keys = list("F10") + +/datum/keybinding/admin/deadmin + full_name = "Deadmin" + hotkey_keys = list("Unbound") + +/datum/keybinding/admin/readmin + full_name = "Readmin" + hotkey_keys = list("Unbound") + +/datum/keybinding/admin/view_tags + full_name = "View Tags" + hotkey_keys = list("CtrlF11") diff --git a/modular_bandastation/keybindings/code/artificial_intelligence.dm b/modular_bandastation/keybindings/code/artificial_intelligence.dm new file mode 100644 index 0000000000000..fc72187c256dc --- /dev/null +++ b/modular_bandastation/keybindings/code/artificial_intelligence.dm @@ -0,0 +1,3 @@ +/datum/keybinding/artificial_intelligence/reconnect + full_name = "Переподключиться к оболочке" + hotkey_keys = list("-") diff --git a/modular_bandastation/keybindings/code/carbon.dm b/modular_bandastation/keybindings/code/carbon.dm new file mode 100644 index 0000000000000..210538c7a5d94 --- /dev/null +++ b/modular_bandastation/keybindings/code/carbon.dm @@ -0,0 +1,11 @@ +/datum/keybinding/carbon/toggle_throw_mode + full_name = "Режим броска (переключить)" + hotkey_keys = list("R", "Southwest") + +/datum/keybinding/carbon/hold_throw_mode + full_name = "Режим броска (зажать)" + hotkey_keys = list("Space") + +/datum/keybinding/carbon/give + full_name = "Передать вещь (переключить)" + hotkey_keys = list("V") diff --git a/modular_bandastation/keybindings/code/client.dm b/modular_bandastation/keybindings/code/client.dm new file mode 100644 index 0000000000000..4a83b861a751d --- /dev/null +++ b/modular_bandastation/keybindings/code/client.dm @@ -0,0 +1,11 @@ +/datum/keybinding/client/admin_help + full_name = "Admin Help" + hotkey_keys = list("F1") + +/datum/keybinding/client/screenshot + full_name = "Сделать Screenshot" + hotkey_keys = list("Unbound") + +/datum/keybinding/client/minimal_hud + full_name = "Переключить минимальный HUD" + hotkey_keys = list("F12") diff --git a/modular_bandastation/keybindings/code/communication.dm b/modular_bandastation/keybindings/code/communication.dm new file mode 100644 index 0000000000000..7476e2c910b68 --- /dev/null +++ b/modular_bandastation/keybindings/code/communication.dm @@ -0,0 +1,23 @@ +/datum/keybinding/client/communication/say + full_name = "Говорить" + hotkey_keys = list("F3", "T") + +/datum/keybinding/client/communication/radio + full_name = "Общий канал рации (;)" + hotkey_keys = list("Unbound") + +/datum/keybinding/client/communication/ooc + full_name = "OOC" + hotkey_keys = list("F2", "O") + +/datum/keybinding/client/communication/me + full_name = "Эмоция" + hotkey_keys = list("F4", "M") + +/datum/keybinding/client/communication/looc + full_name = "LOOC" + hotkey_keys = list("L") + +/datum/keybinding/client/communication/whisper + full_name = "Шептать" + hotkey_keys = list("ShiftT") diff --git a/modular_bandastation/keybindings/code/emote.dm b/modular_bandastation/keybindings/code/emote.dm new file mode 100644 index 0000000000000..eb02d081238ec --- /dev/null +++ b/modular_bandastation/keybindings/code/emote.dm @@ -0,0 +1,4 @@ +/datum/keybinding/emote/link_to_emote(datum/emote/faketype) + . = ..() + if(initial(faketype.name)) + full_name = capitalize(initial(faketype.name)) diff --git a/modular_bandastation/keybindings/code/human.dm b/modular_bandastation/keybindings/code/human.dm new file mode 100644 index 0000000000000..f880f0bd2cb82 --- /dev/null +++ b/modular_bandastation/keybindings/code/human.dm @@ -0,0 +1,15 @@ +/datum/keybinding/human/quick_equip + full_name = "Экипировать вещь" + hotkey_keys = list("E") + +/datum/keybinding/human/quick_equip_belt + full_name = "Быстрая экипировка пояса" + hotkey_keys = list("ShiftE") + +/datum/keybinding/human/quick_equip_belt/quick_equip_bag + full_name = "Быстрая экипировка сумки" + hotkey_keys = list("ShiftV") + +/datum/keybinding/human/quick_equip_belt/quick_equip_suit_storage + full_name = "Быстрая экипировка хранилища костюма" + hotkey_keys = list("ShiftQ") diff --git a/modular_bandastation/keybindings/code/living.dm b/modular_bandastation/keybindings/code/living.dm new file mode 100644 index 0000000000000..644bec4b78fa9 --- /dev/null +++ b/modular_bandastation/keybindings/code/living.dm @@ -0,0 +1,27 @@ +/datum/keybinding/living/resist + full_name = "Сопротивляться" + hotkey_keys = list("B") + +/datum/keybinding/living/look_up + full_name = "Посмотреть вверх" + hotkey_keys = list("P") + +/datum/keybinding/living/look_down + full_name = "Посмотреть вниз" + hotkey_keys = list(";") + +/datum/keybinding/living/rest + full_name = "Лечь/встать" + hotkey_keys = list("ShiftB") + +/datum/keybinding/living/toggle_combat_mode + full_name = "Переключить Combat Mode" + hotkey_keys = list("F") + +/datum/keybinding/living/enable_combat_mode + full_name = "Включить Combat Mode" + hotkey_keys = list("4") + +/datum/keybinding/living/disable_combat_mode + full_name = "Отключить Combat Mode" + hotkey_keys = list("1") diff --git a/modular_bandastation/keybindings/code/mob.dm b/modular_bandastation/keybindings/code/mob.dm new file mode 100644 index 0000000000000..9f5f7cbbe04f0 --- /dev/null +++ b/modular_bandastation/keybindings/code/mob.dm @@ -0,0 +1,63 @@ +/datum/keybinding/mob/stop_pulling + full_name = "Перестать тащить" + hotkey_keys = list("C", "Delete") + +/datum/keybinding/mob/swap_hands + full_name = "Поменять руки" + hotkey_keys = list("X") + +/datum/keybinding/mob/activate_inhand + full_name = "Использовать вещь в руке" + hotkey_keys = list("Z") + +/datum/keybinding/mob/drop_item + full_name = "Выложить вещь в руке" + hotkey_keys = list("Q") + +/datum/keybinding/mob/toggle_move_intent + full_name = "Смена режима ходьбы (зажать)" + hotkey_keys = list("Alt") + +/datum/keybinding/mob/toggle_move_intent_alternative + full_name = "Смена режима ходьбы (переключить)" + hotkey_keys = list("Unbound") + +/datum/keybinding/mob/target/head_cycle + full_name = "Выбрать голову/глаза/рот" + hotkey_keys = list("Numpad8") + +/datum/keybinding/mob/target/eyes + full_name = "Выбрать глаза" + hotkey_keys = list("Numpad7") + +/datum/keybinding/mob/target/mouth + full_name = "Выбрать рот" + hotkey_keys = list("Numpad9") + +/datum/keybinding/mob/target/r_arm + full_name = "Выбрать правую руку" + hotkey_keys = list("Numpad4") + +/datum/keybinding/mob/target/body_chest + full_name = "Выбрать грудь" + hotkey_keys = list("Numpad5") + +/datum/keybinding/mob/target/left_arm + full_name = "Выбрать левую руку" + hotkey_keys = list("Numpad6") + +/datum/keybinding/mob/target/right_leg + full_name = "Выбрать правую ногу" + hotkey_keys = list("Numpad1") + +/datum/keybinding/mob/target/body_groin + full_name = "Выбрать пах" + hotkey_keys = list("Numpad2") + +/datum/keybinding/mob/target/left_leg + full_name = "Выбрать левую ногу" + hotkey_keys = list("Numpad3") + +/datum/keybinding/mob/prevent_movement + full_name = "Остановиться (зажать)" + hotkey_keys = list("Ctrl") diff --git a/modular_bandastation/keybindings/code/movement.dm b/modular_bandastation/keybindings/code/movement.dm new file mode 100644 index 0000000000000..6bcc2b3606e1a --- /dev/null +++ b/modular_bandastation/keybindings/code/movement.dm @@ -0,0 +1,23 @@ +/datum/keybinding/movement/north + full_name = "Идти на север" + hotkey_keys = list("W", "North") + +/datum/keybinding/movement/south + full_name = "Идти на юг" + hotkey_keys = list("S", "South") + +/datum/keybinding/movement/west + full_name = "Идти на запад" + hotkey_keys = list("A", "West") + +/datum/keybinding/movement/east + full_name = "Идти на восток" + hotkey_keys = list("D", "East") + +/datum/keybinding/movement/zlevel_upwards + full_name = "Идти наверх" + hotkey_keys = list("Northeast") // PGUP + +/datum/keybinding/movement/zlevel_downwards + full_name = "Идти вниз" + hotkey_keys = list("Southeast") // PGDOWN diff --git a/modular_bandastation/keybindings/code/robot.dm b/modular_bandastation/keybindings/code/robot.dm new file mode 100644 index 0000000000000..95e99ec7b2e47 --- /dev/null +++ b/modular_bandastation/keybindings/code/robot.dm @@ -0,0 +1,19 @@ +/datum/keybinding/robot/moduleone + full_name = "Ячейка 1" + hotkey_keys = list("1") + +/datum/keybinding/robot/moduletwo + full_name = "Ячейка 2" + hotkey_keys = list("2") + +/datum/keybinding/robot/modulethree + full_name = "Ячейка 3" + hotkey_keys = list("3") + +/datum/keybinding/robot/unequip_module + full_name = "Выложить в хранилище" + hotkey_keys = list("Q") + +/datum/keybinding/robot/undeploy + full_name = "Отсоединиться от оболочки" + hotkey_keys = list("=") diff --git a/modular_bandastation/modular_bandastation.dme b/modular_bandastation/modular_bandastation.dme new file mode 100644 index 0000000000000..604d5888e9864 --- /dev/null +++ b/modular_bandastation/modular_bandastation.dme @@ -0,0 +1,24 @@ +#include "_modpack.dm" +#include "_modpacks.dm" + +// #include "example/_example.dme" + +#include "_defines220/_defines220.dme" +#include "_helpers220/_helpers220.dme" +#include "_signals220/_signals220.dme" +#include "aesthetics/_aesthetics.dme" +#include "ai_laws/_ai_laws.dme" +#include "barsigns/_barsigns.dme" +#include "communication/_communication.dme" +#include "crawl_speed/_crawl_speed.dme" +#include "cyrillic_fixes/_cyrillic_fixes.dme" +#include "discord/_discord.dme" +#include "emote_panel/_emote_panel.dme" +#include "events/_events.dme" +#include "examine_panel/_examine_panel.dme" +#include "gunhud/_gunhud.dme" +#include "keybindings/_keybindings.dme" +#include "pixel_shift/_pixel_shift.dme" +#include "translations/_translations.dme" +#include "tts/_tts.dme" +#include "world_topics/_world_topics.dme" diff --git a/modular_bandastation/pixel_shift/_pixel_shift.dm b/modular_bandastation/pixel_shift/_pixel_shift.dm new file mode 100644 index 0000000000000..b3d6f05911fd3 --- /dev/null +++ b/modular_bandastation/pixel_shift/_pixel_shift.dm @@ -0,0 +1,4 @@ +/datum/modpack/pixel_shift + name = "Pixel Shift" + desc = "Добавляет возможность движения по-пиксельно в пределах турфа." + author = "larentoun (modpack), Vallat (refactor), Ranged66 (layer shift), Azarak (pixel shift port), Gandalf2k15 (pixel shift refactor)" diff --git a/modular_bandastation/pixel_shift/_pixel_shift.dme b/modular_bandastation/pixel_shift/_pixel_shift.dme new file mode 100644 index 0000000000000..5b1685e49cbfe --- /dev/null +++ b/modular_bandastation/pixel_shift/_pixel_shift.dme @@ -0,0 +1,6 @@ +#include "_pixel_shift.dm" + +#include "code/layer_shift.dm" +#include "code/pixel_shift_component.dm" +#include "code/pixel_shift_keybind.dm" +#include "code/pixel_shift_mob.dm" diff --git a/modular_bandastation/pixel_shift/code/layer_shift.dm b/modular_bandastation/pixel_shift/code/layer_shift.dm new file mode 100644 index 0000000000000..3be3824c06fd1 --- /dev/null +++ b/modular_bandastation/pixel_shift/code/layer_shift.dm @@ -0,0 +1,36 @@ +#define MOB_LAYER_SHIFT_INCREMENT 0.01 +#define MOB_LAYER_SHIFT_MIN 3.95 +//#define MOB_LAYER 4 // This is a byond standard define +#define MOB_LAYER_SHIFT_MAX 4.05 + +/mob/living/verb/layershift_up() + set name = "Shift Layer Upwards" + set category = "IC" + + if(incapacitated()) + to_chat(src, span_warning("You can't do that right now!")) + return + + if(layer >= MOB_LAYER_SHIFT_MAX) + to_chat(src, span_warning("You cannot increase your layer priority any further.")) + return + + layer += MOB_LAYER_SHIFT_INCREMENT + var/layer_priority = round((layer - MOB_LAYER) * 100, 1) // Just for text feedback + to_chat(src, span_notice("Your layer priority is now [layer_priority].")) + +/mob/living/verb/layershift_down() + set name = "Shift Layer Downwards" + set category = "IC" + + if(incapacitated()) + to_chat(src, span_warning("You can't do that right now!")) + return + + if(layer <= MOB_LAYER_SHIFT_MIN) + to_chat(src, span_warning("You cannot decrease your layer priority any further.")) + return + + layer -= MOB_LAYER_SHIFT_INCREMENT + var/layer_priority = round((layer - MOB_LAYER) * 100, 1) // Just for text feedback + to_chat(src, span_notice("Your layer priority is now [layer_priority].")) diff --git a/modular_bandastation/pixel_shift/code/pixel_shift_component.dm b/modular_bandastation/pixel_shift/code/pixel_shift_component.dm new file mode 100644 index 0000000000000..76d5f6c08e3c9 --- /dev/null +++ b/modular_bandastation/pixel_shift/code/pixel_shift_component.dm @@ -0,0 +1,96 @@ +/datum/component/pixel_shift + dupe_mode = COMPONENT_DUPE_UNIQUE + /// Whether the mob is pixel shifted or not + var/is_shifted = FALSE + /// If we are in the shifting setting. + var/shifting = TRUE + /// Takes the four cardinal direction defines. Any atoms moving into this atom's tile will be allowed to from the added directions. + var/passthroughable = NONE + var/maximum_pixel_shift = 12 + var/passable_shift_threshold = 8 + +/datum/component/pixel_shift/Initialize(...) + . = ..() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/pixel_shift/RegisterWithParent() + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN, PROC_REF(pixel_shift_down)) + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP, PROC_REF(pixel_shift_up)) + RegisterSignals(parent, list(COMSIG_LIVING_RESET_PULL_OFFSETS, COMSIG_LIVING_SET_PULL_OFFSET, COMSIG_MOVABLE_MOVED, SIGNAL_ADDTRAIT(TRAIT_FLOORED)), PROC_REF(unpixel_shift)) + RegisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(pre_move_check)) + RegisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH, PROC_REF(check_passable)) + +/datum/component/pixel_shift/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN) + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP) + UnregisterSignal(parent, COMSIG_LIVING_RESET_PULL_OFFSETS) + UnregisterSignal(parent, COMSIG_LIVING_SET_PULL_OFFSET) + UnregisterSignal(parent, SIGNAL_ADDTRAIT(TRAIT_FLOORED)) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + UnregisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) + UnregisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH) + +/datum/component/pixel_shift/proc/pre_move_check(mob/source, new_loc, direct) + SIGNAL_HANDLER + if(shifting) + pixel_shift(source, direct) + return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE + +/datum/component/pixel_shift/proc/check_passable(mob/source, atom/movable/mover, border_dir) + SIGNAL_HANDLER + // Make sure to not allow projectiles of any kind past where they normally wouldn't. + if(!isprojectile(mover) && !mover.throwing && passthroughable & border_dir) + return COMPONENT_LIVING_PASSABLE + +/datum/component/pixel_shift/proc/pixel_shift_down() + SIGNAL_HANDLER + shifting = TRUE + return COMSIG_KB_ACTIVATED + +/datum/component/pixel_shift/proc/pixel_shift_up() + SIGNAL_HANDLER + shifting = FALSE + +/datum/component/pixel_shift/proc/unpixel_shift() + SIGNAL_HANDLER + passthroughable = NONE + if(is_shifted) + var/mob/living/owner = parent + owner.pixel_x = owner.body_position_pixel_x_offset + owner.base_pixel_x + owner.pixel_y = owner.body_position_pixel_y_offset + owner.base_pixel_y + qdel(src) + +/datum/component/pixel_shift/proc/pixel_shift(mob/source, direct) + var/mob/living/owner = parent + if(HAS_TRAIT(owner, TRAIT_RESTRAINED) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED) || length(owner.pulledby) || owner.stat != CONSCIOUS) + return + passthroughable = NONE + switch(direct) + if(NORTH) + if(owner.pixel_y <= maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y++ + is_shifted = TRUE + if(EAST) + if(owner.pixel_x <= maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x++ + is_shifted = TRUE + if(SOUTH) + if(owner.pixel_y >= -maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y-- + is_shifted = TRUE + if(WEST) + if(owner.pixel_x >= -maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x-- + is_shifted = TRUE + + // Yes, I know this sets it to true for everything if more than one is matched. + // Movement doesn't check diagonals, and instead just checks EAST or WEST, depending on where you are for those. + if(owner.pixel_y > passable_shift_threshold) + passthroughable |= EAST | SOUTH | WEST + else if(owner.pixel_y < -passable_shift_threshold) + passthroughable |= NORTH | EAST | WEST + if(owner.pixel_x > passable_shift_threshold) + passthroughable |= NORTH | SOUTH | WEST + else if(owner.pixel_x < -passable_shift_threshold) + passthroughable |= NORTH | EAST | SOUTH diff --git a/modular_bandastation/pixel_shift/code/pixel_shift_keybind.dm b/modular_bandastation/pixel_shift/code/pixel_shift_keybind.dm new file mode 100644 index 0000000000000..2375b350a33c7 --- /dev/null +++ b/modular_bandastation/pixel_shift/code/pixel_shift_keybind.dm @@ -0,0 +1,17 @@ +/datum/keybinding/mob/pixel_shift + hotkey_keys = list("B") + name = "pixel_shift" + full_name = "Pixel Shift" + description = "Shift your characters offset." + category = CATEGORY_MOVEMENT + keybind_signal = COMSIG_KB_MOB_PIXEL_SHIFT_DOWN + +/datum/keybinding/mob/pixel_shift/down(client/user) + . = ..() + if(.) + return + user.mob.add_pixel_shift_component() + +/datum/keybinding/mob/pixel_shift/up(client/user) + . = ..() + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_SHIFT_UP) diff --git a/modular_bandastation/pixel_shift/code/pixel_shift_mob.dm b/modular_bandastation/pixel_shift/code/pixel_shift_mob.dm new file mode 100644 index 0000000000000..cd02f441ce038 --- /dev/null +++ b/modular_bandastation/pixel_shift/code/pixel_shift_mob.dm @@ -0,0 +1,5 @@ +/mob/proc/add_pixel_shift_component() + return + +/mob/living/add_pixel_shift_component() + AddComponent(/datum/component/pixel_shift) diff --git a/modular_bandastation/translations/_translations.dm b/modular_bandastation/translations/_translations.dm new file mode 100644 index 0000000000000..7cf16725ef5e0 --- /dev/null +++ b/modular_bandastation/translations/_translations.dm @@ -0,0 +1,4 @@ +/datum/modpack/translations + name = "Переводы" + desc = "Добавляет переводы" + author = "Vallat" diff --git a/modular_bandastation/translations/_translations.dme b/modular_bandastation/translations/_translations.dme new file mode 100644 index 0000000000000..d1949fb31473a --- /dev/null +++ b/modular_bandastation/translations/_translations.dme @@ -0,0 +1,4 @@ +#include "_translations.dm" + +#include "code/moustache.dm" +#include "code/restaurant_customer.dm" diff --git a/modular_bandastation/translations/code/moustache.dm b/modular_bandastation/translations/code/moustache.dm new file mode 100644 index 0000000000000..ff8d1936599b1 --- /dev/null +++ b/modular_bandastation/translations/code/moustache.dm @@ -0,0 +1,37 @@ +/obj/item/clothing/mask/fakemoustache + name = "накладные усы" + desc = "Осторожно: усы накладные." + +/obj/item/clothing/mask/fakemoustache/italian + name = "итальянские усы" + desc = "Изготовлен из настоящих итальянских волосков для усов. Дает владельцу непреодолимое желание дико жестикулировать." + +/obj/item/clothing/mask/fakemoustache/italian/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message[1] != "*") + var/static/regex/words = new(@"(?[text]"} + + var/list/req_body = list() + req_body["api_token"] = CONFIG_GET(string/tts_token_silero) + req_body["text"] = ssml_text + req_body["sample_rate"] = 24000 + req_body["ssml"] = TRUE + req_body["speaker"] = seed.value + req_body["lang"] = "ru" + req_body["remote_id"] = "[world.port]" + req_body["put_accent"] = TRUE + req_body["put_yo"] = FALSE + req_body["symbol_durs"] = list() + req_body["format"] = "ogg" + req_body["word_ts"] = FALSE + // var/json_body = json_encode(req_body) + // log_debug(json_body) + + var/datum/http_request/request = new() + request.prepare(RUSTG_HTTP_METHOD_POST, api_url, json_encode(req_body), list("content-type" = "application/json")) + spawn(0) + request.begin_async() + UNTIL(request.is_complete()) + var/datum/http_response/response = request.into_response() + proc_callback.Invoke(response) + + return TRUE + +/datum/tts_provider/silero/process_response(datum/http_response/response) + var/data = json_decode(response.body) + // log_debug(response.body) + + if(data["timings"]["003_tts_time"] > 3) + is_throttled = TRUE + throttled_until = world.time + 15 SECONDS + + return data["results"][1]["audio"] + + //var/sha1 = data["original_sha1"] + +/datum/tts_provider/silero/pitch_whisper(text) + return {"[text]"} + +/datum/tts_provider/silero/rate_faster(text) + return {"[text]"} + +/datum/tts_provider/silero/rate_medium(text) + return {"[text]"} diff --git a/modular_bandastation/tts/code/seeds/silero.dm b/modular_bandastation/tts/code/seeds/silero.dm new file mode 100644 index 0000000000000..5f83cb4078cd6 --- /dev/null +++ b/modular_bandastation/tts/code/seeds/silero.dm @@ -0,0 +1,3581 @@ +/datum/tts_seed/silero + provider = /datum/tts_provider/silero + +/datum/tts_seed/silero/arthas + name = "Arthas" + value = "arthas" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/kelthuzad + name = "Kelthuzad" + value = "kelthuzad" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/anubarak + name = "Anubarak" + value = "anubarak" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/thrall + name = "Thrall" + value = "thrall" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/grunt + name = "Grunt" + value = "grunt" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/cairne + name = "Cairne" + value = "cairne" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/rexxar + name = "Rexxar" + value = "rexxar" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/uther + name = "Uther" + value = "uther" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/jaina + name = "Jaina" + value = "jaina" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/kael + name = "Kael" + value = "kael" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/garithos + name = "Garithos" + value = "garithos" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/maiev + name = "Maiev" + value = "maiev" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/naisha + name = "Naisha" + value = "naisha" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/tyrande + name = "Tyrande" + value = "tyrande" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/furion + name = "Furion" + value = "furion" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/illidan + name = "Illidan" + value = "illidan" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/ladyvashj + name = "Ladyvashj" + value = "ladyvashj" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/narrator + name = "Narrator" + value = "narrator" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/medivh + name = "Medivh" + value = "medivh" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/villagerm + name = "Villagerm" + value = "villagerm" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/xenia + name = "Xenia" + value = "xenia" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/illidan_f + name = "Illidan_f" + value = "illidan_f" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/peon + name = "Peon" + value = "peon" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/chen + name = "Chen" + value = "chen" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/dread_bm + name = "Dread_bm" + value = "dread_bm" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sylvanas + name = "Sylvanas" + value = "sylvanas" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/priest + name = "Priest" + value = "priest" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/acolyte + name = "Acolyte" + value = "acolyte" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/muradin + name = "Muradin" + value = "muradin" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/dread_t + name = "Dread_t" + value = "dread_t" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/mannoroth + name = "Mannoroth" + value = "mannoroth" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sorceress + name = "Sorceress" + value = "sorceress" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/peasant + name = "Peasant" + value = "peasant" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/alyx + name = "Alyx" + value = "alyx" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/glados + name = "Glados" + value = "glados" + category = TTS_CATEGORY_PORTAL2 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/announcer + name = "Announcer" + value = "announcer" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/wheatley + name = "Wheatley" + value = "wheatley" + category = TTS_CATEGORY_PORTAL2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/barney + name = "Barney" + value = "barney" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/raynor + name = "Raynor" + value = "raynor" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kerrigan + name = "Kerrigan" + value = "kerrigan" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/tusk + name = "Tusk" + value = "tusk" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/earth + name = "Earth" + value = "earth" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/wraith + name = "Wraith" + value = "wraith" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/meepo + name = "Meepo" + value = "meepo" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/lina + name = "Lina" + value = "lina" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/bristle + name = "Bristle" + value = "bristle" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/gyro + name = "Gyro" + value = "gyro" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/treant + name = "Treant" + value = "treant" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/lancer + name = "Lancer" + value = "lancer" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/clockwerk + name = "Clockwerk" + value = "clockwerk" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/batrider + name = "Batrider" + value = "batrider" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/kotl + name = "Kotl" + value = "kotl" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/kunkka + name = "Kunkka" + value = "kunkka" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/pudge + name = "Pudge" + value = "pudge" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/juggernaut + name = "Juggernaut" + value = "juggernaut" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/vort_e2 + name = "Vort_e2" + value = "vort_e2" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/luna + name = "Luna" + value = "luna" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/omni + name = "Omni" + value = "omni" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sniper + name = "Sniper" + value = "sniper" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/skywrath + name = "Skywrath" + value = "skywrath" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/bounty + name = "Bounty" + value = "bounty" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/huskar + name = "Huskar" + value = "huskar" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/windranger + name = "Windranger" + value = "windranger" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/bloodseeker + name = "Bloodseeker" + value = "bloodseeker" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/templar + name = "Templar" + value = "templar" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/ranger + name = "Ranger" + value = "ranger" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/shaker + name = "Shaker" + value = "shaker" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/mortred + name = "Mortred" + value = "mortred" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/queen + name = "Queen" + value = "queen" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/storm + name = "Storm" + value = "storm" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/tide + name = "Tide" + value = "tide" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/evelynn + name = "Evelynn" + value = "evelynn" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/riki + name = "Riki" + value = "riki" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/antimage + name = "Antimage" + value = "antimage" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/witchdoctor + name = "Witchdoctor" + value = "witchdoctor" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/doom + name = "Doom" + value = "doom" + category = TTS_CATEGORY_DOTA2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/yuumi + name = "Yuumi" + value = "yuumi" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/bandit + name = "Bandit" + value = "bandit" + category = TTS_CATEGORY_STALKER + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/pantheon + name = "pantheon" + value = "pantheon" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tychus + name = "Tychus" + value = "tychus" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/breen + name = "Breen" + value = "breen" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/kleiner + name = "Kleiner" + value = "kleiner" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/father + name = "Father" + value = "father" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/tosh + name = "Tosh" + value = "tosh" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/stetmann + name = "Stetmann" + value = "stetmann" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/hanson + name = "Hanson" + value = "hanson" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/swann + name = "Swann" + value = "swann" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/hill + name = "Hill" + value = "hill" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/gman_e2 + name = "Gman_e2" + value = "gman_e2" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/valerian + name = "Valerian" + value = "valerian" + category = TTS_CATEGORY_STARCRAFT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/gman + name = "Gman" + value = "gman" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/vort + name = "Vort" + value = "vort" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/aradesh + name = "Aradesh" + value = "aradesh" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/dornan + name = "Dornan" + value = "dornan" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/elder + name = "Elder" + value = "elder" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/harris + name = "Harris" + value = "harris" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/cabbot + name = "Cabbot" + value = "cabbot" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/decker + name = "Decker" + value = "decker" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/dick + name = "Dick" + value = "dick" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/officer + name = "Officer" + value = "officer" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/frank + name = "Frank" + value = "frank" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/gizmo + name = "Gizmo" + value = "gizmo" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/hakunin + name = "Hakunin" + value = "hakunin" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/harold + name = "Harold" + value = "harold" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/harry + name = "Harry" + value = "harry" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/jain + name = "Jain" + value = "jain" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/maxson + name = "Maxson" + value = "maxson" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/killian + name = "Killian" + value = "killian" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/laura + name = "Laura" + value = "laura" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/lieutenant + name = "Lieutenant" + value = "lieutenant" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/loxley + name = "Loxley" + value = "loxley" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/lynette + name = "Lynette" + value = "lynette" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/marcus + name = "Marcus" + value = "marcus" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/master + name = "Master" + value = "master" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/morpheus + name = "Morpheus" + value = "morpheus" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/myron + name = "Myron" + value = "myron" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/nicole + name = "Nicole" + value = "nicole" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/overseer + name = "Overseer" + value = "overseer" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/rhombus + name = "Rhombus" + value = "rhombus" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/_set + name = "Set" + value = "set" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sulik + name = "Sulik" + value = "sulik" + category = TTS_CATEGORY_FALLOUT2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/tandi + name = "Tandi" + value = "tandi" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/vree + name = "Vree" + value = "vree" + category = TTS_CATEGORY_FALLOUT + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/dude + name = "Dude" + value = "dude" + category = TTS_CATEGORY_POSTAL2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/archmage + name = "Archmage" + value = "archmage" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/demoman + name = "Demoman" + value = "demoman" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/engineer + name = "Engineer" + value = "engineer" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/heavy + name = "Heavy" + value = "heavy" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/medic + name = "Medic" + value = "medic" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/scout + name = "Scout" + value = "scout" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sniper_tf + name = "Sniper_tf" + value = "sniper_tf" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/soldier + name = "Soldier" + value = "soldier" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/spy + name = "Spy" + value = "spy" + category = TTS_CATEGORY_TEAMFORTRESS2 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/admiral + name = "Admiral" + value = "admiral" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/alchemist + name = "Alchemist" + value = "alchemist" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/archimonde + name = "Archimonde" + value = "archimonde" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/breaker + name = "Breaker" + value = "breaker" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/captain + name = "Captain" + value = "captain" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/dryad + name = "Dryad" + value = "dryad" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/elf_eng + name = "Elf_eng" + value = "elf_eng" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/footman + name = "Footman" + value = "footman" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/grom + name = "Grom" + value = "grom" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/hh + name = "Hh" + value = "hh" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/huntress + name = "Huntress" + value = "huntress" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/keeper + name = "Keeper" + value = "keeper" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/naga_m + name = "Naga_m" + value = "naga_m" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/naga_rg + name = "Naga_rg" + value = "naga_rg" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/peasant_w + name = "Peasant_w" + value = "peasant_w" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/rifleman + name = "Rifleman" + value = "rifleman" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/satyr + name = "Satyr" + value = "satyr" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sylvanas_w + name = "Sylvanas_w" + value = "sylvanas_w" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/voljin + name = "Voljin" + value = "voljin" + category = TTS_CATEGORY_WARCRAFT3 + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/sidorovich + name = "Sidorovich" + value = "sidorovich" + category = TTS_CATEGORY_STALKER + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/p3 + name = "P3" + value = "p3" + category = TTS_CATEGORY_ATOMIC_HEART + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hraz + name = "Hraz" + value = "hraz" + category = TTS_CATEGORY_ATOMIC_HEART + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tereshkova + name = "Tereshkova" + value = "tereshkova" + category = TTS_CATEGORY_ATOMIC_HEART + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/babazina + name = "Babazina" + value = "babazina" + category = TTS_CATEGORY_ATOMIC_HEART + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/darius + name = "Darius" + value = "darius" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/trundle + name = "Trundle" + value = "trundle" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/garen + name = "Garen" + value = "garen" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kled + name = "Kled" + value = "kled" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/ekko + name = "Ekko" + value = "ekko" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/volibear + name = "Volibear" + value = "volibear" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/samira + name = "Samira" + value = "samira" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/swain + name = "Swain" + value = "swain" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/udyr + name = "Udyr" + value = "udyr" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dr_mundo + name = "Dr_mundo" + value = "dr_mundo" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/graves + name = "Graves" + value = "graves" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/rakan + name = "Rakan" + value = "rakan" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/renata_glasc + name = "Renata_glasc" + value = "renata_glasc" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/gangplank + name = "Gangplank" + value = "gangplank" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/riven + name = "Riven" + value = "riven" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/katarina + name = "Katarina" + value = "katarina" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ahri + name = "Ahri" + value = "ahri" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ornn + name = "Ornn" + value = "ornn" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/braum + name = "Braum" + value = "braum" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/fizz + name = "Fizz" + value = "fizz" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/draven + name = "Draven" + value = "draven" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/qiyana + name = "Qiyana" + value = "qiyana" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ksante + name = "Ksante" + value = "ksante" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/talon + name = "Talon" + value = "talon" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/shyvana + name = "Shyvana" + value = "shyvana" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zenyatta + name = "Zenyatta" + value = "zenyatta" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kiriko + name = "Kiriko" + value = "kiriko" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/hanzo + name = "Hanzo" + value = "hanzo" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/roadhog + name = "Roadhog" + value = "roadhog" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sigma + name = "Sigma" + value = "sigma" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/soldier_76 + name = "Soldier_76" + value = "soldier_76" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/junkrat + name = "Junkrat" + value = "junkrat" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tracer + name = "Tracer" + value = "tracer" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/genji + name = "Genji" + value = "genji" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/echo + name = "Echo" + value = "echo" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/sojourn + name = "Sojourn" + value = "sojourn" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/winston + name = "Winston" + value = "winston" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/reaper + name = "Reaper" + value = "reaper" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/training_robot + name = "Training_robot" + value = "training_robot" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/m_darkelf + name = "M_darkelf" + value = "m_darkelf" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/esbern + name = "Esbern" + value = "esbern" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_argo + name = "M_argo" + value = "m_argo" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_khajiit + name = "M_khajiit" + value = "m_khajiit" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_coward + name = "M_coward" + value = "m_coward" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/farkas + name = "Farkas" + value = "farkas" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_drunk + name = "M_drunk" + value = "m_drunk" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_khajiit + name = "F_khajiit" + value = "f_khajiit" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/m_citizen + name = "M_citizen" + value = "m_citizen" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_orc + name = "M_orc" + value = "m_orc" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/odahviing + name = "Odahviing" + value = "odahviing" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kodlak + name = "Kodlak" + value = "kodlak" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_child + name = "M_child" + value = "m_child" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/emperor + name = "Emperor" + value = "emperor" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hagraven + name = "Hagraven" + value = "hagraven" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/nazir + name = "Nazir" + value = "nazir" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dremora + name = "Dremora" + value = "dremora" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/alduin + name = "Alduin" + value = "alduin" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/malkoran + name = "Malkoran" + value = "malkoran" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/barbas + name = "Barbas" + value = "barbas" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hermaeus + name = "Hermaeus" + value = "hermaeus" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hakon + name = "Hakon" + value = "hakon" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/rita + name = "Rita" + value = "rita" + category = TTS_CATEGORY_RITA + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/barman + name = "Barman" + value = "barman" + category = TTS_CATEGORY_STALKER + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bridger2 + name = "Bridger2" + value = "bridger2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bridger3 + name = "Bridger3" + value = "bridger3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/cannibal3 + name = "Cannibal3" + value = "cannibal3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bridger1 + name = "Bridger1" + value = "bridger1" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/cannibal2 + name = "Cannibal2" + value = "cannibal2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/slave1 + name = "Slave1" + value = "slave1" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/slave3 + name = "Slave3" + value = "slave3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/mira + name = "Mira" + value = "mira" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/valeera + name = "Valeera" + value = "valeera" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/rehgar + name = "Rehgar" + value = "rehgar" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/yrel + name = "Yrel" + value = "yrel" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/volskaya + name = "Volskaya" + value = "volskaya" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/necromancer + name = "Necromancer" + value = "necromancer" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/zuljin + name = "Zuljin" + value = "zuljin" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/samuro + name = "Samuro" + value = "samuro" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tyrael + name = "Tyrael" + value = "tyrael" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/athena + name = "Athena" + value = "athena" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/default + name = "Default" + value = "default" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/chromie + name = "Chromie" + value = "chromie" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/orphea + name = "Orphea" + value = "orphea" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/adjutant + name = "Adjutant" + value = "adjutant" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/vanndara + name = "Vanndara" + value = "vanndara" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/mechatassadar + name = "Mechatassadar" + value = "mechatassadar" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/blackheart + name = "Blackheart" + value = "blackheart" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/olaf + name = "Olaf" + value = "olaf" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/alarak + name = "Alarak" + value = "alarak" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dva + name = "Dva" + value = "dva" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/toy18 + name = "Toy18" + value = "toy18" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/witchdoctor_h + name = "Witchdoctor_h" + value = "witchdoctor_h" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/lucio + name = "Lucio" + value = "lucio" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/angel + name = "Angel" + value = "angel" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/thunderking + name = "Thunderking" + value = "thunderking" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dr_boom + name = "Dr_boom" + value = "dr_boom" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hooktusk + name = "Hooktusk" + value = "hooktusk" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/sinclari + name = "Sinclari" + value = "sinclari" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/kazakus + name = "Kazakus" + value = "kazakus" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/ol_toomba + name = "Ol_toomba" + value = "ol_toomba" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/moroes + name = "Moroes" + value = "moroes" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/maiev_hs + name = "Maiev_hs" + value = "maiev_hs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zentimo + name = "Zentimo" + value = "zentimo" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/rastakhan + name = "Rastakhan" + value = "rastakhan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/innkeeper + name = "Innkeeper" + value = "innkeeper" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/togwaggle + name = "Togwaggle" + value = "togwaggle" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/biggs + name = "Biggs" + value = "biggs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/brann + name = "Brann" + value = "brann" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tekahn_boss + name = "Tekahn_boss" + value = "tekahn_boss" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/siamat + name = "Siamat" + value = "siamat" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/omnotron + name = "Omnotron" + value = "omnotron" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/putricide + name = "Putricide" + value = "putricide" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/khadgar + name = "Khadgar" + value = "khadgar" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/zoie + name = "Zoie" + value = "zoie" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/azalina + name = "Azalina" + value = "azalina" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/chu + name = "Chu" + value = "chu" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tekahn + name = "Tekahn" + value = "tekahn" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sthara + name = "Sthara" + value = "sthara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/dovo + name = "Dovo" + value = "dovo" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/shaw + name = "Shaw" + value = "shaw" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/greymane + name = "Greymane" + value = "greymane" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/willow + name = "Willow" + value = "willow" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/haro + name = "Haro" + value = "haro" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hagatha + name = "Hagatha" + value = "hagatha" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/reno + name = "Reno" + value = "reno" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/ozara + name = "Ozara" + value = "ozara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/loti + name = "Loti" + value = "loti" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/tarkus + name = "Tarkus" + value = "tarkus" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/voone + name = "Voone" + value = "voone" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tala + name = "Tala" + value = "tala" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/edra + name = "Edra" + value = "edra" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/myra + name = "Myra" + value = "myra" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/smiggs + name = "Smiggs" + value = "smiggs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/timothy + name = "Timothy" + value = "timothy" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/wendy + name = "Wendy" + value = "wendy" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/hannigan + name = "Hannigan" + value = "hannigan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/vargoth + name = "Vargoth" + value = "vargoth" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/jolene + name = "Jolene" + value = "jolene" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/kyriss + name = "Kyriss" + value = "kyriss" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/saurfang + name = "Saurfang" + value = "saurfang" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kizi + name = "Kizi" + value = "kizi" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/slate + name = "Slate" + value = "slate" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hesutu + name = "Hesutu" + value = "hesutu" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/hancho + name = "Hancho" + value = "hancho" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/gnomenapper + name = "Gnomenapper" + value = "gnomenapper" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/valdera + name = "Valdera" + value = "valdera" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/disidra + name = "Disidra" + value = "disidra" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/omu + name = "Omu" + value = "omu" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/floop + name = "Floop" + value = "floop" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/belloc + name = "Belloc" + value = "belloc" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/xurios + name = "Xurios" + value = "xurios" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/wagtoggle + name = "Wagtoggle" + value = "wagtoggle" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/belnaara + name = "Belnaara" + value = "belnaara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/lilayell + name = "Lilayell" + value = "lilayell" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/candlebeard + name = "Candlebeard" + value = "candlebeard" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/awilo + name = "Awilo" + value = "awilo" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/marei + name = "Marei" + value = "marei" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/applebough + name = "Applebough" + value = "applebough" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lazul + name = "Lazul" + value = "lazul" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/arwyn + name = "Arwyn" + value = "arwyn" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/glowtron + name = "Glowtron" + value = "glowtron" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/cardish + name = "Cardish" + value = "cardish" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/robold + name = "Robold" + value = "robold" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/malfurion + name = "Malfurion" + value = "malfurion" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/deathwhisper + name = "Deathwhisper" + value = "deathwhisper" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/janna + name = "Janna" + value = "janna" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/cassiopeia + name = "Cassiopeia" + value = "cassiopeia" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/taliyah + name = "Taliyah" + value = "taliyah" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/neeko + name = "Neeko" + value = "neeko" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/taric + name = "Taric" + value = "taric" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/akshan + name = "Akshan" + value = "akshan" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tristana + name = "Tristana" + value = "tristana" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/sylas + name = "Sylas" + value = "sylas" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sejuani + name = "Sejuani" + value = "sejuani" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/anivia + name = "Anivia" + value = "anivia" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/vayne + name = "Vayne" + value = "vayne" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/karma + name = "Karma" + value = "karma" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/nilah + name = "Nilah" + value = "nilah" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/olaf_lol + name = "Olaf_lol" + value = "olaf_lol" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/quinn + name = "Quinn" + value = "quinn" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lissandra + name = "Lissandra" + value = "lissandra" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/hecarim + name = "Hecarim" + value = "hecarim" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/vi + name = "Vi" + value = "vi" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zyra + name = "Zyra" + value = "zyra" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zac + name = "Zac" + value = "zac" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/moira + name = "Moira" + value = "moira" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ashe + name = "Ashe" + value = "ashe" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/brigitte + name = "Brigitte" + value = "brigitte" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/mercy + name = "Mercy" + value = "mercy" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lucio_ov + name = "Lucio_ov" + value = "lucio_ov" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dva_ov + name = "Dva_ov" + value = "dva_ov" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/symmetra + name = "Symmetra" + value = "symmetra" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zarya + name = "Zarya" + value = "zarya" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/cassidy + name = "Cassidy" + value = "cassidy" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/baptiste + name = "Baptiste" + value = "baptiste" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/junker_queen + name = "Junker_queen" + value = "junker_queen" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/doomfist + name = "Doomfist" + value = "doomfist" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/pharah + name = "Pharah" + value = "pharah" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/sombra + name = "Sombra" + value = "sombra" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ana + name = "Ana" + value = "ana" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/widowmaker + name = "Widowmaker" + value = "widowmaker" + category = TTS_CATEGORY_OVERWATCH + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/harbor + name = "Harbor" + value = "harbor" + category = TTS_CATEGORY_VALORANT + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sage + name = "Sage" + value = "sage" + category = TTS_CATEGORY_VALORANT + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/brimstone + name = "Brimstone" + value = "brimstone" + category = TTS_CATEGORY_VALORANT + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sova + name = "Sova" + value = "sova" + category = TTS_CATEGORY_VALORANT + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_shrill + name = "F_shrill" + value = "f_shrill" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/m_haughty + name = "M_haughty" + value = "m_haughty" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_soldier + name = "M_soldier" + value = "m_soldier" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/sven + name = "Sven" + value = "sven" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_sultry + name = "F_sultry" + value = "f_sultry" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/eorlund + name = "Eorlund" + value = "eorlund" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_commander + name = "M_commander" + value = "m_commander" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_nord + name = "F_nord" + value = "f_nord" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lydia + name = "Lydia" + value = "lydia" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/motierre + name = "Motierre" + value = "motierre" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_haughty + name = "F_haughty" + value = "f_haughty" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/tullius + name = "Tullius" + value = "tullius" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/festus + name = "Festus" + value = "festus" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_nord + name = "M_nord" + value = "m_nord" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/olava + name = "Olava" + value = "olava" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/f_commander + name = "F_commander" + value = "f_commander" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/hadvar + name = "Hadvar" + value = "hadvar" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_argo + name = "F_argo" + value = "f_argo" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/arngeir + name = "Arngeir" + value = "arngeir" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/nazeem + name = "Nazeem" + value = "nazeem" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/falion + name = "Falion" + value = "falion" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/f_coward + name = "F_coward" + value = "f_coward" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/m_guard + name = "M_guard" + value = "m_guard" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_commoner + name = "M_commoner" + value = "m_commoner" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/elisif + name = "Elisif" + value = "elisif" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/paarthurnax + name = "Paarthurnax" + value = "paarthurnax" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/grelka + name = "Grelka" + value = "grelka" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/f_commoner + name = "F_commoner" + value = "f_commoner" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ebony + name = "Ebony" + value = "ebony" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/ulfric + name = "Ulfric" + value = "ulfric" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/farengar + name = "Farengar" + value = "farengar" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/astrid + name = "Astrid" + value = "astrid" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/brynjolf + name = "Brynjolf" + value = "brynjolf" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/maven + name = "Maven" + value = "maven" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/f_child + name = "F_child" + value = "f_child" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/f_orc + name = "F_orc" + value = "f_orc" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/delphine + name = "Delphine" + value = "delphine" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/f_darkelf + name = "F_darkelf" + value = "f_darkelf" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/grelod + name = "Grelod" + value = "grelod" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/tolfdir + name = "Tolfdir" + value = "tolfdir" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_bandit + name = "M_bandit" + value = "m_bandit" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/m_forsworn + name = "M_forsworn" + value = "m_forsworn" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/karliah + name = "Karliah" + value = "karliah" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/felldir + name = "Felldir" + value = "felldir" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/ancano + name = "Ancano" + value = "ancano" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/mercer + name = "Mercer" + value = "mercer" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/vex + name = "Vex" + value = "vex" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/mirabelle + name = "Mirabelle" + value = "mirabelle" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/aventus + name = "Aventus" + value = "aventus" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/tsun + name = "Tsun" + value = "tsun" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/elenwen + name = "Elenwen" + value = "elenwen" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/gormlaith + name = "Gormlaith" + value = "gormlaith" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/dragon + name = "Dragon" + value = "dragon" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/overwatch + name = "Overwatch" + value = "overwatch" + category = TTS_CATEGORY_HALFLIFE2 + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zak + name = "Zak" + value = "zak" + category = TTS_CATEGORY_EVILISLANDS + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/merc2 + name = "Merc2" + value = "merc2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/forest1 + name = "Forest1" + value = "forest1" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bandit3 + name = "Bandit3" + value = "bandit3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/forest2 + name = "Forest2" + value = "forest2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/merc1 + name = "Merc1" + value = "merc1" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bandit2 + name = "Bandit2" + value = "bandit2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/forest3 + name = "Forest3" + value = "forest3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tribal3 + name = "Tribal3" + value = "tribal3" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/slave2 + name = "Slave2" + value = "slave2" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/miller + name = "Miller" + value = "miller" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/krest + name = "Krest" + value = "krest" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tribal1 + name = "Tribal1" + value = "tribal1" + category = TTS_CATEGORY_METRO + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/abathur + name = "Abathur" + value = "abathur" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/erik + name = "Erik" + value = "erik" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/varian + name = "Varian" + value = "varian" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/anduin + name = "Anduin" + value = "anduin" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/deckard + name = "Deckard" + value = "deckard" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/malfurion_h + name = "Malfurion_h" + value = "malfurion_h" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/demonhunter + name = "Demonhunter" + value = "demonhunter" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/demon + name = "Demon" + value = "demon" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kerrigan_h + name = "Kerrigan_h" + value = "kerrigan_h" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ladyofthorns + name = "Ladyofthorns" + value = "ladyofthorns" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/barbarian + name = "Barbarian" + value = "barbarian" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/crusader + name = "Crusader" + value = "crusader" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/whitemane + name = "Whitemane" + value = "whitemane" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/nexushunter + name = "Nexushunter" + value = "nexushunter" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/greymane_h + name = "Greymane_h" + value = "greymane_h" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/gardensdayannouncer + name = "Gardensdayannouncer" + value = "gardensdayannouncer" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/drekthar + name = "Drekthar" + value = "drekthar" + category = TTS_CATEGORY_HEROESOFTHESTORM + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/squeamlish + name = "Squeamlish" + value = "squeamlish" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/dagg + name = "Dagg" + value = "dagg" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/brukan + name = "Brukan" + value = "brukan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/bolan + name = "Bolan" + value = "bolan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/goya + name = "Goya" + value = "goya" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/stargazer + name = "Stargazer" + value = "stargazer" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/eudora + name = "Eudora" + value = "eudora" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/mozaki + name = "Mozaki" + value = "mozaki" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/katrana + name = "Katrana" + value = "katrana" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/valeera_hs + name = "Valeera_hs" + value = "valeera_hs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/malacrass + name = "Malacrass" + value = "malacrass" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/elise + name = "Elise" + value = "elise" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/flark + name = "Flark" + value = "flark" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/rhogi + name = "Rhogi" + value = "rhogi" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/gallywix + name = "Gallywix" + value = "gallywix" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/talanji + name = "Talanji" + value = "talanji" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/dr_sezavo + name = "Dr_sezavo" + value = "dr_sezavo" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/tierra + name = "Tierra" + value = "tierra" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zenda + name = "Zenda" + value = "zenda" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/baechao + name = "Baechao" + value = "baechao" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lilian + name = "Lilian" + value = "lilian" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/aranna + name = "Aranna" + value = "aranna" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/oshi + name = "Oshi" + value = "oshi" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/norroa + name = "Norroa" + value = "norroa" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/turalyon + name = "Turalyon" + value = "turalyon" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/aki + name = "Aki" + value = "aki" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/lunara + name = "Lunara" + value = "lunara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/bob + name = "Bob" + value = "bob" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/illucia + name = "Illucia" + value = "illucia" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/yrel_hs + name = "Yrel_hs" + value = "yrel_hs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/fireheart + name = "Fireheart" + value = "fireheart" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/lanathel + name = "Lanathel" + value = "lanathel" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/tyrande_hs + name = "Tyrande_hs" + value = "tyrande_hs" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/draemus + name = "Draemus" + value = "draemus" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/rasil + name = "Rasil" + value = "rasil" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/kalec + name = "Kalec" + value = "kalec" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/karastamper + name = "Karastamper" + value = "karastamper" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/george + name = "George" + value = "george" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/pollark + name = "Pollark" + value = "pollark" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/stelina + name = "Stelina" + value = "stelina" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/kasa + name = "Kasa" + value = "kasa" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/whirt + name = "Whirt" + value = "whirt" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/anarii + name = "Anarii" + value = "anarii" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/ilza + name = "Ilza" + value = "ilza" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/avozu + name = "Avozu" + value = "avozu" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/jeklik + name = "Jeklik" + value = "jeklik" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/zibb + name = "Zibb" + value = "zibb" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/thrud + name = "Thrud" + value = "thrud" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_MALE + donator_level = 0 + +/datum/tts_seed/silero/isiset + name = "Isiset" + value = "isiset" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_FEMALE + donator_level = 0 + +/datum/tts_seed/silero/akazamzarak + name = "Akazamzarak" + value = "akazamzarak" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/arha + name = "Arha" + value = "arha" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + +/datum/tts_seed/silero/aidar + name = "Aidar" + value = "aidar" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/baya + name = "Baya" + value = "baya" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/kseniya + name = "Kseniya" + value = "kseniya" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/silero/eugene + name = "Eugene" + value = "eugene" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/silero/senna + name = "Senna" + value = "senna" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/nunu + name = "Nunu" + value = "nunu" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/ryze + name = "Ryze" + value = "ryze" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/yone + name = "Yone" + value = "yone" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/sett + name = "Sett" + value = "sett" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/camille + name = "Camille" + value = "camille" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/lee_sin + name = "Lee_sin" + value = "lee_sin" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/kayle + name = "Kayle" + value = "kayle" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/azir + name = "Azir" + value = "azir" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/tryndamere + name = "Tryndamere" + value = "tryndamere" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/nami + name = "Nami" + value = "nami" + category = TTS_CATEGORY_LOL + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/delvin + name = "Delvin" + value = "delvin" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/cicero + name = "Cicero" + value = "cicero" + category = TTS_CATEGORY_SKYRIM + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/linzi + name = "Linzi" + value = "linzi" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/cache + name = "Cache" + value = "cache" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/cravitz + name = "Cravitz" + value = "cravitz" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/lady_vashj + name = "Lady_vashj" + value = "lady_vashj" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/dendrologist + name = "Dendrologist" + value = "dendrologist" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/jythiros + name = "Jythiros" + value = "jythiros" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/draan + name = "Draan" + value = "draan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/rikkar + name = "Rikkar" + value = "rikkar" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/splintergraft + name = "Splintergraft" + value = "splintergraft" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/malchezaar + name = "Malchezaar" + value = "malchezaar" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/taskmaster + name = "Taskmaster" + value = "taskmaster" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/oxana + name = "Oxana" + value = "oxana" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/inara + name = "Inara" + value = "inara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/ivan + name = "Ivan" + value = "ivan" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/kazamon + name = "Kazamon" + value = "kazamon" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/albin + name = "Albin" + value = "albin" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/ammunae + name = "Ammunae" + value = "ammunae" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/illidara + name = "Illidara" + value = "illidara" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 + +/datum/tts_seed/silero/nici + name = "Nici" + value = "nici" + category = TTS_CATEGORY_HEARTHSTONE + gender = TTS_GENDER_ANY + donator_level = 0 diff --git a/modular_bandastation/tts/code/tts_configuration.dm b/modular_bandastation/tts/code/tts_configuration.dm new file mode 100644 index 0000000000000..7f8d628e23674 --- /dev/null +++ b/modular_bandastation/tts/code/tts_configuration.dm @@ -0,0 +1,14 @@ +/datum/config_entry/flag/tts_enabled + default = FALSE + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/tts_token_silero + default = "" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/tts_cache + default = FALSE + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/ffmpeg_cpuaffinity + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/modular_bandastation/tts/code/tts_mob_Hear.dm b/modular_bandastation/tts/code/tts_mob_Hear.dm new file mode 100644 index 0000000000000..ded3d492a8457 --- /dev/null +++ b/modular_bandastation/tts/code/tts_mob_Hear.dm @@ -0,0 +1,67 @@ +/mob/proc/Hear_tts(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) + if(!SStts220.is_enabled) + return + + if(!isliving(src) && !isobserver(src)) + return + + if(!client) + return + + if(HAS_TRAIT(speaker, TRAIT_SIGN_LANG)) + return + + if(!message_language) + return + + var/is_custom_say_emote_without_message = (MODE_CUSTOM_SAY_ERASE_INPUT in message_mods) + if(is_custom_say_emote_without_message) + return + + if(stat == UNCONSCIOUS || stat == HARD_CRIT) + return + + if(!radio_freq && !LOCAL_TTS_ENABLED(src) || radio_freq && !RADIO_TTS_ENABLED(src)) + return + + var/atom/movable/virtualspeaker/virtual_speaker = speaker + var/atom/movable/real_speaker = istype(virtual_speaker) ? virtual_speaker.source : speaker + + var/self_radio = radio_freq && src == real_speaker + if(self_radio) + return + + var/is_speaker_whispering = (WHISPER_MODE in message_mods) + var/can_hear_whisper = get_dist(speaker, src) <= message_range || isobserver(src) + if(is_speaker_whispering && !can_hear_whisper) + return + + var/effect = issilicon(real_speaker) ? SOUND_EFFECT_ROBOT : SOUND_EFFECT_NONE + if(radio_freq) + effect = issilicon(real_speaker) ? SOUND_EFFECT_RADIO_ROBOT : SOUND_EFFECT_RADIO + else if(SPAN_COMMAND in spans) + effect = issilicon(real_speaker) ? SOUND_EFFECT_MEGAPHONE_ROBOT : SOUND_EFFECT_MEGAPHONE + + var/traits = TTS_TRAIT_RATE_MEDIUM + if(is_speaker_whispering) + traits &= TTS_TRAIT_PITCH_WHISPER + + var/message_tts = translate_language(language = message_language, raw_message = raw_message) + + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), speaker, src, message_tts, real_speaker.tts_seed, !radio_freq, effect, traits) + +/mob/living/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) + var/static/regex/plus_sign_replace = new(@"\+", "g") + var/plussless_message = plus_sign_replace.Replace(raw_message, "") + + . = ..(message, speaker, message_language, plussless_message, radio_freq, spans, message_mods, message_range) + + Hear_tts(message, speaker, message_language, raw_message, radio_freq, spans, message_mods, message_range) + +/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range) + var/static/regex/plus_sign_replace = new(@"\+", "g") + var/plussless_message = plus_sign_replace.Replace(raw_message, "") + + . = ..(message, speaker, message_language, plussless_message, radio_freq, spans, message_mods, message_range) + + Hear_tts(message, speaker, message_language, raw_message, radio_freq, spans, message_mods, message_range) diff --git a/modular_bandastation/tts/code/tts_numbers.dm b/modular_bandastation/tts/code/tts_numbers.dm new file mode 100644 index 0000000000000..c330ce48a285a --- /dev/null +++ b/modular_bandastation/tts/code/tts_numbers.dm @@ -0,0 +1,170 @@ +/proc/num_in_words(n) + return get_num_in_words(n) + +/proc/dec_in_words(n) + return get_num_in_words(n, TRUE) + +/proc/get_num_in_words(n, decimal = FALSE) + var/static/datum/number/num + if(!num) + num = new /datum/number + + if(num.cache["[n]"]) + return num.cache["[n]"] + + var/result + if(decimal) + result = num.decimal2words(n) + else + result = num.int2words(n) + + result = " [result] " + num.cache["[n]"] = result + return result + +/datum/number + var/static/list/units = list( + "ноль", + + list("один", "одна"), + list("два", "две"), + + "три", "четыре", "пять", + "шесть", "семь", "восемь", "девять" + ) + + var/static/list/teens = list( + "десять", "одиннадцать", + "двенадцать", "тринадцать", + "четырнадцать", "пятнадцать", + "шестнадцать", "семнадцать", + "восемнадцать", "девятнадцать" + ) + + var/static/list/tens = list( + "десять", + "двадцать", "тридцать", + "сорок", "пятьдесят", + "шестьдесят", "семьдесят", + "восемьдесят", "девяносто" + ) + + var/static/list/hundreds = list( + "сто", "двести", + "триста", "четыреста", + "пятьсот", "шестьсот", + "семьсот", "восемьсот", + "девятьсот" + ) + + var/static/list/orders = list( + list(list("тысяча", "тысячи", "тысяч"), "f"), + list(list("миллион", "миллиона", "миллионов"), "m"), + list(list("миллиард", "миллиарда", "миллиардов"), "m"), + list(list("триллион", "триллиона", "триллионов"), "m"), + list(list("квадриллион", "квадриллиона", "квадриллионов"), "m"), + list(list("квинтиллион", "квинтиллиона", "квинтиллионов"), "m"), + ) + + var/static/list/decimal_int_units = list(list("целая", "целых", "целых"), "f") + + var/static/list/decimal_exp_units = list( + list(list("десятая", "десятых", "десятых"), "f"), + list(list("сотая", "сотых", "сотых"), "f"), + list(list("тысячная", "тысячных", "тысячных"), "f"), + ) + + var/static/minus = "минус" + + var/static/cache = list() + +/datum/number/proc/thousand(rest, sex) +// """Converts numbers from 19 to 999""" + var/prev = 0 + var/plural = 3 + var/list/name = list() + var/use_teens = (rest % 100 >= 10) && (rest % 100 <= 19) + var/list/data = list() + + if(!use_teens) + data = list( list(units, 10), list(tens, 100), list(hundreds, 1000) ) + else + data = list( list(teens, 10), list(hundreds, 1000) ) + for(var/list in data) + + var/names = list[1] + var/x = list[2] + + var/cur = round(((rest - prev) % x) * 10 / x) + 1 + prev = rest % x + + if(x == 10 && use_teens) + plural = 3 + name += teens[cur] + else if(cur == 1) + continue + else if(x == 10) + var/name_ = names[cur] + if(islist(name_)) + name_ = name_[sex == "m" ? 1 : 2] + name += name_ + if(cur >= 3 && cur <= 5) + plural = 2 + else if(cur == 2) + plural = 1 + else + plural = 3 + else + name += names[cur-1] + + return list(plural, name) + +/datum/number/proc/int2words(textnum, list/main_units = list(list("", "", ""), "m")) +// http://ru.wikipedia.org/wiki/Gettext#.D0.9C.D0.BD.D0.BE.D0.B6.D0.B5.D1.81.D1.82.D0.B2.D0.B5.D0.BD.D0.BD.D1.8B.D0.B5_.D1.87.D0.B8.D1.81.D0.BB.D0.B0_2 + + var/list/_orders = list(main_units) + orders + + var/num = text2num(textnum) + if(num == 0) + return trim(jointext(list(units[1], _orders[1][1][3]), " ")) + + var/negative = FALSE + if(num < 0) + negative = TRUE + textnum = copytext_char(textnum, 2, 0) + + var/ord = 1 + var/list/name = list() + + while(textnum) + var/next_thousand = text2num(copytext_char(textnum, -3, 0)) + var/list/thousand_result = thousand(next_thousand, _orders[ord][2]) + var/plural = thousand_result[1] + var/list/nme = thousand_result[2] + + if(length(nme) || ord == 1) + name += _orders[ord][1][plural] + + name += nme + textnum = copytext_char(textnum, 1, -3) + ord += 1 + + if(negative) + name += minus + + var/temp_name = name + name = list() + for(var/i = length_char(temp_name), i >= 1, i--) + name += temp_name[i] + + var/result = trim(jointext(name, " ")) + return result + +/datum/number/proc/decimal2words(textvalue, places = 3) + var/pieces = splittext_char(textvalue, ".") + var/integral = pieces[1] + var/exp = copytext_char(pieces[2], 1, places + 1) + var/list/exp_units = decimal_exp_units[length_char(exp)] + + var/result = trim("[int2words(integral, decimal_int_units)] [int2words(exp, exp_units)]") + return result diff --git a/modular_bandastation/tts/code/tts_preferences.dm b/modular_bandastation/tts/code/tts_preferences.dm new file mode 100644 index 0000000000000..bfcd0a61d8c9c --- /dev/null +++ b/modular_bandastation/tts/code/tts_preferences.dm @@ -0,0 +1,73 @@ +/datum/preferences/ui_static_data(mob/user) + var/list/data = ..() + + data["tts_enabled"] = CONFIG_GET(flag/tts_enabled) + + var/list/providers = list() + for(var/_provider in SStts220.tts_providers) + var/datum/tts_provider/provider = SStts220.tts_providers[_provider] + providers += list(list( + "name" = provider.name, + "is_enabled" = provider.is_enabled, + )) + data["providers"] = providers + + var/list/seeds = list() + for(var/_seed in SStts220.tts_seeds) + var/datum/tts_seed/seed = SStts220.tts_seeds[_seed] + seeds += list(list( + "name" = seed.name, + "value" = seed.value, + "category" = seed.category, + "gender" = seed.gender, + "provider" = initial(seed.provider.name), + "donator_level" = seed.donator_level, + )) + data["seeds"] = seeds + + data["phrases"] = TTS_PHRASES + + return data + + +/datum/preferences/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if (.) + return + + switch (action) + if("listen") + var/phrase = params["phrase"] + var/seed_name = params["seed"] + + if((phrase in TTS_PHRASES) && (seed_name in SStts220.tts_seeds)) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(tts_cast), null, usr, phrase, seed_name, FALSE) + return FALSE + + if("select_voice") + var/seed_name = params["seed"] + var/datum/preference/tts_seed = GLOB.preference_entries_by_key["tts_seed"] + write_preference(tts_seed, seed_name) + return TRUE + +/datum/preference/numeric/sound_tts_local + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "sound_tts_local" + savefile_identifier = PREFERENCE_PLAYER + + minimum = 0 + maximum = 100 + +/datum/preference/numeric/sound_tts_local/create_default_value() + return 100 + +/datum/preference/numeric/sound_tts_radio + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "sound_tts_radio" + savefile_identifier = PREFERENCE_PLAYER + + minimum = 0 + maximum = 100 + +/datum/preference/numeric/sound_tts_radio/create_default_value() + return 50 diff --git a/modular_bandastation/tts/code/tts_provider.dm b/modular_bandastation/tts/code/tts_provider.dm new file mode 100644 index 0000000000000..aa159eef07cde --- /dev/null +++ b/modular_bandastation/tts/code/tts_provider.dm @@ -0,0 +1,31 @@ +/datum/tts_provider + var/name = "STUB" + var/is_enabled = TRUE + + // Throttling + var/is_throttled = FALSE + var/throttled_until = 0 + + var/failed_requests = 0 + var/failed_requests_limit = 10 + +/datum/tts_provider/proc/request(text, datum/tts_seed/seed, datum/callback/proc_callback) + return TRUE + +/datum/tts_provider/proc/process_response(datum/http_response/response) + return null + +/datum/tts_provider/proc/throttle_check() + if(is_throttled && throttled_until < world.time) + return TRUE + is_throttled = FALSE + return FALSE + +/datum/tts_provider/proc/pitch_whisper(text) + return text + +/datum/tts_provider/proc/rate_faster(text) + return text + +/datum/tts_provider/proc/rate_medium(text) + return text diff --git a/modular_bandastation/tts/code/tts_seed.dm b/modular_bandastation/tts/code/tts_seed.dm new file mode 100644 index 0000000000000..627dd3f35f615 --- /dev/null +++ b/modular_bandastation/tts/code/tts_seed.dm @@ -0,0 +1,24 @@ +/datum/tts_seed + var/name = "STUB" + var/value = "STUB" + var/category = TTS_CATEGORY_OTHER + var/gender = TTS_GENDER_ANY + var/datum/tts_provider/provider = /datum/tts_provider + var/donator_level = 0 + +/datum/tts_seed/vv_edit_var(var_name, var_value) + return FALSE + +/datum/preference/text/tts_seed + savefile_key = "tts_seed" + savefile_identifier = PREFERENCE_CHARACTER + +/datum/preference/text/tts_seed/create_default_value() + return "Arthas" + +/// Any movable atom +/atom/movable + var/tts_seed + +/datum/preference/text/tts_seed/apply_to_human(mob/living/carbon/human/target, value) + target.tts_seed = value diff --git a/modular_bandastation/tts/code/tts_sound.dm b/modular_bandastation/tts/code/tts_sound.dm new file mode 100644 index 0000000000000..f9271e3f399cc --- /dev/null +++ b/modular_bandastation/tts/code/tts_sound.dm @@ -0,0 +1,44 @@ +// TODO: SS220-TTS to delete +//world/proc/shelleo +#define SHELLEO_ERRORLEVEL 1 +#define SHELLEO_STDOUT 2 +#define SHELLEO_STDERR 3 + +/proc/apply_sound_effect(effect, filename_input, filename_output) + if(!effect) + CRASH("Invalid sound effect chosen.") + + var/taskset + // TODO: SS220-TTS + if(CONFIG_GET(string/ffmpeg_cpuaffinity)) + taskset = "taskset -ac [CONFIG_GET(string/ffmpeg_cpuaffinity)]" + + var/list/output + switch(effect) + if(SOUND_EFFECT_RADIO) + output = world.shelleo({"[taskset] ffmpeg -y -hide_banner -loglevel error -i [filename_input] -filter:a "highpass=f=1000, lowpass=f=3000, acrusher=1:1:50:0:log" [filename_output]"}) + if(SOUND_EFFECT_ROBOT) + output = world.shelleo({"[taskset] ffmpeg -y -hide_banner -loglevel error -i [filename_input] -filter:a "afftfilt=real='hypot(re,im)*sin(0)':imag='hypot(re,im)*cos(0)':win_size=1024:overlap=0.5, deesser=i=0.4, volume=volume=1.5" [filename_output]"}) + if(SOUND_EFFECT_RADIO_ROBOT) + output = world.shelleo({"[taskset] ffmpeg -y -hide_banner -loglevel error -i [filename_input] -filter:a "afftfilt=real='hypot(re,im)*sin(0)':imag='hypot(re,im)*cos(0)':win_size=1024:overlap=0.5, deesser=i=0.4, volume=volume=1.5, highpass=f=1000, lowpass=f=3000, acrusher=1:1:50:0:log" [filename_output]"}) + if(SOUND_EFFECT_MEGAPHONE) + output = world.shelleo({"[taskset] ffmpeg -y -hide_banner -loglevel error -i [filename_input] -filter:a "highpass=f=500, lowpass=f=4000, volume=volume=10, acrusher=1:1:45:0:log" [filename_output]"}) + if(SOUND_EFFECT_MEGAPHONE_ROBOT) + output = world.shelleo({"[taskset] ffmpeg -y -hide_banner -loglevel error -i [filename_input] -filter:a "afftfilt=real='hypot(re,im)*sin(0)':imag='hypot(re,im)*cos(0)':win_size=1024:overlap=0.5, deesser=i=0.4, highpass=f=500, lowpass=f=4000, volume=volume=10, acrusher=1:1:45:0:log" [filename_output]"}) + else + CRASH("Invalid sound effect chosen.") + var/errorlevel = output[SHELLEO_ERRORLEVEL] + var/stdout = output[SHELLEO_STDOUT] + var/stderr = output[SHELLEO_STDERR] + if(errorlevel) + error("Error: apply_sound_effect([effect], [filename_input], [filename_output]) - See debug logs.") + // TODO: SS220-TTS log_debug -> debug_world_log + debug_world_log("apply_sound_effect([effect], [filename_input], [filename_output]) STDOUT: [stdout]") + debug_world_log("apply_sound_effect([effect], [filename_input], [filename_output]) STDERR: [stderr]") + return FALSE + return TRUE + +//world/proc/shelleo +#undef SHELLEO_ERRORLEVEL +#undef SHELLEO_STDOUT +#undef SHELLEO_STDERR diff --git a/modular_bandastation/tts/code/tts_sound_TEMPORARY.dm b/modular_bandastation/tts/code/tts_sound_TEMPORARY.dm new file mode 100644 index 0000000000000..a8bae493691ec --- /dev/null +++ b/modular_bandastation/tts/code/tts_sound_TEMPORARY.dm @@ -0,0 +1,77 @@ +// TODO: SS220-TTS Remove this file when upstream `/mob/proc/playsound_local` supports passing `wait` as parameter. +// Copypasted `/mob/proc/playsound_local` method with `wait` support. +/mob/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/sound_to_use, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE, wait = FALSE) + if(!wait) + return ..() + + if(!client || !can_hear()) + return + + if(!sound_to_use) + sound_to_use = sound(get_sfx(soundin)) + + sound_to_use.wait = wait + sound_to_use.channel = channel || SSsounds.random_available_channel() + sound_to_use.volume = vol + + if(vary) + if(frequency) + sound_to_use.frequency = frequency + else + sound_to_use.frequency = get_rand_frequency() + + if(isturf(turf_source)) + var/turf/turf_loc = get_turf(src) + + //sound volume falloff with distance + var/distance = get_dist(turf_loc, turf_source) * distance_multiplier + + if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff. + sound_to_use.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * sound_to_use.volume + //https://www.desmos.com/calculator/sqdfl8ipgf + + if(pressure_affected) + //Atmosphere affects sound + var/pressure_factor = 1 + var/datum/gas_mixture/hearer_env = turf_loc.return_air() + var/datum/gas_mixture/source_env = turf_source.return_air() + + if(hearer_env && source_env) + var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure()) + if(pressure < ONE_ATMOSPHERE) + pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0) + else //space + pressure_factor = 0 + + if(distance <= 1) + pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound + + sound_to_use.volume *= pressure_factor + //End Atmosphere affecting sound + + if(sound_to_use.volume <= 0) + return //No sound + + var/dx = turf_source.x - turf_loc.x // Hearing from the right/left + sound_to_use.x = dx * distance_multiplier + var/dz = turf_source.y - turf_loc.y // Hearing from infront/behind + sound_to_use.z = dz * distance_multiplier + var/dy = (turf_source.z - turf_loc.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords. + sound_to_use.y = dy + + sound_to_use.falloff = max_distance || 1 //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant. + + // Sounds can't have their own environment. A sound's environment will be: + // 1. the mob's + // 2. the area's (defaults to SOUND_ENVRIONMENT_NONE) + if(sound_environment_override != SOUND_ENVIRONMENT_NONE) + sound_to_use.environment = sound_environment_override + else + var/area/A = get_area(src) + sound_to_use.environment = A.sound_environment + + if(use_reverb && sound_to_use.environment != SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting + sound_to_use.echo[3] = -1300 //Room setting, 0 means normal reverb //SKYRAT EDIT CHANGE + sound_to_use.echo[4] = -1300 //RoomHF setting, 0 means normal reverb. //SKYRAT EDIT CHANGE + + SEND_SOUND(src, sound_to_use) diff --git a/modular_bandastation/tts/code/tts_subsystem.dm b/modular_bandastation/tts/code/tts_subsystem.dm new file mode 100644 index 0000000000000..2eb40ae067265 --- /dev/null +++ b/modular_bandastation/tts/code/tts_subsystem.dm @@ -0,0 +1,577 @@ +SUBSYSTEM_DEF(tts220) + name = "Text-to-Speech 220" + init_order = INIT_ORDER_DEFAULT + wait = 1 SECONDS + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + + var/tts_wanted = 0 + var/tts_request_failed = 0 + var/tts_request_succeeded = 0 + var/tts_reused = 0 + var/list/tts_errors = list() + var/tts_error_raw = "" + + // Simple Moving Average RPS + var/list/tts_rps_list = list() + var/tts_sma_rps = 0 + + // Requests per Second (RPS), only real API requests + var/tts_rps = 0 + var/tts_rps_counter = 0 + + // Total Requests per Second (TRPS), all TTS request, even reused + var/tts_trps = 0 + var/tts_trps_counter = 0 + + // Reused Requests per Second (RRPS), only reused requests + var/tts_rrps = 0 + var/tts_rrps_counter = 0 + + var/is_enabled = TRUE + + var/list/datum/tts_seed/tts_seeds = list() + var/list/tts_seeds_names = list() + var/list/tts_seeds_names_by_donator_levels = list() + var/list/datum/tts_provider/tts_providers = list() + + var/list/tts_local_channels_by_owner = list() + + var/list/tts_requests_queue = list() + var/tts_requests_queue_limit = 100 + var/tts_rps_limit = 5 + + var/list/tts_queue = list() + var/list/tts_effects_queue = list() + + var/sanitized_messages_caching = TRUE + var/list/sanitized_messages_cache = list() + var/sanitized_messages_cache_hit = 0 + var/sanitized_messages_cache_miss = 0 + + var/debug_mode_enabled = FALSE + + var/static/list/tts_job_replacements = list( + "nanotrasen navy field officer" = "Полевой офицер флота Нанотрэйзен", + "nanotrasen navy officer" = "Офицер флота nanotrasen", + "supreme commander" = "Верховный главнокомандующий", + "solar federation general" = "Генерал Солнечной Федерации", + "special operations officer" = "Офицер специальных операций", + "civilian" = "Гражданский", + "tourist" = "Турист", + "businessman" = "Бизнэсмэн", + "trader" = "Торговец", + "assistant" = "Ассистент", + "chief engineer" = "Главный Инженер", + "station engineer" = "Станционный инженер", + "trainee engineer" = "Инженер-стажер", + "Engineer Assistant" = "Инженерный Ассистент", + "Technical Assistant" = "Технический Ассистент", + "Engineer Student" = "Инженер-практикант", + "Technical Student" = "Техник-практикант", + "Technical Trainee" = "Техник-стажер", + "maintenance technician" = "Техник по обслуживанию", + "engine technician" = "Техник по двигателям", + "electrician" = "Электрик", + "life support specialist" = "Специалист по жизнеобеспечению", + "atmospheric technician" = "Атмосферный техник", + "mechanic" = "Механик", + "chief medical officer" = "Главный врач", + "medical doctor" = "Врач", + "Intern" = "Интерн", + "Student Medical Doctor" = "Врач-практикант", + "Medical Assistant" = "Ассистирующий врач", + "surgeon" = "Хирург", + "nurse" = "Медсестра", + "coroner" = "К+оронэр", + "chemist" = "Химик", + "pharmacist" = "Фармацевт", + "pharmacologist" = "Фармаколог", + "geneticist" = "Генетик", + "virologist" = "Вирусолог", + "pathologist" = "Патологоанатом", + "microbiologist" = "Микробиолог", + "psychiatrist" = "Психиатр", + "psychologist" = "Психолог", + "therapist" = "Терапевт", + "paramedic" = "Парамедик", + "research director" = "Директор исследований", + "scientist" = "Учёный", + "student scientist" = "Учёный-практикант", + "Scientist Assistant" = "Научный Ассистент", + "Scientist Pregraduate" = "Учёный-бакалавр", + "Scientist Graduate" = "Научный выпускник", + "Scientist Postgraduate" = "Учёный-аспирант", + "anomalist" = "Аномалист", + "plasma researcher" = "Исследователь плазмы", + "xenobiologist" = "Ксенобиолог", + "chemical researcher" = "Химик-исследователь", + "roboticist" = "Робототехник", + "student robotist" = "Студент-робототехник", + "biomechanical engineer" = "Биомеханический инженер", + "mechatronic engineer" = "Инженер мехатроники", + "head of security" = "Глава службы безопасности", + "warden" = "Смотритель", + "detective" = "Детектив", + "forensic technician" = "Криминалист", + "security officer" = "Офицер службы безопасности", + "security cadet" = "Кадет службы безопасности", + "Security Assistant" = "Ассистент службы безопасности", + "Security Graduate" = "Выпускник кадетской академии", + "brig physician" = "Врач брига", + "security pod pilot" = "Пилот пода службы безопасности", + "ai" = "И И", + "cyborg" = "Киборг", + "robot" = "Робот", + "captain" = "Капитан", + "head of personnel" = "Глава персонала", + "nanotrasen representative" = "Представитель Нанотрэйзен", + "blueshield" = "Блюшилд", + "magistrate" = "Магистрат", + "internal affairs agent" = "Агент внутренних дел", + "human resources agent" = "Агент по персоналу", + "bartender" = "Бармэн", + "chef" = "Повар", + "cook" = "Кук", + "culinary artist" = "Кулинар", + "butcher" = "Мясник", + "botanist" = "Ботаник", + "hydroponicist" = "Гидропонист", + "botanical researcher" = "Ботаник-исследователь", + "quartermaster" = "Квартирмейстер", + "cargo technician" = "Карго техник", + "shaft miner" = "Шахтёр", + "spelunker" = "Спелеолог", + "clown" = "Клоун", + "mime" = "Мим", + "janitor" = "Уборщик", + "custodial technician" = "Техник по уходу за помещениями", + "librarian" = "Библиотекарь", + "journalist" = "Журналист", + "barber" = "Парикмахер", + "hair stylist" = "Стилист", + "beautician" = "Косметолог", + "explorer" = "Исследователь", + "chaplain" = "Священник", + "syndicate officer" = "Офицер синдиката", + "visitor" = "посетитель", + ) + +/datum/controller/subsystem/tts220/stat_entry(msg) + msg += "tRPS:[tts_trps] " + msg += "rRPS:[tts_rrps] " + msg += "RPS:[tts_rps] " + msg += "smaRPS:[tts_sma_rps] | " + msg += "W:[tts_wanted] " + msg += "F:[tts_request_failed] " + msg += "S:[tts_request_succeeded] " + msg += "R:[tts_reused] " + return ..() + +/datum/controller/subsystem/tts220/PreInit() + . = ..() + for(var/path in subtypesof(/datum/tts_provider)) + var/datum/tts_provider/provider = new path + tts_providers[provider.name] += provider + for(var/path in subtypesof(/datum/tts_seed)) + var/datum/tts_seed/seed = new path + if(seed.value == "STUB") + continue + seed.provider = tts_providers[initial(seed.provider.name)] + tts_seeds[seed.name] = seed + tts_seeds_names += seed.name + tts_seeds_names_by_donator_levels["[seed.donator_level]"] += list(seed.name) + tts_seeds_names = sortTim(tts_seeds_names, /proc/cmp_text_asc) + +/datum/controller/subsystem/tts220/Initialize(start_timeofday) + is_enabled = CONFIG_GET(flag/tts_enabled) + if(!is_enabled) + flags |= SS_NO_FIRE + + return SS_INIT_SUCCESS + +/datum/controller/subsystem/tts220/fire() + tts_rps = tts_rps_counter + tts_rps_counter = 0 + tts_trps = tts_trps_counter + tts_trps_counter = 0 + tts_rrps = tts_rrps_counter + tts_rrps_counter = 0 + + tts_rps_list += tts_rps + if(tts_rps_list.len > 15) + tts_rps_list.Cut(1,2) + + var/rps_sum = 0 + for(var/rps in tts_rps_list) + rps_sum += rps + tts_sma_rps = round(rps_sum / tts_rps_list.len, 0.1) + + var/free_rps = clamp(tts_rps_limit - tts_rps, 0, tts_rps_limit) + var/requests = tts_requests_queue.Copy(1, clamp(LAZYLEN(tts_requests_queue), 0, free_rps) + 1) + for(var/request in requests) + var/text = request[1] + var/datum/tts_seed/seed = request[2] + var/datum/callback/proc_callback = request[3] + var/datum/tts_provider/provider = seed.provider + provider.request(text, seed, proc_callback) + tts_rps_counter++ + tts_requests_queue.Cut(1, clamp(LAZYLEN(tts_requests_queue), 0, free_rps) + 1) + + if(sanitized_messages_caching) + sanitized_messages_cache.Cut() + if(debug_mode_enabled) + world.log << "sanitized_messages_cache: HIT=[sanitized_messages_cache_hit] / MISS=[sanitized_messages_cache_miss]" + sanitized_messages_cache_hit = 0 + sanitized_messages_cache_miss = 0 + +/datum/controller/subsystem/tts220/Recover() + is_enabled = SStts220.is_enabled + tts_wanted = SStts220.tts_wanted + tts_request_failed = SStts220.tts_request_failed + tts_request_succeeded = SStts220.tts_request_succeeded + tts_reused = SStts220.tts_reused + +/datum/controller/subsystem/tts220/proc/queue_request(text, datum/tts_seed/seed, datum/callback/proc_callback) + if(LAZYLEN(tts_requests_queue) > tts_requests_queue_limit) + is_enabled = FALSE + to_chat(world, span_announce("SERVER: очередь запросов превысила лимит, подсистема SStts принудительно отключена!")) + return FALSE + + if(tts_rps_counter < tts_rps_limit) + var/datum/tts_provider/provider = seed.provider + provider.request(text, seed, proc_callback) + tts_rps_counter++ + return TRUE + + tts_requests_queue += list(list(text, seed, proc_callback)) + return TRUE + +/datum/controller/subsystem/tts220/proc/get_tts(atom/speaker, mob/listener, message, seed_name, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null) + if(!is_enabled) + return + if(!message) + return + if(isnull(listener) || !listener.client) + return + if(isnull(seed_name) || !(seed_name in tts_seeds)) + return + var/datum/tts_seed/seed = tts_seeds[seed_name] + + tts_wanted++ + tts_trps_counter++ + + var/datum/tts_provider/provider = seed.provider + if(!provider.is_enabled) + return + if(provider.throttle_check()) + return + + var/dirty_text = message + var/text = sanitize_tts_input(dirty_text) + + if(!text || length_char(text) > MAX_MESSAGE_LEN) + return + + if(traits & TTS_TRAIT_RATE_FASTER) + text = provider.rate_faster(text) + + if(traits & TTS_TRAIT_RATE_MEDIUM) + text = provider.rate_medium(text) + + if(traits & TTS_TRAIT_PITCH_WHISPER) + text = provider.pitch_whisper(text) + + var/hash = rustgss220_hash_string(RUSTG_HASH_MD5, text) + var/filename = "sound/tts_cache/[seed.name]/[hash]" + + var/datum/callback/play_tts_cb = CALLBACK(src, PROC_REF(play_tts), speaker, listener, filename, is_local, effect, preSFX, postSFX) + + if(fexists("[filename].ogg")) + tts_reused++ + tts_rrps_counter++ + play_tts(speaker, listener, filename, is_local, effect, preSFX, postSFX) + return + + if(LAZYLEN(tts_queue[filename])) + tts_reused++ + tts_rrps_counter++ + LAZYADD(tts_queue[filename], play_tts_cb) + return + + var/datum/callback/cb = CALLBACK(src, PROC_REF(get_tts_callback), speaker, listener, filename, seed, is_local, effect, preSFX, postSFX) + queue_request(text, seed, cb) + LAZYADD(tts_queue[filename], play_tts_cb) + +/datum/controller/subsystem/tts220/proc/get_tts_callback(atom/speaker, mob/listener, filename, datum/tts_seed/seed, is_local, effect, preSFX, postSFX, datum/http_response/response) + var/datum/tts_provider/provider = seed.provider + + // Bail if it errored + if(response.errored) + provider.failed_requests++ + if(provider.failed_requests >= provider.failed_requests_limit) + provider.is_enabled = FALSE + message_admins("Error connecting to [provider.name] TTS API. Please inform a maintainer or server host.") + return + + if(response.status_code != 200) + provider.failed_requests++ + if(provider.failed_requests >= provider.failed_requests_limit) + provider.is_enabled = FALSE + message_admins("Error performing [provider.name] TTS API request (Code: [response.status_code])") + tts_request_failed++ + if(response.status_code) + if(tts_errors["[response.status_code]"]) + tts_errors["[response.status_code]"]++ + else + tts_errors += "[response.status_code]" + tts_errors["[response.status_code]"] = 1 + tts_error_raw = response.error + return + + tts_request_succeeded++ + + var/voice = provider.process_response(response) + if(!voice) + return + + rustgss220_file_write_b64decode(voice, "[filename].ogg") + + if (!CONFIG_GET(flag/tts_cache)) + addtimer(CALLBACK(src, PROC_REF(cleanup_tts_file), "[filename].ogg"), 30 SECONDS) + + for(var/datum/callback/cb in tts_queue[filename]) + cb.InvokeAsync() + tts_queue[filename] -= cb + + tts_queue -= filename + +/datum/controller/subsystem/tts220/proc/play_tts(atom/speaker, mob/listener, filename, is_local = TRUE, effect = SOUND_EFFECT_NONE, preSFX = null, postSFX = null) + if(isnull(listener) || !listener.client) + return + + var/voice + switch(effect) + if(SOUND_EFFECT_NONE) + voice = "[filename].ogg" + if(SOUND_EFFECT_RADIO) + voice = "[filename]_radio.ogg" + if(SOUND_EFFECT_ROBOT) + voice = "[filename]_robot.ogg" + if(SOUND_EFFECT_RADIO_ROBOT) + voice = "[filename]_radio_robot.ogg" + if(SOUND_EFFECT_MEGAPHONE) + voice = "[filename]_megaphone.ogg" + if(SOUND_EFFECT_MEGAPHONE_ROBOT) + voice = "[filename]_megaphone_robot.ogg" + else + CRASH("Invalid sound effect chosen.") + if(effect != SOUND_EFFECT_NONE) + if(!fexists(voice)) + var/datum/callback/play_tts_cb = CALLBACK(src, PROC_REF(play_tts), speaker, listener, filename, is_local, effect, preSFX, postSFX) + if(LAZYLEN(tts_effects_queue[voice])) + LAZYADD(tts_effects_queue[voice], play_tts_cb) + return + LAZYADD(tts_effects_queue[voice], play_tts_cb) + apply_sound_effect(effect, "[filename].ogg", voice) + for(var/datum/callback/cb in tts_effects_queue[voice]) + tts_effects_queue[voice] -= cb + if(cb == play_tts_cb) + continue + cb.InvokeAsync() + tts_effects_queue -= voice + + var/turf/turf_source = get_turf(speaker) + + var/volume + var/channel + if(is_local) + volume = LOCAL_TTS_VOLUME(listener) + channel = get_local_channel_by_owner(speaker) + else + volume = RADIO_TTS_VOLUME(listener) + channel = CHANNEL_TTS_RADIO + + var/sound/output = sound(voice) + output.status = SOUND_STREAM + + if(isnull(speaker)) + output.wait = TRUE + output.channel = channel + // TODO: SS220-TTS + // output.volume = volume * listener.client.prefs.get_channel_volume(CHANNEL_GENERAL) * listener.client.prefs.get_channel_volume(channel) + output.volume = volume + output.environment = -1 + + if(output.volume <= 0) + return + + if(preSFX) + play_sfx(listener, preSFX, output.channel, output.volume, output.environment) + + SEND_SOUND(listener, output) + return + + if(preSFX) + play_sfx(listener, preSFX, output.channel, output.volume, output.environment) + + listener.playsound_local(turf_source, output, volume, sound_to_use = output, channel = channel, wait = TRUE) + + if(!output || output.volume <= 0) + return + + if(postSFX) + play_sfx(listener, postSFX, output.channel, output.volume, output.environment) + +/datum/controller/subsystem/tts220/proc/play_sfx(mob/listener, sfx, channel, volume, environment) + var/sound/output = sound(sfx) + output.status = SOUND_STREAM + output.wait = TRUE + output.channel = channel + output.volume = volume + output.environment = environment + SEND_SOUND(listener, output) + +/datum/controller/subsystem/tts220/proc/get_local_channel_by_owner(owner) + var/channel = tts_local_channels_by_owner[owner] + if(isnull(channel)) + channel = SSsounds.reserve_sound_channel_datumless() + tts_local_channels_by_owner[owner] = channel + return channel + +/datum/controller/subsystem/tts220/proc/cleanup_tts_file(filename) + fdel(filename) + +/datum/controller/subsystem/tts220/proc/get_available_seeds(owner) + var/list/_tts_seeds_names = list() + _tts_seeds_names |= tts_seeds_names + + if(!ismob(owner)) + return _tts_seeds_names + + var/mob/M = owner + + if(!M.client) + return _tts_seeds_names + + // TODO: SS220-TTS + // for(var/donator_level in 0 to DONATOR_LEVEL_MAX) + // if(M.client.donator_level < donator_level) + // _tts_seeds_names -= tts_seeds_names_by_donator_levels["[donator_level]"] + return _tts_seeds_names + +/datum/controller/subsystem/tts220/proc/get_random_seed(owner) + return pick(get_available_seeds(owner)) + +/datum/controller/subsystem/tts220/proc/sanitize_tts_input(message) + var/hash + if(sanitized_messages_caching) + hash = rustgss220_hash_string(RUSTG_HASH_MD5, message) + if(sanitized_messages_cache[hash]) + sanitized_messages_cache_hit++ + return sanitized_messages_cache[hash] + sanitized_messages_cache_miss++ + . = message + . = trim(.) + + var/static/regex/punctuation_check = new(@"[.,?!]\Z") + if(!punctuation_check.Find(.)) + . += "." + + var/static/regex/html_tags = new(@"<[^>]*>", "g") + . = html_tags.Replace(., "") + . = html_decode(.) + + var/static/regex/forbidden_symbols = new(@"[^a-zA-Z0-9а-яА-ЯёЁ,!?+./ \r\n\t:—()-]", "g") + . = forbidden_symbols.Replace(., "") + + var/static/regex/words = new(@"(?SERVER: провайдер Silero в подсистеме SStts220 принудительно включен!
") + return json_encode(list("success" = "SStts220\[Silero] was force enabled")) + return json_encode(list("error" = "SStts220\[Silero] is already enabled")) + +/datum/world_topic/playerlist + keyword = "playerlist" + +/datum/world_topic/playerlist/Run(list/input) + var/list/keys = list() + for(var/I in GLOB.clients) + var/client/C = I + keys += C.key + + return json_encode(keys) + +/datum/world_topic/status/Run(list/input) + . = ..() + var/list/admins = list() + for(var/client/C in GLOB.clients) + if(C.holder) + if(C.holder.fakekey) + continue //so stealthmins aren't revealed by the hub + admins += list(list(C.key, join_admin_ranks(C.holder.ranks))) + if(key_valid) + for(var/i in 1 to admins.len) + var/list/A = admins[i] + .["admin[i - 1]"] = A[1] + .["adminrank[i - 1]"] = A[2] diff --git a/rust_g_ss220.dll b/rust_g_ss220.dll new file mode 100644 index 0000000000000..ef1d0ec0bdd59 Binary files /dev/null and b/rust_g_ss220.dll differ diff --git a/tgstation.dme b/tgstation.dme index 9446949bf2f5f..65ce2b7836aaf 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5898,4 +5898,5 @@ #include "interface\fonts\spess_font.dm" #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" +#include "modular_bandastation\modular_bandastation.dme" // BANDASTATION EDIT // END_INCLUDE diff --git a/tgui/packages/tgui-say/ChannelIterator.test.ts b/tgui/packages/tgui-say/ChannelIterator.test.ts index 15e9812e702ec..91719cbbf51a5 100644 --- a/tgui/packages/tgui-say/ChannelIterator.test.ts +++ b/tgui/packages/tgui-say/ChannelIterator.test.ts @@ -11,6 +11,10 @@ describe('ChannelIterator', () => { expect(channelIterator.current()).toBe('Say'); expect(channelIterator.next()).toBe('Radio'); expect(channelIterator.next()).toBe('Me'); + // BANDASTATION EDIT ADDITION START + expect(channelIterator.next()).toBe('Whis'); + expect(channelIterator.next()).toBe('LOOC'); + // BANDASTATION EDIT ADDITION END expect(channelIterator.next()).toBe('OOC'); expect(channelIterator.next()).toBe('Say'); // Admin is blacklisted so it should be skipped }); diff --git a/tgui/packages/tgui-say/ChannelIterator.ts b/tgui/packages/tgui-say/ChannelIterator.ts index 136806927e95e..7515f95adc74c 100644 --- a/tgui/packages/tgui-say/ChannelIterator.ts +++ b/tgui/packages/tgui-say/ChannelIterator.ts @@ -1,4 +1,13 @@ -export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin'; +export type Channel = + | 'Say' + | 'Radio' + | 'Me' + // BANDASTATION EDIT START + | 'Whis' + | 'LOOC' + // BANDASTATION EDIT END + | 'OOC' + | 'Admin'; /** * ### ChannelIterator @@ -8,9 +17,19 @@ export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin'; */ export class ChannelIterator { private index: number = 0; - private readonly channels: Channel[] = ['Say', 'Radio', 'Me', 'OOC', 'Admin']; + private readonly channels: Channel[] = [ + 'Say', + 'Radio', + 'Me', + // BANDASTATION EDIT START + 'Whis', + 'LOOC', + // BANDASTATION EDIT END + 'OOC', + 'Admin', + ]; private readonly blacklist: Channel[] = ['Admin']; - private readonly quiet: Channel[] = ['OOC', 'Admin']; + private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin']; // BANDASTATION EDIT public next(): Channel { if (this.blacklist.includes(this.channels[this.index])) { diff --git a/tgui/packages/tgui-say/styles/colors.scss b/tgui/packages/tgui-say/styles/colors.scss index 475d8b25b26ef..b202ef1d858a4 100644 --- a/tgui/packages/tgui-say/styles/colors.scss +++ b/tgui/packages/tgui-say/styles/colors.scss @@ -14,6 +14,8 @@ $_channel_map: ( 'Engi': #f37746, 'Hive': #855d85, 'io': #1e90ff, + // BANDASTATION EDIT ADDITION + 'LOOC': #ffceb6, 'Me': #5975da, 'Med': #57b8f0, 'OOC': #cca300, @@ -24,6 +26,8 @@ $_channel_map: ( 'Supp': #b88646, 'Svc': #6ca729, 'Synd': #8f4a4b, + // BANDASTATION EDIT ADDITION + 'Whis': #7c7fd9, ); $channel_keys: map.keys($_channel_map) !default; diff --git a/tgui/packages/tgui/interfaces/EmotePanel.tsx b/tgui/packages/tgui/interfaces/EmotePanel.tsx new file mode 100644 index 0000000000000..b5c8f0a41962e --- /dev/null +++ b/tgui/packages/tgui/interfaces/EmotePanel.tsx @@ -0,0 +1,94 @@ +import { useBackend, useSharedState } from '../backend'; +import { Window } from '../layouts'; +import { Button, Section, Stack } from '../components'; +import { SearchBar } from './Fabrication/SearchBar'; +import { BooleanLike } from '../../common/react'; + +type Emote = { + key: string; + emote_path: string; + hands: BooleanLike; + visible: BooleanLike; + audible: BooleanLike; + sound: BooleanLike; +}; + +type EmotePanelData = { + emotes: Emote[]; +}; + +export const EmotePanelContent = (props, context) => { + const { act, data } = useBackend(context); + const { emotes } = data; + + const [searchText, setSearchText] = useSharedState( + context, + 'search_text', + '' + ); + + return ( +
0 + ? `Результаты поиска "${searchText}"` + : `Все эмоции` + } + fill> + + +
+ +
+
+ + {emotes.map((emote) => + emote.key ? ( + searchText.length > 0 ? ( + emote.key.toLowerCase().includes(searchText.toLowerCase()) ? ( + + ) : ( + '' + ) + ) : ( + + ) + ) : ( + '' + ) + )} + +
+
+ ); +}; + +export const EmotePanel = (props, context) => { + return ( + + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/ExaminePanel.js b/tgui/packages/tgui/interfaces/ExaminePanel.js new file mode 100644 index 0000000000000..afabfeccd5607 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ExaminePanel.js @@ -0,0 +1,44 @@ +import { useBackend } from '../backend'; +import { Stack, Section, ByondUi } from '../components'; +import { Window } from '../layouts'; + +export const ExaminePanel = (props, context) => { + const { act, data } = useBackend(context); + const { character_name, obscured, assigned_map, flavor_text } = data; + return ( + + + + +
+ {!obscured && ( + + )} +
+
+ + + +
+ {flavor_text} +
+
+
+
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx index 1b76d2c7a1c5d..c4599fd02a1e8 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx @@ -9,6 +9,7 @@ import { JobsPage } from './JobsPage'; import { MainPage } from './MainPage'; import { SpeciesPage } from './SpeciesPage'; import { QuirksPage } from './QuirksPage'; +import { VoicePage } from './VoicePage'; // BANDASTATION EDIT ADD - TTS enum Page { Antags, @@ -16,6 +17,8 @@ enum Page { Jobs, Species, Quirks, + // BANDASTATION EDIT ADD - TTS + Voice, } const CharacterProfiles = (props: { @@ -76,6 +79,10 @@ export const CharacterPreferenceWindow = (props, context) => { case Page.Quirks: pageContents = ; break; + // BANDASTATION EDIT ADD - TTS + case Page.Voice: + pageContents = ; + break; default: exhaustiveCheck(currentPage); } @@ -146,6 +153,17 @@ export const CharacterPreferenceWindow = (props, context) => { Quirks + + {Boolean(data.tts_enabled) && ( // BANDASTATION EDIT - TTS + + + Voice + + + )} diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/VoicePage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/VoicePage.tsx new file mode 100644 index 0000000000000..29b86e4bd6a6f --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/VoicePage.tsx @@ -0,0 +1,275 @@ +import { useBackend, useLocalState } from '../../backend'; +import { Button, LabeledList, Table, Section, Dropdown, Input, BlockQuote, Box, Icon } from '../../components'; +import { PreferencesMenuData } from './data'; + +const donatorTiers = { + 0: 'Бесплатные', + 1: 'Tier I', + 2: 'Tier II', + 3: 'Tier III', + 4: 'Tier IV', +}; + +const gendersIcons = { + 'Мужской': { + icon: 'mars', + color: 'blue', + }, + 'Женский': { + icon: 'venus', + color: 'purple', + }, + 'Любой': { + icon: 'venus-mars', + color: 'white', + }, +}; + +const getCheckboxGroup = ( + itemsList, + selectedList, + setSelected, + contentKey: string | null = null +) => { + return itemsList.map((item) => { + const title = (contentKey && item[contentKey]) ?? item; + return ( + { + if (selectedList.includes(item)) { + setSelected( + selectedList.filter( + (i) => ((contentKey && i[contentKey]) ?? i) !== item + ) + ); + } else { + setSelected([item, ...selectedList]); + } + }} + /> + ); + }); +}; + +export const VoicePage = (props, context) => { + const { act, data } = useBackend(context); + + const { + providers, + seeds, + phrases, + character_preferences: { + misc: { tts_seed }, + }, + } = data; + + const donator_level = 5; + + const categories = seeds + .map((seed) => seed.category) + .filter((category, i, a) => a.indexOf(category) === i); + const genders = seeds + .map((seed) => seed.gender) + .filter((gender, i, a) => a.indexOf(gender) === i); + const donatorLevels = seeds + .map((seed) => seed.donator_level) + .filter((level, i, a) => a.indexOf(level) === i) + .map((level) => donatorTiers[level]); + + const [selectedProviders, setSelectedProviders] = useLocalState( + context, + 'selectedProviders', + providers + ); + const [selectedGenders, setSelectedGenders] = useLocalState( + context, + 'selectedGenders', + genders + ); + const [selectedCategories, setSelectedCategories] = useLocalState( + context, + 'selectedCategories', + categories + ); + const [selectedDonatorLevels, setSelectedDonatorLevels] = useLocalState( + context, + 'selectedDonatorLevels', + donatorLevels + ); + const [selectedPhrase, setSelectedPhrase] = useLocalState( + context, + 'selectedPhrase', + phrases[0] + ); + const [searchtext, setSearchtext] = useLocalState(context, 'searchtext', ''); + + let providerCheckboxes = getCheckboxGroup( + providers, + selectedProviders, + setSelectedProviders, + 'name' + ); + let genderesCheckboxes = getCheckboxGroup( + genders, + selectedGenders, + setSelectedGenders + ); + let categoriesCheckboxes = getCheckboxGroup( + categories, + selectedCategories, + setSelectedCategories + ); + let donatorLevelsCheckboxes = getCheckboxGroup( + donatorLevels, + selectedDonatorLevels, + setSelectedDonatorLevels + ); + + let phrasesSelect = ( + setSelectedPhrase(value)} + /> + ); + + let searchBar = ( + setSearchtext(value)} + /> + ); + + const availableSeeds = seeds + .sort((a, b) => { + const aname = a.name.toLowerCase(); + const bname = b.name.toLowerCase(); + if (aname > bname) { + return 1; + } + if (aname < bname) { + return -1; + } + return 0; + }) + .filter( + (seed) => + selectedProviders.some((provider) => provider.name === seed.provider) && + selectedGenders.includes(seed.gender) && + selectedCategories.includes(seed.category) && + selectedDonatorLevels.includes(donatorTiers[seed.donator_level]) && + seed.name.toLowerCase().includes(searchtext.toLowerCase()) + ); + + let seedsRow = availableSeeds.map((seed) => { + return ( + + +