Merge branch 'master' into master

This commit is contained in:
Era 2024-02-11 12:37:31 +03:30 committed by GitHub
commit 32894981cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
147 changed files with 1590 additions and 448 deletions

116
.efrocachemap generated
View File

@ -421,42 +421,42 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "bb60812044af0a8d1bdefee759ff2522",
"build/assets/ba_data/data/langdata.json": "831b83240126d0a851104f4148712ed1",
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88",
"build/assets/ba_data/data/languages/belarussian.json": "a112dfca3e188387516788bd8229c5b0",
"build/assets/ba_data/data/languages/chinese.json": "93f3ca9f90d86dc7c8d0923f5f11ef46",
"build/assets/ba_data/data/languages/chinese.json": "1360ffde06828b63ce4fe956c3c3cd1d",
"build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39",
"build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa",
"build/assets/ba_data/data/languages/czech.json": "c9d518a324870066b987b8f412881dd3",
"build/assets/ba_data/data/languages/czech.json": "7171420af6d662e3a47b64576850a384",
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
"build/assets/ba_data/data/languages/dutch.json": "5cbf1a68a9d93dee00dbc27f834d878a",
"build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343",
"build/assets/ba_data/data/languages/english.json": "1c4037fea1066d39d6eced419f314f35",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "0031cbb8eb6a638a94fb43c5d892346c",
"build/assets/ba_data/data/languages/french.json": "8bc35eb4b20a0b30c3348bcc9a3844a6",
"build/assets/ba_data/data/languages/filipino.json": "43e838754fe013b8bac75f75aef78cb3",
"build/assets/ba_data/data/languages/french.json": "cc8ac601f5443dd539893728db983f5c",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "b461539243e8efe3137137b886256ba7",
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "8848f6b0caec0fcf9d85bc6e683809ec",
"build/assets/ba_data/data/languages/hindi.json": "5b6c8e988ffa84a7e26d120b6cd8e1a4",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "408fb026e84c24a8dd7a43cb2b794541",
"build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68",
"build/assets/ba_data/data/languages/italian.json": "f550810b6866ea9bcf1985b7228f8cff",
"build/assets/ba_data/data/languages/korean.json": "03fd99d5e1155e81053fc028f69df982",
"build/assets/ba_data/data/languages/korean.json": "4e3524327a0174250aff5e1ef4c0c597",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
"build/assets/ba_data/data/languages/persian.json": "9728d631cf7d9ad3b209ae1244bb59c0",
"build/assets/ba_data/data/languages/polish.json": "3a90b2d9e2c59305580c96f8098fc839",
"build/assets/ba_data/data/languages/portuguese.json": "0274cb9a4b7d2bd49c8eb8120144a1bf",
"build/assets/ba_data/data/languages/portuguese.json": "b52164747c6308fc9d054eb6c0ff3c54",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
"build/assets/ba_data/data/languages/russian.json": "30d5f3d2415088e1fb6558fcd6ccfa98",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef",
"build/assets/ba_data/data/languages/spanish.json": "08d9b39a519743da9a715c2524c3b6ca",
"build/assets/ba_data/data/languages/spanish.json": "e3e9ac8f96f52302a480c7e955aed71f",
"build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac",
"build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c",
"build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403",
"build/assets/ba_data/data/languages/thai.json": "9c425b420f0488a7f883da98947657ad",
"build/assets/ba_data/data/languages/turkish.json": "2be25c89ca754341f27750e0d595f31e",
"build/assets/ba_data/data/languages/ukrainian.json": "b54a38e93deebafa5706ba2d1f626892",
"build/assets/ba_data/data/languages/venetian.json": "8e9714d98a85e428ce3543fc49188a46",
"build/assets/ba_data/data/languages/venetian.json": "f896fc3df13a42f1bef8813ca80b1a09",
"build/assets/ba_data/data/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba",
"build/assets/ba_data/data/maps/big_g.json": "1dd301d490643088a435ce75df971054",
"build/assets/ba_data/data/maps/bridgit.json": "6aea74805f4880cc11237c5734a24422",
@ -950,7 +950,7 @@
"build/assets/ba_data/python-site-packages/certifi/__main__.py": "ef02e73f8581609df189a9f61aca365b",
"build/assets/ba_data/python-site-packages/certifi/cacert.pem": "4422aed09ab445f7290df7d72a301a47",
"build/assets/ba_data/python-site-packages/certifi/core.py": "1b505388f1475fabd1b60031f985271c",
"build/assets/ba_data/python-site-packages/typing_extensions.py": "2d974cad17a71505d86513d1322976a5",
"build/assets/ba_data/python-site-packages/typing_extensions.py": "188320d92e530be7ea345d3ce3be38de",
"build/assets/ba_data/python-site-packages/yaml/__init__.py": "2b747e5772c203377222afc888ac6b71",
"build/assets/ba_data/python-site-packages/yaml/composer.py": "cef871e1f5f99ba2a7c44941b70afb06",
"build/assets/ba_data/python-site-packages/yaml/constructor.py": "8a15e361e34b79491c81553bb3534062",
@ -4060,50 +4060,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "cd19dfdf480de6e73949db674e1b02d2",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "8c08cdda59e731a3830624000de5ca7f",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "14685eca62b8540cc2a268883d0ebc5d",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "f81876d7827a10be412306c52b03fa08",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b8370845743ebba86ed6eaa6ee1d79d5",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "cdf04825dedae8fb2c26502ec2a505db",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "4036493f98646b58de8bf425bee227cb",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "1cf36c63f68ecaa954fb9c48a132725e",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b757a940c5157197a0138e12e308f859",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "92a07f83fceeddf3b29cfe2ead57f7e3",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "90002c085c66be4af378d4b3fc8e0260",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "eeb363d0d48e68f5f2ac2e536a26aeeb",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "e119b480fc7e542f33ceb16e8c04585f",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "6e657aa09d052765ed891789ec60dfb2",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "2d4eab8ea8399defd1afdbe548216e9c",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "b03bb9d5d1eb695a11843f64f24906ef",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "163fbc40b479ef1db1c753f7beb73c0f",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "37291abd76871f4556348f77e12dd363",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "acca6904f2f2f952ecae99922c602b9d",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "3c2dfd9cf26e77a0b803ed43c85df113",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "3af5cf00e5eb30d55030e8705b83353a",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "be337c05f72235b5b486277bb1a9c259",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "3af5cf00e5eb30d55030e8705b83353a",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "be337c05f72235b5b486277bb1a9c259",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "17c7d0041bc7c84077bf6692b16e3988",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4affbfea91e8a33ab62da763ffc07ddd",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "17c7d0041bc7c84077bf6692b16e3988",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4affbfea91e8a33ab62da763ffc07ddd",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "58656b49d34e6c650983fbf79b5c41ae",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "3ce5652e0ff5d277e256f517dec4eb61",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "58656b49d34e6c650983fbf79b5c41ae",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "3ce5652e0ff5d277e256f517dec4eb61",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "b94fff3a719003c1d8f5dd16dffdb3fc",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5d68e1957febe6053815bbee3f068e76",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "85bbca447ca8a1d0fad984afc6f0700a",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5d68e1957febe6053815bbee3f068e76",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "7f2ed141a475e051d3350d571ef6cb0c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "93fb764531ae16a30d4886eb183c3681",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "750cd7ef428f4faf65ccbeff50c21f8e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "104cf85df9f1f7ffbf4de5997f7c6879",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "af85fb387d755b152c42f8dfb0891ad7",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "01ce8e0619b342e4cc2cc5f18f81a727",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "f8aae2e04f95f4cfb863791da36ff931",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "66252d58a1be97db8523bd0bf8098a16",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d5a8312cd9cf65f32ca2a7c4a2063c03",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "aecb00e9044fa677583e1036fa7875d8",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "eca7f9ab892edfa7423a9d4a6f89e571",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "99647f48362f84112d23a9bc89eaa983",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "31e21a64d77fc0834832b633a26d986b",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "7c12b4078c3af6e627a4051b1c1d8370",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f7a66c48321efa4462e8eae6b72db2b2",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "08cdbeb2ca4fa8c996f3369680c4e5cd",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f92679bab5a0d057427962869e19f057",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "d5bcd695f84dab1ab32655989d399c9e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "c766f437ece15dae0ee971e4c2e10a2d",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "cbecc4c11b9aa4621abfdc996fecfd74",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "7af782c9d9bcf1396a15dea6f2493d70",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "2c04f3f68db3e73e4aad4c656d956c00",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "132c83ee8811828739601ac3d0599fe9",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8de942a2e1ff96c147a9500a56ca4f64",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "6bf51ccbd01937bf1b28cfffe029d857",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c5f0d834a47852f1c240e17a6c933e0a",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4f74b71dabd207bee732dc91c9a28dc4",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f48ab8e4c4d05f4b2231bebf33c965f1",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "dc078f11a4e93062adc7d210fd4f08fb",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "a74bea3380d0fb39f78ac7b7598c1a72",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "dc078f11a4e93062adc7d210fd4f08fb",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "a74bea3380d0fb39f78ac7b7598c1a72",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "b397e020f33132c4dd2280cb1222cd14",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "ff0cb4db976707d25bd401bce80a4882",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "b397e020f33132c4dd2280cb1222cd14",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "ff0cb4db976707d25bd401bce80a4882",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "c464accef921df1325459bdd10c59b84",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "e53c808357cc0a2f0da7b870be147083",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e34cc55fd284e31d9ed1151c5a51bf34",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "36cb65be158a0103d81c82d8a51dc8b6",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "21f8a61745c2fec88749299f5aeeeaf9",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "d61272f101f87b140b84895e482b07f4",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "36c30bcd93d38569b9515ed17896d8de",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "841c7cd3cc96c91ecd11335a91c0c465",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "305aab4423bf510f6bf95fe0c996128f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "f1066b8591d7859df76c8e976ceee2d5",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -9,7 +9,7 @@ assignees: ''
### Description
Describe the bug. Do not forget to fill the title.
Make sure you're running game without any modifications (unless you want to report an api bug).
Make sure you're running game without any modifications.
### Steps to reproduce
1. Launch BombSquad
@ -18,16 +18,17 @@ Make sure you're running game without any modifications (unless you want to repo
4. Bug!
### Expected behavior
Describe what you think should happen.
Describe what you think should happen if it's not obvious.
### Machine
**Platform**: Windows 10 / Ubuntu 20.04 LTS / AOSP 8.1 / etc.
**BombSquad version**: [1.5.27](https://github.com/efroemling/ballistica/releases/tag/v1.5.27)
**Commit**: [2642488](https://github.com/efroemling/ballistica/commit/2642488a51b250752169738f5aeeccaafa2bc8de)
Select what do you want to use: release version or commit. Please use a hyperlink.
**Platform**: Windows 11 / Ubuntu 22.04 LTS / Android 12 / MyToasterOS 7.3 / ... \
**BombSquad version**: [1.7.32](https://github.com/efroemling/ballistica/tree/v1.7.32) \
**Commit**: https://github.com/efroemling/ballistica/tree/978f32f9f098bd0ff1dc64b496ec31cf493ded09
You may specify BombSquad version you're running or refer to the latest commit.
### Screenshots
Put some screenshots here if needed.
### Extra
Put some extra information here. For example, describe your assumptions about the cause of the bug.
You may put some extra information here. For example, describe your assumptions about the cause of the bug.

View File

@ -14,6 +14,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -31,6 +34,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -48,6 +54,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -65,6 +74,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -82,6 +94,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -99,6 +114,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -116,6 +134,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -133,6 +154,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -150,6 +174,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build
@ -167,6 +194,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install pip requirements
run: tools/pcommand install_pip_reqs
- name: Make the build

View File

@ -21,6 +21,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install dependencies
run: tools/pcommand install_pip_reqs
- name: Run checks
@ -35,6 +38,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install dependencies
run: tools/pcommand install_pip_reqs
- name: Assemble monolithic server build
@ -53,6 +59,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install dependencies
run: tools/pcommand install_pip_reqs
- name: Build spinoff project with only core featureset
@ -71,6 +80,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
- name: Install typing_extensions (temp)
run: python3.11 -m pip install typing_extensions
- name: Install dependencies
run: tools/pcommand install_pip_reqs
- name: Create poo feature-set

View File

@ -1,6 +1,4 @@
### 1.7.33 (build 21757, api 8, 2024-01-06)
- Exposed an override for `bascenev1.Session`'s max players on servers (by EraOSBeta)
- Added UI for customizing teams and FFA series length (by EraOSBeta, idea by 3alTemp)
### 1.7.33 (build 21766, api 8, 2024-02-01)
- Stress test input-devices are now a bit smarter; they won't press any buttons
while UIs are up (this could cause lots of chaos if it happened).
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the
@ -13,7 +11,17 @@
- Players now get points for killing bots with their own bombs by catching it
and throwing it back at them. This is actually old logic but was disabled due
to a logic flaw, but should be fixed now. (Thanks VinniTR!)
- Updated the 'Settings->Advanced->Enter Code' functionality to talk to the V2
master server (V1 is still used as a fallback).
- Adopted the `@override` decorator in all Python code and set up Mypy to
enforce its usage. Currently `override` comes from `typing_extensions` module
but when we upgrade to Python 3.12 soon it will come from the standard
`typing` module. This decorator should be familiar to users of other
languages; I feel it helps keep logic more understandable and should help us
catch problems where a base class changes or removes a method and child
classes forget to adapt to the change.
- Implemented `efro.dataclassio.IOMultiType` which will make my life a lot
easier.
### 1.7.32 (build 21741, api 8, 2023-12-20)
- Fixed a screen message that no one will ever see (Thanks vishal332008?...)
- Plugins window now displays 'No Plugins Installed' when no plugins are present (Thanks vishal332008!)

View File

@ -49,7 +49,7 @@ endif
# Prereq targets that should be safe to run anytime; even if project-files
# are out of date.
PREREQS_SAFE = .cache/checkenv $(PCOMMANDBATCHBIN) .dir-locals.el .mypy.ini \
.pyrightconfig.json .pycheckers .pylintrc .style.yapf .clang-format \
.pyrightconfig.json .pylintrc .style.yapf .clang-format \
ballisticakit-cmake/.clang-format .editorconfig
# Prereq targets that may break if the project needs updating should go here.
@ -1216,9 +1216,6 @@ ENV_SRC = $(PCOMMAND) tools/batools/build.py
.pyrightconfig.json: config/toolconfigsrc/pyrightconfig.yaml $(TOOL_CFG_SRC)
@$(TOOL_CFG_INST) $< $@
.pycheckers: config/toolconfigsrc/pycheckers $(TOOL_CFG_SRC)
@$(TOOL_CFG_INST) $< $@
# Set this to 1 to skip environment checks.
SKIP_ENV_CHECKS ?= 0

View File

@ -49,9 +49,6 @@
<file path="$PROJECT_DIR$/../src/external/python-android-debug" />
<file path="$PROJECT_DIR$/../src/external/python-apple" />
<file path="$PROJECT_DIR$/../src/external/python-apple-debug" />
<file path="$PROJECT_DIR$/../src/external/sdl-1.2.14_ef" />
<file path="$PROJECT_DIR$/../src/external/sdl2-ef_android" />
<file path="$PROJECT_DIR$/../src/external/sdl2-ef_ios" />
<file path="$PROJECT_DIR$/../src/external/tremor" />
<file path="$PROJECT_DIR$/../src/external/windows" />
<file path="$PROJECT_DIR$/../src/meta" />

View File

@ -13,7 +13,6 @@
"ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc",
"ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc",
@ -42,7 +41,6 @@
"ba_data/python/babase/_apputils.py",
"ba_data/python/babase/_assetmanager.py",
"ba_data/python/babase/_asyncio.py",
"ba_data/python/babase/_cloud.py",
"ba_data/python/babase/_devconsole.py",
"ba_data/python/babase/_emptyappmode.py",
"ba_data/python/babase/_env.py",
@ -121,8 +119,10 @@
"ba_data/python/baenv.py",
"ba_data/python/baplus/__init__.py",
"ba_data/python/baplus/__pycache__/__init__.cpython-311.opt-1.pyc",
"ba_data/python/baplus/__pycache__/_cloud.cpython-311.opt-1.pyc",
"ba_data/python/baplus/__pycache__/_hooks.cpython-311.opt-1.pyc",
"ba_data/python/baplus/__pycache__/_subsystem.cpython-311.opt-1.pyc",
"ba_data/python/baplus/_cloud.py",
"ba_data/python/baplus/_hooks.py",
"ba_data/python/baplus/_subsystem.py",
"ba_data/python/bascenev1/__init__.py",

View File

@ -171,7 +171,6 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/babase/_apputils.py \
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
$(BUILD_DIR)/ba_data/python/babase/_cloud.py \
$(BUILD_DIR)/ba_data/python/babase/_devconsole.py \
$(BUILD_DIR)/ba_data/python/babase/_emptyappmode.py \
$(BUILD_DIR)/ba_data/python/babase/_env.py \
@ -210,6 +209,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/baclassic/osmusic.py \
$(BUILD_DIR)/ba_data/python/baenv.py \
$(BUILD_DIR)/ba_data/python/baplus/__init__.py \
$(BUILD_DIR)/ba_data/python/baplus/_cloud.py \
$(BUILD_DIR)/ba_data/python/baplus/_hooks.py \
$(BUILD_DIR)/ba_data/python/baplus/_subsystem.py \
$(BUILD_DIR)/ba_data/python/bascenev1/__init__.py \
@ -446,7 +446,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc \
@ -485,6 +484,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/osmusic.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/__pycache__/baenv.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/baplus/__pycache__/__init__.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/baplus/__pycache__/_cloud.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/baplus/__pycache__/_hooks.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/baplus/__pycache__/_subsystem.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/__init__.cpython-311.opt-1.pyc \

View File

@ -118,7 +118,6 @@ from babase._apputils import (
get_remote_app_name,
AppHealthMonitor,
)
from babase._cloud import CloudSubsystem
from babase._devconsole import (
DevConsoleTab,
DevConsoleTabEntry,
@ -213,7 +212,6 @@ __all__ = [
'clipboard_has_text',
'clipboard_is_supported',
'clipboard_set_text',
'CloudSubsystem',
'commit_app_config',
'ContextCall',
'ContextError',

View File

@ -1,15 +1,17 @@
# Released under the MIT License. See LICENSE for details.
#
# pylint: disable=too-many-lines
"""Functionality related to the high level state of the app."""
from __future__ import annotations
import os
import logging
from enum import Enum
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, TypeVar
from concurrent.futures import ThreadPoolExecutor
from functools import cached_property
from typing_extensions import override
from efro.call import tpartial
import _babase
@ -26,7 +28,7 @@ from babase._devconsole import DevConsoleSubsystem
if TYPE_CHECKING:
import asyncio
from typing import Any, Callable, Coroutine
from typing import Any, Callable, Coroutine, Generator, Awaitable
from concurrent.futures import Future
import babase
@ -42,6 +44,8 @@ if TYPE_CHECKING:
# __FEATURESET_APP_SUBSYSTEM_IMPORTS_END__
T = TypeVar('T')
class App:
"""A class for high level app functionality and state.
@ -124,6 +128,7 @@ class App:
statically in a spinoff project.
"""
@override
def app_mode_for_intent(
self, intent: AppIntent
) -> type[AppMode] | None:
@ -199,7 +204,8 @@ class App:
self._called_on_running = False
self._subsystem_registration_ended = False
self._pending_apply_app_config = False
self._aioloop: asyncio.AbstractEventLoop | None = None
self._asyncio_loop: asyncio.AbstractEventLoop | None = None
self._asyncio_tasks: set[asyncio.Task] = set()
self._asyncio_timer: babase.AppTimer | None = None
self._config: babase.AppConfig | None = None
self._pending_intent: AppIntent | None = None
@ -239,18 +245,68 @@ class App:
return _babase.app_is_active()
@property
def aioloop(self) -> asyncio.AbstractEventLoop:
def asyncio_loop(self) -> asyncio.AbstractEventLoop:
"""The logic thread's asyncio event loop.
This allow async tasks to be run in the logic thread.
Generally you should call App.create_async_task() to schedule
async code to run instead of using this directly. That will
handle retaining the task and logging errors automatically.
Only schedule tasks onto asyncio_loop yourself when you intend
to hold on to the returned task and await its results. Releasing
the task reference can lead to subtle bugs such as unreported
errors and garbage-collected tasks disappearing before their
work is done.
Note that, at this time, the asyncio loop is encapsulated
and explicitly stepped by the engine's logic thread loop and
thus things like asyncio.get_running_loop() will not return this
loop from most places in the logic thread; only from within a
task explicitly created in this loop.
thus things like asyncio.get_running_loop() will unintuitively
*not* return this loop from most places in the logic thread;
only from within a task explicitly created in this loop.
Hopefully this situation will be improved in the future with a
unified event loop.
"""
assert self._aioloop is not None
return self._aioloop
assert _babase.in_logic_thread()
assert self._asyncio_loop is not None
return self._asyncio_loop
def create_async_task(
self,
coro: Generator[Any, Any, T] | Coroutine[Any, Any, T],
*,
name: str | None = None,
) -> None:
"""Create a fully managed async task.
This will automatically retain and release a reference to the task
and log any exceptions that occur in it. If you need to await a task
or otherwise need more control, schedule a task directly using
App.asyncio_loop.
"""
assert _babase.in_logic_thread()
# Hold a strong reference to the task until it is done.
# Otherwise it is possible for it to be garbage collected and
# disappear midway if the caller does not hold on to the
# returned task, which seems like a great way to introduce
# hard-to-track bugs.
task = self.asyncio_loop.create_task(coro, name=name)
self._asyncio_tasks.add(task)
task.add_done_callback(self._on_task_done)
# return task
def _on_task_done(self, task: asyncio.Task) -> None:
# Report any errors that occurred.
try:
exc = task.exception()
if exc is not None:
logging.error(
"Error in async task '%s'.", task.get_name(), exc_info=exc
)
except Exception:
logging.exception('Error reporting async task error.')
self._asyncio_tasks.remove(task)
@property
def config(self) -> babase.AppConfig:
@ -594,7 +650,7 @@ class App:
_env.on_app_state_initing()
self._aioloop = _asyncio.setup_asyncio()
self._asyncio_loop = _asyncio.setup_asyncio()
self.health_monitor = AppHealthMonitor()
# __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__
@ -874,8 +930,8 @@ class App:
)
# Now kick off any async shutdown task(s).
assert self._aioloop is not None
self._shutdown_task = self._aioloop.create_task(self._shutdown())
assert self._asyncio_loop is not None
self._shutdown_task = self._asyncio_loop.create_task(self._shutdown())
def _on_shutdown_complete(self) -> None:
"""(internal)"""

View File

@ -40,16 +40,16 @@ class AppSubsystem:
"""Called when the app reaches the running state."""
def on_app_suspend(self) -> None:
"""Called when the app enters the paused state."""
"""Called when the app enters the suspended state."""
def on_app_unsuspend(self) -> None:
"""Called when the app exits the paused state."""
"""Called when the app exits the suspended state."""
def on_app_shutdown(self) -> None:
"""Called when the app is shutting down."""
"""Called when the app begins shutting down."""
def on_app_shutdown_complete(self) -> None:
"""Called when the app is done shutting down."""
"""Called when the app completes shutting down."""
def do_apply_app_config(self) -> None:
"""Called when the app config should be applied."""

View File

@ -10,9 +10,11 @@ from threading import Thread
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
from efro.call import tpartial
from efro.log import LogLevel
from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json
import _babase
from babase._appsubsystem import AppSubsystem
@ -386,6 +388,7 @@ class AppHealthMonitor(AppSubsystem):
self._response = False
self._first_check = True
@override
def on_app_loading(self) -> None:
# If any traceback dumps happened last run, log and clear them.
log_dumped_app_state(from_previous_run=True)
@ -449,10 +452,12 @@ class AppHealthMonitor(AppSubsystem):
self._first_check = False
@override
def on_app_suspend(self) -> None:
assert _babase.in_logic_thread()
self._running = False
@override
def on_app_unsuspend(self) -> None:
assert _babase.in_logic_thread()
self._running = True

View File

@ -8,6 +8,8 @@ from typing import TYPE_CHECKING
from dataclasses import dataclass
import logging
from typing_extensions import override
import _babase
if TYPE_CHECKING:
@ -96,6 +98,7 @@ class DevConsoleTab:
class DevConsoleTabPython(DevConsoleTab):
"""The Python dev-console tab."""
@override
def refresh(self) -> None:
self.python_terminal()
@ -103,6 +106,7 @@ class DevConsoleTabPython(DevConsoleTab):
class DevConsoleTabTest(DevConsoleTab):
"""Test dev-console tab."""
@override
def refresh(self) -> None:
import random

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bacommon.app import AppExperience
import _babase
@ -18,15 +19,18 @@ if TYPE_CHECKING:
class EmptyAppMode(AppMode):
"""An empty app mode that can be used as a fallback/etc."""
@override
@classmethod
def get_app_experience(cls) -> AppExperience:
return AppExperience.EMPTY
@override
@classmethod
def _supports_intent(cls, intent: AppIntent) -> bool:
# We support default and exec intents currently.
return isinstance(intent, AppIntentExec | AppIntentDefault)
@override
def handle_intent(self, intent: AppIntent) -> None:
if isinstance(intent, AppIntentExec):
_babase.empty_app_mode_handle_intent_exec(intent.code)
@ -34,10 +38,12 @@ class EmptyAppMode(AppMode):
assert isinstance(intent, AppIntentDefault)
_babase.empty_app_mode_handle_intent_default()
@override
def on_activate(self) -> None:
# Let the native layer do its thing.
_babase.on_empty_app_mode_activate()
@override
def on_deactivate(self) -> None:
# Let the native layer do its thing.
_babase.on_empty_app_mode_deactivate()

View File

@ -9,6 +9,7 @@ import logging
import warnings
from typing import TYPE_CHECKING
from typing_extensions import override
from efro.log import LogLevel
if TYPE_CHECKING:
@ -216,6 +217,7 @@ def _feed_logs_to_babase(log_handler: LogHandler) -> None:
class _CustomHelper:
"""Replacement 'help' that behaves better for our setup."""
@override
def __repr__(self) -> str:
return 'Type help(object) for help about object.'

View File

@ -10,6 +10,7 @@ import logging
import inspect
from typing import TYPE_CHECKING, TypeVar, Protocol, NewType
from typing_extensions import override
from efro.terminal import Clr
import _babase
@ -178,6 +179,7 @@ class _WeakCall:
def __call__(self, *args_extra: Any) -> Any:
return self._call(*self._args + args_extra, **self._keywds)
@override
def __str__(self) -> str:
return (
'<ba.WeakCall object; _call='
@ -224,6 +226,7 @@ class _Call:
def __call__(self, *args_extra: Any) -> Any:
return self._call(*self._args + args_extra, **self._keywds)
@override
def __str__(self) -> str:
return (
'<ba.Call object; _call='
@ -268,6 +271,7 @@ class WeakMethod:
return None
return self._func(*((obj,) + args), **keywds)
@override
def __str__(self) -> str:
return '<ba.WeakMethod object; call=' + str(self._func) + '>'

View File

@ -8,6 +8,8 @@ import json
import logging
from typing import TYPE_CHECKING, overload
from typing_extensions import override
import _babase
from babase._appsubsystem import AppSubsystem
@ -217,6 +219,7 @@ class LanguageSubsystem(AppSubsystem):
color=(0, 1, 0),
)
@override
def do_apply_app_config(self) -> None:
assert _babase.in_logic_thread()
assert isinstance(_babase.app.config, dict)
@ -598,9 +601,11 @@ class Lstr:
_error.print_exception('_get_json failed for', self.args)
return 'JSON_ERR'
@override
def __str__(self) -> str:
return '<ba.Lstr: ' + self._get_json() + '>'
@override
def __repr__(self) -> str:
return '<ba.Lstr: ' + self._get_json() + '>'
@ -648,5 +653,6 @@ class AttrDict(dict):
assert not isinstance(val, bytes)
return val
@override
def __setattr__(self, attr: str, value: Any) -> None:
raise AttributeError()

View File

@ -9,6 +9,7 @@ import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING, final
from typing_extensions import override
from bacommon.login import LoginType
import _babase
@ -353,6 +354,7 @@ class LoginAdapterNative(LoginAdapter):
self._sign_in_attempt_num = 123
self._sign_in_attempts: dict[int, Callable[[str | None], None]] = {}
@override
def get_sign_in_token(
self, completion_cb: Callable[[str | None], None]
) -> None:
@ -363,6 +365,7 @@ class LoginAdapterNative(LoginAdapter):
self.login_type.value, attempt_id
)
@override
def on_back_end_active_change(self, active: bool) -> None:
_babase.login_adapter_back_end_active_change(
self.login_type.value, active

View File

@ -26,7 +26,7 @@ EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = {
'plugin': 'babase.Plugin',
# DEPRECATED as of 12/2023. Currently am warning if finding these
# but should take this out eventually.
'keyboard': 'babase.Keyboard',
'keyboard': 'bauiv1.Keyboard',
}
T = TypeVar('T')
@ -288,14 +288,12 @@ class DirectoryScan:
) -> None:
"""Scan provided path and add module entries to provided list."""
try:
# Special case: let's save some time and skip the whole 'babase'
# package since we know it doesn't contain any meta tags.
fullpath = Path(path, subpath)
# Note: skipping hidden dirs (starting with '.').
entries = [
(path, Path(subpath, name))
for name in os.listdir(fullpath)
# Actually scratch that for now; trying to avoid special cases.
# if name != 'babase'
if not name.startswith('.')
]
except PermissionError:
# Expected sometimes.

View File

@ -8,6 +8,8 @@ import logging
import importlib.util
from typing import TYPE_CHECKING
from typing_extensions import override
import _babase
from babase._appsubsystem import AppSubsystem
@ -158,6 +160,7 @@ class PluginSubsystem(AppSubsystem):
if config_changed:
_babase.app.config.commit()
@override
def on_app_running(self) -> None:
# Load up our plugins and go ahead and call their on_app_running
# calls.
@ -170,6 +173,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_running()')
@override
def on_app_suspend(self) -> None:
for plugin in self.active_plugins:
try:
@ -179,6 +183,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_suspend()')
@override
def on_app_unsuspend(self) -> None:
for plugin in self.active_plugins:
try:
@ -188,6 +193,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_unsuspend()')
@override
def on_app_shutdown(self) -> None:
for plugin in self.active_plugins:
try:
@ -197,6 +203,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_shutdown()')
@override
def on_app_shutdown_complete(self) -> None:
for plugin in self.active_plugins:
try:

View File

@ -5,6 +5,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from babase._stringedit import StringEditAdapter
import _babase
@ -24,9 +26,11 @@ class DevConsoleStringEditAdapter(StringEditAdapter):
description, initial_text, max_length, screen_space_center
)
@override
def _do_apply(self, new_text: str) -> None:
_babase.set_dev_console_input_text(new_text)
_babase.dev_console_input_adapter_finish()
@override
def _do_cancel(self) -> None:
_babase.dev_console_input_adapter_finish()

View File

@ -229,9 +229,7 @@ class AdsSubsystem:
await asyncio.sleep(1.0)
payload.run(fallback=True)
_fallback_task = babase.app.aioloop.create_task(
add_fallback_task()
)
babase.app.create_async_task(add_fallback_task())
self.show_ad('between_game', on_completion_call=payload.run)
else:
babase.pushcall(call) # Just run the callback without the ad.

View File

@ -7,6 +7,7 @@ import random
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import bascenev1
import _baclassic
@ -43,6 +44,7 @@ def run_cpu_benchmark() -> None:
cfg['Graphics Quality'] = self._old_quality
cfg.apply()
@override
def on_player_request(self, player: bascenev1.SessionPlayer) -> bool:
return False

View File

@ -9,6 +9,7 @@ import threading
from enum import Enum
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import bascenev1
@ -68,6 +69,7 @@ class MasterServerV1CallThread(threading.Thread):
with self._context:
self._callback(arg)
@override
def run(self) -> None:
# pylint: disable=consider-using-with
# pylint: disable=too-many-branches

View File

@ -8,6 +8,7 @@ import random
import logging
import weakref
from typing_extensions import override
from efro.dataclassio import dataclass_from_dict
import babase
import bauiv1
@ -149,6 +150,7 @@ class ClassicSubsystem(babase.AppSubsystem):
assert isinstance(self._env['legacy_user_agent_string'], str)
return self._env['legacy_user_agent_string']
@override
def on_app_loading(self) -> None:
from bascenev1lib.actor import spazappearance
from bascenev1lib import maps as stdmaps
@ -230,13 +232,16 @@ class ClassicSubsystem(babase.AppSubsystem):
self.accounts.on_app_loading()
@override
def on_app_suspend(self) -> None:
self.accounts.on_app_suspend()
@override
def on_app_unsuspend(self) -> None:
self.accounts.on_app_unsuspend()
self.music.on_app_unsuspend()
@override
def on_app_shutdown(self) -> None:
self.music.on_app_shutdown()

View File

@ -8,6 +8,7 @@ import threading
from collections import deque
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
from baclassic._music import MusicPlayer
@ -27,6 +28,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
self._thread = _MacMusicAppThread()
self._thread.start()
@override
def on_select_entry(
self,
callback: Callable[[Any], None],
@ -40,6 +42,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
callback, current_entry, selection_target_name
)
@override
def on_set_volume(self, volume: float) -> None:
self._thread.set_volume(volume)
@ -47,6 +50,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
"""Asynchronously fetch the list of available iTunes playlists."""
self._thread.get_playlists(callback)
@override
def on_play(self, entry: Any) -> None:
assert babase.app.classic is not None
music = babase.app.classic.music
@ -59,9 +63,11 @@ class MacMusicAppMusicPlayer(MusicPlayer):
entry_type,
)
@override
def on_stop(self) -> None:
self._thread.play_playlist(None)
@override
def on_app_shutdown(self) -> None:
self._thread.shutdown()
@ -77,6 +83,7 @@ class _MacMusicAppThread(threading.Thread):
self._current_playlist: str | None = None
self._orig_volume: int | None = None
@override
def run(self) -> None:
"""Run the Music.app thread."""
babase.set_thread_name('BA_MacMusicAppThread')

View File

@ -9,6 +9,7 @@ import logging
import threading
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
from baclassic._music import MusicPlayer
@ -33,6 +34,7 @@ class OSMusicPlayer(MusicPlayer):
# FIXME: should ask the C++ layer for these; just hard-coding for now.
return ['mp3', 'ogg', 'm4a', 'wav', 'flac', 'mid']
@override
def on_select_entry(
self,
callback: Callable[[Any], None],
@ -48,9 +50,11 @@ class OSMusicPlayer(MusicPlayer):
callback, current_entry, selection_target_name
)
@override
def on_set_volume(self, volume: float) -> None:
babase.music_player_set_volume(volume)
@override
def on_play(self, entry: Any) -> None:
assert babase.app.classic is not None
music = babase.app.classic.music
@ -99,11 +103,13 @@ class OSMusicPlayer(MusicPlayer):
self._actually_playing = True
babase.music_player_play(result)
@override
def on_stop(self) -> None:
self._want_to_play = False
self._actually_playing = False
babase.music_player_stop()
@override
def on_app_shutdown(self) -> None:
babase.music_player_shutdown()
@ -120,6 +126,7 @@ class _PickFolderSongThread(threading.Thread):
self._callback = callback
self._path = path
@override
def run(self) -> None:
do_log_error = True
try:

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 21757
TARGET_BALLISTICA_BUILD = 21766
TARGET_BALLISTICA_VERSION = '1.7.33'
@ -287,9 +287,9 @@ def _setup_certs(contains_python_dist: bool) -> None:
import certifi
# Let both OpenSSL and requests (if present) know to use this.
os.environ['SSL_CERT_FILE'] = os.environ[
'REQUESTS_CA_BUNDLE'
] = certifi.where()
os.environ['SSL_CERT_FILE'] = os.environ['REQUESTS_CA_BUNDLE'] = (
certifi.where()
)
def _setup_paths(

View File

@ -16,9 +16,11 @@ from __future__ import annotations
import logging
from baplus._cloud import CloudSubsystem
from baplus._subsystem import PlusSubsystem
__all__ = [
'CloudSubsystem',
'PlusSubsystem',
]

View File

@ -7,8 +7,7 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING, overload
import _babase
from babase._appsubsystem import AppSubsystem
import babase
if TYPE_CHECKING:
from typing import Callable, Any
@ -23,7 +22,7 @@ DEBUG_LOG = False
# internal protocols.
class CloudSubsystem(AppSubsystem):
class CloudSubsystem(babase.AppSubsystem):
"""Manages communication with cloud components."""
@property
@ -44,7 +43,7 @@ class CloudSubsystem(AppSubsystem):
if DEBUG_LOG:
logging.debug('CloudSubsystem: Connectivity is now %s.', connected)
plus = _babase.app.plus
plus = babase.app.plus
assert plus is not None
# Inform things that use this.
@ -117,12 +116,11 @@ class CloudSubsystem(AppSubsystem):
The provided on_response call will be run in the logic thread
and passed either the response or the error that occurred.
"""
from babase._general import Call
del msg # Unused.
_babase.pushcall(
Call(
babase.pushcall(
babase.Call(
on_response,
RuntimeError('Cloud functionality is not available.'),
)
@ -153,6 +151,25 @@ class CloudSubsystem(AppSubsystem):
"""
raise RuntimeError('Cloud functionality is not available.')
@overload
async def send_message_async(
self, msg: bacommon.cloud.PromoCodeMessage
) -> bacommon.cloud.PromoCodeResponse:
...
@overload
async def send_message_async(
self, msg: bacommon.cloud.TestMessage
) -> bacommon.cloud.TestResponse:
...
async def send_message_async(self, msg: Message) -> Response | None:
"""Synchronously send a message to the cloud.
Must be called from the logic thread.
"""
raise RuntimeError('Cloud functionality is not available.')
def cloud_console_exec(code: str) -> None:
"""Called by the cloud console to run code in the logic thread."""
@ -188,7 +205,7 @@ def cloud_console_exec(code: str) -> None:
except Exception:
import traceback
apptime = _babase.apptime()
apptime = babase.apptime()
print(f'Exec error at time {apptime:.2f}.', file=sys.stderr)
traceback.print_exc()

View File

@ -5,13 +5,17 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import _baplus
from typing_extensions import override
from babase import AppSubsystem
import _baplus
if TYPE_CHECKING:
from typing import Callable, Any
from babase import CloudSubsystem, AccountV2Subsystem
from babase import AccountV2Subsystem
from baplus._cloud import CloudSubsystem
class PlusSubsystem(AppSubsystem):
@ -32,6 +36,7 @@ class PlusSubsystem(AppSubsystem):
accounts: AccountV2Subsystem
cloud: CloudSubsystem
@override
def on_app_loading(self) -> None:
_baplus.on_app_loading()
self.accounts.on_app_loading()

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -34,11 +35,13 @@ class EndSessionActivity(Activity[EmptyPlayer, EmptyTeam]):
self.inherits_vr_camera_offset = True
self.inherits_vr_overlay_center = True
@override
def on_transition_in(self) -> None:
super().on_transition_in()
babase.fade_screen(False)
babase.lock_all_input()
@override
def on_begin(self) -> None:
# pylint: disable=cyclic-import
@ -77,6 +80,7 @@ class JoinActivity(Activity[EmptyPlayer, EmptyTeam]):
self._tips_text: bascenev1.Actor | None = None
self._join_info: JoinInfo | None = None
@override
def on_transition_in(self) -> None:
# pylint: disable=cyclic-import
from bascenev1lib.actor.tipstext import TipsText
@ -110,6 +114,7 @@ class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]):
super().__init__(settings)
self._background: bascenev1.Actor | None = None
@override
def on_transition_in(self) -> None:
# pylint: disable=cyclic-import
from bascenev1lib.actor.background import Background
@ -119,6 +124,7 @@ class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]):
fade_time=0.5, start_faded=False, show_logo=False
)
@override
def on_begin(self) -> None:
super().on_begin()
@ -152,6 +158,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
self._custom_continue_message: babase.Lstr | None = None
self._server_transitioning: bool | None = None
@override
def on_player_join(self, player: EmptyPlayer) -> None:
super().on_player_join(player)
time_till_assign = max(
@ -164,6 +171,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
time_till_assign, babase.WeakCall(self._safe_assign, player)
)
@override
def on_transition_in(self) -> None:
from bascenev1lib.actor.tipstext import TipsText
from bascenev1lib.actor.background import Background
@ -176,6 +184,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
self._tips_text = TipsText()
setmusic(self.default_music)
@override
def on_begin(self) -> None:
# pylint: disable=cyclic-import
from bascenev1lib.actor.text import Text

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bacommon.app import AppExperience
from babase import (
app,
@ -23,15 +24,18 @@ if TYPE_CHECKING:
class SceneV1AppMode(AppMode):
"""Our app-mode."""
@override
@classmethod
def get_app_experience(cls) -> AppExperience:
return AppExperience.MELEE
@override
@classmethod
def _supports_intent(cls, intent: AppIntent) -> bool:
# We support default and exec intents currently.
return isinstance(intent, AppIntentExec | AppIntentDefault)
@override
def handle_intent(self, intent: AppIntent) -> None:
if isinstance(intent, AppIntentExec):
_bascenev1.handle_app_intent_exec(intent.code)
@ -39,14 +43,17 @@ class SceneV1AppMode(AppMode):
assert isinstance(intent, AppIntentDefault)
_bascenev1.handle_app_intent_default()
@override
def on_activate(self) -> None:
# Let the native layer do its thing.
_bascenev1.on_app_mode_activate()
@override
def on_deactivate(self) -> None:
# Let the native layer do its thing.
_bascenev1.on_app_mode_deactivate()
@override
def on_app_active_changed(self) -> None:
# If we've gone inactive, bring up the main menu, which has the
# side effect of pausing the action (when possible).

View File

@ -6,6 +6,7 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING, TypeVar
from typing_extensions import override
import babase
import _bascenev1
@ -31,6 +32,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
# We can assume our session is a CoopSession.
session: bascenev1.CoopSession
@override
@classmethod
def supports_session_type(
cls, sessiontype: type[bascenev1.Session]
@ -49,6 +51,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
self._life_warning_beep_timer: bascenev1.Timer | None = None
self._warn_beeps_sound = _bascenev1.getsound('warnBeeps')
@override
def on_begin(self) -> None:
super().on_begin()
@ -139,6 +142,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
)
vval -= 55
@override
def spawn_player_spaz(
self,
player: PlayerT,

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -97,6 +98,7 @@ class CoopSession(Session):
"""Get the game instance currently being played."""
return self._current_game_instance
@override
def should_allow_mid_activity_joins(
self, activity: bascenev1.Activity
) -> bool:
@ -174,9 +176,11 @@ class CoopSession(Session):
self._tutorial_activity = _bascenev1.newactivity(TutorialActivity)
@override
def get_custom_menu_entries(self) -> list[dict[str, Any]]:
return self._custom_menu_ui
@override
def on_player_leave(self, sessionplayer: bascenev1.SessionPlayer) -> None:
super().on_player_leave(sessionplayer)
@ -256,6 +260,7 @@ class CoopSession(Session):
activity.end(results={'outcome': 'restart'}, force=True)
# noinspection PyUnresolvedReferences
@override
def on_activity_end(
self, activity: bascenev1.Activity, results: Any
) -> None:

View File

@ -7,6 +7,7 @@ from __future__ import annotations
import weakref
from typing import Generic, TypeVar, TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -313,6 +314,7 @@ class AssetPackage(DependencyComponent):
self.package_id = entry.config
print(f'LOADING ASSET PACKAGE {self.package_id}')
@override
@classmethod
def dep_is_present(cls, config: Any = None) -> bool:
assert isinstance(config, str)

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -32,6 +33,7 @@ class DualTeamSession(MultiTeamSession):
babase.increment_analytics_count('Teams session start')
super().__init__()
@override
def _switch_to_score_screen(self, results: bascenev1.GameResults) -> None:
# pylint: disable=cyclic-import
from bascenev1lib.activity.multiteamvictory import (

View File

@ -6,6 +6,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -53,6 +54,7 @@ class FreeForAllSession(MultiTeamSession):
babase.increment_analytics_count('Free-for-all session start')
super().__init__()
@override
def _switch_to_score_screen(self, results: bascenev1.GameResults) -> None:
# pylint: disable=cyclic-import
from efro.util import asserttype

View File

@ -9,6 +9,7 @@ import random
import logging
from typing import TYPE_CHECKING, TypeVar
from typing_extensions import override
import babase
import _bascenev1
@ -377,6 +378,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
"""
return ''
@override
def on_transition_in(self) -> None:
super().on_transition_in()
@ -488,6 +490,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
self.end_game()
@override
def on_begin(self) -> None:
super().on_begin()
@ -536,12 +539,14 @@ class GameActivity(Activity[PlayerT, TeamT]):
max(5, data_t[0]['timeRemaining'])
)
@override
def on_player_join(self, player: PlayerT) -> None:
super().on_player_join(player)
# By default, just spawn a dude.
self.spawn_player(player)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, PlayerDiedMessage):
# pylint: disable=cyclic-import
@ -835,6 +840,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
animate(combine, 'input3', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
_bascenev1.timer(5.0, tnode.delete)
@override
def end(
self, results: Any = None, delay: float = 0.0, force: bool = False
) -> None:

View File

@ -7,6 +7,7 @@ import copy
import weakref
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
if TYPE_CHECKING:
@ -38,6 +39,7 @@ class Level:
self._index: int | None = None
self._score_version_string: str | None = None
@override
def __repr__(self) -> str:
cls = type(self)
return f"<{cls.__module__}.{cls.__name__} '{self._name}'>"

View File

@ -6,6 +6,7 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
@ -353,9 +354,11 @@ class Map(Actor):
return self.flag_points_default[:3]
return self.flag_points[team_index % len(self.flag_points)][:3]
@override
def exists(self) -> bool:
return bool(self.node)
@override
def handlemessage(self, msg: Any) -> Any:
from bascenev1 import _messages

View File

@ -8,7 +8,9 @@ import random
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bascenev1
from bascenev1._session import Session
@ -160,6 +162,7 @@ class MultiTeamSession(Session):
"""Returns which game in the series is currently being played."""
return self._game_number
@override
def on_team_join(self, team: bascenev1.SessionTeam) -> None:
team.customdata['previous_score'] = team.customdata['score'] = 0
@ -178,6 +181,7 @@ class MultiTeamSession(Session):
self._next_game_spec['settings'],
)
@override
def on_activity_end(
self, activity: bascenev1.Activity, results: Any
) -> None:

View File

@ -6,6 +6,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bascenev1._messages import DieMessage
from bascenev1._actor import Actor
@ -28,6 +30,7 @@ class NodeActor(Actor):
super().__init__()
self.node = node
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, DieMessage):
if self.node:
@ -35,5 +38,6 @@ class NodeActor(Actor):
return None
return super().handlemessage(msg)
@override
def exists(self) -> bool:
return bool(self.node)

View File

@ -7,6 +7,7 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING, TypeVar
from typing_extensions import override
import babase
import _bascenev1
@ -35,6 +36,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
bascenev1.Player has their own bascenev1.Team)
"""
@override
@classmethod
def supports_session_type(
cls, sessiontype: type[bascenev1.Session]
@ -57,6 +59,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
if isinstance(self.session, FreeForAllSession):
self.show_kill_points = False
@override
def on_transition_in(self) -> None:
# pylint: disable=cyclic-import
from bascenev1._coopsession import CoopSession
@ -85,6 +88,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
).autoretain()
setattr(self.session, attrname, True)
@override
def on_begin(self) -> None:
super().on_begin()
try:
@ -104,6 +108,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
except Exception:
logging.exception('Error in on_begin.')
@override
def spawn_player_spaz(
self,
player: PlayerT,

View File

@ -4,6 +4,7 @@
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
@ -18,6 +19,7 @@ class CoopJoinActivity(bs.JoinActivity):
session = self.session
assert isinstance(session, bs.CoopSession)
@override
def on_transition_in(self) -> None:
from bascenev1lib.actor.controlsguide import ControlsGuide
from bascenev1lib.actor.text import Text

View File

@ -9,6 +9,7 @@ import random
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
from bacommon.login import LoginType
import bascenev1 as bs
import bauiv1 as bui
@ -186,6 +187,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self._victory: bool = settings['outcome'] == 'victory'
@override
def __del__(self) -> None:
super().__del__()
@ -194,6 +196,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
with bui.ContextRef.empty():
bui.containerwidget(edit=self._root_ui, transition='out_left')
@override
def on_transition_in(self) -> None:
from bascenev1lib.actor import background # FIXME NO BSSTD
@ -574,6 +577,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self._player_press,
)
@override
def on_player_join(self, player: bs.Player) -> None:
super().on_player_join(player)
@ -585,6 +589,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
bs.timer(time_till_assign, bs.WeakCall(self._safe_assign, player))
@override
def on_begin(self) -> None:
# FIXME: Clean this up.
# pylint: disable=too-many-statements

View File

@ -4,7 +4,9 @@
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
from bascenev1lib.actor.zoomtext import ZoomText
@ -14,6 +16,7 @@ class DrawScoreScreenActivity(MultiTeamScoreScreenActivity):
default_music = None # Awkward silence...
@override
def on_begin(self) -> None:
bs.set_analytics_screen('Draw Score Screen')
super().on_begin()

View File

@ -4,7 +4,9 @@
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
from bascenev1lib.actor.zoomtext import ZoomText
@ -17,6 +19,7 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
self._winner: bs.SessionTeam = settings['winner']
assert isinstance(self._winner, bs.SessionTeam)
@override
def on_begin(self) -> None:
bs.set_analytics_screen('Teams Score Screen')
super().on_begin()

View File

@ -6,9 +6,11 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
if TYPE_CHECKING:
from typing import Any
@ -23,6 +25,7 @@ class FreeForAllVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
self.transition_time = 0.5
self._cymbal_sound = bs.getsound('cymbal')
@override
def on_begin(self) -> None:
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements

View File

@ -4,7 +4,9 @@
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.text import Text
@ -15,6 +17,7 @@ class MultiTeamJoinActivity(bs.JoinActivity):
super().__init__(settings)
self._next_up_text: Text | None = None
@override
def on_transition_in(self) -> None:
from bascenev1lib.actor.controlsguide import ControlsGuide

View File

@ -3,7 +3,9 @@
"""Functionality related to teams mode score screen."""
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.text import Text
from bascenev1lib.actor.image import Image
@ -18,6 +20,7 @@ class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity):
self._show_up_next: bool = True
@override
def on_begin(self) -> None:
super().on_begin()
session = self.session

View File

@ -4,7 +4,9 @@
from __future__ import annotations
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
@ -22,6 +24,7 @@ class TeamSeriesVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
self._tips_text = None
self._default_show_tips = False
@override
def on_begin(self) -> None:
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals

View File

@ -9,6 +9,7 @@ import weakref
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -104,6 +105,7 @@ class Background(bs.Actor):
timeval += random.random() * 0.1
bs.animate(cmb, 'input1', keys, loop=True)
@override
def __del__(self) -> None:
# Normal actors don't get sent DieMessages when their
# activity is shutting down, but we still need to do so
@ -138,6 +140,7 @@ class Background(bs.Actor):
)
bs.timer(self.fade_time + 0.1, self.node.delete)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -10,7 +10,9 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING, TypeVar
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.gameutils import SharedObjects
if TYPE_CHECKING:
@ -661,6 +663,7 @@ class Blast(bs.Actor):
bs.timer(0.4, _extra_debris_sound)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
@ -935,6 +938,7 @@ class Bomb(bs.Actor):
else None
)
@override
def on_expire(self) -> None:
super().on_expire()
@ -1140,6 +1144,7 @@ class Bomb(bs.Actor):
if msg.srcnode:
pass
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, ExplodeMessage):
self.explode()

