Merge branch 'master' into tournament_entry

This commit is contained in:
TrialTemp 2024-03-13 19:41:05 -06:00 committed by GitHub
commit 7afbadabcd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
246 changed files with 3250 additions and 1917 deletions

109
.efrocachemap generated
View File

@ -421,8 +421,8 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "66f05313ffa9880373066332cff4594c", "build/assets/ba_data/data/langdata.json": "8409781047f46ca6627eacdfc0b4d3d3",
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88", "build/assets/ba_data/data/languages/arabic.json": "2c2915e10124bb8f69206da9c608d57c",
"build/assets/ba_data/data/languages/belarussian.json": "09954e550d13d3d9cb5a635a1d32a151", "build/assets/ba_data/data/languages/belarussian.json": "09954e550d13d3d9cb5a635a1d32a151",
"build/assets/ba_data/data/languages/chinese.json": "bb51b5aa614830c561e8fe2542a9ab8a", "build/assets/ba_data/data/languages/chinese.json": "bb51b5aa614830c561e8fe2542a9ab8a",
"build/assets/ba_data/data/languages/chinesetraditional.json": "319565f8a15667488f48dbce59278e39", "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/czech.json": "15be4fd59895135bad0265f79b362d5b",
"build/assets/ba_data/data/languages/danish.json": "8e57db30c5250df2abff14a822f83ea7", "build/assets/ba_data/data/languages/danish.json": "8e57db30c5250df2abff14a822f83ea7",
"build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343", "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/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/french.json": "917e4174d6f0eb7f00c27fd79cfbb924",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad", "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/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "90f54663e15d85a163f1848a8e9d8d07", "build/assets/ba_data/data/languages/hindi.json": "90f54663e15d85a163f1848a8e9d8d07",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e", "build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68", "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/korean.json": "4e3524327a0174250aff5e1ef4c0c597",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38", "build/assets/ba_data/data/languages/malay.json": "f6ce0426d03a62612e3e436ed5d1be1f",
"build/assets/ba_data/data/languages/persian.json": "c4144aebf2900fc655860de891d16f83", "build/assets/ba_data/data/languages/persian.json": "07eddcf92d3dcc7a745ea74e2b0007c8",
"build/assets/ba_data/data/languages/polish.json": "9d22c6643c097c4cb268d0d6b6319cd4", "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/romanian.json": "b3e46efd6f869dbd78014570e037c290",
"build/assets/ba_data/data/languages/russian.json": "0590f49889616b5279be569dea926e17", "build/assets/ba_data/data/languages/russian.json": "0590f49889616b5279be569dea926e17",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "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/thai.json": "1d665629361f302693dead39de8fa945",
"build/assets/ba_data/data/languages/turkish.json": "db71f3776072b7a15ef37b1bb1245795", "build/assets/ba_data/data/languages/turkish.json": "db71f3776072b7a15ef37b1bb1245795",
"build/assets/ba_data/data/languages/ukrainian.json": "3d75d21205c82db34fb1a1b014592747", "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/languages/vietnamese.json": "921cd1e50f60fe3e101f246e172750ba",
"build/assets/ba_data/data/maps/big_g.json": "1dd301d490643088a435ce75df971054", "build/assets/ba_data/data/maps/big_g.json": "1dd301d490643088a435ce75df971054",
"build/assets/ba_data/data/maps/bridgit.json": "6aea74805f4880cc11237c5734a24422", "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/_common.py": "5b52bdac4156dcbac96743fa99468bf2",
"build/assets/pylib-apple/zoneinfo/_tzpath.py": "f021e91036bd38590f2ce643b59dc881", "build/assets/pylib-apple/zoneinfo/_tzpath.py": "f021e91036bd38590f2ce643b59dc881",
"build/assets/pylib-apple/zoneinfo/_zoneinfo.py": "d000d61aa8998d0076c37f96cf40ca69", "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.pyd": "36024ca5f0f257dd4edfe1a3e92c1a07",
"build/assets/windows/Win32/DLLs/_asyncio_d.pyd": "a809fe3d7f3b6931e5f127821d0d30b6", "build/assets/windows/Win32/DLLs/_asyncio_d.pyd": "a809fe3d7f3b6931e5f127821d0d30b6",
"build/assets/windows/Win32/DLLs/_bz2.pyd": "cf535d3d0a020f0ae5ff20336a56ba3b", "build/assets/windows/Win32/DLLs/_bz2.pyd": "cf535d3d0a020f0ae5ff20336a56ba3b",
@ -4060,50 +4061,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "5db2ea1c6bacab3fe60eb948aaa4afdb", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "db921cf43e8ebf733712fb5bbc673f66",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "2b476166b869112112d57f26833a8381", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4be0f3a7a88da423847863af41ac9c63",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7b8d2cb654ab2c022584114ed9910c38", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7c92d738e7cc724de2ca31cb876224e6",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "846150203fe0611a71ff832176579ce5", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "c2f69ed83f77b602e2a2b2b1c1c78cc6",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "683c3d3b7ac3b052f3ecc3fef36fc13a", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b1c766d4ce567f965c53ff2a4c5c85f4",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "e41d6aeb7a2e335ebcc701a35d45df8c", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "86ebbd9111f8a0fe7905cef7aba1f6db",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f0a97f7c34a78bfd829f460a9f4ea81c", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "8182f4e00ad579eb4c7be5ec1ddca8cb",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d1e697c045e3b4092ec35fb8f3b4bd25", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "3d9e0e7ad8706133e61fb7f7127c3ff5",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "952c02766cecd280af3e9b77c80e91e1", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "5f98bf8b11376161a6f2f60900703f8a",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "bceae148212f47bfc9acf60ea52b1003", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "99d7d247a422eaa46737e3232408e879",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "e9ea0d09ba4af6253025cbe3aa8469cf", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "ffd6ad4dda003e9cd1434aa4a5bc9b09",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "d2cf18fbc6d815268790532bc38d2434", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "216efc77915b75f39f0f15c2806bfbb9",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "1134322221c0ccea4057e462d9fa5197", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "ad9829c065248ee3cde01b6a31deafed",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "30d10d34fb0e14b8f7ceec1760b521d6", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3e9e4e1761fd763eb584598fc0a3ad0a",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "d132bc58d9744941144244484bb005a6", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7522a6fcac27b2579f9cc0b712ce413b",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "5ae4aef6e0291175a3a9e3b77adcc0c0", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0c92e386ab7406da6a719131321bf592",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "abb92db084cdc165d7c1ed500be919ba", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "608cb03aef4dc547aa7433f83f898911",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "57bb6f6b5dadbc8f05fbab3271ef8abb", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "db136c26a3a37611aef68046f2fab62c",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "c4a68563f1237c1679c870def5d91b1a", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3edbd652fbc7afe69f60335bab00875a",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "e2f338fd1d4d8ff9a079e2e9c492aabb", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "48e5cd932b8c322be18b593508d5c451",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "56d6440f62c271c4ce9ef520400395a3",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ee36a39fd0f524989cb68930c89c8868", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "dbed9145e5db116d92aa47cb9e98da39", "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "56d6440f62c271c4ce9ef520400395a3",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "dc078f11a4e93062adc7d210fd4f08fb", "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "390a90cf4af1c55662c61ec19f9481bb",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "a74bea3380d0fb39f78ac7b7598c1a72", "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "e55895a55cc40f79be9e2e8095e8adf2",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "dc078f11a4e93062adc7d210fd4f08fb", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "390a90cf4af1c55662c61ec19f9481bb",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "a74bea3380d0fb39f78ac7b7598c1a72", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "e55895a55cc40f79be9e2e8095e8adf2",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "b397e020f33132c4dd2280cb1222cd14", "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "9846a6a3dd3685417fe834b91be8ac74",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "ff0cb4db976707d25bd401bce80a4882", "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "68087f1bac1513e92cabdb59c637e759",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "b397e020f33132c4dd2280cb1222cd14", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "9846a6a3dd3685417fe834b91be8ac74",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "ff0cb4db976707d25bd401bce80a4882", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "68087f1bac1513e92cabdb59c637e759",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "c464accef921df1325459bdd10c59b84", "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "72a7370f23c76ed8018999b78d88a545",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "c2cf0dc227e41a826c913d12e117c316",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "e53c808357cc0a2f0da7b870be147083", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "fbdc80e41c5883b4a893d2f0786e377f",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0896e849885cef50bcf33ce863efa7d2", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "c2cf0dc227e41a826c913d12e117c316",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "72901cf56d898442b6bcf4ecafd5cd65", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "73e6dd8dfba14ad1528d154ec43188c1",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c185b4f41dfc69c133a75260b95421d1", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "dfdb92bb0d84c405374e7da63c0eea4d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "096880b9e8faac99a72d234a61ddd624", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "c20a6bd8ea7212f52c291fb6134a9bad",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "266f4e6a3d8b39c97ee7b5e766e8b207", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "0e994a801d91149256f2200f75cf58d6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "0927775fb993a977de90e4671a09e996", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "de98295b7373dcf3c31d3cc5a135578b",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "53fcf97128862b34771ca967f88641c8", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "65e5b683dfa92a02909e8182d6b25d6e",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "160a2caaa393f9ddb40ffebc7546e6bb", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "f1e4e29d76abdb38e92a93f45135d1d8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "90716a0e1310a90247a9aee3a7a97a38", "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/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d", "src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -9,9 +9,9 @@ jobs:
make_linux_x86_64_gui_debug_build: make_linux_x86_64_gui_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -29,9 +29,9 @@ jobs:
make_linux_x86_64_server_debug_build: make_linux_x86_64_server_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -49,9 +49,9 @@ jobs:
make_linux_arm64_gui_debug_build: make_linux_arm64_gui_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -69,9 +69,9 @@ jobs:
make_linux_arm64_server_debug_build: make_linux_arm64_server_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -89,9 +89,9 @@ jobs:
make_mac_x86_64_gui_debug_build: make_mac_x86_64_gui_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -109,9 +109,9 @@ jobs:
make_mac_x86_64_server_debug_build: make_mac_x86_64_server_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -129,9 +129,9 @@ jobs:
make_mac_arm64_gui_debug_build: make_mac_arm64_gui_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -149,9 +149,9 @@ jobs:
make_mac_arm64_server_debug_build: make_mac_arm64_server_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -169,9 +169,9 @@ jobs:
make_windows_x86_gui_debug_build: make_windows_x86_gui_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -189,9 +189,9 @@ jobs:
make_windows_x86_server_debug_build: make_windows_x86_server_debug_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -206,3 +206,23 @@ jobs:
with: with:
name: windows_x86_server_(debug) name: windows_x86_server_(debug)
path: build/prefab/full/windows_x86_server 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: check_linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -33,9 +33,9 @@ jobs:
build_and_test_linux: build_and_test_linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -54,9 +54,9 @@ jobs:
spinoff_test_linux: spinoff_test_linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -75,9 +75,9 @@ jobs:
feature_set_copy_test_linux: feature_set_copy_test_linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
# Remove this once we upgrade to 3.12. # Remove this once we upgrade to 3.12.
@ -102,9 +102,9 @@ jobs:
build_and_test_windows: build_and_test_windows:
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install dependencies - 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 - 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). 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 - 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 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 catch problems where a base class changes or removes a method and child
classes forget to adapt to the change. 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!) - Custom spaz "curse_time" values now work properly. (Thanks Temp!)
- Implemented `efro.dataclassio.IOMultiType` which will make my life a lot - Implemented `efro.dataclassio.IOMultiType` which will make my life a lot
easier. easier.
@ -38,6 +42,9 @@
(Thanks EraOSBeta!) (Thanks EraOSBeta!)
- Added a 'Practice' button in tournaments, letting you play them free of - Added a 'Practice' button in tournaments, letting you play them free of
charge while not submitting scores. (Thanks Temp!) charge while not submitting scores. (Thanks Temp!)
- 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) ### 1.7.32 (build 21741, api 8, 2023-12-20)
- Fixed a screen message that no one will ever see (Thanks vishal332008?...) - Fixed a screen message that no one will ever see (Thanks vishal332008?...)

