Merge branch 'master' into keybind_reset

This commit is contained in:
Eric Froemling 2024-03-13 17:45:48 -07:00 committed by GitHub
commit b52fbf198b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
252 changed files with 3127 additions and 1868 deletions

123
.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": "5273cf3bfe2d25d70395690bf3c21825",
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88",
"build/assets/ba_data/data/langdata.json": "8409781047f46ca6627eacdfc0b4d3d3",
"build/assets/ba_data/data/languages/arabic.json": "2c2915e10124bb8f69206da9c608d57c",
"build/assets/ba_data/data/languages/belarussian.json": "09954e550d13d3d9cb5a635a1d32a151",
"build/assets/ba_data/data/languages/chinese.json": "1360ffde06828b63ce4fe956c3c3cd1d",
"build/assets/ba_data/data/languages/chinese.json": "bb51b5aa614830c561e8fe2542a9ab8a",
"build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39",
"build/assets/ba_data/data/languages/croatian.json": "e671b9d0c012be1a30f9c15eb1b81860",
"build/assets/ba_data/data/languages/czech.json": "7171420af6d662e3a47b64576850a384",
"build/assets/ba_data/data/languages/czech.json": "15be4fd59895135bad0265f79b362d5b",
"build/assets/ba_data/data/languages/danish.json": "8e57db30c5250df2abff14a822f83ea7",
"build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343",
"build/assets/ba_data/data/languages/english.json": "28a1c17925aba4f4f908732e5e5cb266",
"build/assets/ba_data/data/languages/english.json": "0a95fdbc1564161bc7c8b419b0c03651",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "fe3f1efcb47efaa23524300d21728933",
"build/assets/ba_data/data/languages/french.json": "cc8ac601f5443dd539893728db983f5c",
"build/assets/ba_data/data/languages/filipino.json": "5226bf247fa1c8f4406360644f3fa15f",
"build/assets/ba_data/data/languages/french.json": "917e4174d6f0eb7f00c27fd79cfbb924",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "ab9571486f703b8d57eab61dbf1d54d8",
"build/assets/ba_data/data/languages/gibberish.json": "5533873020e51186beb2f209adbbfb08",
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "90f54663e15d85a163f1848a8e9d8d07",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68",
"build/assets/ba_data/data/languages/italian.json": "f550810b6866ea9bcf1985b7228f8cff",
"build/assets/ba_data/data/languages/italian.json": "55c350f8f5039802138ffc1013f14ed3",
"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": "1a4c74ad9089cd746ad6fda4186c2220",
"build/assets/ba_data/data/languages/malay.json": "f6ce0426d03a62612e3e436ed5d1be1f",
"build/assets/ba_data/data/languages/persian.json": "07eddcf92d3dcc7a745ea74e2b0007c8",
"build/assets/ba_data/data/languages/polish.json": "9d22c6643c097c4cb268d0d6b6319cd4",
"build/assets/ba_data/data/languages/portuguese.json": "b52164747c6308fc9d054eb6c0ff3c54",
"build/assets/ba_data/data/languages/portuguese.json": "a48df1d11a088a1a2e6e3f66627444be",
"build/assets/ba_data/data/languages/romanian.json": "b3e46efd6f869dbd78014570e037c290",
"build/assets/ba_data/data/languages/russian.json": "30d5f3d2415088e1fb6558fcd6ccfa98",
"build/assets/ba_data/data/languages/russian.json": "0590f49889616b5279be569dea926e17",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "c00fb27cf982ffad5a4370ad3b16bd21",
"build/assets/ba_data/data/languages/spanish.json": "e3e9ac8f96f52302a480c7e955aed71f",
"build/assets/ba_data/data/languages/spanish.json": "b2edb923fdca973a16f0efb1acc26a97",
"build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac",
"build/assets/ba_data/data/languages/tamil.json": "b9fcc523639f55e05c7f4e7914f3321a",
"build/assets/ba_data/data/languages/thai.json": "1d665629361f302693dead39de8fa945",
"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": "f896fc3df13a42f1bef8813ca80b1a09",
"build/assets/ba_data/data/languages/turkish.json": "db71f3776072b7a15ef37b1bb1245795",
"build/assets/ba_data/data/languages/ukrainian.json": "3d75d21205c82db34fb1a1b014592747",
"build/assets/ba_data/data/languages/venetian.json": "035034e0b4de696a41bf753ab4d0e194",
"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",
@ -3521,6 +3521,7 @@
"build/assets/pylib-apple/zoneinfo/_common.py": "5b52bdac4156dcbac96743fa99468bf2",
"build/assets/pylib-apple/zoneinfo/_tzpath.py": "f021e91036bd38590f2ce643b59dc881",
"build/assets/pylib-apple/zoneinfo/_zoneinfo.py": "d000d61aa8998d0076c37f96cf40ca69",
"build/assets/sphinx/template/conf.py": "1d00917de95f8f62f372caa1146ff602",
"build/assets/windows/Win32/DLLs/_asyncio.pyd": "36024ca5f0f257dd4edfe1a3e92c1a07",
"build/assets/windows/Win32/DLLs/_asyncio_d.pyd": "a809fe3d7f3b6931e5f127821d0d30b6",
"build/assets/windows/Win32/DLLs/_bz2.pyd": "cf535d3d0a020f0ae5ff20336a56ba3b",
@ -4060,50 +4061,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": "a7161a4100172e2bb42b838a9851c353",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "9a63e694db2ed7536374c58a45ce65d3",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9668ef38ddc59fadf323cf460c8b692c",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "8f58837d238dba248ae2e23e20bc3f06",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f8a6e20f3fffd198494adfba4e884588",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "255205c95d519a594041fc239e435883",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "36facf256b69a8c0037370e23c82470d",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d78aef348baf274f476ce9e344b80122",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f1b9732cc7e7728dcedc39a55d9afea2",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "8cfc0e04c10a315cce91dae041dfc3ff",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "a9fec1930c851f8ed743b08669df2d75",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a6fcaa9d7eb10412787e4416f3536bb9",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a39230df064404a3b1dd18a644f2f6d6",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "04e971f62a000383a13eb021e30afa7b",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "a93fe4f0cfb3c2c9061df049068230ac",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0f08a84bb09589991faaca9250171e3c",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "12c079e62d0125b8a24b16e418405ba9",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "eb0d76fd3be03082572b0d835df05252",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "e4268ef0b50e94747081ee83666d80ab",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f4646fecfed11f5e2b2ee5c892b2940a",
"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": "f53601899c23c90c2b7e65836c805d8e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "f31b348a7612e5fa3a968f3cc81cefcd",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b8339779a2571b169f9d63c11aa7dfa3",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "511bc23565e830778d5ff183a201579d",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b02faf2aa2df1de233a0549295e6b0ed",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "2e07aaa6d445caf3b33d79dc40bd2475",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "00f50fb4a3a9bbecd1b1188b78abae4b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "88fb67cb3f3752f0b0db1d583f90490d",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "db921cf43e8ebf733712fb5bbc673f66",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "4be0f3a7a88da423847863af41ac9c63",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7c92d738e7cc724de2ca31cb876224e6",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "c2f69ed83f77b602e2a2b2b1c1c78cc6",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b1c766d4ce567f965c53ff2a4c5c85f4",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "86ebbd9111f8a0fe7905cef7aba1f6db",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "8182f4e00ad579eb4c7be5ec1ddca8cb",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "3d9e0e7ad8706133e61fb7f7127c3ff5",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "20373ee90f8987bed980143d5377ae44",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "99d7d247a422eaa46737e3232408e879",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "079c4fd0b6f8aa50510064704466904b",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "216efc77915b75f39f0f15c2806bfbb9",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "204320756307e1833b284c3180e70319",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3e9e4e1761fd763eb584598fc0a3ad0a",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "b8f587f21f39f35072d6c83116c9ae96",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0c92e386ab7406da6a719131321bf592",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "ce48b60be52023e1942cb493bb2f58fb",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "d53ee4e8eed3e1a218db2f927a62c353",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "6597b00a07975230cb3f5b0fa19e0ed4",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "0ff41b8dc440c0490e9ae3bc22c3d201",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "56d6440f62c271c4ce9ef520400395a3",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "56d6440f62c271c4ce9ef520400395a3",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "390a90cf4af1c55662c61ec19f9481bb",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "e55895a55cc40f79be9e2e8095e8adf2",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "390a90cf4af1c55662c61ec19f9481bb",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "e55895a55cc40f79be9e2e8095e8adf2",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "9846a6a3dd3685417fe834b91be8ac74",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "68087f1bac1513e92cabdb59c637e759",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "9846a6a3dd3685417fe834b91be8ac74",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "68087f1bac1513e92cabdb59c637e759",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "72a7370f23c76ed8018999b78d88a545",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "c2cf0dc227e41a826c913d12e117c316",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "fbdc80e41c5883b4a893d2f0786e377f",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "c2cf0dc227e41a826c913d12e117c316",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b04c0e9f0753d99707dc0091f838c724",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "526a6da71fee4e782a5e881cfc747d53",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "9148df22e55a23d1fc5c0674f476af3e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "a46936b72035132ddde1dc166b507d7b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "33595ffc0c36f2280a9215b48284c322",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "432bf79a12258e353a498399d248775f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "6cd33778d0c471e79b252696a22d69ba",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a735a0b19249050d2b6b428be6274c37",
"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,9 +9,9 @@ jobs:
make_linux_x86_64_gui_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -29,9 +29,9 @@ jobs:
make_linux_x86_64_server_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -49,9 +49,9 @@ jobs:
make_linux_arm64_gui_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -69,9 +69,9 @@ jobs:
make_linux_arm64_server_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -89,9 +89,9 @@ jobs:
make_mac_x86_64_gui_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -109,9 +109,9 @@ jobs:
make_mac_x86_64_server_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -129,9 +129,9 @@ jobs:
make_mac_arm64_gui_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -149,9 +149,9 @@ jobs:
make_mac_arm64_server_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -169,9 +169,9 @@ jobs:
make_windows_x86_gui_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -189,9 +189,9 @@ jobs:
make_windows_x86_server_debug_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -206,3 +206,23 @@ jobs:
with:
name: windows_x86_server_(debug)
path: build/prefab/full/windows_x86_server
make_sphinx_docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
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
run: make docs-sphinx
- name: Upload the build
uses: actions/upload-artifact@v3
with:
name: sphinx_html_docs
path: build/sphinx

View File

@ -16,9 +16,9 @@ jobs:
check_linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -33,9 +33,9 @@ jobs:
build_and_test_linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -54,9 +54,9 @@ jobs:
spinoff_test_linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -75,9 +75,9 @@ jobs:
feature_set_copy_test_linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Remove this once we upgrade to 3.12.
@ -102,9 +102,9 @@ jobs:
build_and_test_windows:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies

View File

@ -1,4 +1,4 @@
### 1.7.33 (build 21770, api 8, 2024-03-01)
### 1.7.33 (build 21778, api 8, 2024-03-13)
- 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
@ -21,6 +21,9 @@
catch problems where a base class changes or removes a method and child
classes forget to adapt to the change.
- Added a reset button in the input mapping menu. (Thanks Temp!)
- Respawn icons now have dotted steps showing decimal progress to assist
players on calculating when they are gonna respawn. (Thanks 3alTemp!)
- Replays now have rewind/fast-forward buttons!! (Thanks Dliwk, vishal332008!)
- Custom spaz "curse_time" values now work properly. (Thanks Temp!)
- Implemented `efro.dataclassio.IOMultiType` which will make my life a lot
easier.
@ -30,7 +33,17 @@
brostos!).
- Fixes a bug where Meteor Shower could make the game-end bell sound twice
(Thanks 3alTemp!).
- Leaving the game or dying while touching your team's flag will no longer
recover & return it indefinitely in a teams game of Capture the Flag. (Thanks
3alTemp!)
- Added a server config setting for max players (not max clients) (Thanks
EraOSBeta!)
- Added a UI for customizing Series Length in Teams and Points-to-Win in FFA
(Thanks EraOSBeta!)
- Sphinx based Python documentation generation is now wired up (Thanks
Loup-Garou911XD!)
- Renaming & overwriting existing profiles is no longer possible (Thanks Temp!)
### 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!)
@ -73,7 +86,7 @@
intended. Now, however, such commands get scheduled to a current
'ui-operation' and then run *almost* immediately, which should prevent such
situations. Please holler if you run into any UI weirdness at this point.
### 1.7.30 (build 21697, api 8, 2023-12-08)
- Continued work on the big 1.7.28 update.
- Got the Android version back up and running. There's been lots of cleanup and
@ -350,7 +363,7 @@
- Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when
the text is selected. The default is 'gradient' but there is now a 'uniform'
option which may look better in some circumstances.
### 1.7.27 (build 21282, api 8, 2023-08-30)
- Fixed a rare crash that could occur if the app shuts down while a background
@ -471,7 +484,7 @@
Visual Studio Code (and potentially other editors), so am seeing if it is
worth officially supporting in addition to or as a replacement for Mypy. See
`tools/pcommand pyright`
### 1.7.24 (build 21199, api 8, 2023-07-27)
- Fixed an issue where respawn icons could disappear in epic mode (Thanks for
@ -526,7 +539,7 @@
can be useful for core engine code to directly and clearly point out problems
that cannot be recovered from (Exceptions in such cases can tend to be
'handled' which leads to a broken or crashing app).
### 1.7.23 (build 21178, api 8, 2023-07-19)
- Network security improvements. (Thanks Dliwk!)

View File

@ -37,12 +37,12 @@
- Added feature
### Vishal332008
- Bug Fixer
- QoL and Bug Fixer
- Modder
### Era0S
- Community Suggestions Implementer
- Bug Fixer
- QoL and Bug Fixer
- Modder
### VinniTR
@ -51,8 +51,16 @@
### Rikko
- Created the original "reject_recently_left_players" plugin
### SoK
- Modder
- BSE Heartbeat mechanic port
### Temp (3alTemp)
- Original idea for customizable series length on GUI builds
- Modder & Bug Fixer
### brostos
- Added support for joining using ipv6 address
### Loup Garou
- Added sphinx documentation generation

View File

@ -183,6 +183,14 @@ docs:
docs-pdoc:
@$(PCOMMAND) gen_docs_pdoc
docs-sphinx:
$(MAKE) dummymodules
@$(PCOMMAND) gen_docs_sphinx
docs-sphinx-clean:
rm -rf .cache/sphinx
rm -rf build/sphinx
pcommandbatch_speed_test: prereqs
@$(PCOMMAND) pcommandbatch_speed_test $(PCOMMANDBATCH)

View File

@ -278,6 +278,7 @@ ctx.filter_file_extensions = {
'.xcsettings',
'.xcstrings',
'.filters',
'.rst',
}
# ELSE files with these extensions will NOT be filtered.

View File

@ -4487,6 +4487,8 @@
"pylib-apple/zoneinfo/_common.py",
"pylib-apple/zoneinfo/_tzpath.py",
"pylib-apple/zoneinfo/_zoneinfo.py",
"sphinx/template/__pycache__/conf.cpython-311.opt-1.pyc",
"sphinx/template/conf.py",
"windows/Win32/DLLs/_asyncio.pyd",
"windows/Win32/DLLs/_asyncio_d.pyd",
"windows/Win32/DLLs/_bz2.pyd",

View File

@ -513,6 +513,7 @@
"ba_data/python/bauiv1lib/settings/__pycache__/gamepadselect.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/graphics.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/keyboard.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/moddingtools.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/nettesting.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/plugins.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/pluginsettings.cpython-311.opt-1.pyc",
@ -529,6 +530,7 @@
"ba_data/python/bauiv1lib/settings/gamepadselect.py",
"ba_data/python/bauiv1lib/settings/graphics.py",
"ba_data/python/bauiv1lib/settings/keyboard.py",
"ba_data/python/bauiv1lib/settings/moddingtools.py",
"ba_data/python/bauiv1lib/settings/nettesting.py",
"ba_data/python/bauiv1lib/settings/plugins.py",
"ba_data/python/bauiv1lib/settings/pluginsettings.py",

View File

@ -406,6 +406,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/gamepadselect.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/graphics.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/keyboard.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/moddingtools.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/nettesting.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/plugins.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/pluginsettings.py \
@ -681,6 +682,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/gamepadselect.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/graphics.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/keyboard.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/moddingtools.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/nettesting.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/plugins.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/pluginsettings.cpython-311.opt-1.pyc \
@ -2742,7 +2744,8 @@ SCRIPT_TARGETS_PY_PRIVATE_COMMON = \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/resolver.py \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/scanner.py \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/serializer.py \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/tokens.py
$(BUILD_DIR)/ba_data/python-site-packages/yaml/tokens.py \
$(BUILD_DIR)/sphinx/template/conf.py
SCRIPT_TARGETS_PYC_PRIVATE_COMMON = \
$(BUILD_DIR)/ba_data/python-site-packages/_yaml/__pycache__/__init__.cpython-311.opt-1.pyc \
@ -2766,7 +2769,8 @@ SCRIPT_TARGETS_PYC_PRIVATE_COMMON = \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/__pycache__/resolver.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/__pycache__/scanner.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/__pycache__/serializer.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/__pycache__/tokens.cpython-311.opt-1.pyc
$(BUILD_DIR)/ba_data/python-site-packages/yaml/__pycache__/tokens.cpython-311.opt-1.pyc \
$(BUILD_DIR)/sphinx/template/__pycache__/conf.cpython-311.opt-1.pyc
# Rule to copy src asset scripts to dst.
# (and make non-writable so I'm less likely to accidentally edit them there)

View File

@ -136,7 +136,12 @@ def create_user_system_scripts() -> None:
path = f'{env.python_directory_user}/sys/{env.version}'
pathtmp = path + '_tmp'
if os.path.exists(path):
shutil.rmtree(path)
print('Delete Existing User Scripts first!')
_babase.screenmessage(
'Delete Existing User Scripts first!',
color=(1, 0, 0),
)
return
if os.path.exists(pathtmp):
shutil.rmtree(pathtmp)
@ -159,6 +164,7 @@ def create_user_system_scripts() -> None:
f"'\nRestart {_babase.appname()} to use them."
f' (use babase.quit() to exit the game)'
)
_babase.screenmessage('Created User System Scripts', color=(0, 1, 0))
if app.classic is not None and app.classic.platform == 'android':
print(
'Note: the new files may not be visible via '
@ -183,8 +189,14 @@ def delete_user_system_scripts() -> None:
f'Restart {_babase.appname()} to use internal'
f' scripts. (use babase.quit() to exit the game)'
)
_babase.screenmessage('Deleted User System Scripts', color=(0, 1, 0))
_babase.screenmessage(
f'Restart {_babase.appname()} to take effect.',
color=(0, 1, 0),
)
else:
print(f"User system scripts not found at '{path}'.")
_babase.screenmessage('User Scripts Not Found', color=(1, 0, 0))
# If the sys path is empty, kill it.
dpath = env.python_directory_user + '/sys'