View File

@ -6,6 +6,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -547,9 +548,11 @@ class ControlsGuide(bs.Actor):
self._update_timer = None
self._dead = True
@override
def exists(self) -> bool:
return not self._dead
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -7,9 +7,11 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from bascenev1lib.gameutils import SharedObjects
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.gameutils import SharedObjects
if TYPE_CHECKING:
from typing import Any, Sequence
@ -328,6 +330,7 @@ class Flag(bs.Actor):
1.0, bs.WeakCall(self._hide_score_text)
)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -7,6 +7,7 @@ from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -165,6 +166,7 @@ class Image(bs.Actor):
bs.WeakCall(self.handlemessage, bs.DieMessage()),
)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -6,6 +6,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -72,6 +73,7 @@ class OnScreenCountdown(bs.Actor):
)
self._timer = bs.Timer(1.0, self._update, repeat=True)
@override
def on_expire(self) -> None:
super().on_expire()

View File

@ -6,6 +6,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import logging
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -93,6 +94,7 @@ class OnScreenTimer(bs.Actor):
"""Shortcut for start time in seconds."""
return self.getstarttime()
@override
def handlemessage(self, msg: Any) -> Any:
# if we're asked to die, just kill our node/timer
if isinstance(msg, bs.DieMessage):

View File

