Merge branch 'master' into hex-color-pick

This commit is contained in:
TrialTemp 2024-03-13 19:04:17 -06:00 committed by GitHub
commit 35eef88689
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
245 changed files with 3247 additions and 1921 deletions

109
.efrocachemap generated
View File

@ -421,8 +421,8 @@
"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": "66f05313ffa9880373066332cff4594c",
"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": "bb51b5aa614830c561e8fe2542a9ab8a",
"build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39",
@ -430,22 +430,22 @@
"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": "6501b04faba1d81e26725dfa19b15667",
"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/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": "0c1c4ac59d82a58c4b89328d44510d72",
"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": "fc6440be9ba1846172cf5e11df617c05",
"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": "c4144aebf2900fc655860de891d16f83",
"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": "0590f49889616b5279be569dea926e17",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
@ -456,7 +456,7 @@
"build/assets/ba_data/data/languages/thai.json": "1d665629361f302693dead39de8fa945",
"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": "f896fc3df13a42f1bef8813ca80b1a09",
"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": "5db2ea1c6bacab3fe60eb948aaa4afdb",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "2b476166b869112112d57f26833a8381",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7b8d2cb654ab2c022584114ed9910c38",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "846150203fe0611a71ff832176579ce5",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "683c3d3b7ac3b052f3ecc3fef36fc13a",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "e41d6aeb7a2e335ebcc701a35d45df8c",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f0a97f7c34a78bfd829f460a9f4ea81c",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d1e697c045e3b4092ec35fb8f3b4bd25",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "952c02766cecd280af3e9b77c80e91e1",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "bceae148212f47bfc9acf60ea52b1003",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "e9ea0d09ba4af6253025cbe3aa8469cf",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "d2cf18fbc6d815268790532bc38d2434",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "1134322221c0ccea4057e462d9fa5197",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "30d10d34fb0e14b8f7ceec1760b521d6",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "d132bc58d9744941144244484bb005a6",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "5ae4aef6e0291175a3a9e3b77adcc0c0",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "abb92db084cdc165d7c1ed500be919ba",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "57bb6f6b5dadbc8f05fbab3271ef8abb",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "c4a68563f1237c1679c870def5d91b1a",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "e2f338fd1d4d8ff9a079e2e9c492aabb",
"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": "72901cf56d898442b6bcf4ecafd5cd65",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c185b4f41dfc69c133a75260b95421d1",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "096880b9e8faac99a72d234a61ddd624",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "266f4e6a3d8b39c97ee7b5e766e8b207",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "0927775fb993a977de90e4671a09e996",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "53fcf97128862b34771ca967f88641c8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "160a2caaa393f9ddb40ffebc7546e6bb",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "90716a0e1310a90247a9aee3a7a97a38",
"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": "5f98bf8b11376161a6f2f60900703f8a",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "99d7d247a422eaa46737e3232408e879",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "ffd6ad4dda003e9cd1434aa4a5bc9b09",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "216efc77915b75f39f0f15c2806bfbb9",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "ad9829c065248ee3cde01b6a31deafed",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3e9e4e1761fd763eb584598fc0a3ad0a",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7522a6fcac27b2579f9cc0b712ce413b",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0c92e386ab7406da6a719131321bf592",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "608cb03aef4dc547aa7433f83f898911",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "db136c26a3a37611aef68046f2fab62c",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3edbd652fbc7afe69f60335bab00875a",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "48e5cd932b8c322be18b593508d5c451",
"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": "73e6dd8dfba14ad1528d154ec43188c1",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "dfdb92bb0d84c405374e7da63c0eea4d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "c20a6bd8ea7212f52c291fb6134a9bad",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "0e994a801d91149256f2200f75cf58d6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "de98295b7373dcf3c31d3cc5a135578b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "65e5b683dfa92a02909e8182d6b25d6e",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "f1e4e29d76abdb38e92a93f45135d1d8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "8089cf4b541d14dc38ae71f3d05bde8e",
"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 21772, api 8, 2024-03-02)
### 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
@ -20,6 +20,10 @@
languages; I feel it helps keep logic more understandable and should help us
catch problems where a base class changes or removes a method and child
classes forget to adapt to the change.
- 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.
@ -37,6 +41,9 @@
- Added a UI for customizing Series Length in Teams and Points-to-Win in FFA
(Thanks EraOSBeta!)
- Implemented HEX code support to the advanced color picker (Thanks 3alTemp!)
- 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?...)