View File

@ -152,9 +152,9 @@ class AccountV1Subsystem:
"""(internal)"""
for entry in info:
cache_entry = self.tournament_info[
entry['tournamentID']
] = copy.deepcopy(entry)
cache_entry = self.tournament_info[entry['tournamentID']] = (
copy.deepcopy(entry)
)
# Also store the time we received this, so we can adjust
# time-remaining values/etc.

View File

@ -75,9 +75,9 @@ class AchievementSubsystem:
def __init__(self) -> None:
self.achievements: list[Achievement] = []
self.achievements_to_display: (
list[tuple[baclassic.Achievement, bool]]
) = []
self.achievements_to_display: list[
tuple[baclassic.Achievement, bool]
] = []
self.achievement_display_timer: bascenev1.BaseTimer | None = None
self.last_achievement_display_time: float = 0.0
self.achievement_completion_banner_slots: set[int] = set()

View File

@ -310,9 +310,7 @@ class ServerController:
typename = (
'teams'
if result['playlistType'] == 'Team Tournament'
else 'ffa'
if result['playlistType'] == 'Free-for-All'
else '??'
else 'ffa' if result['playlistType'] == 'Free-for-All' else '??'
)
plistname = result['playlistName']
print(f'{Clr.SBLU}Got playlist: "{plistname}" ({typename}).{Clr.RST}')
@ -390,14 +388,14 @@ class ServerController:
if sessiontype is bascenev1.FreeForAllSession:
appcfg['Free-for-All Playlist Selection'] = self._playlist_name
appcfg[
'Free-for-All Playlist Randomize'
] = self._config.playlist_shuffle
appcfg['Free-for-All Playlist Randomize'] = (
self._config.playlist_shuffle
)
elif sessiontype is bascenev1.DualTeamSession:
appcfg['Team Tournament Playlist Selection'] = self._playlist_name
appcfg[
'Team Tournament Playlist Randomize'
] = self._config.playlist_shuffle
appcfg['Team Tournament Playlist Randomize'] = (
self._config.playlist_shuffle
)
elif sessiontype is bascenev1.CoopSession:
classic.coop_session_args = {
'campaign': self._config.coop_campaign,
@ -406,6 +404,10 @@ class ServerController:
else:
raise RuntimeError(f'Unknown session type {sessiontype}')
appcfg['Teams Series Length'] = self._config.teams_series_length
appcfg['FFA Series Length'] = self._config.ffa_series_length
# deprecated, left here in order to not break mods
classic.teams_series_length = self._config.teams_series_length
classic.ffa_series_length = self._config.ffa_series_length
@ -427,6 +429,10 @@ class ServerController:
self._config.player_rejoin_cooldown
)
bascenev1.set_max_players_override(
self._config.session_max_players_override
)
# And here.. we.. go.
if self._config.stress_test_players is not None:
# Special case: run a stress test.

View File

@ -103,8 +103,8 @@ class ClassicSubsystem(babase.AppSubsystem):
self.maps: dict[str, type[bascenev1.Map]] = {}
# Gameplay.
self.teams_series_length = 7
self.ffa_series_length = 24
self.teams_series_length = 7 # deprecated, left for old mods
self.ffa_series_length = 24 # deprecated, left for old mods
self.coop_session_args: dict = {}
# UI.

View File

@ -35,9 +35,11 @@ def get_tournament_prize_strings(entry: dict[str, Any]) -> list[str]:
prval = (
''
if rng is None
else ('#' + str(rng[0]))
if (rng[0] == rng[1])
else ('#' + str(rng[0]) + '-' + str(rng[1]))
else (
('#' + str(rng[0]))
if (rng[0] == rng[1])
else ('#' + str(rng[0]) + '-' + str(rng[1]))
)
)
pvval = ''
if trophy_type is not None:

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 = 21770
TARGET_BALLISTICA_BUILD = 21778
TARGET_BALLISTICA_VERSION = '1.7.33'
@ -264,6 +264,10 @@ def _calc_data_dir(data_dir: str | None) -> str:
def _setup_logging() -> LogHandler:
from efro.log import setup_logging, LogLevel
# TODO: should set this up with individual loggers under a top level
# 'ba' logger, and at that point we can kill off the
# suppress_non_root_debug option since we'll only ever need to set
# 'ba' to DEBUG at most.
log_handler = setup_logging(
log_path=None,
level=LogLevel.DEBUG,

View File

@ -57,8 +57,7 @@ class CloudSubsystem(babase.AppSubsystem):
on_response: Callable[
[bacommon.cloud.LoginProxyRequestResponse | Exception], None
],
) -> None:
...
) -> None: ...
@overload
def send_message_cb(
@ -67,24 +66,21 @@ class CloudSubsystem(babase.AppSubsystem):
on_response: Callable[
[bacommon.cloud.LoginProxyStateQueryResponse | Exception], None
],
) -> None:
...
) -> None: ...
@overload
def send_message_cb(
self,
msg: bacommon.cloud.LoginProxyCompleteMessage,
on_response: Callable[[None | Exception], None],
) -> None:
...
) -> None: ...
@overload
def send_message_cb(
self,
msg: bacommon.cloud.PingMessage,
on_response: Callable[[bacommon.cloud.PingResponse | Exception], None],
) -> None:
...
) -> None: ...
@overload
def send_message_cb(
@ -93,8 +89,7 @@ class CloudSubsystem(babase.AppSubsystem):
on_response: Callable[
[bacommon.cloud.SignInResponse | Exception], None
],
) -> None:
...
) -> None: ...
@overload
def send_message_cb(
@ -103,8 +98,7 @@ class CloudSubsystem(babase.AppSubsystem):
on_response: Callable[
[bacommon.cloud.ManageAccountResponse | Exception], None
],
) -> None:
...
) -> None: ...
def send_message_cb(
self,
@ -129,20 +123,17 @@ class CloudSubsystem(babase.AppSubsystem):
@overload
def send_message(
self, msg: bacommon.cloud.WorkspaceFetchMessage
) -> bacommon.cloud.WorkspaceFetchResponse:
...
) -> bacommon.cloud.WorkspaceFetchResponse: ...
@overload
def send_message(
self, msg: bacommon.cloud.MerchAvailabilityMessage
) -> bacommon.cloud.MerchAvailabilityResponse:
...
) -> bacommon.cloud.MerchAvailabilityResponse: ...
@overload
def send_message(
self, msg: bacommon.cloud.TestMessage
) -> bacommon.cloud.TestResponse:
...
) -> bacommon.cloud.TestResponse: ...
def send_message(self, msg: Message) -> Response | None:
"""Synchronously send a message to the cloud.
@ -154,14 +145,12 @@ class CloudSubsystem(babase.AppSubsystem):
@overload
async def send_message_async(
self, msg: bacommon.cloud.PromoCodeMessage
) -> bacommon.cloud.PromoCodeResponse:
...
) -> bacommon.cloud.PromoCodeResponse: ...
@overload
async def send_message_async(
self, msg: bacommon.cloud.TestMessage
) -> bacommon.cloud.TestResponse:
...
) -> bacommon.cloud.TestResponse: ...
async def send_message_async(self, msg: Message) -> Response | None:
"""Synchronously send a message to the cloud.

View File