@ -6,7 +6,9 @@ from __future__ import annotations
from typing import TYPE_CHECKING, TypeVar, overload
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.spaz import Spaz
if TYPE_CHECKING:
@ -183,6 +185,7 @@ class PlayerSpaz(Spaz):
' non-connected player'
)
@override
def handlemessage(self, msg: Any) -> Any:
# FIXME: Tidy this up.
# pylint: disable=too-many-branches

View File

@ -7,6 +7,7 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -118,6 +119,7 @@ class PopupText(bs.Actor):
lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage())
)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -7,7 +7,9 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.gameutils import SharedObjects
if TYPE_CHECKING:
@ -278,6 +280,7 @@ class PowerupBox(bs.Actor):
if self.node:
self.node.flashing = True
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired

View File

@ -9,11 +9,13 @@ import random
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.bomb import Bomb, Blast
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
from bascenev1lib.actor.spazfactory import SpazFactory
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence, Callable
@ -228,9 +230,11 @@ class Spaz(bs.Actor):
self.punch_callback: Callable[[Spaz], Any] | None = None
self.pick_up_powerup_callback: Callable[[Spaz], Any] | None = None
@override
def exists(self) -> bool:
return bool(self.node)
@override
def on_expire(self) -> None:
super().on_expire()
@ -249,6 +253,7 @@ class Spaz(bs.Actor):
assert not self.expired
self._dropped_bomb_callbacks.append(call)
@override
def is_alive(self) -> bool:
"""
Method override; returns whether ol' spaz is still kickin'.
@ -694,6 +699,7 @@ class Spaz(bs.Actor):
else:
self.shield_decay_timer = None
@override
def handlemessage(self, msg: Any) -> Any:
# pylint: disable=too-many-return-statements
# pylint: disable=too-many-statements

View File

@ -10,6 +10,7 @@ import weakref
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.spaz import Spaz
@ -489,6 +490,7 @@ class SpazBot(Spaz):
self.on_punch_press()
self.on_punch_release()
@override
def on_punched(self, damage: int) -> None:
"""
Method override; sends bs.SpazBotPunchedMessage
@ -496,6 +498,7 @@ class SpazBot(Spaz):
"""
bs.getactivity().handlemessage(SpazBotPunchedMessage(self, damage))
@override
def on_expire(self) -> None:
super().on_expire()
@ -503,6 +506,7 @@ class SpazBot(Spaz):
# no chance of them keeping activities or other things alive.
self.update_callback = None
@override
def handlemessage(self, msg: Any) -> Any:
# pylint: disable=too-many-branches
assert not self.expired

View File

@ -7,6 +7,7 @@ from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -221,6 +222,7 @@ class Text(bs.Actor):
bs.WeakCall(self.handlemessage, bs.DieMessage()),
)
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -6,6 +6,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -95,6 +96,7 @@ class TipsText(bs.Actor):
)
self.node.text = next_tip
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -8,6 +8,7 @@ import random
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
if TYPE_CHECKING:
@ -158,6 +159,7 @@ class ZoomText(bs.Actor):
if lifespan is not None:
bs.timer(lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage()))
@override
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, bs.DieMessage):

View File

@ -10,11 +10,13 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.flag import Flag
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -71,10 +73,12 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
bs.BoolSetting('Epic Mode', default=False),
]
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -96,16 +100,19 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FORWARD_MARCH
)
@override
def get_instance_description(self) -> str | Sequence:
if self._score_to_win == 1:
return 'Touch the enemy flag.'
return 'Touch the enemy flag ${ARG1} times.', self._score_to_win
@override
def get_instance_description_short(self) -> str | Sequence:
if self._score_to_win == 1:
return 'touch 1 flag'
return 'touch ${ARG1} flags', self._score_to_win
@override
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
shared = SharedObjects.get()
base_pos = self.map.get_flag_position(sessionteam.id)
@ -151,16 +158,19 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
return team
@override
def on_team_join(self, team: Team) -> None:
# Can't do this in create_team because the team's color/etc. have
# not been wired up yet at that point.
self._update_scoreboard()
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
self.setup_standard_powerup_drops()
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment standard.
@ -249,6 +259,7 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
if player_team.score >= self._score_to_win:
self.end_game()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:

View File

@ -10,6 +10,9 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.flag import (
@ -19,7 +22,6 @@ from bascenev1lib.actor.flag import (
FlagDroppedMessage,
FlagDiedMessage,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -141,10 +143,12 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
bs.BoolSetting('Epic Mode', default=False),
]
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -173,16 +177,19 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FLAG_CATCHER
)
@override
def get_instance_description(self) -> str | Sequence:
if self._score_to_win == 1:
return 'Steal the enemy flag.'
return 'Steal the enemy flag ${ARG1} times.', self._score_to_win
@override
def get_instance_description_short(self) -> str | Sequence:
if self._score_to_win == 1:
return 'return 1 flag'
return 'return ${ARG1} flags', self._score_to_win
@override
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
# Create our team instance and its initial values.
@ -272,12 +279,14 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
return team
@override
def on_team_join(self, team: Team) -> None:
# Can't do this in create_team because the team's color/etc. have
# not been wired up yet at that point.
self._spawn_flag_for_team(team)
self._update_scoreboard()
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
@ -406,6 +415,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
if team.score >= self._score_to_win:
self.end_game()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -532,6 +542,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
bs.animate(light, 'intensity', {0.0: 0, 0.25: 2.0, 0.5: 0}, loop=True)
bs.timer(length, light.delete)
@override
def spawn_player_spaz(
self,
player: Player,
@ -576,6 +587,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
team, team.score, self._score_to_win
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment standard behavior.

View File

@ -10,11 +10,13 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.flag import Flag
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -83,6 +85,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
]
scoreconfig = bs.ScoreConfig(label='Time Held')
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -121,20 +124,25 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.CHOSEN_ONE
)
@override
def get_instance_description(self) -> str | Sequence:
return 'There can be only one.'
@override
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
return Team(time_remaining=self._chosen_one_time)
@override
def on_team_join(self, team: Team) -> None:
self._update_scoreboard()
@override
def on_player_leave(self, player: Player) -> None:
super().on_player_leave(player)
if self._get_chosen_one_player() is player:
self._set_chosen_one_player(None)
@override
def on_begin(self) -> None:
super().on_begin()
shared = SharedObjects.get()
@ -251,6 +259,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
logging.error('got nonexistent player as chosen one in _tick')
self._set_chosen_one_player(None)
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -335,6 +344,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
'position', light.node, 'position'
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.

View File

@ -10,12 +10,14 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.flag import Flag
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.gameutils import SharedObjects
from bascenev1lib.actor.respawnicon import RespawnIcon
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -108,10 +110,12 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
bs.BoolSetting('Epic Mode', default=False),
]
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -143,16 +147,20 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
),
)
@override
def get_instance_description(self) -> str | Sequence:
return 'Secure all ${ARG1} flags.', len(self.map.flag_points)
@override
def get_instance_description_short(self) -> str | Sequence:
return 'secure all ${ARG1} flags', len(self.map.flag_points)
@override
def on_team_join(self, team: Team) -> None:
if self.has_begun():
self._update_scores()
@override
def on_player_join(self, player: Player) -> None:
player.respawn_timer = None
@ -160,6 +168,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
if player.team.flags_held > 0:
self.spawn_player(player)
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
@ -221,6 +230,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
team, team.flags_held, len(self._flags)
)
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -272,6 +282,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
):
self.spawn_player(otherplayer)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.
@ -287,6 +298,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
else:
super().handlemessage(msg)
@override
def spawn_player(self, player: Player) -> bs.Actor:
# We spawn players at different places based on what flags are held.
return self.spawn_player_spaz(

View File

@ -9,9 +9,11 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -38,6 +40,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
# Print messages when players die since it matters here.
announce_player_deaths = True
@override
@classmethod
def get_available_settings(
cls, sessiontype: type[bs.Session]
@ -87,12 +90,14 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
return settings
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
sessiontype, bs.FreeForAllSession
)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -116,16 +121,20 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.TO_THE_DEATH
)
@override
def get_instance_description(self) -> str | Sequence:
return 'Crush ${ARG1} of your enemies.', self._score_to_win
@override
def get_instance_description_short(self) -> str | Sequence:
return 'kill ${ARG1} enemies', self._score_to_win
@override
def on_team_join(self, team: Team) -> None:
if self.has_begun():
self._update_scoreboard()
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
@ -137,6 +146,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
)
self._update_scoreboard()
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.
@ -197,6 +207,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
team, team.score, self._score_to_win
)
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:

View File

@ -10,6 +10,9 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.bomb import Bomb
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.spazbot import SpazBotSet, BouncyBot, SpazBotDiedMessage
@ -17,7 +20,6 @@ from bascenev1lib.actor.onscreencountdown import OnScreenCountdown
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.respawnicon import RespawnIcon
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any
@ -51,11 +53,13 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
scoreconfig = bs.ScoreConfig(label='Score', scoretype=bs.ScoreType.POINTS)
# We're currently hard-coded for one map.
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
return ['Tower D']
# We support teams, free-for-all, and co-op sessions.
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return (
@ -93,11 +97,13 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FORWARD_MARCH
)
@override
def on_team_join(self, team: Team) -> None:
if self.has_begun():
self._update_scoreboard()
# Called when our game actually starts.
@override
def on_begin(self) -> None:
from bascenev1lib.maps import TowerD
@ -118,6 +124,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
self._spawn_evil_bunny()
# Overriding the default character spawning.
@override
def spawn_player(self, player: Player) -> bs.Actor:
spaz = self.spawn_player_spaz(player)
spaz.connect_controls_to_player()
@ -191,6 +198,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
self._eggs.append(Egg(position=(xpos, ypos, zpos)))
# Various high-level game events come through this method.
@override
def handlemessage(self, msg: Any) -> Any:
# Respawn dead players.
if isinstance(msg, bs.PlayerDiedMessage):
@ -231,6 +239,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
for team in self.teams:
self._scoreboard.set_team_value(team, team.score)
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -271,9 +280,11 @@ class Egg(bs.Actor):
},
)
@override
def exists(self) -> bool:
return bool(self.node)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.DieMessage):
if self.node:

View File

@ -10,9 +10,11 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.spazfactory import SpazFactory
from bascenev1lib.actor.scoreboard import Scoreboard
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -157,6 +159,7 @@ class Icon(bs.Actor):
if lives == 0:
bs.timer(0.6, self.update_for_lives)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.DieMessage):
self.node.delete()
@ -194,6 +197,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
allow_mid_activity_joins = False
@override
@classmethod
def get_available_settings(
cls, sessiontype: type[bs.Session]
@ -238,12 +242,14 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
)
return settings
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
sessiontype, bs.FreeForAllSession
)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -269,6 +275,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SURVIVAL
)
@override
def get_instance_description(self) -> str | Sequence:
return (
'Last team standing wins.'
@ -276,6 +283,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
else 'Last one standing wins.'
)
@override
def get_instance_description_short(self) -> str | Sequence:
return (
'last team standing wins'
@ -283,6 +291,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
else 'last one standing wins'
)
@override
def on_player_join(self, player: Player) -> None:
player.lives = self._lives_per_player
@ -299,6 +308,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
if self.has_begun():
self._update_icons()
@override
def on_begin(self) -> None:
super().on_begin()
self._start_time = bs.time()
@ -469,6 +479,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
return points[-1][1]
return None
@override
def spawn_player(self, player: Player) -> bs.Actor:
actor = self.spawn_player_spaz(player, self._get_spawn_point(player))
if not self._solo_mode:
@ -495,6 +506,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
position=player.node.position,
).autoretain()
@override
def on_player_leave(self, player: Player) -> None:
super().on_player_leave(player)
player.icons = []
@ -518,6 +530,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
def _get_total_team_lives(self, team: Team) -> int:
return sum(player.lives for player in team.players)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.
@ -588,6 +601,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
and any(player.lives > 0 for player in team.players)
]
@override
def end_game(self) -> None:
if self.has_ended():
return

View File

@ -1,5 +1,6 @@
# Released under the MIT License. See LICENSE for details.
#
# pylint: disable=too-many-lines
"""Implements football games (both co-op and teams varieties)."""
# ba_meta require api 8
@ -12,6 +13,9 @@ import random
import logging
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.bomb import TNTSpawner
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
@ -39,7 +43,6 @@ from bascenev1lib.actor.spazbot import (
StickyBot,
ExplodeyBot,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -128,11 +131,13 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
bs.BoolSetting('Epic Mode', default=False),
]
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
# We only support two-team play.
return issubclass(sessiontype, bs.DualTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -170,6 +175,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FOOTBALL
)
@override
def get_instance_description(self) -> str | Sequence:
touchdowns = self._score_to_win / 7
@ -181,6 +187,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
return 'Score ${ARG1} touchdowns.', touchdowns
return 'Score a touchdown.'
@override
def get_instance_description_short(self) -> str | Sequence:
touchdowns = self._score_to_win / 7
touchdowns = math.ceil(touchdowns)
@ -188,6 +195,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
return 'score ${ARG1} touchdowns', touchdowns
return 'score a touchdown'
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
@ -224,6 +232,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
self._update_scoreboard()
self._chant_sound.play()
@override
def on_team_join(self, team: Team) -> None:
self._update_scoreboard()
@ -285,6 +294,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
bs.cameraflash(duration=10.0)
self._update_scoreboard()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -298,6 +308,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
team, team.score, self._score_to_win
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, FlagPickedUpMessage):
assert isinstance(msg.flag, FootballFlag)
@ -379,9 +390,11 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
default_music = bs.MusicType.FOOTBALL
# FIXME: Need to update co-op games to use getscoreconfig.
@override
def get_score_type(self) -> str:
return 'time'
@override
def get_instance_description(self) -> str | Sequence:
touchdowns = self._score_to_win / 7
touchdowns = math.ceil(touchdowns)
@ -389,6 +402,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
return 'Score ${ARG1} touchdowns.', touchdowns
return 'Score a touchdown.'
@override
def get_instance_description_short(self) -> str | Sequence:
touchdowns = self._score_to_win / 7
touchdowns = math.ceil(touchdowns)
@ -444,6 +458,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
self._flag_respawn_light: bs.Actor | None = None
self._flag: FootballFlag | None = None
@override
def on_transition_in(self) -> None:
super().on_transition_in()
self._scoreboard = Scoreboard()
@ -480,6 +495,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
)
self._chant_sound.play()
@override
def on_begin(self) -> None:
# FIXME: Split this up a bit.
# pylint: disable=too-many-statements
@ -795,11 +811,13 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
if i == 0:
bs.cameraflash(duration=10.0)
@override
def end_game(self) -> None:
bs.setmusic(None)
self._bots.final_celebrate()
bs.timer(0.001, bs.Call(self.do_end, 'defeat'))
@override
def on_continue(self) -> None:
# Subtract one touchdown from the bots and get them moving again.
assert self._bot_team is not None
@ -897,6 +915,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
},
)
@override
def handlemessage(self, msg: Any) -> Any:
"""handle high-level game messages"""
if isinstance(msg, bs.PlayerDiedMessage):
@ -959,6 +978,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
del player # Unused.
self._player_has_punched = True
@override
def spawn_player(self, player: Player) -> bs.Actor:
spaz = self.spawn_player_spaz(
player, position=self.map.get_start_position(player.team.id)

View File

@ -9,11 +9,13 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -58,6 +60,7 @@ class Puck(bs.Actor):
)
bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1})
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.DieMessage):
if self.node:
@ -152,10 +155,12 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
bs.BoolSetting('Epic Mode', default=False),
]
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -231,16 +236,19 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.HOCKEY
)
@override
def get_instance_description(self) -> str | Sequence:
if self._score_to_win == 1:
return 'Score a goal.'
return 'Score ${ARG1} goals.', self._score_to_win
@override
def get_instance_description_short(self) -> str | Sequence:
if self._score_to_win == 1:
return 'score a goal'
return 'score ${ARG1} goals', self._score_to_win
@override
def on_begin(self) -> None:
super().on_begin()
@ -281,6 +289,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
self._update_scoreboard()
self._chant_sound.play()
@override
def on_team_join(self, team: Team) -> None:
self._update_scoreboard()
@ -364,6 +373,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
bs.cameraflash(duration=10.0)
self._update_scoreboard()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -375,6 +385,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
for team in self.teams:
self._scoreboard.set_team_value(team, team.score, winscore)
@override
def handlemessage(self, msg: Any) -> Any:
# Respawn dead players if they're still in the game.
if isinstance(msg, bs.PlayerDiedMessage):

View File

@ -11,6 +11,9 @@ import logging
from enum import Enum
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.flag import (
@ -19,7 +22,6 @@ from bascenev1lib.actor.flag import (
FlagDiedMessage,
FlagPickedUpMessage,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -86,12 +88,14 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
]
scoreconfig = bs.ScoreConfig(label='Time Held')
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
sessiontype, bs.FreeForAllSession
)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -129,18 +133,23 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.KEEP_AWAY
)
@override
def get_instance_description(self) -> str | Sequence:
return 'Carry the flag for ${ARG1} seconds.', self._hold_time
@override
def get_instance_description_short(self) -> str | Sequence:
return 'carry the flag for ${ARG1} seconds', self._hold_time
@override
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
return Team(timeremaining=self._hold_time)
@override
def on_team_join(self, team: Team) -> None:
self._update_scoreboard()
@override
def on_begin(self) -> None:
super().on_begin()
self.setup_standard_time_limit(self._time_limit)
@ -181,6 +190,7 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
if scoreteam.timeremaining <= 0:
self.end_game()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -268,6 +278,7 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
team, team.timeremaining, self._hold_time, countdown=True
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.

View File

@ -11,11 +11,13 @@ import weakref
from enum import Enum
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.flag import Flag
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -84,10 +86,12 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
]
scoreconfig = bs.ScoreConfig(label='Time Held')
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.MultiTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -144,15 +148,19 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SCARY
)
@override
def get_instance_description(self) -> str | Sequence:
return 'Secure the flag for ${ARG1} seconds.', self._hold_time
@override
def get_instance_description_short(self) -> str | Sequence:
return 'secure the flag for ${ARG1} seconds', self._hold_time
@override
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
return Team(time_remaining=self._hold_time)
@override
def on_begin(self) -> None:
super().on_begin()
shared = SharedObjects.get()
@ -223,6 +231,7 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
if scoring_team.time_remaining <= 0:
self.end_game()
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -283,6 +292,7 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
team, team.time_remaining, self._hold_time, countdown=True
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment default.

View File

@ -10,9 +10,11 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.bomb import Bomb
from bascenev1lib.actor.onscreentimer import OnScreenTimer
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -49,11 +51,13 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
allow_mid_activity_joins = False
# We're currently hard-coded for one map.
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
return ['Rampage']
# We support teams, free-for-all, and co-op sessions.
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return (
@ -77,6 +81,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
if self._epic_mode:
self.slow_motion = True
@override
def on_begin(self) -> None:
super().on_begin()
@ -100,6 +105,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
# Check for immediate end (if we've only got 1 player, etc).
bs.timer(5.0, self._check_end_game)
@override
def on_player_leave(self, player: Player) -> None:
# Augment default behavior.
super().on_player_leave(player)
@ -108,6 +114,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
self._check_end_game()
# overriding the default character spawning..
@override
def spawn_player(self, player: Player) -> bs.Actor:
spaz = self.spawn_player_spaz(player)
@ -122,6 +129,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
return spaz
# Various high-level game events come through this method.
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment standard behavior.
@ -213,6 +221,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
def _decrement_meteor_time(self) -> None:
self._meteor_time = max(0.01, self._meteor_time * 0.9)
@override
def end_game(self) -> None:
cur_time = bs.time()
assert self._timer is not None

View File

@ -10,13 +10,15 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.spazbot import (
SpazBotSet,
ChargerBot,
SpazBotDiedMessage,
)
from bascenev1lib.actor.onscreentimer import OnScreenTimer
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any
@ -44,6 +46,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
)
default_music = bs.MusicType.TO_THE_DEATH
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
# For now we're hard-coding spawn positions and whatnot
@ -51,6 +54,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
# a specific map.
return ['Courtyard']
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
# We currently support Co-Op only.
@ -67,6 +71,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
self._preset = str(settings['preset'])
# Called when our game actually begins.
@override
def on_begin(self) -> None:
super().on_begin()
is_pro = self._preset == 'pro'
@ -123,6 +128,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
)
# Called for each spawning player.
@override
def spawn_player(self, player: Player) -> bs.Actor:
# Let's spawn close to the center.
spawn_center = (0, 3, -2)
@ -144,6 +150,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
self.end_game()
# Called for miscellaneous messages.
@override
def handlemessage(self, msg: Any) -> Any:
# A player has died.
if isinstance(msg, bs.PlayerDiedMessage):
@ -166,6 +173,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
# When this is called, we should fill out results and end the game
# *regardless* of whether is has been won. (this may be called due
# to a tournament ending or other external reason).
@override
def end_game(self) -> None:
# Stop our on-screen timer so players can see what they got.
assert self._timer is not None

View File

@ -17,6 +17,9 @@ from enum import Enum, unique
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.popuptext import PopupText
from bascenev1lib.actor.bomb import TNTSpawner
from bascenev1lib.actor.playerspaz import PlayerSpazHurtMessage
@ -45,7 +48,6 @@ from bascenev1lib.actor.spazbot import (
BrawlerBotPro,
BomberBotProShielded,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -222,6 +224,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
self._land_mine_kills = 0
self._tnt_kills = 0
@override
def on_transition_in(self) -> None:
super().on_transition_in()
customdata = bs.getsession().customdata
@ -286,6 +289,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
label=bs.Lstr(resource='scoreText'), score_split=0.5
)
@override
def on_begin(self) -> None:
super().on_begin()
player_count = len(self.players)
@ -825,6 +829,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
break
entry_count += 1
@override
def spawn_player(self, player: Player) -> bs.Actor:
# We keep track of who got hurt each wave for score purposes.
player.has_been_hurt = False
@ -1414,6 +1419,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
assert self._scoreboard is not None
self._scoreboard.set_team_value(self.teams[0], score, max_score=None)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, PlayerSpazHurtMessage):
msg.spaz.getplayer(Player, True).has_been_hurt = True
@ -1526,6 +1532,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
def _set_can_end_wave(self) -> None:
self._can_end_wave = True
@override
def end_game(self) -> None:
# Tell our bots to celebrate just to rub it in.
assert self._bots is not None
@ -1534,6 +1541,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
self.do_end('defeat', delay=2.0)
bs.setmusic(None)
@override
def on_continue(self) -> None:
for player in self.players:
if not player.is_alive():

View File

@ -12,11 +12,13 @@ import logging
from typing import TYPE_CHECKING
from dataclasses import dataclass
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.bomb import Bomb
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.gameutils import SharedObjects
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -84,6 +86,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
label='Time', lower_is_better=True, scoretype=bs.ScoreType.MILLISECONDS
)
@override
@classmethod
def get_available_settings(
cls, sessiontype: type[bs.Session]
@ -133,10 +136,12 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
)
return settings
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
return issubclass(sessiontype, bs.MultiTeamSession)
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
assert bs.app.classic is not None
@ -179,6 +184,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
bs.MusicType.EPIC_RACE if self._epic_mode else bs.MusicType.RACE
)
@override
def get_instance_description(self) -> str | Sequence:
if (
isinstance(self.session, bs.DualTeamSession)
@ -192,11 +198,13 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
return 'Run ${ARG1} laps.' + t_str, self._laps
return 'Run 1 lap.' + t_str
@override
def get_instance_description_short(self) -> str | Sequence:
if self._laps > 1:
return 'run ${ARG1} laps', self._laps
return 'run 1 lap'
@override
def on_transition_in(self) -> None:
super().on_transition_in()
shared = SharedObjects.get()
@ -379,9 +387,11 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
except Exception:
logging.exception('Error printing lap.')
@override
def on_team_join(self, team: Team) -> None:
self._update_scoreboard()
@override
def on_player_leave(self, player: Player) -> None:
super().on_player_leave(player)
@ -442,6 +452,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
show_value=False,
)
@override
def on_begin(self) -> None:
from bascenev1lib.actor.onscreentimer import OnScreenTimer
@ -670,6 +681,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
self._flash_mine(m_index)
bs.timer(0.95, bs.Call(self._make_mine, m_index))
@override
def spawn_player(self, player: Player) -> bs.Actor:
if player.team.finished:
# FIXME: This is not type-safe!
@ -758,6 +770,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
self.end_game()
return
@override
def end_game(self) -> None:
# Stop updating our time text, and set it to show the exact last
# finish time if we have one. (so users don't get upset if their
@ -787,6 +800,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
announce_winning_team=isinstance(self.session, bs.DualTeamSession),
)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
# Augment default behavior.

View File

@ -16,6 +16,9 @@ from enum import Enum
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.popuptext import PopupText
from bascenev1lib.actor.bomb import TNTSpawner
from bascenev1lib.actor.scoreboard import Scoreboard
@ -40,7 +43,6 @@ from bascenev1lib.actor.spazbot import (
BomberBotPro,
BrawlerBotPro,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -194,6 +196,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
self._flawless_bonus: int | None = None
self._wave_update_timer: bs.Timer | None = None
@override
def on_transition_in(self) -> None:
super().on_transition_in()
self._scoreboard = Scoreboard(
@ -211,6 +214,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
)
)
@override
def on_begin(self) -> None:
super().on_begin()
player_count = len(self.players)
@ -571,6 +575,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
),
)
@override
def on_continue(self) -> None:
self._lives = 3
assert self._lives_text is not None
@ -578,6 +583,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
self._lives_text.node.text = str(self._lives)
self._bots.start_moving()
@override
def spawn_player(self, player: Player) -> bs.Actor:
pos = (
self._spawn_center[0] + random.uniform(-1.5, 1.5),
@ -654,6 +660,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
),
).autoretain()
@override
def end_game(self) -> None:
bs.pushcall(bs.Call(self.do_end, 'defeat'))
bs.setmusic(None)
@ -1286,6 +1293,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
# Revert to normal bot behavior otherwise..
return False
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerScoredMessage):
self._score += msg.score

View File

@ -10,11 +10,13 @@ from __future__ import annotations
import random
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.onscreencountdown import OnScreenCountdown
from bascenev1lib.actor.bomb import Bomb
from bascenev1lib.actor.popuptext import PopupText
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -49,10 +51,12 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
]
default_music = bs.MusicType.FORWARD_MARCH
@override
@classmethod
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
return ['Doom Shroom']
@override
@classmethod
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
# We support any teams or versus sessions.
@ -70,10 +74,12 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
self._enable_impact_bombs = bool(settings['Enable Impact Bombs'])
self._enable_triple_bombs = bool(settings['Enable Triple Bombs'])
@override
def on_team_join(self, team: Team) -> None:
if self.has_begun():
self.update_scoreboard()
@override
def on_begin(self) -> None:
super().on_begin()
self.update_scoreboard()
@ -86,6 +92,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
self._countdown = OnScreenCountdown(60, endcall=self.end_game)
bs.timer(4.0, self._countdown.start)
@override
def spawn_player(self, player: Player) -> bs.Actor:
spawn_center = (0, 3, -5)
pos = (
@ -169,6 +176,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
# Clear out targets that have died.
self._targets = [t for t in self._targets if t]
@override
def handlemessage(self, msg: Any) -> Any:
# When players die, respawn them.
if isinstance(msg, bs.PlayerDiedMessage):
@ -188,6 +196,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
for team in self.teams:
self._scoreboard.set_team_value(team, team.score)
@override
def end_game(self) -> None:
results = bs.GameResults()
for team in self.teams:
@ -252,9 +261,11 @@ class Target(bs.Actor):
bs.animate_array(loc3, 'size', 1, {0.1: [0.0], 0.3: [self._r3 * 2.0]})
bs.getsound('laserReverse').play()
@override
def exists(self) -> bool:
return bool(self._nodes)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.DieMessage):
for node in self._nodes:

View File

@ -9,6 +9,9 @@ import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.actor.bomb import TNTSpawner
from bascenev1lib.actor.scoreboard import Scoreboard
@ -29,7 +32,6 @@ from bascenev1lib.actor.spazbot import (
StickyBot,
ExplodeyBot,
)
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any, Sequence
@ -109,6 +111,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
ExplodeyBot: SpawnInfo(0.05, 0.02, 0.002),
}
@override
def on_transition_in(self) -> None:
super().on_transition_in()
bs.timer(1.3, self._new_wave_sound.play)
@ -116,6 +119,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
label=bs.Lstr(resource='scoreText'), score_split=0.5
)
@override
def on_begin(self) -> None:
super().on_begin()
@ -129,6 +133,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
position=self._tntspawnpos, respawn_time=10.0
)
@override
def spawn_player(self, player: Player) -> bs.Actor:
pos = (
self._spawn_center[0] + random.uniform(-1.5, 1.5),
@ -290,6 +295,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
assert self._scoreboard is not None
self._scoreboard.set_team_value(self.teams[0], score, max_score=None)
@override
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
player = msg.getplayer(Player)
@ -327,6 +333,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
else:
super().handlemessage(msg)
@override
def end_game(self) -> None:
# Tell our bots to celebrate just to rub it in.
self._bots.final_celebrate()

View File

@ -10,6 +10,7 @@ import random
import weakref
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
import bauiv1 as bui
@ -44,6 +45,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
self._news: NewsDisplay | None = None
self._attract_mode_timer: bs.Timer | None = None
@override
def on_transition_in(self) -> None:
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
@ -1139,6 +1141,7 @@ class MainMenuSession(bs.Session):
self._locked = False
self.setactivity(bs.newactivity(MainMenuActivity))
@override
def on_activity_end(self, activity: bs.Activity, results: Any) -> None:
if self._locked:
bui.unlock_all_input()
@ -1146,6 +1149,7 @@ class MainMenuSession(bs.Session):
# Any ending activity leads us into the main menu one.
self.setactivity(bs.newactivity(MainMenuActivity))
@override
def on_player_request(self, player: bs.SessionPlayer) -> bool:
# Reject all player requests.
return False

View File

@ -7,7 +7,9 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.gameutils import SharedObjects
if TYPE_CHECKING:
@ -22,15 +24,18 @@ class HockeyStadium(bs.Map):
name = 'Hockey Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'hockey', 'team_flag', 'keep_away']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'hockeyStadiumPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -114,15 +119,18 @@ class FootballStadium(bs.Map):
name = 'Football Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'football', 'team_flag', 'keep_away']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'footballStadiumPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -164,6 +172,7 @@ class FootballStadium(bs.Map):
gnode.vr_camera_offset = (0, -0.8, -1.1)
gnode.vr_near_clip = 0.5
@override
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
box_position = self.defs.boxes['edge_box'][0:3]
box_scale = self.defs.boxes['edge_box'][6:9]
@ -181,16 +190,19 @@ class Bridgit(bs.Map):
name = 'Bridgit'
dataname = 'bridgit'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
# print('getting playtypes', cls._getdata()['play_types'])
return ['melee', 'team_flag', 'keep_away']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'bridgitPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -286,6 +298,7 @@ class BigG(bs.Map):
name = 'Big G'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
@ -298,10 +311,12 @@ class BigG(bs.Map):
'conquest',
]
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'bigGPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -397,15 +412,18 @@ class Roundabout(bs.Map):
name = 'Roundabout'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'roundaboutPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -502,15 +520,18 @@ class MonkeyFace(bs.Map):
name = 'Monkey Face'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'monkeyFacePreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -607,6 +628,7 @@ class ZigZag(bs.Map):
name = 'Zigzag'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
@ -618,10 +640,12 @@ class ZigZag(bs.Map):
'king_of_the_hill',
]
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'zigzagPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -715,15 +739,18 @@ class ThePad(bs.Map):
name = 'The Pad'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'thePadPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -804,15 +831,18 @@ class DoomShroom(bs.Map):
name = 'Doom Shroom'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'doomShroomPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -881,6 +911,7 @@ class DoomShroom(bs.Map):
gnode.vignette_outer = (0.76, 0.76, 0.76)
gnode.vignette_inner = (0.95, 0.95, 0.99)
@override
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
xpos = point.x
zpos = point.z
@ -900,15 +931,18 @@ class LakeFrigid(bs.Map):
name = 'Lake Frigid'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag', 'race']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'lakeFrigidPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -987,15 +1021,18 @@ class TipTop(bs.Map):
name = 'Tip Top'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'tipTopPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1065,15 +1102,18 @@ class CragCastle(bs.Map):
name = 'Crag Castle'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag', 'conquest']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'cragCastlePreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1158,15 +1198,18 @@ class TowerD(bs.Map):
name = 'Tower D'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return []
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'towerDPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1256,6 +1299,7 @@ class TowerD(bs.Map):
gnode.vignette_outer = (0.7, 0.73, 0.7)
gnode.vignette_inner = (0.95, 0.95, 0.95)
@override
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
# see if we're within edge_box
boxes = self.defs.boxes
@ -1281,6 +1325,7 @@ class HappyThoughts(bs.Map):
name = 'Happy Thoughts'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
@ -1292,10 +1337,12 @@ class HappyThoughts(bs.Map):
'king_of_the_hill',
]
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'alwaysLandPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1310,6 +1357,7 @@ class HappyThoughts(bs.Map):
}
return data
@override
@classmethod
def get_music_type(cls) -> bs.MusicType:
return bs.MusicType.FLYING
@ -1397,15 +1445,18 @@ class StepRightUp(bs.Map):
name = 'Step Right Up'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag', 'conquest']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'stepRightUpPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1477,15 +1528,18 @@ class Courtyard(bs.Map):
name = 'Courtyard'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'courtyardPreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1576,6 +1630,7 @@ class Courtyard(bs.Map):
gnode.vignette_outer = (0.6, 0.6, 0.64)
gnode.vignette_inner = (0.95, 0.95, 0.93)
@override
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
# count anything off our ground level as safe (for our platforms)
# see if we're within edge_box
@ -1593,15 +1648,18 @@ class Rampage(bs.Map):
name = 'Rampage'
@override
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
return ['melee', 'keep_away', 'team_flag']
@override
@classmethod
def get_preview_texture_name(cls) -> str:
return 'rampagePreview'
@override
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
@ -1681,6 +1739,7 @@ class Rampage(bs.Map):
gnode.vignette_outer = (0.62, 0.64, 0.69)
gnode.vignette_inner = (0.97, 0.95, 0.93)
@override
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
box_position = self.defs.boxes['edge_box'][0:3]
box_scale = self.defs.boxes['edge_box'][6:9]

View File

@ -19,6 +19,7 @@ import logging
from collections import deque
from typing import TYPE_CHECKING
from typing_extensions import override
import bascenev1 as bs
from bascenev1lib.actor.spaz import Spaz
@ -234,11 +235,13 @@ class TutorialActivity(bs.Activity[Player, Team]):
self._read_entries_timer: bs.Timer | None = None
self._entry_timer: bs.Timer | None = None
@override
def on_transition_in(self) -> None:
super().on_transition_in()
bs.setmusic(bs.MusicType.CHAR_SELECT, continuous=True)
self.map = self._map_type()
@override
def on_begin(self) -> None:
super().on_begin()
@ -2513,6 +2516,7 @@ class TutorialActivity(bs.Activity[Player, Team]):
self._skip_text.color = (1, 1, 1)
self._issued_warning = False
@override
def on_player_join(self, player: Player) -> None:
super().on_player_join(player)
@ -2527,6 +2531,7 @@ class TutorialActivity(bs.Activity[Player, Team]):
bs.Call(self._player_pressed_button, player),
)
@override
def on_player_leave(self, player: Player) -> None:
if not all(self.players):
logging.error(

View File

@ -8,7 +8,9 @@ import logging
import inspect
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bauiv1
if TYPE_CHECKING:
@ -82,6 +84,7 @@ class UIV1Subsystem(babase.AppSubsystem):
"""Current ui scale for the app."""
return self._uiscale
@override
def on_app_loading(self) -> None:
from bauiv1._uitypes import UIController, ui_upkeep

View File

@ -9,6 +9,7 @@ import weakref
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
import babase
import _bauiv1
@ -264,12 +265,14 @@ class TextWidgetStringEditAdapter(babase.StringEditAdapter):
description, initial_text, max_length, screen_space_center
)
@override
def _do_apply(self, new_text: str) -> None:
if self.widget:
_bauiv1.textwidget(
edit=self.widget, text=new_text, adapter_finished=True
)
@override
def _do_cancel(self) -> None:
if self.widget:
_bauiv1.textwidget(edit=self.widget, adapter_finished=True)

View File

@ -7,9 +7,11 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import logging
from bauiv1lib.popup import PopupWindow, PopupMenuWindow
from typing_extensions import override
import bauiv1 as bui
from bauiv1lib.popup import PopupWindow, PopupMenuWindow
if TYPE_CHECKING:
from typing import Any
@ -596,6 +598,7 @@ class AccountViewerWindow(PopupWindow):
self._transitioning_out = True
bui.containerwidget(edit=self.root_widget, transition='out_scale')
@override
def on_popup_cancel(self) -> None:
bui.getsound('swish').play()
self._transition_out()

View File

@ -4,6 +4,8 @@
from __future__ import annotations
from typing_extensions import override
from bauiv1lib.popup import PopupWindow
import bauiv1 as bui
@ -229,6 +231,7 @@ class AchievementsWindow(PopupWindow):
self._transitioning_out = True
bui.containerwidget(edit=self.root_widget, transition='out_scale')
@override
def on_popup_cancel(self) -> None:
bui.getsound('swish').play()
self._transition_out()

View File

@ -7,6 +7,8 @@ from __future__ import annotations
import math
from typing import TYPE_CHECKING
from typing_extensions import override
from bauiv1lib.popup import PopupWindow
import bauiv1 as bui
@ -208,6 +210,7 @@ class CharacterPicker(PopupWindow):
self._transitioning_out = True
bui.containerwidget(edit=self.root_widget, transition='out_scale')
@override
def on_popup_cancel(self) -> None:
bui.getsound('swish').play()
self._transition_out()

View File

@ -6,6 +6,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bauiv1lib.popup import PopupWindow
import bauiv1 as bui
@ -170,6 +172,7 @@ class ColorPicker(PopupWindow):
self._delegate.color_picker_closing(self)
bui.containerwidget(edit=self.root_widget, transition='out_scale')
@override
def on_popup_cancel(self) -> None:
if not self._transitioning_out:
bui.getsound('swish').play()
@ -338,6 +341,7 @@ class ColorPickerExact(PopupWindow):
self._delegate.color_picker_closing(self)
bui.containerwidget(edit=self.root_widget, transition='out_scale')
@override
def on_popup_cancel(self) -> None:
if not self._transitioning_out:
bui.getsound('swish').play()

View File

@ -10,6 +10,8 @@ import logging
from threading import Thread
from typing import TYPE_CHECKING
from typing_extensions import override
import bauiv1 as bui
if TYPE_CHECKING:
@ -204,6 +206,7 @@ class FileSelectorWindow(bui.Window):
self._callback = callback
self._path = path
@override
def run(self) -> None:
try:
starttime = time.time()

View File

@ -6,6 +6,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bauiv1lib.gather import GatherTab
import bauiv1 as bui
@ -16,6 +18,7 @@ if TYPE_CHECKING:
class AboutGatherTab(GatherTab):
"""The about tab in the gather UI"""
@override
def on_activate(
self,
parent_widget: bui.Widget,

View File

@ -6,13 +6,13 @@
from __future__ import annotations
import logging
from threading import Thread
from typing import TYPE_CHECKING, cast
from enum import Enum
from threading import Thread
from dataclasses import dataclass
from typing import TYPE_CHECKING, cast
from bauiv1lib.gather import GatherTab
from typing_extensions import override
import bauiv1 as bui
import bascenev1 as bs
@ -42,6 +42,7 @@ class _HostLookupThread(Thread):
self._port = port
self._call = call
@override
def run(self) -> None:
result: str | None
try:
@ -101,6 +102,7 @@ class ManualGatherTab(GatherTab):
self._party_edit_port_text: bui.Widget | None = None
self._no_parties_added_text: bui.Widget | None = None
@override
def on_activate(
self,
parent_widget: bui.Widget,
@ -180,10 +182,12 @@ class ManualGatherTab(GatherTab):
return self._container
@override
def save_state(self) -> None:
assert bui.app.classic is not None
bui.app.ui_v1.window_states[type(self)] = State(sub_tab=self._sub_tab)
@override
def restore_state(self) -> None:
assert bui.app.classic is not None
state = bui.app.ui_v1.window_states.get(type(self))
@ -771,6 +775,7 @@ class ManualGatherTab(GatherTab):
text=bui.Lstr(resource='gatherWindow.noPartiesAddedText'),
)
@override
def on_deactivate(self) -> None:
self._access_check_timer = None

View File

@ -7,10 +7,12 @@ from __future__ import annotations
import weakref
from typing import TYPE_CHECKING
from bauiv1lib.gather import GatherTab
from typing_extensions import override
import bauiv1 as bui
import bascenev1 as bs
from bauiv1lib.gather import GatherTab
if TYPE_CHECKING:
from typing import Any
@ -104,6 +106,7 @@ class NearbyGatherTab(GatherTab):
self._net_scanner: NetScanner | None = None
self._container: bui.Widget | None = None
@override
def on_activate(
self,
parent_widget: bui.Widget,
@ -156,5 +159,6 @@ class NearbyGatherTab(GatherTab):
bui.widget(edit=scrollw, autoselect=True, up_widget=tab_button)
return self._container
@override
def on_deactivate(self) -> None:
self._net_scanner = None

View File

@ -13,6 +13,7 @@ from enum import Enum
from dataclasses import dataclass
from typing import TYPE_CHECKING, cast
from typing_extensions import override
from efro.dataclassio import dataclass_from_dict, dataclass_to_dict
from bacommon.net import (
PrivateHostingState,
@ -81,6 +82,7 @@ class PrivateGatherTab(GatherTab):
logging.exception('Error building hosting config.')
self._hostingconfig = PrivateHostingConfig()
@override
def on_activate(
self,
parent_widget: bui.Widget,
@ -253,6 +255,7 @@ class PrivateGatherTab(GatherTab):
return hcfg
@override
def on_deactivate(self) -> None:
self._update_timer = None
@ -995,10 +998,12 @@ class PrivateGatherTab(GatherTab):
self._debug_server_comm('got connect response error')
bui.getsound('error').play()
@override
def save_state(self) -> None:
assert bui.app.classic is not None
bui.app.ui_v1.window_states[type(self)] = copy.deepcopy(self._state)
@override
def restore_state(self) -> None:
assert bui.app.classic is not None
state = bui.app.ui_v1.window_states.get(type(self))

Some files were not shown because too many files have changed in this diff Show More