View File

@ -51,9 +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,8 +136,11 @@ def create_user_system_scripts() -> None:
path = f'{env.python_directory_user}/sys/{env.version}'
pathtmp = path + '_tmp'
if os.path.exists(path):
print('Delete Existing User Scripts and try again.')
_babase.screenmessage('Delete Existing User Scripts and try again.')
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)
@ -161,7 +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')
_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 '
@ -186,9 +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')
_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

@ -13,7 +13,10 @@ if TYPE_CHECKING:
def get_input_device_mapped_value(
devicename: str, unique_id: str, name: str
devicename: str,
unique_id: str,
name: str,
default: bool = False,
) -> Any:
"""Returns a mapped value for an input device.
@ -30,8 +33,9 @@ def get_input_device_mapped_value(
subplatform = app.classic.subplatform
appconfig = babase.app.config
# If there's an entry in our config for this controller, use it.
if 'Controllers' in appconfig:
# If there's an entry in our config for this controller and
# we're not looking for our default mappings, use it.
if 'Controllers' in appconfig and not default:
ccfgs = appconfig['Controllers']
if devicename in ccfgs:
mapping = None

View File

@ -575,15 +575,18 @@ class ClassicSubsystem(babase.AppSubsystem):
)
def get_input_device_mapped_value(
self, device: bascenev1.InputDevice, name: str
self,
device: bascenev1.InputDevice,
name: str,
default: bool = False,
) -> Any:
"""Returns a mapped value for an input device.
"""Return a mapped value for an input device.
This checks the user config and falls back to default values
where available.
"""
return _input.get_input_device_mapped_value(
device.name, device.unique_identifier, name
device.name, device.unique_identifier, name, default
)
def get_input_device_map_hash(

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 = 21772
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,
@ -404,6 +405,7 @@ __all__ = [
'release_keyboard_input',
'reset_random_player_names',
'resume_replay',
'seek_replay',
'safecolor',
'screenmessage',
'SceneV1AppMode',

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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -1,5 +1,6 @@
# Released under the MIT License. See LICENSE for details.
#
# pylint: disable=too-many-lines
"""Settings UI functionality related to gamepads."""
from __future__ import annotations
@ -7,16 +8,20 @@ from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from bauiv1lib.popup import PopupMenuWindow
import bascenev1 as bs
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Callable
from bauiv1lib.popup import PopupWindow
class GamepadSettingsWindow(bui.Window):
"""Window for configuring a gamepad."""
# pylint: disable=too-many-public-methods
def __init__(
self,
gamepad: bs.InputDevice,
@ -34,7 +39,6 @@ class GamepadSettingsWindow(bui.Window):
self._name = self._input.name
self._r = 'configGamepadWindow'
self._settings = settings
self._transition_out = transition_out
# We're a secondary gamepad if supplied with settings.
@ -53,23 +57,90 @@ 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,
)
)
self._settings: dict[str, int] = {}
if not self._is_secondary:
self._get_config_mapping()
# Don't ask to config joysticks while we're in here.
self._rebuild_ui()
def _rebuild_ui(self) -> None:
def _get_config_mapping(self, default: bool = False) -> None:
for button in [
'buttonJump',
'buttonJump_B',
'buttonPunch',
'buttonPunch_B',
'buttonBomb',
'buttonBomb_B',
'buttonPickUp',
'buttonPickUp_B',
'buttonStart',
'buttonStart_B',
'buttonStart2',
'buttonStart2_B',
'buttonUp',
'buttonUp_B',
'buttonDown',
'buttonDown_B',
'buttonLeft',
'buttonLeft_B',
'buttonRight',
'buttonRight_B',
'buttonRun1',
'buttonRun1_B',
'buttonRun2',
'buttonRun2_B',
'triggerRun1',
'triggerRun1_B',
'triggerRun2',
'triggerRun2_B',
'buttonIgnored',
'buttonIgnored_B',
'buttonIgnored2',
'buttonIgnored2_B',
'buttonIgnored3',
'buttonIgnored3_B',
'buttonIgnored4',
'buttonIgnored4_B',
'buttonVRReorient',
'buttonVRReorient_B',
'analogStickDeadZone',
'analogStickDeadZone_B',
'dpad',
'dpad_B',
'unassignedButtonsRun',
'unassignedButtonsRun_B',
'startButtonActivatesDefaultWidget',
'startButtonActivatesDefaultWidget_B',
'uiOnly',
'uiOnly_B',
'ignoreCompletely',
'ignoreCompletely_B',
'autoRecalibrateAnalogStick',
'autoRecalibrateAnalogStick_B',
'analogStickLR',
'analogStickLR_B',
'analogStickUD',
'analogStickUD_B',
'enableSecondary',
]:
assert bui.app.classic is not None
val = bui.app.classic.get_input_device_mapped_value(
self._input, button, default
)
if val != -1:
self._settings[button] = val
def _rebuild_ui(self, is_reset: bool = False) -> None:
# pylint: disable=too-many-statements
# pylint: disable=too-many-locals
assert bui.app.classic is not None
@ -79,77 +150,6 @@ class GamepadSettingsWindow(bui.Window):
self._textwidgets: dict[str, bui.Widget] = {}
# If we were supplied with settings, we're a secondary joystick and
# just operate on that. in the other (normal) case we make our own.
if not self._is_secondary:
# Fill our temp config with present values (for our primary and
# secondary controls).
self._settings = {}
for skey in [
'buttonJump',
'buttonJump_B',
'buttonPunch',
'buttonPunch_B',
'buttonBomb',
'buttonBomb_B',
'buttonPickUp',
'buttonPickUp_B',
'buttonStart',
'buttonStart_B',
'buttonStart2',
'buttonStart2_B',
'buttonUp',
'buttonUp_B',
'buttonDown',
'buttonDown_B',
'buttonLeft',
'buttonLeft_B',
'buttonRight',
'buttonRight_B',
'buttonRun1',
'buttonRun1_B',
'buttonRun2',
'buttonRun2_B',
'triggerRun1',
'triggerRun1_B',
'triggerRun2',
'triggerRun2_B',
'buttonIgnored',
'buttonIgnored_B',
'buttonIgnored2',
'buttonIgnored2_B',
'buttonIgnored3',
'buttonIgnored3_B',
'buttonIgnored4',
'buttonIgnored4_B',
'buttonVRReorient',
'buttonVRReorient_B',
'analogStickDeadZone',
'analogStickDeadZone_B',
'dpad',
'dpad_B',
'unassignedButtonsRun',
'unassignedButtonsRun_B',
'startButtonActivatesDefaultWidget',
'startButtonActivatesDefaultWidget_B',
'uiOnly',
'uiOnly_B',
'ignoreCompletely',
'ignoreCompletely_B',
'autoRecalibrateAnalogStick',
'autoRecalibrateAnalogStick_B',
'analogStickLR',
'analogStickLR_B',
'analogStickUD',
'analogStickUD_B',
'enableSecondary',
]:
val = bui.app.classic.get_input_device_mapped_value(
self._input, skey
)
if val != -1:
self._settings[skey] = val
back_button: bui.Widget | None
if self._is_secondary:
@ -369,22 +369,27 @@ class GamepadSettingsWindow(bui.Window):
scale=1.0,
)
self._advanced_button = bui.buttonwidget(
self._more_button = bui.buttonwidget(
parent=self._root_widget,
autoselect=True,
label=bui.Lstr(resource=self._r + '.advancedText'),
label='...',
text_scale=0.9,
color=(0.45, 0.4, 0.5),
textcolor=(0.65, 0.6, 0.7),
position=(self._width - 300, 30),
size=(130, 40),
on_activate_call=self._do_advanced,
on_activate_call=self._do_more,
)
try:
if cancel_button is not None and save_button is not None:
bui.widget(edit=cancel_button, right_widget=save_button)
bui.widget(edit=save_button, left_widget=cancel_button)
if is_reset:
bui.containerwidget(
edit=self._root_widget,
selected_child=self._more_button,
)
except Exception:
logging.exception('Error wiring up gamepad config window.')
@ -394,7 +399,7 @@ class GamepadSettingsWindow(bui.Window):
def get_advanced_button(self) -> bui.Widget:
"""(internal)"""
return self._advanced_button
return self._more_button
def get_is_secondary(self) -> bool:
"""(internal)"""
@ -543,16 +548,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)))
@ -595,9 +596,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:
@ -809,6 +808,77 @@ class GamepadSettingsWindow(bui.Window):
from_window=self._root_widget,
)
def _reset(self) -> None:
from bauiv1lib.confirm import ConfirmWindow
assert bui.app.classic is not None
ConfirmWindow(
# TODO: Implement a translation string for this!
'Are you sure you want to reset your button mapping?\n'
'This will also reset your advanced mappings\n'
'and secondary controller button mappings.',
self._do_reset,
width=490,
height=150,
)
def _do_reset(self) -> None:
"""Resets the input's mapping settings."""
from babase import InputDeviceNotFoundError
self._settings = {}
# Unplugging the controller while performing a
# mapping reset makes things go bonkers a little.
try:
self._get_config_mapping(default=True)
except InputDeviceNotFoundError:
pass
self._rebuild_ui(is_reset=True)
bui.getsound('gunCocking').play()
def _do_more(self) -> None:
"""Show a burger menu with extra settings."""
# pylint: disable=cyclic-import
choices: list[str] = [
'advanced',
'reset',
]
choices_display: list[bui.Lstr] = [
bui.Lstr(resource=self._r + '.advancedText'),
bui.Lstr(resource='settingsWindowAdvanced.resetText'),
]
uiscale = bui.app.ui_v1.uiscale
PopupMenuWindow(
position=self._more_button.get_screen_space_center(),
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
),
width=150,
choices=choices,
choices_display=choices_display,
current_choice='advanced',
delegate=self,
)
def popup_menu_selected_choice(
self, popup_window: PopupMenuWindow, choice: str
) -> None:
"""Called when a choice is selected in the popup."""
del popup_window # unused
if choice == 'reset':
self._reset()
elif choice == 'advanced':
self._do_advanced()
else:
print(f'invalid choice: {choice}')
def popup_menu_closing(self, popup_window: PopupWindow) -> None:
"""Called when the popup is closing."""
def _save(self) -> None:
classic = bui.app.classic
assert classic is not None
@ -893,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'),