@ -120,6 +120,7 @@ from _bascenev1 import (
release_keyboard_input,
reset_random_player_names,
resume_replay,
seek_replay,
broadcastmessage,
SessionData,
SessionPlayer,
@ -231,7 +232,11 @@ from bascenev1._settings import (
IntSetting,
Setting,
)
from bascenev1._session import Session, set_player_rejoin_cooldown
from bascenev1._session import (
Session,
set_player_rejoin_cooldown,
set_max_players_override,
)
from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats
from bascenev1._team import SessionTeam, Team, EmptyTeam
from bascenev1._teamgame import TeamGameActivity
@ -400,6 +405,7 @@ __all__ = [
'release_keyboard_input',
'reset_random_player_names',
'resume_replay',
'seek_replay',
'safecolor',
'screenmessage',
'SceneV1AppMode',
@ -426,6 +432,7 @@ __all__ = [
'set_public_party_queue_enabled',
'set_public_party_stats_url',
'set_player_rejoin_cooldown',
'set_max_players_override',
'set_replay_speed_exponent',
'set_touchscreen_editing',
'setmusic',

View File

@ -203,9 +203,11 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
sval = babase.Lstr(resource='pressAnyButtonText')
Text(
self._custom_continue_message
if self._custom_continue_message is not None
else sval,
(
self._custom_continue_message
if self._custom_continue_message is not None
else sval
),
v_attach=Text.VAttach.BOTTOM,
h_align=Text.HAlign.CENTER,
flash=True,

View File

@ -198,12 +198,14 @@ class Actor:
# Overloads to convey our exact return type depending on 'doraise' value.
@overload
def getactivity(self, doraise: Literal[True] = True) -> bascenev1.Activity:
...
def getactivity(
self, doraise: Literal[True] = True
) -> bascenev1.Activity: ...
@overload
def getactivity(self, doraise: Literal[False]) -> bascenev1.Activity | None:
...
def getactivity(
self, doraise: Literal[False]
) -> bascenev1.Activity | None: ...
def getactivity(self, doraise: bool = True) -> bascenev1.Activity | None:
"""Return the bascenev1.Activity this Actor is associated with.

View File

@ -42,9 +42,9 @@ class GameResults:
self._scores: dict[
int, tuple[weakref.ref[bascenev1.SessionTeam], int | None]
] = {}
self._sessionteams: list[
weakref.ref[bascenev1.SessionTeam]
] | None = None
self._sessionteams: list[weakref.ref[bascenev1.SessionTeam]] | None = (
None
)
self._playerinfos: list[bascenev1.PlayerInfo] | None = None
self._lower_is_better: bool | None = None
self._score_label: str | None = None

View File

@ -73,9 +73,11 @@ class Level:
return babase.Lstr(
translate=(
'coopLevelNames',
self._displayname
if self._displayname is not None
else self._name,
(
self._displayname
if self._displayname is not None
else self._name
),
),
subs=[
('${GAME}', self._gametype.get_display_string(self._settings))

View File

@ -67,8 +67,8 @@ class MultiTeamSession(Session):
max_players=self.get_max_players(),
)
self._series_length: int = classic.teams_series_length
self._ffa_series_length: int = classic.ffa_series_length
self._series_length: int = int(cfg.get('Teams Series Length', 7))
self._ffa_series_length: int = int(cfg.get('FFA Series Length', 24))
show_tutorial = cfg.get('Show Tutorial', True)

View File

@ -89,18 +89,18 @@ def filter_playlist(
'bs_king_of_the_hill.KingOfTheHillGame',
'bastd.game.kingofthehill.KingOfTheHillGame',
):
entry[
'type'
] = 'bascenev1lib.game.kingofthehill.KingOfTheHillGame'
entry['type'] = (
'bascenev1lib.game.kingofthehill.KingOfTheHillGame'
)
if entry['type'] in (
'Capture_the_Flag.CTFGame',
'bsCaptureTheFlag.CTFGame',
'bs_capture_the_flag.CTFGame',
'bastd.game.capturetheflag.CaptureTheFlagGame',
):
entry[
'type'
] = 'bascenev1lib.game.capturetheflag.CaptureTheFlagGame'
entry['type'] = (
'bascenev1lib.game.capturetheflag.CaptureTheFlagGame'
)
if entry['type'] in (
'Death_Match.DeathMatchGame',
'bsDeathMatch.DeathMatchGame',
@ -163,25 +163,25 @@ def filter_playlist(
'bs_easter_egg_hunt.EasterEggHuntGame',
'bastd.game.easteregghunt.EasterEggHuntGame',
):
entry[
'type'
] = 'bascenev1lib.game.easteregghunt.EasterEggHuntGame'
entry['type'] = (
'bascenev1lib.game.easteregghunt.EasterEggHuntGame'
)
if entry['type'] in (
'bsMeteorShower.MeteorShowerGame',
'bs_meteor_shower.MeteorShowerGame',
'bastd.game.meteorshower.MeteorShowerGame',
):
entry[
'type'
] = 'bascenev1lib.game.meteorshower.MeteorShowerGame'
entry['type'] = (
'bascenev1lib.game.meteorshower.MeteorShowerGame'
)
if entry['type'] in (
'bsTargetPractice.TargetPracticeGame',
'bs_target_practice.TargetPracticeGame',
'bastd.game.targetpractice.TargetPracticeGame',
):
entry[
'type'
] = 'bascenev1lib.game.targetpractice.TargetPracticeGame'
entry['type'] = (
'bascenev1lib.game.targetpractice.TargetPracticeGame'
)
gameclass = babase.getclass(entry['type'], GameActivity)

View File

@ -23,6 +23,9 @@ if TYPE_CHECKING:
# such as skipping respawn waits.
_g_player_rejoin_cooldown: float = 0.0
# overrides the session's decision of max_players
_max_players_override: int | None = None
def set_player_rejoin_cooldown(cooldown: float) -> None:
"""Set the cooldown for individual players rejoining after leaving."""
@ -30,6 +33,12 @@ def set_player_rejoin_cooldown(cooldown: float) -> None:
_g_player_rejoin_cooldown = max(0.0, cooldown)
def set_max_players_override(max_players: int | None) -> None:
"""Set the override for how many players can join a session"""
global _max_players_override # pylint: disable=global-statement
_max_players_override = max_players
class Session:
"""Defines a high level series of bascenev1.Activity-es.
@ -161,7 +170,11 @@ class Session:
self.sessionteams = []
self.sessionplayers = []
self.min_players = min_players
self.max_players = max_players
self.max_players = (
max_players
if _max_players_override is None
else _max_players_override
)
self.customdata = {}
self._in_set_activity = False
@ -255,7 +268,7 @@ class Session:
babase.app.classic is not None
and babase.app.classic.stress_test_update_timer is None
):
if len(self.sessionplayers) >= self.max_players:
if len(self.sessionplayers) >= self.max_players >= 0:
# Print a rejection message *only* to the client trying to
# join (prevents spamming everyone else in the game).
_bascenev1.getsound('error').play()

View File

@ -395,11 +395,15 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
color=(0.45, 0.4, 0.5),
position=(160, v_offs + 480),
size=(350, 62),
label=bui.Lstr(resource='tournamentStandingsText')
if self.session.tournament_id is not None
else bui.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bui.Lstr(resource='worldsBestTimesText'),
label=(
bui.Lstr(resource='tournamentStandingsText')
if self.session.tournament_id is not None
else (
bui.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bui.Lstr(resource='worldsBestTimesText')
)
),
autoselect=True,
on_activate_call=bui.WeakCall(self._ui_worlds_best),
transition_delay=delay + 1.9,
@ -515,9 +519,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
bui.containerwidget(
edit=rootc,
selected_child=next_button
if (self._newly_complete and self._victory and show_next_button)
else restart_button,
selected_child=(
next_button
if (self._newly_complete and self._victory and show_next_button)
else restart_button
),
on_cancel_call=menu_button.activate,
)
@ -644,14 +650,16 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
and not (env.demo or env.arcade)
):
Text(
bs.Lstr(
value='${A}:\n',
subs=[('${A}', bs.Lstr(resource='levelUnlockedText'))],
)
if self._newly_complete
else bs.Lstr(
value='${A}:\n',
subs=[('${A}', bs.Lstr(resource='nextLevelText'))],
(
bs.Lstr(
value='${A}:\n',
subs=[('${A}', bs.Lstr(resource='levelUnlockedText'))],
)
if self._newly_complete
else bs.Lstr(
value='${A}:\n',
subs=[('${A}', bs.Lstr(resource='nextLevelText'))],
)
),
transition=Text.Transition.IN_RIGHT,
transition_delay=5.2,
@ -860,11 +868,15 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
ts_h_offs = 210
v_offs = 40
txt = Text(
bs.Lstr(resource='tournamentStandingsText')
if self.session.tournament_id is not None
else bs.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bs.Lstr(resource='worldsBestTimesText'),
(
bs.Lstr(resource='tournamentStandingsText')
if self.session.tournament_id is not None
else (
bs.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bs.Lstr(resource='worldsBestTimesText')
)
),
maxwidth=210,
position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20),
transition=Text.Transition.IN_LEFT,
@ -882,9 +894,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
ts_h_offs = -480
v_offs = 40
Text(
bs.Lstr(resource='yourBestScoresText')
if self._score_type == 'points'
else bs.Lstr(resource='yourBestTimesText'),
(
bs.Lstr(resource='yourBestScoresText')
if self._score_type == 'points'
else bs.Lstr(resource='yourBestTimesText')
),
maxwidth=210,
position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20),
transition=Text.Transition.IN_RIGHT,
@ -948,9 +962,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
tdelay1 = times[i][0]
tdelay2 = times[i][1]
Text(
str(display_scores[i][0])
if self._score_type == 'points'
else bs.timestring((display_scores[i][0] * 10) / 1000.0),
(
str(display_scores[i][0])
if self._score_type == 'points'
else bs.timestring((display_scores[i][0] * 10) / 1000.0)
),
position=(
ts_h_offs + 20 + h_offs_extra,
v_offs_extra
@ -1127,9 +1143,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
tdelay2 = times[i][1]
if name_str != '-':
Text(
str(score)
if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0),
(
str(score)
if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0)
),
position=(
ts_h_offs + 20 + h_offs_extra,
v_offs_extra
@ -1313,9 +1331,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
if name_str != '-':
Text(
str(score)
if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0),
(
str(score)
if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0)
),
position=(
ts_h_offs + 20 + h_offs_extra,
ts_height / 2
@ -1689,17 +1709,22 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
)
if not self._newly_complete:
Text(
bs.Lstr(
value='${A}${B}',
subs=[
('${A}', bs.Lstr(resource='newPersonalBestText')),
('${B}', was_string),
],
)
if new_best
else bs.Lstr(
resource='bestRatingText',
subs=[('${RATING}', str(best_rank))],
(
bs.Lstr(
value='${A}${B}',
subs=[
(
'${A}',
bs.Lstr(resource='newPersonalBestText'),
),
('${B}', was_string),
],
)
if new_best
else bs.Lstr(
resource='bestRatingText',
subs=[('${RATING}', str(best_rank))],
)
),
position=(0, -165),
color=(1, 1, 1, 0.7),
@ -1773,14 +1798,16 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
jitter=1.0,
).autoretain()
Text(
bs.Lstr(
value='${A}:',
subs=[('${A}', bs.Lstr(resource='finalScoreText'))],
)
if self._score_type == 'points'
else bs.Lstr(
value='${A}:',
subs=[('${A}', bs.Lstr(resource='finalTimeText'))],
(
bs.Lstr(
value='${A}:',
subs=[('${A}', bs.Lstr(resource='finalScoreText'))],
)
if self._score_type == 'points'
else bs.Lstr(
value='${A}:',
subs=[('${A}', bs.Lstr(resource='finalTimeText'))],
)
),
maxwidth=300,
position=(0, 200),

View File

@ -199,9 +199,9 @@ class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity):
ts_v_offset + (voffs + 15) * scale,
),
scale=scale,
color=(1.0, 0.9, 0.5, 1.0)
if highlight
else (0.5, 0.5, 0.6, 0.5),
color=(
(1.0, 0.9, 0.5, 1.0) if highlight else (0.5, 0.5, 0.6, 0.5)
),
h_align=Text.HAlign.RIGHT,
v_align=Text.VAlign.CENTER,
maxwidth=maxwidth,

View File

@ -374,9 +374,11 @@ class TeamSeriesVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
tdelay -= 4 * t_incr
v_offs -= 40
Text(
str(prec.team.customdata['score'])
if self._is_ffa
else str(prec.score),
(
str(prec.team.customdata['score'])
if self._is_ffa
else str(prec.score)
),
color=(0.5, 0.5, 0.5, 1.0),
position=(ts_h_offs + 230, ts_height / 2 + v_offs),
h_align=Text.HAlign.RIGHT,

View File

@ -456,9 +456,11 @@ class ControlsGuide(bs.Actor):
(
'${B}',
bs.Lstr(
resource='holdAnyKeyText'
if all_keyboards
else 'holdAnyButtonText'
resource=(
'holdAnyKeyText'
if all_keyboards
else 'holdAnyButtonText'
)
),
),
],

View File

@ -79,14 +79,12 @@ class PlayerSpaz(Spaz):
@overload
def getplayer(
self, playertype: type[PlayerT], doraise: Literal[False] = False
) -> PlayerT | None:
...
) -> PlayerT | None: ...
@overload
def getplayer(
self, playertype: type[PlayerT], doraise: Literal[True]
) -> PlayerT:
...
) -> PlayerT: ...
def getplayer(
self, playertype: type[PlayerT], doraise: bool = False

View File

@ -22,7 +22,9 @@ class RespawnIcon:
def __init__(self, player: bs.Player, respawn_time: float):
"""Instantiate with a Player and respawn_time (in seconds)."""
# pylint: disable=too-many-locals
self._visible = True
self._dots_epic_only = False
on_right, offs_extra, respawn_icons = self._get_context(player)
@ -92,7 +94,7 @@ class RespawnIcon:
assert self._name.node
bs.animate(self._name.node, 'scale', {0: 0, 0.1: 0.5})
tpos = (-60 - h_offs if on_right else 60 + h_offs, -192 + offs)
tpos = (-60 - h_offs if on_right else 60 + h_offs, -193 + offs)
self._text: bs.NodeActor | None = bs.NodeActor(
bs.newnode(
'text',
@ -109,11 +111,37 @@ class RespawnIcon:
},
)
)
dpos = [ipos[0] + (7 if on_right else -7), ipos[1] - 16]
self._dec_text: bs.NodeActor | None = None
if (
self._dots_epic_only
and bs.getactivity().globalsnode.slow_motion
or not self._dots_epic_only
):
self._dec_text = bs.NodeActor(
bs.newnode(
'text',
attrs={
'position': dpos,
'h_attach': 'right' if on_right else 'left',
'h_align': 'right' if on_right else 'left',
'scale': 0.65,
'shadow': 0.5,
'flatness': 0.5,
'v_attach': 'top',
'color': bs.safecolor(icon['tint_color']),
'text': '',
},
)
)
assert self._text.node
bs.animate(self._text.node, 'scale', {0: 0, 0.1: 0.9})
if self._dec_text:
bs.animate(self._dec_text.node, 'scale', {0: 0, 0.1: 0.65})
self._respawn_time = bs.time() + respawn_time
self._dec_timer: bs.Timer | None = None
self._update()
self._timer: bs.Timer | None = bs.Timer(
1.0, bs.WeakCall(self._update), repeat=True
@ -128,7 +156,7 @@ class RespawnIcon:
"""Return info on where we should be shown and stored."""
activity = bs.getactivity()
if isinstance(bs.getsession(), bs.DualTeamSession):
if isinstance(activity.session, bs.DualTeamSession):
on_right = player.team.id % 2 == 1
# Store a list of icons in the team.
@ -153,12 +181,43 @@ class RespawnIcon:
offs_extra = -20
return on_right, offs_extra, icons
def _dec_step(self, display: list) -> None:
if not self._dec_text:
self._dec_timer = None
return
old_text: bs.Lstr | str = self._dec_text.node.text
iterate: int
# Get the following display text using our current one.
try:
iterate = display.index(old_text) + 1
# If we don't match any in the display list, we
# can assume we've just started iterating.
except ValueError:
iterate = 0
# Kill the timer if we're at the last iteration.
if iterate >= len(display):
self._dec_timer = None
return
self._dec_text.node.text = display[iterate]
def _update(self) -> None:
remaining = int(round(self._respawn_time - bs.time()))
if remaining > 0:
assert self._text is not None
if self._text.node:
self._text.node.text = str(remaining)
if self._dec_text:
# Display our decimal dots.
self._dec_text.node.text = '...'
# Start the timer to tick down.
self._dec_timer = bs.Timer(
0.25,
bs.WeakCall(self._dec_step, ['..', '.', '']),
repeat=True,
)
else:
self._visible = False
self._image = self._text = self._timer = self._name = None
self._image = self._text = self._dec_text = self._timer = (
self._name
) = None

View File

@ -776,7 +776,6 @@ class ChargerBotPro(ChargerBot):
color = PRO_BOT_COLOR
highlight = PRO_BOT_HIGHLIGHT
default_shields = True
default_boxing_gloves = True
points_mult = 3

View File

@ -73,9 +73,11 @@ class TipsText(bs.Actor):
next_tip = bs.Lstr(
translate=(
'tips',
bs.app.classic.get_next_tip()
if bs.app.classic is not None
else '',
(
bs.app.classic.get_next_tip()
if bs.app.classic is not None
else ''
),
),
subs=[('${REMOTE_APP_NAME}', get_remote_app_name())],
)

View File

@ -529,6 +529,30 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
if team.flag_return_touches < 0:
logging.exception('CTF flag_return_touches < 0')
def _handle_death_flag_capture(self, player: Player) -> None:
"""Handles flag values when a player dies or leaves the game."""
# Don't do anything if the player hasn't touched the flag at all.
if not player.touching_own_flag:
return
team = player.team
# For each "point" our player has touched theflag (Could be multiple),
# deduct one from both our player and
# the flag's return touches variable.
for _ in range(player.touching_own_flag):
# Deduct
player.touching_own_flag -= 1
team.flag_return_touches -= 1
# Update our flag's timer accordingly
# (Prevents immediate resets in case
# there might be more people touching it).
if team.flag_return_touches == 0:
team.touch_return_timer = None
team.touch_return_timer_ticking = None
# Safety check, just to be sure!
if team.flag_return_touches < 0:
logging.exception('CTF flag_return_touches < 0')
def _flash_base(self, team: Team, length: float = 2.0) -> None:
light = bs.newnode(
'light',
@ -591,6 +615,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
def handlemessage(self, msg: Any) -> Any:
if isinstance(msg, bs.PlayerDiedMessage):
super().handlemessage(msg) # Augment standard behavior.
self._handle_death_flag_capture(msg.getplayer(Player))
self.respawn_player(msg.getplayer(Player))
elif isinstance(msg, FlagDiedMessage):
@ -617,3 +642,8 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
else:
super().handlemessage(msg)
@override
def on_player_leave(self, player: Player) -> None:
"""Prevents leaving players from capturing their flag."""
self._handle_death_flag_capture(player)

View File

@ -334,29 +334,37 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Wave(
base_angle=130,
entries=[
Spawn(BrawlerBotLite, spacing=5)
if player_count > 1
else None,
(
Spawn(BrawlerBotLite, spacing=5)
if player_count > 1
else None
),
Spawn(BrawlerBotLite, spacing=5),
Spacing(30),
Spawn(BomberBotLite, spacing=5)
if player_count > 3
else None,
(
Spawn(BomberBotLite, spacing=5)
if player_count > 3
else None
),
Spawn(BomberBotLite, spacing=5),
Spacing(30),
Spawn(BrawlerBotLite, spacing=5),
Spawn(BrawlerBotLite, spacing=5)
if player_count > 2
else None,
(
Spawn(BrawlerBotLite, spacing=5)
if player_count > 2
else None
),
],
),
Wave(
base_angle=195,
entries=[
Spawn(TriggerBot, spacing=90),
Spawn(TriggerBot, spacing=90)
if player_count > 1
else None,
(
Spawn(TriggerBot, spacing=90)
if player_count > 1
else None
),
],
),
]
@ -367,9 +375,11 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
self._waves = [
Wave(
entries=[
Spawn(ChargerBot, Point.LEFT_UPPER_MORE)
if player_count > 2
else None,
(
Spawn(ChargerBot, Point.LEFT_UPPER_MORE)
if player_count > 2
else None
),
Spawn(ChargerBot, Point.LEFT_UPPER),
]
),
@ -377,36 +387,50 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
entries=[
Spawn(BomberBotStaticLite, Point.TURRET_TOP_RIGHT),
Spawn(BrawlerBotLite, Point.RIGHT_UPPER),
Spawn(BrawlerBotLite, Point.RIGHT_LOWER)
if player_count > 1
else None,
Spawn(BomberBotStaticLite, Point.TURRET_BOTTOM_RIGHT)
if player_count > 2
else None,
(
Spawn(BrawlerBotLite, Point.RIGHT_LOWER)
if player_count > 1
else None
),
(
Spawn(
BomberBotStaticLite, Point.TURRET_BOTTOM_RIGHT
)
if player_count > 2
else None
),
]
),
Wave(
entries=[
Spawn(BomberBotStaticLite, Point.TURRET_BOTTOM_LEFT),
Spawn(TriggerBot, Point.LEFT),
Spawn(TriggerBot, Point.LEFT_LOWER)
if player_count > 1
else None,
Spawn(TriggerBot, Point.LEFT_UPPER)
if player_count > 2
else None,
(
Spawn(TriggerBot, Point.LEFT_LOWER)
if player_count > 1
else None
),
(
Spawn(TriggerBot, Point.LEFT_UPPER)
if player_count > 2
else None
),
]
),
Wave(
entries=[
Spawn(BrawlerBotLite, Point.TOP_RIGHT),
Spawn(BrawlerBot, Point.TOP_HALF_RIGHT)
if player_count > 1
else None,
(
Spawn(BrawlerBot, Point.TOP_HALF_RIGHT)
if player_count > 1
else None
),
Spawn(BrawlerBotLite, Point.TOP_LEFT),
Spawn(BrawlerBotLite, Point.TOP_HALF_LEFT)
if player_count > 2
else None,
(
Spawn(BrawlerBotLite, Point.TOP_HALF_LEFT)
if player_count > 2
else None
),
Spawn(BrawlerBot, Point.TOP),
Spawn(BomberBotStaticLite, Point.TURRET_TOP_MIDDLE),
]
@ -416,12 +440,16 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Spawn(TriggerBotStatic, Point.TURRET_BOTTOM_LEFT),
Spawn(TriggerBotStatic, Point.TURRET_BOTTOM_RIGHT),
Spawn(TriggerBot, Point.BOTTOM),
Spawn(TriggerBot, Point.BOTTOM_HALF_RIGHT)
if player_count > 1
else None,
Spawn(TriggerBot, Point.BOTTOM_HALF_LEFT)
if player_count > 2
else None,
(
Spawn(TriggerBot, Point.BOTTOM_HALF_RIGHT)
if player_count > 1
else None
),
(
Spawn(TriggerBot, Point.BOTTOM_HALF_LEFT)
if player_count > 2
else None
),
]
),
Wave(
@ -429,12 +457,16 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Spawn(BomberBotStaticLite, Point.TURRET_TOP_LEFT),
Spawn(BomberBotStaticLite, Point.TURRET_TOP_RIGHT),
Spawn(ChargerBot, Point.BOTTOM),
Spawn(ChargerBot, Point.BOTTOM_HALF_LEFT)
if player_count > 1
else None,
Spawn(ChargerBot, Point.BOTTOM_HALF_RIGHT)
if player_count > 2
else None,
(
Spawn(ChargerBot, Point.BOTTOM_HALF_LEFT)
if player_count > 1
else None
),
(
Spawn(ChargerBot, Point.BOTTOM_HALF_RIGHT)
if player_count > 2
else None
),
]
),
]
@ -446,44 +478,62 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Wave(
base_angle=-50,
entries=[
Spawn(BrawlerBot, spacing=12)
if player_count > 3
else None,
(
Spawn(BrawlerBot, spacing=12)
if player_count > 3
else None
),
Spawn(BrawlerBot, spacing=12),
Spawn(BomberBot, spacing=6),
Spawn(BomberBot, spacing=6)
if self._preset is Preset.PRO
else None,
Spawn(BomberBot, spacing=6)
if player_count > 1
else None,
(
Spawn(BomberBot, spacing=6)
if self._preset is Preset.PRO
else None
),
(
Spawn(BomberBot, spacing=6)
if player_count > 1
else None
),
Spawn(BrawlerBot, spacing=12),
Spawn(BrawlerBot, spacing=12)
if player_count > 2
else None,
(
Spawn(BrawlerBot, spacing=12)
if player_count > 2
else None
),
],
),
Wave(
base_angle=180,
entries=[
Spawn(BrawlerBot, spacing=6)
if player_count > 3
else None,
Spawn(BrawlerBot, spacing=6)
if self._preset is Preset.PRO
else None,
(
Spawn(BrawlerBot, spacing=6)
if player_count > 3
else None
),
(
Spawn(BrawlerBot, spacing=6)
if self._preset is Preset.PRO
else None
),
Spawn(BrawlerBot, spacing=6),
Spawn(ChargerBot, spacing=45),
Spawn(ChargerBot, spacing=45)
if player_count > 1
else None,
(
Spawn(ChargerBot, spacing=45)
if player_count > 1
else None
),
Spawn(BrawlerBot, spacing=6),
Spawn(BrawlerBot, spacing=6)
if self._preset is Preset.PRO
else None,
Spawn(BrawlerBot, spacing=6)
if player_count > 2
else None,
(
Spawn(BrawlerBot, spacing=6)
if self._preset is Preset.PRO
else None
),
(
Spawn(BrawlerBot, spacing=6)
if player_count > 2
else None
),
],
),
Wave(
@ -492,15 +542,21 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Spawn(ChargerBot, spacing=30),
Spawn(TriggerBot, spacing=30),
Spawn(TriggerBot, spacing=30),
Spawn(TriggerBot, spacing=30)
if self._preset is Preset.PRO
else None,
Spawn(TriggerBot, spacing=30)
if player_count > 1
else None,
Spawn(TriggerBot, spacing=30)
if player_count > 3
else None,
(
Spawn(TriggerBot, spacing=30)
if self._preset is Preset.PRO
else None
),
(
Spawn(TriggerBot, spacing=30)
if player_count > 1
else None
),
(
Spawn(TriggerBot, spacing=30)
if player_count > 3
else None
),
Spawn(ChargerBot, spacing=30),
],
),
@ -508,16 +564,22 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
base_angle=90,
entries=[
Spawn(StickyBot, spacing=50),
Spawn(StickyBot, spacing=50)
if self._preset is Preset.PRO
else None,
(
Spawn(StickyBot, spacing=50)
if self._preset is Preset.PRO
else None
),
Spawn(StickyBot, spacing=50),
Spawn(StickyBot, spacing=50)
if player_count > 1
else None,
Spawn(StickyBot, spacing=50)
if player_count > 3
else None,
(
Spawn(StickyBot, spacing=50)
if player_count > 1
else None
),
(
Spawn(StickyBot, spacing=50)
if player_count > 3
else None
),
],
),
Wave(
@ -525,14 +587,18 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
entries=[
Spawn(TriggerBot, spacing=72),
Spawn(TriggerBot, spacing=72),
Spawn(TriggerBot, spacing=72)
if self._preset is Preset.PRO
else None,
(
Spawn(TriggerBot, spacing=72)
if self._preset is Preset.PRO
else None
),
Spawn(TriggerBot, spacing=72),
Spawn(TriggerBot, spacing=72),
Spawn(TriggerBot, spacing=36)
if player_count > 2
else None,
(
Spawn(TriggerBot, spacing=36)
if player_count > 2
else None
),
],
),
Wave(
@ -540,15 +606,21 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
entries=[
Spawn(ChargerBotProShielded, spacing=50),
Spawn(ChargerBotProShielded, spacing=50),
Spawn(ChargerBotProShielded, spacing=50)
if self._preset is Preset.PRO
else None,
Spawn(ChargerBotProShielded, spacing=50)
if player_count > 1
else None,
Spawn(ChargerBotProShielded, spacing=50)
if player_count > 2
else None,
(
Spawn(ChargerBotProShielded, spacing=50)
if self._preset is Preset.PRO
else None
),
(
Spawn(ChargerBotProShielded, spacing=50)
if player_count > 1
else None
),
(
Spawn(ChargerBotProShielded, spacing=50)
if player_count > 2
else None
),
],
),
]
@ -566,15 +638,21 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
self._waves = [
Wave(
entries=[
Spawn(BomberBotProStatic, Point.TURRET_TOP_MIDDLE_LEFT)
if hard
else None,
(
Spawn(
BomberBotProStatic, Point.TURRET_TOP_MIDDLE_LEFT
)
if hard
else None
),
Spawn(
BomberBotProStatic, Point.TURRET_TOP_MIDDLE_RIGHT
),
Spawn(BomberBotProStatic, Point.TURRET_TOP_LEFT)
if player_count > 2
else None,
(
Spawn(BomberBotProStatic, Point.TURRET_TOP_LEFT)
if player_count > 2
else None
),
Spawn(ExplodeyBot, Point.TOP_RIGHT),
Delay(4.0),
Spawn(ExplodeyBot, Point.TOP_LEFT),
@ -584,9 +662,11 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
entries=[
Spawn(ChargerBot, Point.LEFT),
Spawn(ChargerBot, Point.RIGHT),
Spawn(ChargerBot, Point.RIGHT_UPPER_MORE)
if player_count > 2
else None,
(
Spawn(ChargerBot, Point.RIGHT_UPPER_MORE)
if player_count > 2
else None
),
Spawn(BomberBotProStatic, Point.TURRET_TOP_LEFT),
Spawn(BomberBotProStatic, Point.TURRET_TOP_RIGHT),
]
@ -594,29 +674,39 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Wave(
entries=[
Spawn(TriggerBotPro, Point.TOP_RIGHT),
Spawn(TriggerBotPro, Point.RIGHT_UPPER_MORE)
if player_count > 1
else None,
(
Spawn(TriggerBotPro, Point.RIGHT_UPPER_MORE)
if player_count > 1
else None
),
Spawn(TriggerBotPro, Point.RIGHT_UPPER),
Spawn(TriggerBotPro, Point.RIGHT_LOWER)
if hard
else None,
Spawn(TriggerBotPro, Point.RIGHT_LOWER_MORE)
if player_count > 2
else None,
(
Spawn(TriggerBotPro, Point.RIGHT_LOWER)
if hard
else None
),
(
Spawn(TriggerBotPro, Point.RIGHT_LOWER_MORE)
if player_count > 2
else None
),
Spawn(TriggerBotPro, Point.BOTTOM_RIGHT),
]
),
Wave(
entries=[
Spawn(ChargerBotProShielded, Point.BOTTOM_RIGHT),
Spawn(ChargerBotProShielded, Point.BOTTOM)
if player_count > 2
else None,
(
Spawn(ChargerBotProShielded, Point.BOTTOM)
if player_count > 2
else None
),
Spawn(ChargerBotProShielded, Point.BOTTOM_LEFT),
Spawn(ChargerBotProShielded, Point.TOP)
if hard
else None,
(
Spawn(ChargerBotProShielded, Point.TOP)
if hard
else None
),
Spawn(BomberBotProStatic, Point.TURRET_TOP_MIDDLE),
]
),
@ -643,12 +733,21 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
Spawn(BomberBotProStatic, Point.TURRET_TOP_RIGHT),
Spawn(BomberBotProStatic, Point.TURRET_BOTTOM_LEFT),
Spawn(BomberBotProStatic, Point.TURRET_BOTTOM_RIGHT),
Spawn(BomberBotProStatic, Point.TURRET_TOP_MIDDLE_LEFT)
if hard
else None,
Spawn(BomberBotProStatic, Point.TURRET_TOP_MIDDLE_RIGHT)
if hard
else None,
(
Spawn(
BomberBotProStatic, Point.TURRET_TOP_MIDDLE_LEFT
)
if hard
else None
),
(
Spawn(
BomberBotProStatic,
Point.TURRET_TOP_MIDDLE_RIGHT,
)
if hard
else None
),
]
),
]
@ -667,12 +766,14 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
# Spit out a few powerups and start dropping more shortly.
self._drop_powerups(
standard_points=True,
poweruptype='curse'
if self._preset in [Preset.UBER, Preset.UBER_EASY]
else (
'land_mines'
if self._preset in [Preset.ROOKIE, Preset.ROOKIE_EASY]
else None
poweruptype=(
'curse'
if self._preset in [Preset.UBER, Preset.UBER_EASY]
else (
'land_mines'
if self._preset in [Preset.ROOKIE, Preset.ROOKIE_EASY]
else None
)
),
)
bs.timer(4.0, self._start_powerup_drops)

View File

@ -778,9 +778,11 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
assert self._timer is not None
if self._timer.has_started():
self._timer.stop(
endtime=None
if self._last_team_time is None
else (self._timer.getstarttime() + self._last_team_time)
endtime=(
None
if self._last_team_time is None
else (self._timer.getstarttime() + self._last_team_time)
)
)
results = bs.GameResults()

View File

@ -14,7 +14,7 @@ import random
import logging
from enum import Enum
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, cast, Sequence
from typing_extensions import override
import bascenev1 as bs
@ -45,7 +45,7 @@ from bascenev1lib.actor.spazbot import (
)
if TYPE_CHECKING:
from typing import Any, Sequence
from typing import Any
class Preset(Enum):
@ -190,6 +190,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
self._lives_text: bs.NodeActor | None = None
self._flawless = True
self._time_bonus_timer: bs.Timer | None = None
self._lives_hbtime: bs.Timer | None = None
self._time_bonus_text: bs.NodeActor | None = None
self._time_bonus_mult: float | None = None
self._wave_text: bs.NodeActor | None = None
@ -279,9 +280,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spacing(duration=1.0),
Spawn(TriggerBot, path=3),
Spacing(duration=1.0),
Spawn(TriggerBot, path=1)
if (player_count > 1 and hard)
else None,
(
Spawn(TriggerBot, path=1)
if (player_count > 1 and hard)
else None
),
Spacing(duration=1.0),
Spawn(TriggerBot, path=2) if player_count > 2 else None,
Spacing(duration=1.0),
@ -320,17 +323,23 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1) if hard else None,
Spacing(duration=1.5) if hard else None,
Spawn(BomberBotProShielded, path=3)
if player_count > 1
else None,
(
Spawn(BomberBotProShielded, path=3)
if player_count > 1
else None
),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=2)
if player_count > 2
else None,
(
Spawn(BomberBotProShielded, path=2)
if player_count > 2
else None
),
Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1)
if player_count > 3
else None,
(
Spawn(BomberBotProShielded, path=1)
if player_count > 3
else None
),
]
),
]
@ -352,9 +361,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
BrawlerBotPro if hard else BrawlerBot,
point=Point.BOTTOM_LEFT,
),
Spawn(BrawlerBotPro, point=Point.BOTTOM_RIGHT)
if player_count > 2
else None,
(
Spawn(BrawlerBotPro, point=Point.BOTTOM_RIGHT)
if player_count > 2
else None
),
]
),
Wave(
@ -375,9 +386,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spawn(BomberBotProShielded, path=3),
Spawn(BomberBotProShielded, path=3),
Spawn(ChargerBot, point=Point.BOTTOM_RIGHT),
Spawn(ChargerBot, point=Point.BOTTOM_LEFT)
if player_count > 2
else None,
(
Spawn(ChargerBot, point=Point.BOTTOM_LEFT)
if player_count > 2
else None
),
]
),
Wave(
@ -388,12 +401,16 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2),
Spawn(TriggerBotPro, path=1 if hard else 2)
if player_count > 1
else None,
Spawn(TriggerBotPro, path=1 if hard else 2)
if player_count > 3
else None,
(
Spawn(TriggerBotPro, path=1 if hard else 2)
if player_count > 1
else None
),
(
Spawn(TriggerBotPro, path=1 if hard else 2)
if player_count > 3
else None
),
]
),
Wave(
@ -402,12 +419,20 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
TriggerBotProShielded if hard else TriggerBotPro,
point=Point.BOTTOM_LEFT,
),
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT)
if hard
else None,
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT)
if player_count > 2
else None,
(
Spawn(
TriggerBotProShielded, point=Point.BOTTOM_RIGHT
)
if hard
else None
),
(
Spawn(
TriggerBotProShielded, point=Point.BOTTOM_RIGHT
)
if player_count > 2
else None
),
Spawn(BomberBot, path=3),
Spawn(BomberBot, path=3),
Spacing(duration=5.0),
@ -425,15 +450,19 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spawn(StickyBot, point=Point.BOTTOM_RIGHT),
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2),
Spawn(StickyBot, point=Point.BOTTOM_RIGHT)
if player_count > 2
else None,
(
Spawn(StickyBot, point=Point.BOTTOM_RIGHT)
if player_count > 2
else None
),
Spawn(BomberBotProShielded, path=2),
Spawn(ExplodeyBot, point=Point.BOTTOM_LEFT),
Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2)
if player_count > 1
else None,
(
Spawn(BomberBotProShielded, path=2)
if player_count > 1
else None
),
Spacing(duration=5.0),
Spawn(StickyBot, point=Point.BOTTOM_LEFT),
Spacing(duration=2.0),
@ -461,9 +490,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
l_offs = (
-80
if uiscale is bs.UIScale.SMALL
else -40
if uiscale is bs.UIScale.MEDIUM
else 0
else -40 if uiscale is bs.UIScale.MEDIUM else 0
)
self._lives_bg = bs.NodeActor(
@ -525,6 +552,18 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
if self._lives == 0:
self._bots.stop_moving()
self.continue_or_end_game()
# Heartbeat behavior
if self._lives < 5:
hbtime = 0.39 + (0.21 * self._lives)
self._lives_hbtime = bs.Timer(
hbtime, lambda: self.heart_dyin(True, hbtime), repeat=True
)
self.heart_dyin(True)
else:
self._lives_hbtime = None
self.heart_dyin(False)
assert self._lives_text is not None
assert self._lives_text.node
self._lives_text.node.text = str(self._lives)
@ -1366,3 +1405,43 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
def _set_can_end_wave(self) -> None:
self._can_end_wave = True
def heart_dyin(self, status: bool, time: float = 1.22) -> None:
"""Makes the UI heart beat at low health."""
assert self._lives_bg is not None
if self._lives_bg.node.exists():
return
heart = self._lives_bg.node
# Make the heart beat intensely!
if status:
bs.animate_array(
heart,
'scale',
2,
{
0: (90, 90),
time * 0.1: (105, 105),
time * 0.21: (88, 88),
time * 0.42: (90, 90),
time * 0.52: (105, 105),
time * 0.63: (88, 88),
time: (90, 90),
},
)
# Neutralize heartbeat (Done did when dead.)
else:
# Ew; janky old scenev1 has a single 'Node' Python type so
# it thinks heart.scale could be a few different things
# (float, Sequence[float], etc.). So we have to force the
# issue with a cast(). This should go away with scenev2/etc.
bs.animate_array(
heart,
'scale',
2,
{
0.0: cast(Sequence[float], heart.scale),
time: (90, 90),
},
)

View File

@ -321,11 +321,15 @@ class Target(bs.Actor):
bs.getsound(
'orchestraHit4'
if streak > 3
else 'orchestraHit3'
if streak > 2
else 'orchestraHit2'
if streak > 1
else 'orchestraHit'
else (
'orchestraHit3'
if streak > 2
else (
'orchestraHit2'
if streak > 1
else 'orchestraHit'
)
)
).play()
elif dist <= self._r2 + self._rfudge:
self._nodes[0].color = cdull

View File

@ -43,7 +43,10 @@ class UIV1Subsystem(babase.AppSubsystem):
self._uiscale: babase.UIScale
interfacetype = env['ui_scale']
interfacetype = babase.app.config.get('UI Scale', env['ui_scale'])
if interfacetype == 'auto':
interfacetype = env['ui_scale']
if interfacetype == 'large':
self._uiscale = babase.UIScale.LARGE
elif interfacetype == 'medium':

View File

@ -164,9 +164,7 @@ class UIController:
entrynew = (
self._dialog_stack[-1]
if self._dialog_stack
else self._main_stack[-1]
if self._main_stack
else None
else self._main_stack[-1] if self._main_stack else None
)
if entrynew is not None:
entrynew.create()

View File

@ -41,15 +41,13 @@ class OnScreenKeyboardWindow(Window):
scale=(
2.0
if uiscale is babase.UIScale.SMALL
else 1.5
if uiscale is babase.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is babase.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, 0)
if uiscale is babase.UIScale.SMALL
else (0, 0) if uiscale is babase.UIScale.MEDIUM else (0, 0)
),
stack_offset=(0, 0)
if uiscale is babase.UIScale.SMALL
else (0, 0)
if uiscale is babase.UIScale.MEDIUM
else (0, 0),
)
)
self._cancel_button = _bauiv1.buttonwidget(
@ -300,9 +298,11 @@ class OnScreenKeyboardWindow(Window):
chars = [c.upper() for c in chars]
_bauiv1.buttonwidget(
edit=self._shift_button,
color=self._key_color_lit
if self._mode == 'caps'
else self._key_color_dark,
color=(
self._key_color_lit
if self._mode == 'caps'
else self._key_color_dark
),
label=babase.charstr(babase.SpecialChar.SHIFT),
on_activate_call=self._shift,
)

View File

@ -38,9 +38,7 @@ class AccountLinkWindow(bui.Window):
base_scale = (
1.65
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.1
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.1
)
super().__init__(
root_widget=bui.containerwidget(
@ -48,9 +46,9 @@ class AccountLinkWindow(bui.Window):
transition=transition,
scale=base_scale,
scale_origin_stack_offset=scale_origin,
stack_offset=(0, -10)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, -10) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)
self._cancel_button = bui.buttonwidget(
@ -159,9 +157,7 @@ class AccountLinkCodeWindow(bui.Window):
scale=(
1.8
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -74,9 +74,7 @@ class AccountSettingsWindow(bui.Window):
self._height = (
390
if uiscale is bui.UIScale.SMALL
else 430
if uiscale is bui.UIScale.MEDIUM
else 490
else 430 if uiscale is bui.UIScale.MEDIUM else 490
)
self._sign_in_button = None
@ -112,13 +110,11 @@ class AccountSettingsWindow(bui.Window):
scale=(
2.09
if uiscale is bui.UIScale.SMALL
else 1.4
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -19) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -19)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
if uiscale is bui.UIScale.SMALL and app.ui_v1.use_toolbars:
@ -928,9 +924,9 @@ class AccountSettingsWindow(bui.Window):
if gpgs_active
else 'achievementsIcon'
),
icon_color=(0.8, 0.95, 0.7)
if gpgs_active
else (0.85, 0.8, 0.9),
icon_color=(
(0.8, 0.95, 0.7) if gpgs_active else (0.85, 0.8, 0.9)
),
on_activate_call=(
self._on_custom_achievements_press
if gpgs_active

View File

@ -39,9 +39,7 @@ class AccountUnlinkWindow(bui.Window):
base_scale = (
2.0
if uiscale is bui.UIScale.SMALL
else 1.6
if uiscale is bui.UIScale.MEDIUM
else 1.1
else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.1
)
super().__init__(
root_widget=bui.containerwidget(
@ -49,9 +47,9 @@ class AccountUnlinkWindow(bui.Window):
transition=transition,
scale=base_scale,
scale_origin_stack_offset=scale_origin,
stack_offset=(0, -10)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, -10) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)
self._cancel_button = bui.buttonwidget(

View File

@ -34,9 +34,7 @@ class V2ProxySignInWindow(bui.Window):
scale=(
1.25
if uiscale is bui.UIScale.SMALL
else 1.05
if uiscale is bui.UIScale.MEDIUM
else 0.9
else 1.05 if uiscale is bui.UIScale.MEDIUM else 0.9
),
)
)

View File

@ -43,9 +43,7 @@ class AccountViewerWindow(PopupWindow):
scale = (
2.6
if uiscale is bui.UIScale.SMALL
else 1.8
if uiscale is bui.UIScale.MEDIUM
else 1.4
else 1.8 if uiscale is bui.UIScale.MEDIUM else 1.4
)
self._transitioning_out = False
@ -53,9 +51,7 @@ class AccountViewerWindow(PopupWindow):
self._height = (
300
if uiscale is bui.UIScale.SMALL
else 400
if uiscale is bui.UIScale.MEDIUM
else 450
else 400 if uiscale is bui.UIScale.MEDIUM else 450
)
self._subcontainer: bui.Widget | None = None
@ -186,9 +182,7 @@ class AccountViewerWindow(PopupWindow):
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
),
choices=choices,
choices_display=choices_display,

