diff --git a/.github/nativefuncs.json b/.github/nativefuncs.json index 889432d73..110429031 100644 --- a/.github/nativefuncs.json +++ b/.github/nativefuncs.json @@ -18,6 +18,12 @@ "returnTypeString":"void", "argTypes":"string modName, bool enabled" }, + { + "name":"NSIsModRemote", + "helpText":"", + "returnTypeString":"bool", + "argTypes":"string modName" + }, { "name":"NSGetModDescriptionByModName", "helpText":"", @@ -266,6 +272,12 @@ "returnTypeString":"void", "argTypes":"string modName, bool enabled" }, + { + "name":"NSIsModRemote", + "helpText":"", + "returnTypeString":"bool", + "argTypes":"string modName" + }, { "name":"NSGetModDescriptionByModName", "helpText":"", @@ -466,6 +478,12 @@ "returnTypeString":"void", "argTypes":"string modName, bool enabled" }, + { + "name":"NSIsModRemote", + "helpText":"", + "returnTypeString":"bool", + "argTypes":"string modName" + }, { "name":"NSGetModDescriptionByModName", "helpText":"", diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8cda06a32..e4dd3515d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -16,3 +16,11 @@ Note that commit messages in PRs will generally be squashed to keep commit histo --> Replace this line with a description of your change (and screenshots/screenrecordings if applicable). + +### Code review: + +Replace this line with anything specific to look out for during code reviews. + +### Testing: + +Replace this line with instructions on how to test your pull request. The more detailed, the easier it is for reviewers to test, the faster your PR gets merged. diff --git a/.github/workflows/compile-check.yml b/.github/workflows/compile-check.yml index cb7ab1d08..8803f4f4c 100644 --- a/.github/workflows/compile-check.yml +++ b/.github/workflows/compile-check.yml @@ -8,7 +8,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: "mods" diff --git a/.github/workflows/encoding.yml b/.github/workflows/encoding.yml index 5a730c203..b1d851a14 100644 --- a/.github/workflows/encoding.yml +++ b/.github/workflows/encoding.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Check localization files encoding run: | files=$(ls Northstar.Client/mod/resource/northstar_client_localisation_*.txt) @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Look out for missing translations run: node .github/build/find-missing-translations.js continue-on-error: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..64b8c0c3c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Contributing +> NOTE: This is the first iteration of this file. You're welcome to pull request changes + +### Contents +- [Making issues](#Making-issues) +- [Making pull requests](#Making-pull-requests) +- [Formatting code](#Formatting-code) + +## Making issues +When creating issues, whether to track a bug or suggest a feature, please try to follow this set of rules: +1. When filing a bug report issue, please attach a log file ( Located in `R2Northstar/logs/` ). +2. **Short, consise.** No-one wants to read an essay on why x should be added. +3. When applicable attach a short video / screen shots to better convey what the issue is about. + +## Making pull requests +When creating a pull request please follow this set of rules: +1. **1 Fix/Feature should equal to 1 Pull Request.** The more you do in 1 PR the longer it'll take to merge. +2. Mark your Pull Request as draft if it isnt finished just yet. +3. Properly format your code. As we currently don't have a formatter we're very lax on this. That doesn't mean you don't have to try to format your code. +4. **Mention how to test your changes / add a test mod to make it easier to test** + +## Formatting code +A basic set of rules you should follow when creating a Pull Request + +### Comment your code +- If you're adding a new file you should add a doc comment noting what the file does and its origin + ```cpp + ///----------------------------------------------------------------------------- + /// Origin: Northstar + /// Purpose: handles server-side rui + ///----------------------------------------------------------------------------- + ``` + Alternative to `Origin: Northstar` would be `Origin: Respawn` +- Each function should have a header doc comment + ```cpp + ///----------------------------------------------------------------------------- + /// Sends a string message to player + /// Returns true if it succeeded + ///----------------------------------------------------------------------------- + bool function NSSendInfoMessageToPlayer( entity player, string text ) + ``` +### Functions +- Functions should have spaces in the parentheses + ```cpp + bool function NSSendInfoMessageToPlayer( entity player, string text ) + ``` +- If a function need to be threaded off using `thread` it should have a `_Threaded` suffix + +### File +- Files should use tabs for indentation diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_german.txt b/Northstar.Client/mod/resource/northstar_client_localisation_german.txt index 996a3e2ba..7951fe35b 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_german.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_german.txt @@ -320,7 +320,7 @@ Drücke Ja, um zuzustimmen. Du kannst diese Entscheidung jederzeit im Modmenü "SHOW_ONLY_NOT_REQUIRED" "Nur optionale Mods" "SHOW_ONLY_REQUIRED" "Nur notwendige Mods" "PROGRESSION_TOGGLE_DISABLED_HEADER" "Fortschritt aktivieren?" - "TOGGLE_PROGRESSION" "Fortschritt zuschalten" + "TOGGLE_PROGRESSION" "Fortschritt umschalten" "PROGRESSION_TOGGLE_ENABLED_HEADER" "Fortschritt deaktivieren?" "PROGRESSION_TOGGLE_ENABLED_BODY" "Titans, Waffen, Fraktionen, Skins, usw werden freigeschaltet und sind zu jeder Zeit verfügbar .\n\nDies kann in der Mehrspielerlobby zu jedem Zeitpunkt geändert werden." "MATCH_COUNTDOWN_LENGTH" "Countdown für privates Match" @@ -357,7 +357,7 @@ Drücke Ja, um zuzustimmen. Du kannst diese Entscheidung jederzeit im Modmenü "PROGRESSION_DISABLED_HEADER" "Fortschritt deaktiviert!" "WILL_RESET_ALL_SETTINGS" "Dadurch werden ALLE Einstellungen, die zu dieser Kategorie gehören, zurückgesetzt.\n\nDies kann nicht rückgängig gemacht werden." "WILL_RESET_SETTING" "Dies setzten die Einstellungen %s1 auf deren Ursprungeswert zurück.\n\nDies kann nicht rückgängig gemacht werden." - "Y_BUTTON_TOGGLE_PROGRESSION" "%[Y_BUTTON|]% Fortschritt zuschalten." + "Y_BUTTON_TOGGLE_PROGRESSION" "%[Y_BUTTON|]% Fortschritt umschalten" "PROGRESSION_TOGGLE_DISABLED_BODY" "Titans, Waffen, Fraktionen, Skins usw. müssen durch Levelaufstieg freigeschaltet oder mit Verdiensten gekauft werden.\n\nDies kann jederzeit in der Mehrspieler-Lobby geändert werden.\n\n^CC000000Warnung: Wenn Sie derzeit ausgerüstete Gegenstände besitzen, die Sie nicht freigeschaltet haben, werden diese zurückgesetzt!" "PROGRESSION_ENABLED_BODY" "^CCCC0000Fortschritt wurde aktiviert.^\n\nTitans, Waffen, Fraktionen, Skins usw. müssen durch Levelaufstieg freigeschaltet oder mit Verdiensten gekauft werden.\n\nDies kann jederzeit in der Mehrspieler-Lobby geändert werden." "PROGRESSION_DISABLED_BODY" "^CCCC0000Fortschritt wurde deaktiviert.^\n\nTitans, Waffen, Fraktionen, Skins usw. werden alle freigeschaltet und jederzeit nutzbar sein.\n\nDies kann jederzeit in der Mehrspieler-Lobby geändert werden." diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt index 38e67dea4..089edf35b 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt @@ -316,7 +316,7 @@ Premi Sì se sei d'accordo. Questa scelta può essere modificata in qualsiasi mo "UNAUTHORIZED_PWD" "Password errata" "STRYDER_RESPONSE" "Non è stato possibile analizzare la risposta di Stryder" "PLAYER_NOT_FOUND" "Non è stato trovato l'account player" - "INVALID_MASTERSERVER_TOKEN" "Token Masterserver invalido o scaduto" + "INVALID_MASTERSERVER_TOKEN" "Token Masterserver invalido o scaduto, prova a riavviare l'App EA" "JSON_PARSE_ERROR" "Errore nell'analisi della risposta json" "UNSUPPORTED_VERSION" "La versione che stai usando non è più supportata" @@ -380,5 +380,42 @@ Premi Sì se sei d'accordo. Questa scelta può essere modificata in qualsiasi mo "sns_wme_kill_value" "Valore per uccisione Wingman d'Elite" "sns_reset_kill_value" "Valore per uccisione Lama Impulsi/Esecuzione" "PL_tffa_desc" "Ogni pilota per sè, distruggi tutti i titan nemici." + "player_force_respawn" "Respawn Forzato" + "PROGRESSION_TOGGLE_DISABLED_HEADER" "Attivare Progressione?" + "TOGGLE_PROGRESSION" "Attiva/Disattiva Progressione" + "Y_BUTTON_TOGGLE_PROGRESSION" "%[Y_BUTTON|]% Attiva/Disattiva Progressione" + "PROGRESSION_TOGGLE_ENABLED_HEADER" "Disattivare la Progressione?" + "AUTHENTICATION_FAILED_BODY" "Fallimento nell'autenticare con Atlas" + "AUTHENTICATION_FAILED_ERROR_CODE" "Codice di errore: ^DB6F2C00%s1^" + "AUTHENTICATION_FAILED_HELP" "Aiuto" + "AUTHENTICATION_FAILED_HEADER" "Autenticazione Fallita" + "MISSING_MOD" "Mod mancante \"%s1\" v%s2" + "MOD_NOT_VERIFIED" "(Mod non verificata, non è stato possibile il download automatico)" + "MOD_DL_DISABLED" "(Il download automatico delle mod è disabilitato)" + "DOWNLOADING_MOD_TEXT" "Download %s1 v%s2..." + "CHECKSUMING_TEXT" "Verifica contenuti %s1 v%s2..." + "EXTRACTING_MOD_TITLE" "Estrazione mod (%s1%)" + "FAILED_DOWNLOADING" "Download della mod fallito" + "NO_DISK_SPACE_AVAILABLE" "Non c'è abbastanza spazio sul disco." + "MOD_FETCHING_FAILED_GENERAL" "Estrazione mod fallita. Controlla i file di log per più dettagli." + "DOWNLOADING_MOD_TITLE" "Download mod in corso" + "DOWNLOADING_MOD_TITLE_W_PROGRESS" "Download in corso della mod (%s1%)" + "FAILED_READING_ARCHIVE" "C'è stato un errore durante la lettura dell'archivio della mod." + "FAILED_WRITING_TO_DISK" "C'è stato un errore durante l'estrazione della mod al filesystem." + "MOD_FETCHING_FAILED" "Impossibile scaricare l'archivio mod da Thunderstore." + "MOD_CORRUPTED" "La firma dell'archivio scaricato non corrisponde con quella verificata." + "DOWNLOADING_MOD_TEXT_W_PROGRESS" "Download %s1 v%s2...\n(%s3/%s4 MB)" + "EXTRACTING_MOD_TEXT" "Estraendo %s1 v%s2...\n(%s3/%s4 MB)" + "MOD_REQUIRED_WARNING" " : Questa mod potrebbe venire (non)caricata entrando in un server" + "PROGRESSION_ENABLED_HEADER" "Progressione Attivata!" + "PROGRESSION_ENABLED_BODY" "^CCCC0000La progessione è stata abilitata.^\n\nTitan, Armi, Fazioni, Skin, etc. dovranno essere sbloccate livellando, o comprate con i Meriti.\n\nQuesto può essere cambiato in qualsiasi momento nella lobby multigiocatore." + "PROGRESSION_DISABLED_HEADER" "Progressione Disabilitata!" + "PROGRESSION_DISABLED_BODY" "^CCCC0000La progressione è stata disabilitata.^\n\nTitan, Armi, Fazioni, Skin, etc. saranno sbloccate e utilizzabili in qualsiasi momento.\n\nQuesto può essere cambiato in qualsiasi momento nella lobby multigiocatore." + "WRONG_MOD_VERSION" "Il server ha la mod \"%s1\" v%s2 mentre tu hai v%s3" + "MANIFESTO_FETCHING_TITLE" "Iniziando download mod" + "MANIFESTO_FETCHING_TEXT" "Recuperando lista delle mod verificate..." + "PROGRESSION_TOGGLE_ENABLED_BODY" "Titan, Armi, Fazioni, Skin, etc. saranno tutti sbloccati e utilizzabili in ogni momento.\n\nQuesto può essere cambiato in qualsiasi momento nella lobby Multigiocatore." + "PROGRESSION_TOGGLE_DISABLED_BODY" "Titan, Armi, Factions, Skin, etc. avranno bisogno di essere sbloccate livellando, o comprate con i Meriti.\n\nQuesto può essere cambiato in ogni momento nella lobby Multiplayer.\n\n^CC000000Attenzione: se al momento hai equipaggiato degli item che non hai sbloccato, verranno resettati!" + "PROGRESSION_ANNOUNCEMENT_BODY" "^CCCC0000La progressione può essere abilitata ora!^\n\nNorthstar ora supporta la progressione vanilla, ciò significa che puoi scegliere di sbloccare Armi, Skin, Titan, etc. attraverso i livelli e le sfide.\n\nPuoi abilitare la progressione cliccando il pulsante in basso nella schermata lobby.\n\nQuesto può essere cambiato in qualsiasi momento." } } diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_polish.txt b/Northstar.Client/mod/resource/northstar_client_localisation_polish.txt new file mode 100644 index 000000000..9b570cebe --- /dev/null +++ b/Northstar.Client/mod/resource/northstar_client_localisation_polish.txt @@ -0,0 +1,394 @@ +"lang" +{ + "Language" "polish" + "Tokens" + { + // This file needs to be encoded as UTF-16 LE + + "MENU_LAUNCH_NORTHSTAR" "Uruchom Northstar" + "MENU_TITLE_MODS" "Mody" + "RELOAD_MODS" "Przeładuj Mody" + "WARNING" "Ostrzeżenie" + "CORE_MOD_DISABLE_WARNING" "Wyłączenie kluczowych Modów może zepsuć Northstar!" + "DISABLE" "Wyłącz" + + "DIALOG_TITLE_INSTALLED_NORTHSTAR" "Dzięki za instalację Northstar!" + "AUTHENTICATION_AGREEMENT_DIALOG_TEXT" "Dla poprawnego działania Northstar potrzebne jest uwierzytelnienie z głównym serwerem. Potrzebne będzie wysłanie twojego tokena Origin do głównego serwera, nie będzie on przechowywany ani użyty do żadnych innych celów. +Naciśnij Tak jeżeli wyrażasz zgodę. Wybór może zostać zmieniony w menu Modów." + "BACK_AUTHENTICATION_AGREEMENT" "Zgoda na uwierzytelnianie" + "AUTHENTICATION_AGREEMENT" "Zgoda na uwierzytelnianie" + "AUTHENTICATION_AGREEMENT_RESTART" "Potrzebne jest ponowne odpalenie Titanfall 2 by zmiany dały efekt." + + "DIALOG_AUTHENTICATING_MASTERSERVER" "Uwierzytelnianie z głównym serwerem." + "AUTHENTICATIONAGREEMENT_NO" "Zdecydowałeś się nie uwierzytelniać się z Northstar. Zgodę można wyrazić w menu z modami." + + "MENU_TITLE_SERVER_BROWSER" "Wyszukiwarka serwerów" + "NS_SERVERBROWSER_NOSERVERS" "Nie znaleziono serwerów" + "NS_SERVERBROWSER_UNKNOWNMODE" "Nieznany tryb" + "NS_SERVERBROWSER_WAITINGFORSERVERS" "Oczekiwanie na serwery..." + "NS_SERVERBROWSER_CONNECTIONFAILED" "Połączenie nieudane!" + "REFRESH_SERVERS" "Odśwież" + + "MENU_TITLE_CONNECT_PASSWORD" "Dołącz z hasłem" + "MENU_CONNECT_MENU_CONNECT" "Dołącz" + + "PRIVATE_MATCH_PAGE_PREV" "Poprzednia strona" + "PRIVATE_MATCH_PAGE_NEXT" "Następna strona" + + "MENU_MATCH_SETTINGS" "Ustawienia meczu" + "MENU_MATCH_SETTINGS_SUBMENU" "%s1 Ustawienia trybu" + + "PRIVATE_MATCH_SINGLEPLAYER_LEVEL" "%s1 (Tryb Jednoosobowy)" + + // fra hint for private match menu, because fra only has PL_fra_desc in vanilla + "PL_fra_hint" "Każdy na każdego. Zbierz 3 baterie, aby otrzymać Tytana." + + // mode settings + "MODE_SETTING_CATEGORY_PILOT" "Pilot" + "MODE_SETTING_CATEGORY_TITAN" "Tytan" + "MODE_SETTING_CATEGORY_RIFF" "Modyfikatory rozgrywki" + "MODE_SETTING_CATEGORY_MATCH" "Mecz" + + "classic_mp" "Klasyczny tryb wieloosobowy" + "run_epilogue" "Epilog" + "scorelimit" "Limit wyniku" + "roundscorelimit" "Limit wyniku (na rundę)" + "timelimit" "Limit Czasu" + "roundtimelimit" "Limit Czasu (na rundę)" + "respawnprotection" "Ochrona po odrodzeniu" + + "pilot_health_multiplier" "Mnożnik życia" + "respawn_delay" "Opóźnienie odrodzeń" + "boosts_enabled" "Wzmocnienia" + "earn_meter_pilot_overdrive" "Doładowanie wskaźnika Tytana/wzmocnienia" + "earn_meter_pilot_multiplier" "Mnożnik wsk. Tytana/wzm." + + "earn_meter_titan_multiplier" "Mnożnik wskaźnika rdzenia" + "aegis_upgrades" "POSTĘPY DOTYCZĄCE RANGI EGIDY" + "infinite_doomed_state" "Stan tytana spisany na straty jest nieskończony" + "titan_shield_regen" "Regeneracja tarczy Tytanów" + + "riff_floorislava" "Deadly ground" + "featured_mode_all_holopilot" "The Great Bamboozle" + "featured_mode_all_grapple" "Attack on Titanfall" + "featured_mode_all_phase" "The Otherside" + "featured_mode_all_ticks" "Spicy" + "featured_mode_tactikill" "Tactikill" + "featured_mode_amped_tacticals" "Amped Tacticals" + "featured_mode_rocket_arena" "Rocket Arena" + "featured_mode_shotguns_snipers" "Armed and Dangerous" + "iron_rules" "Iron Titan Rules" + + "cp_amped_capture_points" "Obrona umocnień" + "coliseum_loadouts_enabled" "Uzbrojenie Koloseum" + + "aitdm_archer_grunts" "Piechurzy z łucznikami" + + // northstar.custom localisation is just deciding not to work, so putting it here for now + "PL_sbox" "Piaskownica" + "PL_sbox_lobby" "Piaskownica Lobby" + "PL_sbox_desc" "jak gmod tylko gorsze" + "PL_sbox_abbr" "Piaskownica" + "GAMEMODE_SBOX" "Piaskownica" + + "PL_gg" "Gun Game" + "PL_gg_lobby" "Gun Game" + "PL_gg_desc" "Zdobądź zabójstwo każdą bronią by wygrać." + "PL_gg_hint" "Zdobądź zabójstwo każdą bronią by wygrać." + "PL_gg_abbr" "GG" + "GAMEMODE_GG" "Gun Game" + "gg_kill_reward" "Procentowa nagroda za zabójstwo" + "gg_assist_reward" "Procentowa nagroda za asystę" + "gg_execution_reward" "Procentowa nagroda za egzekucję" + + "PL_tt" "Titan Tag" + "PL_tt_lobby" "Titan Tag Lobby" + "PL_tt_desc" "Zdobywaj punkty będąc w Tytanie. Zniszcz Tytana by otrzymać własnego." + "PL_tt_hint" "Zdobywaj punkty będąc w Tytanie. Zniszcz Tytana by otrzymać własnego." + "PL_tt_abbr" "TT" + "GAMEMODE_TT" "Titan Tag" + + "PL_chamber" "One in the Chamber" + "PL_chamber_lobby" "One in the Chamber Lobby" + "PL_chamber_desc" "Jeden strzał, Jedno zabójstwo. Zdobądź kolejny pocisk w magazynku zabijając przeciwnika." + "PL_chamber_hint" "Jeden strzał, Jedno zabójstwo. Zdobądź kolejny pocisk w magazynku zabijając przeciwnika." + "PL_chamber_abbr" "CHAMBER" + "GAMEMODE_CHAMBER" "One in the Chamber Lobby" + + "PL_hidden" "The Hidden" + "PL_hidden_lobby" "The Hidden Lobby" + "PL_hidden_desc" "Jeden gracz jest niewidzialny i poluję na resztę." + "PL_hidden_hint" "Jeden gracz jest niewidzialny i poluję na resztę." + "PL_hidden_abbr" "HIDDEN" + "GAMEMODE_HIDDEN" "The Hidden" + "HIDDEN_YOU_ARE_HIDDEN" "Jesteś The Hidden!" + "HIDDEN_KILL_SURVIVORS" "Zabij wszystkich ocaleńców." + "HIDDEN_FIRST_HIDDEN" "%s1 jest The Hidden." + + "PL_sns" "Sticks and Stones" + "PL_sns_lobby" "Sticks and Stones Lobby" + "PL_sns_desc" "Każdy na każdego. Zabij przeciwnika ostrzem pulsacyjnym lub wykonaj egzekucję by zresetować jego wynik" + "PL_sns_abbr" "SNS" + "GAMEMODE_SNS" "Sticks and Stones" + "SCOREBOARD_BANKRUPTS" "Zabójstwa resetujące" + "SNS_LEADER_BANKRUPT" "Wynik Lidera został zresetowany!" + "SNS_LEADER_BANKRUPT_SUB" "Wynik %s1 został zresetowany przez %s2" + "SNS_BANKRUPT" "Reset!" + "SNS_BANKRUPT_SUB" "Twój wynik został zresetowany przez %s1" + "sns_wme_kill_value" "Wartość zabójstwa przy użyciu Elitarny skrzydłowy" + "sns_softball_kill_value" "Wartość zabójstwa przy użyciu Softball" + "sns_offhand_kill_value" "Wartość zabójstwa przy użyciu Offhand " + "sns_reset_kill_value" "Wartość zabójstwa przy użyciu Ostrza pulsacyjnego/egzekucji" + "sns_melee_kill_value" "Wartość zabójstwa wręcz" + "sns_reset_pulse_blade_cooldown_on_pulse_blade_kill" "Zabójstwa regenerują zdolność taktyczną - Ostrze pulsacyjne" + "sns_softball_enabled" "Softball Włączony" + + "PL_inf" "Infekcja" + "PL_inf_lobby" "Infekcja Lobby" + "PL_inf_desc" "Przeżyj zarazę. Ocaleńcy zostają zainfekowani gdy zabici." + "PL_inf_hint" "Przeżyj zarazę. Ocaleńcy zostają zainfekowani gdy zabici.." + "PL_inf_abbr" "INF" + "GAMEMODE_INF" "Infekcja" + "INFECTION_YOU_ARE_INFECTED" "Zostałeś zainfekowany!" + "INFECTION_KILL_SURVIVORS" "Zainfekuj pozostałych ocaleńców." + "INFECTION_FIRST_INFECTED" "%s1 jest pierwszym zainfekowanym." + "INFECTION_LAST_SURVIVOR" "%s1 jest ostatnim ocaleńcem!" + "INFECTION_KILL_LAST_SURVIVOR" "Zainfekuj ich przed końcem czasu!" + "INFECTION_YOU_ARE_LAST_SURVIVOR" "Jesteś ostatnim ocaleńcem!" + "INFECTION_SURVIVE_LAST_SURVIVOR" "Przeżyj..." + + "PL_tffa" "Każdy na każdego Tytany" + "PL_tffa_lobby" "Każdy na każdego Tytany" + "PL_tffa_desc" "Każdy na każdego, zniszcz tytany przeciwników." + "PL_tffa_hint" "Każdy na każdego, zniszcz tytany przeciwników." + "PL_tffa_abbr" "TFFA" + "GAMEMODE_TFFA" "Każdy na każdego Tytany" + + "PL_hs" "Chowany" + "PL_hs_lobby" "Chowany Lobby" + "PL_hs_desc" "Szukający szukają chowających się." + "PL_hs_hint" "Szukający szukają chowających się." + "PL_hs_abbr" "HS" + "GAMEMODE_hs" "Chowany" + "HIDEANDSEEK_YOU_ARE_SEEKER" "JESTEŚ SZUKAJĄCYM" + "HIDEANDSEEK_SEEKER_DESC" "Znajdź chowających się i przyłóż im wręcz.\nOdrodzisz się w %s1 sekund" + "HIDEANDSEEK_YOU_ARE_HIDER" "JESTEŚ CHOWAJĄCYM SIĘ" + "HIDEANDSEEK_HIDER_DESC" "Schowaj się." + "HIDEANDSEEK_SEEKERS_INCOMING" "Szukający nadchodzi" + "HIDEANDSEEK_DONT_GET_FOUND" "Nie daj się znaleźć!" + "HIDEANDSEEK_GET_LAST_HIDER" "%s1 JEST OSTATNIM CHOWAJĄCYM SIĘ" + "HIDEANDSEEK_YOU_ARE_LAST_HIDER" "JESTEŚ OSTATNIM CHOWAJĄCYM SIĘ" + "HIDEANDSEEK_GOT_STIM" "Masz Stymulant! Nie daj się złapać!" + "hideandseek_balance_teams" "Automatyczny balans Chowający się/Szukający" + "hideandseek_hiding_time" "Czas na ukrycie się dla Chowających się" + + // these are defined in r1_english but titan war is a shit name so i'm changing it to another one that was referenced in development + "GAMEMODE_fw" "Wojna Kresów" + "PL_fw" "Wojna Kresów" + "PL_fw_lobby" "Wojna Kresów Lobby" + "PL_fw_desc" "Zniszcz Zbieracz przeciwnika i ochroń swój" + "PL_fw_abbr" "FW" + + "GAMEMODE_kr" "Seria Zabójstw" + "PL_kr" "Seria Zabójstw" + "PL_kr_lobby" "Seria Zabójstw Lobby" + "PL_kr_desc" "Zabijaj przeciwników by ustanowić rekord serii i wygrać. Zbierz flagę by ją aktywować." + "PL_kr_hint" "Zabijaj przeciwników by ustanowić rekord serii i wygrać. Zbierz flagę by ją aktywować." + "PL_kr_abbr" "KR" + "SCOREBOARD_KR_RECORD" "Rekord Zabójstw" + "KR_NEW_RACER" "%s1 aktywował Serię" + "KR_YOU_ARE_NEW_RACER" "Aktywowałeś Serię" + "KR_YOU_SET_NEW_RECORD" "Ustaw nowy rekord zabójstw!" + "KR_FLAG_INCOMING" "Niedługo pojawi się flaga" + "KR_COLLECT_FLAG" "Zdobądź ją by aktywować Serię!" + "KR_ENEMY_KILLRACE_OVER" "Seria %s1 się skończyła" + "KR_YOUR_KILLRACE_OVER" "Twoja Seria się skończyła" + "KR_YOUR_KILLRACE_SCORE" "Zdobyłeś %s1 zabójstw." + + "GAMEMODE_fastball" "Fastball" + "PL_fastball" "Fastball" + "PL_fastball_lobby" "Fastball Lobby" + "PL_fastball_desc" "Śmierć pernamentna. Hackuj panele kotrolne by wygrywać rundy i odradzać swoich osoby z swojej drużyny." + "PL_fastball_hint" "Śmierć pernamentna. Hackuj panele kotrolne by wygrywać rundy i odradzać swoich osoby z swojej drużyny." + "PL_fastball_abbr" "FB" + "FASTBALL_PANEL_CAPTURED" "%s1 przęjeli panel %s2" + "SCOREBOARD_FASTBALL_HACKS" "Przejęte panele" + + "GAMEMODE_ctf_comp" "Kompetetywne - Walka o flagę" + + // mode settings + "MODE_SETTING_CATEGORY_PROMODE" "Tryb pro" + "MODE_SETTING_CATEGORY_BLEEDOUT" "Krwawienie Pilotów" + + "custom_air_accel_pilot" "Air Acceleration" + "no_pilot_collision" "Kolidowanie Pilotów" + "promode_enable" "Bronie trybu pro" + "fp_embark_enabled" "Pierwszoosobowe wsiadanie/egzekucje" + "classic_rodeo" "Klasyczne Rodeo" + "oob_timer_enabled" "Licznik czasu poza granicami mapy" + "riff_instagib" "Instagib Mode" + "player_force_respawn" "Wymuszone odrodzenie" + + "riff_player_bleedout" "Krwawienie Pilotów" + "player_bleedout_forceHolster" "Schowaj bronie gdy powalonym" + "player_bleedout_forceDeathOnTeamBleedout" "Umrzyj przy wykrawieniu się drużyny" + "player_bleedout_bleedoutTime" "Czas do wykrwawienia się" + "player_bleedout_firstAidTime" "Czas potrzebny do udzielenia pierwszej pomocy" + "player_bleedout_firstAidTimeSelf" "Czas potrzebny do samo-reanimacji" + "player_bleedout_firstAidHealPercent" "Procent życia po otrzymaniu pierwszej pomocy" + "player_bleedout_aiBleedingPlayerMissChance" "Szanasa na nietrafienie przez powalone SI" + + // coop stuff + "PL_sp_coop" "(NIE UKOŃCZONE) Kampania w trybie Kooperacji" + "PL_sp_coop_lobby" "Kampania w trybie Kooperacji Lobby" + "PL_sp_coop_desc" "Zagraj kampanie z przyjaciółmi" + "PL_sp_coop_hint" "Zagraj kampanie z przyjaciółmi" + "PL_sp_coop_abbr" "SP" + + "SP_TRAINING" "Tor przeszkód" + "SP_TRAINING_CLASSIC_DESC" "Symulacja kapitana Lastimosy." + + "SP_CRASHSITE" "BT-7274" + "SP_CRASHSITE_CLASSIC_DESC" "Jack Cooper spotyka BT-7274." + + "SP_SEWERS1" "Krew i rdza" + "SP_SEWERS1_CLASSIC_DESC" "Cooper i BT ruszają spotkać się z majorem Andersonem." + + "SP_BOOMTOWN_START" "W paszczę otchłani" + "SP_BOOMTOWN_START_CLASSIC_DESC" "Przeprawa podziemnym skrótem przynosi nieoczekiwane skutki." + + "SP_HUB_TIMESHIFT" "Skutek i przyczyna" + "SP_HUB_TIMESHIFT_CLASSIC_DESC" "W miejscu, w którym przebywa major Anderson zaobserwowano osobliwe zjawisko." + + "SP_BEACON" "Nadajnik" + "SP_BEACON_CLASSIC_DESC" "Cooper i BT podejmują próbę nawiązania kontaktu z pozostałymi siłami by przekazać im plany IMC." + + "SP_TDAY" "Próba ognia" + "SP_TDAY_CLASSIC_DESC" "Zdolności pilotażu Coopera zostają wystawione na próbę w ostatecznym starciu o Arkę." + + "SP_S2S" "Arka" + "SP_S2S_CLASSIC_DESC" "Cooper i BT ruszają statkiem w pościg za Arką." + + "SP_SKYWAY_V1" "Zakrzywiacz" + "SP_SKYWAY_V1_CLASSIC_DESC" "Cooper i BT zostają pojmani przez Kubena Bliska." + + // Better.Serverbrowser + "SERVERS_COLUMN" "Serwery" + "PLAYERS_COLUMN" "Gracze" + "MAP_COLUMN" "Mapa" + "GAMEMODE_COLUMN" "Tryb gry" + "REGION_COLUMN" "Region" + "SEARCHBAR_LABEL" "Wyszukiwanie:" + "MAP_FILTER" "Mapa" + "GAMEMODE_FILTER" "Tryb gry" + "HIDE_FULL_FILTER" "Ukryj Pełne Serwery" + "HIDE_EMPTY_FILTER" "Ukryj Puste Serwery" + "HIDE_PROT_FILTER" "Ukryj Chronione Hasłem Serwery" + "SERVER_DESCRIPTION" "Opis" + "SERVER_MODS" "Mody" + "CLEAR_FILTERS" "WYCZYŚĆ" + "JOIN_BUTTON" "DOŁĄCZ" + + "SWITCH_YES" "Tak" + "SWITCH_NO" "Nie" + "SWITCH_ANY" "Dowolnie" + + "CONNECTING" "Łączenie..." + "INGAME_PLAYERS" "Gracze: ^6BA6C400%s1" + "TOTAL_SERVERS" "Serwery: ^C46C6C00%s1" + + // Mods menu + "SHOW" "Pokaż" + "SHOW_ALL" "Wszystko" + "SHOW_ONLY_ENABLED" "Tylko Włączone" + "SHOW_ONLY_DISABLED" "Tylko Wyłączone" + "SHOW_ONLY_NOT_REQUIRED" "Tylko Mody Opcjonalne" + "SHOW_ONLY_REQUIRED" "Tylko Mody Wymagane" + "MOD_REQUIRED_WARNING" " : Ten mod może zostać wyłączony po dołączeniu na serwer" + + // Maps menu + "HIDE_LOCKED" "Ukryj zablokowane" + + // In-game chat + "HUD_CHAT_WHISPER_PREFIX" "[SZEPT]" + "HUD_CHAT_SERVER_PREFIX" "[SERWER]" + + "NO_GAMESERVER_RESPONSE" "Nie udało się osiągnąć serwera" + "BAD_GAMESERVER_RESPONSE" "Serwer dał nieprawidłową odpowiedź" + "UNAUTHORIZED_GAMESERVER" "Serwer nie ma autoryzacji by przedstawić takie zapytanie" + "UNAUTHORIZED_GAME" "Stryder nie może potwierdzić że to konto ma Titanfall 2" + "UNAUTHORIZED_PWD" "Nieprawidłowe hasło" + "STRYDER_RESPONSE" "Nieprawidłowa odpowiedź od Stryder" + "PLAYER_NOT_FOUND" "Nie udało się znaleźć konta gracza" + "INVALID_MASTERSERVER_TOKEN" "Token głównego serwera jest nieprawidłowy lub wygasł, spróbuj odpalić ponownie aplikację EA" + "JSON_PARSE_ERROR" "Wystąpił błąd przy sprawdzaniu pliku json" + "UNSUPPORTED_VERSION" "Wersja której używasz nie jest już wspierana" + + "AUTHENTICATION_FAILED_HEADER" "Uwierzytelnianie się nie powiodło" + "AUTHENTICATION_FAILED_BODY" "Uwierzytelnianie z Atlas się nie powiodło!" + "AUTHENTICATION_FAILED_ERROR_CODE" "Kod błędu: ^DB6F2C00%s1^" + "AUTHENTICATION_FAILED_HELP" "Pomoc" + + // Mod Settings + "MOD_SETTINGS" "Ustawienia Modów" + "NORTHSTAR_BASE_SETTINGS" "Główne ustawienia Northstar" + "ONLY_HOST_MATCH_SETTINGS" "Tylko Host może zmienić ustawienia meczu prywatnego" + "ONLY_HOST_CAN_START_MATCH" "Tylko Host może rozpocząć mecz" + "MATCH_COUNTDOWN_LENGTH" "Długość odliczana do rozpoczęcia meczu prywatnego" + "LOG_UNKNOWN_CLIENTCOMMANDS" "Loguj nieznane komendy klienta" + "DISALLOWED_TACTICALS" "Zabroniona umiejętność taktyczna" + "TACTICAL_REPLACEMENT" "Zastępująca umiejętność taktyczna" + "DISALLOWED_WEAPONS" "Zabroniona broń" + "REPLACEMENT_WEAPON" "Zastępująca broń" + "SHOULD_RETURN_TO_LOBBY" "Powróć do lobby po zakończeniu meczu" + "ARE_YOU_SURE" "Jesteś pewien?" + "WILL_RESET_ALL_SETTINGS" "Zresetujesz WSZYSTKIE ustawienia tej kategorii.\n\nAkcja jest nieodwracalna." + "WILL_RESET_SETTING" "Zresetujesz %s1 do startowej wartości.\n\nAkcja jest nieodwracalna." + "MOD_SETTINGS_SERVER" "Serwer" + "MOD_SETTINGS_RESET" "Zresetuj" + "MOD_SETTINGS_RESET_ALL" "Zresetuj WSZYSTKO" + "NO_RESULTS" "Brak rezultatu." + "NO_MODS" "Brak dostępnych ustawień, zainstaluj więcej modów w ^5588FF00northstar.thunderstore.io^0." + + // Toggleable progression + "TOGGLE_PROGRESSION" "Przełącz Progresję" + "Y_BUTTON_TOGGLE_PROGRESSION" "%[Y_BUTTON|]% Przełącz Progresję" + + "PROGRESSION_TOGGLE_ENABLED_HEADER" "Wyłączyć Progresję?" + "PROGRESSION_TOGGLE_ENABLED_BODY" "Tytany, Bronie, Fakcje, Skórki, itd. zostaną wszytskie odblokowane.\n\nDecyzję możesz zmienić kiedykolwiek w Lobby trybu wieloosobowego." + + "PROGRESSION_TOGGLE_DISABLED_HEADER" "Włączyć Progresję?" + "PROGRESSION_TOGGLE_DISABLED_BODY" "Tytany, Bronie, Fakcje, Skórki, itd. będą musiały być odblokowane poprzez zwiększanie swojego poziomu lub zakupione.\n\nDecyzję możesz zmienić kiedykolwiek w Lobby trybu wieloosobowego.\n\n^CC000000Ostrzeżenie: jeżeli masz wyekwipowane uzbrojenie której nie jest odblokowane zostenie ono zresetowane!" + + "PROGRESSION_ENABLED_HEADER" "Progresja została Włączona!" + "PROGRESSION_ENABLED_BODY" "^CCCC0000Progresja została Włączona.^\n\nTytany, Bronie, Fakcje, Skórki, itd. będą musiały być odblokowane poprzez zwiększanie swojego poziomu lub zakupione.\n\nDecyzję możesz zmienić kiedykolwiek w Lobby trybu wieloosobowego." + + "PROGRESSION_DISABLED_HEADER" "Progresja została Wyłączona!" + "PROGRESSION_DISABLED_BODY" "^CCCC0000Progresja została Wyłączona.^\n\nTytany, Bronie, Fakcje, Skórki, itd. zostaną wszytskie odblokowane.\n\nDecyzję możesz zmienić kiedykolwiek w Lobby trybu wieloosobowego." + + "PROGRESSION_ANNOUNCEMENT_BODY" "^CCCC0000Jest już możliwość włączenia Progresjii!^\n\nNorthstar teraz wspiera klasyczną Progresję, Dzięki niej możesz wybrać odblokowawanie Broni, Tytanów, Skórek, itd. poprzez zwiększanie swojego poziomu lub ukańczanie wyzwań.\n\nProgresja może zostać włączona poprzez przycisk na dole ekranu Lobby.\n\nDecyzję możesz zmienić kiedykolwiek." + + // Mod downloading + "MISSING_MOD" "Brakujący Mod \"%s1\" v%s2" + "WRONG_MOD_VERSION" "Serwer ma Moda \"%s1\" v%s2 podczas gdy ty masz v%s3" + "MOD_NOT_VERIFIED" "(Mod nie został zweryfikowany i nie mógł być pobrany automatycznie)" + "MOD_DL_DISABLED" "(Automatyczne pobieranie modów jest wyłączone)" + "MANIFESTO_FETCHING_TITLE" "Przygotowywanie do pobierania Moda" + "MANIFESTO_FETCHING_TEXT" "Zdobywanie listy zweryfikowanych modów..." + "DOWNLOADING_MOD_TITLE" "Pobieranie" + "DOWNLOADING_MOD_TITLE_W_PROGRESS" "Pobieranie (%s1%)" + "DOWNLOADING_MOD_TEXT" "Pobieranie %s1 v%s2..." + "DOWNLOADING_MOD_TEXT_W_PROGRESS" "Pobieranie %s1 v%s2...\n(%s3/%s4 MB)" + "CHECKSUMING_TITLE" "Sprawdzanie wartości kontrolnej Moda" + "CHECKSUMING_TEXT" "Weryfikowanie zawartości %s1 v%s2..." + "EXTRACTING_MOD_TITLE" "Rozpakowywanie Moda (%s1%)" + "EXTRACTING_MOD_TEXT" "Rozpakowywanie %s1 v%s2...\n(%s3/%s4 MB)" + "FAILED_DOWNLOADING" "Pobieranie Moda się nie powiodło" + "FAILED_READING_ARCHIVE" "Wystąpił błąd podczas czytania archiwum Moda." + "FAILED_WRITING_TO_DISK" "Wystąpił błąd podczas rozpakowywania Moda." + "MOD_FETCHING_FAILED" "Pobieranie archiwum Moda się nie powiodło." + "MOD_CORRUPTED" "Wartość kontrolna pobranego archiwum/moda nie zgadza się z zweryfikowaną wartośćią kontrolną." + "NO_DISK_SPACE_AVAILABLE" "Nie ma wystarczająco miejsca na dysku." + "MOD_FETCHING_FAILED_GENERAL" "Rozpakowywanie Moda się nie powiodło. Sprawdź Logi po więcej detali." + } +} diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt b/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt index 500f8a969..fd649cdb6 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_tchinese.txt @@ -320,7 +320,7 @@ "UNAUTHORIZED_PWD" "密碼錯誤" "STRYDER_RESPONSE" "無法讀取Stryder回應" "PLAYER_NOT_FOUND" "找不到玩家賬戶" - "INVALID_MASTERSERVER_TOKEN" "主伺服器token過期或無效" + "INVALID_MASTERSERVER_TOKEN" "主伺服器token過期或無效。" "JSON_PARSE_ERROR" "讀取json回應時發生錯誤" "UNSUPPORTED_VERSION" "您的遊戲版本過低" "NORTHSTAR_BASE_SETTINGS" "北极星基础设置" @@ -356,5 +356,31 @@ "PROGRESSION_DISABLED_BODY" "^CCCC0000個人進度已停用^\n\n泰坦,武器,陣營,皮膚及所有其他一切需要解鎖的物品將隨時可以進行解鎖並使用。\n\n您可以隨時在多人大廳中更改此項。" "PROGRESSION_ENABLED_BODY" "^CCCC0000個人進度已啟用^\n\n泰坦,武器, 陣營,皮膚以及其他一切需要解鎖的物品將通過升級或是使用點數購買來進行解鎖。.\n\n您可以隨時在多人大廳中更改此項。" "PROGRESSION_ANNOUNCEMENT_BODY" "^CCCC0000現在可以隨時開啟個人進度!^\n\nNorthstar 現在支持類似官服的進度系統, 这意味着你可以选择通过升级和完成挑战来解锁武器、皮肤、泰坦等。\n\n您可以通過多人大廳底部的“遊戲進度”按鈕來進行開啟。\n\n您可以隨時在多人大廳中更改此項。" + "AUTHENTICATION_FAILED_HEADER" "認證失敗" + "AUTHENTICATION_FAILED_BODY" "無法與Atlas驗證!" + "AUTHENTICATION_FAILED_ERROR_CODE" "錯誤代碼:^DB6F2C00%s1^" + "AUTHENTICATION_FAILED_HELP" "幫助" + "MISSING_MOD" "缺少Mod \"%s1\" v%s2" + "MOD_NOT_VERIFIED" "(Mod未經驗證并且無法自動下載)" + "MOD_REQUIRED_WARNING" " : 加入一個服務器時,這個Mod可能加載或不加載" + "DOWNLOADING_MOD_TEXT" "正在下載Mod %s1 %s2..." + "DOWNLOADING_MOD_TEXT_W_PROGRESS" "正在下載Mod %s1 %s2...\n(%s3/%s4 MB)" + "CHECKSUMING_TITLE" "正在校驗Mod" + "WRONG_MOD_VERSION" "服務器的 \"%s1\" Mod版本為 %s2 而你的版本是 %s3" + "MOD_DL_DISABLED" "(Mod自動下載已禁用)" + "DOWNLOADING_MOD_TITLE" "下載Mod中" + "DOWNLOADING_MOD_TITLE_W_PROGRESS" "下載Mod中(%s1%)" + "CHECKSUMING_TEXT" "驗證内容 %s1 %s2……" + "EXTRACTING_MOD_TITLE" "解壓Mod中 (%s1%)" + "EXTRACTING_MOD_TEXT" "解壓Mod中 %s1 %s2...\n(%s3/%s4 MB)" + "FAILED_DOWNLOADING" "下載Mod失敗" + "FAILED_READING_ARCHIVE" "在讀取Mod檔案時發生錯誤。" + "FAILED_WRITING_TO_DISK" "在解壓Mod文件到文件系統時發生錯誤。" + "MOD_FETCHING_FAILED" "從Thunderstore下載Mod檔案失敗。" + "MOD_CORRUPTED" "已下載檔案的校驗和無法與驗證簽名匹配。" + "NO_DISK_SPACE_AVAILABLE" "你的存儲設備沒有足夠空間。" + "MOD_FETCHING_FAILED_GENERAL" "Mod解壓失敗。在日志中查看更多詳情。" + "MANIFESTO_FETCHING_TITLE" "設置Mod下載" + "MANIFESTO_FETCHING_TEXT" "獲取已驗證Mod列表……" } } diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut index 3f643aa3d..f08d69a72 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut @@ -338,6 +338,10 @@ void function RefreshMods() { string mod = modNames[i] + // Do not display remote mods + if ( NSIsModRemote( mod ) ) + continue + if ( searchTerm.len() && mod.tolower().find( searchTerm ) == null ) continue diff --git a/Northstar.Custom/mod/scripts/vscripts/sh_damage_types.nut b/Northstar.Custom/mod/scripts/vscripts/sh_damage_types.nut index 4987ee015..bae0116ef 100644 --- a/Northstar.Custom/mod/scripts/vscripts/sh_damage_types.nut +++ b/Northstar.Custom/mod/scripts/vscripts/sh_damage_types.nut @@ -727,7 +727,7 @@ bool function RegisterWeaponDamageSourceInternal( int id, string newVal, string damageSourceID[ newVal ] <- id file.damageSourceIDToString[ id ] <- newVal file.damageSourceIDToName[ id ] <- stringVal - file.customDamageSourceIDList.extend( [ id.tostring(), newVal, StringReplace( stringVal, " ", MESSAGE_SPACE_PADDING ) ] ) + file.customDamageSourceIDList.extend( [ id.tostring(), newVal, StringReplace( stringVal, " ", MESSAGE_SPACE_PADDING, true ) ] ) return true } @@ -773,6 +773,6 @@ void function ReceiveNewDamageSourceIDs( array args ) { // IDs are inserted to the custom list in triplets, so we can trust these indices exist and the loop will end properly for ( int i = 0; i < args.len(); i += 3 ) - RegisterWeaponDamageSourceInternal( args[ i ].tointeger(), args[ i + 1 ], StringReplace( args[ i + 2 ], MESSAGE_SPACE_PADDING, " " ) ) + RegisterWeaponDamageSourceInternal( args[ i ].tointeger(), args[ i + 1 ], StringReplace( args[ i + 2 ], MESSAGE_SPACE_PADDING, " ", true ) ) } #endif diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut index 7d73c926f..cacb54cf1 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut @@ -435,9 +435,12 @@ void function SquadHandler( array guys ) // Setup AI, first assault point foreach ( guy in guys ) { - guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) - guy.AssaultPoint( point ) - guy.AssaultSetGoalRadius( 1600 ) // 1600 is minimum for npc_stalker, works fine for others + if ( IsAlive( guy ) ) + { + guy.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_HAND_SIGNALS | NPC_ALLOW_FLEE ) + guy.AssaultPoint( point ) + guy.AssaultSetGoalRadius( 1600 ) // 1600 is minimum for npc_stalker, works fine for others + } //thread AITdm_CleanupBoredNPCThread( guy ) } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut index 97addc241..85b80d744 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut @@ -1,5 +1,4 @@ untyped -// this needs a refactor lol global function CaptureTheFlag_Init global function RateSpawnpoints_CTF @@ -12,16 +11,31 @@ const array SWAP_FLAG_MAPS = [ struct { entity imcFlagSpawn entity imcFlag - entity imcFlagReturnTrigger entity militiaFlagSpawn entity militiaFlag - entity militiaFlagReturnTrigger array imcCaptureAssistList array militiaCaptureAssistList } file + + + + + + + + + +/* + ██████ █████ ██████ ████████ ██ ██ ██████ ███████ ████████ ██ ██ ███████ ███████ ██ █████ ██████ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +██ ███████ ██████ ██ ██ ██ ██████ █████ ██ ███████ █████ █████ ██ ███████ ██ ███ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ + ██████ ██ ██ ██ ██ ██████ ██ ██ ███████ ██ ██ ██ ███████ ██ ███████ ██ ██ ██████ +*/ + void function CaptureTheFlag_Init() { PrecacheModel( CTF_FLAG_MODEL ) @@ -30,30 +44,31 @@ void function CaptureTheFlag_Init() PrecacheParticleSystem( FLAG_FX_ENEMY ) CaptureTheFlagShared_Init() + SetSwitchSidesBased( true ) SetSuddenDeathBased( true ) + SetShouldUseRoundWinningKillReplay( true ) - SetRoundWinningKillReplayKillClasses( false, false ) // make these fully manual + SetRoundWinningKillReplayKillClasses( false, false ) AddCallback_OnClientConnected( CTFInitPlayer ) - + AddCallback_OnClientDisconnected( CTFPlayerDisconnected ) + AddCallback_GameStateEnter( eGameState.Prematch, CreateFlags ) AddCallback_GameStateEnter( eGameState.Epilogue, RemoveFlags ) + AddCallback_GameStateEnter( eGameState.Playing, OnPlaying ) + AddCallback_OnTouchHealthKit( "item_flag", OnFlagCollected ) + AddCallback_OnPlayerKilled( OnPlayerKilled ) AddCallback_OnPilotBecomesTitan( DropFlagForBecomingTitan ) - SetSpawnZoneRatingFunc( DecideSpawnZone_CTF ) AddSpawnpointValidationRule( VerifyCTFSpawnpoint ) - RegisterSignal( "FlagReturnEnded" ) RegisterSignal( "ResetDropTimeout" ) - // setup stuff for the functions in sh_gamemode_ctf - // don't really like using level for stuff but just how it be level.teamFlags <- {} - // setup score event earnmeter values ScoreEvent_SetEarnMeterValues( "KillPilot", 0.05, 0.20 ) ScoreEvent_SetEarnMeterValues( "Headshot", 0.0, 0.02 ) ScoreEvent_SetEarnMeterValues( "FirstStrike", 0.0, 0.05 ) @@ -67,54 +82,21 @@ void function CaptureTheFlag_Init() ScoreEvent_SetEarnMeterValues( "FlagReturn", 0.0, 0.20 ) } -void function RateSpawnpoints_CTF( int checkClass, array spawnpoints, int team, entity player ) -{ - RateSpawnpoints_SpawnZones( checkClass, spawnpoints, team, player ) -} -bool function VerifyCTFSpawnpoint( entity spawnpoint, int team ) -{ - // ensure spawnpoints aren't too close to enemy base - vector allyFlagSpot - vector enemyFlagSpot - foreach ( entity spawn in GetEntArrayByClass_Expensive( "info_spawnpoint_flag" ) ) - { - if( spawn.GetTeam() == team ) - allyFlagSpot = spawn.GetOrigin() - else - enemyFlagSpot = spawn.GetOrigin() - } - - if( Distance2D( spawnpoint.GetOrigin(), allyFlagSpot ) > Distance2D( spawnpoint.GetOrigin(), enemyFlagSpot ) ) - return false - - return true -} -void function CTFInitPlayer( entity player ) -{ - if ( !IsValid( file.imcFlagSpawn ) ) - return - - vector imcSpawn = file.imcFlagSpawn.GetOrigin() - Remote_CallFunction_NonReplay( player, "ServerCallback_SetFlagHomeOrigin", TEAM_IMC, imcSpawn.x, imcSpawn.y, imcSpawn.z ) - - vector militiaSpawn = file.militiaFlagSpawn.GetOrigin() - Remote_CallFunction_NonReplay( player, "ServerCallback_SetFlagHomeOrigin", TEAM_MILITIA, militiaSpawn.x, militiaSpawn.y, militiaSpawn.z ) -} -void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) -{ - if ( !IsValid( GetFlagForTeam( GetOtherTeam( victim.GetTeam() ) ) ) ) // getting a crash idk - return - if ( GetFlagForTeam( GetOtherTeam( victim.GetTeam() ) ).GetParent() == victim ) - { - if ( victim != attacker && attacker.IsPlayer() ) - AddPlayerScore( attacker, "FlagCarrierKill", victim ) - - DropFlag( victim ) - } -} + + + + + +/* +███████ ██████ █████ ██ ██ ███ ██ ██ ██████ ██████ ██ ██████ +██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ +███████ ██████ ███████ ██ █ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██ + ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +███████ ██ ██ ██ ███ ███ ██ ████ ███████ ██████ ██████ ██ ██████ +*/ void function CreateFlags() { @@ -122,25 +104,20 @@ void function CreateFlags() { file.imcFlagSpawn.Destroy() file.imcFlag.Destroy() - file.imcFlagReturnTrigger.Destroy() - + } + if ( IsValid( file.militiaFlagSpawn ) ) + { file.militiaFlagSpawn.Destroy() file.militiaFlag.Destroy() - file.militiaFlagReturnTrigger.Destroy() } foreach ( entity spawn in GetEntArrayByClass_Expensive( "info_spawnpoint_flag" ) ) { - // on some maps flags are on the opposite side from what they should be - // likely this is because respawn uses distance checks from spawns to check this in official - // but i don't like doing that so just using a list of maps to swap them on lol bool switchedSides = HasSwitchedSides() == 1 - - // i dont know why this works and whatever we had before didn't, but yeah + bool shouldSwap = switchedSides - if (!shouldSwap && SWAP_FLAG_MAPS.contains( GetMapName() )) + if ( !shouldSwap && SWAP_FLAG_MAPS.contains( GetMapName() ) ) shouldSwap = !shouldSwap - int flagTeam = spawn.GetTeam() if ( shouldSwap ) @@ -148,48 +125,33 @@ void function CreateFlags() flagTeam = GetOtherTeam( flagTeam ) SetTeam( spawn, flagTeam ) } - - // create flag base + entity base = CreatePropDynamic( CTF_FLAG_BASE_MODEL, spawn.GetOrigin(), spawn.GetAngles(), 0 ) SetTeam( base, spawn.GetTeam() ) svGlobal.flagSpawnPoints[ flagTeam ] = base - // create flag entity flag = CreateEntity( "item_flag" ) flag.SetValueForModelKey( CTF_FLAG_MODEL ) SetTeam( flag, flagTeam ) flag.MarkAsNonMovingAttachment() - flag.Minimap_AlwaysShow( TEAM_IMC, null ) // show flag icon on minimap + flag.Minimap_AlwaysShow( TEAM_IMC, null ) flag.Minimap_AlwaysShow( TEAM_MILITIA, null ) flag.Minimap_SetAlignUpright( true ) DispatchSpawn( flag ) flag.SetModel( CTF_FLAG_MODEL ) - flag.SetOrigin( spawn.GetOrigin() + < 0, 0, base.GetBoundingMaxs().z * 2 > ) // ensure flag doesn't spawn clipped into geometry + flag.SetOrigin( spawn.GetOrigin() + < 0, 0, base.GetBoundingMaxs().z * 2 > ) flag.SetVelocity( < 0, 0, 1 > ) flag.s.canTake <- true - flag.s.playersReturning <- [] level.teamFlags[ flag.GetTeam() ] <- flag - - entity returnTrigger = CreateEntity( "trigger_cylinder" ) - SetTeam( returnTrigger, flagTeam ) - returnTrigger.SetRadius( CTF_GetFlagReturnRadius() ) - returnTrigger.SetAboveHeight( CTF_GetFlagReturnRadius() ) - returnTrigger.SetBelowHeight( CTF_GetFlagReturnRadius() ) - - returnTrigger.SetEnterCallback( OnPlayerEntersFlagReturnTrigger ) - returnTrigger.SetLeaveCallback( OnPlayerExitsFlagReturnTrigger ) - DispatchSpawn( returnTrigger ) - - thread TrackFlagReturnTrigger( flag, returnTrigger ) + thread FlagProximityTracker( flag ) if ( flagTeam == TEAM_IMC ) { file.imcFlagSpawn = base file.imcFlag = flag - file.imcFlagReturnTrigger = returnTrigger SetGlobalNetEnt( "imcFlag", file.imcFlag ) SetGlobalNetEnt( "imcFlagHome", file.imcFlagSpawn ) @@ -198,76 +160,185 @@ void function CreateFlags() { file.militiaFlagSpawn = base file.militiaFlag = flag - file.militiaFlagReturnTrigger = returnTrigger SetGlobalNetEnt( "milFlag", file.militiaFlag ) SetGlobalNetEnt( "milFlagHome", file.militiaFlagSpawn ) } } - // reset the flag states, prevents issues where flag is home but doesnt think it's home when halftime goes SetFlagStateForTeam( TEAM_MILITIA, eFlagState.None ) SetFlagStateForTeam( TEAM_IMC, eFlagState.None ) - - foreach ( entity player in GetPlayerArray() ) - CTFInitPlayer( player ) } void function RemoveFlags() { - // destroy all the flag related things if ( IsValid( file.imcFlagSpawn ) ) { + PlayFX( $"P_phase_shift_main", file.imcFlagSpawn.GetOrigin() ) file.imcFlagSpawn.Destroy() file.imcFlag.Destroy() - file.imcFlagReturnTrigger.Destroy() } + if ( IsValid( file.militiaFlagSpawn ) ) { + PlayFX( $"P_phase_shift_main", file.militiaFlagSpawn.GetOrigin() ) file.militiaFlagSpawn.Destroy() file.militiaFlag.Destroy() - file.militiaFlagReturnTrigger.Destroy() } - - // unsure if this is needed, since the flags are destroyed? idk + SetFlagStateForTeam( TEAM_MILITIA, eFlagState.None ) SetFlagStateForTeam( TEAM_IMC, eFlagState.None ) } -void function TrackFlagReturnTrigger( entity flag, entity returnTrigger ) +void function RateSpawnpoints_CTF( int checkClass, array spawnpoints, int team, entity player ) { - // this is a bit of a hack, it seems parenting the return trigger to the flag actually sets the pickup radius of the flag to be the same as the trigger - // this isn't wanted since only pickups should use that additional radius - flag.EndSignal( "OnDestroy" ) + vector allyFlagSpot + vector enemyFlagSpot + foreach ( entity spawn in GetEntArrayByClass_Expensive( "info_spawnpoint_flag" ) ) + { + if( spawn.GetTeam() == team ) + allyFlagSpot = spawn.GetOrigin() + else + enemyFlagSpot = spawn.GetOrigin() + } + + foreach ( entity spawn in spawnpoints ) + { + float rating = 0.0 + float allyFlagDistance = Distance2D( spawn.GetOrigin(), allyFlagSpot ) + float enemyFlagDistance = Distance2D( spawn.GetOrigin(), enemyFlagSpot ) + + if( enemyFlagDistance > allyFlagDistance ) + { + rating += spawn.NearbyAllyScore( team, "ai" ) + rating += spawn.NearbyAllyScore( team, "titan" ) + rating += spawn.NearbyAllyScore( team, "pilot" ) + + rating += spawn.NearbyEnemyScore( team, "ai" ) + rating += spawn.NearbyEnemyScore( team, "titan" ) + rating += spawn.NearbyEnemyScore( team, "pilot" ) - while ( true ) + rating = rating / allyFlagDistance + } + + if ( spawn == player.p.lastSpawnPoint ) + rating += GetConVarFloat( "spawnpoint_last_spawn_rating" ) + + spawn.CalculateRating( checkClass, team, rating, rating * 0.25 ) + } +} + +bool function VerifyCTFSpawnpoint( entity spawnpoint, int team ) +{ + vector allyFlagSpot + vector enemyFlagSpot + foreach ( entity spawn in GetEntArrayByClass_Expensive( "info_spawnpoint_flag" ) ) { - returnTrigger.SetOrigin( flag.GetOrigin() ) - WaitFrame() + if( spawn.GetTeam() == team ) + allyFlagSpot = spawn.GetOrigin() + else + enemyFlagSpot = spawn.GetOrigin() } + + if( Distance2D( spawnpoint.GetOrigin(), allyFlagSpot ) > Distance2D( spawnpoint.GetOrigin(), enemyFlagSpot ) ) + return false + + return true } -void function SetFlagStateForTeam( int team, int state ) + + + + + + + + +/* +██████ ██ █████ ██ ██ ███████ ██████ ██ ██████ ██████ ██ ██████ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +██████ ██ ███████ ████ █████ ██████ ██ ██ ██ ██ ███ ██ ██ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +██ ███████ ██ ██ ██ ███████ ██ ██ ███████ ██████ ██████ ██ ██████ +*/ + +void function OnPlaying() { - if ( state == eFlagState.Away ) // we tell the client the flag is the player carrying it if they're carrying it - SetGlobalNetEnt( team == TEAM_IMC ? "imcFlag" : "milFlag", ( team == TEAM_IMC ? file.imcFlag : file.militiaFlag ).GetParent() ) - else - SetGlobalNetEnt( team == TEAM_IMC ? "imcFlag" : "milFlag", team == TEAM_IMC ? file.imcFlag : file.militiaFlag ) + foreach ( entity player in GetPlayerArray() ) + CTFInitPlayer( player ) +} - SetGlobalNetInt( team == TEAM_IMC ? "imcFlagState" : "milFlagState", state ) +void function CTFInitPlayer( entity player ) +{ + if ( !GamePlaying() ) + return + + if ( IsValid( file.imcFlagSpawn ) ) + { + vector imcSpawn = file.imcFlagSpawn.GetOrigin() + Remote_CallFunction_NonReplay( player, "ServerCallback_SetFlagHomeOrigin", TEAM_IMC, imcSpawn.x, imcSpawn.y, imcSpawn.z ) + } + + if ( IsValid( file.militiaFlagSpawn ) ) + { + vector militiaSpawn = file.militiaFlagSpawn.GetOrigin() + Remote_CallFunction_NonReplay( player, "ServerCallback_SetFlagHomeOrigin", TEAM_MILITIA, militiaSpawn.x, militiaSpawn.y, militiaSpawn.z ) + } +} + +void function CTFPlayerDisconnected( entity player ) +{ + // This has no validity checks on the player because the disconnection callback happens in the exact last frame the player entity still exists + if( !GamePlaying() ) + return + + if ( PlayerHasEnemyFlag( player ) ) + DropFlag( player, false ) +} + +void function OnPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( !IsValid( GetFlagForTeam( GetOtherTeam( victim.GetTeam() ) ) ) ) // getting a crash idk + return + + if ( PlayerHasEnemyFlag( victim ) ) + { + if ( victim != attacker && attacker.IsPlayer() ) + AddPlayerScore( attacker, "FlagCarrierKill", victim ) + + DropFlag( victim ) + } } + + + + + + + + + + +/* +███████ ██ █████ ██████ ██ ██████ ██████ ██ ██████ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +█████ ██ ███████ ██ ███ ██ ██ ██ ██ ███ ██ ██ +██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +██ ███████ ██ ██ ██████ ███████ ██████ ██████ ██ ██████ +*/ + bool function OnFlagCollected( entity player, entity flag ) { if ( !IsAlive( player ) || flag.GetParent() != null || player.IsTitan() || player.IsPhaseShifted() ) return false if ( player.GetTeam() != flag.GetTeam() && flag.s.canTake ) - GiveFlag( player, flag ) // pickup enemy flag + GiveFlag( player, flag ) else if ( player.GetTeam() == flag.GetTeam() && IsFlagHome( flag ) && PlayerHasEnemyFlag( player ) ) - CaptureFlag( player, GetFlagForTeam( GetOtherTeam( flag.GetTeam() ) ) ) // cap the flag + CaptureFlag( player, GetFlagForTeam( GetOtherTeam( flag.GetTeam() ) ) ) - return false // don't wanna delete the flag entity + return false // Don't delete the flag } void function GiveFlag( entity player, entity flag ) @@ -276,7 +347,8 @@ void function GiveFlag( entity player, entity flag ) flag.Signal( "ResetDropTimeout" ) flag.SetParent( player, "FLAG" ) - thread DropFlagIfPhased( player, flag ) + if ( GetCurrentPlaylistVarInt( "phase_shift_drop_flag", 0 ) == 1 ) + thread DropFlagIfPhased( player, flag ) // do notifications MessageToPlayer( player, eEventNotifications.YouHaveTheEnemyFlag ) @@ -294,103 +366,10 @@ void function GiveFlag( entity player, entity flag ) SetFlagStateForTeam( flag.GetTeam(), eFlagState.Away ) // used for held } -void function DropFlagIfPhased( entity player, entity flag ) -{ - player.EndSignal( "StartPhaseShift" ) - player.EndSignal( "OnDestroy" ) - - OnThreadEnd( function() : ( player ) - { - if (GetGameState() == eGameState.Playing || GetGameState() == eGameState.SuddenDeath) - DropFlag( player, true ) - }) - // the IsValid check is purely to prevent a crash due to a destroyed flag (epilogue) - while( IsValid(flag) && flag.GetParent() == player ) - WaitFrame() -} - -void function DropFlagForBecomingTitan( entity pilot, entity titan ) -{ - DropFlag( pilot, true ) -} - -void function DropFlag( entity player, bool realDrop = true ) -{ - entity flag = GetFlagForTeam( GetOtherTeam( player.GetTeam() ) ) - - if ( flag.GetParent() != player ) - return - - print( player + " dropped the flag!" ) - - flag.ClearParent() - flag.SetAngles( < 0, 0, 0 > ) - flag.SetVelocity( < 0, 0, 0 > ) - - if ( realDrop ) - { - // start drop timeout countdown - thread TrackFlagDropTimeout( flag ) - - // add to capture assists - if ( player.GetTeam() == TEAM_IMC ) - file.imcCaptureAssistList.append( player ) - else - file.militiaCaptureAssistList.append( player ) - - // do notifications - MessageToPlayer( player, eEventNotifications.YouDroppedTheEnemyFlag ) - EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_FlagDrop" ) - - MessageToTeam( player.GetTeam(), eEventNotifications.PlayerDroppedEnemyFlag, player, player ) - // todo need a sound here maybe - MessageToTeam( GetOtherTeam( player.GetTeam() ), eEventNotifications.PlayerDroppedFriendlyFlag, player, player ) - // todo need a sound here maybe - } - - SetFlagStateForTeam( flag.GetTeam(), eFlagState.Home ) // used for return prompt -} - -void function TrackFlagDropTimeout( entity flag ) -{ - flag.EndSignal( "ResetDropTimeout" ) - - wait CTF_GetDropTimeout() - - ResetFlag( flag ) -} - -void function ResetFlag( entity flag ) -{ - // prevents crash when flag is reset after it's been destroyed due to epilogue - if (!IsValid(flag)) - return - // ensure we can't pickup the flag after it's been dropped but before it's been reset - flag.s.canTake = false - - if ( flag.GetParent() != null ) - DropFlag( flag.GetParent(), false ) - - entity spawn - if ( flag.GetTeam() == TEAM_IMC ) - spawn = file.imcFlagSpawn - else - spawn = file.militiaFlagSpawn - - flag.SetOrigin( spawn.GetOrigin() + < 0, 0, spawn.GetBoundingMaxs().z + 1 > ) - - // we can take it again now - flag.s.canTake = true - - SetFlagStateForTeam( flag.GetTeam(), eFlagState.None ) // used for home - - flag.Signal( "ResetDropTimeout" ) -} - void function CaptureFlag( entity player, entity flag ) { // can only capture flags during normal play or sudden death - if (GetGameState() != eGameState.Playing && GetGameState() != eGameState.SuddenDeath) + if ( GetGameState() != eGameState.Playing && GetGameState() != eGameState.SuddenDeath ) { printt( player + " tried to capture the flag, but the game state was " + GetGameState() + " not " + eGameState.Playing + " or " + eGameState.SuddenDeath) return @@ -415,12 +394,15 @@ void function CaptureFlag( entity player, entity flag ) foreach( entity assistPlayer in assistList ) { - if ( player != assistPlayer ) - AddPlayerScore( assistPlayer, "FlagCaptureAssist", player ) - if( !HasPlayerCompletedMeritScore( assistPlayer ) ) + if ( IsValidPlayer( assistPlayer ) ) { - AddPlayerScore( assistPlayer, "ChallengeCTFCapAssist" ) - SetPlayerChallengeMeritScore( assistPlayer ) + if ( player != assistPlayer ) + AddPlayerScore( assistPlayer, "FlagCaptureAssist", player ) + if( !HasPlayerCompletedMeritScore( assistPlayer ) ) + { + AddPlayerScore( assistPlayer, "ChallengeCTFCapAssist" ) + SetPlayerChallengeMeritScore( assistPlayer ) + } } } @@ -431,10 +413,7 @@ void function CaptureFlag( entity player, entity flag ) EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_PlayerScore" ) if( !HasPlayerCompletedMeritScore( player ) ) - { - AddPlayerScore( player, "ChallengeCTFRetAssist" ) SetPlayerChallengeMeritScore( player ) - } MessageToTeam( team, eEventNotifications.PlayerCapturedEnemyFlag, player, player ) EmitSoundOnEntityToTeamExceptPlayer( flag, "UI_CTF_3P_TeamScore", player.GetTeam(), player ) @@ -442,84 +421,198 @@ void function CaptureFlag( entity player, entity flag ) MessageToTeam( GetOtherTeam( team ), eEventNotifications.PlayerCapturedFriendlyFlag, player, player ) EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_EnemyScores", flag.GetTeam() ) - if ( GameRules_GetTeamScore( team ) == GameMode_GetRoundScoreLimit( GAMETYPE ) - 1 ) + if ( GameRules_GetTeamScore( team ) == GetScoreLimit_FromPlaylist() - 1 ) { PlayFactionDialogueToTeam( "ctf_notifyWin1more", team ) PlayFactionDialogueToTeam( "ctf_notifyLose1more", GetOtherTeam( team ) ) + foreach( entity otherPlayer in GetPlayerArray() ) + Remote_CallFunction_NonReplay( otherPlayer, "ServerCallback_CTF_PlayMatchNearEndMusic" ) } } -void function OnPlayerEntersFlagReturnTrigger( entity trigger, entity player ) +void function DropFlag( entity player, bool realDrop = true ) { - entity flag - if ( trigger.GetTeam() == TEAM_IMC ) - flag = file.imcFlag - else - flag = file.militiaFlag - - if( !IsValid( flag ) || !IsValid( player ) ) - return + entity flag = GetFlagForTeam( GetOtherTeam( player.GetTeam() ) ) - if ( !player.IsPlayer() || player.IsTitan() || player.GetTeam() != flag.GetTeam() || IsFlagHome( flag ) || flag.GetParent() != null ) + if( !IsValid( flag ) || flag.GetParent() != player ) return - thread TryReturnFlag( player, flag ) + print( player + " dropped the flag!" ) + + flag.ClearParent() + flag.SetAngles( < 0, 0, 0 > ) + flag.SetVelocity( < 0, 0, 0 > ) + + if ( realDrop ) + { + if ( player.GetTeam() == TEAM_IMC && !file.imcCaptureAssistList.contains( player ) ) + file.imcCaptureAssistList.append( player ) + + else if( !file.militiaCaptureAssistList.contains( player ) ) + file.militiaCaptureAssistList.append( player ) + + MessageToPlayer( player, eEventNotifications.YouDroppedTheEnemyFlag ) + EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_FlagDrop" ) + + MessageToTeam( player.GetTeam(), eEventNotifications.PlayerDroppedEnemyFlag, player, player ) + MessageToTeam( GetOtherTeam( player.GetTeam() ), eEventNotifications.PlayerDroppedFriendlyFlag, player, player ) + } + + thread TrackFlagDropTimeout( flag ) + SetFlagStateForTeam( flag.GetTeam(), eFlagState.Home ) } -void function OnPlayerExitsFlagReturnTrigger( entity trigger, entity player ) +void function ResetFlag( entity flag ) { - entity flag - if ( trigger.GetTeam() == TEAM_IMC ) - flag = file.imcFlag + flag.s.canTake = false + + if ( flag.GetParent() != null ) + DropFlag( flag.GetParent(), false ) + + entity flagBase + if ( flag.GetTeam() == TEAM_IMC ) + flagBase = file.imcFlagSpawn else - flag = file.militiaFlag + flagBase = file.militiaFlagSpawn - if ( !player.IsPlayer() || player.IsTitan() || player.GetTeam() != flag.GetTeam() || IsFlagHome( flag ) || flag.GetParent() != null ) - return + flag.SetOrigin( flagBase.GetOrigin() + < 0, 0, flagBase.GetBoundingMaxs().z + 1 > ) + + flag.s.canTake = true + + SetFlagStateForTeam( flag.GetTeam(), eFlagState.None ) + + flag.Signal( "ResetDropTimeout" ) +} + +//----------------------------------------------------------------------------- +// Purpose: Check proximity for flag returns +// Input : flag - The flag entity +//----------------------------------------------------------------------------- +void function FlagProximityTracker( entity flag ) +{ + flag.EndSignal( "OnDestroy" ) - player.Signal( "FlagReturnEnded" ) -} + array < entity > playerInsidePerimeter + while( true ) + { + if( !playerInsidePerimeter.len() ) + ArrayRemoveDead( playerInsidePerimeter ) + + foreach ( player in GetPlayerArrayOfTeam_Alive( flag.GetTeam() ) ) + { + if ( Distance( player.GetOrigin(), flag.GetOrigin() ) < CTF_GetFlagReturnRadius() ) + { + if ( player.IsTitan() || player.GetTeam() != flag.GetTeam() || IsFlagHome( flag ) || flag.GetParent() != null ) + continue + + if( playerInsidePerimeter.contains( player ) ) + continue + + playerInsidePerimeter.append( player ) + thread TryReturnFlag( player, flag ) + } + else + { + if( playerInsidePerimeter.contains( player ) ) + { + player.Signal( "CTF_LeftReturnTriggerArea" ) // Cut the progress if outside range + playerInsidePerimeter.removebyvalue( player ) + } + } + } + + WaitFrame() + } +} void function TryReturnFlag( entity player, entity flag ) { - // start return progress bar Remote_CallFunction_NonReplay( player, "ServerCallback_CTF_StartReturnFlagProgressBar", Time() + CTF_GetFlagReturnTime() ) EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_FlagReturnMeter" ) - OnThreadEnd( function() : ( player ) + OnThreadEnd( function() : ( flag, player ) { - // cleanup - Remote_CallFunction_NonReplay( player, "ServerCallback_CTF_StopReturnFlagProgressBar" ) - StopSoundOnEntity( player, "UI_CTF_1P_FlagReturnMeter" ) + if ( IsValidPlayer( player ) ) + { + Remote_CallFunction_NonReplay( player, "ServerCallback_CTF_StopReturnFlagProgressBar" ) + StopSoundOnEntity( player, "UI_CTF_1P_FlagReturnMeter" ) + } }) - player.EndSignal( "FlagReturnEnded" ) - flag.EndSignal( "FlagReturnEnded" ) // avoid multiple players to return one flag at once + flag.EndSignal( "CTF_ReturnedFlag" ) + flag.EndSignal( "OnDestroy" ) + + player.EndSignal( "CTF_LeftReturnTriggerArea" ) player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) wait CTF_GetFlagReturnTime() - // flag return succeeded - // return flag ResetFlag( flag ) - flag.Signal( "FlagReturnEnded" ) - - // do notifications for return + + MessageToTeam( flag.GetTeam(), eEventNotifications.PlayerReturnedFriendlyFlag, null, player ) + EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_TeamReturnsFlag", flag.GetTeam() ) + PlayFactionDialogueToTeam( "ctf_flagReturnedFriendly", flag.GetTeam() ) + MessageToPlayer( player, eEventNotifications.YouReturnedFriendlyFlag ) AddPlayerScore( player, "FlagReturn", player ) player.AddToPlayerGameStat( PGS_DEFENSE_SCORE, 1 ) - if( !HasPlayerCompletedMeritScore( player ) ) + if ( !HasPlayerCompletedMeritScore( player ) ) { AddPlayerScore( player, "ChallengeCTFRetAssist" ) SetPlayerChallengeMeritScore( player ) } - MessageToTeam( flag.GetTeam(), eEventNotifications.PlayerReturnedFriendlyFlag, null, player ) - EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_TeamReturnsFlag", flag.GetTeam() ) - PlayFactionDialogueToTeam( "ctf_flagReturnedFriendly", flag.GetTeam() ) - MessageToTeam( GetOtherTeam( flag.GetTeam() ), eEventNotifications.PlayerReturnedEnemyFlag, null, player ) EmitSoundOnEntityToTeam( flag, "UI_CTF_3P_EnemyReturnsFlag", GetOtherTeam( flag.GetTeam() ) ) + EmitSoundOnEntityOnlyToPlayer( player, player, "UI_CTF_1P_ReturnsFlag" ) PlayFactionDialogueToTeam( "ctf_flagReturnedEnemy", GetOtherTeam( flag.GetTeam() ) ) -} \ No newline at end of file + + flag.Signal( "CTF_ReturnedFlag" ) +} + +void function SetFlagStateForTeam( int team, int state ) +{ + if ( state == eFlagState.Away ) // we tell the client the flag is the player carrying it if they're carrying it + SetGlobalNetEnt( team == TEAM_IMC ? "imcFlag" : "milFlag", ( team == TEAM_IMC ? file.imcFlag : file.militiaFlag ).GetParent() ) + else + SetGlobalNetEnt( team == TEAM_IMC ? "imcFlag" : "milFlag", team == TEAM_IMC ? file.imcFlag : file.militiaFlag ) + + SetGlobalNetInt( team == TEAM_IMC ? "imcFlagState" : "milFlagState", state ) +} + +void function DropFlagIfPhased( entity player, entity flag ) +{ + player.EndSignal( "StartPhaseShift" ) + player.EndSignal( "OnDestroy" ) + flag.EndSignal( "OnDestroy" ) + + OnThreadEnd( function() : ( player ) + { + if ( IsValidPlayer( player ) ) + { + if ( GetGameState() == eGameState.Playing || GetGameState() == eGameState.SuddenDeath ) + DropFlag( player, true ) + } + }) + + while( flag.GetParent() == player ) + WaitFrame() +} + +void function DropFlagForBecomingTitan( entity pilot, entity titan ) +{ + DropFlag( pilot, true ) +} + +void function TrackFlagDropTimeout( entity flag ) +{ + flag.EndSignal( "CTF_ReturnedFlag" ) + flag.EndSignal( "ResetDropTimeout" ) + flag.EndSignal( "OnDestroy" ) + + wait CTF_GetDropTimeout() + + ResetFlag( flag ) +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut index c91c27d11..fb84cc82b 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut @@ -20,12 +20,6 @@ void function GamemodePs_Init() ScoreEvent_SetupEarnMeterValuesForMixedModes() SetTimeoutWinnerDecisionFunc( CheckScoreForDraw ) SetupGenericFFAChallenge() - - // spawnzone stuff - SetShouldCreateMinimapSpawnZones( true ) - - //AddCallback_OnPlayerKilled( CheckSpawnzoneSuspiciousDeaths ) - //AddSpawnCallbackEditorClass( "trigger_multiple", "trigger_mp_spawn_zone", SpawnzoneTriggerInit ) file.militiaPreviousSpawnZones = [ null, null, null ] file.imcPreviousSpawnZones = [ null, null, null ] diff --git a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut index 9057f7d8b..3814126ba 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut @@ -32,7 +32,7 @@ void function PrematchClearInventory() // vanilla behavior { foreach( entity player in GetPlayerArray() ) { - PlayerInventory_TakeAllInventoryItems( player ) + thread PlayerInventory_TakeAllInventoryItems( player ) } } diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut index 8d859ba63..376c5b7c3 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut @@ -231,6 +231,8 @@ void function OnPrematchStart() void function PlayerWatchesWargamesIntro( entity player ) { + player.EndSignal( "OnDestroy" ) + if ( IsAlive( player ) ) player.Die() @@ -253,8 +255,6 @@ void function PlayerWatchesWargamesIntro( entity player ) // we need to wait a frame if we killed ourselves to spawn into this, so just easier to do it all the time to remove any weirdness WaitFrame() - - player.EndSignal( "OnDestroy" ) player.EndSignal( "OnDeath" ) int factionTeam = ConvertPlayerFactionToIMCOrMilitiaTeam( player ) diff --git a/README.md b/README.md index 7b6dfaf02..4dbbd6edd 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Issues in this repository should be created if they are related to these domains - `Northstar.Client` - Localisation files, UI and client-side scripts. - `Northstar.Coop` - Soon™. - `Northstar.Custom` - Northstar custom content. -- `Northstar.CustomServer` - Server config files and scripts necessary for multiplayer. +- `Northstar.CustomServers` - Server config files and scripts necessary for multiplayer. ### Translating