View File

@ -51,9 +51,16 @@
### Rikko ### Rikko
- Created the original "reject_recently_left_players" plugin - Created the original "reject_recently_left_players" plugin
### SoK
- Modder
- BSE Heartbeat mechanic port
### Temp (3alTemp) ### Temp (3alTemp)
- Original idea for customizable series length on GUI builds - Original idea for customizable series length on GUI builds
- Modder & Bug Fixer - Modder & Bug Fixer
### brostos ### brostos
- Added support for joining using ipv6 address - Added support for joining using ipv6 address
### Loup Garou
- Added sphinx documentation generation

View File

@ -183,6 +183,14 @@ docs:
docs-pdoc: docs-pdoc:
@$(PCOMMAND) gen_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 pcommandbatch_speed_test: prereqs
@$(PCOMMAND) pcommandbatch_speed_test $(PCOMMANDBATCH) @$(PCOMMAND) pcommandbatch_speed_test $(PCOMMANDBATCH)

View File

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

View File

@ -4487,6 +4487,8 @@
"pylib-apple/zoneinfo/_common.py", "pylib-apple/zoneinfo/_common.py",
"pylib-apple/zoneinfo/_tzpath.py", "pylib-apple/zoneinfo/_tzpath.py",
"pylib-apple/zoneinfo/_zoneinfo.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.pyd",
"windows/Win32/DLLs/_asyncio_d.pyd", "windows/Win32/DLLs/_asyncio_d.pyd",
"windows/Win32/DLLs/_bz2.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__/gamepadselect.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/graphics.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__/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__/nettesting.cpython-311.opt-1.pyc",
"ba_data/python/bauiv1lib/settings/__pycache__/plugins.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", "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/gamepadselect.py",
"ba_data/python/bauiv1lib/settings/graphics.py", "ba_data/python/bauiv1lib/settings/graphics.py",
"ba_data/python/bauiv1lib/settings/keyboard.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/nettesting.py",
"ba_data/python/bauiv1lib/settings/plugins.py", "ba_data/python/bauiv1lib/settings/plugins.py",
"ba_data/python/bauiv1lib/settings/pluginsettings.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/gamepadselect.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/graphics.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/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/nettesting.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/plugins.py \ $(BUILD_DIR)/ba_data/python/bauiv1lib/settings/plugins.py \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/pluginsettings.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__/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__/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__/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__/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__/plugins.cpython-311.opt-1.pyc \
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/pluginsettings.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/resolver.py \
$(BUILD_DIR)/ba_data/python-site-packages/yaml/scanner.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/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 = \ SCRIPT_TARGETS_PYC_PRIVATE_COMMON = \
$(BUILD_DIR)/ba_data/python-site-packages/_yaml/__pycache__/__init__.cpython-311.opt-1.pyc \ $(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__/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__/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__/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. # Rule to copy src asset scripts to dst.
# (and make non-writable so I'm less likely to accidentally edit them there) # (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}' path = f'{env.python_directory_user}/sys/{env.version}'
pathtmp = path + '_tmp' pathtmp = path + '_tmp'
if os.path.exists(path): if os.path.exists(path):
print('Delete Existing User Scripts and try again.') print('Delete Existing User Scripts first!')
_babase.screenmessage('Delete Existing User Scripts and try again.') _babase.screenmessage(
'Delete Existing User Scripts first!',
color=(1, 0, 0),
)
return return
if os.path.exists(pathtmp): if os.path.exists(pathtmp):
shutil.rmtree(pathtmp) shutil.rmtree(pathtmp)
@ -161,7 +164,7 @@ def create_user_system_scripts() -> None:
f"'\nRestart {_babase.appname()} to use them." f"'\nRestart {_babase.appname()} to use them."
f' (use babase.quit() to exit the game)' 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': if app.classic is not None and app.classic.platform == 'android':
print( print(
'Note: the new files may not be visible via ' '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'Restart {_babase.appname()} to use internal'
f' scripts. (use babase.quit() to exit the game)' 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: else:
print(f"User system scripts not found at '{path}'.") 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. # If the sys path is empty, kill it.
dpath = env.python_directory_user + '/sys' dpath = env.python_directory_user + '/sys'

View File

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

View File

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

View File

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

View File

@ -575,15 +575,18 @@ class ClassicSubsystem(babase.AppSubsystem):
) )
def get_input_device_mapped_value( def get_input_device_mapped_value(
self, device: bascenev1.InputDevice, name: str self,
device: bascenev1.InputDevice,
name: str,
default: bool = False,
) -> Any: ) -> 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 This checks the user config and falls back to default values
where available. where available.
""" """
return _input.get_input_device_mapped_value( 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( def get_input_device_map_hash(

View File

@ -35,9 +35,11 @@ def get_tournament_prize_strings(entry: dict[str, Any]) -> list[str]:
prval = ( prval = (
'' ''
if rng is None if rng is None
else ('#' + str(rng[0])) else (
if (rng[0] == rng[1]) ('#' + str(rng[0]))
else ('#' + str(rng[0]) + '-' + str(rng[1])) if (rng[0] == rng[1])
else ('#' + str(rng[0]) + '-' + str(rng[1]))
)
) )
pvval = '' pvval = ''
if trophy_type is not None: 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 # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21772 TARGET_BALLISTICA_BUILD = 21778
TARGET_BALLISTICA_VERSION = '1.7.33' TARGET_BALLISTICA_VERSION = '1.7.33'
@ -264,6 +264,10 @@ def _calc_data_dir(data_dir: str | None) -> str:
def _setup_logging() -> LogHandler: def _setup_logging() -> LogHandler:
from efro.log import setup_logging, LogLevel 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_handler = setup_logging(
log_path=None, log_path=None,
level=LogLevel.DEBUG, level=LogLevel.DEBUG,

View File

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

View File

@ -120,6 +120,7 @@ from _bascenev1 import (
release_keyboard_input, release_keyboard_input,
reset_random_player_names, reset_random_player_names,
resume_replay, resume_replay,
seek_replay,
broadcastmessage, broadcastmessage,
SessionData, SessionData,
SessionPlayer, SessionPlayer,
@ -404,6 +405,7 @@ __all__ = [
'release_keyboard_input', 'release_keyboard_input',
'reset_random_player_names', 'reset_random_player_names',
'resume_replay', 'resume_replay',
'seek_replay',
'safecolor', 'safecolor',
'screenmessage', 'screenmessage',
'SceneV1AppMode', 'SceneV1AppMode',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -396,11 +396,15 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
color=(0.45, 0.4, 0.5), color=(0.45, 0.4, 0.5),
position=(160, v_offs + 480), position=(160, v_offs + 480),
size=(350, 62), size=(350, 62),
label=bui.Lstr(resource='tournamentStandingsText') label=(
if self.session.tournament_id is not None bui.Lstr(resource='tournamentStandingsText')
else bui.Lstr(resource='worldsBestScoresText') if self.session.tournament_id is not None
if self._score_type == 'points' else (
else bui.Lstr(resource='worldsBestTimesText'), bui.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bui.Lstr(resource='worldsBestTimesText')
)
),
autoselect=True, autoselect=True,
on_activate_call=bui.WeakCall(self._ui_worlds_best), on_activate_call=bui.WeakCall(self._ui_worlds_best),
transition_delay=delay + 1.9, transition_delay=delay + 1.9,
@ -516,9 +520,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
bui.containerwidget( bui.containerwidget(
edit=rootc, edit=rootc,
selected_child=next_button selected_child=(
if (self._newly_complete and self._victory and show_next_button) next_button
else restart_button, if (self._newly_complete and self._victory and show_next_button)
else restart_button
),
on_cancel_call=menu_button.activate, on_cancel_call=menu_button.activate,
) )
@ -645,14 +651,16 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
and not (env.demo or env.arcade) and not (env.demo or env.arcade)
): ):
Text( Text(
bs.Lstr( (
value='${A}:\n', bs.Lstr(
subs=[('${A}', bs.Lstr(resource='levelUnlockedText'))], value='${A}:\n',
) subs=[('${A}', bs.Lstr(resource='levelUnlockedText'))],
if self._newly_complete )
else bs.Lstr( if self._newly_complete
value='${A}:\n', else bs.Lstr(
subs=[('${A}', bs.Lstr(resource='nextLevelText'))], value='${A}:\n',
subs=[('${A}', bs.Lstr(resource='nextLevelText'))],
)
), ),
transition=Text.Transition.IN_RIGHT, transition=Text.Transition.IN_RIGHT,
transition_delay=5.2, transition_delay=5.2,
@ -861,11 +869,15 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
ts_h_offs = 210 ts_h_offs = 210
v_offs = 40 v_offs = 40
txt = Text( txt = Text(
bs.Lstr(resource='tournamentStandingsText') (
if self.session.tournament_id is not None bs.Lstr(resource='tournamentStandingsText')
else bs.Lstr(resource='worldsBestScoresText') if self.session.tournament_id is not None
if self._score_type == 'points' else (
else bs.Lstr(resource='worldsBestTimesText'), bs.Lstr(resource='worldsBestScoresText')
if self._score_type == 'points'
else bs.Lstr(resource='worldsBestTimesText')
)
),
maxwidth=210, maxwidth=210,
position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20), position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20),
transition=Text.Transition.IN_LEFT, transition=Text.Transition.IN_LEFT,
@ -883,9 +895,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
ts_h_offs = -480 ts_h_offs = -480
v_offs = 40 v_offs = 40
Text( Text(
bs.Lstr(resource='yourBestScoresText') (
if self._score_type == 'points' bs.Lstr(resource='yourBestScoresText')
else bs.Lstr(resource='yourBestTimesText'), if self._score_type == 'points'
else bs.Lstr(resource='yourBestTimesText')
),
maxwidth=210, maxwidth=210,
position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20), position=(ts_h_offs - 10, ts_height / 2 + 25 + v_offs + 20),
transition=Text.Transition.IN_RIGHT, transition=Text.Transition.IN_RIGHT,
@ -949,9 +963,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
tdelay1 = times[i][0] tdelay1 = times[i][0]
tdelay2 = times[i][1] tdelay2 = times[i][1]
Text( Text(
str(display_scores[i][0]) (
if self._score_type == 'points' str(display_scores[i][0])
else bs.timestring((display_scores[i][0] * 10) / 1000.0), if self._score_type == 'points'
else bs.timestring((display_scores[i][0] * 10) / 1000.0)
),
position=( position=(
ts_h_offs + 20 + h_offs_extra, ts_h_offs + 20 + h_offs_extra,
v_offs_extra v_offs_extra
@ -1128,9 +1144,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
tdelay2 = times[i][1] tdelay2 = times[i][1]
if name_str != '-': if name_str != '-':
Text( Text(
str(score) (
if self._score_type == 'points' str(score)
else bs.timestring((score * 10) / 1000.0), if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0)
),
position=( position=(
ts_h_offs + 20 + h_offs_extra, ts_h_offs + 20 + h_offs_extra,
v_offs_extra v_offs_extra
@ -1314,9 +1332,11 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
if name_str != '-': if name_str != '-':
Text( Text(
str(score) (
if self._score_type == 'points' str(score)
else bs.timestring((score * 10) / 1000.0), if self._score_type == 'points'
else bs.timestring((score * 10) / 1000.0)
),
position=( position=(
ts_h_offs + 20 + h_offs_extra, ts_h_offs + 20 + h_offs_extra,
ts_height / 2 ts_height / 2
@ -1690,17 +1710,22 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
) )
if not self._newly_complete: if not self._newly_complete:
Text( Text(
bs.Lstr( (
value='${A}${B}', bs.Lstr(
subs=[ value='${A}${B}',
('${A}', bs.Lstr(resource='newPersonalBestText')), subs=[
('${B}', was_string), (
], '${A}',
) bs.Lstr(resource='newPersonalBestText'),
if new_best ),
else bs.Lstr( ('${B}', was_string),
resource='bestRatingText', ],
subs=[('${RATING}', str(best_rank))], )
if new_best
else bs.Lstr(
resource='bestRatingText',
subs=[('${RATING}', str(best_rank))],
)
), ),
position=(0, -165), position=(0, -165),
color=(1, 1, 1, 0.7), color=(1, 1, 1, 0.7),
@ -1775,14 +1800,16 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
jitter=1.0, jitter=1.0,
).autoretain() ).autoretain()
Text( Text(
bs.Lstr( (
value='${A}:', bs.Lstr(
subs=[('${A}', bs.Lstr(resource='finalScoreText'))], value='${A}:',
) subs=[('${A}', bs.Lstr(resource='finalScoreText'))],
if self._score_type == 'points' )
else bs.Lstr( if self._score_type == 'points'
value='${A}:', else bs.Lstr(
subs=[('${A}', bs.Lstr(resource='finalTimeText'))], value='${A}:',
subs=[('${A}', bs.Lstr(resource='finalTimeText'))],
)
), ),
maxwidth=300, maxwidth=300,
position=(0, 200), position=(0, 200),

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,9 @@ class RespawnIcon:
def __init__(self, player: bs.Player, respawn_time: float): def __init__(self, player: bs.Player, respawn_time: float):
"""Instantiate with a Player and respawn_time (in seconds).""" """Instantiate with a Player and respawn_time (in seconds)."""
# pylint: disable=too-many-locals
self._visible = True self._visible = True
self._dots_epic_only = False
on_right, offs_extra, respawn_icons = self._get_context(player) on_right, offs_extra, respawn_icons = self._get_context(player)
@ -92,7 +94,7 @@ class RespawnIcon:
assert self._name.node assert self._name.node
bs.animate(self._name.node, 'scale', {0: 0, 0.1: 0.5}) 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( self._text: bs.NodeActor | None = bs.NodeActor(
bs.newnode( bs.newnode(
'text', '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 assert self._text.node
bs.animate(self._text.node, 'scale', {0: 0, 0.1: 0.9}) 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._respawn_time = bs.time() + respawn_time
self._dec_timer: bs.Timer | None = None
self._update() self._update()
self._timer: bs.Timer | None = bs.Timer( self._timer: bs.Timer | None = bs.Timer(
1.0, bs.WeakCall(self._update), repeat=True 1.0, bs.WeakCall(self._update), repeat=True
@ -128,7 +156,7 @@ class RespawnIcon:
"""Return info on where we should be shown and stored.""" """Return info on where we should be shown and stored."""
activity = bs.getactivity() activity = bs.getactivity()
if isinstance(bs.getsession(), bs.DualTeamSession): if isinstance(activity.session, bs.DualTeamSession):
on_right = player.team.id % 2 == 1 on_right = player.team.id % 2 == 1
# Store a list of icons in the team. # Store a list of icons in the team.
@ -153,12 +181,43 @@ class RespawnIcon:
offs_extra = -20 offs_extra = -20
return on_right, offs_extra, icons 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: def _update(self) -> None:
remaining = int(round(self._respawn_time - bs.time())) remaining = int(round(self._respawn_time - bs.time()))
if remaining > 0: if remaining > 0:
assert self._text is not None assert self._text is not None
if self._text.node: if self._text.node:
self._text.node.text = str(remaining) 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: else:
self._visible = False 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 color = PRO_BOT_COLOR
highlight = PRO_BOT_HIGHLIGHT highlight = PRO_BOT_HIGHLIGHT
default_shields = True
default_boxing_gloves = True default_boxing_gloves = True
points_mult = 3 points_mult = 3

View File

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

View File

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

View File

@ -14,7 +14,7 @@ import random
import logging import logging
from enum import Enum from enum import Enum
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, cast, Sequence
from typing_extensions import override from typing_extensions import override
import bascenev1 as bs import bascenev1 as bs
@ -45,7 +45,7 @@ from bascenev1lib.actor.spazbot import (
) )
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any
class Preset(Enum): class Preset(Enum):
@ -190,6 +190,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
self._lives_text: bs.NodeActor | None = None self._lives_text: bs.NodeActor | None = None
self._flawless = True self._flawless = True
self._time_bonus_timer: bs.Timer | None = None 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_text: bs.NodeActor | None = None
self._time_bonus_mult: float | None = None self._time_bonus_mult: float | None = None
self._wave_text: bs.NodeActor | None = None self._wave_text: bs.NodeActor | None = None
@ -279,9 +280,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spacing(duration=1.0), Spacing(duration=1.0),
Spawn(TriggerBot, path=3), Spawn(TriggerBot, path=3),
Spacing(duration=1.0), Spacing(duration=1.0),
Spawn(TriggerBot, path=1) (
if (player_count > 1 and hard) Spawn(TriggerBot, path=1)
else None, if (player_count > 1 and hard)
else None
),
Spacing(duration=1.0), Spacing(duration=1.0),
Spawn(TriggerBot, path=2) if player_count > 2 else None, Spawn(TriggerBot, path=2) if player_count > 2 else None,
Spacing(duration=1.0), Spacing(duration=1.0),
@ -320,17 +323,23 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spacing(duration=1.5), Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1) if hard else None, Spawn(BomberBotProShielded, path=1) if hard else None,
Spacing(duration=1.5) if hard else None, Spacing(duration=1.5) if hard else None,
Spawn(BomberBotProShielded, path=3) (
if player_count > 1 Spawn(BomberBotProShielded, path=3)
else None, if player_count > 1
else None
),
Spacing(duration=1.5), Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=2) (
if player_count > 2 Spawn(BomberBotProShielded, path=2)
else None, if player_count > 2
else None
),
Spacing(duration=1.5), Spacing(duration=1.5),
Spawn(BomberBotProShielded, path=1) (
if player_count > 3 Spawn(BomberBotProShielded, path=1)
else None, if player_count > 3
else None
),
] ]
), ),
] ]
@ -352,9 +361,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
BrawlerBotPro if hard else BrawlerBot, BrawlerBotPro if hard else BrawlerBot,
point=Point.BOTTOM_LEFT, point=Point.BOTTOM_LEFT,
), ),
Spawn(BrawlerBotPro, point=Point.BOTTOM_RIGHT) (
if player_count > 2 Spawn(BrawlerBotPro, point=Point.BOTTOM_RIGHT)
else None, if player_count > 2
else None
),
] ]
), ),
Wave( Wave(
@ -375,9 +386,11 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spawn(BomberBotProShielded, path=3), Spawn(BomberBotProShielded, path=3),
Spawn(BomberBotProShielded, path=3), Spawn(BomberBotProShielded, path=3),
Spawn(ChargerBot, point=Point.BOTTOM_RIGHT), Spawn(ChargerBot, point=Point.BOTTOM_RIGHT),
Spawn(ChargerBot, point=Point.BOTTOM_LEFT) (
if player_count > 2 Spawn(ChargerBot, point=Point.BOTTOM_LEFT)
else None, if player_count > 2
else None
),
] ]
), ),
Wave( 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),
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 Spawn(TriggerBotPro, path=1 if hard else 2)
else None, if player_count > 1
Spawn(TriggerBotPro, path=1 if hard else 2) else None
if player_count > 3 ),
else None, (
Spawn(TriggerBotPro, path=1 if hard else 2)
if player_count > 3
else None
),
] ]
), ),
Wave( Wave(
@ -402,12 +419,20 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
TriggerBotProShielded if hard else TriggerBotPro, TriggerBotProShielded if hard else TriggerBotPro,
point=Point.BOTTOM_LEFT, point=Point.BOTTOM_LEFT,
), ),
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT) (
if hard Spawn(
else None, TriggerBotProShielded, point=Point.BOTTOM_RIGHT
Spawn(TriggerBotProShielded, point=Point.BOTTOM_RIGHT) )
if player_count > 2 if hard
else None, else None
),
(
Spawn(
TriggerBotProShielded, point=Point.BOTTOM_RIGHT
)
if player_count > 2
else None
),
Spawn(BomberBot, path=3), Spawn(BomberBot, path=3),
Spawn(BomberBot, path=3), Spawn(BomberBot, path=3),
Spacing(duration=5.0), Spacing(duration=5.0),
@ -425,15 +450,19 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
Spawn(StickyBot, point=Point.BOTTOM_RIGHT), Spawn(StickyBot, point=Point.BOTTOM_RIGHT),
Spawn(BomberBotProShielded, path=2), Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2), Spawn(BomberBotProShielded, path=2),
Spawn(StickyBot, point=Point.BOTTOM_RIGHT) (
if player_count > 2 Spawn(StickyBot, point=Point.BOTTOM_RIGHT)
else None, if player_count > 2
else None
),
Spawn(BomberBotProShielded, path=2), Spawn(BomberBotProShielded, path=2),
Spawn(ExplodeyBot, point=Point.BOTTOM_LEFT), Spawn(ExplodeyBot, point=Point.BOTTOM_LEFT),
Spawn(BomberBotProShielded, path=2), Spawn(BomberBotProShielded, path=2),
Spawn(BomberBotProShielded, path=2) (
if player_count > 1 Spawn(BomberBotProShielded, path=2)
else None, if player_count > 1
else None
),
Spacing(duration=5.0), Spacing(duration=5.0),
Spawn(StickyBot, point=Point.BOTTOM_LEFT), Spawn(StickyBot, point=Point.BOTTOM_LEFT),
Spacing(duration=2.0), Spacing(duration=2.0),
@ -461,9 +490,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
l_offs = ( l_offs = (
-80 -80
if uiscale is bs.UIScale.SMALL if uiscale is bs.UIScale.SMALL
else -40 else -40 if uiscale is bs.UIScale.MEDIUM else 0
if uiscale is bs.UIScale.MEDIUM
else 0
) )
self._lives_bg = bs.NodeActor( self._lives_bg = bs.NodeActor(
@ -525,6 +552,18 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
if self._lives == 0: if self._lives == 0:
self._bots.stop_moving() self._bots.stop_moving()
self.continue_or_end_game() 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 is not None
assert self._lives_text.node assert self._lives_text.node
self._lives_text.node.text = str(self._lives) 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: def _set_can_end_wave(self) -> None:
self._can_end_wave = True 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( bs.getsound(
'orchestraHit4' 'orchestraHit4'
if streak > 3 if streak > 3
else 'orchestraHit3' else (
if streak > 2 'orchestraHit3'
else 'orchestraHit2' if streak > 2
if streak > 1 else (
else 'orchestraHit' 'orchestraHit2'
if streak > 1
else 'orchestraHit'
)
)
).play() ).play()
elif dist <= self._r2 + self._rfudge: elif dist <= self._r2 + self._rfudge:
self._nodes[0].color = cdull self._nodes[0].color = cdull

View File

@ -43,7 +43,10 @@ class UIV1Subsystem(babase.AppSubsystem):
self._uiscale: babase.UIScale 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': if interfacetype == 'large':
self._uiscale = babase.UIScale.LARGE self._uiscale = babase.UIScale.LARGE
elif interfacetype == 'medium': elif interfacetype == 'medium':

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,13 +51,11 @@ class CreditsListWindow(bui.Window):
scale=( scale=(
2.0 2.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.3 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
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 = ( self._height = height = (
350 350
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 420 else 420 if uiscale is bui.UIScale.MEDIUM else 520
if uiscale is bui.UIScale.MEDIUM
else 520
) )
self._scroll_width = self._width - 100 self._scroll_width = self._width - 100
@ -50,13 +48,11 @@ class DebugWindow(bui.Window):
scale=( scale=(
2.35 2.35
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.55 else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.0
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=( scale=(
1.6 1.6
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.3 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 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=( scale=(
1.6 1.6
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
) )
v = height - 50 v = height - 50

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -72,13 +72,11 @@ class GetCurrencyWindow(bui.Window):
scale=( scale=(
1.63 1.63
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.2 else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
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 = ( self._smooth_increase_speed = (
diff / 100.0 diff / 100.0
if diff >= 5000 if diff >= 5000
else diff / 50.0 else (
if diff >= 1500 diff / 50.0
else diff / 30.0 if diff >= 1500
if diff >= 500 else diff / 30.0 if diff >= 500 else diff / 15.0
else diff / 15.0 )
) )
def _disabled_press(self) -> None: def _disabled_press(self) -> None:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,9 +43,11 @@ class MainMenuWindow(bui.Window):
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
transition=transition, transition=transition,
toolbar_visibility='menu_minimal_no_back' toolbar_visibility=(
if self._in_game 'menu_minimal_no_back'
else 'menu_minimal_no_back', if self._in_game
else 'menu_minimal_no_back'
),
) )
) )
@ -142,9 +144,11 @@ class MainMenuWindow(bui.Window):
return ( return (
'storeCharacterXmas' 'storeCharacterXmas'
if plus.get_v1_account_misc_read_val('xmas', False) if plus.get_v1_account_misc_read_val('xmas', False)
else 'storeCharacterEaster' else (
if plus.get_v1_account_misc_read_val('easter', False) 'storeCharacterEaster'
else 'storeCharacter' if plus.get_v1_account_misc_read_val('easter', False)
else 'storeCharacter'
)
) )
def _check_refresh(self) -> None: def _check_refresh(self) -> None:
@ -344,9 +348,7 @@ class MainMenuWindow(bui.Window):
icon_size = ( icon_size = (
55 55
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 55 else 55 if uiscale is bui.UIScale.MEDIUM else 70
if uiscale is bui.UIScale.MEDIUM
else 70
) )
bui.imagewidget( bui.imagewidget(
parent=self._root_widget, parent=self._root_widget,
@ -452,7 +454,7 @@ class MainMenuWindow(bui.Window):
resource='watchWindow.playbackSpeedText', resource='watchWindow.playbackSpeedText',
subs=[('${SPEED}', str(1.23))], subs=[('${SPEED}', str(1.23))],
), ),
position=(h, v + v_offs + 7 * t_scale), position=(h, v + v_offs + 15 * t_scale),
h_align='center', h_align='center',
v_align='center', v_align='center',
size=(0, 0), size=(0, 0),
@ -526,6 +528,64 @@ class MainMenuWindow(bui.Window):
autoselect=True, autoselect=True,
on_activate_call=bui.Call(self._pause_or_resume_replay), 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( def _refresh_not_in_game(
self, positions: list[tuple[float, float, float]] self, positions: list[tuple[float, float, float]]
@ -646,9 +706,11 @@ class MainMenuWindow(bui.Window):
color=(0.45, 0.55, 0.45), color=(0.45, 0.55, 0.45),
textcolor=(0.7, 0.8, 0.7), textcolor=(0.7, 0.8, 0.7),
label=bui.Lstr( label=bui.Lstr(
resource='modeArcadeText' resource=(
if bui.app.env.arcade 'modeArcadeText'
else 'modeDemoText' if bui.app.env.arcade
else 'modeDemoText'
)
), ),
transition_delay=demo_menu_delay, transition_delay=demo_menu_delay,
on_activate_call=self._demo_menu_press, on_activate_call=self._demo_menu_press,
@ -659,9 +721,7 @@ class MainMenuWindow(bui.Window):
foof = ( foof = (
-1 -1
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1 else 1 if uiscale is bui.UIScale.MEDIUM else 3
if uiscale is bui.UIScale.MEDIUM
else 3
) )
h, v, scale = positions[self._p_index] h, v, scale = positions[self._p_index]
v = v + foof v = v + foof
@ -906,9 +966,7 @@ class MainMenuWindow(bui.Window):
scale=( scale=(
2.15 2.15
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.6 else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
) )
h = 125.0 h = 125.0
@ -1398,8 +1456,9 @@ class MainMenuWindow(bui.Window):
def _resume(self) -> None: def _resume(self) -> None:
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.classic.resume() bui.app.classic.resume()
if self._root_widget: # if self._root_widget:
bui.containerwidget(edit=self._root_widget, transition='out_right') # bui.containerwidget(edit=self._root_widget,
# transition='out_right')
bui.app.ui_v1.clear_main_menu_window(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. # 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 = ( self._height = (
365 365
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 480 else 480 if uiscale is bui.UIScale.MEDIUM else 600
if uiscale is bui.UIScale.MEDIUM
else 600
) )
self._display_old_msgs = True self._display_old_msgs = True
super().__init__( super().__init__(
@ -52,15 +50,15 @@ class PartyWindow(bui.Window):
scale=( scale=(
2.0 2.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
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=( scale=(
2.3 2.3
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.65 else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
if uiscale is bui.UIScale.MEDIUM
else 1.23
), ),
choices=choices, choices=choices,
choices_display=choices_display, choices_display=choices_display,
@ -312,9 +308,7 @@ class PartyWindow(bui.Window):
columns = ( columns = (
1 1
if len(self._roster) == 1 if len(self._roster) == 1
else 2 else 2 if len(self._roster) == 2 else 3
if len(self._roster) == 2
else 3
) )
rows = int(math.ceil(float(len(self._roster)) / columns)) rows = int(math.ceil(float(len(self._roster)) / columns))
c_width = (self._width * 0.9) / max(3, columns) c_width = (self._width * 0.9) / max(3, columns)
@ -572,9 +566,7 @@ class PartyWindow(bui.Window):
scale=( scale=(
2.3 2.3
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.65 else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
if uiscale is bui.UIScale.MEDIUM
else 1.23
), ),
choices=['kick'], choices=['kick'],
choices_display=[kick_str], choices_display=[kick_str],

View File

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

View File

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

View File

@ -30,9 +30,7 @@ class PlaylistAddGameWindow(bui.Window):
self._height = ( self._height = (
346 346
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 380 else 380 if uiscale is bui.UIScale.MEDIUM else 440
if uiscale is bui.UIScale.MEDIUM
else 440
) )
top_extra = 30 if uiscale is bui.UIScale.SMALL else 20 top_extra = 30 if uiscale is bui.UIScale.SMALL else 20
self._scroll_width = 210 self._scroll_width = 210
@ -44,9 +42,7 @@ class PlaylistAddGameWindow(bui.Window):
scale=( scale=(
2.17 2.17
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.5 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
stack_offset=(0, 1) if uiscale is bui.UIScale.SMALL else (0, 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 = ( self._height = (
480 480
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 510 else 510 if uiscale is bui.UIScale.MEDIUM else 580
if uiscale is bui.UIScale.MEDIUM
else 580
) )
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
@ -83,13 +81,11 @@ class PlaylistBrowserWindow(bui.Window):
scale=( scale=(
1.69 1.69
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.05 else 1.05 if uiscale is bui.UIScale.MEDIUM else 0.9
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: if self._selected_playlist != prev_sel:
cfg = bui.app.config cfg = bui.app.config
cfg[ cfg[self._pvars.config_name + ' Playlist Selection'] = (
self._pvars.config_name + ' Playlist Selection' self._selected_playlist
] = self._selected_playlist )
cfg.commit() cfg.commit()
self._save_state() self._save_state()

View File

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

View File

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

View File

@ -49,9 +49,7 @@ class PlaylistMapSelectWindow(bui.Window):
height = ( height = (
400 400
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 480 else 480 if uiscale is bui.UIScale.MEDIUM else 600
if uiscale is bui.UIScale.MEDIUM
else 600
) )
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
@ -62,13 +60,11 @@ class PlaylistMapSelectWindow(bui.Window):
scale=( scale=(
2.17 2.17
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.3 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
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=( scale=(
1.8 1.8
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
) )
) )

View File

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

View File

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

View File

@ -65,17 +65,13 @@ class EditProfileWindow(bui.Window):
self._height = height = ( self._height = height = (
350.0 350.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 400.0 else 400.0 if uiscale is bui.UIScale.MEDIUM else 450.0
if uiscale is bui.UIScale.MEDIUM
else 450.0
) )
spacing = 40 spacing = 40
self._base_scale = ( self._base_scale = (
2.05 2.05
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.5 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
) )
top_extra = 15 if uiscale is bui.UIScale.SMALL else 15 top_extra = 15 if uiscale is bui.UIScale.SMALL else 15
super().__init__( super().__init__(
@ -83,9 +79,9 @@ class EditProfileWindow(bui.Window):
size=(width, height + top_extra), size=(width, height + top_extra),
transition=transition, transition=transition,
scale=self._base_scale, scale=self._base_scale,
stack_offset=(0, 15) stack_offset=(
if uiscale is bui.UIScale.SMALL (0, 15) if uiscale is bui.UIScale.SMALL else (0, 0)
else (0, 0), ),
) )
) )
cancel_button = btn = bui.buttonwidget( cancel_button = btn = bui.buttonwidget(
@ -475,9 +471,11 @@ class EditProfileWindow(bui.Window):
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,
position=(self._width * 0.5 + b_offs - b_size * 0.5, v - 50), position=(self._width * 0.5 + b_offs - b_size * 0.5, v - 50),
up_widget=self._upgrade_button up_widget=(
if self._upgrade_button is not None self._upgrade_button
else self._account_type_info_button, if self._upgrade_button is not None
else self._account_type_info_button
),
size=(b_size, b_size), size=(b_size, b_size),
color=self._highlight, color=self._highlight,
label='', label='',
@ -803,6 +801,15 @@ class EditProfileWindow(bui.Window):
bui.getsound('error').play() bui.getsound('error').play()
return False 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: if transition_out:
bui.getsound('gunCocking').play() bui.getsound('gunCocking').play()

View File

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

View File

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

View File

@ -48,13 +48,11 @@ class PurchaseWindow(bui.Window):
scale=( scale=(
1.2 1.2
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.1 else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0
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 self._is_double = False

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
"""UI functionality for advanced settings.""" """UI functionality for advanced settings."""
# pylint: disable=too-many-lines
from __future__ import annotations from __future__ import annotations
@ -52,9 +53,7 @@ class AdvancedSettingsWindow(bui.Window):
self._height = ( self._height = (
390.0 390.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 450.0 else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0
if uiscale is bui.UIScale.MEDIUM
else 520.0
) )
self._lang_status_text: bui.Widget | None = None self._lang_status_text: bui.Widget | None = None
@ -71,13 +70,11 @@ class AdvancedSettingsWindow(bui.Window):
scale=( scale=(
2.06 2.06
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.4 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
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: if self._do_net_test_button:
self._sub_height += self._extra_button_spacing self._sub_height += self._extra_button_spacing
self._sub_height += self._spacing * 2.0 # plugins self._sub_height += self._spacing * 2.0 # plugins
self._sub_height += self._spacing * 2.0 # modding tools
self._r = 'settingsWindowAdvanced' self._r = 'settingsWindowAdvanced'
@ -196,36 +194,45 @@ class AdvancedSettingsWindow(bui.Window):
from bauiv1lib import promocode as _unused7 from bauiv1lib import promocode as _unused7
from bauiv1lib import debug as _unused8 from bauiv1lib import debug as _unused8
from bauiv1lib.settings import plugins as _unused9 from bauiv1lib.settings import plugins as _unused9
from bauiv1lib.settings import moddingtools as _unused10
def _update_lang_status(self) -> None: def _update_lang_status(self) -> None:
if self._complete_langs_list is not None: if self._complete_langs_list is not None:
up_to_date = bui.app.lang.language in self._complete_langs_list up_to_date = bui.app.lang.language in self._complete_langs_list
bui.textwidget( bui.textwidget(
edit=self._lang_status_text, edit=self._lang_status_text,
text='' text=(
if bui.app.lang.language == 'Test' ''
else bui.Lstr( if bui.app.lang.language == 'Test'
resource=f'{self._r}.translationNoUpdateNeededText' else (
) bui.Lstr(
if up_to_date resource=f'{self._r}.translationNoUpdateNeededText'
else bui.Lstr( )
resource=f'{self._r}.translationUpdateNeededText' 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: else:
bui.textwidget( bui.textwidget(
edit=self._lang_status_text, edit=self._lang_status_text,
text=bui.Lstr(resource=f'{self._r}.translationFetchErrorText') text=(
if self._complete_langs_error bui.Lstr(resource=f'{self._r}.translationFetchErrorText')
else bui.Lstr( if self._complete_langs_error
resource=f'{self._r}.translationFetchingStatusText' 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: def _rebuild(self) -> None:
@ -575,6 +582,19 @@ class AdvancedSettingsWindow(bui.Window):
bui.open_url, 'https://ballistica.net/wiki/modding-guide' 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: if self._show_always_use_internal_keyboard:
assert self._always_use_internal_keyboard_check_box is not None assert self._always_use_internal_keyboard_check_box is not None
bui.widget( bui.widget(
@ -763,6 +783,24 @@ class AdvancedSettingsWindow(bui.Window):
from_window=self._root_widget, 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: def _on_promo_code_press(self) -> None:
from bauiv1lib.promocode import PromoCodeWindow from bauiv1lib.promocode import PromoCodeWindow
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt
@ -806,6 +844,7 @@ class AdvancedSettingsWindow(bui.Window):
def _save_state(self) -> None: def _save_state(self) -> None:
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# pylint: disable=too-many-statements
try: try:
sel = self._root_widget.get_selected_child() sel = self._root_widget.get_selected_child()
if sel == self._scrollwidget: if sel == self._scrollwidget:
@ -848,6 +887,8 @@ class AdvancedSettingsWindow(bui.Window):
sel_name = 'ShowUserMods' sel_name = 'ShowUserMods'
elif sel == self._plugins_button: elif sel == self._plugins_button:
sel_name = 'Plugins' sel_name = 'Plugins'
elif sel == self._modding_tools_button:
sel_name = 'ModdingTools'
elif sel == self._modding_guide_button: elif sel == self._modding_guide_button:
sel_name = 'ModdingGuide' sel_name = 'ModdingGuide'
elif sel == self._language_inform_checkbox: elif sel == self._language_inform_checkbox:
@ -915,6 +956,8 @@ class AdvancedSettingsWindow(bui.Window):
sel = self._show_user_mods_button sel = self._show_user_mods_button
elif sel_name == 'Plugins': elif sel_name == 'Plugins':
sel = self._plugins_button sel = self._plugins_button
elif sel_name == 'ModdingTools':
sel = self._modding_tools_button
elif sel_name == 'ModdingGuide': elif sel_name == 'ModdingGuide':
sel = self._modding_guide_button sel = self._modding_guide_button
elif sel_name == 'LangInform': elif sel_name == 'LangInform':

View File

@ -56,13 +56,11 @@ class AllSettingsWindow(bui.Window):
scale=( scale=(
1.75 1.75
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
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 = ( base_scale = (
2.05 2.05
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.6 else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
) )
popup_menu_scale = base_scale * 1.2 popup_menu_scale = base_scale * 1.2
@ -75,9 +73,9 @@ class AudioSettingsWindow(bui.Window):
transition=transition, transition=transition,
scale=base_scale, scale=base_scale,
scale_origin_stack_offset=scale_origin, scale_origin_stack_offset=scale_origin,
stack_offset=(0, -20) stack_offset=(
if uiscale is bui.UIScale.SMALL (0, -20) if uiscale is bui.UIScale.SMALL else (0, 0)
else (0, 0), ),
) )
) )

View File

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

View File

@ -1,5 +1,6 @@
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
# pylint: disable=too-many-lines
"""Settings UI functionality related to gamepads.""" """Settings UI functionality related to gamepads."""
from __future__ import annotations from __future__ import annotations
@ -7,16 +8,20 @@ from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from bauiv1lib.popup import PopupMenuWindow
import bascenev1 as bs import bascenev1 as bs
import bauiv1 as bui import bauiv1 as bui
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Callable from typing import Any, Callable
from bauiv1lib.popup import PopupWindow
class GamepadSettingsWindow(bui.Window): class GamepadSettingsWindow(bui.Window):
"""Window for configuring a gamepad.""" """Window for configuring a gamepad."""
# pylint: disable=too-many-public-methods
def __init__( def __init__(
self, self,
gamepad: bs.InputDevice, gamepad: bs.InputDevice,
@ -34,7 +39,6 @@ class GamepadSettingsWindow(bui.Window):
self._name = self._input.name self._name = self._input.name
self._r = 'configGamepadWindow' self._r = 'configGamepadWindow'
self._settings = settings
self._transition_out = transition_out self._transition_out = transition_out
# We're a secondary gamepad if supplied with settings. # We're a secondary gamepad if supplied with settings.
@ -53,23 +57,90 @@ class GamepadSettingsWindow(bui.Window):
scale=( scale=(
1.63 1.63
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
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, 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. # Don't ask to config joysticks while we're in here.
self._rebuild_ui() 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-statements
# pylint: disable=too-many-locals
assert bui.app.classic is not None assert bui.app.classic is not None
@ -79,77 +150,6 @@ class GamepadSettingsWindow(bui.Window):
self._textwidgets: dict[str, bui.Widget] = {} 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 back_button: bui.Widget | None
if self._is_secondary: if self._is_secondary:
@ -369,22 +369,27 @@ class GamepadSettingsWindow(bui.Window):
scale=1.0, scale=1.0,
) )
self._advanced_button = bui.buttonwidget( self._more_button = bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,
label=bui.Lstr(resource=self._r + '.advancedText'), label='...',
text_scale=0.9, text_scale=0.9,
color=(0.45, 0.4, 0.5), color=(0.45, 0.4, 0.5),
textcolor=(0.65, 0.6, 0.7), textcolor=(0.65, 0.6, 0.7),
position=(self._width - 300, 30), position=(self._width - 300, 30),
size=(130, 40), size=(130, 40),
on_activate_call=self._do_advanced, on_activate_call=self._do_more,
) )
try: try:
if cancel_button is not None and save_button is not None: if cancel_button is not None and save_button is not None:
bui.widget(edit=cancel_button, right_widget=save_button) bui.widget(edit=cancel_button, right_widget=save_button)
bui.widget(edit=save_button, left_widget=cancel_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: except Exception:
logging.exception('Error wiring up gamepad config window.') logging.exception('Error wiring up gamepad config window.')
@ -394,7 +399,7 @@ class GamepadSettingsWindow(bui.Window):
def get_advanced_button(self) -> bui.Widget: def get_advanced_button(self) -> bui.Widget:
"""(internal)""" """(internal)"""
return self._advanced_button return self._more_button
def get_is_secondary(self) -> bool: def get_is_secondary(self) -> bool:
"""(internal)""" """(internal)"""
@ -543,16 +548,12 @@ class GamepadSettingsWindow(bui.Window):
sval1 = ( sval1 = (
self._settings['analogStickLR' + self._ext] self._settings['analogStickLR' + self._ext]
if 'analogStickLR' + self._ext in self._settings if 'analogStickLR' + self._ext in self._settings
else 5 else 5 if self._is_secondary else None
if self._is_secondary
else None
) )
sval2 = ( sval2 = (
self._settings['analogStickUD' + self._ext] self._settings['analogStickUD' + self._ext]
if 'analogStickUD' + self._ext in self._settings if 'analogStickUD' + self._ext in self._settings
else 6 else 6 if self._is_secondary else None
if self._is_secondary
else None
) )
assert isinstance(sval1, (int, type(None))) assert isinstance(sval1, (int, type(None)))
assert isinstance(sval2, (int, type(None))) assert isinstance(sval2, (int, type(None)))
@ -595,9 +596,7 @@ class GamepadSettingsWindow(bui.Window):
dpadnum = ( dpadnum = (
self._settings['dpad' + self._ext] self._settings['dpad' + self._ext]
if 'dpad' + self._ext in self._settings if 'dpad' + self._ext in self._settings
else 2 else 2 if self._is_secondary else None
if self._is_secondary
else None
) )
assert isinstance(dpadnum, (int, type(None))) assert isinstance(dpadnum, (int, type(None)))
if dpadnum is not None: if dpadnum is not None:
@ -809,6 +808,77 @@ class GamepadSettingsWindow(bui.Window):
from_window=self._root_widget, 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: def _save(self) -> None:
classic = bui.app.classic classic = bui.app.classic
assert classic is not None assert classic is not None
@ -893,9 +963,7 @@ class AwaitGamepadInputWindow(bui.Window):
scale=( scale=(
2.0 2.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.9 else 1.9 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
size=(width, height), size=(width, height),
transition='in_scale', transition='in_scale',

View File

@ -42,13 +42,11 @@ class GamepadAdvancedSettingsWindow(bui.Window):
* ( * (
1.85 1.85
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.35 else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
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()), 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=( scale=(
1.7 1.7
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.4 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
size=(width, height), size=(width, height),
transition='in_right', transition='in_right',
@ -122,9 +120,7 @@ class GamepadSelectWindow(bui.Window):
scale=( scale=(
2.3 2.3
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.5 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
size=(width, height), size=(width, height),
transition='in_right', transition='in_right',

View File

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

View File

@ -6,11 +6,13 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from bauiv1lib.popup import PopupMenuWindow
import bauiv1 as bui import bauiv1 as bui
import bascenev1 as bs import bascenev1 as bs
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
from bauiv1lib.popup import PopupWindow
class ConfigKeyboardWindow(bui.Window): class ConfigKeyboardWindow(bui.Window):
@ -39,25 +41,19 @@ class ConfigKeyboardWindow(bui.Window):
scale=( scale=(
1.6 1.6
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.3 else 1.3 if uiscale is bui.UIScale.MEDIUM else 1.0
if uiscale is bui.UIScale.MEDIUM
else 1.0
), ),
stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 0), stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 0),
transition=transition, transition=transition,
) )
) )
self._settings: dict[str, int] = {}
self._get_config_mapping()
self._rebuild_ui() self._rebuild_ui()
def _rebuild_ui(self) -> None: def _get_config_mapping(self, default: bool = False) -> 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] = {}
for button in [ for button in [
'buttonJump', 'buttonJump',
'buttonPunch', 'buttonPunch',
@ -70,12 +66,20 @@ class ConfigKeyboardWindow(bui.Window):
'buttonLeft', 'buttonLeft',
'buttonRight', 'buttonRight',
]: ]:
self._settings[ assert bui.app.classic is not None
button self._settings[button] = (
] = bui.app.classic.get_input_device_mapped_value( bui.app.classic.get_input_device_mapped_value(
self._input, button 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( cancel_button = bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,
@ -101,9 +105,6 @@ class ConfigKeyboardWindow(bui.Window):
start_button=save_button, 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 v = self._height - 74.0
bui.textwidget( bui.textwidget(
parent=self._root_widget, parent=self._root_widget,
@ -213,6 +214,24 @@ class ConfigKeyboardWindow(bui.Window):
scale=1.0, 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: def _pretty_button_name(self, button_name: str) -> bui.Lstr:
button_id = self._settings[button_name] button_id = self._settings[button_name]
if button_id == -1: if button_id == -1:
@ -282,6 +301,63 @@ class ConfigKeyboardWindow(bui.Window):
from_window=self._root_widget, 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: def _save(self) -> None:
from bauiv1lib.settings.controls import ControlsSettingsWindow from bauiv1lib.settings.controls import ControlsSettingsWindow
@ -347,9 +423,7 @@ class AwaitKeyboardInputWindow(bui.Window):
scale=( scale=(
2.0 2.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.5 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
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=( scale=(
1.56 1.56
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.2 else 1.2 if uiscale is bui.UIScale.MEDIUM else 0.8
if uiscale is bui.UIScale.MEDIUM
else 0.8
), ),
stack_offset=(0.0, -7 if uiscale is bui.UIScale.SMALL else 0.0), stack_offset=(0.0, -7 if uiscale is bui.UIScale.SMALL else 0.0),
transition=transition, transition=transition,

View File

@ -58,9 +58,7 @@ class PluginWindow(bui.Window):
self._height = ( self._height = (
390.0 390.0
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 450.0 else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0
if uiscale is bui.UIScale.MEDIUM
else 520.0
) )
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0 top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
super().__init__( super().__init__(
@ -72,13 +70,11 @@ class PluginWindow(bui.Window):
scale=( scale=(
2.06 2.06
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.4 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
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=( scale=(
2.3 2.3
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
else 1.65 else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
if uiscale is bui.UIScale.MEDIUM
else 1.23
), ),
choices=[c.value for c in Category], choices=[c.value for c in Category],
choices_display=[bui.Lstr(resource=c.resource) for c in Category], choices_display=[bui.Lstr(resource=c.resource) for c in Category],
@ -365,9 +359,11 @@ class PluginWindow(bui.Window):
textcolor=( textcolor=(
(0.8, 0.3, 0.3) (0.8, 0.3, 0.3)
if (plugspec.attempted_load and plugspec.plugin is None) if (plugspec.attempted_load and plugspec.plugin is None)
else (0.6, 0.6, 0.6) else (
if plugspec.plugin is None (0.6, 0.6, 0.6)
else (0, 1, 0) if plugspec.plugin is None
else (0, 1, 0)
)
), ),
) )
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences

View File

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

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