View File

@ -23,18 +23,14 @@ class AchievementsWindow(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._transitioning_out = False
self._width = 450
self._height = (
300
if uiscale is bui.UIScale.SMALL
else 370
if uiscale is bui.UIScale.MEDIUM
else 450
else 370 if uiscale is bui.UIScale.MEDIUM else 450
)
bg_color = (0.5, 0.4, 0.6)
@ -126,9 +122,11 @@ class AchievementsWindow(PopupWindow):
bui.imagewidget(
parent=self._subcontainer,
position=(sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9)
if complete
else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14),
position=(
(sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9)
if complete
else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14)
),
size=(18, 18) if complete else (27, 27),
opacity=1.0 if complete else 0.3,
color=ach.get_icon_color(complete)[:3],
@ -167,9 +165,11 @@ class AchievementsWindow(PopupWindow):
flatness=1.0,
shadow=0.0,
color=(0.83, 0.8, 0.85) if complete else (0.8, 0.8, 0.8, 0.2),
text=ach.description_full_complete
if complete
else ach.description_full,
text=(
ach.description_full_complete
if complete
else ach.description_full
),
size=(0, 0),
h_align='left',
v_align='center',

View File

@ -31,9 +31,7 @@ class ShowFriendCodeWindow(bui.Window):
scale=(
1.7
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -41,9 +41,7 @@ class CharacterPicker(PopupWindow):
scale = (
1.85
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._delegate = delegate

View File

@ -43,9 +43,7 @@ class ColorPicker(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._parent = parent
self._position = position
@ -206,9 +204,7 @@ class ColorPickerExact(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._delegate = delegate
self._transitioning_out = False

View File

@ -94,6 +94,8 @@ class ConfigNumberEdit:
changesound: bool = True,
textscale: float = 1.0,
as_percent: bool = False,
fallback_value: float = 0.0,
f: int = 1,
):
if displayname is None:
displayname = configkey
@ -103,8 +105,12 @@ class ConfigNumberEdit:
self._maxval = maxval
self._increment = increment
self._callback = callback
self._value = bui.app.config.resolve(configkey)
try:
self._value = bui.app.config.resolve(configkey)
except ValueError:
self._value = bui.app.config.get(configkey, fallback_value)
self._as_percent = as_percent
self._f = f
self.nametext = bui.textwidget(
parent=parent,
@ -171,5 +177,5 @@ class ConfigNumberEdit:
if self._as_percent:
val = f'{round(self._value*100.0)}%'
else:
val = f'{self._value:.1f}'
val = f'{self._value:.{self._f}f}'
bui.textwidget(edit=self.valuetext, text=val)

View File

@ -61,9 +61,7 @@ class ConfirmWindow:
scale=(
2.1
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
scale_origin_stack_offset=scale_origin,
)
@ -187,8 +185,10 @@ class QuitWindow:
resource=quit_resource,
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
),
lambda: bui.quit(confirm=False, quit_type=self._quit_type)
if self._quit_type is not None
else bui.quit(confirm=False),
lambda: (
bui.quit(confirm=False, quit_type=self._quit_type)
if self._quit_type is not None
else bui.quit(confirm=False)
),
origin_widget=origin_widget,
).root_widget

View File

@ -148,9 +148,11 @@ class GameButton:
draw_controller=btn,
position=(xach, yach),
size=(a_scale, a_scale),
color=tuple(ach.get_icon_color(a_complete)[:3])
if a_complete
else (1.2, 1.2, 1.2),
color=(
tuple(ach.get_icon_color(a_complete)[:3])
if a_complete
else (1.2, 1.2, 1.2)
),
texture=ach.get_icon_ui_texture(a_complete),
)
imw2 = bui.imagewidget(
@ -307,8 +309,6 @@ class GameButton:
opacity=(
1.0
if (a_complete and unlocked)
else 0.2
if a_complete
else 0.0
else 0.2 if a_complete else 0.0
),
)

View File

@ -23,9 +23,7 @@ class CoopLevelLockedWindow(bui.Window):
scale=(
1.7
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -417,9 +417,7 @@ class TournamentButton:
prize_y_offs = (
34
if 'prizeRange3' in entry
else 20
if 'prizeRange2' in entry
else 12
else 20 if 'prizeRange2' in entry else 12
)
x_offs = 90
@ -460,9 +458,11 @@ class TournamentButton:
bui.textwidget(
edit=self.prize_value_1_text,
text='-' if pv1 == '' else pv1,
scale=prize_value_scale_large
if ticket_char not in pv1
else prize_value_scale_small,
scale=(
prize_value_scale_large
if ticket_char not in pv1
else prize_value_scale_small
),
position=(
self.button_x + 380 + x_offs,
self.button_y + self.button_scale_y - 93 + prize_y_offs,
@ -480,9 +480,11 @@ class TournamentButton:
bui.textwidget(
edit=self.prize_value_2_text,
text=pv2,
scale=prize_value_scale_large
if ticket_char not in pv2
else prize_value_scale_small,
scale=(
prize_value_scale_large
if ticket_char not in pv2
else prize_value_scale_small
),
position=(
self.button_x + 380 + x_offs,
self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs,
@ -500,9 +502,11 @@ class TournamentButton:
bui.textwidget(
edit=self.prize_value_3_text,
text=pv3,
scale=prize_value_scale_large
if ticket_char not in pv3
else prize_value_scale_small,
scale=(
prize_value_scale_large
if ticket_char not in pv3
else prize_value_scale_small
),
position=(
self.button_x + 380 + x_offs,
self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs,
@ -667,9 +671,11 @@ class TournamentButton:
self.button_x + 360,
self.button_y + self.button_scale_y - 146,
),
text=''
if ad_tries_remaining in [None, 0]
else ('' + str(ad_tries_remaining)),
text=(
''
if ad_tries_remaining in [None, 0]
else ('' + str(ad_tries_remaining))
),
color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2),
)
else:

View File

@ -51,13 +51,11 @@ class CreditsListWindow(bui.Window):
scale=(
2.0
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -8) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -8)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)

View File

@ -25,9 +25,7 @@ class DebugWindow(bui.Window):
self._height = height = (
350
if uiscale is bui.UIScale.SMALL
else 420
if uiscale is bui.UIScale.MEDIUM
else 520
else 420 if uiscale is bui.UIScale.MEDIUM else 520
)
self._scroll_width = self._width - 100
@ -50,13 +48,11 @@ class DebugWindow(bui.Window):
scale=(
2.35
if uiscale is bui.UIScale.SMALL
else 1.55
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -30) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -30)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)

View File

@ -45,9 +45,7 @@ class DiscordWindow(bui.Window):
scale=(
1.6
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 0),
)