View File

@ -6,11 +6,13 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from bauiv1lib.popup import PopupMenuWindow
import bauiv1 as bui
import bascenev1 as bs
if TYPE_CHECKING:
from typing import Any
from bauiv1lib.popup import PopupWindow
class ConfigKeyboardWindow(bui.Window):
@ -39,25 +41,19 @@ class ConfigKeyboardWindow(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),
transition=transition,
)
)
self._settings: dict[str, int] = {}
self._get_config_mapping()
self._rebuild_ui()
def _rebuild_ui(self) -> None:
assert bui.app.classic is not None
for widget in self._root_widget.get_children():
widget.delete()
# Fill our temp config with present values.
self._settings: dict[str, int] = {}
def _get_config_mapping(self, default: bool = False) -> None:
for button in [
'buttonJump',
'buttonPunch',
@ -70,12 +66,20 @@ class ConfigKeyboardWindow(bui.Window):
'buttonLeft',
'buttonRight',
]:
self._settings[
button
] = bui.app.classic.get_input_device_mapped_value(
self._input, button
assert bui.app.classic is not None
self._settings[button] = (
bui.app.classic.get_input_device_mapped_value(
self._input, button, default
)
)
def _rebuild_ui(self, is_reset: bool = False) -> None:
assert bui.app.classic is not None
for widget in self._root_widget.get_children():
widget.delete()
# b_off = 0 if self._unique_id != '#1' else 9
cancel_button = bui.buttonwidget(
parent=self._root_widget,
autoselect=True,
@ -101,9 +105,6 @@ class ConfigKeyboardWindow(bui.Window):
start_button=save_button,
)
bui.widget(edit=cancel_button, right_widget=save_button)
bui.widget(edit=save_button, left_widget=cancel_button)
v = self._height - 74.0
bui.textwidget(
parent=self._root_widget,
@ -213,6 +214,24 @@ class ConfigKeyboardWindow(bui.Window):
scale=1.0,
)
self._more_button = bui.buttonwidget(
parent=self._root_widget,
autoselect=True,
label='...',
text_scale=0.9,
color=(0.45, 0.4, 0.5),
textcolor=(0.65, 0.6, 0.7),
position=(self._width * 0.5 - 65, 30),
size=(130, 40),
on_activate_call=self._do_more,
)
if is_reset:
bui.containerwidget(
edit=self._root_widget,
selected_child=self._more_button,
)
def _pretty_button_name(self, button_name: str) -> bui.Lstr:
button_id = self._settings[button_name]
if button_id == -1:
@ -282,6 +301,63 @@ class ConfigKeyboardWindow(bui.Window):
from_window=self._root_widget,
)
def _reset(self) -> None:
from bauiv1lib.confirm import ConfirmWindow
assert bui.app.classic is not None
ConfirmWindow(
# TODO: Implement a translation string for this!
'Are you sure you want to reset your button mapping?',
self._do_reset,
width=480,
height=95,
)
def _do_reset(self) -> None:
"""Resets the input's mapping settings."""
self._settings = {}
self._get_config_mapping(default=True)
self._rebuild_ui(is_reset=True)
bui.getsound('gunCocking').play()
def _do_more(self) -> None:
"""Show a burger menu with extra settings."""
# pylint: disable=cyclic-import
choices: list[str] = [
'reset',
]
choices_display: list[bui.Lstr] = [
bui.Lstr(resource='settingsWindowAdvanced.resetText'),
]
uiscale = bui.app.ui_v1.uiscale
PopupMenuWindow(
position=self._more_button.get_screen_space_center(),
scale=(
2.3
if uiscale is bui.UIScale.SMALL
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
),
width=150,
choices=choices,
choices_display=choices_display,
current_choice='reset',
delegate=self,
)
def popup_menu_selected_choice(
self, popup_window: PopupMenuWindow, choice: str
) -> None:
"""Called when a choice is selected in the popup."""
del popup_window # unused
if choice == 'reset':
self._reset()
else:
print(f'invalid choice: {choice}')
def popup_menu_closing(self, popup_window: PopupWindow) -> None:
"""Called when the popup is closing."""
def _save(self) -> None:
from bauiv1lib.settings.controls import ControlsSettingsWindow
@ -347,9 +423,7 @@ class AwaitKeyboardInputWindow(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

@ -0,0 +1,207 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality for Modding Tools."""
from __future__ import annotations
import babase
import bauiv1 as bui
from bauiv1lib.popup import PopupMenu
from bauiv1lib.confirm import ConfirmWindow
class ModdingToolsWindow(bui.Window):
"""Window for accessing modding tools."""
def __init__(
self,
transition: str = 'in_right',
origin_widget: bui.Widget | None = None,
):
app = bui.app
assert app.classic is not None
# If they provided an origin-widget, scale up from that.
scale_origin: tuple[float, float] | None
if origin_widget is not None:
self._transition_out = 'out_scale'
scale_origin = origin_widget.get_screen_space_center()
transition = 'in_scale'
else:
self._transition_out = 'out_right'
scale_origin = None
uiscale = app.ui_v1.uiscale
self._width = 970.0 if uiscale is bui.UIScale.SMALL else 670.0
x_inset = 150 if uiscale is bui.UIScale.SMALL else 0
self._height = (
390.0
if uiscale is bui.UIScale.SMALL
else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0
)
self._spacing = 32
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
self._scroll_width = self._width - (100 + 2 * x_inset)
self._scroll_height = self._height - 115.0
self._sub_width = self._scroll_width * 0.95
self._sub_height = 100.0
super().__init__(
root_widget=bui.containerwidget(
size=(self._width, self._height + top_extra),
transition=transition,
toolbar_visibility='menu_minimal',
scale_origin_stack_offset=scale_origin,
scale=(
2.06
if uiscale is bui.UIScale.SMALL
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)
),
)
)
self._r = 'settingsModdingTools'
if app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
bui.containerwidget(
edit=self._root_widget, on_cancel_call=self._do_back
)
self._back_button = None
else:
self._back_button = bui.buttonwidget(
parent=self._root_widget,
position=(53 + x_inset, self._height - 60),
size=(140, 60),
scale=0.8,
autoselect=True,
label=bui.Lstr(resource='backText'),
button_type='back',
on_activate_call=self._do_back,
)
bui.containerwidget(
edit=self._root_widget, cancel_button=self._back_button
)
self._title_text = bui.textwidget(
parent=self._root_widget,
position=(0, self._height - 52),
size=(self._width, 25),
text=bui.Lstr(resource='moddingToolsTitleText'),
color=app.ui_v1.title_color,
h_align='center',
v_align='top',
)
if self._back_button is not None:
bui.buttonwidget(
edit=self._back_button,
button_type='backSmall',
size=(60, 60),
label=bui.charstr(bui.SpecialChar.BACK),
)
self._scrollwidget = bui.scrollwidget(
parent=self._root_widget,
position=(50 + x_inset, 50),
simple_culling_v=20.0,
highlight=False,
size=(self._scroll_width, self._scroll_height),
selection_loops_to_parent=True,
)
bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
self._subcontainer = bui.containerwidget(
parent=self._scrollwidget,
size=(self._sub_width, self._sub_height),
background=False,
selection_loops_to_parent=True,
)
v = self._sub_height - 35
this_button_width = 410
v -= self._spacing * 1.2
self._create_user_system_scripts_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='createUserSystemScriptsText'),
text_scale=1.0,
on_activate_call=babase.modutils.create_user_system_scripts,
)
v -= self._spacing * 2.5
self._delete_user_system_scripts_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='deleteUserSystemScriptsText'),
text_scale=1.0,
on_activate_call=lambda: ConfirmWindow(
action=babase.modutils.delete_user_system_scripts,
),
)
v -= self._spacing * 2.5
bui.textwidget(
parent=self._subcontainer,
position=(170, v + 10),
size=(0, 0),
text=bui.Lstr(value='UI SIZE :'),
color=app.ui_v1.title_color,
h_align='center',
v_align='center',
)
PopupMenu(
parent=self._subcontainer,
position=(230, v - 20),
button_size=(200.0, 60.0),
choices=[
'auto',
'small',
'medium',
'large',
],
choices_display=[
bui.Lstr(resource='autoText'),
bui.Lstr(resource='smallText'),
bui.Lstr(resource='mediumText'),
bui.Lstr(resource='largeText'),
],
current_choice=app.config.get('UI Scale', 'auto'),
on_value_change_call=self._set_uiscale,
)
def _set_uiscale(self, val: str) -> None:
cfg = bui.app.config
cfg['UI Scale'] = val
cfg.apply_and_commit()
if bui.app.ui_v1.uiscale.name != val.upper():
bui.screenmessage(
bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
color=(1.0, 0.5, 0.0),
)
def _do_back(self) -> None:
from bauiv1lib.settings.advanced import AdvancedSettingsWindow
# 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
bui.containerwidget(
edit=self._root_widget, transition=self._transition_out
)
assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window(
AdvancedSettingsWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
)

View File

@ -37,9 +37,7 @@ class NetTestingWindow(bui.Window):
scale=(
1.56
if uiscale is bui.UIScale.SMALL
else 1.2
if uiscale is bui.UIScale.MEDIUM
else 0.8
else 1.2 if uiscale is bui.UIScale.MEDIUM else 0.8
),
stack_offset=(0.0, -7 if uiscale is bui.UIScale.SMALL else 0.0),
transition=transition,

View File

@ -58,9 +58,7 @@ class PluginWindow(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
)
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
super().__init__(
@ -72,13 +70,11 @@ class PluginWindow(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),
)
)
@ -252,9 +248,7 @@ class PluginWindow(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=[c.value for c in Category],
choices_display=[bui.Lstr(resource=c.resource) for c in Category],
@ -365,9 +359,11 @@ class PluginWindow(bui.Window):
textcolor=(
(0.8, 0.3, 0.3)
if (plugspec.attempted_load and plugspec.plugin is None)
else (0.6, 0.6, 0.6)
if plugspec.plugin is None
else (0, 1, 0)
else (
(0.6, 0.6, 0.6)
if plugspec.plugin is None
else (0, 1, 0)
)
),
)
# noinspection PyUnresolvedReferences

View File

@ -22,9 +22,7 @@ class PluginSettingsWindow(bui.Window):
height = (
365.0
if uiscale is bui.UIScale.SMALL
else 300.0
if uiscale is bui.UIScale.MEDIUM
else 370.0
else 300.0 if uiscale is bui.UIScale.MEDIUM else 370.0
)
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
@ -37,13 +35,11 @@ class PluginSettingsWindow(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),
)
)

View File

@ -24,13 +24,11 @@ class RemoteAppSettingsWindow(bui.Window):
scale=(
1.85
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=(
(-10, 0) if uiscale is bui.UIScale.SMALL else (0, 0)
),
stack_offset=(-10, 0)
if uiscale is bui.UIScale.SMALL
else (0, 0),
)
)
btn = bui.buttonwidget(

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