View File

@ -33,9 +33,7 @@ def ask_for_rating() -> bui.Widget | None:
scale=(
1.6
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
v = height - 50

View File

@ -57,13 +57,11 @@ class FileSelectorWindow(bui.Window):
scale=(
2.23
if uiscale is bui.UIScale.SMALL
else 1.4
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -35) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -35)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
bui.textwidget(
@ -73,11 +71,15 @@ class FileSelectorWindow(bui.Window):
color=bui.app.ui_v1.title_color,
h_align='center',
v_align='center',
text=bui.Lstr(resource=self._r + '.titleFolderText')
if (allow_folders and not valid_file_extensions)
else bui.Lstr(resource=self._r + '.titleFileText')
if not allow_folders
else bui.Lstr(resource=self._r + '.titleFileFolderText'),
text=(
bui.Lstr(resource=self._r + '.titleFolderText')
if (allow_folders and not valid_file_extensions)
else (
bui.Lstr(resource=self._r + '.titleFileText')
if not allow_folders
else bui.Lstr(resource=self._r + '.titleFileFolderText')
)
),
maxwidth=210,
)
@ -444,9 +446,11 @@ class FileSelectorWindow(bui.Window):
position=(10 + folder_icon_size * 1.05, entry_height * 0.5),
size=(0, 0),
maxwidth=self._scroll_width * 0.93 - 50,
color=(1, 1, 1, 1)
if (is_valid_file_path or is_dir)
else (0.5, 0.5, 0.5, 1),
color=(
(1, 1, 1, 1)
if (is_valid_file_path or is_dir)
else (0.5, 0.5, 0.5, 1)
),
)
v -= entry_height

View File

@ -99,9 +99,7 @@ class GatherWindow(bui.Window):
self._height = (
582
if uiscale is bui.UIScale.SMALL
else 680
if uiscale is bui.UIScale.MEDIUM
else 800
else 680 if uiscale is bui.UIScale.MEDIUM else 800
)
self._current_tab: GatherWindow.TabID | None = None
extra_top = 20 if uiscale is bui.UIScale.SMALL else 0
@ -116,15 +114,13 @@ class GatherWindow(bui.Window):
scale=(
1.3
if uiscale is bui.UIScale.SMALL
else 0.97
if uiscale is bui.UIScale.MEDIUM
else 0.8
else 0.97 if uiscale is bui.UIScale.MEDIUM else 0.8
),
stack_offset=(
(0, -11)
if uiscale is bui.UIScale.SMALL
else (0, 0) if uiscale is bui.UIScale.MEDIUM else (0, 0)
),
stack_offset=(0, -11)
if uiscale is bui.UIScale.SMALL
else (0, 0)
if uiscale is bui.UIScale.MEDIUM
else (0, 0),
)
)
@ -165,9 +161,7 @@ class GatherWindow(bui.Window):
scale=(
1.5
if not condensed
else 1.0
if uiscale is bui.UIScale.MEDIUM
else 0.6
else 1.0 if uiscale is bui.UIScale.MEDIUM else 0.6
),
h_align='center',
v_align='center',

View File

@ -44,9 +44,7 @@ class AboutGatherTab(GatherTab):
message_height = (
210
if uiscale is bui.UIScale.SMALL
else 305
if uiscale is bui.UIScale.MEDIUM
else 370
else 305 if uiscale is bui.UIScale.MEDIUM else 370
)
# Let's not talk about sharing in vr-mode; its tricky to fit more
# than one head in a VR-headset.

View File

@ -837,9 +837,7 @@ class PrivateGatherTab(GatherTab):
color=(
(0.6, 0.6, 0.6)
if disabled
else (0.5, 1.0, 0.5)
if waiting
else None
else (0.5, 1.0, 0.5) if waiting else None
),
enable_sound=False,
label=btnlabel,

View File

@ -204,11 +204,11 @@ class UIRow:
bui.textwidget(
edit=self._ping_widget,
text=str(int(party.ping)),
color=(0, 1, 0)
if party.ping <= ping_good
else (1, 1, 0)
if party.ping <= ping_med
else (1, 0, 0),
color=(
(0, 1, 0)
if party.ping <= ping_good
else (1, 1, 0) if party.ping <= ping_med else (1, 0, 0)
),
)
party.clean_display_index = index
@ -369,8 +369,8 @@ class PublicGatherTab(GatherTab):
self._join_status_text: bui.Widget | None = None
self._no_servers_found_text: bui.Widget | None = None
self._host_max_party_size_value: bui.Widget | None = None
self._host_max_party_size_minus_button: (bui.Widget | None) = None
self._host_max_party_size_plus_button: (bui.Widget | None) = None
self._host_max_party_size_minus_button: bui.Widget | None = None
self._host_max_party_size_plus_button: bui.Widget | None = None
self._host_status_text: bui.Widget | None = None
self._signed_in = False
self._ui_rows: list[UIRow] = []
@ -800,9 +800,11 @@ class PublicGatherTab(GatherTab):
parent=self._container,
label=label,
size=(400, 80),
on_activate_call=self._on_stop_advertising_press
if is_public_enabled
else self._on_start_advertizing_press,
on_activate_call=(
self._on_stop_advertising_press
if is_public_enabled
else self._on_start_advertizing_press
),
position=(c_width * 0.5 - 200, v),
autoselect=True,
up_widget=btn2,

View File

@ -72,13 +72,11 @@ class GetCurrencyWindow(bui.Window):
scale=(
1.63
if uiscale is bui.UIScale.SMALL
else 1.2
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -3) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -3)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
@ -605,11 +603,11 @@ class GetCurrencyWindow(bui.Window):
self._smooth_increase_speed = (
diff / 100.0
if diff >= 5000
else diff / 50.0
if diff >= 1500
else diff / 30.0
if diff >= 500
else diff / 15.0
else (
diff / 50.0
if diff >= 1500
else diff / 30.0 if diff >= 500 else diff / 15.0
)
)
def _disabled_press(self) -> None:

View File

@ -20,9 +20,7 @@ class GetBSRemoteWindow(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._transitioning_out = False
self._width = 570

View File

@ -41,9 +41,7 @@ class HelpWindow(bui.Window):
height = (
460
if uiscale is bui.UIScale.SMALL
else 530
if uiscale is bui.UIScale.MEDIUM
else 600
else 530 if uiscale is bui.UIScale.MEDIUM else 600
)
super().__init__(
@ -55,15 +53,13 @@ class HelpWindow(bui.Window):
scale=(
1.77
if uiscale is bui.UIScale.SMALL
else 1.25
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.25 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -30)
if uiscale is bui.UIScale.SMALL
else (0, 15) if uiscale is bui.UIScale.MEDIUM else (0, 0)
),
stack_offset=(0, -30)
if uiscale is bui.UIScale.SMALL
else (0, 15)
if uiscale is bui.UIScale.MEDIUM
else (0, 0),
)
)
@ -119,9 +115,11 @@ class HelpWindow(bui.Window):
),
size=(140, 60),
scale=0.7 if uiscale is bui.UIScale.SMALL else 0.8,
label=bui.Lstr(resource='backText')
if self._main_menu
else 'Close',
label=(
bui.Lstr(resource='backText')
if self._main_menu
else 'Close'
),
button_type='back' if self._main_menu else None,
extra_touch_border_scale=2.0,
autoselect=True,

View File

@ -40,9 +40,7 @@ class IconPicker(PopupWindow):
scale = (
1.85
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._delegate = delegate

View File

@ -472,9 +472,9 @@ class KioskWindow(bui.Window):
'type': 'bs_hockey.HockeyGame',
}
]
appconfig[
'Team Tournament Playlist Selection'
] = 'Just Hockey'
appconfig['Team Tournament Playlist Selection'] = (
'Just Hockey'
)
bui.fade_screen(
False,
endcall=bui.Call(
@ -488,9 +488,11 @@ class KioskWindow(bui.Window):
game = (
'Easy:Onslaught Training'
if mode == 'easy'
else 'Easy:Rookie Football'
if mode == 'medium'
else 'Easy:Uber Onslaught'
else (
'Easy:Rookie Football'
if mode == 'medium'
else 'Easy:Uber Onslaught'
)
)
cfg = bui.app.config
cfg['Selected Coop Game'] = game

View File

@ -63,9 +63,7 @@ class LeagueRankWindow(bui.Window):
self._height = (
657
if uiscale is bui.UIScale.SMALL
else 710
if uiscale is bui.UIScale.MEDIUM
else 800
else 710 if uiscale is bui.UIScale.MEDIUM else 800
)
self._r = 'coopSelectWindow'
self._rdict = bui.app.lang.get_resource(self._r)
@ -79,19 +77,17 @@ class LeagueRankWindow(bui.Window):
super().__init__(
root_widget=bui.containerwidget(
size=(self._width, self._height + top_extra),
stack_offset=(0, -15)
if uiscale is bui.UIScale.SMALL
else (0, 10)
if uiscale is bui.UIScale.MEDIUM
else (0, 0),
stack_offset=(
(0, -15)
if uiscale is bui.UIScale.SMALL
else (0, 10) if uiscale is bui.UIScale.MEDIUM else (0, 0)
),
transition=transition,
scale_origin_stack_offset=scale_origin,
scale=(
1.2
if uiscale is bui.UIScale.SMALL
else 0.93
if uiscale is bui.UIScale.MEDIUM
else 0.8
else 0.93 if uiscale is bui.UIScale.MEDIUM else 0.8
),
)
)
@ -210,9 +206,11 @@ class LeagueRankWindow(bui.Window):
assert plus is not None
txt = bui.Lstr(
resource='coopSelectWindow.activenessAllTimeInfoText'
if self._season == 'a'
else 'coopSelectWindow.activenessInfoText',
resource=(
'coopSelectWindow.activenessAllTimeInfoText'
if self._season == 'a'
else 'coopSelectWindow.activenessInfoText'
),
subs=[
(
'${MAX}',
@ -853,9 +851,11 @@ class LeagueRankWindow(bui.Window):
bui.textwidget(
edit=self._league_title_text,
text=''
if self._season == 'a'
else bui.Lstr(resource='league.leagueText'),
text=(
''
if self._season == 'a'
else bui.Lstr(resource='league.leagueText')
),
)
if data is None:
@ -910,9 +910,11 @@ class LeagueRankWindow(bui.Window):
bui.textwidget(edit=self._season_ends_text, text=to_end_string)
bui.textwidget(
edit=self._trophy_counts_reset_text,
text=bui.Lstr(resource='league.trophyCountsResetText')
if self._is_current_season and show_season_end
else '',
text=(
bui.Lstr(resource='league.trophyCountsResetText')
if self._is_current_season and show_season_end
else ''
),
)
bui.textwidget(edit=self._league_text, text=lname, color=lcolor)
@ -932,21 +934,25 @@ class LeagueRankWindow(bui.Window):
)
bui.textwidget(
edit=self._to_ranked_text,
text=bui.Lstr(resource='coopSelectWindow.toRankedText').evaluate()
+ ''
+ extra_text
if do_percent
else '',
text=(
bui.Lstr(resource='coopSelectWindow.toRankedText').evaluate()
+ ''
+ extra_text
if do_percent
else ''
),
)
bui.textwidget(
edit=self._your_power_ranking_text,
text=bui.Lstr(
resource='rankText',
fallback_resource='coopSelectWindow.yourPowerRankingText',
)
if (not do_percent)
else '',
text=(
bui.Lstr(
resource='rankText',
fallback_resource='coopSelectWindow.yourPowerRankingText',
)
if (not do_percent)
else ''
),
)
bui.textwidget(
@ -954,11 +960,11 @@ class LeagueRankWindow(bui.Window):
position=(473, v - 70 - (170 if do_percent else 220)),
text=status_text,
big=(in_top or do_percent),
scale=3.0
if (in_top or do_percent)
else 0.7
if finished_season_unranked
else 1.0,
scale=(
3.0
if (in_top or do_percent)
else 0.7 if finished_season_unranked else 1.0
),
)
if self._activity_mult_button is not None:
@ -992,9 +998,11 @@ class LeagueRankWindow(bui.Window):
# pylint: disable=consider-using-f-string
bui.textwidget(
edit=self._pro_mult_text,
text=' -'
if (data is None or not have_pro)
else 'x ' + ('%.2f' % pro_mult),
text=(
' -'
if (data is None or not have_pro)
else 'x ' + ('%.2f' % pro_mult)
),
)
bui.buttonwidget(
edit=self._pro_mult_button,
@ -1019,9 +1027,11 @@ class LeagueRankWindow(bui.Window):
bui.textwidget(
edit=self._power_ranking_achievement_total_text,
text='-'
if data is None
else ('+ ' + pts_txt.replace('${NUMBER}', str(total_ach_value))),
text=(
'-'
if data is None
else ('+ ' + pts_txt.replace('${NUMBER}', str(total_ach_value)))
),
)
total_trophies_count = accounts.get_league_rank_points(
@ -1035,19 +1045,24 @@ class LeagueRankWindow(bui.Window):
)
bui.textwidget(
edit=self._power_ranking_trophies_total_text,
text='-'
if data is None
else (
'+ ' + pts_txt.replace('${NUMBER}', str(total_trophies_value))
text=(
'-'
if data is None
else (
'+ '
+ pts_txt.replace('${NUMBER}', str(total_trophies_value))
)
),
)
bui.textwidget(
edit=self._power_ranking_total_text,
text='-'
if data is None
else eq_text.replace(
'${NUMBER}', str(accounts.get_league_rank_points(data))
text=(
'-'
if data is None
else eq_text.replace(
'${NUMBER}', str(accounts.get_league_rank_points(data))
)
),
)
for widget in self._power_ranking_score_widgets:

View File

@ -43,9 +43,11 @@ class MainMenuWindow(bui.Window):
super().__init__(
root_widget=bui.containerwidget(
transition=transition,
toolbar_visibility='menu_minimal_no_back'
if self._in_game
else 'menu_minimal_no_back',
toolbar_visibility=(
'menu_minimal_no_back'
if self._in_game
else 'menu_minimal_no_back'
),
)
)
@ -142,9 +144,11 @@ class MainMenuWindow(bui.Window):
return (
'storeCharacterXmas'
if plus.get_v1_account_misc_read_val('xmas', False)
else 'storeCharacterEaster'
if plus.get_v1_account_misc_read_val('easter', False)
else 'storeCharacter'
else (
'storeCharacterEaster'
if plus.get_v1_account_misc_read_val('easter', False)
else 'storeCharacter'
)
)
def _check_refresh(self) -> None:
@ -344,9 +348,7 @@ class MainMenuWindow(bui.Window):
icon_size = (
55
if uiscale is bui.UIScale.SMALL
else 55
if uiscale is bui.UIScale.MEDIUM
else 70
else 55 if uiscale is bui.UIScale.MEDIUM else 70
)
bui.imagewidget(
parent=self._root_widget,
@ -452,7 +454,7 @@ class MainMenuWindow(bui.Window):
resource='watchWindow.playbackSpeedText',
subs=[('${SPEED}', str(1.23))],
),
position=(h, v + v_offs + 7 * t_scale),
position=(h, v + v_offs + 15 * t_scale),
h_align='center',
v_align='center',
size=(0, 0),
@ -526,6 +528,64 @@ class MainMenuWindow(bui.Window):
autoselect=True,
on_activate_call=bui.Call(self._pause_or_resume_replay),
)
btn = bui.buttonwidget(
parent=self._root_widget,
position=(
h - b_size * 1.5 - b_buffer_1 * 2,
v - b_size - b_buffer_2 + v_offs,
),
button_type='square',
size=(b_size, b_size),
label='',
autoselect=True,
on_activate_call=bui.WeakCall(self._rewind_replay),
)
bui.textwidget(
parent=self._root_widget,
draw_controller=btn,
# text='<<',
text=bui.charstr(bui.SpecialChar.REWIND_BUTTON),
position=(
h - b_size - b_buffer_1 * 2,
v - b_size * 0.5 - b_buffer_2 + 5 * t_scale + v_offs,
),
h_align='center',
v_align='center',
size=(0, 0),
scale=2.0 * t_scale,
)
btn = bui.buttonwidget(
parent=self._root_widget,
position=(
h + b_size * 0.5 + b_buffer_1 * 2,
v - b_size - b_buffer_2 + v_offs,
),
button_type='square',
size=(b_size, b_size),
label='',
autoselect=True,
on_activate_call=bui.WeakCall(self._forward_replay),
)
bui.textwidget(
parent=self._root_widget,
draw_controller=btn,
# text='>>',
text=bui.charstr(bui.SpecialChar.FAST_FORWARD_BUTTON),
position=(
h + b_size + b_buffer_1 * 2,
v - b_size * 0.5 - b_buffer_2 + 5 * t_scale + v_offs,
),
h_align='center',
v_align='center',
size=(0, 0),
scale=2.0 * t_scale,
)
def _rewind_replay(self) -> None:
bs.seek_replay(-2 * pow(2, bs.get_replay_speed_exponent()))
def _forward_replay(self) -> None:
bs.seek_replay(2 * pow(2, bs.get_replay_speed_exponent()))
def _refresh_not_in_game(
self, positions: list[tuple[float, float, float]]
@ -646,9 +706,11 @@ class MainMenuWindow(bui.Window):
color=(0.45, 0.55, 0.45),
textcolor=(0.7, 0.8, 0.7),
label=bui.Lstr(
resource='modeArcadeText'
if bui.app.env.arcade
else 'modeDemoText'
resource=(
'modeArcadeText'
if bui.app.env.arcade
else 'modeDemoText'
)
),
transition_delay=demo_menu_delay,
on_activate_call=self._demo_menu_press,
@ -659,9 +721,7 @@ class MainMenuWindow(bui.Window):
foof = (
-1
if uiscale is bui.UIScale.SMALL
else 1
if uiscale is bui.UIScale.MEDIUM
else 3
else 1 if uiscale is bui.UIScale.MEDIUM else 3
)
h, v, scale = positions[self._p_index]
v = v + foof
@ -906,9 +966,7 @@ class MainMenuWindow(bui.Window):
scale=(
2.15
if uiscale is bui.UIScale.SMALL
else 1.6
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
h = 125.0
@ -1398,8 +1456,9 @@ class MainMenuWindow(bui.Window):
def _resume(self) -> None:
assert bui.app.classic is not None
bui.app.classic.resume()
if self._root_widget:
bui.containerwidget(edit=self._root_widget, transition='out_right')
# if self._root_widget:
# bui.containerwidget(edit=self._root_widget,
# transition='out_right')
bui.app.ui_v1.clear_main_menu_window(transition='out_right')
# If there's callbacks waiting for this window to go away, call them.

View File

@ -36,9 +36,7 @@ class PartyWindow(bui.Window):
self._height = (
365
if uiscale is bui.UIScale.SMALL
else 480
if uiscale is bui.UIScale.MEDIUM
else 600
else 480 if uiscale is bui.UIScale.MEDIUM else 600
)
self._display_old_msgs = True
super().__init__(
@ -52,15 +50,15 @@ class PartyWindow(bui.Window):
scale=(
2.0
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -10)
if uiscale is bui.UIScale.SMALL
else (
(240, 0) if uiscale is bui.UIScale.MEDIUM else (330, 20)
)
),
stack_offset=(0, -10)
if uiscale is bui.UIScale.SMALL
else (240, 0)
if uiscale is bui.UIScale.MEDIUM
else (330, 20),
)
)
@ -251,9 +249,7 @@ class PartyWindow(bui.Window):
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
),
choices=choices,
choices_display=choices_display,
@ -312,9 +308,7 @@ class PartyWindow(bui.Window):
columns = (
1
if len(self._roster) == 1
else 2
if len(self._roster) == 2
else 3
else 2 if len(self._roster) == 2 else 3
)
rows = int(math.ceil(float(len(self._roster)) / columns))
c_width = (self._width * 0.9) / max(3, columns)
@ -572,9 +566,7 @@ class PartyWindow(bui.Window):
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
),
choices=['kick'],
choices_display=[kick_str],

View File

@ -274,9 +274,7 @@ class PartyQueueWindow(bui.Window):
scale=(
1.4
if uiscale is bui.UIScale.SMALL
else 1.2
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -57,9 +57,7 @@ class PlayWindow(bui.Window):
scale=(
1.6
if uiscale is bui.UIScale.SMALL
else 0.9
if uiscale is bui.UIScale.MEDIUM
else 0.8
else 0.9 if uiscale is bui.UIScale.MEDIUM else 0.8
),
stack_offset=(0, 0) if uiscale is bui.UIScale.SMALL else (0, 0),
)
@ -83,9 +81,11 @@ class PlayWindow(bui.Window):
# (101 if main_menu else 61)),
size=(0, 0),
text=bui.Lstr(
resource=(self._r + '.titleText')
if self._is_main_menu
else 'playlistsText'
resource=(
(self._r + '.titleText')
if self._is_main_menu
else 'playlistsText'
)
),
scale=1.7,
res_scale=2.0,
@ -494,18 +494,22 @@ class PlayWindow(bui.Window):
bui.containerwidget(
edit=self._root_widget,
on_cancel_call=self._back,
selected_child=self._coop_button
if self._is_main_menu
else self._teams_button,
selected_child=(
self._coop_button
if self._is_main_menu
else self._teams_button
),
)
else:
bui.buttonwidget(edit=back_button, on_activate_call=self._back)
bui.containerwidget(
edit=self._root_widget,
cancel_button=back_button,
selected_child=self._coop_button
if self._is_main_menu
else self._teams_button,
selected_child=(
self._coop_button
if self._is_main_menu
else self._teams_button
),
)
self._restore_state()

View File

@ -30,9 +30,7 @@ class PlaylistAddGameWindow(bui.Window):
self._height = (
346
if uiscale is bui.UIScale.SMALL
else 380
if uiscale is bui.UIScale.MEDIUM
else 440
else 380 if uiscale is bui.UIScale.MEDIUM else 440
)
top_extra = 30 if uiscale is bui.UIScale.SMALL else 20
self._scroll_width = 210
@ -44,9 +42,7 @@ class PlaylistAddGameWindow(bui.Window):
scale=(
2.17
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 0),
)

View File

@ -67,9 +67,7 @@ class PlaylistBrowserWindow(bui.Window):
self._height = (
480
if uiscale is bui.UIScale.SMALL
else 510
if uiscale is bui.UIScale.MEDIUM
else 580
else 510 if uiscale is bui.UIScale.MEDIUM else 580
)
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
@ -83,13 +81,11 @@ class PlaylistBrowserWindow(bui.Window):
scale=(
1.69
if uiscale is bui.UIScale.SMALL
else 1.05
if uiscale is bui.UIScale.MEDIUM
else 0.9
else 1.05 if uiscale is bui.UIScale.MEDIUM else 0.9
),
stack_offset=(
(0, -26) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -26)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
@ -714,9 +710,9 @@ class PlaylistBrowserWindow(bui.Window):
)
if self._selected_playlist != prev_sel:
cfg = bui.app.config
cfg[
self._pvars.config_name + ' Playlist Selection'
] = self._selected_playlist
cfg[self._pvars.config_name + ' Playlist Selection'] = (
self._selected_playlist
)
cfg.commit()
self._save_state()

View File

@ -36,9 +36,7 @@ class PlaylistEditWindow(bui.Window):
self._height = (
400
if uiscale is bui.UIScale.SMALL
else 470
if uiscale is bui.UIScale.MEDIUM
else 540
else 470 if uiscale is bui.UIScale.MEDIUM else 540
)
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
@ -49,13 +47,11 @@ class PlaylistEditWindow(bui.Window):
scale=(
2.0
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -16) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -16)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
cancel_button = bui.buttonwidget(
@ -149,9 +145,7 @@ class PlaylistEditWindow(bui.Window):
scl = (
1.03
if uiscale is bui.UIScale.SMALL
else 1.36
if uiscale is bui.UIScale.MEDIUM
else 1.74
else 1.36 if uiscale is bui.UIScale.MEDIUM else 1.74
)
v -= 63.0 * scl

View File

@ -108,9 +108,7 @@ class PlaylistEditGameWindow(bui.Window):
height = (
365
if uiscale is bui.UIScale.SMALL
else 460
if uiscale is bui.UIScale.MEDIUM
else 550
else 460 if uiscale is bui.UIScale.MEDIUM else 550
)
spacing = 52
y_extra = 15
@ -129,13 +127,11 @@ class PlaylistEditGameWindow(bui.Window):
scale=(
2.19
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -17) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -17)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
@ -143,9 +139,11 @@ class PlaylistEditGameWindow(bui.Window):
parent=self._root_widget,
position=(45 + x_inset, height - 82 + y_extra2),
size=(180, 70) if is_add else (180, 65),
label=bui.Lstr(resource='backText')
if is_add
else bui.Lstr(resource='cancelText'),
label=(
bui.Lstr(resource='backText')
if is_add
else bui.Lstr(resource='cancelText')
),
button_type='back' if is_add else None,
autoselect=True,
scale=0.75,
@ -160,9 +158,11 @@ class PlaylistEditGameWindow(bui.Window):
size=(200, 65),
scale=0.75,
text_scale=1.3,
label=bui.Lstr(resource=self._r + '.addGameText')
if is_add
else bui.Lstr(resource='doneText'),
label=(
bui.Lstr(resource=self._r + '.addGameText')
if is_add
else bui.Lstr(resource='doneText')
),
)
if bui.app.ui_v1.use_toolbars:
@ -447,9 +447,11 @@ class PlaylistEditGameWindow(bui.Window):
parent=self._subcontainer,
position=(h + 509 - 95, v),
size=(0, 28),
text=bui.Lstr(resource='onText')
if value
else bui.Lstr(resource='offText'),
text=(
bui.Lstr(resource='onText')
if value
else bui.Lstr(resource='offText')
),
editable=False,
color=(0.6, 1.0, 0.6, 1.0),
maxwidth=mw2,
@ -566,9 +568,11 @@ class PlaylistEditGameWindow(bui.Window):
) -> None:
bui.textwidget(
edit=widget,
text=bui.Lstr(resource='onText')
if value
else bui.Lstr(resource='offText'),
text=(
bui.Lstr(resource='onText')
if value
else bui.Lstr(resource='offText')
),
)
self._settings[setting_name] = value

View File

@ -49,9 +49,7 @@ class PlaylistMapSelectWindow(bui.Window):
height = (
400
if uiscale is bui.UIScale.SMALL
else 480
if uiscale is bui.UIScale.MEDIUM
else 600
else 480 if uiscale is bui.UIScale.MEDIUM else 600
)
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
@ -62,13 +60,11 @@ class PlaylistMapSelectWindow(bui.Window):
scale=(
2.17
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -27) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -27)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)

View File

@ -93,9 +93,7 @@ class SharePlaylistResultsWindow(bui.Window):
scale=(
1.8
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -33,6 +33,7 @@ class PlayOptionsWindow(PopupWindow):
# pylint: disable=too-many-locals
from bascenev1 import filter_playlist, get_map_class
from bauiv1lib.playlist import PlaylistTypeVars
from bauiv1lib.config import ConfigNumberEdit
self._r = 'gameListWindow'
self._delegate = delegate
@ -52,7 +53,7 @@ class PlayOptionsWindow(PopupWindow):
self._playlist = playlist
self._width = 500.0
self._height = 330.0 - 50.0
self._height = 370.0 - 50.0
# In teams games, show the custom names/colors button.
if self._sessiontype is bs.DualTeamSession:
@ -145,9 +146,7 @@ class PlayOptionsWindow(PopupWindow):
scale = (
1.69
if uiscale is bui.UIScale.SMALL
else 1.1
if uiscale is bui.UIScale.MEDIUM
else 0.85
else 1.1 if uiscale is bui.UIScale.MEDIUM else 0.85
)
# Creates our _root_widget.
super().__init__(
@ -275,13 +274,39 @@ class PlayOptionsWindow(PopupWindow):
texture=bui.gettexture('lock'),
)
y_offs = 50 if show_shuffle_check_box else 0
# Series Length
y_offs2 = 40 if self._sessiontype is bs.DualTeamSession else 0
self._series_length_numedit = ConfigNumberEdit(
parent=self.root_widget,
position=(100, 200 + y_offs + y_offs2),
configkey=(
'FFA' if self._sessiontype is bs.FreeForAllSession else 'Teams'
)
+ ' Series Length',
displayname=bui.Lstr(
resource=self._r
+ (
'.pointsToWinText'
if self._sessiontype is bs.FreeForAllSession
else '.seriesLengthText'
)
),
minval=1.0,
increment=1.0 if self._sessiontype is bs.FreeForAllSession else 2.0,
fallback_value=(
24 if self._sessiontype is bs.FreeForAllSession else 7
),
f=0,
)
# Team names/colors.
self._custom_colors_names_button: bui.Widget | None
if self._sessiontype is bs.DualTeamSession:
y_offs = 50 if show_shuffle_check_box else 0
self._custom_colors_names_button = bui.buttonwidget(
parent=self.root_widget,
position=(100, 200 + y_offs),
position=(100, 195 + y_offs),
size=(290, 35),
on_activate_call=bui.WeakCall(self._custom_colors_names_press),
autoselect=True,
@ -304,9 +329,9 @@ class PlayOptionsWindow(PopupWindow):
def _cb_callback(val: bool) -> None:
self._do_randomize_val = val
cfg = bui.app.config
cfg[
self._pvars.config_name + ' Playlist Randomize'
] = self._do_randomize_val
cfg[self._pvars.config_name + ' Playlist Randomize'] = (
self._do_randomize_val
)
cfg.commit()
if show_shuffle_check_box:

View File

@ -223,12 +223,14 @@ class PopupMenuWindow(PopupWindow):
size=(self._width - 40, 28),
on_select_call=bui.Call(self._select, index),
click_activate=True,
color=(0.5, 0.5, 0.5, 0.5)
if inactive
else (
(0.5, 1, 0.5, 1)
if choice == self._current_choice
else (0.8, 0.8, 0.8, 1.0)
color=(
(0.5, 0.5, 0.5, 0.5)
if inactive
else (
(0.5, 1, 0.5, 1)
if choice == self._current_choice
else (0.8, 0.8, 0.8, 1.0)
)
),
padding=0,
maxwidth=maxwidth,
@ -318,9 +320,7 @@ class PopupMenu:
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
if current_choice not in choices:
current_choice = None

View File

@ -38,9 +38,7 @@ class ProfileBrowserWindow(bui.Window):
self._height = (
360.0
if uiscale is bui.UIScale.SMALL
else 385.0
if uiscale is bui.UIScale.MEDIUM
else 410.0
else 385.0 if uiscale is bui.UIScale.MEDIUM else 410.0
)
# If we're being called up standalone, handle pause/resume ourself.
@ -74,13 +72,11 @@ class ProfileBrowserWindow(bui.Window):
scale=(
2.2
if uiscale is bui.UIScale.SMALL
else 1.6
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -14) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -14)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
@ -125,9 +121,7 @@ class ProfileBrowserWindow(bui.Window):
scl = (
1.055
if uiscale is bui.UIScale.SMALL
else 1.18
if uiscale is bui.UIScale.MEDIUM
else 1.3
else 1.18 if uiscale is bui.UIScale.MEDIUM else 1.3
)
v -= 70.0 * scl
self._new_button = bui.buttonwidget(

View File

@ -65,17 +65,13 @@ class EditProfileWindow(bui.Window):
self._height = height = (
350.0
if uiscale is bui.UIScale.SMALL
else 400.0
if uiscale is bui.UIScale.MEDIUM
else 450.0
else 400.0 if uiscale is bui.UIScale.MEDIUM else 450.0
)
spacing = 40
self._base_scale = (
2.05
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
)
top_extra = 15 if uiscale is bui.UIScale.SMALL else 15
super().__init__(
@ -83,9 +79,9 @@ class EditProfileWindow(bui.Window):
size=(width, height + top_extra),
transition=transition,
scale=self._base_scale,
stack_offset=(0, 15)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, 15) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)
cancel_button = btn = bui.buttonwidget(
@ -475,9 +471,11 @@ class EditProfileWindow(bui.Window):
parent=self._root_widget,
autoselect=True,
position=(self._width * 0.5 + b_offs - b_size * 0.5, v - 50),
up_widget=self._upgrade_button
if self._upgrade_button is not None
else self._account_type_info_button,
up_widget=(
self._upgrade_button
if self._upgrade_button is not None
else self._account_type_info_button
),
size=(b_size, b_size),
color=self._highlight,
label='',
@ -803,6 +801,15 @@ class EditProfileWindow(bui.Window):
bui.getsound('error').play()
return False
# Make sure we're not renaming to another existing profile.
profiles: dict = bui.app.config.get('Player Profiles', {})
if self._existing_profile != new_name and new_name in profiles.keys():
bui.screenmessage(
bui.Lstr(resource='editProfileWindow.profileAlreadyExistsText')
)
bui.getsound('error').play()
return False
if transition_out:
bui.getsound('gunCocking').play()

View File

@ -39,9 +39,7 @@ class ProfileUpgradeWindow(bui.Window):
self._base_scale = (
2.05
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.2
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.2
)
self._upgrade_start_time: float | None = None
self._name = edit_profile_window.getname()
@ -54,9 +52,9 @@ class ProfileUpgradeWindow(bui.Window):
toolbar_visibility='menu_currency',
transition=transition,
scale=self._base_scale,
stack_offset=(0, 15)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, 15) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)
cancel_button = bui.buttonwidget(

View File

@ -47,9 +47,7 @@ class PromoCodeWindow(bui.Window):
scale=(
2.0
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -48,13 +48,11 @@ class PurchaseWindow(bui.Window):
scale=(
1.2
if uiscale is bui.UIScale.SMALL
else 1.1
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -15) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -15)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
self._is_double = False

View File

@ -19,9 +19,7 @@ class QRCodeWindow(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._transitioning_out = False
self._width = 450

View File

@ -29,9 +29,7 @@ class ReportPlayerWindow(bui.Window):
scale=(
1.8
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -19,9 +19,7 @@ class ResourceTypeInfoWindow(PopupWindow):
scale = (
2.3
if uiscale is bui.UIScale.SMALL
else 1.65
if uiscale is bui.UIScale.MEDIUM
else 1.23
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
)
self._transitioning_out = False
self._width = 570

View File

@ -51,9 +51,7 @@ class ServerDialogWindow(bui.Window):
scale=(
1.8
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)
@ -114,9 +112,11 @@ class ServerDialogWindow(bui.Window):
self._ok_button = bui.buttonwidget(
parent=self._root_widget,
position=(
(self._width - 182)
if (data.show_cancel or show_copy)
else (self._width * 0.5 - 80),
(
(self._width - 182)
if (data.show_cancel or show_copy)
else (self._width * 0.5 - 80)
),
30,
),
size=(160, 60),

View File

@ -1,6 +1,7 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality for advanced settings."""
# pylint: disable=too-many-lines
from __future__ import annotations
@ -52,9 +53,7 @@ class AdvancedSettingsWindow(bui.Window):
self._height = (
390.0
if uiscale is bui.UIScale.SMALL
else 450.0
if uiscale is bui.UIScale.MEDIUM
else 520.0
else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0
)
self._lang_status_text: bui.Widget | None = None
@ -71,13 +70,11 @@ class AdvancedSettingsWindow(bui.Window):
scale=(
2.06
if uiscale is bui.UIScale.SMALL
else 1.4
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -25) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -25)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
@ -112,6 +109,7 @@ class AdvancedSettingsWindow(bui.Window):
if self._do_net_test_button:
self._sub_height += self._extra_button_spacing
self._sub_height += self._spacing * 2.0 # plugins
self._sub_height += self._spacing * 2.0 # modding tools
self._r = 'settingsWindowAdvanced'
@ -196,36 +194,45 @@ class AdvancedSettingsWindow(bui.Window):
from bauiv1lib import promocode as _unused7
from bauiv1lib import debug as _unused8
from bauiv1lib.settings import plugins as _unused9
from bauiv1lib.settings import moddingtools as _unused10
def _update_lang_status(self) -> None:
if self._complete_langs_list is not None:
up_to_date = bui.app.lang.language in self._complete_langs_list
bui.textwidget(
edit=self._lang_status_text,
text=''
if bui.app.lang.language == 'Test'
else bui.Lstr(
resource=f'{self._r}.translationNoUpdateNeededText'
)
if up_to_date
else bui.Lstr(
resource=f'{self._r}.translationUpdateNeededText'
text=(
''
if bui.app.lang.language == 'Test'
else (
bui.Lstr(
resource=f'{self._r}.translationNoUpdateNeededText'
)
if up_to_date
else bui.Lstr(
resource=f'{self._r}.translationUpdateNeededText'
)
)
),
color=(
(0.2, 1.0, 0.2, 0.8) if up_to_date else (1.0, 0.2, 0.2, 0.8)
),
color=(0.2, 1.0, 0.2, 0.8)
if up_to_date
else (1.0, 0.2, 0.2, 0.8),
)
else:
bui.textwidget(
edit=self._lang_status_text,
text=bui.Lstr(resource=f'{self._r}.translationFetchErrorText')
if self._complete_langs_error
else bui.Lstr(
resource=f'{self._r}.translationFetchingStatusText'
text=(
bui.Lstr(resource=f'{self._r}.translationFetchErrorText')
if self._complete_langs_error
else bui.Lstr(
resource=f'{self._r}.translationFetchingStatusText'
)
),
color=(
(1.0, 0.5, 0.2)
if self._complete_langs_error
else (0.7, 0.7, 0.7)
),
color=(1.0, 0.5, 0.2)
if self._complete_langs_error
else (0.7, 0.7, 0.7),
)
def _rebuild(self) -> None:
@ -575,6 +582,19 @@ class AdvancedSettingsWindow(bui.Window):
bui.open_url, 'https://ballistica.net/wiki/modding-guide'
),
)
v -= self._spacing * 2.0
self._modding_tools_button = bui.buttonwidget(
parent=self._subcontainer,
position=(self._sub_width / 2 - this_button_width / 2, v - 10),
size=(this_button_width, 60),
autoselect=True,
label=bui.Lstr(resource=f'{self._r}.moddingToolsText'),
text_scale=1.0,
on_activate_call=self._on_modding_tools_button_press,
)
if self._show_always_use_internal_keyboard:
assert self._always_use_internal_keyboard_check_box is not None
bui.widget(
@ -763,6 +783,24 @@ class AdvancedSettingsWindow(bui.Window):
from_window=self._root_widget,
)
def _on_modding_tools_button_press(self) -> None:
# pylint: disable=cyclic-import
from bauiv1lib.settings.moddingtools import ModdingToolsWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window(
ModdingToolsWindow(
origin_widget=self._modding_tools_button
).get_root_widget(),
from_window=self._root_widget,
)
def _on_promo_code_press(self) -> None:
from bauiv1lib.promocode import PromoCodeWindow
from bauiv1lib.account import show_sign_in_prompt
@ -806,6 +844,7 @@ class AdvancedSettingsWindow(bui.Window):
def _save_state(self) -> None:
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
try:
sel = self._root_widget.get_selected_child()
if sel == self._scrollwidget:
@ -848,6 +887,8 @@ class AdvancedSettingsWindow(bui.Window):
sel_name = 'ShowUserMods'
elif sel == self._plugins_button:
sel_name = 'Plugins'
elif sel == self._modding_tools_button:
sel_name = 'ModdingTools'
elif sel == self._modding_guide_button:
sel_name = 'ModdingGuide'
elif sel == self._language_inform_checkbox:
@ -915,6 +956,8 @@ class AdvancedSettingsWindow(bui.Window):
sel = self._show_user_mods_button
elif sel_name == 'Plugins':
sel = self._plugins_button
elif sel_name == 'ModdingTools':
sel = self._modding_tools_button
elif sel_name == 'ModdingGuide':
sel = self._modding_guide_button
elif sel_name == 'LangInform':

View File

@ -56,13 +56,11 @@ class AllSettingsWindow(bui.Window):
scale=(
1.75
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -8) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -8)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)

View File

@ -63,9 +63,7 @@ class AudioSettingsWindow(bui.Window):
base_scale = (
2.05
if uiscale is bui.UIScale.SMALL
else 1.6
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
)
popup_menu_scale = base_scale * 1.2
@ -75,9 +73,9 @@ class AudioSettingsWindow(bui.Window):
transition=transition,
scale=base_scale,
scale_origin_stack_offset=scale_origin,
stack_offset=(0, -20)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, -20) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)

View File

@ -124,9 +124,7 @@ class ControlsSettingsWindow(bui.Window):
scale=(
smallscale
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
)
)

View File

@ -56,13 +56,11 @@ class GamepadSettingsWindow(bui.Window):
scale=(
1.63
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(-20, -16) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(-20, -16)
if uiscale is bui.UIScale.SMALL
else (0, 0),
transition=transition,
)
)
@ -549,16 +547,12 @@ class GamepadSettingsWindow(bui.Window):
sval1 = (
self._settings['analogStickLR' + self._ext]
if 'analogStickLR' + self._ext in self._settings
else 5
if self._is_secondary
else None
else 5 if self._is_secondary else None
)
sval2 = (
self._settings['analogStickUD' + self._ext]
if 'analogStickUD' + self._ext in self._settings
else 6
if self._is_secondary
else None
else 6 if self._is_secondary else None
)
assert isinstance(sval1, (int, type(None)))
assert isinstance(sval2, (int, type(None)))
@ -601,9 +595,7 @@ class GamepadSettingsWindow(bui.Window):
dpadnum = (
self._settings['dpad' + self._ext]
if 'dpad' + self._ext in self._settings
else 2
if self._is_secondary
else None
else 2 if self._is_secondary else None
)
assert isinstance(dpadnum, (int, type(None)))
if dpadnum is not None:
@ -971,9 +963,7 @@ class AwaitGamepadInputWindow(bui.Window):
scale=(
2.0
if uiscale is bui.UIScale.SMALL
else 1.9
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.9 if uiscale is bui.UIScale.MEDIUM else 1.0
),
size=(width, height),
transition='in_scale',

View File

@ -42,13 +42,11 @@ class GamepadAdvancedSettingsWindow(bui.Window):
* (
1.85
if uiscale is bui.UIScale.SMALL
else 1.35
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
),
stack_offset=(
(0, -25) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(0, -25)
if uiscale is bui.UIScale.SMALL
else (0, 0),
scale_origin_stack_offset=(advb.get_screen_space_center()),
)
)

View File

@ -45,9 +45,7 @@ def gamepad_configure_callback(event: dict[str, Any]) -> None:
scale=(
1.7
if uiscale is bui.UIScale.SMALL
else 1.4
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
),
size=(width, height),
transition='in_right',
@ -122,9 +120,7 @@ class GamepadSelectWindow(bui.Window):
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
size=(width, height),
transition='in_right',

View File

@ -75,9 +75,7 @@ class GraphicsSettingsWindow(bui.Window):
base_scale = (
2.0
if uiscale is bui.UIScale.SMALL
else 1.5
if uiscale is bui.UIScale.MEDIUM
else 1.0
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
)
popup_menu_scale = base_scale * 1.2
v = height - 50
@ -88,9 +86,9 @@ class GraphicsSettingsWindow(bui.Window):
transition=transition,
scale_origin_stack_offset=scale_origin,
scale=base_scale,
stack_offset=(0, -30)
if uiscale is bui.UIScale.SMALL
else (0, 0),
stack_offset=(
(0, -30) if uiscale is bui.UIScale.SMALL else (0, 0)
),
)
)
@ -174,9 +172,11 @@ class GraphicsSettingsWindow(bui.Window):
width=150,
scale=popup_menu_scale,
choices=['Auto', 'Higher', 'High', 'Medium', 'Low'],
choices_disabled=['Higher', 'High']
if bui.get_max_graphics_quality() == 'Medium'
else [],
choices_disabled=(
['Higher', 'High']
if bui.get_max_graphics_quality() == 'Medium'
else []
),
choices_display=[
bui.Lstr(resource='autoText'),
bui.Lstr(resource=self._r + '.higherText'),

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