mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 13:25:31 +08:00
Lots of stuff. Chests now functional for tourneys
This commit is contained in:
parent
690da5a3da
commit
2190568baf
111
.efrocachemap
generated
111
.efrocachemap
generated
@ -53,6 +53,7 @@
|
|||||||
"build/assets/ba_data/audio/assassinFall.ogg": "201d192debe8bda9e9dead28e9cc6939",
|
"build/assets/ba_data/audio/assassinFall.ogg": "201d192debe8bda9e9dead28e9cc6939",
|
||||||
"build/assets/ba_data/audio/assassinHit1.ogg": "caaab755b159e399b121be1aec8f61b9",
|
"build/assets/ba_data/audio/assassinHit1.ogg": "caaab755b159e399b121be1aec8f61b9",
|
||||||
"build/assets/ba_data/audio/assassinHit2.ogg": "a08ac94f02040af67bc46eff6a691a84",
|
"build/assets/ba_data/audio/assassinHit2.ogg": "a08ac94f02040af67bc46eff6a691a84",
|
||||||
|
"build/assets/ba_data/audio/aww.ogg": "80cf7a35a58ec6633d3c5440764de3f5",
|
||||||
"build/assets/ba_data/audio/bear1.ogg": "acddcf643e9fbf8d92eacf50992c81d0",
|
"build/assets/ba_data/audio/bear1.ogg": "acddcf643e9fbf8d92eacf50992c81d0",
|
||||||
"build/assets/ba_data/audio/bear2.ogg": "74f7ce4f64e0fb943ab4ec34fdc83779",
|
"build/assets/ba_data/audio/bear2.ogg": "74f7ce4f64e0fb943ab4ec34fdc83779",
|
||||||
"build/assets/ba_data/audio/bear3.ogg": "142d1f3d021c8639fbbc1a2ed0f3dc93",
|
"build/assets/ba_data/audio/bear3.ogg": "142d1f3d021c8639fbbc1a2ed0f3dc93",
|
||||||
@ -95,6 +96,7 @@
|
|||||||
"build/assets/ba_data/audio/cheer.ogg": "b9f1cce825ca00295b61b088f353715b",
|
"build/assets/ba_data/audio/cheer.ogg": "b9f1cce825ca00295b61b088f353715b",
|
||||||
"build/assets/ba_data/audio/click01.ogg": "204f93a3eb7d82cf8ca9172ee5f01c11",
|
"build/assets/ba_data/audio/click01.ogg": "204f93a3eb7d82cf8ca9172ee5f01c11",
|
||||||
"build/assets/ba_data/audio/corkPop.ogg": "7b0bdbb0cdaf40ec5adf3311ecfe620a",
|
"build/assets/ba_data/audio/corkPop.ogg": "7b0bdbb0cdaf40ec5adf3311ecfe620a",
|
||||||
|
"build/assets/ba_data/audio/corkPop2.ogg": "1ad5aff84af244acb2f3eaf95ddb7f6a",
|
||||||
"build/assets/ba_data/audio/cowboy1.ogg": "e12671599d7f6fa7e246b3ad4d83ad7d",
|
"build/assets/ba_data/audio/cowboy1.ogg": "e12671599d7f6fa7e246b3ad4d83ad7d",
|
||||||
"build/assets/ba_data/audio/cowboy2.ogg": "0cd227e165a76bf829ac0e3ac129929c",
|
"build/assets/ba_data/audio/cowboy2.ogg": "0cd227e165a76bf829ac0e3ac129929c",
|
||||||
"build/assets/ba_data/audio/cowboy3.ogg": "9ce2c947a9ddcf9c6e793721d5b1eb66",
|
"build/assets/ba_data/audio/cowboy3.ogg": "9ce2c947a9ddcf9c6e793721d5b1eb66",
|
||||||
@ -121,6 +123,7 @@
|
|||||||
"build/assets/ba_data/audio/dingSmallHigh.ogg": "73ce9e68ef59847dc7621d38ed019c42",
|
"build/assets/ba_data/audio/dingSmallHigh.ogg": "73ce9e68ef59847dc7621d38ed019c42",
|
||||||
"build/assets/ba_data/audio/dripity.ogg": "db450cee4e5241fbaa80a2874cb3cf7f",
|
"build/assets/ba_data/audio/dripity.ogg": "db450cee4e5241fbaa80a2874cb3cf7f",
|
||||||
"build/assets/ba_data/audio/drumRoll.ogg": "8d8234c10e7b9dee277a4e26aec3c9e1",
|
"build/assets/ba_data/audio/drumRoll.ogg": "8d8234c10e7b9dee277a4e26aec3c9e1",
|
||||||
|
"build/assets/ba_data/audio/drumRollShort.ogg": "b4273cdd69c0b09bd1da5146a6b1bc76",
|
||||||
"build/assets/ba_data/audio/error.ogg": "a39731636b92282052e15eb5b9413816",
|
"build/assets/ba_data/audio/error.ogg": "a39731636b92282052e15eb5b9413816",
|
||||||
"build/assets/ba_data/audio/explosion01.ogg": "51bba8fc738410a61da8d535d8485a20",
|
"build/assets/ba_data/audio/explosion01.ogg": "51bba8fc738410a61da8d535d8485a20",
|
||||||
"build/assets/ba_data/audio/explosion02.ogg": "b4ce0ea7abd1c5b52ad7a868f1029a2d",
|
"build/assets/ba_data/audio/explosion02.ogg": "b4ce0ea7abd1c5b52ad7a868f1029a2d",
|
||||||
@ -147,6 +150,7 @@
|
|||||||
"build/assets/ba_data/audio/frostyHit02.ogg": "c608e2ce52c872d701110367fa447656",
|
"build/assets/ba_data/audio/frostyHit02.ogg": "c608e2ce52c872d701110367fa447656",
|
||||||
"build/assets/ba_data/audio/frostyHit03.ogg": "20860a3e0acd4104d2b62ac4a624749f",
|
"build/assets/ba_data/audio/frostyHit03.ogg": "20860a3e0acd4104d2b62ac4a624749f",
|
||||||
"build/assets/ba_data/audio/fuse01.ogg": "f24744d8b4590b5898015dd98b2b9374",
|
"build/assets/ba_data/audio/fuse01.ogg": "f24744d8b4590b5898015dd98b2b9374",
|
||||||
|
"build/assets/ba_data/audio/gasp.ogg": "91b267abf7015cf36d263e961f83856b",
|
||||||
"build/assets/ba_data/audio/gladiator1.ogg": "528596df10aec80417a4df83325fc09d",
|
"build/assets/ba_data/audio/gladiator1.ogg": "528596df10aec80417a4df83325fc09d",
|
||||||
"build/assets/ba_data/audio/gladiator2.ogg": "a0f42843c7a73523e90ed32d766959f1",
|
"build/assets/ba_data/audio/gladiator2.ogg": "a0f42843c7a73523e90ed32d766959f1",
|
||||||
"build/assets/ba_data/audio/gladiator3.ogg": "b3fa702291a4da6f439e72481177a5c2",
|
"build/assets/ba_data/audio/gladiator3.ogg": "b3fa702291a4da6f439e72481177a5c2",
|
||||||
@ -218,6 +222,7 @@
|
|||||||
"build/assets/ba_data/audio/menuMusic.ogg": "b25ee0041baf71b08c7650ae9f4daab0",
|
"build/assets/ba_data/audio/menuMusic.ogg": "b25ee0041baf71b08c7650ae9f4daab0",
|
||||||
"build/assets/ba_data/audio/metalHit.ogg": "ced0188b46245cd60b248fc7bc13b706",
|
"build/assets/ba_data/audio/metalHit.ogg": "ced0188b46245cd60b248fc7bc13b706",
|
||||||
"build/assets/ba_data/audio/metalSkid.ogg": "a069f5022be74229c008a19b3e00e64c",
|
"build/assets/ba_data/audio/metalSkid.ogg": "a069f5022be74229c008a19b3e00e64c",
|
||||||
|
"build/assets/ba_data/audio/nice.ogg": "fb362c97a244ed3a2c2f98c38691fb00",
|
||||||
"build/assets/ba_data/audio/ninjaAttack1.ogg": "82c98bc81f3e3e224ddd3151be918dd6",
|
"build/assets/ba_data/audio/ninjaAttack1.ogg": "82c98bc81f3e3e224ddd3151be918dd6",
|
||||||
"build/assets/ba_data/audio/ninjaAttack2.ogg": "1f0952bb9df1877fbb9e05b8649b63da",
|
"build/assets/ba_data/audio/ninjaAttack2.ogg": "1f0952bb9df1877fbb9e05b8649b63da",
|
||||||
"build/assets/ba_data/audio/ninjaAttack3.ogg": "e5edefe727e4fe2bcb16ab90edc36c39",
|
"build/assets/ba_data/audio/ninjaAttack3.ogg": "e5edefe727e4fe2bcb16ab90edc36c39",
|
||||||
@ -287,6 +292,7 @@
|
|||||||
"build/assets/ba_data/audio/raceBeep1.ogg": "2d271c487cefbd67f15a21a0904b3e1f",
|
"build/assets/ba_data/audio/raceBeep1.ogg": "2d271c487cefbd67f15a21a0904b3e1f",
|
||||||
"build/assets/ba_data/audio/raceBeep2.ogg": "47cf9d039e19a3446444bfeb82b394b6",
|
"build/assets/ba_data/audio/raceBeep2.ogg": "47cf9d039e19a3446444bfeb82b394b6",
|
||||||
"build/assets/ba_data/audio/refWhistle.ogg": "8ebbde5488b834e73f1d8ee4dad8b1f3",
|
"build/assets/ba_data/audio/refWhistle.ogg": "8ebbde5488b834e73f1d8ee4dad8b1f3",
|
||||||
|
"build/assets/ba_data/audio/revUp.ogg": "19862620186556029821e41b403f3a11",
|
||||||
"build/assets/ba_data/audio/robot1.ogg": "feed97d9abb23097d659b10c6276bab8",
|
"build/assets/ba_data/audio/robot1.ogg": "feed97d9abb23097d659b10c6276bab8",
|
||||||
"build/assets/ba_data/audio/robot2.ogg": "d9fc996427452f76b0527d5ca84983af",
|
"build/assets/ba_data/audio/robot2.ogg": "d9fc996427452f76b0527d5ca84983af",
|
||||||
"build/assets/ba_data/audio/robot3.ogg": "bf766b82d438323f89fe4688dd78f5ef",
|
"build/assets/ba_data/audio/robot3.ogg": "bf766b82d438323f89fe4688dd78f5ef",
|
||||||
@ -395,7 +401,11 @@
|
|||||||
"build/assets/ba_data/audio/wizardFall.ogg": "e422bd05ae30a28b02b1c55fb0c1fa00",
|
"build/assets/ba_data/audio/wizardFall.ogg": "e422bd05ae30a28b02b1c55fb0c1fa00",
|
||||||
"build/assets/ba_data/audio/wizardHit1.ogg": "7686120c658c811064efda94ac3e90ca",
|
"build/assets/ba_data/audio/wizardHit1.ogg": "7686120c658c811064efda94ac3e90ca",
|
||||||
"build/assets/ba_data/audio/wizardHit2.ogg": "d245e07803be7158da49d4962ccf483a",
|
"build/assets/ba_data/audio/wizardHit2.ogg": "d245e07803be7158da49d4962ccf483a",
|
||||||
|
"build/assets/ba_data/audio/woo.ogg": "e84ef95cb1d97b65ff529687d6076da9",
|
||||||
|
"build/assets/ba_data/audio/woo2.ogg": "5dfb2e489f406d11772f96ded5611c4f",
|
||||||
|
"build/assets/ba_data/audio/woo3.ogg": "637878bb31decb36e6db7a5295eea933",
|
||||||
"build/assets/ba_data/audio/woodDebrisFall.ogg": "e163c84d87821e3e19ec8b0bf1fef9a7",
|
"build/assets/ba_data/audio/woodDebrisFall.ogg": "e163c84d87821e3e19ec8b0bf1fef9a7",
|
||||||
|
"build/assets/ba_data/audio/wow.ogg": "581d224d771195bde72548509cc1cc32",
|
||||||
"build/assets/ba_data/audio/wrestler1.ogg": "7486e02349206e8082b44105d0a1195c",
|
"build/assets/ba_data/audio/wrestler1.ogg": "7486e02349206e8082b44105d0a1195c",
|
||||||
"build/assets/ba_data/audio/wrestler2.ogg": "0f197b1d7e6c2e0cc86e57d1b53581aa",
|
"build/assets/ba_data/audio/wrestler2.ogg": "0f197b1d7e6c2e0cc86e57d1b53581aa",
|
||||||
"build/assets/ba_data/audio/wrestler3.ogg": "911ad7c64018e8d5fa5f722a04de8837",
|
"build/assets/ba_data/audio/wrestler3.ogg": "911ad7c64018e8d5fa5f722a04de8837",
|
||||||
@ -404,6 +414,7 @@
|
|||||||
"build/assets/ba_data/audio/wrestlerFall.ogg": "3c6bb84fb09a0829fd60066b1807a16c",
|
"build/assets/ba_data/audio/wrestlerFall.ogg": "3c6bb84fb09a0829fd60066b1807a16c",
|
||||||
"build/assets/ba_data/audio/wrestlerHit1.ogg": "1950d463514448069f0d3c0f00108eaa",
|
"build/assets/ba_data/audio/wrestlerHit1.ogg": "1950d463514448069f0d3c0f00108eaa",
|
||||||
"build/assets/ba_data/audio/wrestlerHit2.ogg": "5b549fb2406fd72d1d0947fc8173cc08",
|
"build/assets/ba_data/audio/wrestlerHit2.ogg": "5b549fb2406fd72d1d0947fc8173cc08",
|
||||||
|
"build/assets/ba_data/audio/yeah.ogg": "2c55f21c39cf5f41a81317dec3f5d7fa",
|
||||||
"build/assets/ba_data/audio/zoeAttack01.ogg": "0b0536b8afba7cb773beffeaa2e4bb90",
|
"build/assets/ba_data/audio/zoeAttack01.ogg": "0b0536b8afba7cb773beffeaa2e4bb90",
|
||||||
"build/assets/ba_data/audio/zoeAttack02.ogg": "931a5b3d78e2322443fe1e51e6c25b99",
|
"build/assets/ba_data/audio/zoeAttack02.ogg": "931a5b3d78e2322443fe1e51e6c25b99",
|
||||||
"build/assets/ba_data/audio/zoeAttack03.ogg": "e1d1f58f038bedda8c22fc518aa37c7e",
|
"build/assets/ba_data/audio/zoeAttack03.ogg": "e1d1f58f038bedda8c22fc518aa37c7e",
|
||||||
@ -421,21 +432,21 @@
|
|||||||
"build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb",
|
"build/assets/ba_data/audio/zoeOw.ogg": "b2d705c31c9dcc1efdc71394764c3beb",
|
||||||
"build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789",
|
"build/assets/ba_data/audio/zoePickup01.ogg": "e9366dc2d2b8ab8b0c4e2c14c02d0789",
|
||||||
"build/assets/ba_data/audio/zoeScream01.ogg": "903e0e45ee9b3373e9d9ce20c814374e",
|
"build/assets/ba_data/audio/zoeScream01.ogg": "903e0e45ee9b3373e9d9ce20c814374e",
|
||||||
"build/assets/ba_data/data/langdata.json": "ce2f76ab5f36cbc0212d1b3c424eb954",
|
"build/assets/ba_data/data/langdata.json": "dbbd8f26d2f85c0b649d461e991b80cb",
|
||||||
"build/assets/ba_data/data/languages/arabic.json": "3c22e7b6d7b09a812a2e28b35c9e9241",
|
"build/assets/ba_data/data/languages/arabic.json": "3c22e7b6d7b09a812a2e28b35c9e9241",
|
||||||
"build/assets/ba_data/data/languages/belarussian.json": "0b60a9d4496d1213c2d0b647d346ce30",
|
"build/assets/ba_data/data/languages/belarussian.json": "0b60a9d4496d1213c2d0b647d346ce30",
|
||||||
"build/assets/ba_data/data/languages/chinese.json": "fc45d2838b834889c06920ae7c2102fa",
|
"build/assets/ba_data/data/languages/chinese.json": "fc45d2838b834889c06920ae7c2102fa",
|
||||||
"build/assets/ba_data/data/languages/chinesetraditional.json": "904b35b656c53f9830e406565edd5120",
|
"build/assets/ba_data/data/languages/chinesetraditional.json": "904b35b656c53f9830e406565edd5120",
|
||||||
"build/assets/ba_data/data/languages/croatian.json": "1e541070309ff6be95b0c39940aa7e99",
|
"build/assets/ba_data/data/languages/croatian.json": "e131a87cf5783e0fbb3d211a927efe1a",
|
||||||
"build/assets/ba_data/data/languages/czech.json": "d18b7d1c6bf51fc81af4084ef0e69e3e",
|
"build/assets/ba_data/data/languages/czech.json": "d18b7d1c6bf51fc81af4084ef0e69e3e",
|
||||||
"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": "f4e1e8e9231cda9d1bcc7e87a7f8821e",
|
"build/assets/ba_data/data/languages/dutch.json": "4085dec5af362cf068b494524ced3872",
|
||||||
"build/assets/ba_data/data/languages/english.json": "b5917c3b975155e35fedb655dbd7568c",
|
"build/assets/ba_data/data/languages/english.json": "527d106870b0690cc39a80b88e60ab7a",
|
||||||
"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": "3d9269a90a2fee164d0a7513c4f130a3",
|
"build/assets/ba_data/data/languages/filipino.json": "3d9269a90a2fee164d0a7513c4f130a3",
|
||||||
"build/assets/ba_data/data/languages/french.json": "6d20655730b1017ef187fd828b91d43c",
|
"build/assets/ba_data/data/languages/french.json": "6d20655730b1017ef187fd828b91d43c",
|
||||||
"build/assets/ba_data/data/languages/german.json": "a150dbb5c0f43984757f7db295d96203",
|
"build/assets/ba_data/data/languages/german.json": "b92ec951b5a0ce4f73677051ca59a06b",
|
||||||
"build/assets/ba_data/data/languages/gibberish.json": "df76e851aee59657b69e34efd54fee06",
|
"build/assets/ba_data/data/languages/gibberish.json": "2569fe1b2f686670f825e2faaa8c5dc3",
|
||||||
"build/assets/ba_data/data/languages/greek.json": "d28d1092fbb00ed857cbd53124c0dc78",
|
"build/assets/ba_data/data/languages/greek.json": "d28d1092fbb00ed857cbd53124c0dc78",
|
||||||
"build/assets/ba_data/data/languages/hindi.json": "567e6976b3c72f891431ad7fcc62ab16",
|
"build/assets/ba_data/data/languages/hindi.json": "567e6976b3c72f891431ad7fcc62ab16",
|
||||||
"build/assets/ba_data/data/languages/hungarian.json": "9d88004a98f0fbe2ea72edd5e0b3002e",
|
"build/assets/ba_data/data/languages/hungarian.json": "9d88004a98f0fbe2ea72edd5e0b3002e",
|
||||||
@ -451,7 +462,7 @@
|
|||||||
"build/assets/ba_data/data/languages/russian.json": "fc64ed6b6356ea11385ee5c20748425a",
|
"build/assets/ba_data/data/languages/russian.json": "fc64ed6b6356ea11385ee5c20748425a",
|
||||||
"build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a",
|
"build/assets/ba_data/data/languages/serbian.json": "623fa4129a1154c2f32ed7867e56ff6a",
|
||||||
"build/assets/ba_data/data/languages/slovak.json": "c11c29708b3742cdc2a92b4fa0d6d29f",
|
"build/assets/ba_data/data/languages/slovak.json": "c11c29708b3742cdc2a92b4fa0d6d29f",
|
||||||
"build/assets/ba_data/data/languages/spanish.json": "499b464318a8c9d1fb271cf480862b57",
|
"build/assets/ba_data/data/languages/spanish.json": "f8ab976d219e579546bb98b6d7fd12ce",
|
||||||
"build/assets/ba_data/data/languages/swedish.json": "3b179e7333183c70adb0811246b09959",
|
"build/assets/ba_data/data/languages/swedish.json": "3b179e7333183c70adb0811246b09959",
|
||||||
"build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec",
|
"build/assets/ba_data/data/languages/tamil.json": "ead39b864228696a9b0d19344bc4b5ec",
|
||||||
"build/assets/ba_data/data/languages/thai.json": "383540a1e9c7c131ac579f51afc87471",
|
"build/assets/ba_data/data/languages/thai.json": "383540a1e9c7c131ac579f51afc87471",
|
||||||
@ -1362,10 +1373,18 @@
|
|||||||
"build/assets/ba_data/textures/chestIconMulti.ktx": "c026aa573aab141044b503437ffdaeea",
|
"build/assets/ba_data/textures/chestIconMulti.ktx": "c026aa573aab141044b503437ffdaeea",
|
||||||
"build/assets/ba_data/textures/chestIconMulti.pvr": "3f41eaa108068751ba40e08964c45ec0",
|
"build/assets/ba_data/textures/chestIconMulti.pvr": "3f41eaa108068751ba40e08964c45ec0",
|
||||||
"build/assets/ba_data/textures/chestIconMulti_preview.png": "47b6839bdc19ad9e3d3d6282ce0138dd",
|
"build/assets/ba_data/textures/chestIconMulti_preview.png": "47b6839bdc19ad9e3d3d6282ce0138dd",
|
||||||
|
"build/assets/ba_data/textures/chestIconTint.dds": "04c079c1a79d548ca02969e9934d591b",
|
||||||
|
"build/assets/ba_data/textures/chestIconTint.ktx": "ff39e97211bb71f59091aac2f51ebbed",
|
||||||
|
"build/assets/ba_data/textures/chestIconTint.pvr": "129b44259f8b62c0e1d4c08612b9c691",
|
||||||
|
"build/assets/ba_data/textures/chestIconTint_preview.png": "022f3f8bb8bc9c082dbb21958ec8722f",
|
||||||
"build/assets/ba_data/textures/chestIcon_preview.png": "d3046ccf2fedefa9ad766054e350a5d6",
|
"build/assets/ba_data/textures/chestIcon_preview.png": "d3046ccf2fedefa9ad766054e350a5d6",
|
||||||
"build/assets/ba_data/textures/chestOpenIcon.dds": "325e93c7147c3bf098857d0e3eff4a73",
|
"build/assets/ba_data/textures/chestOpenIcon.dds": "325e93c7147c3bf098857d0e3eff4a73",
|
||||||
"build/assets/ba_data/textures/chestOpenIcon.ktx": "562afa582aa621b946c22460e0caca61",
|
"build/assets/ba_data/textures/chestOpenIcon.ktx": "562afa582aa621b946c22460e0caca61",
|
||||||
"build/assets/ba_data/textures/chestOpenIcon.pvr": "703c88d07b9ab22cbab647677eb05370",
|
"build/assets/ba_data/textures/chestOpenIcon.pvr": "703c88d07b9ab22cbab647677eb05370",
|
||||||
|
"build/assets/ba_data/textures/chestOpenIconTint.dds": "c3003ed402d46da9d5c8351f028c5d95",
|
||||||
|
"build/assets/ba_data/textures/chestOpenIconTint.ktx": "d32fe2152a1bf6feff1f2416627b2023",
|
||||||
|
"build/assets/ba_data/textures/chestOpenIconTint.pvr": "bd665e8289bfd5c369c473e973dd2d65",
|
||||||
|
"build/assets/ba_data/textures/chestOpenIconTint_preview.png": "e5a2377c127998faaef83e06d4cc2584",
|
||||||
"build/assets/ba_data/textures/chestOpenIcon_preview.png": "40ae165451f052265d07ea62f7d08713",
|
"build/assets/ba_data/textures/chestOpenIcon_preview.png": "40ae165451f052265d07ea62f7d08713",
|
||||||
"build/assets/ba_data/textures/circle.dds": "0f4c08ab481dcadce164227a146fdb62",
|
"build/assets/ba_data/textures/circle.dds": "0f4c08ab481dcadce164227a146fdb62",
|
||||||
"build/assets/ba_data/textures/circle.ktx": "a6ff1b802324d1874aaa9c24050cfcf3",
|
"build/assets/ba_data/textures/circle.ktx": "a6ff1b802324d1874aaa9c24050cfcf3",
|
||||||
@ -2359,6 +2378,10 @@
|
|||||||
"build/assets/ba_data/textures/sparks.ktx": "919af9b0b1b2e756c232c34bc15d506a",
|
"build/assets/ba_data/textures/sparks.ktx": "919af9b0b1b2e756c232c34bc15d506a",
|
||||||
"build/assets/ba_data/textures/sparks.pvr": "249e98bbadad09b59f0e8bdd46b1c9b1",
|
"build/assets/ba_data/textures/sparks.pvr": "249e98bbadad09b59f0e8bdd46b1c9b1",
|
||||||
"build/assets/ba_data/textures/sparks_preview.png": "9b6b74000a0f56899dd09a956a864ec9",
|
"build/assets/ba_data/textures/sparks_preview.png": "9b6b74000a0f56899dd09a956a864ec9",
|
||||||
|
"build/assets/ba_data/textures/spinner.dds": "54b0a3a695689974defcb7d0ddc40101",
|
||||||
|
"build/assets/ba_data/textures/spinner.ktx": "9e47f8b7dcca8f061bff6a04a30a2833",
|
||||||
|
"build/assets/ba_data/textures/spinner.pvr": "312c7ffa74c39d262d00971881ecd93b",
|
||||||
|
"build/assets/ba_data/textures/spinner_preview.png": "680af969ab856865098dfcf4fb8b6845",
|
||||||
"build/assets/ba_data/textures/star.dds": "e799668a604f3e680f7676994e894c1d",
|
"build/assets/ba_data/textures/star.dds": "e799668a604f3e680f7676994e894c1d",
|
||||||
"build/assets/ba_data/textures/star.ktx": "725da9d09a93c636bd825788f859c62d",
|
"build/assets/ba_data/textures/star.ktx": "725da9d09a93c636bd825788f859c62d",
|
||||||
"build/assets/ba_data/textures/star.pvr": "bb68b74f455c36dcd7a40f9d38b5c74f",
|
"build/assets/ba_data/textures/star.pvr": "bb68b74f455c36dcd7a40f9d38b5c74f",
|
||||||
@ -4103,47 +4126,47 @@
|
|||||||
"build/assets/windows/Win32/ucrtbased.dll": "bfd1180c269d3950b76f35a63655e9e1",
|
"build/assets/windows/Win32/ucrtbased.dll": "bfd1180c269d3950b76f35a63655e9e1",
|
||||||
"build/assets/windows/Win32/vc_redist.x86.exe": "15a5f1f876503885adbdf5b3989b3718",
|
"build/assets/windows/Win32/vc_redist.x86.exe": "15a5f1f876503885adbdf5b3989b3718",
|
||||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "390472d8d44b0a650796bfd6022d0549",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "2444899f2f36667dc27fcf5537fc76b6",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "23f27d6f139c653f23a15a0af7f7e02c",
|
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "efebe5318abe421031108d9908b4cb84",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "097b082f8f5abb18d824b2044da1de78",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9b4928361ff7e3aa85ea6cca5f3903d8",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "c027478f038af2faedcc4103e75bc39d",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "9fad073f6fd49702ceb1ee5057c4f9de",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "5c7f18d5ff9eb14421fe3743550ddf57",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "ac52ed0994f33ea4997da21d0a7f6877",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "cef0bc0d149a4c433c2e4bee5b47414a",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "43f429f37c145fc2bf80c01dfd095a7e",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "25546af5cf64a0e1e1d1f46b38298820",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "ea87a5838b465c40b60ff911cccbe189",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "7f172d6c531c371837302f370f77db08",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "3cafa3287637bba5e56b363bb4fc8f9a",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "0d79db47846defaffaa0bf97ec6b23fc",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "1fbe4ab96f25d20b421c8206c9230948",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "45373e10bb60989787e415ae938756fe",
|
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "0a4dbc635f8e9b3f42e89dd2027bd9d3",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0cc3834e81761efdc50babed9e5c7151",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "6114856f2ab42ef6b20a1affdf53032d",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "4e28c4abb0e7128d08f2b84a87d8a765",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "bfa75071d993efc3853fa350c1de2bcb",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "96b856d3db5d061527383b42e588a333",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "3971d8deb2c33cfd18c4e3b338d48ec3",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "124afb5eec04365e42b059b0c2ec98e7",
|
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "bd0c352337d72f020b431feca7974c3a",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "0271c53794bdb4a762ae7210d9828fb7",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "073b3690cfb03847ac3b3fe9c017e520",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f8b3744f90503502618130c8d28f1aa4",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "c7f0d9c4db7a67b4d72f3c406c585897",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "33a0ae6f1ea5a0b0c60055ce01478488",
|
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "1c375e8003442dd3d059bc0baa260e61",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "aad882eaf2230b89973e2cf4f13c9759",
|
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "40daac4bbc8990d5140f97e792bc4fb1",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "33a0ae6f1ea5a0b0c60055ce01478488",
|
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "1c375e8003442dd3d059bc0baa260e61",
|
||||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "aad882eaf2230b89973e2cf4f13c9759",
|
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "40daac4bbc8990d5140f97e792bc4fb1",
|
||||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "c20929c73caa78445525c5788b6963e0",
|
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "19af08729bed7249eaf9acd697966f3f",
|
||||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "0f21a43d99552df99e0d21c646e6e698",
|
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "97d2486072bf3a83edb0250ea2d3e69e",
|
||||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "c20929c73caa78445525c5788b6963e0",
|
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "19af08729bed7249eaf9acd697966f3f",
|
||||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "0f21a43d99552df99e0d21c646e6e698",
|
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "97d2486072bf3a83edb0250ea2d3e69e",
|
||||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "01dab862a43d9e7c4ee4e49212442d42",
|
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "51884d81e2d7bdeb6b59a72f0247c8e1",
|
||||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "ae4e3f563892f6b9311c4b7284f28c11",
|
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "36bb6f32ab12e2a46b82155a93b2e527",
|
||||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "01dab862a43d9e7c4ee4e49212442d42",
|
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "51884d81e2d7bdeb6b59a72f0247c8e1",
|
||||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "ae4e3f563892f6b9311c4b7284f28c11",
|
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "36bb6f32ab12e2a46b82155a93b2e527",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "2f581e3dead7038e5b94bc096a7b8c80",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "f629e97c70198ab3688f11ab4a2d1e97",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "4538ad0d6b4794de96fb78742ebcdc84",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "a868c0116adf9f48f503b50b50c70cd8",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "0d1a2f2066ae412549034e981ae39e2c",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "04216607232edde485d139e9e96c6612",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "55180e66455f91d3af8f15c0c81607a4",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "bdc158a2dfd592cd8dcb235a162a82fe",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bb2c15187840ef373ae79cdf1623d3b5",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "4a0340814c6034b39b2c08287935e26a",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "8ee1bb4440c364f9fa91791276d64b87",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "546ccf01f342463d46302b05c0171044",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "863f70d88ab9b3c7c6910d94e26b6f35",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "67bb2ff991e00433c1abba2044a0d21e",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "bb928df1aa05c84889b45f2a00544e64",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "8653a52a8fd75c527c976abb9d223e90",
|
||||||
"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": "794d258d59fd17a61752843a9a0551ad",
|
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91",
|
"src/ballistica/base/mgen/pyembed/binding_base.inc": "06042d31df0ff9af96b99477162e2a91",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "2d228e7c5578261d394f9c407f4becb1",
|
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "2d228e7c5578261d394f9c407f4becb1",
|
||||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "fc09126750304b2761049aa9d93a951e",
|
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "8ab156122cde23d9718923abe1b4ae5b",
|
||||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "217c84a30f866aaca3a4373e82af7db2",
|
"src/ballistica/core/mgen/pyembed/binding_core.inc": "217c84a30f866aaca3a4373e82af7db2",
|
||||||
"src/ballistica/core/mgen/pyembed/env.inc": "f015d726b44d2922112fc14d9f146d8b",
|
"src/ballistica/core/mgen/pyembed/env.inc": "f015d726b44d2922112fc14d9f146d8b",
|
||||||
"src/ballistica/core/mgen/python_modules_monolithic.h": "fb967ed1c7db0c77d8deb4f00a7103c5",
|
"src/ballistica/core/mgen/python_modules_monolithic.h": "fb967ed1c7db0c77d8deb4f00a7103c5",
|
||||||
|
|||||||
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,4 +1,4 @@
|
|||||||
### 1.7.37 (build 22155, api 9, 2024-12-31)
|
### 1.7.37 (build 22178, api 9, 2025-01-11)
|
||||||
- Bumping api version to 9. As you'll see below, there's some UI changes that
|
- Bumping api version to 9. As you'll see below, there's some UI changes that
|
||||||
will require a bit of work for any UI mods to adapt to. If your mods don't
|
will require a bit of work for any UI mods to adapt to. If your mods don't
|
||||||
touch UI stuff at all you can simply bump your api version and call it a day.
|
touch UI stuff at all you can simply bump your api version and call it a day.
|
||||||
@ -176,6 +176,21 @@
|
|||||||
should use arrow keys for navigation. To update any old UI code, search for
|
should use arrow keys for navigation. To update any old UI code, search for
|
||||||
and remove any 'claims_tab' arguments to UI calls since that argument no
|
and remove any 'claims_tab' arguments to UI calls since that argument no
|
||||||
longer exists.
|
longer exists.
|
||||||
|
- Added a `get_unknown_type_fallback()` method to `dataclassio.IOMultiType`.
|
||||||
|
This be defined to allow multi-type data to be loadable even in the presence
|
||||||
|
of new types it doesn't recognize.
|
||||||
|
- Added a `lossy` arg to `dataclassio.dataclass_from_dict()` and
|
||||||
|
`dataclassio.dataclass_from_json()`. Enum value fallbacks and the new
|
||||||
|
multitype fallbacks are now only applied when `lossy` is True. This also flags
|
||||||
|
the returned dataclass to prevent it from being serialized back out. Fallbacks
|
||||||
|
are useful for forward compatibility, but they are also dangerous in that they
|
||||||
|
can silently modify/destroy data, so this mechanism will hopefully help keep
|
||||||
|
them used safely.
|
||||||
|
- Added a spinner widget (creatable via `bauiv1.spinnerwidget()`). This should
|
||||||
|
help things look more alive than the static 'loading...' text I've been using
|
||||||
|
in various places.
|
||||||
|
- Tournament now award chests instead of tickets.
|
||||||
|
- Tournaments are now free to enter if you are running this build or newer.
|
||||||
|
|
||||||
### 1.7.36 (build 21944, api 8, 2024-07-26)
|
### 1.7.36 (build 21944, api 8, 2024-07-26)
|
||||||
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these
|
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these
|
||||||
|
|||||||
@ -772,6 +772,8 @@ set(BALLISTICA_SOURCES
|
|||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/row_widget.h
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/row_widget.h
|
||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/scroll_widget.cc
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/scroll_widget.cc
|
||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/scroll_widget.h
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/scroll_widget.h
|
||||||
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/spinner_widget.cc
|
||||||
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/spinner_widget.h
|
||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/stack_widget.cc
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/stack_widget.cc
|
||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/stack_widget.h
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/stack_widget.h
|
||||||
${BA_SRC_ROOT}/ballistica/ui_v1/widget/text_widget.cc
|
${BA_SRC_ROOT}/ballistica/ui_v1/widget/text_widget.cc
|
||||||
|
|||||||
@ -764,6 +764,8 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\row_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\row_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h" />
|
||||||
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.cc" />
|
||||||
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\stack_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\stack_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\text_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\text_widget.cc" />
|
||||||
|
|||||||
@ -1726,6 +1726,12 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h">
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h">
|
||||||
<Filter>ballistica\ui_v1\widget</Filter>
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.cc">
|
||||||
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.h">
|
||||||
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc">
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc">
|
||||||
<Filter>ballistica\ui_v1\widget</Filter>
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -759,6 +759,8 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\row_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\row_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h" />
|
||||||
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.cc" />
|
||||||
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\stack_widget.h" />
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\stack_widget.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\text_widget.cc" />
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\text_widget.cc" />
|
||||||
|
|||||||
@ -1726,6 +1726,12 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h">
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\scroll_widget.h">
|
||||||
<Filter>ballistica\ui_v1\widget</Filter>
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.cc">
|
||||||
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\..\src\ballistica\ui_v1\widget\spinner_widget.h">
|
||||||
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc">
|
<ClCompile Include="..\..\src\ballistica\ui_v1\widget\stack_widget.cc">
|
||||||
<Filter>ballistica\ui_v1\widget</Filter>
|
<Filter>ballistica\ui_v1\widget</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
cpplint==2.0.0
|
cpplint==2.0.0
|
||||||
dmgbuild==1.6.2
|
dmgbuild==1.6.4
|
||||||
filelock==3.16.1
|
filelock==3.16.1
|
||||||
furo==2024.8.6
|
furo==2024.8.6
|
||||||
mypy==1.14.1
|
mypy==1.14.1
|
||||||
|
|||||||
@ -52,6 +52,7 @@
|
|||||||
"ba_data/audio/assassinFall.ogg",
|
"ba_data/audio/assassinFall.ogg",
|
||||||
"ba_data/audio/assassinHit1.ogg",
|
"ba_data/audio/assassinHit1.ogg",
|
||||||
"ba_data/audio/assassinHit2.ogg",
|
"ba_data/audio/assassinHit2.ogg",
|
||||||
|
"ba_data/audio/aww.ogg",
|
||||||
"ba_data/audio/bear1.ogg",
|
"ba_data/audio/bear1.ogg",
|
||||||
"ba_data/audio/bear2.ogg",
|
"ba_data/audio/bear2.ogg",
|
||||||
"ba_data/audio/bear3.ogg",
|
"ba_data/audio/bear3.ogg",
|
||||||
@ -94,6 +95,7 @@
|
|||||||
"ba_data/audio/cheer.ogg",
|
"ba_data/audio/cheer.ogg",
|
||||||
"ba_data/audio/click01.ogg",
|
"ba_data/audio/click01.ogg",
|
||||||
"ba_data/audio/corkPop.ogg",
|
"ba_data/audio/corkPop.ogg",
|
||||||
|
"ba_data/audio/corkPop2.ogg",
|
||||||
"ba_data/audio/cowboy1.ogg",
|
"ba_data/audio/cowboy1.ogg",
|
||||||
"ba_data/audio/cowboy2.ogg",
|
"ba_data/audio/cowboy2.ogg",
|
||||||
"ba_data/audio/cowboy3.ogg",
|
"ba_data/audio/cowboy3.ogg",
|
||||||
@ -120,6 +122,7 @@
|
|||||||
"ba_data/audio/dingSmallHigh.ogg",
|
"ba_data/audio/dingSmallHigh.ogg",
|
||||||
"ba_data/audio/dripity.ogg",
|
"ba_data/audio/dripity.ogg",
|
||||||
"ba_data/audio/drumRoll.ogg",
|
"ba_data/audio/drumRoll.ogg",
|
||||||
|
"ba_data/audio/drumRollShort.ogg",
|
||||||
"ba_data/audio/error.ogg",
|
"ba_data/audio/error.ogg",
|
||||||
"ba_data/audio/explosion01.ogg",
|
"ba_data/audio/explosion01.ogg",
|
||||||
"ba_data/audio/explosion02.ogg",
|
"ba_data/audio/explosion02.ogg",
|
||||||
@ -146,6 +149,7 @@
|
|||||||
"ba_data/audio/frostyHit02.ogg",
|
"ba_data/audio/frostyHit02.ogg",
|
||||||
"ba_data/audio/frostyHit03.ogg",
|
"ba_data/audio/frostyHit03.ogg",
|
||||||
"ba_data/audio/fuse01.ogg",
|
"ba_data/audio/fuse01.ogg",
|
||||||
|
"ba_data/audio/gasp.ogg",
|
||||||
"ba_data/audio/gladiator1.ogg",
|
"ba_data/audio/gladiator1.ogg",
|
||||||
"ba_data/audio/gladiator2.ogg",
|
"ba_data/audio/gladiator2.ogg",
|
||||||
"ba_data/audio/gladiator3.ogg",
|
"ba_data/audio/gladiator3.ogg",
|
||||||
@ -217,6 +221,7 @@
|
|||||||
"ba_data/audio/menuMusic.ogg",
|
"ba_data/audio/menuMusic.ogg",
|
||||||
"ba_data/audio/metalHit.ogg",
|
"ba_data/audio/metalHit.ogg",
|
||||||
"ba_data/audio/metalSkid.ogg",
|
"ba_data/audio/metalSkid.ogg",
|
||||||
|
"ba_data/audio/nice.ogg",
|
||||||
"ba_data/audio/ninjaAttack1.ogg",
|
"ba_data/audio/ninjaAttack1.ogg",
|
||||||
"ba_data/audio/ninjaAttack2.ogg",
|
"ba_data/audio/ninjaAttack2.ogg",
|
||||||
"ba_data/audio/ninjaAttack3.ogg",
|
"ba_data/audio/ninjaAttack3.ogg",
|
||||||
@ -286,6 +291,7 @@
|
|||||||
"ba_data/audio/raceBeep1.ogg",
|
"ba_data/audio/raceBeep1.ogg",
|
||||||
"ba_data/audio/raceBeep2.ogg",
|
"ba_data/audio/raceBeep2.ogg",
|
||||||
"ba_data/audio/refWhistle.ogg",
|
"ba_data/audio/refWhistle.ogg",
|
||||||
|
"ba_data/audio/revUp.ogg",
|
||||||
"ba_data/audio/robot1.ogg",
|
"ba_data/audio/robot1.ogg",
|
||||||
"ba_data/audio/robot2.ogg",
|
"ba_data/audio/robot2.ogg",
|
||||||
"ba_data/audio/robot3.ogg",
|
"ba_data/audio/robot3.ogg",
|
||||||
@ -394,7 +400,11 @@
|
|||||||
"ba_data/audio/wizardFall.ogg",
|
"ba_data/audio/wizardFall.ogg",
|
||||||
"ba_data/audio/wizardHit1.ogg",
|
"ba_data/audio/wizardHit1.ogg",
|
||||||
"ba_data/audio/wizardHit2.ogg",
|
"ba_data/audio/wizardHit2.ogg",
|
||||||
|
"ba_data/audio/woo.ogg",
|
||||||
|
"ba_data/audio/woo2.ogg",
|
||||||
|
"ba_data/audio/woo3.ogg",
|
||||||
"ba_data/audio/woodDebrisFall.ogg",
|
"ba_data/audio/woodDebrisFall.ogg",
|
||||||
|
"ba_data/audio/wow.ogg",
|
||||||
"ba_data/audio/wrestler1.ogg",
|
"ba_data/audio/wrestler1.ogg",
|
||||||
"ba_data/audio/wrestler2.ogg",
|
"ba_data/audio/wrestler2.ogg",
|
||||||
"ba_data/audio/wrestler3.ogg",
|
"ba_data/audio/wrestler3.ogg",
|
||||||
@ -403,6 +413,7 @@
|
|||||||
"ba_data/audio/wrestlerFall.ogg",
|
"ba_data/audio/wrestlerFall.ogg",
|
||||||
"ba_data/audio/wrestlerHit1.ogg",
|
"ba_data/audio/wrestlerHit1.ogg",
|
||||||
"ba_data/audio/wrestlerHit2.ogg",
|
"ba_data/audio/wrestlerHit2.ogg",
|
||||||
|
"ba_data/audio/yeah.ogg",
|
||||||
"ba_data/audio/zoeAttack01.ogg",
|
"ba_data/audio/zoeAttack01.ogg",
|
||||||
"ba_data/audio/zoeAttack02.ogg",
|
"ba_data/audio/zoeAttack02.ogg",
|
||||||
"ba_data/audio/zoeAttack03.ogg",
|
"ba_data/audio/zoeAttack03.ogg",
|
||||||
@ -1401,10 +1412,18 @@
|
|||||||
"ba_data/textures/chestIconMulti.ktx",
|
"ba_data/textures/chestIconMulti.ktx",
|
||||||
"ba_data/textures/chestIconMulti.pvr",
|
"ba_data/textures/chestIconMulti.pvr",
|
||||||
"ba_data/textures/chestIconMulti_preview.png",
|
"ba_data/textures/chestIconMulti_preview.png",
|
||||||
|
"ba_data/textures/chestIconTint.dds",
|
||||||
|
"ba_data/textures/chestIconTint.ktx",
|
||||||
|
"ba_data/textures/chestIconTint.pvr",
|
||||||
|
"ba_data/textures/chestIconTint_preview.png",
|
||||||
"ba_data/textures/chestIcon_preview.png",
|
"ba_data/textures/chestIcon_preview.png",
|
||||||
"ba_data/textures/chestOpenIcon.dds",
|
"ba_data/textures/chestOpenIcon.dds",
|
||||||
"ba_data/textures/chestOpenIcon.ktx",
|
"ba_data/textures/chestOpenIcon.ktx",
|
||||||
"ba_data/textures/chestOpenIcon.pvr",
|
"ba_data/textures/chestOpenIcon.pvr",
|
||||||
|
"ba_data/textures/chestOpenIconTint.dds",
|
||||||
|
"ba_data/textures/chestOpenIconTint.ktx",
|
||||||
|
"ba_data/textures/chestOpenIconTint.pvr",
|
||||||
|
"ba_data/textures/chestOpenIconTint_preview.png",
|
||||||
"ba_data/textures/chestOpenIcon_preview.png",
|
"ba_data/textures/chestOpenIcon_preview.png",
|
||||||
"ba_data/textures/circle.dds",
|
"ba_data/textures/circle.dds",
|
||||||
"ba_data/textures/circle.ktx",
|
"ba_data/textures/circle.ktx",
|
||||||
@ -2398,6 +2417,10 @@
|
|||||||
"ba_data/textures/sparks.ktx",
|
"ba_data/textures/sparks.ktx",
|
||||||
"ba_data/textures/sparks.pvr",
|
"ba_data/textures/sparks.pvr",
|
||||||
"ba_data/textures/sparks_preview.png",
|
"ba_data/textures/sparks_preview.png",
|
||||||
|
"ba_data/textures/spinner.dds",
|
||||||
|
"ba_data/textures/spinner.ktx",
|
||||||
|
"ba_data/textures/spinner.pvr",
|
||||||
|
"ba_data/textures/spinner_preview.png",
|
||||||
"ba_data/textures/star.dds",
|
"ba_data/textures/star.dds",
|
||||||
"ba_data/textures/star.ktx",
|
"ba_data/textures/star.ktx",
|
||||||
"ba_data/textures/star.pvr",
|
"ba_data/textures/star.pvr",
|
||||||
|
|||||||
@ -77,6 +77,8 @@
|
|||||||
"ba_data/python/baclassic/__pycache__/_appmode.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_appmode.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/baclassic/__pycache__/_appsubsystem.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_appsubsystem.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/baclassic/__pycache__/_benchmark.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_benchmark.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/baclassic/__pycache__/_chest.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/baclassic/__pycache__/_clienteffect.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/baclassic/__pycache__/_input.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_input.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/baclassic/__pycache__/_music.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_music.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/baclassic/__pycache__/_net.cpython-312.opt-1.pyc",
|
"ba_data/python/baclassic/__pycache__/_net.cpython-312.opt-1.pyc",
|
||||||
@ -93,6 +95,8 @@
|
|||||||
"ba_data/python/baclassic/_appmode.py",
|
"ba_data/python/baclassic/_appmode.py",
|
||||||
"ba_data/python/baclassic/_appsubsystem.py",
|
"ba_data/python/baclassic/_appsubsystem.py",
|
||||||
"ba_data/python/baclassic/_benchmark.py",
|
"ba_data/python/baclassic/_benchmark.py",
|
||||||
|
"ba_data/python/baclassic/_chest.py",
|
||||||
|
"ba_data/python/baclassic/_clienteffect.py",
|
||||||
"ba_data/python/baclassic/_input.py",
|
"ba_data/python/baclassic/_input.py",
|
||||||
"ba_data/python/baclassic/_music.py",
|
"ba_data/python/baclassic/_music.py",
|
||||||
"ba_data/python/baclassic/_net.py",
|
"ba_data/python/baclassic/_net.py",
|
||||||
@ -107,6 +111,7 @@
|
|||||||
"ba_data/python/bacommon/__pycache__/app.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/app.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bacommon/__pycache__/assets.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/assets.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bacommon/__pycache__/bacloud.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/bacloud.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/bacommon/__pycache__/bs.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bacommon/__pycache__/build.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/build.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bacommon/__pycache__/cloud.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/cloud.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/bacommon/__pycache__/loggercontrol.cpython-312.opt-1.pyc",
|
"ba_data/python/bacommon/__pycache__/loggercontrol.cpython-312.opt-1.pyc",
|
||||||
@ -118,6 +123,7 @@
|
|||||||
"ba_data/python/bacommon/app.py",
|
"ba_data/python/bacommon/app.py",
|
||||||
"ba_data/python/bacommon/assets.py",
|
"ba_data/python/bacommon/assets.py",
|
||||||
"ba_data/python/bacommon/bacloud.py",
|
"ba_data/python/bacommon/bacloud.py",
|
||||||
|
"ba_data/python/bacommon/bs.py",
|
||||||
"ba_data/python/bacommon/build.py",
|
"ba_data/python/bacommon/build.py",
|
||||||
"ba_data/python/bacommon/cloud.py",
|
"ba_data/python/bacommon/cloud.py",
|
||||||
"ba_data/python/bacommon/loggercontrol.py",
|
"ba_data/python/bacommon/loggercontrol.py",
|
||||||
@ -603,6 +609,7 @@
|
|||||||
"ba_data/python/efro/dataclassio/__pycache__/_pathcapture.cpython-312.opt-1.pyc",
|
"ba_data/python/efro/dataclassio/__pycache__/_pathcapture.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/efro/dataclassio/__pycache__/_prep.cpython-312.opt-1.pyc",
|
"ba_data/python/efro/dataclassio/__pycache__/_prep.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/efro/dataclassio/__pycache__/extras.cpython-312.opt-1.pyc",
|
"ba_data/python/efro/dataclassio/__pycache__/extras.cpython-312.opt-1.pyc",
|
||||||
|
"ba_data/python/efro/dataclassio/__pycache__/templatemultitype.cpython-312.opt-1.pyc",
|
||||||
"ba_data/python/efro/dataclassio/_api.py",
|
"ba_data/python/efro/dataclassio/_api.py",
|
||||||
"ba_data/python/efro/dataclassio/_base.py",
|
"ba_data/python/efro/dataclassio/_base.py",
|
||||||
"ba_data/python/efro/dataclassio/_inputter.py",
|
"ba_data/python/efro/dataclassio/_inputter.py",
|
||||||
@ -610,6 +617,7 @@
|
|||||||
"ba_data/python/efro/dataclassio/_pathcapture.py",
|
"ba_data/python/efro/dataclassio/_pathcapture.py",
|
||||||
"ba_data/python/efro/dataclassio/_prep.py",
|
"ba_data/python/efro/dataclassio/_prep.py",
|
||||||
"ba_data/python/efro/dataclassio/extras.py",
|
"ba_data/python/efro/dataclassio/extras.py",
|
||||||
|
"ba_data/python/efro/dataclassio/templatemultitype.py",
|
||||||
"ba_data/python/efro/debug.py",
|
"ba_data/python/efro/debug.py",
|
||||||
"ba_data/python/efro/error.py",
|
"ba_data/python/efro/error.py",
|
||||||
"ba_data/python/efro/logging.py",
|
"ba_data/python/efro/logging.py",
|
||||||
|
|||||||
@ -206,6 +206,8 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/baclassic/_appmode.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_appmode.py \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/_appsubsystem.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_appsubsystem.py \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/_benchmark.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_benchmark.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/baclassic/_chest.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/baclassic/_clienteffect.py \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/_input.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_input.py \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/_music.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_music.py \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/_net.py \
|
$(BUILD_DIR)/ba_data/python/baclassic/_net.py \
|
||||||
@ -486,6 +488,8 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_appmode.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_appmode.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_appsubsystem.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_appsubsystem.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_benchmark.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_benchmark.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_chest.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_clienteffect.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_input.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_input.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_music.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_music.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_net.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/baclassic/__pycache__/_net.cpython-312.opt-1.pyc \
|
||||||
@ -738,6 +742,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bacommon/app.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/app.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/assets.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/assets.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/bacloud.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/bacloud.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bacommon/bs.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/build.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/build.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/cloud.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/cloud.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/loggercontrol.py \
|
$(BUILD_DIR)/ba_data/python/bacommon/loggercontrol.py \
|
||||||
@ -759,6 +764,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \
|
|||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/_pathcapture.py \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/_pathcapture.py \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/_prep.py \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/_prep.py \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/extras.py \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/extras.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/templatemultitype.py \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/debug.py \
|
$(BUILD_DIR)/ba_data/python/efro/debug.py \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/error.py \
|
$(BUILD_DIR)/ba_data/python/efro/error.py \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/logging.py \
|
$(BUILD_DIR)/ba_data/python/efro/logging.py \
|
||||||
@ -778,6 +784,7 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/app.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/app.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/assets.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/assets.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/bacloud.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/bacloud.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/bs.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/build.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/build.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/cloud.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/cloud.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/loggercontrol.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bacommon/__pycache__/loggercontrol.cpython-312.opt-1.pyc \
|
||||||
@ -799,6 +806,7 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \
|
|||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/_pathcapture.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/_pathcapture.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/_prep.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/_prep.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/extras.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/extras.cpython-312.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/efro/dataclassio/__pycache__/templatemultitype.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/__pycache__/debug.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/__pycache__/debug.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/__pycache__/error.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/__pycache__/error.cpython-312.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/efro/__pycache__/logging.cpython-312.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/efro/__pycache__/logging.cpython-312.opt-1.pyc \
|
||||||
@ -5259,6 +5267,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/assassinFall.ogg \
|
$(BUILD_DIR)/ba_data/audio/assassinFall.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/assassinHit1.ogg \
|
$(BUILD_DIR)/ba_data/audio/assassinHit1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/assassinHit2.ogg \
|
$(BUILD_DIR)/ba_data/audio/assassinHit2.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/aww.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/bear1.ogg \
|
$(BUILD_DIR)/ba_data/audio/bear1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/bear2.ogg \
|
$(BUILD_DIR)/ba_data/audio/bear2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/bear3.ogg \
|
$(BUILD_DIR)/ba_data/audio/bear3.ogg \
|
||||||
@ -5301,6 +5310,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/cheer.ogg \
|
$(BUILD_DIR)/ba_data/audio/cheer.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/click01.ogg \
|
$(BUILD_DIR)/ba_data/audio/click01.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/corkPop.ogg \
|
$(BUILD_DIR)/ba_data/audio/corkPop.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/corkPop2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/cowboy1.ogg \
|
$(BUILD_DIR)/ba_data/audio/cowboy1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/cowboy2.ogg \
|
$(BUILD_DIR)/ba_data/audio/cowboy2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/cowboy3.ogg \
|
$(BUILD_DIR)/ba_data/audio/cowboy3.ogg \
|
||||||
@ -5327,6 +5337,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/dingSmallHigh.ogg \
|
$(BUILD_DIR)/ba_data/audio/dingSmallHigh.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/dripity.ogg \
|
$(BUILD_DIR)/ba_data/audio/dripity.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/drumRoll.ogg \
|
$(BUILD_DIR)/ba_data/audio/drumRoll.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/drumRollShort.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/error.ogg \
|
$(BUILD_DIR)/ba_data/audio/error.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/explosion01.ogg \
|
$(BUILD_DIR)/ba_data/audio/explosion01.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/explosion02.ogg \
|
$(BUILD_DIR)/ba_data/audio/explosion02.ogg \
|
||||||
@ -5353,6 +5364,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/frostyHit02.ogg \
|
$(BUILD_DIR)/ba_data/audio/frostyHit02.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/frostyHit03.ogg \
|
$(BUILD_DIR)/ba_data/audio/frostyHit03.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/fuse01.ogg \
|
$(BUILD_DIR)/ba_data/audio/fuse01.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/gasp.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/gladiator1.ogg \
|
$(BUILD_DIR)/ba_data/audio/gladiator1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/gladiator2.ogg \
|
$(BUILD_DIR)/ba_data/audio/gladiator2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/gladiator3.ogg \
|
$(BUILD_DIR)/ba_data/audio/gladiator3.ogg \
|
||||||
@ -5424,6 +5436,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/menuMusic.ogg \
|
$(BUILD_DIR)/ba_data/audio/menuMusic.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/metalHit.ogg \
|
$(BUILD_DIR)/ba_data/audio/metalHit.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/metalSkid.ogg \
|
$(BUILD_DIR)/ba_data/audio/metalSkid.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/nice.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/ninjaAttack1.ogg \
|
$(BUILD_DIR)/ba_data/audio/ninjaAttack1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/ninjaAttack2.ogg \
|
$(BUILD_DIR)/ba_data/audio/ninjaAttack2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/ninjaAttack3.ogg \
|
$(BUILD_DIR)/ba_data/audio/ninjaAttack3.ogg \
|
||||||
@ -5493,6 +5506,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/raceBeep1.ogg \
|
$(BUILD_DIR)/ba_data/audio/raceBeep1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/raceBeep2.ogg \
|
$(BUILD_DIR)/ba_data/audio/raceBeep2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/refWhistle.ogg \
|
$(BUILD_DIR)/ba_data/audio/refWhistle.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/revUp.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/robot1.ogg \
|
$(BUILD_DIR)/ba_data/audio/robot1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/robot2.ogg \
|
$(BUILD_DIR)/ba_data/audio/robot2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/robot3.ogg \
|
$(BUILD_DIR)/ba_data/audio/robot3.ogg \
|
||||||
@ -5601,7 +5615,11 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/wizardFall.ogg \
|
$(BUILD_DIR)/ba_data/audio/wizardFall.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wizardHit1.ogg \
|
$(BUILD_DIR)/ba_data/audio/wizardHit1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wizardHit2.ogg \
|
$(BUILD_DIR)/ba_data/audio/wizardHit2.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/woo.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/woo2.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/woo3.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/woodDebrisFall.ogg \
|
$(BUILD_DIR)/ba_data/audio/woodDebrisFall.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/wow.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wrestler1.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestler1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wrestler2.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestler2.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wrestler3.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestler3.ogg \
|
||||||
@ -5610,6 +5628,7 @@ AUDIO_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/audio/wrestlerFall.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestlerFall.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wrestlerHit1.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestlerHit1.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/wrestlerHit2.ogg \
|
$(BUILD_DIR)/ba_data/audio/wrestlerHit2.ogg \
|
||||||
|
$(BUILD_DIR)/ba_data/audio/yeah.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/zoeAttack01.ogg \
|
$(BUILD_DIR)/ba_data/audio/zoeAttack01.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/zoeAttack02.ogg \
|
$(BUILD_DIR)/ba_data/audio/zoeAttack02.ogg \
|
||||||
$(BUILD_DIR)/ba_data/audio/zoeAttack03.ogg \
|
$(BUILD_DIR)/ba_data/audio/zoeAttack03.ogg \
|
||||||
@ -5723,7 +5742,9 @@ TEX2D_DDS_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/chestIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/chestIcon.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.dds \
|
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconMulti.dds \
|
$(BUILD_DIR)/ba_data/textures/chestIconMulti.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestIconTint.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.dds \
|
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestOpenIconTint.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/circle.dds \
|
$(BUILD_DIR)/ba_data/textures/circle.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.dds \
|
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleOutline.dds \
|
$(BUILD_DIR)/ba_data/textures/circleOutline.dds \
|
||||||
@ -5972,6 +5993,7 @@ TEX2D_DDS_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/softRect2.dds \
|
$(BUILD_DIR)/ba_data/textures/softRect2.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/softRectVertical.dds \
|
$(BUILD_DIR)/ba_data/textures/softRectVertical.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/sparks.dds \
|
$(BUILD_DIR)/ba_data/textures/sparks.dds \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/spinner.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/star.dds \
|
$(BUILD_DIR)/ba_data/textures/star.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/startButton.dds \
|
$(BUILD_DIR)/ba_data/textures/startButton.dds \
|
||||||
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.dds \
|
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.dds \
|
||||||
@ -6135,7 +6157,9 @@ TEX2D_PVR_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/chestIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/chestIcon.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.pvr \
|
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconMulti.pvr \
|
$(BUILD_DIR)/ba_data/textures/chestIconMulti.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestIconTint.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.pvr \
|
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestOpenIconTint.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/circle.pvr \
|
$(BUILD_DIR)/ba_data/textures/circle.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.pvr \
|
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleOutline.pvr \
|
$(BUILD_DIR)/ba_data/textures/circleOutline.pvr \
|
||||||
@ -6384,6 +6408,7 @@ TEX2D_PVR_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/softRect2.pvr \
|
$(BUILD_DIR)/ba_data/textures/softRect2.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/softRectVertical.pvr \
|
$(BUILD_DIR)/ba_data/textures/softRectVertical.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/sparks.pvr \
|
$(BUILD_DIR)/ba_data/textures/sparks.pvr \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/spinner.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/star.pvr \
|
$(BUILD_DIR)/ba_data/textures/star.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/startButton.pvr \
|
$(BUILD_DIR)/ba_data/textures/startButton.pvr \
|
||||||
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.pvr \
|
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.pvr \
|
||||||
@ -6547,7 +6572,9 @@ TEX2D_KTX_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/chestIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/chestIcon.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.ktx \
|
$(BUILD_DIR)/ba_data/textures/chestIconEmpty.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconMulti.ktx \
|
$(BUILD_DIR)/ba_data/textures/chestIconMulti.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestIconTint.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.ktx \
|
$(BUILD_DIR)/ba_data/textures/chestOpenIcon.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestOpenIconTint.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/circle.ktx \
|
$(BUILD_DIR)/ba_data/textures/circle.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.ktx \
|
$(BUILD_DIR)/ba_data/textures/circleNoAlpha.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleOutline.ktx \
|
$(BUILD_DIR)/ba_data/textures/circleOutline.ktx \
|
||||||
@ -6796,6 +6823,7 @@ TEX2D_KTX_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/softRect2.ktx \
|
$(BUILD_DIR)/ba_data/textures/softRect2.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/softRectVertical.ktx \
|
$(BUILD_DIR)/ba_data/textures/softRectVertical.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/sparks.ktx \
|
$(BUILD_DIR)/ba_data/textures/sparks.ktx \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/spinner.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/star.ktx \
|
$(BUILD_DIR)/ba_data/textures/star.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/startButton.ktx \
|
$(BUILD_DIR)/ba_data/textures/startButton.ktx \
|
||||||
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.ktx \
|
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor.ktx \
|
||||||
@ -6958,7 +6986,9 @@ TEX2D_PREVIEW_PNG_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/characterIconMask_preview.png \
|
$(BUILD_DIR)/ba_data/textures/characterIconMask_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconEmpty_preview.png \
|
$(BUILD_DIR)/ba_data/textures/chestIconEmpty_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIconMulti_preview.png \
|
$(BUILD_DIR)/ba_data/textures/chestIconMulti_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestIconTint_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/chestIcon_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/chestOpenIconTint_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/chestOpenIcon_preview.png \
|
$(BUILD_DIR)/ba_data/textures/chestOpenIcon_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleNoAlpha_preview.png \
|
$(BUILD_DIR)/ba_data/textures/circleNoAlpha_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/circleOutlineNoAlpha_preview.png \
|
$(BUILD_DIR)/ba_data/textures/circleOutlineNoAlpha_preview.png \
|
||||||
@ -7208,6 +7238,7 @@ TEX2D_PREVIEW_PNG_TARGETS = \
|
|||||||
$(BUILD_DIR)/ba_data/textures/softRectVertical_preview.png \
|
$(BUILD_DIR)/ba_data/textures/softRectVertical_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/softRect_preview.png \
|
$(BUILD_DIR)/ba_data/textures/softRect_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/sparks_preview.png \
|
$(BUILD_DIR)/ba_data/textures/sparks_preview.png \
|
||||||
|
$(BUILD_DIR)/ba_data/textures/spinner_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/star_preview.png \
|
$(BUILD_DIR)/ba_data/textures/star_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/startButton_preview.png \
|
$(BUILD_DIR)/ba_data/textures/startButton_preview.png \
|
||||||
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor_preview.png \
|
$(BUILD_DIR)/ba_data/textures/stepRightUpLevelColor_preview.png \
|
||||||
|
|||||||
@ -68,9 +68,10 @@ class App:
|
|||||||
health_monitor: AppHealthMonitor
|
health_monitor: AppHealthMonitor
|
||||||
|
|
||||||
# How long we allow shutdown tasks to run before killing them.
|
# How long we allow shutdown tasks to run before killing them.
|
||||||
# Currently the entire app hard-exits if shutdown takes 10 seconds,
|
# Currently the entire app hard-exits if shutdown takes 15 seconds,
|
||||||
# so we need to keep it under that.
|
# so we need to keep it under that. Staying above 10 should allow
|
||||||
SHUTDOWN_TASK_TIMEOUT_SECONDS = 5
|
# 10 second network timeouts to happen though.
|
||||||
|
SHUTDOWN_TASK_TIMEOUT_SECONDS = 12
|
||||||
|
|
||||||
class State(Enum):
|
class State(Enum):
|
||||||
"""High level state the app can be in."""
|
"""High level state the app can be in."""
|
||||||
|
|||||||
@ -30,7 +30,9 @@ def utc_now_cloud() -> datetime.datetime:
|
|||||||
|
|
||||||
Applies offsets pulled from server communication/etc.
|
Applies offsets pulled from server communication/etc.
|
||||||
"""
|
"""
|
||||||
# FIXME - do something smart here.
|
# TODO: wire this up. Just using local time for now. Make sure that
|
||||||
|
# BaseFeatureSet::TimeSinceEpochCloudSeconds() and this are synced
|
||||||
|
# up.
|
||||||
return utc_now()
|
return utc_now()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,11 @@
|
|||||||
#
|
#
|
||||||
"""Components for the classic BombSquad experience.
|
"""Components for the classic BombSquad experience.
|
||||||
|
|
||||||
This package is used as a dumping ground for functionality that is
|
This package/feature-set contains functionality related to the classic
|
||||||
necessary to keep classic BombSquad working, but which may no longer be
|
BombSquad experience. Note that much legacy BombSquad code is still a
|
||||||
the best way to do things going forward.
|
bit tangled and thus this feature-set is largely inseperable from
|
||||||
|
scenev1 and uiv1. Future feature-sets will be designed in a more modular
|
||||||
New code should try to avoid using code from here when possible.
|
way.
|
||||||
|
|
||||||
Functionality in this package should be exposed through the
|
|
||||||
ClassicAppSubsystem. This allows type-checked code to go through the
|
|
||||||
babase.app.classic singleton which forces it to explicitly handle the
|
|
||||||
possibility of babase.app.classic being None. When code instead imports
|
|
||||||
classic submodules directly, it is much harder to make it cleanly handle
|
|
||||||
classic not being present.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ba_meta require api 9
|
# ba_meta require api 9
|
||||||
@ -29,8 +22,16 @@ from efro.util import set_canonical_module_names
|
|||||||
from baclassic._appmode import ClassicAppMode
|
from baclassic._appmode import ClassicAppMode
|
||||||
from baclassic._appsubsystem import ClassicAppSubsystem
|
from baclassic._appsubsystem import ClassicAppSubsystem
|
||||||
from baclassic._achievement import Achievement, AchievementSubsystem
|
from baclassic._achievement import Achievement, AchievementSubsystem
|
||||||
|
from baclassic._chest import (
|
||||||
|
ChestAppearanceDisplayInfo,
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT,
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFOS,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
'ChestAppearanceDisplayInfo',
|
||||||
|
'CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT',
|
||||||
|
'CHEST_APPEARANCE_DISPLAY_INFOS',
|
||||||
'ClassicAppMode',
|
'ClassicAppMode',
|
||||||
'ClassicAppSubsystem',
|
'ClassicAppSubsystem',
|
||||||
'Achievement',
|
'Achievement',
|
||||||
|
|||||||
@ -197,9 +197,9 @@ class ClassicAppMode(babase.AppMode):
|
|||||||
if account is None:
|
if account is None:
|
||||||
self._account_data_sub = None
|
self._account_data_sub = None
|
||||||
_baclassic.set_root_ui_account_values(
|
_baclassic.set_root_ui_account_values(
|
||||||
tickets_text='',
|
tickets=-1,
|
||||||
tokens_text='',
|
tokens=-1,
|
||||||
league_rank_text='',
|
league_rank=-1,
|
||||||
league_type='',
|
league_type='',
|
||||||
achievements_percent_text='',
|
achievements_percent_text='',
|
||||||
level_text='',
|
level_text='',
|
||||||
@ -250,7 +250,7 @@ class ClassicAppMode(babase.AppMode):
|
|||||||
print(f'GOT SUB TEST UPDATE: {val}')
|
print(f'GOT SUB TEST UPDATE: {val}')
|
||||||
|
|
||||||
def _on_classic_account_data_change(
|
def _on_classic_account_data_change(
|
||||||
self, val: bacommon.cloud.BSClassicAccountLiveData
|
self, val: bacommon.bs.ClassicAccountLiveData
|
||||||
) -> None:
|
) -> None:
|
||||||
# print('ACCOUNT CHANGED:', val)
|
# print('ACCOUNT CHANGED:', val)
|
||||||
achp = round(val.achievements / max(val.achievements_total, 1) * 100.0)
|
achp = round(val.achievements / max(val.achievements_total, 1) * 100.0)
|
||||||
@ -264,11 +264,9 @@ class ClassicAppMode(babase.AppMode):
|
|||||||
chest3 = val.chests.get('3')
|
chest3 = val.chests.get('3')
|
||||||
|
|
||||||
_baclassic.set_root_ui_account_values(
|
_baclassic.set_root_ui_account_values(
|
||||||
tickets_text=str(val.tickets),
|
tickets=val.tickets,
|
||||||
tokens_text=str(val.tokens),
|
tokens=val.tokens,
|
||||||
league_rank_text=(
|
league_rank=(-1 if val.league_rank is None else val.league_rank),
|
||||||
'-' if val.league_rank is None else f'#{val.league_rank}'
|
|
||||||
),
|
|
||||||
league_type=(
|
league_type=(
|
||||||
'' if val.league_type is None else val.league_type.value
|
'' if val.league_type is None else val.league_type.value
|
||||||
),
|
),
|
||||||
@ -292,17 +290,35 @@ class ClassicAppMode(babase.AppMode):
|
|||||||
chest_0_unlock_time=(
|
chest_0_unlock_time=(
|
||||||
-1.0 if chest0 is None else chest0.unlock_time.timestamp()
|
-1.0 if chest0 is None else chest0.unlock_time.timestamp()
|
||||||
),
|
),
|
||||||
chest_1_unlock_time=-1.0,
|
chest_1_unlock_time=(
|
||||||
chest_2_unlock_time=-1.0,
|
-1.0 if chest1 is None else chest1.unlock_time.timestamp()
|
||||||
chest_3_unlock_time=-1.0,
|
),
|
||||||
|
chest_2_unlock_time=(
|
||||||
|
-1.0 if chest2 is None else chest2.unlock_time.timestamp()
|
||||||
|
),
|
||||||
|
chest_3_unlock_time=(
|
||||||
|
-1.0 if chest3 is None else chest3.unlock_time.timestamp()
|
||||||
|
),
|
||||||
chest_0_ad_allow_time=(
|
chest_0_ad_allow_time=(
|
||||||
-1.0
|
-1.0
|
||||||
if chest0 is None or chest0.ad_allow_time is None
|
if chest0 is None or chest0.ad_allow_time is None
|
||||||
else chest0.ad_allow_time.timestamp()
|
else chest0.ad_allow_time.timestamp()
|
||||||
),
|
),
|
||||||
chest_1_ad_allow_time=-1.0,
|
chest_1_ad_allow_time=(
|
||||||
chest_2_ad_allow_time=-1.0,
|
-1.0
|
||||||
chest_3_ad_allow_time=-1.0,
|
if chest1 is None or chest1.ad_allow_time is None
|
||||||
|
else chest1.ad_allow_time.timestamp()
|
||||||
|
),
|
||||||
|
chest_2_ad_allow_time=(
|
||||||
|
-1.0
|
||||||
|
if chest2 is None or chest2.ad_allow_time is None
|
||||||
|
else chest2.ad_allow_time.timestamp()
|
||||||
|
),
|
||||||
|
chest_3_ad_allow_time=(
|
||||||
|
-1.0
|
||||||
|
if chest3 is None or chest3.ad_allow_time is None
|
||||||
|
else chest3.ad_allow_time.timestamp()
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note that we have values and updated faded state accordingly.
|
# Note that we have values and updated faded state accordingly.
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
"""Provides classic app subsystem."""
|
"""Provides classic app subsystem."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, override
|
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
import weakref
|
import weakref
|
||||||
|
from typing import TYPE_CHECKING, override, assert_never
|
||||||
|
|
||||||
from efro.dataclassio import dataclass_from_dict
|
from efro.dataclassio import dataclass_from_dict
|
||||||
import babase
|
import babase
|
||||||
@ -26,6 +26,7 @@ from baclassic import _input
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Callable, Any, Sequence
|
from typing import Callable, Any, Sequence
|
||||||
|
|
||||||
|
import bacommon.bs
|
||||||
from bascenev1lib.actor import spazappearance
|
from bascenev1lib.actor import spazappearance
|
||||||
from bauiv1lib.party import PartyWindow
|
from bauiv1lib.party import PartyWindow
|
||||||
|
|
||||||
@ -509,11 +510,36 @@ class ClassicAppSubsystem(babase.AppSubsystem):
|
|||||||
request, 'post', data, callback, response_type
|
request, 'post', data, callback, response_type
|
||||||
).start()
|
).start()
|
||||||
|
|
||||||
def get_tournament_prize_strings(self, entry: dict[str, Any]) -> list[str]:
|
def set_tournament_prize_image(
|
||||||
|
self, entry: dict[str, Any], index: int, image: bauiv1.Widget
|
||||||
|
) -> None:
|
||||||
"""Given a tournament entry, return strings for its prize levels."""
|
"""Given a tournament entry, return strings for its prize levels."""
|
||||||
from baclassic import _tournament
|
from baclassic import _tournament
|
||||||
|
|
||||||
return _tournament.get_tournament_prize_strings(entry)
|
return _tournament.set_tournament_prize_chest_image(entry, index, image)
|
||||||
|
|
||||||
|
def create_in_game_tournament_prize_image(
|
||||||
|
self,
|
||||||
|
entry: dict[str, Any],
|
||||||
|
index: int,
|
||||||
|
position: tuple[float, float],
|
||||||
|
) -> None:
|
||||||
|
"""Given a tournament entry, return strings for its prize levels."""
|
||||||
|
from baclassic import _tournament
|
||||||
|
|
||||||
|
_tournament.create_in_game_tournament_prize_image(
|
||||||
|
entry, index, position
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_tournament_prize_strings(
|
||||||
|
self, entry: dict[str, Any], include_tickets: bool
|
||||||
|
) -> list[str]:
|
||||||
|
"""Given a tournament entry, return strings for its prize levels."""
|
||||||
|
from baclassic import _tournament
|
||||||
|
|
||||||
|
return _tournament.get_tournament_prize_strings(
|
||||||
|
entry, include_tickets=include_tickets
|
||||||
|
)
|
||||||
|
|
||||||
def getcampaign(self, name: str) -> bascenev1.Campaign:
|
def getcampaign(self, name: str) -> bascenev1.Campaign:
|
||||||
"""Return a campaign by name."""
|
"""Return a campaign by name."""
|
||||||
@ -852,3 +878,48 @@ class ClassicAppSubsystem(babase.AppSubsystem):
|
|||||||
is_top_level=True,
|
is_top_level=True,
|
||||||
suppress_warning=True,
|
suppress_warning=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def run_bs_client_effects(effects: list[bacommon.bs.ClientEffect]) -> None:
|
||||||
|
"""Run client effects sent from the master server."""
|
||||||
|
from baclassic._clienteffect import run_bs_client_effects
|
||||||
|
|
||||||
|
run_bs_client_effects(effects)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def basic_client_ui_button_label_str(
|
||||||
|
label: bacommon.bs.BasicClientUI.ButtonLabel,
|
||||||
|
) -> babase.Lstr:
|
||||||
|
"""Given a client-ui label, return an Lstr."""
|
||||||
|
import bacommon.bs
|
||||||
|
|
||||||
|
cls = bacommon.bs.BasicClientUI.ButtonLabel
|
||||||
|
if label is cls.UNKNOWN:
|
||||||
|
# Server should not be sending us unknown stuff; make noise
|
||||||
|
# if they do.
|
||||||
|
logging.error(
|
||||||
|
'Got BasicClientUI.ButtonLabel.UNKNOWN; should not happen.'
|
||||||
|
)
|
||||||
|
return babase.Lstr(value='<error>')
|
||||||
|
|
||||||
|
rsrc: str | None = None
|
||||||
|
if label is cls.OK:
|
||||||
|
rsrc = 'okText'
|
||||||
|
elif label is cls.APPLY:
|
||||||
|
rsrc = 'applyText'
|
||||||
|
elif label is cls.CANCEL:
|
||||||
|
rsrc = 'cancelText'
|
||||||
|
elif label is cls.ACCEPT:
|
||||||
|
rsrc = 'gatherWindow.partyInviteAcceptText'
|
||||||
|
elif label is cls.DECLINE:
|
||||||
|
rsrc = 'gatherWindow.partyInviteDeclineText'
|
||||||
|
elif label is cls.IGNORE:
|
||||||
|
rsrc = 'gatherWindow.partyInviteIgnoreText'
|
||||||
|
elif label is cls.CLAIM:
|
||||||
|
rsrc = 'claimText'
|
||||||
|
elif label is cls.DISCARD:
|
||||||
|
rsrc = 'discardText'
|
||||||
|
else:
|
||||||
|
assert_never(label)
|
||||||
|
|
||||||
|
return babase.Lstr(resource=rsrc)
|
||||||
|
|||||||
91
src/assets/ba_data/python/baclassic/_chest.py
Normal file
91
src/assets/ba_data/python/baclassic/_chest.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Chest related functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from bacommon.bs import ClassicChestAppearance
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ChestAppearanceDisplayInfo:
|
||||||
|
"""Info about how to locally display chest appearances."""
|
||||||
|
|
||||||
|
# NOTE TO SELF: Don't rename these attrs; the C++ layer is hard
|
||||||
|
# coded to look for them.
|
||||||
|
|
||||||
|
texclosed: str
|
||||||
|
texclosedtint: str
|
||||||
|
texopen: str
|
||||||
|
texopentint: str
|
||||||
|
color: tuple[float, float, float]
|
||||||
|
tint: tuple[float, float, float]
|
||||||
|
tint2: tuple[float, float, float]
|
||||||
|
|
||||||
|
|
||||||
|
# Info for chest types we know how to draw. Anything not found in here
|
||||||
|
# should fall back to the DEFAULT entry.
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT = ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(1, 1, 1),
|
||||||
|
tint=(1, 1, 1),
|
||||||
|
tint2=(1, 1, 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFOS: dict[
|
||||||
|
ClassicChestAppearance, ChestAppearanceDisplayInfo
|
||||||
|
] = {
|
||||||
|
ClassicChestAppearance.L2: ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(0.8, 1.0, 0.93),
|
||||||
|
tint=(0.65, 1.0, 0.8),
|
||||||
|
tint2=(0.65, 1.0, 0.8),
|
||||||
|
),
|
||||||
|
ClassicChestAppearance.L3: ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(0.75, 0.9, 1.3),
|
||||||
|
tint=(0.7, 1, 1.9),
|
||||||
|
tint2=(0.7, 1, 1.9),
|
||||||
|
),
|
||||||
|
ClassicChestAppearance.L4: ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(0.7, 1.0, 1.4),
|
||||||
|
tint=(1.4, 1.6, 2.0),
|
||||||
|
tint2=(1.4, 1.6, 2.0),
|
||||||
|
),
|
||||||
|
ClassicChestAppearance.L5: ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(0.75, 0.5, 2.4),
|
||||||
|
tint=(1.0, 0.8, 0.0),
|
||||||
|
tint2=(1.0, 0.8, 0.0),
|
||||||
|
),
|
||||||
|
ClassicChestAppearance.L6: ChestAppearanceDisplayInfo(
|
||||||
|
texclosed='chestIcon',
|
||||||
|
texclosedtint='chestIconTint',
|
||||||
|
texopen='chestOpenIcon',
|
||||||
|
texopentint='chestOpenIconTint',
|
||||||
|
color=(1.1, 0.8, 0.0),
|
||||||
|
tint=(2, 2, 2),
|
||||||
|
tint2=(2, 2, 2),
|
||||||
|
),
|
||||||
|
}
|
||||||
77
src/assets/ba_data/python/baclassic/_clienteffect.py
Normal file
77
src/assets/ba_data/python/baclassic/_clienteffect.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Functionality related to running client-effects from the master server."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import TYPE_CHECKING, assert_never
|
||||||
|
|
||||||
|
from efro.util import strict_partial
|
||||||
|
|
||||||
|
import bacommon.bs
|
||||||
|
import bauiv1
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def run_bs_client_effects(effects: list[bacommon.bs.ClientEffect]) -> None:
|
||||||
|
"""Run effects."""
|
||||||
|
# pylint: disable=too-many-branches
|
||||||
|
|
||||||
|
delay = 0.0
|
||||||
|
for effect in effects:
|
||||||
|
if isinstance(effect, bacommon.bs.ClientEffectScreenMessage):
|
||||||
|
textfin = bauiv1.Lstr(
|
||||||
|
translate=('serverResponses', effect.message)
|
||||||
|
).evaluate()
|
||||||
|
if effect.subs is not None:
|
||||||
|
# Should always be even.
|
||||||
|
assert len(effect.subs) % 2 == 0
|
||||||
|
for j in range(0, len(effect.subs) - 1, 2):
|
||||||
|
textfin = textfin.replace(
|
||||||
|
effect.subs[j],
|
||||||
|
effect.subs[j + 1],
|
||||||
|
)
|
||||||
|
bauiv1.apptimer(
|
||||||
|
delay,
|
||||||
|
strict_partial(
|
||||||
|
bauiv1.screenmessage, textfin, color=effect.color
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
elif isinstance(effect, bacommon.bs.ClientEffectSound):
|
||||||
|
smcls = bacommon.bs.ClientEffectSound.Sound
|
||||||
|
soundfile: str | None = None
|
||||||
|
if effect.sound is smcls.UNKNOWN:
|
||||||
|
# Server should avoid sending us sounds we don't
|
||||||
|
# support. Make some noise if it happens.
|
||||||
|
logging.error('Got unrecognized bacommon.bs.ClientEffectSound.')
|
||||||
|
elif effect.sound is smcls.CASH_REGISTER:
|
||||||
|
soundfile = 'cashRegister'
|
||||||
|
elif effect.sound is smcls.ERROR:
|
||||||
|
soundfile = 'error'
|
||||||
|
elif effect.sound is smcls.POWER_DOWN:
|
||||||
|
soundfile = 'powerdown01'
|
||||||
|
elif effect.sound is smcls.GUN_COCKING:
|
||||||
|
soundfile = 'gunCocking'
|
||||||
|
else:
|
||||||
|
assert_never(effect.sound)
|
||||||
|
if soundfile is not None:
|
||||||
|
bauiv1.apptimer(
|
||||||
|
delay,
|
||||||
|
strict_partial(
|
||||||
|
bauiv1.getsound(soundfile).play, volume=effect.volume
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
elif isinstance(effect, bacommon.bs.ClientEffectDelay):
|
||||||
|
delay += effect.seconds
|
||||||
|
else:
|
||||||
|
# Server should not send us stuff we can't digest. Make
|
||||||
|
# some noise if it happens.
|
||||||
|
logging.error(
|
||||||
|
'Got unrecognized bacommon.bs.ClientEffect;'
|
||||||
|
' should not happen.'
|
||||||
|
)
|
||||||
@ -6,13 +6,23 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from bacommon.bs import ClassicChestAppearance
|
||||||
import babase
|
import babase
|
||||||
|
import bauiv1
|
||||||
|
import bascenev1
|
||||||
|
|
||||||
|
from baclassic._chest import (
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFOS,
|
||||||
|
CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def get_tournament_prize_strings(entry: dict[str, Any]) -> list[str]:
|
def get_tournament_prize_strings(
|
||||||
|
entry: dict[str, Any], include_tickets: bool
|
||||||
|
) -> list[str]:
|
||||||
"""Given a tournament entry, return strings for its prize levels."""
|
"""Given a tournament entry, return strings for its prize levels."""
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
from bascenev1 import get_trophy_string
|
from bascenev1 import get_trophy_string
|
||||||
@ -27,7 +37,7 @@ def get_tournament_prize_strings(entry: dict[str, Any]) -> list[str]:
|
|||||||
trophy_type_2 = entry.get('prizeTrophy2')
|
trophy_type_2 = entry.get('prizeTrophy2')
|
||||||
trophy_type_3 = entry.get('prizeTrophy3')
|
trophy_type_3 = entry.get('prizeTrophy3')
|
||||||
out_vals = []
|
out_vals = []
|
||||||
for rng, prize, trophy_type in (
|
for rng, ticket_prize, trophy_type in (
|
||||||
(range1, prize1, trophy_type_1),
|
(range1, prize1, trophy_type_1),
|
||||||
(range2, prize2, trophy_type_2),
|
(range2, prize2, trophy_type_2),
|
||||||
(range3, prize3, trophy_type_3),
|
(range3, prize3, trophy_type_3),
|
||||||
@ -45,14 +55,100 @@ def get_tournament_prize_strings(entry: dict[str, Any]) -> list[str]:
|
|||||||
if trophy_type is not None:
|
if trophy_type is not None:
|
||||||
pvval += get_trophy_string(trophy_type)
|
pvval += get_trophy_string(trophy_type)
|
||||||
|
|
||||||
# If we've got trophies but not for this entry, throw some space
|
if ticket_prize is not None and include_tickets:
|
||||||
# in to compensate so the ticket counts line up.
|
|
||||||
if prize is not None:
|
|
||||||
pvval = (
|
pvval = (
|
||||||
babase.charstr(babase.SpecialChar.TICKET_BACKING)
|
babase.charstr(babase.SpecialChar.TICKET_BACKING)
|
||||||
+ str(prize)
|
+ str(ticket_prize)
|
||||||
+ pvval
|
+ pvval
|
||||||
)
|
)
|
||||||
out_vals.append(prval)
|
out_vals.append(prval)
|
||||||
out_vals.append(pvval)
|
out_vals.append(pvval)
|
||||||
return out_vals
|
return out_vals
|
||||||
|
|
||||||
|
|
||||||
|
def set_tournament_prize_chest_image(
|
||||||
|
entry: dict[str, Any], index: int, image: bauiv1.Widget
|
||||||
|
) -> None:
|
||||||
|
"""Set image attrs representing a tourney prize chest."""
|
||||||
|
ranges = [
|
||||||
|
entry.get('prizeRange1'),
|
||||||
|
entry.get('prizeRange2'),
|
||||||
|
entry.get('prizeRange3'),
|
||||||
|
]
|
||||||
|
chests = [
|
||||||
|
entry.get('prizeChest1'),
|
||||||
|
entry.get('prizeChest2'),
|
||||||
|
entry.get('prizeChest3'),
|
||||||
|
]
|
||||||
|
|
||||||
|
assert 0 <= index < 3
|
||||||
|
|
||||||
|
# If tourney doesn't include this prize, just hide the image.
|
||||||
|
if ranges[index] is None:
|
||||||
|
bauiv1.imagewidget(edit=image, opacity=0.0)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
appearance = ClassicChestAppearance(chests[index])
|
||||||
|
except ValueError:
|
||||||
|
appearance = ClassicChestAppearance.DEFAULT
|
||||||
|
chestdisplayinfo = CHEST_APPEARANCE_DISPLAY_INFOS.get(
|
||||||
|
appearance, CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT
|
||||||
|
)
|
||||||
|
bauiv1.imagewidget(
|
||||||
|
edit=image,
|
||||||
|
opacity=1.0,
|
||||||
|
color=chestdisplayinfo.color,
|
||||||
|
texture=bauiv1.gettexture(chestdisplayinfo.texclosed),
|
||||||
|
tint_texture=bauiv1.gettexture(chestdisplayinfo.texclosedtint),
|
||||||
|
tint_color=chestdisplayinfo.tint,
|
||||||
|
tint2_color=chestdisplayinfo.tint2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_in_game_tournament_prize_image(
|
||||||
|
entry: dict[str, Any], index: int, position: tuple[float, float]
|
||||||
|
) -> None:
|
||||||
|
"""Create a display for the prize chest (if any) in-game."""
|
||||||
|
from bascenev1lib.actor.image import Image
|
||||||
|
|
||||||
|
ranges = [
|
||||||
|
entry.get('prizeRange1'),
|
||||||
|
entry.get('prizeRange2'),
|
||||||
|
entry.get('prizeRange3'),
|
||||||
|
]
|
||||||
|
chests = [
|
||||||
|
entry.get('prizeChest1'),
|
||||||
|
entry.get('prizeChest2'),
|
||||||
|
entry.get('prizeChest3'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# If tourney doesn't include this prize, no-op.
|
||||||
|
if ranges[index] is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
appearance = ClassicChestAppearance(chests[index])
|
||||||
|
except ValueError:
|
||||||
|
appearance = ClassicChestAppearance.DEFAULT
|
||||||
|
chestdisplayinfo = CHEST_APPEARANCE_DISPLAY_INFOS.get(
|
||||||
|
appearance, CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT
|
||||||
|
)
|
||||||
|
Image(
|
||||||
|
# Provide magical extended dict version of texture that Image
|
||||||
|
# actor supports.
|
||||||
|
texture={
|
||||||
|
'texture': bascenev1.gettexture(chestdisplayinfo.texclosed),
|
||||||
|
'tint_texture': bascenev1.gettexture(
|
||||||
|
chestdisplayinfo.texclosedtint
|
||||||
|
),
|
||||||
|
'tint_color': chestdisplayinfo.tint,
|
||||||
|
'tint2_color': chestdisplayinfo.tint2,
|
||||||
|
'mask_texture': None,
|
||||||
|
},
|
||||||
|
color=chestdisplayinfo.color + (1.0,),
|
||||||
|
position=position,
|
||||||
|
scale=(48.0, 48.0),
|
||||||
|
transition=Image.Transition.FADE_IN,
|
||||||
|
transition_delay=2.0,
|
||||||
|
).autoretain()
|
||||||
|
|||||||
@ -53,7 +53,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 = 22155
|
TARGET_BALLISTICA_BUILD = 22178
|
||||||
TARGET_BALLISTICA_VERSION = '1.7.37'
|
TARGET_BALLISTICA_VERSION = '1.7.37'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import _baplus
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Callable, Any
|
from typing import Callable, Any
|
||||||
|
|
||||||
|
import bacommon.bs
|
||||||
from babase import AccountV2Subsystem
|
from babase import AccountV2Subsystem
|
||||||
|
|
||||||
from baplus._cloud import CloudSubsystem
|
from baplus._cloud import CloudSubsystem
|
||||||
|
|||||||
@ -15,6 +15,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
from efro.message import Message, Response
|
from efro.message import Message, Response
|
||||||
import bacommon.cloud
|
import bacommon.cloud
|
||||||
|
import bacommon.bs
|
||||||
|
|
||||||
|
|
||||||
# TODO: Should make it possible to define a protocol in bacommon.cloud and
|
# TODO: Should make it possible to define a protocol in bacommon.cloud and
|
||||||
@ -120,45 +121,45 @@ class CloudSubsystem(babase.AppSubsystem):
|
|||||||
@overload
|
@overload
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: bacommon.cloud.BSPrivatePartyMessage,
|
msg: bacommon.bs.PrivatePartyMessage,
|
||||||
on_response: Callable[
|
on_response: Callable[
|
||||||
[bacommon.cloud.BSPrivatePartyResponse | Exception], None
|
[bacommon.bs.PrivatePartyResponse | Exception], None
|
||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: bacommon.cloud.BSInboxRequestMessage,
|
msg: bacommon.bs.InboxRequestMessage,
|
||||||
on_response: Callable[
|
on_response: Callable[
|
||||||
[bacommon.cloud.BSInboxRequestResponse | Exception], None
|
[bacommon.bs.InboxRequestResponse | Exception], None
|
||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: bacommon.cloud.BSInboxEntryProcessMessage,
|
msg: bacommon.bs.ClientUIActionMessage,
|
||||||
on_response: Callable[
|
on_response: Callable[
|
||||||
[bacommon.cloud.BSInboxEntryProcessResponse | Exception], None
|
[bacommon.bs.ClientUIActionResponse | Exception], None
|
||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: bacommon.cloud.BSChestInfoMessage,
|
msg: bacommon.bs.ChestInfoMessage,
|
||||||
on_response: Callable[
|
on_response: Callable[
|
||||||
[bacommon.cloud.BSChestInfoResponse | Exception], None
|
[bacommon.bs.ChestInfoResponse | Exception], None
|
||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def send_message_cb(
|
def send_message_cb(
|
||||||
self,
|
self,
|
||||||
msg: bacommon.cloud.BSChestActionMessage,
|
msg: bacommon.bs.ChestActionMessage,
|
||||||
on_response: Callable[
|
on_response: Callable[
|
||||||
[bacommon.cloud.BSChestActionResponse | Exception], None
|
[bacommon.bs.ChestActionResponse | Exception], None
|
||||||
],
|
],
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
@ -229,7 +230,7 @@ class CloudSubsystem(babase.AppSubsystem):
|
|||||||
|
|
||||||
def subscribe_classic_account_data(
|
def subscribe_classic_account_data(
|
||||||
self,
|
self,
|
||||||
updatecall: Callable[[bacommon.cloud.BSClassicAccountLiveData], None],
|
updatecall: Callable[[bacommon.bs.ClassicAccountLiveData], None],
|
||||||
) -> babase.CloudSubscription:
|
) -> babase.CloudSubscription:
|
||||||
"""Subscribe to classic account data."""
|
"""Subscribe to classic account data."""
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
|
|||||||
@ -357,6 +357,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
|
|
||||||
h_offs = 7.0
|
h_offs = 7.0
|
||||||
v_offs = -280.0
|
v_offs = -280.0
|
||||||
|
v_offs2 = -236.0
|
||||||
|
|
||||||
# We wanna prevent controllers users from popping up browsers
|
# We wanna prevent controllers users from popping up browsers
|
||||||
# or game-center widgets in cases where they can't easily get back
|
# or game-center widgets in cases where they can't easily get back
|
||||||
@ -384,7 +385,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
bui.buttonwidget(
|
bui.buttonwidget(
|
||||||
parent=rootc,
|
parent=rootc,
|
||||||
color=(0.45, 0.4, 0.5),
|
color=(0.45, 0.4, 0.5),
|
||||||
position=(160, v_offs + 439),
|
position=(240, v_offs2 + 439),
|
||||||
size=(350, 62),
|
size=(350, 62),
|
||||||
label=(
|
label=(
|
||||||
bui.Lstr(resource='tournamentStandingsText')
|
bui.Lstr(resource='tournamentStandingsText')
|
||||||
@ -406,7 +407,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
show_next_button = self._is_more_levels and not (env.demo or env.arcade)
|
show_next_button = self._is_more_levels and not (env.demo or env.arcade)
|
||||||
|
|
||||||
if not show_next_button:
|
if not show_next_button:
|
||||||
h_offs += 70
|
h_offs += 60
|
||||||
|
|
||||||
# Due to virtual-bounds changes, have to squish buttons a bit to
|
# Due to virtual-bounds changes, have to squish buttons a bit to
|
||||||
# avoid overlapping with tips at bottom. Could look nicer to
|
# avoid overlapping with tips at bottom. Could look nicer to
|
||||||
@ -614,7 +615,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
# FIXME: Clean this up.
|
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
@ -882,7 +882,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
# If we're not doing the world's-best button, just show a title
|
# If we're not doing the world's-best button, just show a title
|
||||||
# instead.
|
# instead.
|
||||||
ts_height = 300
|
ts_height = 300
|
||||||
ts_h_offs = 210
|
ts_h_offs = 290
|
||||||
v_offs = 40
|
v_offs = 40
|
||||||
txt = Text(
|
txt = Text(
|
||||||
(
|
(
|
||||||
@ -956,7 +956,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
if display_scores[i][1] is None:
|
if display_scores[i][1] is None:
|
||||||
name_str = '-'
|
name_str = '-'
|
||||||
else:
|
else:
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
name_str = ', '.join(
|
name_str = ', '.join(
|
||||||
[p['name'] for p in display_scores[i][1]['players']]
|
[p['name'] for p in display_scores[i][1]['players']]
|
||||||
)
|
)
|
||||||
@ -1025,9 +1024,8 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
ts_h_offs = -480
|
ts_h_offs = -480
|
||||||
v_offs = 40
|
v_offs = 40
|
||||||
|
|
||||||
# Only make this if we don't have the button
|
# Only make this if we don't have the button (never want clients
|
||||||
# (never want clients to see it so no need for client-only
|
# to see it so no need for client-only version, etc).
|
||||||
# version, etc).
|
|
||||||
if self._have_achievements:
|
if self._have_achievements:
|
||||||
if not self._account_has_achievements:
|
if not self._account_has_achievements:
|
||||||
Text(
|
Text(
|
||||||
@ -1069,7 +1067,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
).autoretain()
|
).autoretain()
|
||||||
|
|
||||||
def _got_friend_score_results(self, results: list[Any] | None) -> None:
|
def _got_friend_score_results(self, results: list[Any] | None) -> None:
|
||||||
# FIXME: tidy this up
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
@ -1205,7 +1202,6 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
).autoretain()
|
).autoretain()
|
||||||
|
|
||||||
def _got_score_results(self, results: dict[str, Any] | None) -> None:
|
def _got_score_results(self, results: dict[str, Any] | None) -> None:
|
||||||
# FIXME: tidy this up
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
@ -1222,11 +1218,12 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
# Delay a bit if results come in too fast.
|
# Delay a bit if results come in too fast.
|
||||||
assert self._begin_time is not None
|
assert self._begin_time is not None
|
||||||
base_delay = max(0, 2.7 - (bs.time() - self._begin_time))
|
base_delay = max(0, 2.7 - (bs.time() - self._begin_time))
|
||||||
v_offs = 20
|
# v_offs = 20
|
||||||
|
v_offs = 64
|
||||||
if results is None:
|
if results is None:
|
||||||
self._score_loading_status = Text(
|
self._score_loading_status = Text(
|
||||||
bs.Lstr(resource='worldScoresUnavailableText'),
|
bs.Lstr(resource='worldScoresUnavailableText'),
|
||||||
position=(230, 150 + v_offs),
|
position=(280, 130 + v_offs),
|
||||||
color=(1, 1, 1, 0.4),
|
color=(1, 1, 1, 0.4),
|
||||||
transition=Text.Transition.FADE_IN,
|
transition=Text.Transition.FADE_IN,
|
||||||
transition_delay=base_delay + 0.3,
|
transition_delay=base_delay + 0.3,
|
||||||
@ -1271,7 +1268,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
(1.5 + base_delay),
|
(1.5 + base_delay),
|
||||||
bs.WeakCall(self._show_world_rank, offs_x),
|
bs.WeakCall(self._show_world_rank, offs_x),
|
||||||
)
|
)
|
||||||
ts_h_offs = 200
|
ts_h_offs = 280
|
||||||
ts_height = 300
|
ts_height = 300
|
||||||
|
|
||||||
# Show world tops.
|
# Show world tops.
|
||||||
@ -1299,7 +1296,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
transition_delay=base_delay + 0.3,
|
transition_delay=base_delay + 0.3,
|
||||||
).autoretain()
|
).autoretain()
|
||||||
else:
|
else:
|
||||||
v_offs += 20
|
v_offs += 40
|
||||||
|
|
||||||
h_offs_extra = 0
|
h_offs_extra = 0
|
||||||
v_offs_names = 0
|
v_offs_names = 0
|
||||||
@ -1326,6 +1323,37 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
random.randrange(0, len(times) + 1),
|
random.randrange(0, len(times) + 1),
|
||||||
(base_delay + i * 0.05, base_delay + 0.4 + i * 0.05),
|
(base_delay + i * 0.05, base_delay + 0.4 + i * 0.05),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Conundrum: We want to place line numbers to the
|
||||||
|
# left of our score column based on the largest
|
||||||
|
# score width. However scores may use Lstrs and thus
|
||||||
|
# may have different widths in different languages.
|
||||||
|
# We don't want to bake down the Lstrs we display
|
||||||
|
# because then clients can't view scores in their
|
||||||
|
# own language. So as a compromise lets measure
|
||||||
|
# max-width based on baked down Lstrs but then
|
||||||
|
# display regular Lstrs with max-width set based on
|
||||||
|
# that. Hopefully that'll look reasonable for most
|
||||||
|
# languages.
|
||||||
|
max_score_width = 10.0
|
||||||
|
for tval in self._show_info['tops']:
|
||||||
|
score = int(tval[0])
|
||||||
|
name_str = tval[1]
|
||||||
|
if name_str != '-':
|
||||||
|
max_score_width = max(
|
||||||
|
max_score_width,
|
||||||
|
bui.get_string_width(
|
||||||
|
(
|
||||||
|
str(score)
|
||||||
|
if self._score_type == 'points'
|
||||||
|
else bs.timestring(
|
||||||
|
(score * 10) / 1000.0
|
||||||
|
).evaluate()
|
||||||
|
),
|
||||||
|
suppress_warning=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
for i, tval in enumerate(self._show_info['tops']):
|
for i, tval in enumerate(self._show_info['tops']):
|
||||||
score = int(tval[0])
|
score = int(tval[0])
|
||||||
name_str = tval[1]
|
name_str = tval[1]
|
||||||
@ -1347,12 +1375,37 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
tdelay2 = times[i][1]
|
tdelay2 = times[i][1]
|
||||||
|
|
||||||
if name_str != '-':
|
if name_str != '-':
|
||||||
|
sstr = (
|
||||||
|
str(score)
|
||||||
|
if self._score_type == 'points'
|
||||||
|
else bs.timestring((score * 10) / 1000.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Line number.
|
||||||
Text(
|
Text(
|
||||||
(
|
str(i + 1),
|
||||||
str(score)
|
position=(
|
||||||
if self._score_type == 'points'
|
ts_h_offs
|
||||||
else bs.timestring((score * 10) / 1000.0)
|
+ 20
|
||||||
|
+ h_offs_extra
|
||||||
|
- max_score_width
|
||||||
|
- 8.0,
|
||||||
|
ts_height / 2
|
||||||
|
+ -ts_height * (i + 1) / 10
|
||||||
|
+ v_offs
|
||||||
|
- 30.0,
|
||||||
),
|
),
|
||||||
|
scale=0.5,
|
||||||
|
h_align=Text.HAlign.RIGHT,
|
||||||
|
v_align=Text.VAlign.CENTER,
|
||||||
|
color=(0.3, 0.3, 0.3),
|
||||||
|
transition=Text.Transition.IN_LEFT,
|
||||||
|
transition_delay=tdelay1,
|
||||||
|
).autoretain()
|
||||||
|
|
||||||
|
# Score.
|
||||||
|
Text(
|
||||||
|
sstr,
|
||||||
position=(
|
position=(
|
||||||
ts_h_offs + 20 + h_offs_extra,
|
ts_h_offs + 20 + h_offs_extra,
|
||||||
ts_height / 2
|
ts_height / 2
|
||||||
@ -1360,6 +1413,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
+ v_offs
|
+ v_offs
|
||||||
- 30.0,
|
- 30.0,
|
||||||
),
|
),
|
||||||
|
maxwidth=max_score_width,
|
||||||
h_align=Text.HAlign.RIGHT,
|
h_align=Text.HAlign.RIGHT,
|
||||||
v_align=Text.VAlign.CENTER,
|
v_align=Text.VAlign.CENTER,
|
||||||
color=color0,
|
color=color0,
|
||||||
@ -1367,6 +1421,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
transition=Text.Transition.IN_LEFT,
|
transition=Text.Transition.IN_LEFT,
|
||||||
transition_delay=tdelay1,
|
transition_delay=tdelay1,
|
||||||
).autoretain()
|
).autoretain()
|
||||||
|
# Player name.
|
||||||
Text(
|
Text(
|
||||||
bs.Lstr(value=name_str),
|
bs.Lstr(value=name_str),
|
||||||
position=(
|
position=(
|
||||||
@ -1470,16 +1525,12 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
]
|
]
|
||||||
# pylint: disable=useless-suppression
|
# pylint: disable=useless-suppression
|
||||||
# pylint: disable=unbalanced-tuple-unpacking
|
# pylint: disable=unbalanced-tuple-unpacking
|
||||||
(
|
(pr1, pv1, pr2, pv2, pr3, pv3) = (
|
||||||
pr1,
|
bs.app.classic.get_tournament_prize_strings(
|
||||||
pv1,
|
tourney_info, include_tickets=False
|
||||||
pr2,
|
)
|
||||||
pv2,
|
|
||||||
pr3,
|
|
||||||
pv3,
|
|
||||||
) = bs.app.classic.get_tournament_prize_strings(
|
|
||||||
tourney_info
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# pylint: enable=unbalanced-tuple-unpacking
|
# pylint: enable=unbalanced-tuple-unpacking
|
||||||
# pylint: enable=useless-suppression
|
# pylint: enable=useless-suppression
|
||||||
|
|
||||||
@ -1495,10 +1546,14 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
transition_delay=2.0,
|
transition_delay=2.0,
|
||||||
).autoretain()
|
).autoretain()
|
||||||
vval = -107 + 70
|
vval = -107 + 70
|
||||||
for rng, val in ((pr1, pv1), (pr2, pv2), (pr3, pv3)):
|
for i, rng, val in (
|
||||||
|
(0, pr1, pv1),
|
||||||
|
(1, pr2, pv2),
|
||||||
|
(2, pr3, pv3),
|
||||||
|
):
|
||||||
Text(
|
Text(
|
||||||
rng,
|
rng,
|
||||||
position=(-410 + 10, vval),
|
position=(-430 + 10, vval),
|
||||||
color=(1, 1, 1, 0.7),
|
color=(1, 1, 1, 0.7),
|
||||||
h_align=Text.HAlign.RIGHT,
|
h_align=Text.HAlign.RIGHT,
|
||||||
v_align=Text.VAlign.CENTER,
|
v_align=Text.VAlign.CENTER,
|
||||||
@ -1509,7 +1564,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
).autoretain()
|
).autoretain()
|
||||||
Text(
|
Text(
|
||||||
val,
|
val,
|
||||||
position=(-390 + 10, vval),
|
position=(-410 + 10, vval),
|
||||||
color=(0.7, 0.7, 0.7, 1.0),
|
color=(0.7, 0.7, 0.7, 1.0),
|
||||||
h_align=Text.HAlign.LEFT,
|
h_align=Text.HAlign.LEFT,
|
||||||
v_align=Text.VAlign.CENTER,
|
v_align=Text.VAlign.CENTER,
|
||||||
@ -1518,6 +1573,9 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||||||
maxwidth=300,
|
maxwidth=300,
|
||||||
transition_delay=2.0,
|
transition_delay=2.0,
|
||||||
).autoretain()
|
).autoretain()
|
||||||
|
bs.app.classic.create_in_game_tournament_prize_image(
|
||||||
|
tourney_info, i, (-410 + 70, vval)
|
||||||
|
)
|
||||||
vval -= 35
|
vval -= 35
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.exception('Error showing prize ranges.')
|
logging.exception('Error showing prize ranges.')
|
||||||
|
|||||||
@ -56,15 +56,21 @@ class Image(bs.Actor):
|
|||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
# If they provided a dict as texture, assume its an icon.
|
# If they provided a dict as texture, use it to wire up extended
|
||||||
# otherwise its just a texture value itself.
|
# stuff like tints and masks.
|
||||||
mask_texture: bs.Texture | None
|
mask_texture: bs.Texture | None
|
||||||
if isinstance(texture, dict):
|
if isinstance(texture, dict):
|
||||||
tint_color = texture['tint_color']
|
tint_color = texture['tint_color']
|
||||||
tint2_color = texture['tint2_color']
|
tint2_color = texture['tint2_color']
|
||||||
tint_texture = texture['tint_texture']
|
tint_texture = texture['tint_texture']
|
||||||
|
|
||||||
|
# Assume we're dealing with a character icon but allow
|
||||||
|
# overriding.
|
||||||
|
mask_tex_name = texture.get('mask_texture', 'characterIconMask')
|
||||||
|
mask_texture = (
|
||||||
|
None if mask_tex_name is None else bs.gettexture(mask_tex_name)
|
||||||
|
)
|
||||||
texture = texture['texture']
|
texture = texture['texture']
|
||||||
mask_texture = bs.gettexture('characterIconMask')
|
|
||||||
else:
|
else:
|
||||||
tint_color = (1, 1, 1)
|
tint_color = (1, 1, 1)
|
||||||
tint2_color = None
|
tint2_color = None
|
||||||
|
|||||||
@ -114,9 +114,12 @@ from _bauiv1 import (
|
|||||||
hscrollwidget,
|
hscrollwidget,
|
||||||
imagewidget,
|
imagewidget,
|
||||||
Mesh,
|
Mesh,
|
||||||
|
root_ui_pause_updates,
|
||||||
|
root_ui_resume_updates,
|
||||||
rowwidget,
|
rowwidget,
|
||||||
scrollwidget,
|
scrollwidget,
|
||||||
set_party_window_open,
|
set_party_window_open,
|
||||||
|
spinnerwidget,
|
||||||
Sound,
|
Sound,
|
||||||
Texture,
|
Texture,
|
||||||
textwidget,
|
textwidget,
|
||||||
@ -218,6 +221,8 @@ __all__ = [
|
|||||||
'quit',
|
'quit',
|
||||||
'QuitType',
|
'QuitType',
|
||||||
'request_permission',
|
'request_permission',
|
||||||
|
'root_ui_pause_updates',
|
||||||
|
'root_ui_resume_updates',
|
||||||
'rowwidget',
|
'rowwidget',
|
||||||
'safecolor',
|
'safecolor',
|
||||||
'screenmessage',
|
'screenmessage',
|
||||||
@ -228,6 +233,7 @@ __all__ = [
|
|||||||
'set_ui_input_device',
|
'set_ui_input_device',
|
||||||
'Sound',
|
'Sound',
|
||||||
'SpecialChar',
|
'SpecialChar',
|
||||||
|
'spinnerwidget',
|
||||||
'supports_max_fps',
|
'supports_max_fps',
|
||||||
'supports_vsync',
|
'supports_vsync',
|
||||||
'supports_unicode_display',
|
'supports_unicode_display',
|
||||||
|
|||||||
@ -100,17 +100,20 @@ class AccountViewerWindow(PopupWindow):
|
|||||||
)
|
)
|
||||||
bui.widget(edit=self._scrollwidget, autoselect=True)
|
bui.widget(edit=self._scrollwidget, autoselect=True)
|
||||||
|
|
||||||
|
# Note to self: Make sure to always update loading text and
|
||||||
|
# spinner visibility together.
|
||||||
self._loading_text = bui.textwidget(
|
self._loading_text = bui.textwidget(
|
||||||
parent=self._scrollwidget,
|
parent=self._scrollwidget,
|
||||||
scale=0.5,
|
scale=0.5,
|
||||||
text=bui.Lstr(
|
text='',
|
||||||
value='${A}...',
|
|
||||||
subs=[('${A}', bui.Lstr(resource='loadingText'))],
|
|
||||||
),
|
|
||||||
size=(self._width - 60, 100),
|
size=(self._width - 60, 100),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
)
|
)
|
||||||
|
self._loading_spinner = bui.spinnerwidget(
|
||||||
|
parent=self.root_widget,
|
||||||
|
position=(self._width * 0.5, self._height * 0.5),
|
||||||
|
)
|
||||||
|
|
||||||
# In cases where the user most likely has a browser/email, lets
|
# In cases where the user most likely has a browser/email, lets
|
||||||
# offer a 'report this user' button.
|
# offer a 'report this user' button.
|
||||||
@ -227,9 +230,11 @@ class AccountViewerWindow(PopupWindow):
|
|||||||
edit=self._loading_text,
|
edit=self._loading_text,
|
||||||
text=bui.Lstr(resource='internal.unavailableNoConnectionText'),
|
text=bui.Lstr(resource='internal.unavailableNoConnectionText'),
|
||||||
)
|
)
|
||||||
|
bui.spinnerwidget(edit=self._loading_spinner, visible=False)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self._loading_text.delete()
|
self._loading_text.delete()
|
||||||
|
self._loading_spinner.delete()
|
||||||
trophystr = ''
|
trophystr = ''
|
||||||
try:
|
try:
|
||||||
trophystr = data['trophies']
|
trophystr = data['trophies']
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -57,7 +57,7 @@ class WaitForConnectivityWindow(bui.Window):
|
|||||||
)
|
)
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(self._width * 0.5, self._height * 0.65),
|
position=(self._width * 0.5, self._height * 0.7),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
scale=1.2,
|
scale=1.2,
|
||||||
h_align='center',
|
h_align='center',
|
||||||
@ -65,9 +65,15 @@ class WaitForConnectivityWindow(bui.Window):
|
|||||||
text=bui.Lstr(resource='internal.connectingToPartyText'),
|
text=bui.Lstr(resource='internal.connectingToPartyText'),
|
||||||
maxwidth=self._width * 0.9,
|
maxwidth=self._width * 0.9,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._spinner = bui.spinnerwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height * 0.54),
|
||||||
|
)
|
||||||
|
|
||||||
self._info_text = bui.textwidget(
|
self._info_text = bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(self._width * 0.5, self._height * 0.45),
|
position=(self._width * 0.5, self._height * 0.4),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
color=(0.6, 0.5, 0.6),
|
color=(0.6, 0.5, 0.6),
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
@ -115,6 +121,15 @@ class WaitForConnectivityWindow(bui.Window):
|
|||||||
def _connected(self) -> None:
|
def _connected(self) -> None:
|
||||||
if not self._root_widget or self._root_widget.transitioning_out:
|
if not self._root_widget or self._root_widget.transitioning_out:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Show 'connected.' and kill the spinner for the brief moment
|
||||||
|
# we're visible on our way out.
|
||||||
|
bui.textwidget(
|
||||||
|
edit=self._info_text, text=bui.Lstr(resource='remote_app.connected')
|
||||||
|
)
|
||||||
|
if self._spinner:
|
||||||
|
self._spinner.delete()
|
||||||
|
|
||||||
bui.containerwidget(
|
bui.containerwidget(
|
||||||
edit=self._root_widget,
|
edit=self._root_widget,
|
||||||
transition=('out_scale'),
|
transition=('out_scale'),
|
||||||
|
|||||||
@ -231,11 +231,11 @@ class CoopBrowserWindow(bui.MainWindow):
|
|||||||
# Don't want initial construction affecting our last-selected.
|
# Don't want initial construction affecting our last-selected.
|
||||||
self._do_selection_callbacks = False
|
self._do_selection_callbacks = False
|
||||||
v = self._height - 95
|
v = self._height - 95
|
||||||
txt = bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(
|
position=(
|
||||||
self._width * 0.5,
|
self._width * 0.5,
|
||||||
v + 40 - (0 if uiscale is bui.UIScale.SMALL else 0),
|
v + 40 - (25 if uiscale is bui.UIScale.SMALL else 0),
|
||||||
),
|
),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
text=bui.Lstr(
|
text=bui.Lstr(
|
||||||
@ -244,14 +244,11 @@ class CoopBrowserWindow(bui.MainWindow):
|
|||||||
),
|
),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
color=app.ui_v1.title_color,
|
color=app.ui_v1.title_color,
|
||||||
scale=1.5,
|
scale=0.85 if uiscale is bui.UIScale.SMALL else 1.5,
|
||||||
maxwidth=500,
|
maxwidth=280 if uiscale is bui.UIScale.SMALL else 500,
|
||||||
v_align='center',
|
v_align='center',
|
||||||
)
|
)
|
||||||
|
|
||||||
if uiscale is bui.UIScale.SMALL:
|
|
||||||
bui.textwidget(edit=txt, text='')
|
|
||||||
|
|
||||||
self._selected_row = cfg.get('Selected Coop Row', None)
|
self._selected_row = cfg.get('Selected Coop Row', None)
|
||||||
|
|
||||||
self._scroll_width = self._width - (130 + 2 * x_inset)
|
self._scroll_width = self._width - (130 + 2 * x_inset)
|
||||||
|
|||||||
@ -12,6 +12,11 @@ import bauiv1 as bui
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
# As of 1.7.37, no longer charging entry fees for tourneys (tourneys now
|
||||||
|
# reward chests and the game now makes its money from tokens/ads used to
|
||||||
|
# speed up chest openings).
|
||||||
|
USE_ENTRY_FEES = False
|
||||||
|
|
||||||
|
|
||||||
class TournamentButton:
|
class TournamentButton:
|
||||||
"""Button showing a tournament in coop window."""
|
"""Button showing a tournament in coop window."""
|
||||||
@ -25,6 +30,7 @@ class TournamentButton:
|
|||||||
on_pressed: Callable[[TournamentButton], None],
|
on_pressed: Callable[[TournamentButton], None],
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=too-many-positional-arguments
|
# pylint: disable=too-many-positional-arguments
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
self._r = 'coopSelectWindow'
|
self._r = 'coopSelectWindow'
|
||||||
sclx = 300
|
sclx = 300
|
||||||
scly = 195.0
|
scly = 195.0
|
||||||
@ -37,6 +43,7 @@ class TournamentButton:
|
|||||||
self.has_time_remaining: bool = False
|
self.has_time_remaining: bool = False
|
||||||
self.leader: Any = None
|
self.leader: Any = None
|
||||||
self.required_league: str | None = None
|
self.required_league: str | None = None
|
||||||
|
self._base_x_offs = 0 if USE_ENTRY_FEES else -45.0
|
||||||
self.button = btn = bui.buttonwidget(
|
self.button = btn = bui.buttonwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
position=(x + 23, y + 4),
|
position=(x + 23, y + 4),
|
||||||
@ -96,69 +103,72 @@ class TournamentButton:
|
|||||||
header_color = (0.43, 0.4, 0.5, 1)
|
header_color = (0.43, 0.4, 0.5, 1)
|
||||||
value_color = (0.6, 0.6, 0.6, 1)
|
value_color = (0.6, 0.6, 0.6, 1)
|
||||||
|
|
||||||
x_offs = 0
|
x_offs = self._base_x_offs
|
||||||
bui.textwidget(
|
|
||||||
parent=parent,
|
|
||||||
draw_controller=btn,
|
|
||||||
position=(x + 360, y + scly - 20),
|
|
||||||
size=(0, 0),
|
|
||||||
h_align='center',
|
|
||||||
text=bui.Lstr(resource=f'{self._r}.entryFeeText'),
|
|
||||||
v_align='center',
|
|
||||||
maxwidth=100,
|
|
||||||
scale=0.9,
|
|
||||||
color=header_color,
|
|
||||||
flatness=1.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.entry_fee_text_top = bui.textwidget(
|
# No longer using entry fees.
|
||||||
parent=parent,
|
if USE_ENTRY_FEES:
|
||||||
draw_controller=btn,
|
bui.textwidget(
|
||||||
position=(x + 360, y + scly - 60),
|
parent=parent,
|
||||||
size=(0, 0),
|
draw_controller=btn,
|
||||||
h_align='center',
|
position=(x + 360, y + scly - 20),
|
||||||
text='-',
|
size=(0, 0),
|
||||||
v_align='center',
|
h_align='center',
|
||||||
maxwidth=60,
|
text=bui.Lstr(resource=f'{self._r}.entryFeeText'),
|
||||||
scale=1.3,
|
v_align='center',
|
||||||
color=value_color,
|
maxwidth=100,
|
||||||
flatness=1.0,
|
scale=0.9,
|
||||||
)
|
color=header_color,
|
||||||
self.entry_fee_text_or = bui.textwidget(
|
flatness=1.0,
|
||||||
parent=parent,
|
)
|
||||||
draw_controller=btn,
|
|
||||||
position=(x + 360, y + scly - 90),
|
|
||||||
size=(0, 0),
|
|
||||||
h_align='center',
|
|
||||||
text='',
|
|
||||||
v_align='center',
|
|
||||||
maxwidth=60,
|
|
||||||
scale=0.5,
|
|
||||||
color=value_color,
|
|
||||||
flatness=1.0,
|
|
||||||
)
|
|
||||||
self.entry_fee_text_remaining = bui.textwidget(
|
|
||||||
parent=parent,
|
|
||||||
draw_controller=btn,
|
|
||||||
position=(x + 360, y + scly - 90),
|
|
||||||
size=(0, 0),
|
|
||||||
h_align='center',
|
|
||||||
text='',
|
|
||||||
v_align='center',
|
|
||||||
maxwidth=60,
|
|
||||||
scale=0.5,
|
|
||||||
color=value_color,
|
|
||||||
flatness=1.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.entry_fee_ad_image = bui.imagewidget(
|
self.entry_fee_text_top = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
size=(40, 40),
|
draw_controller=btn,
|
||||||
draw_controller=btn,
|
position=(x + 360, y + scly - 60),
|
||||||
position=(x + 360 - 20, y + scly - 140),
|
size=(0, 0),
|
||||||
opacity=0.0,
|
h_align='center',
|
||||||
texture=bui.gettexture('tv'),
|
text='-',
|
||||||
)
|
v_align='center',
|
||||||
|
maxwidth=60,
|
||||||
|
scale=1.3,
|
||||||
|
color=value_color,
|
||||||
|
flatness=1.0,
|
||||||
|
)
|
||||||
|
self.entry_fee_text_or = bui.textwidget(
|
||||||
|
parent=parent,
|
||||||
|
draw_controller=btn,
|
||||||
|
position=(x + 360, y + scly - 90),
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='center',
|
||||||
|
text='',
|
||||||
|
v_align='center',
|
||||||
|
maxwidth=60,
|
||||||
|
scale=0.5,
|
||||||
|
color=value_color,
|
||||||
|
flatness=1.0,
|
||||||
|
)
|
||||||
|
self.entry_fee_text_remaining = bui.textwidget(
|
||||||
|
parent=parent,
|
||||||
|
draw_controller=btn,
|
||||||
|
position=(x + 360, y + scly - 90),
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='center',
|
||||||
|
text='',
|
||||||
|
v_align='center',
|
||||||
|
maxwidth=60,
|
||||||
|
scale=0.5,
|
||||||
|
color=value_color,
|
||||||
|
flatness=1.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.entry_fee_ad_image = bui.imagewidget(
|
||||||
|
parent=parent,
|
||||||
|
size=(40, 40),
|
||||||
|
draw_controller=btn,
|
||||||
|
position=(x + 360 - 20, y + scly - 140),
|
||||||
|
opacity=0.0,
|
||||||
|
texture=bui.gettexture('tv'),
|
||||||
|
)
|
||||||
|
|
||||||
x_offs += 50
|
x_offs += 50
|
||||||
|
|
||||||
@ -180,8 +190,8 @@ class TournamentButton:
|
|||||||
self.button_y = y
|
self.button_y = y
|
||||||
self.button_scale_y = scly
|
self.button_scale_y = scly
|
||||||
|
|
||||||
xo2 = 0
|
# Offset for prize range/values.
|
||||||
prize_value_scale = 1.5
|
xo2 = 0.0
|
||||||
|
|
||||||
self.prize_range_1_text = bui.textwidget(
|
self.prize_range_1_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
@ -191,7 +201,7 @@ class TournamentButton:
|
|||||||
h_align='right',
|
h_align='right',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=50,
|
maxwidth=50,
|
||||||
text='-',
|
text='',
|
||||||
scale=0.8,
|
scale=0.8,
|
||||||
color=header_color,
|
color=header_color,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
@ -202,13 +212,21 @@ class TournamentButton:
|
|||||||
position=(x + 380 + xo2 + x_offs, y + scly - 93),
|
position=(x + 380 + xo2 + x_offs, y + scly - 93),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='left',
|
h_align='left',
|
||||||
text='-',
|
text='',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=100,
|
maxwidth=100,
|
||||||
scale=prize_value_scale,
|
|
||||||
color=value_color,
|
color=value_color,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
)
|
)
|
||||||
|
self._chestsz = 50
|
||||||
|
self.prize_chest_1_image = bui.imagewidget(
|
||||||
|
parent=parent,
|
||||||
|
draw_controller=btn,
|
||||||
|
texture=bui.gettexture('white'),
|
||||||
|
position=(x + 380 + xo2 + x_offs, y + scly - 93),
|
||||||
|
size=(self._chestsz, self._chestsz),
|
||||||
|
opacity=0.0,
|
||||||
|
)
|
||||||
|
|
||||||
self.prize_range_2_text = bui.textwidget(
|
self.prize_range_2_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
@ -216,6 +234,7 @@ class TournamentButton:
|
|||||||
position=(x + 355 + xo2 + x_offs, y + scly - 93),
|
position=(x + 355 + xo2 + x_offs, y + scly - 93),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='right',
|
h_align='right',
|
||||||
|
text='',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=50,
|
maxwidth=50,
|
||||||
scale=0.8,
|
scale=0.8,
|
||||||
@ -231,10 +250,17 @@ class TournamentButton:
|
|||||||
text='',
|
text='',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=100,
|
maxwidth=100,
|
||||||
scale=prize_value_scale,
|
|
||||||
color=value_color,
|
color=value_color,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
)
|
)
|
||||||
|
self.prize_chest_2_image = bui.imagewidget(
|
||||||
|
parent=parent,
|
||||||
|
draw_controller=btn,
|
||||||
|
texture=bui.gettexture('white'),
|
||||||
|
position=(x + 380 + xo2 + x_offs, y + scly - 93),
|
||||||
|
size=(self._chestsz, self._chestsz),
|
||||||
|
opacity=0.0,
|
||||||
|
)
|
||||||
|
|
||||||
self.prize_range_3_text = bui.textwidget(
|
self.prize_range_3_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
@ -242,6 +268,7 @@ class TournamentButton:
|
|||||||
position=(x + 355 + xo2 + x_offs, y + scly - 93),
|
position=(x + 355 + xo2 + x_offs, y + scly - 93),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='right',
|
h_align='right',
|
||||||
|
text='',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=50,
|
maxwidth=50,
|
||||||
scale=0.8,
|
scale=0.8,
|
||||||
@ -257,15 +284,22 @@ class TournamentButton:
|
|||||||
text='',
|
text='',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
maxwidth=100,
|
maxwidth=100,
|
||||||
scale=prize_value_scale,
|
|
||||||
color=value_color,
|
color=value_color,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
)
|
)
|
||||||
|
self.prize_chest_3_image = bui.imagewidget(
|
||||||
|
parent=parent,
|
||||||
|
draw_controller=btn,
|
||||||
|
texture=bui.gettexture('white'),
|
||||||
|
position=(x + 380 + xo2 + x_offs, y + scly - 93),
|
||||||
|
size=(self._chestsz, self._chestsz),
|
||||||
|
opacity=0.0,
|
||||||
|
)
|
||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(x + 620 + x_offs, y + scly - 20),
|
position=(x + 625 + x_offs, y + scly - 20),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
text=bui.Lstr(resource=f'{self._r}.currentBestText'),
|
text=bui.Lstr(resource=f'{self._r}.currentBestText'),
|
||||||
@ -279,7 +313,7 @@ class TournamentButton:
|
|||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(
|
position=(
|
||||||
x + 620 + x_offs - (170 / 1.4) * 0.5,
|
x + 625 + x_offs - (170 / 1.4) * 0.5,
|
||||||
y + scly - 60 - 40 * 0.5,
|
y + scly - 60 - 40 * 0.5,
|
||||||
),
|
),
|
||||||
selectable=True,
|
selectable=True,
|
||||||
@ -299,7 +333,7 @@ class TournamentButton:
|
|||||||
self.current_leader_score_text = bui.textwidget(
|
self.current_leader_score_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(x + 620 + x_offs, y + scly - 113 + 10),
|
position=(x + 625 + x_offs, y + scly - 113 + 10),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
text='-',
|
text='-',
|
||||||
@ -312,7 +346,7 @@ class TournamentButton:
|
|||||||
|
|
||||||
self.more_scores_button = bui.buttonwidget(
|
self.more_scores_button = bui.buttonwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
position=(x + 620 + x_offs - 60, y + scly - 50 - 125),
|
position=(x + 625 + x_offs - 60, y + scly - 50 - 125),
|
||||||
color=(0.5, 0.5, 0.6),
|
color=(0.5, 0.5, 0.6),
|
||||||
textcolor=(0.7, 0.7, 0.8),
|
textcolor=(0.7, 0.7, 0.8),
|
||||||
label='-',
|
label='-',
|
||||||
@ -330,7 +364,7 @@ class TournamentButton:
|
|||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(x + 820 + x_offs, y + scly - 20),
|
position=(x + 840 + x_offs, y + scly - 20),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
text=bui.Lstr(resource=f'{self._r}.timeRemainingText'),
|
text=bui.Lstr(resource=f'{self._r}.timeRemainingText'),
|
||||||
@ -343,7 +377,7 @@ class TournamentButton:
|
|||||||
self.time_remaining_value_text = bui.textwidget(
|
self.time_remaining_value_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(x + 820 + x_offs, y + scly - 68),
|
position=(x + 840 + x_offs, y + scly - 68),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
text='-',
|
text='-',
|
||||||
@ -356,7 +390,7 @@ class TournamentButton:
|
|||||||
self.time_remaining_out_of_text = bui.textwidget(
|
self.time_remaining_out_of_text = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
draw_controller=btn,
|
draw_controller=btn,
|
||||||
position=(x + 820 + x_offs, y + scly - 110),
|
position=(x + 840 + x_offs, y + scly - 110),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
text='-',
|
text='-',
|
||||||
@ -415,26 +449,26 @@ class TournamentButton:
|
|||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
|
|
||||||
assert bui.app.classic is not None
|
classic = bui.app.classic
|
||||||
|
assert classic is not None
|
||||||
|
|
||||||
prize_y_offs = (
|
prize_y_offs = (
|
||||||
34
|
34
|
||||||
if 'prizeRange3' in entry
|
if 'prizeRange3' in entry
|
||||||
else 20 if 'prizeRange2' in entry else 12
|
else 20 if 'prizeRange2' in entry else 12
|
||||||
)
|
)
|
||||||
x_offs = 90
|
x_offs = self._base_x_offs + 90
|
||||||
|
|
||||||
# pylint: disable=useless-suppression
|
# Special offset for prize ranges/vals.
|
||||||
# pylint: disable=unbalanced-tuple-unpacking
|
x_offs2 = x_offs - 20.0
|
||||||
(
|
|
||||||
pr1,
|
# Special offset for prize chests.
|
||||||
pv1,
|
x_offs2c = x_offs2 + 50
|
||||||
pr2,
|
|
||||||
pv2,
|
# Fetch prize range and trophy strings.
|
||||||
pr3,
|
(pr1, pv1, pr2, pv2, pr3, pv3) = classic.get_tournament_prize_strings(
|
||||||
pv3,
|
entry, include_tickets=False
|
||||||
) = bui.app.classic.get_tournament_prize_strings(entry)
|
)
|
||||||
# pylint: enable=unbalanced-tuple-unpacking
|
|
||||||
# pylint: enable=useless-suppression
|
|
||||||
|
|
||||||
enabled = 'requiredLeague' not in entry
|
enabled = 'requiredLeague' not in entry
|
||||||
bui.buttonwidget(
|
bui.buttonwidget(
|
||||||
@ -446,74 +480,91 @@ class TournamentButton:
|
|||||||
edit=self.prize_range_1_text,
|
edit=self.prize_range_1_text,
|
||||||
text='-' if pr1 == '' else pr1,
|
text='-' if pr1 == '' else pr1,
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 365 + x_offs,
|
self.button_x + 365 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# We want to draw values containing tickets a bit smaller
|
|
||||||
# (scratch that; we now draw medals a bit bigger).
|
|
||||||
ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING)
|
|
||||||
prize_value_scale_large = 1.0
|
|
||||||
prize_value_scale_small = 1.0
|
|
||||||
|
|
||||||
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
|
|
||||||
if ticket_char not in pv1
|
|
||||||
else prize_value_scale_small
|
|
||||||
),
|
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 380 + x_offs,
|
self.button_x + 380 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
bui.imagewidget(
|
||||||
|
edit=self.prize_chest_1_image,
|
||||||
|
position=(
|
||||||
|
self.button_x + 380 + x_offs2c,
|
||||||
|
self.button_y
|
||||||
|
+ self.button_scale_y
|
||||||
|
- 93
|
||||||
|
+ prize_y_offs
|
||||||
|
- 0.5 * self._chestsz,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
classic.set_tournament_prize_image(entry, 0, self.prize_chest_1_image)
|
||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self.prize_range_2_text,
|
edit=self.prize_range_2_text,
|
||||||
text=pr2,
|
text=pr2,
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 365 + x_offs,
|
self.button_x + 365 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
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
|
|
||||||
if ticket_char not in pv2
|
|
||||||
else prize_value_scale_small
|
|
||||||
),
|
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 380 + x_offs,
|
self.button_x + 380 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
bui.imagewidget(
|
||||||
|
edit=self.prize_chest_2_image,
|
||||||
|
position=(
|
||||||
|
self.button_x + 380 + x_offs2c,
|
||||||
|
self.button_y
|
||||||
|
+ self.button_scale_y
|
||||||
|
- 93
|
||||||
|
- 45
|
||||||
|
+ prize_y_offs
|
||||||
|
- 0.5 * self._chestsz,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
classic.set_tournament_prize_image(entry, 1, self.prize_chest_2_image)
|
||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self.prize_range_3_text,
|
edit=self.prize_range_3_text,
|
||||||
text=pr3,
|
text=pr3,
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 365 + x_offs,
|
self.button_x + 365 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
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
|
|
||||||
if ticket_char not in pv3
|
|
||||||
else prize_value_scale_small
|
|
||||||
),
|
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 380 + x_offs,
|
self.button_x + 380 + x_offs2,
|
||||||
self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs,
|
self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
bui.imagewidget(
|
||||||
|
edit=self.prize_chest_3_image,
|
||||||
|
position=(
|
||||||
|
self.button_x + 380 + x_offs2c,
|
||||||
|
self.button_y
|
||||||
|
+ self.button_scale_y
|
||||||
|
- 93
|
||||||
|
- 90
|
||||||
|
+ prize_y_offs
|
||||||
|
- 0.5 * self._chestsz,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
classic.set_tournament_prize_image(entry, 2, self.prize_chest_3_image)
|
||||||
|
|
||||||
leader_name = '-'
|
leader_name = '-'
|
||||||
leader_score: str | bui.Lstr = '-'
|
leader_score: str | bui.Lstr = '-'
|
||||||
@ -599,6 +650,7 @@ class TournamentButton:
|
|||||||
)
|
)
|
||||||
|
|
||||||
fee = entry['fee']
|
fee = entry['fee']
|
||||||
|
assert isinstance(fee, int | None)
|
||||||
|
|
||||||
if fee is None:
|
if fee is None:
|
||||||
fee_var = None
|
fee_var = None
|
||||||
@ -610,18 +662,23 @@ class TournamentButton:
|
|||||||
fee_var = 'price.tournament_entry_2'
|
fee_var = 'price.tournament_entry_2'
|
||||||
elif fee == 1:
|
elif fee == 1:
|
||||||
fee_var = 'price.tournament_entry_1'
|
fee_var = 'price.tournament_entry_1'
|
||||||
|
elif fee == -1:
|
||||||
|
fee_var = None
|
||||||
else:
|
else:
|
||||||
if fee != 0:
|
if fee != 0:
|
||||||
print('Unknown fee value:', fee)
|
print('Unknown fee value:', fee)
|
||||||
fee_var = 'price.tournament_entry_0'
|
fee_var = 'price.tournament_entry_0'
|
||||||
|
|
||||||
self.allow_ads = allow_ads = entry['allowAds']
|
self.allow_ads = allow_ads = (
|
||||||
|
entry['allowAds'] if USE_ENTRY_FEES else False
|
||||||
|
)
|
||||||
|
|
||||||
final_fee: int | None = (
|
final_fee = (
|
||||||
None
|
None
|
||||||
if fee_var is None
|
if fee_var is None
|
||||||
else plus.get_v1_account_misc_read_val(fee_var, '?')
|
else plus.get_v1_account_misc_read_val(fee_var, '?')
|
||||||
)
|
)
|
||||||
|
assert isinstance(final_fee, int | None)
|
||||||
|
|
||||||
final_fee_str: str | bui.Lstr
|
final_fee_str: str | bui.Lstr
|
||||||
if fee_var is None:
|
if fee_var is None:
|
||||||
@ -638,72 +695,77 @@ class TournamentButton:
|
|||||||
ad_tries_remaining = bui.app.classic.accounts.tournament_info[
|
ad_tries_remaining = bui.app.classic.accounts.tournament_info[
|
||||||
self.tournament_id
|
self.tournament_id
|
||||||
]['adTriesRemaining']
|
]['adTriesRemaining']
|
||||||
|
assert isinstance(ad_tries_remaining, int | None)
|
||||||
free_tries_remaining = bui.app.classic.accounts.tournament_info[
|
free_tries_remaining = bui.app.classic.accounts.tournament_info[
|
||||||
self.tournament_id
|
self.tournament_id
|
||||||
]['freeTriesRemaining']
|
]['freeTriesRemaining']
|
||||||
|
assert isinstance(free_tries_remaining, int | None)
|
||||||
|
|
||||||
# Now, if this fee allows ads and we support video ads, show
|
# Now, if this fee allows ads and we support video ads, show
|
||||||
# the 'or ad' version.
|
# the 'or ad' version.
|
||||||
if allow_ads and plus.has_video_ads():
|
if USE_ENTRY_FEES:
|
||||||
ads_enabled = plus.have_incentivized_ad()
|
if allow_ads and plus.has_video_ads():
|
||||||
bui.imagewidget(
|
ads_enabled = plus.have_incentivized_ad()
|
||||||
edit=self.entry_fee_ad_image,
|
bui.imagewidget(
|
||||||
opacity=1.0 if ads_enabled else 0.25,
|
edit=self.entry_fee_ad_image,
|
||||||
)
|
opacity=1.0 if ads_enabled else 0.25,
|
||||||
or_text = (
|
)
|
||||||
bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')])
|
or_text = (
|
||||||
.evaluate()
|
bui.Lstr(
|
||||||
.strip()
|
resource='orText', subs=[('${A}', ''), ('${B}', '')]
|
||||||
)
|
)
|
||||||
bui.textwidget(edit=self.entry_fee_text_or, text=or_text)
|
.evaluate()
|
||||||
bui.textwidget(
|
.strip()
|
||||||
edit=self.entry_fee_text_top,
|
)
|
||||||
position=(
|
bui.textwidget(edit=self.entry_fee_text_or, text=or_text)
|
||||||
self.button_x + 360,
|
bui.textwidget(
|
||||||
self.button_y + self.button_scale_y - 60,
|
edit=self.entry_fee_text_top,
|
||||||
),
|
position=(
|
||||||
scale=1.3,
|
self.button_x + 360,
|
||||||
text=final_fee_str,
|
self.button_y + self.button_scale_y - 60,
|
||||||
)
|
),
|
||||||
|
scale=1.3,
|
||||||
|
text=final_fee_str,
|
||||||
|
)
|
||||||
|
|
||||||
# Possibly show number of ad-plays remaining.
|
# Possibly show number of ad-plays remaining.
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self.entry_fee_text_remaining,
|
edit=self.entry_fee_text_remaining,
|
||||||
position=(
|
position=(
|
||||||
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]
|
if ad_tries_remaining in [None, 0]
|
||||||
else ('' + str(ad_tries_remaining))
|
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:
|
||||||
bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0)
|
bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0)
|
||||||
bui.textwidget(edit=self.entry_fee_text_or, text='')
|
bui.textwidget(edit=self.entry_fee_text_or, text='')
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self.entry_fee_text_top,
|
edit=self.entry_fee_text_top,
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 360,
|
self.button_x + 360,
|
||||||
self.button_y + self.button_scale_y - 80,
|
self.button_y + self.button_scale_y - 80,
|
||||||
),
|
),
|
||||||
scale=1.3,
|
scale=1.3,
|
||||||
text=final_fee_str,
|
text=final_fee_str,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Possibly show number of free-plays remaining.
|
# Possibly show number of free-plays remaining.
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self.entry_fee_text_remaining,
|
edit=self.entry_fee_text_remaining,
|
||||||
position=(
|
position=(
|
||||||
self.button_x + 360,
|
self.button_x + 360,
|
||||||
self.button_y + self.button_scale_y - 100,
|
self.button_y + self.button_scale_y - 100,
|
||||||
),
|
),
|
||||||
text=(
|
text=(
|
||||||
''
|
''
|
||||||
if (free_tries_remaining in [None, 0] or final_fee != 0)
|
if (free_tries_remaining in [None, 0] or final_fee != 0)
|
||||||
else ('' + str(free_tries_remaining))
|
else ('' + str(free_tries_remaining))
|
||||||
),
|
),
|
||||||
color=(0.6, 0.6, 0.6, 1),
|
color=(0.6, 0.6, 0.6, 1),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ class PrivateGatherTab(GatherTab):
|
|||||||
self._state: State = State()
|
self._state: State = State()
|
||||||
self._last_datacode_refresh_time: float | None = None
|
self._last_datacode_refresh_time: float | None = None
|
||||||
self._hostingstate = PrivateHostingState()
|
self._hostingstate = PrivateHostingState()
|
||||||
self._v2state: bacommon.cloud.BSPrivatePartyResponse | None = None
|
self._v2state: bacommon.bs.PrivatePartyResponse | None = None
|
||||||
self._join_sub_tab_text: bui.Widget | None = None
|
self._join_sub_tab_text: bui.Widget | None = None
|
||||||
self._host_sub_tab_text: bui.Widget | None = None
|
self._host_sub_tab_text: bui.Widget | None = None
|
||||||
self._update_timer: bui.AppTimer | None = None
|
self._update_timer: bui.AppTimer | None = None
|
||||||
@ -339,7 +339,7 @@ class PrivateGatherTab(GatherTab):
|
|||||||
if plus.accounts.primary is not None:
|
if plus.accounts.primary is not None:
|
||||||
with plus.accounts.primary:
|
with plus.accounts.primary:
|
||||||
plus.cloud.send_message_cb(
|
plus.cloud.send_message_cb(
|
||||||
bacommon.cloud.BSPrivatePartyMessage(
|
bacommon.bs.PrivatePartyMessage(
|
||||||
need_datacode=(
|
need_datacode=(
|
||||||
self._last_datacode_refresh_time is None
|
self._last_datacode_refresh_time is None
|
||||||
or time.monotonic()
|
or time.monotonic()
|
||||||
@ -355,7 +355,7 @@ class PrivateGatherTab(GatherTab):
|
|||||||
self._last_v2_state_query_time = now
|
self._last_v2_state_query_time = now
|
||||||
|
|
||||||
def _on_private_party_query_response(
|
def _on_private_party_query_response(
|
||||||
self, response: bacommon.cloud.BSPrivatePartyResponse | Exception
|
self, response: bacommon.bs.PrivatePartyResponse | Exception
|
||||||
) -> None:
|
) -> None:
|
||||||
if isinstance(response, Exception):
|
if isinstance(response, Exception):
|
||||||
self._debug_server_comm('got pp v2 state response (err)')
|
self._debug_server_comm('got pp v2 state response (err)')
|
||||||
|
|||||||
@ -367,6 +367,7 @@ class PublicGatherTab(GatherTab):
|
|||||||
self._last_server_list_query_time: float | None = None
|
self._last_server_list_query_time: float | None = None
|
||||||
self._join_list_column: bui.Widget | None = None
|
self._join_list_column: bui.Widget | None = None
|
||||||
self._join_status_text: bui.Widget | None = None
|
self._join_status_text: bui.Widget | None = None
|
||||||
|
self._join_status_spinner: 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
|
||||||
@ -665,6 +666,9 @@ class PublicGatherTab(GatherTab):
|
|||||||
size=(400, 400),
|
size=(400, 400),
|
||||||
claims_left_right=True,
|
claims_left_right=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Create join status text and join spinner. Always make sure to
|
||||||
|
# update both of these together.
|
||||||
self._join_status_text = bui.textwidget(
|
self._join_status_text = bui.textwidget(
|
||||||
parent=self._container,
|
parent=self._container,
|
||||||
text='',
|
text='',
|
||||||
@ -678,6 +682,10 @@ class PublicGatherTab(GatherTab):
|
|||||||
color=(0.6, 0.6, 0.6),
|
color=(0.6, 0.6, 0.6),
|
||||||
position=(c_width * 0.5, c_height * 0.5),
|
position=(c_width * 0.5, c_height * 0.5),
|
||||||
)
|
)
|
||||||
|
self._join_status_spinner = bui.spinnerwidget(
|
||||||
|
parent=self._container, position=(c_width * 0.5, c_height * 0.5)
|
||||||
|
)
|
||||||
|
|
||||||
self._no_servers_found_text = bui.textwidget(
|
self._no_servers_found_text = bui.textwidget(
|
||||||
parent=self._container,
|
parent=self._container,
|
||||||
text='',
|
text='',
|
||||||
@ -944,37 +952,51 @@ class PublicGatherTab(GatherTab):
|
|||||||
name = cast(str, bui.textwidget(query=self._host_name_text))
|
name = cast(str, bui.textwidget(query=self._host_name_text))
|
||||||
bs.set_public_party_name(name)
|
bs.set_public_party_name(name)
|
||||||
|
|
||||||
# Update status text.
|
# Update status text and loading spinner.
|
||||||
status_text = self._join_status_text
|
if self._join_status_text:
|
||||||
if status_text:
|
assert self._join_status_spinner
|
||||||
if not signed_in:
|
if not signed_in:
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=status_text, text=bui.Lstr(resource='notSignedInText')
|
edit=self._join_status_text,
|
||||||
|
text=bui.Lstr(resource='notSignedInText'),
|
||||||
)
|
)
|
||||||
|
bui.spinnerwidget(edit=self._join_status_spinner, visible=False)
|
||||||
else:
|
else:
|
||||||
# If we have a valid list, show no status; just the list.
|
# If we have a valid list, show no status; just the list.
|
||||||
# Otherwise show either 'loading...' or 'error' depending
|
# Otherwise show either 'loading...' or 'error' depending
|
||||||
# on whether this is our first go-round.
|
# on whether this is our first go-round.
|
||||||
if self._have_valid_server_list:
|
if self._have_valid_server_list:
|
||||||
bui.textwidget(edit=status_text, text='')
|
bui.textwidget(edit=self._join_status_text, text='')
|
||||||
|
bui.spinnerwidget(
|
||||||
|
edit=self._join_status_spinner, visible=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if self._have_server_list_response:
|
if self._have_server_list_response:
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=status_text,
|
edit=self._join_status_text,
|
||||||
text=bui.Lstr(resource='errorText'),
|
text=bui.Lstr(resource='errorText'),
|
||||||
)
|
)
|
||||||
|
bui.spinnerwidget(
|
||||||
|
edit=self._join_status_spinner, visible=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
bui.textwidget(
|
# Show our loading spinner.
|
||||||
edit=status_text,
|
bui.textwidget(edit=self._join_status_text, text='')
|
||||||
text=bui.Lstr(
|
# bui.textwidget(
|
||||||
value='${A}...',
|
# edit=self._join_status_text,
|
||||||
subs=[
|
# text=bui.Lstr(
|
||||||
(
|
# value='${A}...',
|
||||||
'${A}',
|
# subs=[
|
||||||
bui.Lstr(resource='store.loadingText'),
|
# (
|
||||||
)
|
# '${A}',
|
||||||
],
|
#
|
||||||
),
|
# bui.Lstr(resource='store.loadingText'),
|
||||||
|
# )
|
||||||
|
# ],
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
|
bui.spinnerwidget(
|
||||||
|
edit=self._join_status_spinner, visible=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self._update_party_rows()
|
self._update_party_rows()
|
||||||
@ -1005,16 +1027,11 @@ class PublicGatherTab(GatherTab):
|
|||||||
self._ui_rows = self._ui_rows[:-clipcount]
|
self._ui_rows = self._ui_rows[:-clipcount]
|
||||||
|
|
||||||
# If we have no parties to show, we're done.
|
# If we have no parties to show, we're done.
|
||||||
if not self._parties_displayed:
|
if self._have_valid_server_list and not self._parties_displayed:
|
||||||
text = self._join_status_text
|
bui.textwidget(
|
||||||
if (
|
edit=self._no_servers_found_text,
|
||||||
plus.get_v1_account_state() == 'signed_in'
|
text=bui.Lstr(resource='noServersFoundText'),
|
||||||
and cast(str, bui.textwidget(query=text)) == ''
|
)
|
||||||
):
|
|
||||||
bui.textwidget(
|
|
||||||
edit=self._no_servers_found_text,
|
|
||||||
text=bui.Lstr(resource='noServersFoundText'),
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
sub_scroll_width = 830
|
sub_scroll_width = 830
|
||||||
|
|||||||
@ -863,7 +863,7 @@ def show_get_tokens_prompt() -> None:
|
|||||||
if bool(True):
|
if bool(True):
|
||||||
ConfirmWindow(
|
ConfirmWindow(
|
||||||
bui.Lstr(resource='tokens.notEnoughTokensText'),
|
bui.Lstr(resource='tokens.notEnoughTokensText'),
|
||||||
GetTokensWindow,
|
_show_get_tokens,
|
||||||
ok_text=bui.Lstr(resource='tokens.getTokensText'),
|
ok_text=bui.Lstr(resource='tokens.getTokensText'),
|
||||||
width=460,
|
width=460,
|
||||||
height=130,
|
height=130,
|
||||||
@ -875,3 +875,30 @@ def show_get_tokens_prompt() -> None:
|
|||||||
width=460,
|
width=460,
|
||||||
height=130,
|
height=130,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _show_get_tokens() -> None:
|
||||||
|
|
||||||
|
# NOTE TO USERS: The code below is not the proper way to do things;
|
||||||
|
# whenever possible one should use a MainWindow's
|
||||||
|
# main_window_replace() or main_window_back() methods. We just need
|
||||||
|
# to do things a bit more manually in this case.
|
||||||
|
|
||||||
|
prev_main_window = bui.app.ui_v1.get_main_window()
|
||||||
|
|
||||||
|
# Special-case: If it seems we're already in the account window, do
|
||||||
|
# nothing.
|
||||||
|
if isinstance(prev_main_window, GetTokensWindow):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Set our new main window.
|
||||||
|
bui.app.ui_v1.set_main_window(
|
||||||
|
GetTokensWindow(),
|
||||||
|
from_window=False,
|
||||||
|
is_auxiliary=True,
|
||||||
|
suppress_warning=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition out any previous main window.
|
||||||
|
if prev_main_window is not None:
|
||||||
|
prev_main_window.main_window_close()
|
||||||
|
|||||||
@ -6,30 +6,100 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import weakref
|
import weakref
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import override
|
from typing import override, assert_never
|
||||||
|
|
||||||
from efro.error import CommunicationError
|
from efro.error import CommunicationError
|
||||||
import bacommon.cloud
|
import bacommon.bs
|
||||||
import bauiv1 as bui
|
import bauiv1 as bui
|
||||||
|
|
||||||
# Messages with format versions higher than this will show up as
|
|
||||||
# 'app needs to be updated to view this'
|
class _Section:
|
||||||
SUPPORTED_INBOX_MESSAGE_FORMAT_VERSION = 1
|
def get_height(self) -> float:
|
||||||
|
"""Return section height."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def draw(self, subcontainer: bui.Widget, y: float) -> None:
|
||||||
|
"""Draw the section."""
|
||||||
|
|
||||||
|
|
||||||
|
class _TextSection(_Section):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
sub_width: float,
|
||||||
|
text: str,
|
||||||
|
*,
|
||||||
|
subs: list[str],
|
||||||
|
spacing_top: float = 0.0,
|
||||||
|
spacing_bottom: float = 0.0,
|
||||||
|
scale: float = 0.6,
|
||||||
|
color: tuple[float, float, float, float] = (1.0, 1.0, 1.0, 1.0),
|
||||||
|
) -> None:
|
||||||
|
self.sub_width = sub_width
|
||||||
|
self.spacing_top = spacing_top
|
||||||
|
self.spacing_bottom = spacing_bottom
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
self.textfin = bui.Lstr(translate=('serverResponses', text)).evaluate()
|
||||||
|
assert len(subs) % 2 == 0 # Should always be even.
|
||||||
|
for j in range(0, len(subs) - 1, 2):
|
||||||
|
self.textfin = self.textfin.replace(subs[j], subs[j + 1])
|
||||||
|
|
||||||
|
# Calc scale to fit width and then see what height we need at
|
||||||
|
# that scale.
|
||||||
|
t_width = max(
|
||||||
|
10.0,
|
||||||
|
bui.get_string_width(self.textfin, suppress_warning=True) * scale,
|
||||||
|
)
|
||||||
|
self.text_scale = scale * min(1.0, (sub_width * 0.9) / t_width)
|
||||||
|
|
||||||
|
self.text_height = (
|
||||||
|
0.0
|
||||||
|
if not self.textfin
|
||||||
|
else bui.get_string_height(self.textfin, suppress_warning=True)
|
||||||
|
) * self.text_scale
|
||||||
|
|
||||||
|
self.full_height = self.text_height + spacing_top + spacing_bottom
|
||||||
|
|
||||||
|
@override
|
||||||
|
def get_height(self) -> float:
|
||||||
|
return self.full_height
|
||||||
|
|
||||||
|
@override
|
||||||
|
def draw(self, subcontainer: bui.Widget, y: float) -> None:
|
||||||
|
bui.textwidget(
|
||||||
|
parent=subcontainer,
|
||||||
|
position=(
|
||||||
|
self.sub_width * 0.5,
|
||||||
|
y - self.spacing_top - self.text_height * 0.5,
|
||||||
|
# y - self.height * 0.5 - 23.0,
|
||||||
|
),
|
||||||
|
color=self.color,
|
||||||
|
scale=self.text_scale,
|
||||||
|
flatness=1.0,
|
||||||
|
shadow=0.0,
|
||||||
|
text=self.textfin,
|
||||||
|
size=(0, 0),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class _MessageEntry:
|
class _EntryDisplay:
|
||||||
type: bacommon.cloud.BSInboxEntryType
|
interaction_style: bacommon.bs.BasicClientUI.InteractionStyle
|
||||||
|
button_label_positive: bacommon.bs.BasicClientUI.ButtonLabel
|
||||||
|
button_label_negative: bacommon.bs.BasicClientUI.ButtonLabel
|
||||||
|
sections: list[_Section]
|
||||||
id: str
|
id: str
|
||||||
height: float
|
total_height: float
|
||||||
text_height: float
|
|
||||||
scale: float
|
|
||||||
text: str
|
|
||||||
color: tuple[float, float, float]
|
color: tuple[float, float, float]
|
||||||
backing: bui.Widget | None = None
|
backing: bui.Widget | None = None
|
||||||
button_positive: bui.Widget | None = None
|
button_positive: bui.Widget | None = None
|
||||||
|
button_spinner_positive: bui.Widget | None = None
|
||||||
button_negative: bui.Widget | None = None
|
button_negative: bui.Widget | None = None
|
||||||
message_text: bui.Widget | None = None
|
button_spinner_negative: bui.Widget | None = None
|
||||||
|
# message_text: bui.Widget | None = None
|
||||||
processing_complete: bool = False
|
processing_complete: bool = False
|
||||||
|
|
||||||
|
|
||||||
@ -45,15 +115,15 @@ class InboxWindow(bui.MainWindow):
|
|||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
|
||||||
self._message_entries: list[_MessageEntry] = []
|
self._entry_displays: list[_EntryDisplay] = []
|
||||||
|
|
||||||
self._width = 600 if uiscale is bui.UIScale.SMALL else 450
|
self._width = 800 if uiscale is bui.UIScale.SMALL else 500
|
||||||
self._height = (
|
self._height = (
|
||||||
375
|
455
|
||||||
if uiscale is bui.UIScale.SMALL
|
if uiscale is bui.UIScale.SMALL
|
||||||
else 370 if uiscale is bui.UIScale.MEDIUM else 450
|
else 370 if uiscale is bui.UIScale.MEDIUM else 450
|
||||||
)
|
)
|
||||||
yoffs = -47 if uiscale is bui.UIScale.SMALL else 0
|
yoffs = -42 if uiscale is bui.UIScale.SMALL else 0
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
root_widget=bui.containerwidget(
|
root_widget=bui.containerwidget(
|
||||||
@ -62,9 +132,9 @@ class InboxWindow(bui.MainWindow):
|
|||||||
'menu_full' if uiscale is bui.UIScale.SMALL else 'menu_full'
|
'menu_full' if uiscale is bui.UIScale.SMALL else 'menu_full'
|
||||||
),
|
),
|
||||||
scale=(
|
scale=(
|
||||||
2.3
|
1.7
|
||||||
if uiscale is bui.UIScale.SMALL
|
if uiscale is bui.UIScale.SMALL
|
||||||
else 1.65 if uiscale is bui.UIScale.MEDIUM else 1.23
|
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.15
|
||||||
),
|
),
|
||||||
stack_offset=(
|
stack_offset=(
|
||||||
(0, 0)
|
(0, 0)
|
||||||
@ -101,7 +171,7 @@ class InboxWindow(bui.MainWindow):
|
|||||||
position=(
|
position=(
|
||||||
self._width * 0.5,
|
self._width * 0.5,
|
||||||
self._height
|
self._height
|
||||||
- (27 if uiscale is bui.UIScale.SMALL else 20)
|
- (24 if uiscale is bui.UIScale.SMALL else 20)
|
||||||
+ yoffs,
|
+ yoffs,
|
||||||
),
|
),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
@ -122,11 +192,15 @@ class InboxWindow(bui.MainWindow):
|
|||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
color=(0.4, 0.4, 0.5),
|
color=(0.4, 0.4, 0.5),
|
||||||
shadow=0.0,
|
shadow=0.0,
|
||||||
text=bui.Lstr(resource='loadingText'),
|
text='',
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
)
|
)
|
||||||
|
self._loading_spinner = bui.spinnerwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(self._width * 0.5, self._height * 0.5),
|
||||||
|
)
|
||||||
self._scrollwidget = bui.scrollwidget(
|
self._scrollwidget = bui.scrollwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
size=(
|
size=(
|
||||||
@ -141,6 +215,7 @@ class InboxWindow(bui.MainWindow):
|
|||||||
simple_culling_v=200,
|
simple_culling_v=200,
|
||||||
claims_left_right=True,
|
claims_left_right=True,
|
||||||
claims_up_down=True,
|
claims_up_down=True,
|
||||||
|
center_small_content_horizontally=True,
|
||||||
)
|
)
|
||||||
bui.widget(edit=self._scrollwidget, autoselect=True)
|
bui.widget(edit=self._scrollwidget, autoselect=True)
|
||||||
if uiscale is bui.UIScale.SMALL:
|
if uiscale is bui.UIScale.SMALL:
|
||||||
@ -163,7 +238,7 @@ class InboxWindow(bui.MainWindow):
|
|||||||
|
|
||||||
with plus.accounts.primary:
|
with plus.accounts.primary:
|
||||||
plus.cloud.send_message_cb(
|
plus.cloud.send_message_cb(
|
||||||
bacommon.cloud.BSInboxRequestMessage(),
|
bacommon.bs.InboxRequestMessage(),
|
||||||
on_response=bui.WeakCall(self._on_inbox_request_response),
|
on_response=bui.WeakCall(self._on_inbox_request_response),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -179,26 +254,33 @@ class InboxWindow(bui.MainWindow):
|
|||||||
|
|
||||||
def _error(self, errmsg: bui.Lstr | str) -> None:
|
def _error(self, errmsg: bui.Lstr | str) -> None:
|
||||||
"""Put ourself in a permanent error state."""
|
"""Put ourself in a permanent error state."""
|
||||||
|
bui.spinnerwidget(edit=self._loading_spinner, visible=False)
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self._infotext,
|
edit=self._infotext,
|
||||||
color=(1, 0, 0),
|
color=(1, 0, 0),
|
||||||
text=errmsg,
|
text=errmsg,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_message_entry_press(
|
def _on_entry_display_press(
|
||||||
self,
|
self,
|
||||||
entry_weak: weakref.ReferenceType[_MessageEntry],
|
display_weak: weakref.ReferenceType[_EntryDisplay],
|
||||||
process_type: bacommon.cloud.BSInboxEntryProcessType,
|
action: bacommon.bs.ClientUIAction,
|
||||||
) -> None:
|
) -> None:
|
||||||
entry = entry_weak()
|
display = display_weak()
|
||||||
if entry is None:
|
if display is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._neuter_message_entry(entry)
|
bui.getsound('click01').play()
|
||||||
|
|
||||||
# We don't do anything for invalid messages.
|
self._neuter_entry_display(display)
|
||||||
if entry.type is bacommon.cloud.BSInboxEntryType.UNKNOWN:
|
|
||||||
entry.processing_complete = True
|
# We currently only recognize basic entries and their possible
|
||||||
|
# interaction types.
|
||||||
|
if (
|
||||||
|
display.interaction_style
|
||||||
|
is bacommon.bs.BasicClientUI.InteractionStyle.UNKNOWN
|
||||||
|
):
|
||||||
|
display.processing_complete = True
|
||||||
self._close_soon_if_all_processed()
|
self._close_soon_if_all_processed()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -211,38 +293,43 @@ class InboxWindow(bui.MainWindow):
|
|||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Message the master-server to process the entry.
|
# Ask the master-server to run our action.
|
||||||
with plus.accounts.primary:
|
with plus.accounts.primary:
|
||||||
plus.cloud.send_message_cb(
|
plus.cloud.send_message_cb(
|
||||||
bacommon.cloud.BSInboxEntryProcessMessage(
|
bacommon.bs.ClientUIActionMessage(display.id, action),
|
||||||
entry.id, process_type
|
|
||||||
),
|
|
||||||
on_response=bui.WeakCall(
|
on_response=bui.WeakCall(
|
||||||
self._on_inbox_entry_process_response,
|
self._on_client_ui_action_response,
|
||||||
entry_weak,
|
display_weak,
|
||||||
process_type,
|
action,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tweak the button to show this is in progress.
|
# Tweak the UI to show that things are in motion.
|
||||||
button = (
|
button = (
|
||||||
entry.button_positive
|
display.button_positive
|
||||||
if process_type is bacommon.cloud.BSInboxEntryProcessType.POSITIVE
|
if action is bacommon.bs.ClientUIAction.BUTTON_PRESS_POSITIVE
|
||||||
else entry.button_negative
|
else display.button_negative
|
||||||
|
)
|
||||||
|
button_spinner = (
|
||||||
|
display.button_spinner_positive
|
||||||
|
if action is bacommon.bs.ClientUIAction.BUTTON_PRESS_POSITIVE
|
||||||
|
else display.button_spinner_negative
|
||||||
)
|
)
|
||||||
if button is not None:
|
if button is not None:
|
||||||
bui.buttonwidget(edit=button, label='...')
|
bui.buttonwidget(edit=button, label='')
|
||||||
|
if button_spinner is not None:
|
||||||
|
bui.spinnerwidget(edit=button_spinner, visible=True)
|
||||||
|
|
||||||
def _close_soon_if_all_processed(self) -> None:
|
def _close_soon_if_all_processed(self) -> None:
|
||||||
bui.apptimer(0.25, bui.WeakCall(self._close_if_all_processed))
|
bui.apptimer(0.25, bui.WeakCall(self._close_if_all_processed))
|
||||||
|
|
||||||
def _close_if_all_processed(self) -> None:
|
def _close_if_all_processed(self) -> None:
|
||||||
if not all(m.processing_complete for m in self._message_entries):
|
if not all(m.processing_complete for m in self._entry_displays):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.main_window_back()
|
self.main_window_back()
|
||||||
|
|
||||||
def _neuter_message_entry(self, entry: _MessageEntry) -> None:
|
def _neuter_entry_display(self, entry: _EntryDisplay) -> None:
|
||||||
errsound = bui.getsound('error')
|
errsound = bui.getsound('error')
|
||||||
if entry.button_positive is not None:
|
if entry.button_positive is not None:
|
||||||
bui.buttonwidget(
|
bui.buttonwidget(
|
||||||
@ -260,22 +347,20 @@ class InboxWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
if entry.backing is not None:
|
if entry.backing is not None:
|
||||||
bui.imagewidget(edit=entry.backing, color=(0.4, 0.4, 0.4))
|
bui.imagewidget(edit=entry.backing, color=(0.4, 0.4, 0.4))
|
||||||
if entry.message_text is not None:
|
|
||||||
bui.textwidget(edit=entry.message_text, color=(0.5, 0.5, 0.5, 0.5))
|
|
||||||
|
|
||||||
def _on_inbox_entry_process_response(
|
def _on_client_ui_action_response(
|
||||||
self,
|
self,
|
||||||
entry_weak: weakref.ReferenceType[_MessageEntry],
|
display_weak: weakref.ReferenceType[_EntryDisplay],
|
||||||
process_type: bacommon.cloud.BSInboxEntryProcessType,
|
action: bacommon.bs.ClientUIAction,
|
||||||
response: bacommon.cloud.BSInboxEntryProcessResponse | Exception,
|
response: bacommon.bs.ClientUIActionResponse | Exception,
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
entry = entry_weak()
|
display = display_weak()
|
||||||
if entry is None:
|
if display is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
assert not entry.processing_complete
|
assert not display.processing_complete
|
||||||
entry.processing_complete = True
|
display.processing_complete = True
|
||||||
self._close_soon_if_all_processed()
|
self._close_soon_if_all_processed()
|
||||||
|
|
||||||
# No-op if our UI is dead or on its way out.
|
# No-op if our UI is dead or on its way out.
|
||||||
@ -284,10 +369,18 @@ class InboxWindow(bui.MainWindow):
|
|||||||
|
|
||||||
# Tweak the button to show results.
|
# Tweak the button to show results.
|
||||||
button = (
|
button = (
|
||||||
entry.button_positive
|
display.button_positive
|
||||||
if process_type is bacommon.cloud.BSInboxEntryProcessType.POSITIVE
|
if action is bacommon.bs.ClientUIAction.BUTTON_PRESS_POSITIVE
|
||||||
else entry.button_negative
|
else display.button_negative
|
||||||
)
|
)
|
||||||
|
button_spinner = (
|
||||||
|
display.button_spinner_positive
|
||||||
|
if action is bacommon.bs.ClientUIAction.BUTTON_PRESS_POSITIVE
|
||||||
|
else display.button_spinner_negative
|
||||||
|
)
|
||||||
|
# Always hide spinner at this point.
|
||||||
|
if button_spinner is not None:
|
||||||
|
bui.spinnerwidget(edit=button_spinner, visible=False)
|
||||||
|
|
||||||
# See if we should show an error message.
|
# See if we should show an error message.
|
||||||
if isinstance(response, Exception):
|
if isinstance(response, Exception):
|
||||||
@ -297,9 +390,11 @@ class InboxWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
error_message = bui.Lstr(resource='errorText')
|
error_message = bui.Lstr(resource='errorText')
|
||||||
elif response.error is not None:
|
elif response.error_type is not None:
|
||||||
|
# If error_type is set, error should be also.
|
||||||
|
assert response.error_message is not None
|
||||||
error_message = bui.Lstr(
|
error_message = bui.Lstr(
|
||||||
translate=('serverResponses', response.error)
|
translate=('serverResponses', response.error_message)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
error_message = None
|
error_message = None
|
||||||
@ -314,6 +409,13 @@ class InboxWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Success!
|
||||||
|
assert not isinstance(response, Exception)
|
||||||
|
|
||||||
|
# Run any bundled effects.
|
||||||
|
assert bui.app.classic is not None
|
||||||
|
bui.app.classic.run_bs_client_effects(response.effects)
|
||||||
|
|
||||||
# Whee; no error. Mark as done.
|
# Whee; no error. Mark as done.
|
||||||
if button is not None:
|
if button is not None:
|
||||||
# If we have full unicode, just show a checkmark in all cases.
|
# If we have full unicode, just show a checkmark in all cases.
|
||||||
@ -321,24 +423,11 @@ class InboxWindow(bui.MainWindow):
|
|||||||
if bui.supports_unicode_display():
|
if bui.supports_unicode_display():
|
||||||
label = '✓'
|
label = '✓'
|
||||||
else:
|
else:
|
||||||
# For positive claim buttons, say 'success'.
|
label = bui.Lstr(resource='doneText')
|
||||||
# Otherwise default to 'done.'
|
|
||||||
if (
|
|
||||||
entry.type
|
|
||||||
in {
|
|
||||||
bacommon.cloud.BSInboxEntryType.CLAIM,
|
|
||||||
bacommon.cloud.BSInboxEntryType.CLAIM_DISCARD,
|
|
||||||
}
|
|
||||||
and process_type
|
|
||||||
is bacommon.cloud.BSInboxEntryProcessType.POSITIVE
|
|
||||||
):
|
|
||||||
label = bui.Lstr(resource='successText')
|
|
||||||
else:
|
|
||||||
label = bui.Lstr(resource='doneText')
|
|
||||||
bui.buttonwidget(edit=button, label=label)
|
bui.buttonwidget(edit=button, label=label)
|
||||||
|
|
||||||
def _on_inbox_request_response(
|
def _on_inbox_request_response(
|
||||||
self, response: bacommon.cloud.BSInboxRequestResponse | Exception
|
self, response: bacommon.bs.InboxRequestResponse | Exception
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
@ -364,11 +453,12 @@ class InboxWindow(bui.MainWindow):
|
|||||||
self._error(errmsg)
|
self._error(errmsg)
|
||||||
return
|
return
|
||||||
|
|
||||||
assert isinstance(response, bacommon.cloud.BSInboxRequestResponse)
|
assert isinstance(response, bacommon.bs.InboxRequestResponse)
|
||||||
|
|
||||||
# If we got no messages, don't touch anything. This keeps
|
# If we got no messages, don't touch anything. This keeps
|
||||||
# keyboard control working in the empty case.
|
# keyboard control working in the empty case.
|
||||||
if not response.entries:
|
if not response.wrappers:
|
||||||
|
bui.spinnerwidget(edit=self._loading_spinner, visible=False)
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self._infotext,
|
edit=self._infotext,
|
||||||
color=(0.4, 0.4, 0.5),
|
color=(0.4, 0.4, 0.5),
|
||||||
@ -376,63 +466,96 @@ class InboxWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
bui.spinnerwidget(edit=self._loading_spinner, visible=False)
|
||||||
bui.textwidget(edit=self._infotext, text='')
|
bui.textwidget(edit=self._infotext, text='')
|
||||||
|
|
||||||
sub_width = self._width - 90
|
# Even though our window size varies with uiscale, we want
|
||||||
|
# notifications to target a fixed width.
|
||||||
|
sub_width = 400.0
|
||||||
sub_height = 0.0
|
sub_height = 0.0
|
||||||
|
|
||||||
# Run the math on row heights/etc.
|
# Construct entries for everything we'll display.
|
||||||
for i, entry in enumerate(response.entries):
|
for i, wrapper in enumerate(response.wrappers):
|
||||||
|
|
||||||
# We need to flatten text here so we can measure it.
|
# We need to flatten text here so we can measure it.
|
||||||
textfin: str
|
# textfin: str
|
||||||
color: tuple[float, float, float]
|
color: tuple[float, float, float]
|
||||||
|
|
||||||
# Messages with either newer formatting or unrecognized
|
interaction_style: bacommon.bs.BasicClientUI.InteractionStyle
|
||||||
# types show up as 'upgrade your app to see this'.
|
button_label_positive: bacommon.bs.BasicClientUI.ButtonLabel
|
||||||
if (
|
button_label_negative: bacommon.bs.BasicClientUI.ButtonLabel
|
||||||
entry.format_version > SUPPORTED_INBOX_MESSAGE_FORMAT_VERSION
|
|
||||||
or entry.type is bacommon.cloud.BSInboxEntryType.UNKNOWN
|
|
||||||
):
|
|
||||||
textfin = bui.Lstr(
|
|
||||||
translate=(
|
|
||||||
'serverResponses',
|
|
||||||
'You must update the app to view this.',
|
|
||||||
)
|
|
||||||
).evaluate()
|
|
||||||
color = (0.6, 0.6, 0.6)
|
|
||||||
else:
|
|
||||||
# Translate raw response and apply any replacements.
|
|
||||||
textfin = bui.Lstr(
|
|
||||||
translate=('serverResponses', entry.message)
|
|
||||||
).evaluate()
|
|
||||||
assert len(entry.subs) % 2 == 0 # Should always be even.
|
|
||||||
for j in range(0, len(entry.subs) - 1, 2):
|
|
||||||
textfin = textfin.replace(entry.subs[j], entry.subs[j + 1])
|
|
||||||
color = (0.55, 0.5, 0.7)
|
|
||||||
|
|
||||||
# Calc scale to fit width and then see what height we need
|
sections: list[_Section] = []
|
||||||
# at that scale.
|
total_height = 90.0
|
||||||
t_width = max(
|
|
||||||
10.0, bui.get_string_width(textfin, suppress_warning=True)
|
# Display only entries where we recognize all style/label
|
||||||
)
|
# values and ui component types.
|
||||||
scale = min(0.6, (sub_width * 0.9) / t_width)
|
if (
|
||||||
t_height = (
|
isinstance(wrapper.ui, bacommon.bs.BasicClientUI)
|
||||||
max(10.0, bui.get_string_height(textfin, suppress_warning=True))
|
and not wrapper.ui.contains_unknown_elements()
|
||||||
* scale
|
):
|
||||||
)
|
color = (0.55, 0.5, 0.7)
|
||||||
entry_height = 90.0 + t_height
|
interaction_style = wrapper.ui.interaction_style
|
||||||
self._message_entries.append(
|
button_label_positive = wrapper.ui.button_label_positive
|
||||||
_MessageEntry(
|
button_label_negative = wrapper.ui.button_label_negative
|
||||||
type=entry.type,
|
|
||||||
id=entry.id,
|
idcls = bacommon.bs.BasicClientUIComponentTypeID
|
||||||
height=entry_height,
|
for component in wrapper.ui.components:
|
||||||
text_height=t_height,
|
ctypeid = component.get_type_id()
|
||||||
scale=scale,
|
if ctypeid is idcls.TEXT:
|
||||||
text=textfin,
|
assert isinstance(
|
||||||
|
component, bacommon.bs.BasicClientUIComponentText
|
||||||
|
)
|
||||||
|
section = _TextSection(
|
||||||
|
sub_width=sub_width,
|
||||||
|
text=component.text,
|
||||||
|
subs=component.subs,
|
||||||
|
color=component.color,
|
||||||
|
scale=component.scale,
|
||||||
|
spacing_top=component.spacing_top,
|
||||||
|
spacing_bottom=component.spacing_bottom,
|
||||||
|
)
|
||||||
|
total_height += section.get_height()
|
||||||
|
sections.append(section)
|
||||||
|
|
||||||
|
elif ctypeid is idcls.UNKNOWN:
|
||||||
|
raise RuntimeError('Should not get here.')
|
||||||
|
else:
|
||||||
|
# Make sure we handle all types.
|
||||||
|
assert_never(ctypeid)
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Display anything with unknown components as an
|
||||||
|
# 'upgrade your app to see this' message.
|
||||||
|
color = (0.6, 0.6, 0.6)
|
||||||
|
interaction_style = (
|
||||||
|
bacommon.bs.BasicClientUI.InteractionStyle.UNKNOWN
|
||||||
|
)
|
||||||
|
button_label_positive = bacommon.bs.BasicClientUI.ButtonLabel.OK
|
||||||
|
button_label_negative = (
|
||||||
|
bacommon.bs.BasicClientUI.ButtonLabel.CANCEL
|
||||||
|
)
|
||||||
|
|
||||||
|
section = _TextSection(
|
||||||
|
sub_width=sub_width,
|
||||||
|
text='You must update the app to view this.',
|
||||||
|
subs=[],
|
||||||
|
)
|
||||||
|
total_height += section.get_height()
|
||||||
|
sections.append(section)
|
||||||
|
|
||||||
|
self._entry_displays.append(
|
||||||
|
_EntryDisplay(
|
||||||
|
interaction_style=interaction_style,
|
||||||
|
button_label_positive=button_label_positive,
|
||||||
|
button_label_negative=button_label_negative,
|
||||||
|
id=wrapper.id,
|
||||||
|
sections=sections,
|
||||||
|
total_height=total_height,
|
||||||
color=color,
|
color=color,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sub_height += entry_height
|
sub_height += total_height
|
||||||
|
|
||||||
subcontainer = bui.containerwidget(
|
subcontainer = bui.containerwidget(
|
||||||
id='inboxsub',
|
id='inboxsub',
|
||||||
@ -446,98 +569,116 @@ class InboxWindow(bui.MainWindow):
|
|||||||
|
|
||||||
backing_tex = bui.gettexture('buttonSquareWide')
|
backing_tex = bui.gettexture('buttonSquareWide')
|
||||||
|
|
||||||
|
assert bui.app.classic is not None
|
||||||
|
|
||||||
buttonrows: list[list[bui.Widget]] = []
|
buttonrows: list[list[bui.Widget]] = []
|
||||||
y = sub_height
|
y = sub_height
|
||||||
for i, _entry in enumerate(response.entries):
|
for i, _wrapper in enumerate(response.wrappers):
|
||||||
message_entry = self._message_entries[i]
|
entry_display = self._entry_displays[i]
|
||||||
message_entry_weak = weakref.ref(message_entry)
|
entry_display_weak = weakref.ref(entry_display)
|
||||||
bwidth = 140
|
bwidth = 140
|
||||||
bheight = 40
|
bheight = 40
|
||||||
|
|
||||||
|
ysection = y - 23.0
|
||||||
|
|
||||||
# Backing.
|
# Backing.
|
||||||
message_entry.backing = img = bui.imagewidget(
|
entry_display.backing = img = bui.imagewidget(
|
||||||
parent=subcontainer,
|
parent=subcontainer,
|
||||||
position=(-0.022 * sub_width, y - message_entry.height * 1.09),
|
position=(
|
||||||
|
-0.022 * sub_width,
|
||||||
|
y - entry_display.total_height * 1.09,
|
||||||
|
),
|
||||||
texture=backing_tex,
|
texture=backing_tex,
|
||||||
size=(sub_width * 1.07, message_entry.height * 1.15),
|
size=(sub_width * 1.07, entry_display.total_height * 1.15),
|
||||||
color=message_entry.color,
|
color=entry_display.color,
|
||||||
opacity=0.9,
|
opacity=0.9,
|
||||||
)
|
)
|
||||||
bui.widget(edit=img, depth_range=(0, 0.1))
|
bui.widget(edit=img, depth_range=(0, 0.1))
|
||||||
|
|
||||||
|
# Section contents.
|
||||||
|
for sec in entry_display.sections:
|
||||||
|
sec.draw(subcontainer, ysection)
|
||||||
|
ysection -= sec.get_height()
|
||||||
|
|
||||||
buttonrow: list[bui.Widget] = []
|
buttonrow: list[bui.Widget] = []
|
||||||
have_negative_button = (
|
have_negative_button = (
|
||||||
message_entry.type
|
entry_display.interaction_style
|
||||||
is bacommon.cloud.BSInboxEntryType.CLAIM_DISCARD
|
is (
|
||||||
|
bacommon.bs.BasicClientUI
|
||||||
|
).InteractionStyle.BUTTON_POSITIVE_NEGATIVE
|
||||||
)
|
)
|
||||||
|
|
||||||
message_entry.button_positive = btn = bui.buttonwidget(
|
bpos = (
|
||||||
|
(
|
||||||
|
(sub_width - bwidth - 25)
|
||||||
|
if have_negative_button
|
||||||
|
else ((sub_width - bwidth) * 0.5)
|
||||||
|
),
|
||||||
|
y - entry_display.total_height + 15.0,
|
||||||
|
)
|
||||||
|
entry_display.button_positive = btn = bui.buttonwidget(
|
||||||
parent=subcontainer,
|
parent=subcontainer,
|
||||||
position=(
|
position=bpos,
|
||||||
(
|
|
||||||
(sub_width - bwidth - 25)
|
|
||||||
if have_negative_button
|
|
||||||
else ((sub_width - bwidth) * 0.5)
|
|
||||||
),
|
|
||||||
y - message_entry.height + 15.0,
|
|
||||||
),
|
|
||||||
size=(bwidth, bheight),
|
size=(bwidth, bheight),
|
||||||
label=bui.Lstr(
|
label=bui.app.classic.basic_client_ui_button_label_str(
|
||||||
resource=(
|
entry_display.button_label_positive
|
||||||
'claimText'
|
|
||||||
if message_entry.type
|
|
||||||
in {
|
|
||||||
bacommon.cloud.BSInboxEntryType.CLAIM,
|
|
||||||
bacommon.cloud.BSInboxEntryType.CLAIM_DISCARD,
|
|
||||||
}
|
|
||||||
else 'okText'
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
color=message_entry.color,
|
color=entry_display.color,
|
||||||
textcolor=(0, 1, 0),
|
textcolor=(0, 1, 0),
|
||||||
on_activate_call=bui.WeakCall(
|
on_activate_call=bui.WeakCall(
|
||||||
self._on_message_entry_press,
|
self._on_entry_display_press,
|
||||||
message_entry_weak,
|
entry_display_weak,
|
||||||
bacommon.cloud.BSInboxEntryProcessType.POSITIVE,
|
bacommon.bs.ClientUIAction.BUTTON_PRESS_POSITIVE,
|
||||||
),
|
),
|
||||||
|
enable_sound=False,
|
||||||
)
|
)
|
||||||
bui.widget(edit=btn, depth_range=(0.1, 1.0))
|
bui.widget(edit=btn, depth_range=(0.1, 1.0))
|
||||||
buttonrow.append(btn)
|
buttonrow.append(btn)
|
||||||
|
spinner = entry_display.button_spinner_positive = bui.spinnerwidget(
|
||||||
|
parent=subcontainer,
|
||||||
|
position=(
|
||||||
|
bpos[0] + 0.5 * bwidth,
|
||||||
|
bpos[1] + 0.5 * bheight,
|
||||||
|
),
|
||||||
|
visible=False,
|
||||||
|
)
|
||||||
|
bui.widget(edit=spinner, depth_range=(0.1, 1.0))
|
||||||
|
|
||||||
if have_negative_button:
|
if have_negative_button:
|
||||||
message_entry.button_negative = btn2 = bui.buttonwidget(
|
bpos = (25, y - entry_display.total_height + 15.0)
|
||||||
|
entry_display.button_negative = btn2 = bui.buttonwidget(
|
||||||
parent=subcontainer,
|
parent=subcontainer,
|
||||||
position=(25, y - message_entry.height + 15.0),
|
position=bpos,
|
||||||
size=(bwidth, bheight),
|
size=(bwidth, bheight),
|
||||||
label=bui.Lstr(resource='discardText'),
|
label=bui.app.classic.basic_client_ui_button_label_str(
|
||||||
|
entry_display.button_label_negative
|
||||||
|
),
|
||||||
color=(0.85, 0.5, 0.7),
|
color=(0.85, 0.5, 0.7),
|
||||||
textcolor=(1, 0.4, 0.4),
|
textcolor=(1, 0.4, 0.4),
|
||||||
on_activate_call=bui.WeakCall(
|
on_activate_call=bui.WeakCall(
|
||||||
self._on_message_entry_press,
|
self._on_entry_display_press,
|
||||||
message_entry_weak,
|
entry_display_weak,
|
||||||
bacommon.cloud.BSInboxEntryProcessType.NEGATIVE,
|
(bacommon.bs.ClientUIAction).BUTTON_PRESS_NEGATIVE,
|
||||||
),
|
),
|
||||||
|
enable_sound=False,
|
||||||
)
|
)
|
||||||
bui.widget(edit=btn2, depth_range=(0.1, 1.0))
|
bui.widget(edit=btn2, depth_range=(0.1, 1.0))
|
||||||
buttonrow.append(btn2)
|
buttonrow.append(btn2)
|
||||||
|
spinner = entry_display.button_spinner_negative = (
|
||||||
|
bui.spinnerwidget(
|
||||||
|
parent=subcontainer,
|
||||||
|
position=(
|
||||||
|
bpos[0] + 0.5 * bwidth,
|
||||||
|
bpos[1] + 0.5 * bheight,
|
||||||
|
),
|
||||||
|
visible=False,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bui.widget(edit=spinner, depth_range=(0.1, 1.0))
|
||||||
|
|
||||||
buttonrows.append(buttonrow)
|
buttonrows.append(buttonrow)
|
||||||
|
|
||||||
message_entry.message_text = bui.textwidget(
|
y -= entry_display.total_height
|
||||||
parent=subcontainer,
|
|
||||||
position=(
|
|
||||||
sub_width * 0.5,
|
|
||||||
y - message_entry.text_height * 0.5 - 23.0,
|
|
||||||
),
|
|
||||||
scale=message_entry.scale,
|
|
||||||
flatness=1.0,
|
|
||||||
shadow=0.0,
|
|
||||||
text=message_entry.text,
|
|
||||||
size=(0, 0),
|
|
||||||
h_align='center',
|
|
||||||
v_align='center',
|
|
||||||
)
|
|
||||||
y -= message_entry.height
|
|
||||||
|
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
above_widget = (
|
above_widget = (
|
||||||
|
|||||||
@ -39,6 +39,7 @@ class LeagueRankWindow(bui.MainWindow):
|
|||||||
self._league_text: bui.Widget | None = None
|
self._league_text: bui.Widget | None = None
|
||||||
self._league_number_text: bui.Widget | None = None
|
self._league_number_text: bui.Widget | None = None
|
||||||
self._your_power_ranking_text: bui.Widget | None = None
|
self._your_power_ranking_text: bui.Widget | None = None
|
||||||
|
self._loading_spinner: bui.Widget | None = None
|
||||||
self._season_ends_text: bui.Widget | None = None
|
self._season_ends_text: bui.Widget | None = None
|
||||||
self._power_ranking_rank_text: bui.Widget | None = None
|
self._power_ranking_rank_text: bui.Widget | None = None
|
||||||
self._to_ranked_text: bui.Widget | None = None
|
self._to_ranked_text: bui.Widget | None = None
|
||||||
@ -150,7 +151,7 @@ class LeagueRankWindow(bui.MainWindow):
|
|||||||
self._doing_power_ranking_query = False
|
self._doing_power_ranking_query = False
|
||||||
|
|
||||||
self._subcontainer: bui.Widget | None = None
|
self._subcontainer: bui.Widget | None = None
|
||||||
self._subcontainerwidth = 800
|
self._subcontainerwidth = max(800, self._scroll_width)
|
||||||
self._subcontainerheight = 483
|
self._subcontainerheight = 483
|
||||||
self._power_ranking_score_widgets: list[bui.Widget] = []
|
self._power_ranking_score_widgets: list[bui.Widget] = []
|
||||||
|
|
||||||
@ -330,13 +331,8 @@ class LeagueRankWindow(bui.MainWindow):
|
|||||||
bui.textwidget(edit=self._league_title_text, text='')
|
bui.textwidget(edit=self._league_title_text, text='')
|
||||||
bui.textwidget(edit=self._league_text, text='')
|
bui.textwidget(edit=self._league_text, text='')
|
||||||
bui.textwidget(edit=self._league_number_text, text='')
|
bui.textwidget(edit=self._league_number_text, text='')
|
||||||
bui.textwidget(
|
bui.textwidget(edit=self._your_power_ranking_text, text='')
|
||||||
edit=self._your_power_ranking_text,
|
bui.spinnerwidget(edit=self._loading_spinner, visible=True)
|
||||||
text=bui.Lstr(
|
|
||||||
value='${A}...',
|
|
||||||
subs=[('${A}', bui.Lstr(resource='loadingText'))],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
bui.textwidget(edit=self._to_ranked_text, text='')
|
bui.textwidget(edit=self._to_ranked_text, text='')
|
||||||
bui.textwidget(edit=self._power_ranking_rank_text, text='')
|
bui.textwidget(edit=self._power_ranking_rank_text, text='')
|
||||||
bui.textwidget(edit=self._season_ends_text, text='')
|
bui.textwidget(edit=self._season_ends_text, text='')
|
||||||
@ -618,6 +614,14 @@ class LeagueRankWindow(bui.MainWindow):
|
|||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._loading_spinner = bui.spinnerwidget(
|
||||||
|
parent=w_parent,
|
||||||
|
position=(
|
||||||
|
self._subcontainerwidth * 0.5,
|
||||||
|
self._subcontainerheight * 0.5,
|
||||||
|
),
|
||||||
|
size=64,
|
||||||
|
)
|
||||||
self._your_power_ranking_text = bui.textwidget(
|
self._your_power_ranking_text = bui.textwidget(
|
||||||
parent=w_parent,
|
parent=w_parent,
|
||||||
position=(self._xoffs + 470, v - 142 - 70),
|
position=(self._xoffs + 470, v - 142 - 70),
|
||||||
@ -968,6 +972,7 @@ class LeagueRankWindow(bui.MainWindow):
|
|||||||
else ''
|
else ''
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
bui.spinnerwidget(edit=self._loading_spinner, visible=False)
|
||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self._power_ranking_rank_text,
|
edit=self._power_ranking_rank_text,
|
||||||
|
|||||||
@ -431,7 +431,6 @@ class MainMenuWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Credits button.
|
# Credits button.
|
||||||
# self._tdelay += self._t_delay_inc
|
|
||||||
thistdelay = self._tdelay + td5 * self._t_delay_inc
|
thistdelay = self._tdelay + td5 * self._t_delay_inc
|
||||||
|
|
||||||
h += side_button_width * side_button_scale * 0.5 + hspace2
|
h += side_button_width * side_button_scale * 0.5 + hspace2
|
||||||
@ -454,15 +453,16 @@ class MainMenuWindow(bui.MainWindow):
|
|||||||
transition_delay=thistdelay,
|
transition_delay=thistdelay,
|
||||||
on_activate_call=self._credits,
|
on_activate_call=self._credits,
|
||||||
)
|
)
|
||||||
# self._tdelay += self._t_delay_inc
|
|
||||||
|
|
||||||
self._quit_button: bui.Widget | None
|
self._quit_button: bui.Widget | None
|
||||||
if self._have_quit_button:
|
if self._have_quit_button:
|
||||||
v -= 1.1 * side_button_2_height * side_button_2_scale
|
v -= 1.1 * side_button_2_height * side_button_2_scale
|
||||||
|
# Nudge this a tiny bit right so we can press right from the
|
||||||
|
# credits button to get to it.
|
||||||
self._quit_button = quit_button = bui.buttonwidget(
|
self._quit_button = quit_button = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
autoselect=self._use_autoselect,
|
autoselect=self._use_autoselect,
|
||||||
position=(h, v),
|
position=(h + 4.0, v),
|
||||||
size=(side_button_2_width, side_button_2_height),
|
size=(side_button_2_width, side_button_2_height),
|
||||||
scale=side_button_2_scale,
|
scale=side_button_2_scale,
|
||||||
label=bui.Lstr(
|
label=bui.Lstr(
|
||||||
|
|||||||
@ -579,6 +579,10 @@ class PartyQueueWindow(bui.Window):
|
|||||||
|
|
||||||
if plus.get_v1_account_ticket_count() < self._boost_tickets:
|
if plus.get_v1_account_ticket_count() < self._boost_tickets:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notEnoughTicketsText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
# gettickets.show_get_tickets_prompt()
|
# gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@ -42,9 +42,9 @@ class PlayWindow(bui.MainWindow):
|
|||||||
self._playlist_select_context = playlist_select_context
|
self._playlist_select_context = playlist_select_context
|
||||||
|
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
width = 1100 if uiscale is bui.UIScale.SMALL else 800
|
width = 1100 if uiscale is bui.UIScale.SMALL else 1000
|
||||||
x_offs = 150 if uiscale is bui.UIScale.SMALL else 0
|
x_offs = 150 if uiscale is bui.UIScale.SMALL else 90
|
||||||
y_offs = -60 if uiscale is bui.UIScale.SMALL else 0
|
y_offs = -60 if uiscale is bui.UIScale.SMALL else 45
|
||||||
height = 650 if uiscale is bui.UIScale.SMALL else 550
|
height = 650 if uiscale is bui.UIScale.SMALL else 550
|
||||||
button_width = 400
|
button_width = 400
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class PlayWindow(bui.MainWindow):
|
|||||||
else:
|
else:
|
||||||
self._back_button = bui.buttonwidget(
|
self._back_button = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(55 + x_offs, height - 132 + y_offs),
|
position=(5 + x_offs, height - 162 + y_offs),
|
||||||
size=(60, 60),
|
size=(60, 60),
|
||||||
scale=1.1,
|
scale=1.1,
|
||||||
text_res_scale=1.5,
|
text_res_scale=1.5,
|
||||||
@ -103,11 +103,12 @@ class PlayWindow(bui.MainWindow):
|
|||||||
edit=self._root_widget, cancel_button=self._back_button
|
edit=self._root_widget, cancel_button=self._back_button
|
||||||
)
|
)
|
||||||
|
|
||||||
txt = bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(width * 0.5, height - 101 + y_offs),
|
position=(
|
||||||
# position=(width * 0.5, height -
|
width * 0.5,
|
||||||
# (101 if main_menu else 61)),
|
height - (83 if uiscale is bui.UIScale.SMALL else 131) + y_offs,
|
||||||
|
),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
text=bui.Lstr(
|
text=bui.Lstr(
|
||||||
resource=(
|
resource=(
|
||||||
@ -116,17 +117,13 @@ class PlayWindow(bui.MainWindow):
|
|||||||
else 'playlistsText'
|
else 'playlistsText'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
scale=1.7,
|
scale=1.2 if uiscale is bui.UIScale.SMALL else 1.7,
|
||||||
res_scale=2.0,
|
res_scale=2.0,
|
||||||
maxwidth=400,
|
maxwidth=400,
|
||||||
color=bui.app.ui_v1.heading_color,
|
color=bui.app.ui_v1.heading_color,
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
)
|
)
|
||||||
|
|
||||||
if uiscale is bui.UIScale.SMALL:
|
|
||||||
bui.textwidget(edit=txt, text='')
|
|
||||||
|
|
||||||
v = (
|
v = (
|
||||||
height
|
height
|
||||||
- (110 if self._playlist_select_context is None else 90)
|
- (110 if self._playlist_select_context is None else 90)
|
||||||
@ -134,14 +131,14 @@ class PlayWindow(bui.MainWindow):
|
|||||||
)
|
)
|
||||||
v -= 100
|
v -= 100
|
||||||
clr = (0.6, 0.7, 0.6, 1.0)
|
clr = (0.6, 0.7, 0.6, 1.0)
|
||||||
v -= 280 if self._playlist_select_context is None else 180
|
v -= 270 if self._playlist_select_context is None else 280
|
||||||
v += 30 if uiscale is bui.UIScale.SMALL else 0
|
v += 65 if uiscale is bui.UIScale.SMALL else 0
|
||||||
hoffs = (
|
hoffs = (
|
||||||
x_offs + 80
|
x_offs - 45
|
||||||
if self._playlist_select_context is None
|
if self._playlist_select_context is None
|
||||||
else x_offs - 100
|
else x_offs - 100
|
||||||
)
|
)
|
||||||
scl = 1.13 if self._playlist_select_context is None else 0.68
|
scl = 0.75 if self._playlist_select_context is None else 0.68
|
||||||
|
|
||||||
self._lineup_tex = bui.gettexture('playerLineup')
|
self._lineup_tex = bui.gettexture('playerLineup')
|
||||||
angry_computer_transparent_mesh = bui.getmesh(
|
angry_computer_transparent_mesh = bui.getmesh(
|
||||||
@ -167,16 +164,15 @@ class PlayWindow(bui.MainWindow):
|
|||||||
if self._playlist_select_context is None:
|
if self._playlist_select_context is None:
|
||||||
self._coop_button = btn = bui.buttonwidget(
|
self._coop_button = btn = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(hoffs, v + (scl * 15)),
|
position=(hoffs, v),
|
||||||
size=(
|
size=(
|
||||||
scl * button_width,
|
scl * button_width,
|
||||||
scl * 300,
|
scl * 360,
|
||||||
),
|
),
|
||||||
extra_touch_border_scale=0.1,
|
extra_touch_border_scale=0.1,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
label='',
|
label='',
|
||||||
button_type='square',
|
button_type='square',
|
||||||
text_scale=1.13,
|
|
||||||
on_activate_call=self._coop,
|
on_activate_call=self._coop,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -247,7 +243,7 @@ class PlayWindow(bui.MainWindow):
|
|||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
color=(0.7, 0.9, 0.7, 1.0),
|
color=(0.7, 0.9, 0.7, 1.0),
|
||||||
scale=scl * 2.3,
|
scale=scl * 1.5,
|
||||||
)
|
)
|
||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
@ -264,34 +260,29 @@ class PlayWindow(bui.MainWindow):
|
|||||||
color=clr,
|
color=clr,
|
||||||
)
|
)
|
||||||
|
|
||||||
scl = 0.5 if self._playlist_select_context is None else 0.68
|
scl = 0.75 if self._playlist_select_context is None else 0.68
|
||||||
hoffs += 440 if self._playlist_select_context is None else 216
|
hoffs += 300 if self._playlist_select_context is None else 216
|
||||||
v += 180 if self._playlist_select_context is None else -68
|
# v += 0 if self._playlist_select_context is None else -68
|
||||||
|
|
||||||
self._teams_button = btn = bui.buttonwidget(
|
self._teams_button = btn = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(
|
position=(
|
||||||
hoffs,
|
hoffs,
|
||||||
v + (scl * 15 if self._playlist_select_context is None else 0),
|
v,
|
||||||
|
# v + (scl * 15 if
|
||||||
|
# self._playlist_select_context is None else 0),
|
||||||
),
|
),
|
||||||
size=(
|
size=(
|
||||||
scl * button_width,
|
scl * button_width,
|
||||||
scl * (300 if self._playlist_select_context is None else 360),
|
scl * (360 if self._playlist_select_context is None else 360),
|
||||||
),
|
),
|
||||||
extra_touch_border_scale=0.1,
|
extra_touch_border_scale=0.1,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
label='',
|
label='',
|
||||||
button_type='square',
|
button_type='square',
|
||||||
text_scale=1.13,
|
|
||||||
on_activate_call=self._team_tourney,
|
on_activate_call=self._team_tourney,
|
||||||
)
|
)
|
||||||
|
|
||||||
bui.widget(
|
|
||||||
edit=btn,
|
|
||||||
up_widget=bui.get_special_widget('get_tokens_button'),
|
|
||||||
right_widget=bui.get_special_widget('squad_button'),
|
|
||||||
)
|
|
||||||
|
|
||||||
xxx = -14
|
xxx = -14
|
||||||
self._draw_dude(
|
self._draw_dude(
|
||||||
2,
|
2,
|
||||||
@ -381,7 +372,7 @@ class PlayWindow(bui.MainWindow):
|
|||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
color=(0.7, 0.9, 0.7, 1.0),
|
color=(0.7, 0.9, 0.7, 1.0),
|
||||||
scale=scl * 2.3,
|
scale=scl * 1.5,
|
||||||
)
|
)
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
@ -392,29 +383,30 @@ class PlayWindow(bui.MainWindow):
|
|||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
res_scale=1.5,
|
res_scale=1.5,
|
||||||
scale=0.9 * scl,
|
scale=0.83 * scl,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
maxwidth=scl * button_width * 0.7,
|
maxwidth=scl * button_width * 0.7,
|
||||||
color=clr,
|
color=clr,
|
||||||
)
|
)
|
||||||
|
|
||||||
hoffs += 0 if self._playlist_select_context is None else 300
|
hoffs += 300 if self._playlist_select_context is None else 300
|
||||||
v -= 155 if self._playlist_select_context is None else 0
|
# v -= 0 if self._playlist_select_context is None else 0
|
||||||
self._free_for_all_button = btn = bui.buttonwidget(
|
self._free_for_all_button = btn = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(
|
position=(
|
||||||
hoffs,
|
hoffs,
|
||||||
v + (scl * 15 if self._playlist_select_context is None else 0),
|
v,
|
||||||
|
# v + (scl * 15
|
||||||
|
# if self._playlist_select_context is None else 0),
|
||||||
),
|
),
|
||||||
size=(
|
size=(
|
||||||
scl * button_width,
|
scl * button_width,
|
||||||
scl * (300 if self._playlist_select_context is None else 360),
|
scl * (360 if self._playlist_select_context is None else 360),
|
||||||
),
|
),
|
||||||
extra_touch_border_scale=0.1,
|
extra_touch_border_scale=0.1,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
label='',
|
label='',
|
||||||
button_type='square',
|
button_type='square',
|
||||||
text_scale=1.13,
|
|
||||||
on_activate_call=self._free_for_all,
|
on_activate_call=self._free_for_all,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -505,7 +497,7 @@ class PlayWindow(bui.MainWindow):
|
|||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
color=(0.7, 0.9, 0.7, 1.0),
|
color=(0.7, 0.9, 0.7, 1.0),
|
||||||
scale=scl * 1.9,
|
scale=scl * 1.5,
|
||||||
)
|
)
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
@ -515,7 +507,7 @@ class PlayWindow(bui.MainWindow):
|
|||||||
text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'),
|
text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
scale=0.9 * scl,
|
scale=0.83 * scl,
|
||||||
flatness=1.0,
|
flatness=1.0,
|
||||||
maxwidth=scl * button_width * 0.7,
|
maxwidth=scl * button_width * 0.7,
|
||||||
color=clr,
|
color=clr,
|
||||||
|
|||||||
@ -17,6 +17,8 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
from bauiv1lib.play import PlaylistSelectContext
|
from bauiv1lib.play import PlaylistSelectContext
|
||||||
|
|
||||||
|
REQUIRE_PRO = False
|
||||||
|
|
||||||
|
|
||||||
class PlayOptionsWindow(PopupWindow):
|
class PlayOptionsWindow(PopupWindow):
|
||||||
"""A popup window for configuring play options."""
|
"""A popup window for configuring play options."""
|
||||||
@ -316,7 +318,7 @@ class PlayOptionsWindow(PopupWindow):
|
|||||||
label=bui.Lstr(resource='teamNamesColorText'),
|
label=bui.Lstr(resource='teamNamesColorText'),
|
||||||
)
|
)
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
if not bui.app.classic.accounts.have_pro():
|
if REQUIRE_PRO and not bui.app.classic.accounts.have_pro():
|
||||||
bui.imagewidget(
|
bui.imagewidget(
|
||||||
parent=self.root_widget,
|
parent=self.root_widget,
|
||||||
size=(30, 30),
|
size=(30, 30),
|
||||||
@ -440,7 +442,7 @@ class PlayOptionsWindow(PopupWindow):
|
|||||||
assert plus is not None
|
assert plus is not None
|
||||||
|
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
if not bui.app.classic.accounts.have_pro():
|
if REQUIRE_PRO and not bui.app.classic.accounts.have_pro():
|
||||||
if plus.get_v1_account_state() != 'signed_in':
|
if plus.get_v1_account_state() != 'signed_in':
|
||||||
show_sign_in_prompt()
|
show_sign_in_prompt()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -205,7 +205,10 @@ class ProfileUpgradeWindow(bui.Window):
|
|||||||
tickets = plus.get_v1_account_ticket_count()
|
tickets = plus.get_v1_account_ticket_count()
|
||||||
if tickets < self._cost:
|
if tickets < self._cost:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
print('FIXME - show not-enough-tickets msg.')
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notEnoughTicketsText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
# gettickets.show_get_tickets_prompt()
|
# gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
bui.screenmessage(
|
bui.screenmessage(
|
||||||
|
|||||||
@ -162,7 +162,6 @@ class PurchaseWindow(bui.Window):
|
|||||||
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||||
|
|
||||||
def _purchase(self) -> None:
|
def _purchase(self) -> None:
|
||||||
# from bauiv1lib import gettickets
|
|
||||||
|
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
@ -176,9 +175,12 @@ class PurchaseWindow(bui.Window):
|
|||||||
except Exception:
|
except Exception:
|
||||||
ticket_count = None
|
ticket_count = None
|
||||||
if ticket_count is not None and ticket_count < self._price:
|
if ticket_count is not None and ticket_count < self._price:
|
||||||
# gettickets.show_get_tickets_prompt()
|
|
||||||
print('FIXME - show not-enough-tickets msg')
|
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notEnoughTicketsText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
|
# gettickets.show_get_tickets_prompt()
|
||||||
return
|
return
|
||||||
|
|
||||||
def do_it() -> None:
|
def do_it() -> None:
|
||||||
|
|||||||
@ -53,24 +53,25 @@ class ResourceTypeInfoWindow(PopupWindow):
|
|||||||
iconscale=1.2,
|
iconscale=1.2,
|
||||||
)
|
)
|
||||||
|
|
||||||
yoffs = self._height - 150
|
yoffs = self._height - 145
|
||||||
|
|
||||||
if resource_type == 'tickets':
|
if resource_type == 'tickets':
|
||||||
rdesc = (
|
rdesc = (
|
||||||
'Tickets can be used to unlock characters,\n'
|
'Tickets can be used to unlock characters,\n'
|
||||||
'maps, minigames, and more in the store.\n'
|
'maps, minigames, and more in the store.\n'
|
||||||
'\n'
|
'\n'
|
||||||
'Earn tickets by completing achievements\n'
|
'Tickets can be found in chests won through\n'
|
||||||
'or by opening chests won in the game.'
|
'campaigns, tournaments, and achievements.'
|
||||||
)
|
)
|
||||||
texname = 'tickets'
|
texname = 'tickets'
|
||||||
elif resource_type == 'tokens':
|
elif resource_type == 'tokens':
|
||||||
rdesc = (
|
rdesc = (
|
||||||
'Tokens have various uses in the game such as\n'
|
'Tokens are used to speed up chest unlocks\n'
|
||||||
'speeding up chest unlocks.\n'
|
'and for other game and account features.\n'
|
||||||
'\n'
|
'\n'
|
||||||
'You can buy packs of tokens or you can buy a\n'
|
'You can win tokens in the game or buy them\n'
|
||||||
'Gold Pass to get unlimited tokens.\n'
|
'in packs. Or buy a Gold Pass to get infinite\n'
|
||||||
|
'tokens forever and never hear of them again.'
|
||||||
)
|
)
|
||||||
texname = 'coin'
|
texname = 'coin'
|
||||||
elif resource_type == 'trophies':
|
elif resource_type == 'trophies':
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import logging
|
|||||||
import bauiv1 as bui
|
import bauiv1 as bui
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
from typing import Callable
|
||||||
|
|
||||||
|
|
||||||
class AllSettingsWindow(bui.MainWindow):
|
class AllSettingsWindow(bui.MainWindow):
|
||||||
@ -21,7 +21,6 @@ class AllSettingsWindow(bui.MainWindow):
|
|||||||
transition: str | None = 'in_right',
|
transition: str | None = 'in_right',
|
||||||
origin_widget: bui.Widget | None = None,
|
origin_widget: bui.Widget | None = None,
|
||||||
):
|
):
|
||||||
# pylint: disable=too-many-statements
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
|
|
||||||
# Preload some modules we use in a background thread so we won't
|
# Preload some modules we use in a background thread so we won't
|
||||||
@ -31,12 +30,12 @@ class AllSettingsWindow(bui.MainWindow):
|
|||||||
bui.set_analytics_screen('Settings Window')
|
bui.set_analytics_screen('Settings Window')
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
width = 1000 if uiscale is bui.UIScale.SMALL else 580
|
width = 1000 if uiscale is bui.UIScale.SMALL else 900
|
||||||
x_inset = 125 if uiscale is bui.UIScale.SMALL else 0
|
x_inset = 125 if uiscale is bui.UIScale.SMALL else 0
|
||||||
height = 500 if uiscale is bui.UIScale.SMALL else 435
|
height = 500 if uiscale is bui.UIScale.SMALL else 450
|
||||||
self._r = 'settingsWindow'
|
self._r = 'settingsWindow'
|
||||||
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
|
top_extra = 20 if uiscale is bui.UIScale.SMALL else 0
|
||||||
yoffs = -30 if uiscale is bui.UIScale.SMALL else 0
|
yoffs = -30 if uiscale is bui.UIScale.SMALL else -30
|
||||||
|
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@ -50,10 +49,7 @@ class AllSettingsWindow(bui.MainWindow):
|
|||||||
scale=(
|
scale=(
|
||||||
1.5
|
1.5
|
||||||
if uiscale is bui.UIScale.SMALL
|
if uiscale is bui.UIScale.SMALL
|
||||||
else 1.25 if uiscale is bui.UIScale.MEDIUM else 1.0
|
else 1.1 if uiscale is bui.UIScale.MEDIUM else 0.8
|
||||||
),
|
|
||||||
stack_offset=(
|
|
||||||
(0, 0) if uiscale is bui.UIScale.SMALL else (0, 0)
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
transition=transition,
|
transition=transition,
|
||||||
@ -69,12 +65,12 @@ class AllSettingsWindow(bui.MainWindow):
|
|||||||
self._back_button = btn = bui.buttonwidget(
|
self._back_button = btn = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
position=(40 + x_inset, height - 55 + yoffs),
|
position=(40 + x_inset, height - 60 + yoffs),
|
||||||
size=(130, 60),
|
size=(70, 70),
|
||||||
scale=0.8,
|
scale=0.8,
|
||||||
text_scale=1.2,
|
text_scale=1.2,
|
||||||
label=bui.Lstr(resource='backText'),
|
label=bui.charstr(bui.SpecialChar.BACK),
|
||||||
button_type='back',
|
button_type='backSmall',
|
||||||
on_activate_call=self.main_window_back,
|
on_activate_call=self.main_window_back,
|
||||||
)
|
)
|
||||||
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||||
@ -87,131 +83,116 @@ class AllSettingsWindow(bui.MainWindow):
|
|||||||
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',
|
||||||
|
scale=1.1,
|
||||||
maxwidth=130,
|
maxwidth=130,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._back_button is not None:
|
bwidth = 200
|
||||||
bui.buttonwidget(
|
bheight = 230
|
||||||
edit=self._back_button,
|
margin = 1
|
||||||
button_type='backSmall',
|
all_buttons_width = 4.0 * bwidth + 3.0 * margin
|
||||||
size=(60, 60),
|
|
||||||
label=bui.charstr(bui.SpecialChar.BACK),
|
x = width * 0.5 - all_buttons_width * 0.5
|
||||||
|
y = height + yoffs - 320.0
|
||||||
|
|
||||||
|
def _button(
|
||||||
|
position: tuple[float, float],
|
||||||
|
label: bui.Lstr,
|
||||||
|
call: Callable[[], None],
|
||||||
|
texture: bui.Texture,
|
||||||
|
imgsize: float,
|
||||||
|
*,
|
||||||
|
color: tuple[float, float, float] = (1.0, 1.0, 1.0),
|
||||||
|
imgoffs: tuple[float, float] = (0.0, 0.0),
|
||||||
|
) -> bui.Widget:
|
||||||
|
x, y = position
|
||||||
|
btn = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
autoselect=True,
|
||||||
|
position=(x, y),
|
||||||
|
size=(bwidth, bheight),
|
||||||
|
button_type='square',
|
||||||
|
label='',
|
||||||
|
on_activate_call=call,
|
||||||
)
|
)
|
||||||
|
|
||||||
v = height - 80 + yoffs
|
|
||||||
v -= 145
|
|
||||||
|
|
||||||
basew = 280 if uiscale is bui.UIScale.SMALL else 230
|
|
||||||
baseh = 170
|
|
||||||
x_offs = (
|
|
||||||
x_inset + (105 if uiscale is bui.UIScale.SMALL else 72) - basew
|
|
||||||
) # now unused
|
|
||||||
x_offs2 = x_offs + basew - 7
|
|
||||||
x_offs3 = x_offs + 2 * (basew - 7)
|
|
||||||
x_offs4 = x_offs2
|
|
||||||
x_offs5 = x_offs3
|
|
||||||
|
|
||||||
def _b_title(
|
|
||||||
x: float, y: float, button: bui.Widget, text: str | bui.Lstr
|
|
||||||
) -> None:
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
text=text,
|
text=label,
|
||||||
position=(x + basew * 0.47, y + baseh * 0.22),
|
position=(x + bwidth * 0.5, y + bheight * 0.25),
|
||||||
maxwidth=basew * 0.7,
|
maxwidth=bwidth * 0.7,
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
draw_controller=button,
|
draw_controller=btn,
|
||||||
color=(0.7, 0.9, 0.7, 1.0),
|
color=(0.7, 0.9, 0.7, 1.0),
|
||||||
)
|
)
|
||||||
|
bui.imagewidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(
|
||||||
|
x + bwidth * 0.5 - imgsize * 0.5 + imgoffs[0],
|
||||||
|
y + bheight * 0.56 - imgsize * 0.5 + imgoffs[1],
|
||||||
|
),
|
||||||
|
size=(imgsize, imgsize),
|
||||||
|
texture=texture,
|
||||||
|
draw_controller=btn,
|
||||||
|
color=color,
|
||||||
|
)
|
||||||
|
return btn
|
||||||
|
|
||||||
ctb = self._controllers_button = bui.buttonwidget(
|
self._controllers_button = _button(
|
||||||
parent=self._root_widget,
|
position=(x, y),
|
||||||
autoselect=True,
|
label=bui.Lstr(resource=f'{self._r}.controllersText'),
|
||||||
position=(x_offs2, v),
|
call=self._do_controllers,
|
||||||
size=(basew, baseh),
|
|
||||||
button_type='square',
|
|
||||||
label='',
|
|
||||||
on_activate_call=self._do_controllers,
|
|
||||||
)
|
|
||||||
if self._back_button is None:
|
|
||||||
bbtn = bui.get_special_widget('back_button')
|
|
||||||
bui.widget(edit=ctb, left_widget=bbtn)
|
|
||||||
_b_title(
|
|
||||||
x_offs2, v, ctb, bui.Lstr(resource=f'{self._r}.controllersText')
|
|
||||||
)
|
|
||||||
imgw = imgh = 130
|
|
||||||
bui.imagewidget(
|
|
||||||
parent=self._root_widget,
|
|
||||||
position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35),
|
|
||||||
size=(imgw, imgh),
|
|
||||||
texture=bui.gettexture('controllerIcon'),
|
texture=bui.gettexture('controllerIcon'),
|
||||||
draw_controller=ctb,
|
imgsize=150,
|
||||||
|
imgoffs=(-2.0, 2.0),
|
||||||
)
|
)
|
||||||
|
x += bwidth + margin
|
||||||
|
|
||||||
gfxb = self._graphics_button = bui.buttonwidget(
|
self._graphics_button = _button(
|
||||||
parent=self._root_widget,
|
position=(x, y),
|
||||||
autoselect=True,
|
label=bui.Lstr(resource=f'{self._r}.graphicsText'),
|
||||||
position=(x_offs3, v),
|
call=self._do_graphics,
|
||||||
size=(basew, baseh),
|
|
||||||
button_type='square',
|
|
||||||
label='',
|
|
||||||
on_activate_call=self._do_graphics,
|
|
||||||
)
|
|
||||||
pbtn = bui.get_special_widget('squad_button')
|
|
||||||
bui.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn)
|
|
||||||
_b_title(x_offs3, v, gfxb, bui.Lstr(resource=f'{self._r}.graphicsText'))
|
|
||||||
imgw = imgh = 110
|
|
||||||
bui.imagewidget(
|
|
||||||
parent=self._root_widget,
|
|
||||||
position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42),
|
|
||||||
size=(imgw, imgh),
|
|
||||||
texture=bui.gettexture('graphicsIcon'),
|
texture=bui.gettexture('graphicsIcon'),
|
||||||
draw_controller=gfxb,
|
imgsize=135,
|
||||||
|
imgoffs=(0, 4.0),
|
||||||
)
|
)
|
||||||
|
x += bwidth + margin
|
||||||
|
|
||||||
v -= baseh - 5
|
self._audio_button = _button(
|
||||||
|
position=(x, y),
|
||||||
abtn = self._audio_button = bui.buttonwidget(
|
label=bui.Lstr(resource=f'{self._r}.audioText'),
|
||||||
parent=self._root_widget,
|
call=self._do_audio,
|
||||||
autoselect=True,
|
|
||||||
position=(x_offs4, v),
|
|
||||||
size=(basew, baseh),
|
|
||||||
button_type='square',
|
|
||||||
label='',
|
|
||||||
on_activate_call=self._do_audio,
|
|
||||||
)
|
|
||||||
_b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText'))
|
|
||||||
imgw = imgh = 120
|
|
||||||
bui.imagewidget(
|
|
||||||
parent=self._root_widget,
|
|
||||||
position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5, v + 35),
|
|
||||||
size=(imgw, imgh),
|
|
||||||
color=(1, 1, 0),
|
|
||||||
texture=bui.gettexture('audioIcon'),
|
texture=bui.gettexture('audioIcon'),
|
||||||
draw_controller=abtn,
|
imgsize=150,
|
||||||
|
color=(1, 1, 0),
|
||||||
|
)
|
||||||
|
x += bwidth + margin
|
||||||
|
|
||||||
|
self._advanced_button = _button(
|
||||||
|
position=(x, y),
|
||||||
|
label=bui.Lstr(resource=f'{self._r}.advancedText'),
|
||||||
|
call=self._do_advanced,
|
||||||
|
texture=bui.gettexture('advancedIcon'),
|
||||||
|
imgsize=150,
|
||||||
|
color=(0.8, 0.95, 1),
|
||||||
|
imgoffs=(0, 5.0),
|
||||||
)
|
)
|
||||||
|
|
||||||
avb = self._advanced_button = bui.buttonwidget(
|
# Hmm; we're now wide enough that being limited to pressing up
|
||||||
parent=self._root_widget,
|
# might be ok.
|
||||||
autoselect=True,
|
if bool(False):
|
||||||
position=(x_offs5, v),
|
# Left from our leftmost button should go to back button.
|
||||||
size=(basew, baseh),
|
if self._back_button is None:
|
||||||
button_type='square',
|
bbtn = bui.get_special_widget('back_button')
|
||||||
label='',
|
bui.widget(edit=self._controllers_button, left_widget=bbtn)
|
||||||
on_activate_call=self._do_advanced,
|
|
||||||
)
|
# Right from our rightmost widget should go to squad button.
|
||||||
_b_title(x_offs5, v, avb, bui.Lstr(resource=f'{self._r}.advancedText'))
|
bui.widget(
|
||||||
imgw = imgh = 120
|
edit=self._advanced_button,
|
||||||
bui.imagewidget(
|
right_widget=bui.get_special_widget('squad_button'),
|
||||||
parent=self._root_widget,
|
)
|
||||||
position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5, v + 35),
|
|
||||||
size=(imgw, imgh),
|
|
||||||
color=(0.8, 0.95, 1),
|
|
||||||
texture=bui.gettexture('advancedIcon'),
|
|
||||||
draw_controller=avb,
|
|
||||||
)
|
|
||||||
self._restore_state()
|
self._restore_state()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -34,7 +34,10 @@ class AudioSettingsWindow(bui.MainWindow):
|
|||||||
|
|
||||||
spacing = 50.0
|
spacing = 50.0
|
||||||
width = 460.0
|
width = 460.0
|
||||||
height = 210.0
|
height = 240.0
|
||||||
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
|
||||||
|
yoffs = -5.0
|
||||||
|
|
||||||
# Update: hard-coding head-relative audio to true now,
|
# Update: hard-coding head-relative audio to true now,
|
||||||
# so not showing options.
|
# so not showing options.
|
||||||
@ -49,11 +52,10 @@ class AudioSettingsWindow(bui.MainWindow):
|
|||||||
show_soundtracks = True
|
show_soundtracks = True
|
||||||
height += spacing * 2.0
|
height += spacing * 2.0
|
||||||
|
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
|
||||||
base_scale = (
|
base_scale = (
|
||||||
2.05
|
1.9
|
||||||
if uiscale is bui.UIScale.SMALL
|
if uiscale is bui.UIScale.SMALL
|
||||||
else 1.6 if uiscale is bui.UIScale.MEDIUM else 1.0
|
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
|
||||||
)
|
)
|
||||||
popup_menu_scale = base_scale * 1.2
|
popup_menu_scale = base_scale * 1.2
|
||||||
|
|
||||||
@ -61,9 +63,6 @@ class AudioSettingsWindow(bui.MainWindow):
|
|||||||
root_widget=bui.containerwidget(
|
root_widget=bui.containerwidget(
|
||||||
size=(width, height),
|
size=(width, height),
|
||||||
scale=base_scale,
|
scale=base_scale,
|
||||||
stack_offset=(
|
|
||||||
(0, -20) if uiscale is bui.UIScale.SMALL else (0, 0)
|
|
||||||
),
|
|
||||||
toolbar_visibility=(
|
toolbar_visibility=(
|
||||||
None if uiscale is bui.UIScale.SMALL else 'menu_full'
|
None if uiscale is bui.UIScale.SMALL else 'menu_full'
|
||||||
),
|
),
|
||||||
@ -74,21 +73,20 @@ class AudioSettingsWindow(bui.MainWindow):
|
|||||||
|
|
||||||
self._back_button = back_button = btn = bui.buttonwidget(
|
self._back_button = back_button = btn = bui.buttonwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(35, height - 55),
|
position=(35, height + yoffs - 55),
|
||||||
size=(120, 60),
|
size=(60, 60),
|
||||||
scale=0.8,
|
scale=0.8,
|
||||||
text_scale=1.2,
|
text_scale=1.2,
|
||||||
label=bui.Lstr(resource='backText'),
|
label=bui.charstr(bui.SpecialChar.BACK),
|
||||||
button_type='back',
|
button_type='backSmall',
|
||||||
on_activate_call=self.main_window_back,
|
on_activate_call=self.main_window_back,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
)
|
)
|
||||||
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||||
v = height - 60
|
|
||||||
v -= spacing * 1.0
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(width * 0.5, height - 32),
|
position=(width * 0.5, height + yoffs - 32),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
text=bui.Lstr(resource=f'{self._r}.titleText'),
|
text=bui.Lstr(resource=f'{self._r}.titleText'),
|
||||||
color=bui.app.ui_v1.title_color,
|
color=bui.app.ui_v1.title_color,
|
||||||
@ -97,12 +95,8 @@ class AudioSettingsWindow(bui.MainWindow):
|
|||||||
v_align='center',
|
v_align='center',
|
||||||
)
|
)
|
||||||
|
|
||||||
bui.buttonwidget(
|
v = height + yoffs - 60
|
||||||
edit=self._back_button,
|
v -= spacing * 1.0
|
||||||
button_type='backSmall',
|
|
||||||
size=(60, 60),
|
|
||||||
label=bui.charstr(bui.SpecialChar.BACK),
|
|
||||||
)
|
|
||||||
|
|
||||||
self._sound_volume_numedit = svne = ConfigNumberEdit(
|
self._sound_volume_numedit = svne = ConfigNumberEdit(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
|
|||||||
@ -141,11 +141,11 @@ class StoreBrowserWindow(bui.MainWindow):
|
|||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
position=(
|
position=(
|
||||||
self._width * 0.5,
|
self._width * 0.5,
|
||||||
self._height - (53 if uiscale is bui.UIScale.SMALL else 44),
|
self._height - (55 if uiscale is bui.UIScale.SMALL else 44),
|
||||||
),
|
),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
color=app.ui_v1.title_color,
|
color=app.ui_v1.title_color,
|
||||||
scale=1.5,
|
scale=1.1 if uiscale is bui.UIScale.SMALL else 1.5,
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
text=bui.Lstr(resource='storeText'),
|
text=bui.Lstr(resource='storeText'),
|
||||||
@ -536,7 +536,10 @@ class StoreBrowserWindow(bui.MainWindow):
|
|||||||
our_tickets = plus.get_v1_account_ticket_count()
|
our_tickets = plus.get_v1_account_ticket_count()
|
||||||
if price is not None and our_tickets < price:
|
if price is not None and our_tickets < price:
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
print('FIXME - show not-enough-tickets info.')
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notEnoughTicketsText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
# gettickets.show_get_tickets_prompt()
|
# gettickets.show_get_tickets_prompt()
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,8 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
|
|
||||||
|
from bauiv1lib.coop.tournamentbutton import USE_ENTRY_FEES
|
||||||
|
|
||||||
assert bui.app.classic is not None
|
assert bui.app.classic is not None
|
||||||
assert bui.app.plus
|
assert bui.app.plus
|
||||||
bui.set_analytics_screen('Tournament Entry Window')
|
bui.set_analytics_screen('Tournament Entry Window')
|
||||||
@ -42,9 +44,15 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
self._tournament_id
|
self._tournament_id
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self._purchase_name: str | None
|
||||||
|
self._purchase_price_name: str | None
|
||||||
|
|
||||||
# Set a few vars depending on the tourney fee.
|
# Set a few vars depending on the tourney fee.
|
||||||
self._fee = self._tournament_info['fee']
|
self._fee = self._tournament_info['fee']
|
||||||
self._allow_ads = self._tournament_info['allowAds']
|
assert isinstance(self._fee, int | None)
|
||||||
|
self._allow_ads = (
|
||||||
|
self._tournament_info['allowAds'] if USE_ENTRY_FEES else False
|
||||||
|
)
|
||||||
if self._fee == 4:
|
if self._fee == 4:
|
||||||
self._purchase_name = 'tournament_entry_4'
|
self._purchase_name = 'tournament_entry_4'
|
||||||
self._purchase_price_name = 'price.tournament_entry_4'
|
self._purchase_price_name = 'price.tournament_entry_4'
|
||||||
@ -57,6 +65,9 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
elif self._fee == 1:
|
elif self._fee == 1:
|
||||||
self._purchase_name = 'tournament_entry_1'
|
self._purchase_name = 'tournament_entry_1'
|
||||||
self._purchase_price_name = 'price.tournament_entry_1'
|
self._purchase_price_name = 'price.tournament_entry_1'
|
||||||
|
elif self._fee is None or self._fee == -1:
|
||||||
|
self._purchase_name = None
|
||||||
|
self._purchase_price_name = 'FREE-WOOT'
|
||||||
else:
|
else:
|
||||||
if self._fee != 0:
|
if self._fee != 0:
|
||||||
raise ValueError('invalid fee: ' + str(self._fee))
|
raise ValueError('invalid fee: ' + str(self._fee))
|
||||||
@ -218,7 +229,7 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
scale=0.6,
|
scale=0.6,
|
||||||
# Note: AdMob now requires rewarded ad usage
|
# Note to self: AdMob requires rewarded ad usage
|
||||||
# specifically says 'Ad' in it.
|
# specifically says 'Ad' in it.
|
||||||
text=bui.Lstr(resource='watchAnAdText'),
|
text=bui.Lstr(resource='watchAnAdText'),
|
||||||
maxwidth=95,
|
maxwidth=95,
|
||||||
@ -439,29 +450,52 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Keep price up-to-date and update the button with it.
|
# Keep price up-to-date and update the button with it.
|
||||||
self._purchase_price = plus.get_v1_account_misc_read_val(
|
if self._purchase_price_name is not None:
|
||||||
self._purchase_price_name, None
|
self._purchase_price = (
|
||||||
)
|
0
|
||||||
|
if self._purchase_price_name == 'FREE-WOOT'
|
||||||
|
else plus.get_v1_account_misc_read_val(
|
||||||
|
self._purchase_price_name, None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# HACK - this is always free now, so just have this say 'PLAY'
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self._ticket_cost_text,
|
edit=self._ticket_cost_text,
|
||||||
text=(
|
text=(
|
||||||
bui.Lstr(resource='getTicketsWindow.freeText')
|
bui.Lstr(resource='playText')
|
||||||
if self._purchase_price == 0
|
# if self._purchase_price == 0
|
||||||
else bui.Lstr(
|
# else bui.Lstr(
|
||||||
resource='getTicketsWindow.ticketsText',
|
# resource='getTicketsWindow.ticketsText',
|
||||||
subs=[
|
# subs=[
|
||||||
(
|
# (
|
||||||
'${COUNT}',
|
# '${COUNT}',
|
||||||
(
|
# (
|
||||||
str(self._purchase_price)
|
# str(self._purchase_price)
|
||||||
if self._purchase_price is not None
|
# if self._purchase_price is not None
|
||||||
else '?'
|
# else '?'
|
||||||
),
|
# ),
|
||||||
)
|
# )
|
||||||
],
|
# ],
|
||||||
)
|
# )
|
||||||
),
|
),
|
||||||
|
# text=(
|
||||||
|
# bui.Lstr(resource='getTicketsWindow.freeText')
|
||||||
|
# if self._purchase_price == 0
|
||||||
|
# else bui.Lstr(
|
||||||
|
# resource='getTicketsWindow.ticketsText',
|
||||||
|
# subs=[
|
||||||
|
# (
|
||||||
|
# '${COUNT}',
|
||||||
|
# (
|
||||||
|
# str(self._purchase_price)
|
||||||
|
# if self._purchase_price is not None
|
||||||
|
# else '?'
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
|
# ],
|
||||||
|
# )
|
||||||
|
# ),
|
||||||
position=(
|
position=(
|
||||||
self._ticket_cost_text_position_free
|
self._ticket_cost_text_position_free
|
||||||
if self._purchase_price == 0
|
if self._purchase_price == 0
|
||||||
@ -472,19 +506,20 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
|
|
||||||
bui.textwidget(
|
bui.textwidget(
|
||||||
edit=self._free_plays_remaining_text,
|
edit=self._free_plays_remaining_text,
|
||||||
text=(
|
# text=(
|
||||||
''
|
# ''
|
||||||
if (
|
# if (
|
||||||
self._tournament_info['freeTriesRemaining'] in [None, 0]
|
# self._tournament_info['freeTriesRemaining'] in [None, 0]
|
||||||
or self._purchase_price != 0
|
# or self._purchase_price != 0
|
||||||
)
|
# )
|
||||||
else '' + str(self._tournament_info['freeTriesRemaining'])
|
# else '' + str(self._tournament_info['freeTriesRemaining'])
|
||||||
),
|
# ),
|
||||||
|
text='', # No longer relevant.
|
||||||
)
|
)
|
||||||
|
|
||||||
bui.imagewidget(
|
bui.imagewidget(
|
||||||
edit=self._ticket_img,
|
edit=self._ticket_img,
|
||||||
opacity=0.2 if self._purchase_price == 0 else 1.0,
|
opacity=0.0 if self._purchase_price == 0 else 1.0,
|
||||||
position=(
|
position=(
|
||||||
self._ticket_img_pos_free
|
self._ticket_img_pos_free
|
||||||
if self._purchase_price == 0
|
if self._purchase_price == 0
|
||||||
@ -547,15 +582,16 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
self._launched = True
|
self._launched = True
|
||||||
launched = False
|
launched = False
|
||||||
|
|
||||||
# If they gave us an existing, non-consistent
|
# If they gave us an existing, non-consistent practice activity,
|
||||||
# practice activity, just restart it.
|
# just restart it.
|
||||||
if (
|
if (
|
||||||
self._tournament_activity is not None
|
self._tournament_activity is not None
|
||||||
and not practice == self._tournament_activity.session.submit_score
|
and not practice == self._tournament_activity.session.submit_score
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
if not practice:
|
if not practice:
|
||||||
bui.apptimer(0.1, bui.getsound('cashRegister').play)
|
bui.apptimer(0.1, bui.getsound('drumRollShort').play)
|
||||||
|
# bui.apptimer(0.1, bui.getsound('cashRegister').play)
|
||||||
bui.screenmessage(
|
bui.screenmessage(
|
||||||
bui.Lstr(
|
bui.Lstr(
|
||||||
translate=(
|
translate=(
|
||||||
@ -584,7 +620,8 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
# launch a new session.
|
# launch a new session.
|
||||||
if not launched:
|
if not launched:
|
||||||
if not practice:
|
if not practice:
|
||||||
bui.apptimer(0.1, bui.getsound('cashRegister').play)
|
bui.apptimer(0.1, bui.getsound('drumRollShort').play)
|
||||||
|
# bui.apptimer(0.1, bui.getsound('cashRegister').play)
|
||||||
bui.screenmessage(
|
bui.screenmessage(
|
||||||
bui.Lstr(
|
bui.Lstr(
|
||||||
translate=('serverResponses', 'Entering tournament...')
|
translate=('serverResponses', 'Entering tournament...')
|
||||||
@ -653,16 +690,21 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
ticket_count = None
|
ticket_count = None
|
||||||
ticket_cost = self._purchase_price
|
ticket_cost = self._purchase_price
|
||||||
if ticket_count is not None and ticket_count < ticket_cost:
|
if ticket_count is not None and ticket_count < ticket_cost:
|
||||||
# gettickets.show_get_tickets_prompt()
|
|
||||||
print('FIXME - show not-enough-tickets msg.')
|
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
|
bui.screenmessage(
|
||||||
|
bui.Lstr(resource='notEnoughTicketsText'),
|
||||||
|
color=(1, 0, 0),
|
||||||
|
)
|
||||||
|
# gettickets.show_get_tickets_prompt()
|
||||||
self._transition_out()
|
self._transition_out()
|
||||||
return
|
return
|
||||||
|
|
||||||
cur_time = bui.apptime()
|
cur_time = bui.apptime()
|
||||||
self._last_ticket_press_time = cur_time
|
self._last_ticket_press_time = cur_time
|
||||||
assert isinstance(ticket_cost, int)
|
|
||||||
plus.in_game_purchase(self._purchase_name, ticket_cost)
|
if self._purchase_name is not None:
|
||||||
|
assert isinstance(ticket_cost, int)
|
||||||
|
plus.in_game_purchase(self._purchase_name, ticket_cost)
|
||||||
|
|
||||||
self._entering = True
|
self._entering = True
|
||||||
plus.add_v1_account_transaction(
|
plus.add_v1_account_transaction(
|
||||||
@ -759,30 +801,20 @@ class TournamentEntryWindow(PopupWindow):
|
|||||||
plus.run_v1_account_transactions()
|
plus.run_v1_account_transactions()
|
||||||
self._launch()
|
self._launch()
|
||||||
|
|
||||||
# def _on_get_tickets_press(self) -> None:
|
|
||||||
# from bauiv1lib import gettickets
|
|
||||||
|
|
||||||
# # If we're already entering, ignore presses.
|
|
||||||
# if self._entering:
|
|
||||||
# return
|
|
||||||
|
|
||||||
# # Bring up get-tickets window and then kill ourself (we're on the
|
|
||||||
# # overlay layer so we'd show up above it).
|
|
||||||
# gettickets.GetTicketsWindow(
|
|
||||||
# modal=True, origin_widget=self._get_tickets_button
|
|
||||||
# )
|
|
||||||
# self._transition_out()
|
|
||||||
|
|
||||||
def _on_cancel(self) -> None:
|
def _on_cancel(self) -> None:
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
# Don't allow canceling for several seconds after poking an enter
|
# Don't allow canceling for several seconds after poking an enter
|
||||||
# button if it looks like we're waiting on a purchase or entering
|
# button if it looks like we're waiting on a purchase or entering
|
||||||
# the tournament.
|
# the tournament.
|
||||||
if (bui.apptime() - self._last_ticket_press_time < 6.0) and (
|
if (
|
||||||
plus.have_outstanding_v1_account_transactions()
|
(bui.apptime() - self._last_ticket_press_time < 6.0)
|
||||||
or plus.get_v1_account_product_purchased(self._purchase_name)
|
and self._purchase_name is not None
|
||||||
or self._entering
|
and (
|
||||||
|
plus.have_outstanding_v1_account_transactions()
|
||||||
|
or plus.get_v1_account_product_purchased(self._purchase_name)
|
||||||
|
or self._entering
|
||||||
|
)
|
||||||
):
|
):
|
||||||
bui.getsound('error').play()
|
bui.getsound('error').play()
|
||||||
return
|
return
|
||||||
|
|||||||
@ -138,7 +138,7 @@ auto AppAdapterApple::TryRender() -> bool {
|
|||||||
|
|
||||||
// Keep on drawing until the drawn window size
|
// Keep on drawing until the drawn window size
|
||||||
// matches what we have (or until we try for too long or fail at drawing).
|
// matches what we have (or until we try for too long or fail at drawing).
|
||||||
seconds_t start_time = g_core->GetAppTimeSeconds();
|
seconds_t start_time = g_core->AppTimeSeconds();
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
bool size_differs =
|
bool size_differs =
|
||||||
((std::abs(resize_target_resolution_.x
|
((std::abs(resize_target_resolution_.x
|
||||||
@ -147,7 +147,7 @@ auto AppAdapterApple::TryRender() -> bool {
|
|||||||
|| (std::abs(resize_target_resolution_.y
|
|| (std::abs(resize_target_resolution_.y
|
||||||
- g_base->graphics_server->screen_pixel_height())
|
- g_base->graphics_server->screen_pixel_height())
|
||||||
> 0.01f));
|
> 0.01f));
|
||||||
if (size_differs && g_core->GetAppTimeSeconds() - start_time < 0.1
|
if (size_differs && g_core->AppTimeSeconds() - start_time < 0.1
|
||||||
&& result) {
|
&& result) {
|
||||||
result = g_base->graphics_server->TryRender();
|
result = g_base->graphics_server->TryRender();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -210,7 +210,7 @@ void AppAdapterSDL::RunMainThreadEventLoopToCompletion() {
|
|||||||
assert(g_core->InMainThread());
|
assert(g_core->InMainThread());
|
||||||
|
|
||||||
while (!done_) {
|
while (!done_) {
|
||||||
microsecs_t cycle_start_time = g_core->GetAppTimeMicrosecs();
|
microsecs_t cycle_start_time = g_core->AppTimeMicrosecs();
|
||||||
|
|
||||||
// Events.
|
// Events.
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@ -274,7 +274,7 @@ void AppAdapterSDL::SleepUntilNextEventCycle_(microsecs_t cycle_start_time) {
|
|||||||
|
|
||||||
// Normally we just calc when our next draw should happen and sleep 'til
|
// Normally we just calc when our next draw should happen and sleep 'til
|
||||||
// then.
|
// then.
|
||||||
microsecs_t now = g_core->GetAppTimeMicrosecs();
|
microsecs_t now = g_core->AppTimeMicrosecs();
|
||||||
auto used_max_fps = max_fps_;
|
auto used_max_fps = max_fps_;
|
||||||
millisecs_t millisecs_per_frame = 1000000 / used_max_fps;
|
millisecs_t millisecs_per_frame = 1000000 / used_max_fps;
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ void AppAdapterSDL::SleepUntilNextEventCycle_(microsecs_t cycle_start_time) {
|
|||||||
// Maintain an 'oversleep' amount to compensate for the timer not being
|
// Maintain an 'oversleep' amount to compensate for the timer not being
|
||||||
// exact. This should keep us exactly at our target frame-rate in the
|
// exact. This should keep us exactly at our target frame-rate in the
|
||||||
// end.
|
// end.
|
||||||
now = g_core->GetAppTimeMicrosecs();
|
now = g_core->AppTimeMicrosecs();
|
||||||
oversleep_ = now - target_time;
|
oversleep_ = now - target_time;
|
||||||
|
|
||||||
// Prevent oversleep from compensating by more than a few millisecs per
|
// Prevent oversleep from compensating by more than a few millisecs per
|
||||||
@ -438,7 +438,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
if (g_core->GetAppTimeSeconds() - last_windowevent_close_time_ < 0.1) {
|
if (g_core->AppTimeSeconds() - last_windowevent_close_time_ < 0.1) {
|
||||||
// If they hit the window close button, skip the confirm.
|
// If they hit the window close button, skip the confirm.
|
||||||
g_base->QuitApp(false);
|
g_base->QuitApp(false);
|
||||||
} else {
|
} else {
|
||||||
@ -459,7 +459,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
|
|||||||
case SDL_WINDOWEVENT_CLOSE: {
|
case SDL_WINDOWEVENT_CLOSE: {
|
||||||
// Simply note that this happened. We use this to adjust our
|
// Simply note that this happened. We use this to adjust our
|
||||||
// SDL_QUIT behavior (quit is called right after this).
|
// SDL_QUIT behavior (quit is called right after this).
|
||||||
last_windowevent_close_time_ = g_core->GetAppTimeSeconds();
|
last_windowevent_close_time_ = g_core->AppTimeSeconds();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace ballistica::base {
|
|||||||
Asset::Asset() {
|
Asset::Asset() {
|
||||||
assert(g_base);
|
assert(g_base);
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
last_used_time_ = g_core->GetAppTimeMillisecs();
|
last_used_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Asset::AssetTypeName(AssetType assettype) -> const char* {
|
auto Asset::AssetTypeName(AssetType assettype) -> const char* {
|
||||||
@ -65,9 +65,9 @@ void Asset::Preload(bool already_locked) {
|
|||||||
return std::string("preloading ") + AssetTypeName(GetAssetType()) + " "
|
return std::string("preloading ") + AssetTypeName(GetAssetType()) + " "
|
||||||
+ GetName();
|
+ GetName();
|
||||||
});
|
});
|
||||||
preload_start_time_ = g_core->GetAppTimeMillisecs();
|
preload_start_time_ = g_core->AppTimeMillisecs();
|
||||||
DoPreload();
|
DoPreload();
|
||||||
preload_end_time_ = g_core->GetAppTimeMillisecs();
|
preload_end_time_ = g_core->AppTimeMillisecs();
|
||||||
preloaded_ = true;
|
preloaded_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,9 +87,9 @@ void Asset::Load(bool already_locked) {
|
|||||||
return std::string("loading ") + AssetTypeName(GetAssetType()) + " "
|
return std::string("loading ") + AssetTypeName(GetAssetType()) + " "
|
||||||
+ GetName();
|
+ GetName();
|
||||||
});
|
});
|
||||||
load_start_time_ = g_core->GetAppTimeMillisecs();
|
load_start_time_ = g_core->AppTimeMillisecs();
|
||||||
DoLoad();
|
DoLoad();
|
||||||
load_end_time_ = g_core->GetAppTimeMillisecs();
|
load_end_time_ = g_core->AppTimeMillisecs();
|
||||||
BA_DEBUG_FUNCTION_TIMER_END_THREAD_EX(50, GetName());
|
BA_DEBUG_FUNCTION_TIMER_END_THREAD_EX(50, GetName());
|
||||||
loaded_ = true;
|
loaded_ = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -165,6 +165,7 @@ void Assets::StartLoading() {
|
|||||||
LoadSystemTexture(SysTextureID::kCharacterIconMask, "characterIconMask");
|
LoadSystemTexture(SysTextureID::kCharacterIconMask, "characterIconMask");
|
||||||
LoadSystemTexture(SysTextureID::kBlack, "black");
|
LoadSystemTexture(SysTextureID::kBlack, "black");
|
||||||
LoadSystemTexture(SysTextureID::kWings, "wings");
|
LoadSystemTexture(SysTextureID::kWings, "wings");
|
||||||
|
LoadSystemTexture(SysTextureID::kSpinner, "spinner");
|
||||||
|
|
||||||
// System cube map textures:
|
// System cube map textures:
|
||||||
LoadSystemCubeMapTexture(SysCubeMapTextureID::kReflectionChar,
|
LoadSystemCubeMapTexture(SysCubeMapTextureID::kReflectionChar,
|
||||||
@ -479,7 +480,7 @@ auto Assets::GetAsset(const std::string& file_name,
|
|||||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||||
MarkAssetForLoad(d.get());
|
MarkAssetForLoad(d.get());
|
||||||
}
|
}
|
||||||
d->set_last_used_time(g_core->GetAppTimeMillisecs());
|
d->set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
return Object::Ref<T>(d);
|
return Object::Ref<T>(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -499,7 +500,7 @@ auto Assets::GetTexture(TextPacker* packer) -> Object::Ref<TextureAsset> {
|
|||||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||||
MarkAssetForLoad(d.get());
|
MarkAssetForLoad(d.get());
|
||||||
}
|
}
|
||||||
d->set_last_used_time(g_core->GetAppTimeMillisecs());
|
d->set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
return Object::Ref<TextureAsset>(d);
|
return Object::Ref<TextureAsset>(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -519,7 +520,7 @@ auto Assets::GetQRCodeTexture(const std::string& url)
|
|||||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||||
MarkAssetForLoad(d.get());
|
MarkAssetForLoad(d.get());
|
||||||
}
|
}
|
||||||
d->set_last_used_time(g_core->GetAppTimeMillisecs());
|
d->set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
return Object::Ref<TextureAsset>(d);
|
return Object::Ref<TextureAsset>(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,7 +543,7 @@ auto Assets::GetCubeMapTexture(const std::string& file_name)
|
|||||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||||
MarkAssetForLoad(d.get());
|
MarkAssetForLoad(d.get());
|
||||||
}
|
}
|
||||||
d->set_last_used_time(g_core->GetAppTimeMillisecs());
|
d->set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
return Object::Ref<TextureAsset>(d);
|
return Object::Ref<TextureAsset>(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -598,7 +599,7 @@ auto Assets::GetTexture(const std::string& file_name)
|
|||||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||||
MarkAssetForLoad(d.get());
|
MarkAssetForLoad(d.get());
|
||||||
}
|
}
|
||||||
d->set_last_used_time(g_core->GetAppTimeMillisecs());
|
d->set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
return Object::Ref<TextureAsset>(d);
|
return Object::Ref<TextureAsset>(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -750,7 +751,7 @@ auto Assets::RunPendingLoadsLogicThread() -> bool {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
||||||
bool flush = false;
|
bool flush = false;
|
||||||
millisecs_t starttime = g_core->GetAppTimeMillisecs();
|
millisecs_t starttime = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
std::vector<Object::Ref<T>*> l;
|
std::vector<Object::Ref<T>*> l;
|
||||||
std::vector<Object::Ref<T>*> l_unfinished;
|
std::vector<Object::Ref<T>*> l_unfinished;
|
||||||
@ -760,8 +761,7 @@ auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
|||||||
|
|
||||||
// If we're already out of time.
|
// If we're already out of time.
|
||||||
if (!flush
|
if (!flush
|
||||||
&& g_core->GetAppTimeMillisecs() - starttime
|
&& g_core->AppTimeMillisecs() - starttime > PENDING_LOAD_PROCESS_TIME) {
|
||||||
> PENDING_LOAD_PROCESS_TIME) {
|
|
||||||
bool return_val = (!c_list->empty());
|
bool return_val = (!c_list->empty());
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
@ -790,8 +790,7 @@ auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
|||||||
// If the load finished, pop it on our "done-loading" list.. otherwise
|
// If the load finished, pop it on our "done-loading" list.. otherwise
|
||||||
// keep it around.
|
// keep it around.
|
||||||
l_finished.push_back(*i); // else l_unfinished.push_back(*i);
|
l_finished.push_back(*i); // else l_unfinished.push_back(*i);
|
||||||
if (g_core->GetAppTimeMillisecs() - starttime
|
if (g_core->AppTimeMillisecs() - starttime > PENDING_LOAD_PROCESS_TIME
|
||||||
> PENDING_LOAD_PROCESS_TIME
|
|
||||||
&& !flush) {
|
&& !flush) {
|
||||||
out_of_time = true;
|
out_of_time = true;
|
||||||
}
|
}
|
||||||
@ -832,7 +831,7 @@ auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
|||||||
|
|
||||||
void Assets::Prune(int level) {
|
void Assets::Prune(int level) {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
millisecs_t current_time = g_core->GetAppTimeMillisecs();
|
millisecs_t current_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Need lists locked while accessing/modifying them.
|
// Need lists locked while accessing/modifying them.
|
||||||
AssetListLock lock;
|
AssetListLock lock;
|
||||||
@ -1168,11 +1167,11 @@ auto Assets::FindAssetFile(FileType type, const std::string& name)
|
|||||||
// We wanna fail gracefully for some types.
|
// We wanna fail gracefully for some types.
|
||||||
if (type == FileType::kSound && name != "blank") {
|
if (type == FileType::kSound && name != "blank") {
|
||||||
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
||||||
"Unable to load audio: '" + name + "'; trying fallback...");
|
"Unable to load audio: '" + name + "'.");
|
||||||
return FindAssetFile(type, "blank");
|
return FindAssetFile(type, "blank");
|
||||||
} else if (type == FileType::kTexture && name != "white") {
|
} else if (type == FileType::kTexture && name != "white") {
|
||||||
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
||||||
"Unable to load texture: '" + name + "'; trying fallback...");
|
"Unable to load texture: '" + name + "'.");
|
||||||
return FindAssetFile(type, "white");
|
return FindAssetFile(type, "white");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,8 +1559,8 @@ auto DoCompileResourceString(cJSON* obj) -> std::string {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Assets::CompileResourceString(const std::string& s, const std::string& loc,
|
auto Assets::CompileResourceString(const std::string& s, bool* valid)
|
||||||
bool* valid) -> std::string {
|
-> std::string {
|
||||||
bool dummyvalid;
|
bool dummyvalid;
|
||||||
if (valid == nullptr) {
|
if (valid == nullptr) {
|
||||||
valid = &dummyvalid;
|
valid = &dummyvalid;
|
||||||
@ -1577,8 +1576,7 @@ auto Assets::CompileResourceString(const std::string& s, const std::string& loc,
|
|||||||
cJSON* root = cJSON_Parse(s.c_str());
|
cJSON* root = cJSON_Parse(s.c_str());
|
||||||
if (root == nullptr) {
|
if (root == nullptr) {
|
||||||
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
||||||
"CompileResourceString failed (loc " + loc
|
"CompileResourceString failed; invalid json: '" + s + "'");
|
||||||
+ "); invalid json: '" + s + "'");
|
|
||||||
*valid = false;
|
*valid = false;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1588,8 +1586,8 @@ auto Assets::CompileResourceString(const std::string& s, const std::string& loc,
|
|||||||
*valid = true;
|
*valid = true;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
g_core->Log(LogName::kBaAssets, LogLevel::kError,
|
||||||
"CompileResourceString failed (loc " + loc
|
"CompileResourceString failed: " + std::string(e.what())
|
||||||
+ "): " + std::string(e.what()) + "; str='" + s + "'");
|
+ "; str='" + s + "'");
|
||||||
result = "<error>";
|
result = "<error>";
|
||||||
*valid = false;
|
*valid = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,8 +111,8 @@ class Assets {
|
|||||||
const std::unordered_map<std::string, std::string>& language);
|
const std::unordered_map<std::string, std::string>& language);
|
||||||
auto GetResourceString(const std::string& key) -> std::string;
|
auto GetResourceString(const std::string& key) -> std::string;
|
||||||
auto CharStr(SpecialChar id) -> std::string;
|
auto CharStr(SpecialChar id) -> std::string;
|
||||||
auto CompileResourceString(const std::string& s, const std::string& loc,
|
auto CompileResourceString(const std::string& s, bool* valid = nullptr)
|
||||||
bool* valid = nullptr) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
auto sys_assets_loaded() const { return sys_assets_loaded_; }
|
auto sys_assets_loaded() const { return sys_assets_loaded_; }
|
||||||
|
|
||||||
|
|||||||
@ -324,7 +324,7 @@ void SoundAsset::DoUnload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::UpdatePlayTime() {
|
void SoundAsset::UpdatePlayTime() {
|
||||||
last_play_time_ = g_core->GetAppTimeMillisecs();
|
last_play_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ballistica::base
|
} // namespace ballistica::base
|
||||||
|
|||||||
@ -156,7 +156,7 @@ auto Audio::SourceBeginExisting(uint32_t play_id, int debug_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto Audio::ShouldPlay(SoundAsset* sound) -> bool {
|
auto Audio::ShouldPlay(SoundAsset* sound) -> bool {
|
||||||
millisecs_t time = g_core->GetAppTimeMillisecs();
|
millisecs_t time = g_core->AppTimeMillisecs();
|
||||||
assert(sound);
|
assert(sound);
|
||||||
return (time - sound->last_play_time() > 50);
|
return (time - sound->last_play_time() > 50);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,9 +212,8 @@ void AudioServer::OpenALSoftLogCallback(const std::string& msg) {
|
|||||||
std::scoped_lock lock(openalsoft_android_log_mutex_);
|
std::scoped_lock lock(openalsoft_android_log_mutex_);
|
||||||
|
|
||||||
if (openalsoft_android_log_.size() < log_cap) {
|
if (openalsoft_android_log_.size() < log_cap) {
|
||||||
openalsoft_android_log_ += "openal-log("
|
openalsoft_android_log_ +=
|
||||||
+ std::to_string(g_core->GetAppTimeSeconds())
|
"openal-log(" + std::to_string(g_core->AppTimeSeconds()) + "s): " + msg;
|
||||||
+ "s): " + msg;
|
|
||||||
if (openalsoft_android_log_.size() >= log_cap) {
|
if (openalsoft_android_log_.size() >= log_cap) {
|
||||||
openalsoft_android_log_ +=
|
openalsoft_android_log_ +=
|
||||||
"\n<max openalsoft log storage size reached>\n";
|
"\n<max openalsoft log storage size reached>\n";
|
||||||
@ -477,7 +476,7 @@ void AudioServer::OnAppStartInThread_() {
|
|||||||
// Now make available any stopped sources (should be all of them).
|
// Now make available any stopped sources (should be all of them).
|
||||||
UpdateAvailableSources_();
|
UpdateAvailableSources_();
|
||||||
|
|
||||||
last_started_playing_time_ = g_core->GetAppTimeSeconds();
|
last_started_playing_time_ = g_core->AppTimeSeconds();
|
||||||
#endif // BA_ENABLE_AUDIO
|
#endif // BA_ENABLE_AUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +486,7 @@ void AudioServer::Shutdown() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
shutting_down_ = true;
|
shutting_down_ = true;
|
||||||
shutdown_start_time_ = g_core->GetAppTimeSeconds();
|
shutdown_start_time_ = g_core->AppTimeSeconds();
|
||||||
|
|
||||||
// Stop all playing sounds and note the time. We'll then give everything a
|
// Stop all playing sounds and note the time. We'll then give everything a
|
||||||
// moment to come to a halt before we tear down the audio context to
|
// moment to come to a halt before we tear down the audio context to
|
||||||
@ -538,8 +537,8 @@ struct AudioServer::SoundFadeNode_ {
|
|||||||
bool out;
|
bool out;
|
||||||
SoundFadeNode_(uint32_t play_id_in, millisecs_t duration_in, bool out_in)
|
SoundFadeNode_(uint32_t play_id_in, millisecs_t duration_in, bool out_in)
|
||||||
: play_id(play_id_in),
|
: play_id(play_id_in),
|
||||||
starttime(g_core->GetAppTimeMillisecs()),
|
starttime(g_core->AppTimeMillisecs()),
|
||||||
endtime(g_core->GetAppTimeMillisecs() + duration_in),
|
endtime(g_core->AppTimeMillisecs() + duration_in),
|
||||||
out(out_in) {}
|
out(out_in) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -566,16 +565,16 @@ void AudioServer::SetSuspended_(bool suspend) {
|
|||||||
try {
|
try {
|
||||||
g_core->platform->LowLevelDebugLog(
|
g_core->platform->LowLevelDebugLog(
|
||||||
"Calling alcDevicePauseSOFT at "
|
"Calling alcDevicePauseSOFT at "
|
||||||
+ std::to_string(g_core->GetAppTimeSeconds()));
|
+ std::to_string(g_core->AppTimeSeconds()));
|
||||||
alcDevicePauseSOFT(device);
|
alcDevicePauseSOFT(device);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
g_core->Log(LogName::kBaAudio, LogLevel::kError,
|
g_core->Log(
|
||||||
"Error in alcDevicePauseSOFT at time "
|
LogName::kBaAudio, LogLevel::kError,
|
||||||
+ std::to_string(g_core->GetAppTimeSeconds())
|
"Error in alcDevicePauseSOFT at time "
|
||||||
+ "( playing since "
|
+ std::to_string(g_core->AppTimeSeconds()) + "( playing since "
|
||||||
+ std::to_string(last_started_playing_time_) + "): "
|
+ std::to_string(last_started_playing_time_)
|
||||||
+ g_core->platform->DemangleCXXSymbol(typeid(e).name())
|
+ "): " + g_core->platform->DemangleCXXSymbol(typeid(e).name())
|
||||||
+ " " + e.what());
|
+ " " + e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
g_core->Log(LogName::kBaAudio, LogLevel::kError,
|
g_core->Log(LogName::kBaAudio, LogLevel::kError,
|
||||||
"Unknown error in alcDevicePauseSOFT");
|
"Unknown error in alcDevicePauseSOFT");
|
||||||
@ -609,12 +608,12 @@ void AudioServer::SetSuspended_(bool suspend) {
|
|||||||
try {
|
try {
|
||||||
g_core->platform->LowLevelDebugLog(
|
g_core->platform->LowLevelDebugLog(
|
||||||
"Calling alcDeviceResumeSOFT at "
|
"Calling alcDeviceResumeSOFT at "
|
||||||
+ std::to_string(g_core->GetAppTimeSeconds()));
|
+ std::to_string(g_core->AppTimeSeconds()));
|
||||||
alcDeviceResumeSOFT(device);
|
alcDeviceResumeSOFT(device);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
g_core->Log(LogName::kBaAudio, LogLevel::kError,
|
g_core->Log(LogName::kBaAudio, LogLevel::kError,
|
||||||
"Error in alcDeviceResumeSOFT at time "
|
"Error in alcDeviceResumeSOFT at time "
|
||||||
+ std::to_string(g_core->GetAppTimeSeconds()) + ": "
|
+ std::to_string(g_core->AppTimeSeconds()) + ": "
|
||||||
+ g_core->platform->DemangleCXXSymbol(typeid(e).name())
|
+ g_core->platform->DemangleCXXSymbol(typeid(e).name())
|
||||||
+ " " + e.what());
|
+ " " + e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@ -622,7 +621,7 @@ void AudioServer::SetSuspended_(bool suspend) {
|
|||||||
"Unknown error in alcDeviceResumeSOFT");
|
"Unknown error in alcDeviceResumeSOFT");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
last_started_playing_time_ = g_core->GetAppTimeSeconds();
|
last_started_playing_time_ = g_core->AppTimeSeconds();
|
||||||
suspended_ = false;
|
suspended_ = false;
|
||||||
#if BA_ENABLE_AUDIO
|
#if BA_ENABLE_AUDIO
|
||||||
CHECK_AL_ERROR;
|
CHECK_AL_ERROR;
|
||||||
@ -774,7 +773,7 @@ void AudioServer::UpdateAvailableSources_() {
|
|||||||
// and see how many are in use, how many are currently locked by the client,
|
// and see how many are in use, how many are currently locked by the client,
|
||||||
// etc.
|
// etc.
|
||||||
#if (BA_DEBUG_BUILD || BA_TEST_BUILD)
|
#if (BA_DEBUG_BUILD || BA_TEST_BUILD)
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs();
|
millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
if (t - last_sanity_check_time_ > 5000) {
|
if (t - last_sanity_check_time_ > 5000) {
|
||||||
last_sanity_check_time_ = t;
|
last_sanity_check_time_ = t;
|
||||||
|
|
||||||
@ -1033,7 +1032,7 @@ void AudioServer::OnDeviceDisconnected() {
|
|||||||
|
|
||||||
void AudioServer::Process_() {
|
void AudioServer::Process_() {
|
||||||
assert(g_base->InAudioThread());
|
assert(g_base->InAudioThread());
|
||||||
seconds_t real_time_seconds = g_core->GetAppTimeSeconds();
|
seconds_t real_time_seconds = g_core->AppTimeSeconds();
|
||||||
millisecs_t real_time_millisecs = real_time_seconds * 1000;
|
millisecs_t real_time_millisecs = real_time_seconds * 1000;
|
||||||
|
|
||||||
// Only do real work if we're in normal running mode.
|
// Only do real work if we're in normal running mode.
|
||||||
@ -1085,7 +1084,7 @@ void AudioServer::Process_() {
|
|||||||
// for the mixer to spit out some silence so we don't hear sudden cut-offs
|
// for the mixer to spit out some silence so we don't hear sudden cut-offs
|
||||||
// in one or both ears.
|
// in one or both ears.
|
||||||
if (shutting_down_ && !shutdown_completed_) {
|
if (shutting_down_ && !shutdown_completed_) {
|
||||||
if (g_core->GetAppTimeSeconds() - shutdown_start_time_ > 0.2) {
|
if (g_core->AppTimeSeconds() - shutdown_start_time_ > 0.2) {
|
||||||
CompleteShutdown_();
|
CompleteShutdown_();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,13 +1124,13 @@ void AudioServer::ProcessSoundFades_() {
|
|||||||
|
|
||||||
AudioServer::ThreadSource_* s = GetPlayingSound_(i->second.play_id);
|
AudioServer::ThreadSource_* s = GetPlayingSound_(i->second.play_id);
|
||||||
if (s) {
|
if (s) {
|
||||||
if (g_core->GetAppTimeMillisecs() > i->second.endtime) {
|
if (g_core->AppTimeMillisecs() > i->second.endtime) {
|
||||||
StopSound(i->second.play_id);
|
StopSound(i->second.play_id);
|
||||||
sound_fade_nodes_.erase(i);
|
sound_fade_nodes_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
float fade_val =
|
float fade_val =
|
||||||
1
|
1
|
||||||
- (static_cast<float>(g_core->GetAppTimeMillisecs()
|
- (static_cast<float>(g_core->AppTimeMillisecs()
|
||||||
- i->second.starttime)
|
- i->second.starttime)
|
||||||
/ static_cast<float>(i->second.endtime - i->second.starttime));
|
/ static_cast<float>(i->second.endtime - i->second.starttime));
|
||||||
s->SetFade(fade_val);
|
s->SetFade(fade_val);
|
||||||
@ -1639,12 +1638,12 @@ void AudioServer::ClearSoundRefDeleteList() {
|
|||||||
// g_base->audio_server->PushSetSuspendedCall(true);
|
// g_base->audio_server->PushSetSuspendedCall(true);
|
||||||
|
|
||||||
// // Wait a reasonable amount of time for the thread to act on it.
|
// // Wait a reasonable amount of time for the thread to act on it.
|
||||||
// millisecs_t t = g_core->GetAppTimeMillisecs();
|
// millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
// while (true) {
|
// while (true) {
|
||||||
// if (g_base->audio_server->suspended()) {
|
// if (g_base->audio_server->suspended()) {
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// if (g_core->GetAppTimeMillisecs() - t > 1000) {
|
// if (g_core->AppTimeMillisecs() - t > 1000) {
|
||||||
// Log(LogLevel::kError, "Timed out waiting for audio suspend.");
|
// Log(LogLevel::kError, "Timed out waiting for audio suspend.");
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
@ -1657,12 +1656,12 @@ void AudioServer::ClearSoundRefDeleteList() {
|
|||||||
// g_base->audio_server->PushSetSuspendedCall(false);
|
// g_base->audio_server->PushSetSuspendedCall(false);
|
||||||
|
|
||||||
// // Wait a reasonable amount of time for the thread to act on it.
|
// // Wait a reasonable amount of time for the thread to act on it.
|
||||||
// millisecs_t t = g_core->GetAppTimeMillisecs();
|
// millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
// while (true) {
|
// while (true) {
|
||||||
// if (!g_base->audio_server->suspended()) {
|
// if (!g_base->audio_server->suspended()) {
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// if (g_core->GetAppTimeMillisecs() - t > 1000) {
|
// if (g_core->AppTimeMillisecs() - t > 1000) {
|
||||||
// Log(LogLevel::kError, "Timed out waiting for audio unsuspend.");
|
// Log(LogLevel::kError, "Timed out waiting for audio unsuspend.");
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
|
|||||||
@ -103,7 +103,7 @@ void AudioSource::Lock(int debug_id) {
|
|||||||
BA_DEBUG_FUNCTION_TIMER_BEGIN();
|
BA_DEBUG_FUNCTION_TIMER_BEGIN();
|
||||||
mutex_.lock();
|
mutex_.lock();
|
||||||
#if BA_DEBUG_BUILD
|
#if BA_DEBUG_BUILD
|
||||||
last_lock_time_ = g_core->GetAppTimeMillisecs();
|
last_lock_time_ = g_core->AppTimeMillisecs();
|
||||||
lock_debug_id_ = debug_id;
|
lock_debug_id_ = debug_id;
|
||||||
locked_ = true;
|
locked_ = true;
|
||||||
#endif
|
#endif
|
||||||
@ -115,7 +115,7 @@ auto AudioSource::TryLock(int debug_id) -> bool {
|
|||||||
#if (BA_DEBUG_BUILD || BA_TEST_BUILD)
|
#if (BA_DEBUG_BUILD || BA_TEST_BUILD)
|
||||||
if (locked) {
|
if (locked) {
|
||||||
locked_ = true;
|
locked_ = true;
|
||||||
last_lock_time_ = g_core->GetAppTimeMillisecs();
|
last_lock_time_ = g_core->AppTimeMillisecs();
|
||||||
lock_debug_id_ = debug_id;
|
lock_debug_id_ = debug_id;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -174,6 +174,11 @@ void BaseFeatureSet::ErrorScreenMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto BaseFeatureSet::GetV2AccountID() -> std::optional<std::string> {
|
auto BaseFeatureSet::GetV2AccountID() -> std::optional<std::string> {
|
||||||
|
// Guard against this getting called early.
|
||||||
|
if (!IsAppStarted()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
auto gil = Python::ScopedInterpreterLock();
|
auto gil = Python::ScopedInterpreterLock();
|
||||||
auto result =
|
auto result =
|
||||||
python->objs().Get(BasePython::ObjID::kGetV2AccountIdCall).Call();
|
python->objs().Get(BasePython::ObjID::kGetV2AccountIdCall).Call();
|
||||||
@ -199,7 +204,7 @@ void BaseFeatureSet::StartApp() {
|
|||||||
BA_PRECONDITION(g_core->InMainThread());
|
BA_PRECONDITION(g_core->InMainThread());
|
||||||
BA_PRECONDITION(g_base);
|
BA_PRECONDITION(g_base);
|
||||||
|
|
||||||
auto start_time = g_core->GetAppTimeSeconds();
|
auto start_time = g_core->AppTimeSeconds();
|
||||||
|
|
||||||
// Currently limiting this to once per process.
|
// Currently limiting this to once per process.
|
||||||
BA_PRECONDITION(!called_start_app_);
|
BA_PRECONDITION(!called_start_app_);
|
||||||
@ -253,7 +258,7 @@ void BaseFeatureSet::StartApp() {
|
|||||||
// Make some noise if this takes more than a few seconds. If we pass 5
|
// Make some noise if this takes more than a few seconds. If we pass 5
|
||||||
// seconds or so we start to trigger App-Not-Responding reports which
|
// seconds or so we start to trigger App-Not-Responding reports which
|
||||||
// isn't good.
|
// isn't good.
|
||||||
auto duration = g_core->GetAppTimeSeconds() - start_time;
|
auto duration = g_core->AppTimeSeconds() - start_time;
|
||||||
if (duration > 3.0) {
|
if (duration > 3.0) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
snprintf(buffer, sizeof(buffer),
|
snprintf(buffer, sizeof(buffer),
|
||||||
@ -272,7 +277,7 @@ void BaseFeatureSet::SuspendApp() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
millisecs_t start_time{core::CorePlatform::GetCurrentMillisecs()};
|
millisecs_t start_time{core::CorePlatform::TimeMonotonicMillisecs()};
|
||||||
|
|
||||||
// Apple mentioned 5 seconds to run stuff once backgrounded or they bring
|
// Apple mentioned 5 seconds to run stuff once backgrounded or they bring
|
||||||
// down the hammer. Let's aim to stay under 2.
|
// down the hammer. Let's aim to stay under 2.
|
||||||
@ -280,7 +285,7 @@ void BaseFeatureSet::SuspendApp() {
|
|||||||
|
|
||||||
g_core->platform->LowLevelDebugLog(
|
g_core->platform->LowLevelDebugLog(
|
||||||
"SuspendApp@"
|
"SuspendApp@"
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs()));
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()));
|
||||||
app_suspended_ = true;
|
app_suspended_ = true;
|
||||||
|
|
||||||
// IMPORTANT: Any pause related stuff that event-loop-threads need to do
|
// IMPORTANT: Any pause related stuff that event-loop-threads need to do
|
||||||
@ -311,13 +316,13 @@ void BaseFeatureSet::SuspendApp() {
|
|||||||
g_core->Log(
|
g_core->Log(
|
||||||
LogName::kBa, LogLevel::kDebug,
|
LogName::kBa, LogLevel::kDebug,
|
||||||
"SuspendApp() completed in "
|
"SuspendApp() completed in "
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs()
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()
|
||||||
- start_time)
|
- start_time)
|
||||||
+ "ms.");
|
+ "ms.");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (std::abs(core::CorePlatform::GetCurrentMillisecs() - start_time)
|
} while (std::abs(core::CorePlatform::TimeMonotonicMillisecs() - start_time)
|
||||||
< max_duration);
|
< max_duration);
|
||||||
|
|
||||||
// If we made it here, we timed out. Complain.
|
// If we made it here, we timed out. Complain.
|
||||||
@ -325,7 +330,8 @@ void BaseFeatureSet::SuspendApp() {
|
|||||||
std::string("SuspendApp() took too long; ")
|
std::string("SuspendApp() took too long; ")
|
||||||
+ std::to_string(running_loops.size())
|
+ std::to_string(running_loops.size())
|
||||||
+ " event-loops not yet suspended after "
|
+ " event-loops not yet suspended after "
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs() - start_time)
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()
|
||||||
|
- start_time)
|
||||||
+ " ms: (";
|
+ " ms: (";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto* loop : running_loops) {
|
for (auto* loop : running_loops) {
|
||||||
@ -383,10 +389,10 @@ void BaseFeatureSet::UnsuspendApp() {
|
|||||||
"AppAdapter::UnsuspendApp() called with app not in suspendedstate.");
|
"AppAdapter::UnsuspendApp() called with app not in suspendedstate.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
millisecs_t start_time{core::CorePlatform::GetCurrentMillisecs()};
|
millisecs_t start_time{core::CorePlatform::TimeMonotonicMillisecs()};
|
||||||
g_core->platform->LowLevelDebugLog(
|
g_core->platform->LowLevelDebugLog(
|
||||||
"UnsuspendApp@"
|
"UnsuspendApp@"
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs()));
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()));
|
||||||
app_suspended_ = false;
|
app_suspended_ = false;
|
||||||
|
|
||||||
// Spin all event-loops back up.
|
// Spin all event-loops back up.
|
||||||
@ -397,11 +403,12 @@ void BaseFeatureSet::UnsuspendApp() {
|
|||||||
g_base->networking->OnAppUnsuspend();
|
g_base->networking->OnAppUnsuspend();
|
||||||
|
|
||||||
if (g_buildconfig.debug_build()) {
|
if (g_buildconfig.debug_build()) {
|
||||||
g_core->Log(LogName::kBa, LogLevel::kDebug,
|
g_core->Log(
|
||||||
"UnsuspendApp() completed in "
|
LogName::kBa, LogLevel::kDebug,
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs()
|
"UnsuspendApp() completed in "
|
||||||
- start_time)
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()
|
||||||
+ "ms.");
|
- start_time)
|
||||||
|
+ "ms.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +578,7 @@ auto BaseFeatureSet::GetAppInstanceUUID() -> const std::string& {
|
|||||||
g_core->Log(LogName::kBa, LogLevel::kWarning,
|
g_core->Log(LogName::kBa, LogLevel::kWarning,
|
||||||
"GetSessionUUID() using rand fallback.");
|
"GetSessionUUID() using rand fallback.");
|
||||||
srand(static_cast<unsigned int>(
|
srand(static_cast<unsigned int>(
|
||||||
core::CorePlatform::GetCurrentMillisecs())); // NOLINT
|
core::CorePlatform::TimeMonotonicMillisecs())); // NOLINT
|
||||||
app_instance_uuid =
|
app_instance_uuid =
|
||||||
std::to_string(static_cast<uint32_t>(rand())); // NOLINT
|
std::to_string(static_cast<uint32_t>(rand())); // NOLINT
|
||||||
have_app_instance_uuid = true;
|
have_app_instance_uuid = true;
|
||||||
@ -966,7 +973,7 @@ void BaseFeatureSet::SetAppActive(bool active) {
|
|||||||
|
|
||||||
g_core->platform->LowLevelDebugLog(
|
g_core->platform->LowLevelDebugLog(
|
||||||
"SetAppActive(" + std::to_string(active) + ")@"
|
"SetAppActive(" + std::to_string(active) + ")@"
|
||||||
+ std::to_string(core::CorePlatform::GetCurrentMillisecs()));
|
+ std::to_string(core::CorePlatform::TimeMonotonicMillisecs()));
|
||||||
|
|
||||||
// Issue a gentle warning if they are feeding us the same state twice in a
|
// Issue a gentle warning if they are feeding us the same state twice in a
|
||||||
// row; might imply faulty logic on an app-adapter or whatnot.
|
// row; might imply faulty logic on an app-adapter or whatnot.
|
||||||
@ -990,6 +997,12 @@ void BaseFeatureSet::Reset() {
|
|||||||
audio->Reset();
|
audio->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto BaseFeatureSet::TimeSinceEpochCloudSeconds() -> seconds_t {
|
||||||
|
// TODO(ericf): wire this up. Just using local time for now. And make sure
|
||||||
|
// that this and utc_now_cloud() in the Python layer are synced up.
|
||||||
|
return core::CorePlatform::TimeSinceEpochSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
void BaseFeatureSet::SetUIScale(UIScale scale) {
|
void BaseFeatureSet::SetUIScale(UIScale scale) {
|
||||||
assert(InLogicThread());
|
assert(InLogicThread());
|
||||||
|
|
||||||
|
|||||||
@ -476,7 +476,8 @@ enum class SysTextureID : uint8_t {
|
|||||||
kFontExtras4,
|
kFontExtras4,
|
||||||
kCharacterIconMask,
|
kCharacterIconMask,
|
||||||
kBlack,
|
kBlack,
|
||||||
kWings
|
kWings,
|
||||||
|
kSpinner
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SysCubeMapTextureID : uint8_t {
|
enum class SysCubeMapTextureID : uint8_t {
|
||||||
@ -761,8 +762,8 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
|
|||||||
|
|
||||||
void PushMainThreadRunnable(Runnable* runnable) override;
|
void PushMainThreadRunnable(Runnable* runnable) override;
|
||||||
|
|
||||||
/// Return the currently signed in V2 account id as
|
/// Return the currently signed in V2 account id as reported by the Python
|
||||||
/// reported by the Python layer.
|
/// layer.
|
||||||
auto GetV2AccountID() -> std::optional<std::string>;
|
auto GetV2AccountID() -> std::optional<std::string>;
|
||||||
|
|
||||||
/// Return whether clipboard operations are supported at all. This gets
|
/// Return whether clipboard operations are supported at all. This gets
|
||||||
@ -784,6 +785,10 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
|
|||||||
/// Set overall ui scale for the app.
|
/// Set overall ui scale for the app.
|
||||||
void SetUIScale(UIScale scale);
|
void SetUIScale(UIScale scale);
|
||||||
|
|
||||||
|
/// Time since epoch on the master-server. Tries to
|
||||||
|
/// be correct even if local time is set wrong.
|
||||||
|
auto TimeSinceEpochCloudSeconds() -> seconds_t;
|
||||||
|
|
||||||
// Const subsystems.
|
// Const subsystems.
|
||||||
AppAdapter* const app_adapter;
|
AppAdapter* const app_adapter;
|
||||||
AppConfig* const app_config;
|
AppConfig* const app_config;
|
||||||
|
|||||||
@ -96,7 +96,7 @@ class BGDynamicsServer::Terrain {
|
|||||||
if (collision_mesh_) {
|
if (collision_mesh_) {
|
||||||
Object::Ref<CollisionMeshAsset>* ref = collision_mesh_;
|
Object::Ref<CollisionMeshAsset>* ref = collision_mesh_;
|
||||||
g_base->logic->event_loop()->PushCall([ref] {
|
g_base->logic->event_loop()->PushCall([ref] {
|
||||||
(**ref).set_last_used_time(g_core->GetAppTimeMillisecs());
|
(**ref).set_last_used_time(g_core->AppTimeMillisecs());
|
||||||
delete ref;
|
delete ref;
|
||||||
});
|
});
|
||||||
collision_mesh_ = nullptr;
|
collision_mesh_ = nullptr;
|
||||||
|
|||||||
@ -90,12 +90,12 @@ void RendererGL::CheckGLError(const char* file, int line) {
|
|||||||
BA_PRECONDITION_FATAL(vendor);
|
BA_PRECONDITION_FATAL(vendor);
|
||||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||||
BA_PRECONDITION_FATAL(renderer);
|
BA_PRECONDITION_FATAL(renderer);
|
||||||
g_core->Log(
|
g_core->Log(LogName::kBaGraphics, LogLevel::kError,
|
||||||
LogName::kBaGraphics, LogLevel::kError,
|
"OpenGL Error at " + std::string(file) + " line "
|
||||||
"OpenGL Error at " + std::string(file) + " line " + std::to_string(line)
|
+ std::to_string(line) + ": " + GLErrorToString(err)
|
||||||
+ ": " + GLErrorToString(err) + "\nrenderer: " + renderer
|
+ "\nrenderer: " + renderer + "\nvendor: " + vendor
|
||||||
+ "\nvendor: " + vendor + "\nversion: " + version
|
+ "\nversion: " + version
|
||||||
+ "\ntime: " + std::to_string(g_core->GetAppTimeMillisecs()));
|
+ "\ntime: " + std::to_string(g_core->AppTimeMillisecs()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -253,13 +253,13 @@ auto Graphics::GraphicsQualityFromAppConfig() -> GraphicsQualityRequest {
|
|||||||
void Graphics::SetGyroEnabled(bool enable) {
|
void Graphics::SetGyroEnabled(bool enable) {
|
||||||
// If we're turning back on, suppress gyro updates for a bit.
|
// If we're turning back on, suppress gyro updates for a bit.
|
||||||
if (enable && !gyro_enabled_) {
|
if (enable && !gyro_enabled_) {
|
||||||
last_suppress_gyro_time_ = g_core->GetAppTimeMicrosecs();
|
last_suppress_gyro_time_ = g_core->AppTimeMicrosecs();
|
||||||
}
|
}
|
||||||
gyro_enabled_ = enable;
|
gyro_enabled_ = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::UpdateProgressBarProgress(float target) {
|
void Graphics::UpdateProgressBarProgress(float target) {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
float p = target;
|
float p = target;
|
||||||
if (p < 0) {
|
if (p < 0) {
|
||||||
p = 0;
|
p = 0;
|
||||||
@ -274,7 +274,7 @@ void Graphics::UpdateProgressBarProgress(float target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::DrawProgressBar(RenderPass* pass, float opacity) {
|
void Graphics::DrawProgressBar(RenderPass* pass, float opacity) {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
float amount = progress_bar_progress_;
|
float amount = progress_bar_progress_;
|
||||||
if (amount < 0) {
|
if (amount < 0) {
|
||||||
amount = 0;
|
amount = 0;
|
||||||
@ -361,9 +361,9 @@ void Graphics::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
assert(g_base && g_base->InLogicThread());
|
assert(g_base && g_base->InLogicThread());
|
||||||
|
|
||||||
// Every now and then, update our stats.
|
// Every now and then, update our stats.
|
||||||
while (g_core->GetAppTimeMillisecs() >= next_stat_update_time_) {
|
while (g_core->AppTimeMillisecs() >= next_stat_update_time_) {
|
||||||
if (g_core->GetAppTimeMillisecs() - next_stat_update_time_ > 1000) {
|
if (g_core->AppTimeMillisecs() - next_stat_update_time_ > 1000) {
|
||||||
next_stat_update_time_ = g_core->GetAppTimeMillisecs() + 1000;
|
next_stat_update_time_ = g_core->AppTimeMillisecs() + 1000;
|
||||||
} else {
|
} else {
|
||||||
next_stat_update_time_ += 1000;
|
next_stat_update_time_ += 1000;
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ void Graphics::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
// Draw any debug graphs.
|
// Draw any debug graphs.
|
||||||
{
|
{
|
||||||
float debug_graph_y = 50.0;
|
float debug_graph_y = 50.0;
|
||||||
auto now = g_core->GetAppTimeMillisecs();
|
auto now = g_core->AppTimeMillisecs();
|
||||||
for (auto it = debug_graphs_.begin(); it != debug_graphs_.end();) {
|
for (auto it = debug_graphs_.begin(); it != debug_graphs_.end();) {
|
||||||
assert(it->second.exists());
|
assert(it->second.exists());
|
||||||
if (now - it->second->LastUsedTime() > 1000) {
|
if (now - it->second->LastUsedTime() > 1000) {
|
||||||
@ -508,7 +508,7 @@ auto Graphics::GetDebugGraph(const std::string& name, bool smoothed)
|
|||||||
debug_graphs_[name]->SetLabel(name);
|
debug_graphs_[name]->SetLabel(name);
|
||||||
debug_graphs_[name]->SetSmoothed(smoothed);
|
debug_graphs_[name]->SetSmoothed(smoothed);
|
||||||
}
|
}
|
||||||
debug_graphs_[name]->SetLastUsedTime(g_core->GetAppTimeMillisecs());
|
debug_graphs_[name]->SetLastUsedTime(g_core->AppTimeMillisecs());
|
||||||
return debug_graphs_[name].get();
|
return debug_graphs_[name].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +770,7 @@ void Graphics::BuildAndPushFrameDef() {
|
|||||||
assert(!building_frame_def_);
|
assert(!building_frame_def_);
|
||||||
building_frame_def_ = true;
|
building_frame_def_ = true;
|
||||||
|
|
||||||
microsecs_t app_time_microsecs = g_core->GetAppTimeMicrosecs();
|
microsecs_t app_time_microsecs = g_core->AppTimeMicrosecs();
|
||||||
|
|
||||||
// Store how much time this frame_def represents.
|
// Store how much time this frame_def represents.
|
||||||
auto display_time_microsecs = g_base->logic->display_time_microsecs();
|
auto display_time_microsecs = g_base->logic->display_time_microsecs();
|
||||||
@ -1222,7 +1222,7 @@ void Graphics::EnableProgressBar(bool fade_in) {
|
|||||||
if (progress_bar_loads_ > 0) {
|
if (progress_bar_loads_ > 0) {
|
||||||
progress_bar_ = true;
|
progress_bar_ = true;
|
||||||
progress_bar_fade_in_ = fade_in;
|
progress_bar_fade_in_ = fade_in;
|
||||||
last_progress_bar_draw_time_ = g_core->GetAppTimeMillisecs();
|
last_progress_bar_draw_time_ = g_core->AppTimeMillisecs();
|
||||||
last_progress_bar_start_time_ = last_progress_bar_draw_time_;
|
last_progress_bar_start_time_ = last_progress_bar_draw_time_;
|
||||||
progress_bar_progress_ = 0.0f;
|
progress_bar_progress_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -147,7 +147,7 @@ auto GraphicsServer::TryRender() -> bool {
|
|||||||
|
|
||||||
auto GraphicsServer::WaitForRenderFrameDef_() -> FrameDef* {
|
auto GraphicsServer::WaitForRenderFrameDef_() -> FrameDef* {
|
||||||
assert(g_base->app_adapter->InGraphicsContext());
|
assert(g_base->app_adapter->InGraphicsContext());
|
||||||
millisecs_t start_time = g_core->GetAppTimeMillisecs();
|
millisecs_t start_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Spin and wait for a short bit for a frame_def to appear.
|
// Spin and wait for a short bit for a frame_def to appear.
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -176,7 +176,7 @@ auto GraphicsServer::WaitForRenderFrameDef_() -> FrameDef* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there's no frame_def for us, sleep for a bit and wait for it.
|
// If there's no frame_def for us, sleep for a bit and wait for it.
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs() - start_time;
|
millisecs_t t = g_core->AppTimeMillisecs() - start_time;
|
||||||
if (t >= 1000) {
|
if (t >= 1000) {
|
||||||
if (g_buildconfig.debug_build()) {
|
if (g_buildconfig.debug_build()) {
|
||||||
g_core->Log(LogName::kBaGraphics, LogLevel::kWarning,
|
g_core->Log(LogName::kBaGraphics, LogLevel::kWarning,
|
||||||
|
|||||||
@ -650,7 +650,7 @@ void Renderer::UpdatePixelScaleAndBackingBuffer(FrameDef* frame_def) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::LoadMedia(FrameDef* frame_def) {
|
void Renderer::LoadMedia(FrameDef* frame_def) {
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs();
|
millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
for (auto&& i : frame_def->media_components()) {
|
for (auto&& i : frame_def->media_components()) {
|
||||||
Asset* mc = i.get();
|
Asset* mc = i.get();
|
||||||
assert(mc);
|
assert(mc);
|
||||||
@ -667,7 +667,7 @@ void Renderer::LoadMedia(FrameDef* frame_def) {
|
|||||||
// // default about 1 second after a res change, etc...
|
// // default about 1 second after a res change, etc...
|
||||||
// // so if we're using a non-1.0 gamma, lets keep setting it periodically
|
// // so if we're using a non-1.0 gamma, lets keep setting it periodically
|
||||||
// // to force the issue
|
// // to force the issue
|
||||||
// millisecs_t t = g_core->GetAppTimeMillisecs();
|
// millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
// if (screen_gamma_requested_ != screen_gamma_
|
// if (screen_gamma_requested_ != screen_gamma_
|
||||||
// || (t - last_screen_gamma_update_time_ > 300 && screen_gamma_ != 1.0f))
|
// || (t - last_screen_gamma_update_time_ > 300 && screen_gamma_ != 1.0f))
|
||||||
// {
|
// {
|
||||||
|
|||||||
@ -207,10 +207,9 @@ void Camera::UpdatePosition() {
|
|||||||
lr_jitter = 0.0f;
|
lr_jitter = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
lr_jitter =
|
lr_jitter =
|
||||||
sinf(static_cast<float>(g_core->GetAppTimeMillisecs()) / 108.0f)
|
sinf(static_cast<float>(g_core->AppTimeMillisecs()) / 108.0f)
|
||||||
* 0.4f
|
* 0.4f
|
||||||
+ sinf(static_cast<float>(g_core->GetAppTimeMillisecs())
|
+ sinf(static_cast<float>(g_core->AppTimeMillisecs()) / 268.0f)
|
||||||
/ 268.0f)
|
|
||||||
* 1.0f;
|
* 1.0f;
|
||||||
lr_jitter *= 0.05f;
|
lr_jitter *= 0.05f;
|
||||||
}
|
}
|
||||||
@ -891,7 +890,7 @@ void Camera::SetMode(CameraMode m) {
|
|||||||
if (mode_ != m) {
|
if (mode_ != m) {
|
||||||
mode_ = m;
|
mode_ = m;
|
||||||
smooth_next_frame_ = false;
|
smooth_next_frame_ = false;
|
||||||
// last_mode_set_time_ = g_core->GetAppTimeMillisecs();
|
// last_mode_set_time_ = g_core->AppTimeMillisecs();
|
||||||
// last_mode_set_time_ = time_;
|
// last_mode_set_time_ = time_;
|
||||||
heading_ = kInitialHeading;
|
heading_ = kInitialHeading;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,8 +65,8 @@ void ScreenMessages::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
// Delete old ones.
|
// Delete old ones.
|
||||||
if (!screen_messages_.empty()) {
|
if (!screen_messages_.empty()) {
|
||||||
millisecs_t cutoff;
|
millisecs_t cutoff;
|
||||||
if (g_core->GetAppTimeMillisecs() > 5000) {
|
if (g_core->AppTimeMillisecs() > 5000) {
|
||||||
cutoff = g_core->GetAppTimeMillisecs() - 5000;
|
cutoff = g_core->AppTimeMillisecs() - 5000;
|
||||||
for (auto i = screen_messages_.begin(); i != screen_messages_.end();) {
|
for (auto i = screen_messages_.begin(); i != screen_messages_.end();) {
|
||||||
if (i->creation_time < cutoff) {
|
if (i->creation_time < cutoff) {
|
||||||
auto next = i;
|
auto next = i;
|
||||||
@ -128,7 +128,7 @@ void ScreenMessages::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
// which is calculated as part of it.
|
// which is calculated as part of it.
|
||||||
i->GetText();
|
i->GetText();
|
||||||
|
|
||||||
millisecs_t age = g_core->GetAppTimeMillisecs() - i->creation_time;
|
millisecs_t age = g_core->AppTimeMillisecs() - i->creation_time;
|
||||||
youngest_age = std::min(youngest_age, age);
|
youngest_age = std::min(youngest_age, age);
|
||||||
float s_extra = 1.0f;
|
float s_extra = 1.0f;
|
||||||
if (age < 100) {
|
if (age < 100) {
|
||||||
@ -244,7 +244,7 @@ void ScreenMessages::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
|
|
||||||
for (auto i = screen_messages_.rbegin(); i != screen_messages_.rend();
|
for (auto i = screen_messages_.rbegin(); i != screen_messages_.rend();
|
||||||
i++) {
|
i++) {
|
||||||
millisecs_t age = g_core->GetAppTimeMillisecs() - i->creation_time;
|
millisecs_t age = g_core->AppTimeMillisecs() - i->creation_time;
|
||||||
youngest_age = std::min(youngest_age, age);
|
youngest_age = std::min(youngest_age, age);
|
||||||
float s_extra = 1.0f;
|
float s_extra = 1.0f;
|
||||||
if (age < 100) {
|
if (age < 100) {
|
||||||
@ -315,8 +315,8 @@ void ScreenMessages::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
// Delete old ones.
|
// Delete old ones.
|
||||||
if (!screen_messages_top_.empty()) {
|
if (!screen_messages_top_.empty()) {
|
||||||
millisecs_t cutoff;
|
millisecs_t cutoff;
|
||||||
if (g_core->GetAppTimeMillisecs() > 5000) {
|
if (g_core->AppTimeMillisecs() > 5000) {
|
||||||
cutoff = g_core->GetAppTimeMillisecs() - 5000;
|
cutoff = g_core->AppTimeMillisecs() - 5000;
|
||||||
for (auto i = screen_messages_top_.begin();
|
for (auto i = screen_messages_top_.begin();
|
||||||
i != screen_messages_top_.end();) {
|
i != screen_messages_top_.end();) {
|
||||||
if (i->creation_time < cutoff) {
|
if (i->creation_time < cutoff) {
|
||||||
@ -354,7 +354,7 @@ void ScreenMessages::DrawMiscOverlays(FrameDef* frame_def) {
|
|||||||
// Update the translation if need be.
|
// Update the translation if need be.
|
||||||
i->UpdateTranslation();
|
i->UpdateTranslation();
|
||||||
|
|
||||||
millisecs_t age = g_core->GetAppTimeMillisecs() - i->creation_time;
|
millisecs_t age = g_core->AppTimeMillisecs() - i->creation_time;
|
||||||
float s_extra = 1.0f;
|
float s_extra = 1.0f;
|
||||||
if (age < 100) {
|
if (age < 100) {
|
||||||
s_extra = std::min(1.1f, 1.1f * (static_cast<float>(age) / 100.0f));
|
s_extra = std::min(1.1f, 1.1f * (static_cast<float>(age) / 100.0f));
|
||||||
@ -466,13 +466,13 @@ void ScreenMessages::AddScreenMessage(const std::string& msg,
|
|||||||
start_v,
|
start_v,
|
||||||
std::max(-100.0f, screen_messages_top_.back().v_smoothed - 25.0f));
|
std::max(-100.0f, screen_messages_top_.back().v_smoothed - 25.0f));
|
||||||
}
|
}
|
||||||
screen_messages_top_.emplace_back(m, true, g_core->GetAppTimeMillisecs(),
|
screen_messages_top_.emplace_back(m, true, g_core->AppTimeMillisecs(),
|
||||||
color, texture, tint_texture, tint,
|
color, texture, tint_texture, tint,
|
||||||
tint2);
|
tint2);
|
||||||
screen_messages_top_.back().v_smoothed = start_v;
|
screen_messages_top_.back().v_smoothed = start_v;
|
||||||
} else {
|
} else {
|
||||||
screen_messages_.emplace_back(m, false, g_core->GetAppTimeMillisecs(),
|
screen_messages_.emplace_back(m, false, g_core->AppTimeMillisecs(), color,
|
||||||
color, texture, tint_texture, tint, tint2);
|
texture, tint_texture, tint, tint2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,8 +534,7 @@ auto ScreenMessages::ScreenMessageEntry::GetText() -> TextGroup& {
|
|||||||
|
|
||||||
void ScreenMessages::ScreenMessageEntry::UpdateTranslation() {
|
void ScreenMessages::ScreenMessageEntry::UpdateTranslation() {
|
||||||
if (translation_dirty) {
|
if (translation_dirty) {
|
||||||
s_translated = g_base->assets->CompileResourceString(
|
s_translated = g_base->assets->CompileResourceString(s_raw);
|
||||||
s_raw, "Graphics::ScreenMessageEntry::UpdateTranslation");
|
|
||||||
translation_dirty = false;
|
translation_dirty = false;
|
||||||
mesh_dirty = true;
|
mesh_dirty = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ JoystickInput::JoystickInput(int sdl_joystick_id,
|
|||||||
calibration_break_threshold_(kJoystickCalibrationBreakThreshold),
|
calibration_break_threshold_(kJoystickCalibrationBreakThreshold),
|
||||||
custom_device_name_(custom_device_name),
|
custom_device_name_(custom_device_name),
|
||||||
can_configure_(can_configure),
|
can_configure_(can_configure),
|
||||||
creation_time_(g_core->GetAppTimeMillisecs()),
|
creation_time_(g_core->AppTimeMillisecs()),
|
||||||
calibrate_(calibrate) {
|
calibrate_(calibrate) {
|
||||||
// This is the default calibration for 'non-full' analog calibration.
|
// This is the default calibration for 'non-full' analog calibration.
|
||||||
for (float& analog_calibration_val : analog_calibration_vals_) {
|
for (float& analog_calibration_val : analog_calibration_vals_) {
|
||||||
@ -374,7 +374,7 @@ void JoystickInput::Update() {
|
|||||||
// Let's take this opportunity to update our calibration
|
// Let's take this opportunity to update our calibration
|
||||||
// (should probably have a specific place to do that but this works)
|
// (should probably have a specific place to do that but this works)
|
||||||
if (calibrate_) {
|
if (calibrate_) {
|
||||||
millisecs_t time = g_core->GetAppTimeMillisecs();
|
millisecs_t time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// If we're doing 'aggressive' auto-recalibration we expand extents outward
|
// If we're doing 'aggressive' auto-recalibration we expand extents outward
|
||||||
// but suck them inward a tiny bit too to account for jitter or random fluke
|
// but suck them inward a tiny bit too to account for jitter or random fluke
|
||||||
@ -545,7 +545,7 @@ void JoystickInput::HandleSDLEvent(const SDL_Event* e) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
millisecs_t time = g_core->GetAppTimeMillisecs();
|
millisecs_t time = g_core->AppTimeMillisecs();
|
||||||
SDL_Event e2;
|
SDL_Event e2;
|
||||||
|
|
||||||
// Ignore analog-stick input while we're holding a hat switch or d-pad
|
// Ignore analog-stick input while we're holding a hat switch or d-pad
|
||||||
@ -959,7 +959,7 @@ void JoystickInput::HandleSDLEvent(const SDL_Event* e) {
|
|||||||
&& (e->jbutton.button != hold_position_button_)
|
&& (e->jbutton.button != hold_position_button_)
|
||||||
&& (e->jbutton.button != back_button_)) {
|
&& (e->jbutton.button != back_button_)) {
|
||||||
if (ui_only_ || e->jbutton.button == remote_enter_button_) {
|
if (ui_only_ || e->jbutton.button == remote_enter_button_) {
|
||||||
millisecs_t current_time = g_core->GetAppTimeMillisecs();
|
millisecs_t current_time = g_core->AppTimeMillisecs();
|
||||||
if (current_time - last_ui_only_print_time_ > 5000) {
|
if (current_time - last_ui_only_print_time_ > 5000) {
|
||||||
g_base->python->objs()
|
g_base->python->objs()
|
||||||
.Get(BasePython::ObjID::kUIRemotePressCall)
|
.Get(BasePython::ObjID::kUIRemotePressCall)
|
||||||
|
|||||||
@ -93,7 +93,7 @@ TouchInput::TouchInput() {
|
|||||||
TouchInput::~TouchInput() = default;
|
TouchInput::~TouchInput() = default;
|
||||||
|
|
||||||
void TouchInput::UpdateButtons(bool new_touch) {
|
void TouchInput::UpdateButtons(bool new_touch) {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
float spread_scaled_actions =
|
float spread_scaled_actions =
|
||||||
kButtonSpread * base_controls_scale_ * controls_scale_actions_;
|
kButtonSpread * base_controls_scale_ * controls_scale_actions_;
|
||||||
float width = g_base->graphics->screen_virtual_width();
|
float width = g_base->graphics->screen_virtual_width();
|
||||||
@ -134,7 +134,7 @@ void TouchInput::UpdateButtons(bool new_touch) {
|
|||||||
closest_to_bomb = true;
|
closest_to_bomb = true;
|
||||||
}
|
}
|
||||||
if (buttons_touch_) {
|
if (buttons_touch_) {
|
||||||
last_buttons_touch_time_ = g_core->GetAppTimeMillisecs();
|
last_buttons_touch_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle swipe mode.
|
// Handle swipe mode.
|
||||||
|
|||||||
@ -158,7 +158,7 @@ void Input::AnnounceConnects_() {
|
|||||||
|
|
||||||
// For the first announcement just say "X controllers detected" and don't
|
// For the first announcement just say "X controllers detected" and don't
|
||||||
// have a sound.
|
// have a sound.
|
||||||
if (first_print && g_core->GetAppTimeSeconds() < 3.0) {
|
if (first_print && g_core->AppTimeSeconds() < 3.0) {
|
||||||
first_print = false;
|
first_print = false;
|
||||||
|
|
||||||
// If there's been several connected, just give a number.
|
// If there's been several connected, just give a number.
|
||||||
@ -225,7 +225,7 @@ void Input::ShowStandardInputDeviceConnectedMessage_(InputDevice* j) {
|
|||||||
// On Android we never show messages for initial input-devices; we often
|
// On Android we never show messages for initial input-devices; we often
|
||||||
// get large numbers of strange virtual devices that aren't actually
|
// get large numbers of strange virtual devices that aren't actually
|
||||||
// controllers so this is more confusing than helpful.
|
// controllers so this is more confusing than helpful.
|
||||||
if (g_buildconfig.ostype_android() && g_core->GetAppTimeSeconds() < 3.0) {
|
if (g_buildconfig.ostype_android() && g_core->AppTimeSeconds() < 3.0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +554,7 @@ void Input::OnScreenSizeChange() { assert(g_base->InLogicThread()); }
|
|||||||
void Input::StepDisplayTime() {
|
void Input::StepDisplayTime() {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// If input has been locked an excessively long amount of time, unlock it.
|
// If input has been locked an excessively long amount of time, unlock it.
|
||||||
if (input_lock_count_temp_) {
|
if (input_lock_count_temp_) {
|
||||||
@ -622,13 +622,13 @@ void Input::LockAllInput(bool permanent, const std::string& label) {
|
|||||||
} else {
|
} else {
|
||||||
input_lock_count_temp_++;
|
input_lock_count_temp_++;
|
||||||
if (input_lock_count_temp_ == 1) {
|
if (input_lock_count_temp_ == 1) {
|
||||||
last_input_temp_lock_time_ = g_core->GetAppTimeMillisecs();
|
last_input_temp_lock_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
input_lock_temp_labels_.push_back(label);
|
input_lock_temp_labels_.push_back(label);
|
||||||
|
|
||||||
recent_input_locks_unlocks_.push_back(
|
recent_input_locks_unlocks_.push_back(
|
||||||
"temp lock: " + label + " time "
|
"temp lock: " + label + " time "
|
||||||
+ std::to_string(g_core->GetAppTimeMillisecs()));
|
+ std::to_string(g_core->AppTimeMillisecs()));
|
||||||
while (recent_input_locks_unlocks_.size() > 10) {
|
while (recent_input_locks_unlocks_.size() > 10) {
|
||||||
recent_input_locks_unlocks_.pop_front();
|
recent_input_locks_unlocks_.pop_front();
|
||||||
}
|
}
|
||||||
@ -641,7 +641,7 @@ void Input::UnlockAllInput(bool permanent, const std::string& label) {
|
|||||||
recent_input_locks_unlocks_.push_back(
|
recent_input_locks_unlocks_.push_back(
|
||||||
permanent ? "permanent unlock: "
|
permanent ? "permanent unlock: "
|
||||||
: "temp unlock: " + label + " time "
|
: "temp unlock: " + label + " time "
|
||||||
+ std::to_string(g_core->GetAppTimeMillisecs()));
|
+ std::to_string(g_core->AppTimeMillisecs()));
|
||||||
while (recent_input_locks_unlocks_.size() > 10) {
|
while (recent_input_locks_unlocks_.size() > 10) {
|
||||||
recent_input_locks_unlocks_.pop_front();
|
recent_input_locks_unlocks_.pop_front();
|
||||||
}
|
}
|
||||||
@ -667,7 +667,7 @@ void Input::UnlockAllInput(bool permanent, const std::string& label) {
|
|||||||
if (input_lock_count_temp_ < 0) {
|
if (input_lock_count_temp_ < 0) {
|
||||||
g_core->Log(LogName::kBaInput, LogLevel::kWarning,
|
g_core->Log(LogName::kBaInput, LogLevel::kWarning,
|
||||||
"temp input unlock at time "
|
"temp input unlock at time "
|
||||||
+ std::to_string(g_core->GetAppTimeMillisecs())
|
+ std::to_string(g_core->AppTimeMillisecs())
|
||||||
+ " with no active lock: '" + label + "'");
|
+ " with no active lock: '" + label + "'");
|
||||||
// This is to be expected since we can reset this to 0.
|
// This is to be expected since we can reset this to 0.
|
||||||
input_lock_count_temp_ = 0;
|
input_lock_count_temp_ = 0;
|
||||||
@ -684,7 +684,7 @@ void Input::UnlockAllInput(bool permanent, const std::string& label) {
|
|||||||
|
|
||||||
void Input::PrintLockLabels_() {
|
void Input::PrintLockLabels_() {
|
||||||
std::string s = "INPUT LOCK REPORT (time="
|
std::string s = "INPUT LOCK REPORT (time="
|
||||||
+ std::to_string(g_core->GetAppTimeMillisecs()) + "):";
|
+ std::to_string(g_core->AppTimeMillisecs()) + "):";
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
s += "\n " + std::to_string(input_lock_temp_labels_.size()) + " TEMP LOCKS:";
|
s += "\n " + std::to_string(input_lock_temp_labels_.size()) + " TEMP LOCKS:";
|
||||||
@ -926,7 +926,7 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
|
|||||||
// fluke repeat key press event due to funky OS circumstances.
|
// fluke repeat key press event due to funky OS circumstances.
|
||||||
static int count{};
|
static int count{};
|
||||||
static seconds_t last_count_reset_time{};
|
static seconds_t last_count_reset_time{};
|
||||||
auto now = g_core->GetAppTimeSeconds();
|
auto now = g_core->AppTimeSeconds();
|
||||||
if (now - last_count_reset_time > 2.0) {
|
if (now - last_count_reset_time > 2.0) {
|
||||||
count = 0;
|
count = 0;
|
||||||
last_count_reset_time = now;
|
last_count_reset_time = now;
|
||||||
@ -1238,7 +1238,7 @@ void Input::HandleSmoothMouseScroll_(const Vector2f& velocity, bool momentum) {
|
|||||||
WidgetMessage(WidgetMessage::Type::kMouseWheelVelocityH, nullptr,
|
WidgetMessage(WidgetMessage::Type::kMouseWheelVelocityH, nullptr,
|
||||||
cursor_pos_x_, cursor_pos_y_, velocity.x, momentum));
|
cursor_pos_x_, cursor_pos_y_, velocity.x, momentum));
|
||||||
|
|
||||||
last_mouse_move_time_ = g_core->GetAppTimeSeconds();
|
last_mouse_move_time_ = g_core->AppTimeSeconds();
|
||||||
mouse_move_count_++;
|
mouse_move_count_++;
|
||||||
|
|
||||||
Camera* camera = g_base->graphics->camera();
|
Camera* camera = g_base->graphics->camera();
|
||||||
@ -1282,7 +1282,7 @@ void Input::HandleMouseMotion_(const Vector2f& position) {
|
|||||||
cursor_pos_y_ = g_base->graphics->PixelToVirtualY(
|
cursor_pos_y_ = g_base->graphics->PixelToVirtualY(
|
||||||
position.y * g_base->graphics->screen_pixel_height());
|
position.y * g_base->graphics->screen_pixel_height());
|
||||||
|
|
||||||
last_mouse_move_time_ = g_core->GetAppTimeSeconds();
|
last_mouse_move_time_ = g_core->AppTimeSeconds();
|
||||||
mouse_move_count_++;
|
mouse_move_count_++;
|
||||||
|
|
||||||
// If we have a touch-input in editing mode, pass along events to it. (it
|
// If we have a touch-input in editing mode, pass along events to it. (it
|
||||||
@ -1324,7 +1324,7 @@ void Input::HandleMouseDown_(int button, const Vector2f& position) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_mouse_move_time_ = g_core->GetAppTimeSeconds();
|
last_mouse_move_time_ = g_core->AppTimeSeconds();
|
||||||
mouse_move_count_++;
|
mouse_move_count_++;
|
||||||
|
|
||||||
// Convert normalized view coords to our virtual ones.
|
// Convert normalized view coords to our virtual ones.
|
||||||
@ -1333,7 +1333,7 @@ void Input::HandleMouseDown_(int button, const Vector2f& position) {
|
|||||||
cursor_pos_y_ = g_base->graphics->PixelToVirtualY(
|
cursor_pos_y_ = g_base->graphics->PixelToVirtualY(
|
||||||
position.y * g_base->graphics->screen_pixel_height());
|
position.y * g_base->graphics->screen_pixel_height());
|
||||||
|
|
||||||
millisecs_t click_time = g_core->GetAppTimeMillisecs();
|
millisecs_t click_time = g_core->AppTimeMillisecs();
|
||||||
bool double_click = (click_time - last_click_time_ <= double_click_time_);
|
bool double_click = (click_time - last_click_time_ <= double_click_time_);
|
||||||
last_click_time_ = click_time;
|
last_click_time_ = click_time;
|
||||||
|
|
||||||
@ -1528,7 +1528,7 @@ auto Input::IsCursorVisible() const -> bool {
|
|||||||
bool val;
|
bool val;
|
||||||
|
|
||||||
// Show our cursor only if its been moved recently.
|
// Show our cursor only if its been moved recently.
|
||||||
val = (g_core->GetAppTimeSeconds() - last_mouse_move_time_ < 2.071);
|
val = (g_core->AppTimeSeconds() - last_mouse_move_time_ < 2.071);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -221,7 +221,7 @@ void RemoteAppServer::HandleData(int socket, uint8_t* buffer, size_t amt,
|
|||||||
RemoteAppClient* client = clients_ + joystick_id;
|
RemoteAppClient* client = clients_ + joystick_id;
|
||||||
|
|
||||||
// Take note that we heard from them.
|
// Take note that we heard from them.
|
||||||
client->last_contact_time = g_core->GetAppTimeMillisecs();
|
client->last_contact_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Ok now iterate.
|
// Ok now iterate.
|
||||||
uint8_t* val = buffer + 4;
|
uint8_t* val = buffer + 4;
|
||||||
@ -389,7 +389,7 @@ auto RemoteAppServer::GetClient(int request_id, struct sockaddr* addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't reuse a slot for 5 seconds (if its been heard from since this time).
|
// Don't reuse a slot for 5 seconds (if its been heard from since this time).
|
||||||
millisecs_t cooldown_time = g_core->GetAppTimeMillisecs() - 5000;
|
millisecs_t cooldown_time = g_core->AppTimeMillisecs() - 5000;
|
||||||
|
|
||||||
// Ok, not there already.. now look for a non-taken one and return that.
|
// Ok, not there already.. now look for a non-taken one and return that.
|
||||||
for (int i = 0; i < kMaxRemoteAppClients; i++) {
|
for (int i = 0; i < kMaxRemoteAppClients; i++) {
|
||||||
@ -412,7 +412,7 @@ auto RemoteAppServer::GetClient(int request_id, struct sockaddr* addr,
|
|||||||
strcpy(clients_[i].display_name, clients_[i].name); // NOLINT
|
strcpy(clients_[i].display_name, clients_[i].name); // NOLINT
|
||||||
char* c = strchr(clients_[i].display_name, '#');
|
char* c = strchr(clients_[i].display_name, '#');
|
||||||
if (c) *c = 0;
|
if (c) *c = 0;
|
||||||
clients_[i].last_contact_time = g_core->GetAppTimeMillisecs();
|
clients_[i].last_contact_time = g_core->AppTimeMillisecs();
|
||||||
clients_[i].request_id = request_id;
|
clients_[i].request_id = request_id;
|
||||||
char m[256];
|
char m[256];
|
||||||
|
|
||||||
|
|||||||
@ -236,7 +236,7 @@ void Logic::OnAppShutdown() {
|
|||||||
assert(shutting_down_);
|
assert(shutting_down_);
|
||||||
|
|
||||||
// Nuke the app from orbit if we get stuck while shutting down.
|
// Nuke the app from orbit if we get stuck while shutting down.
|
||||||
g_core->StartSuicideTimer("shutdown", 10000);
|
g_core->StartSuicideTimer("shutdown", 15000);
|
||||||
|
|
||||||
// Tell base to disallow shutdown-suppressors from here on out.
|
// Tell base to disallow shutdown-suppressors from here on out.
|
||||||
g_base->ShutdownSuppressDisallow();
|
g_base->ShutdownSuppressDisallow();
|
||||||
@ -402,7 +402,7 @@ void Logic::UpdateDisplayTimeForHeadlessMode_() {
|
|||||||
// scheduled (or at least close enough so we can fudge it and tell them
|
// scheduled (or at least close enough so we can fudge it and tell them
|
||||||
// its that exact time).
|
// its that exact time).
|
||||||
|
|
||||||
auto app_time_microsecs = g_core->GetAppTimeMicrosecs();
|
auto app_time_microsecs = g_core->AppTimeMicrosecs();
|
||||||
|
|
||||||
// Set our int based time vals so we can exactly hit timers.
|
// Set our int based time vals so we can exactly hit timers.
|
||||||
auto old_display_time_microsecs = display_time_microsecs_;
|
auto old_display_time_microsecs = display_time_microsecs_;
|
||||||
@ -438,7 +438,7 @@ void Logic::PostUpdateDisplayTimeForHeadlessMode_() {
|
|||||||
[headless_display_step_microsecs] {
|
[headless_display_step_microsecs] {
|
||||||
auto sleepsecs =
|
auto sleepsecs =
|
||||||
static_cast<double>(headless_display_step_microsecs) / 1000000.0;
|
static_cast<double>(headless_display_step_microsecs) / 1000000.0;
|
||||||
auto apptimesecs = g_core->GetAppTimeSeconds();
|
auto apptimesecs = g_core->AppTimeSeconds();
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer),
|
snprintf(buffer, sizeof(buffer),
|
||||||
"will try to sleep for %.4f at app-time %.4f (until %.4f)",
|
"will try to sleep for %.4f at app-time %.4f (until %.4f)",
|
||||||
@ -467,7 +467,7 @@ void Logic::UpdateDisplayTimeForFrameDraw_() {
|
|||||||
// - 'current' should mostly show '(avg)'; rarely '(sample)'.
|
// - 'current' should mostly show '(avg)'; rarely '(sample)'.
|
||||||
// - these can vary briefly during load spikes/etc. but should quickly
|
// - these can vary briefly during load spikes/etc. but should quickly
|
||||||
// reconverge to stability. If not, this may need further calibration.
|
// reconverge to stability. If not, this may need further calibration.
|
||||||
auto current_app_time = g_core->GetAppTimeSeconds();
|
auto current_app_time = g_core->AppTimeSeconds();
|
||||||
|
|
||||||
// We handle the first measurement specially.
|
// We handle the first measurement specially.
|
||||||
if (last_display_time_update_app_time_ < 0) {
|
if (last_display_time_update_app_time_ < 0) {
|
||||||
|
|||||||
@ -330,8 +330,8 @@ static auto PyAppTime(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
const_cast<char**>(kwlist))) {
|
const_cast<char**>(kwlist))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return PyFloat_FromDouble(
|
return PyFloat_FromDouble(0.001
|
||||||
0.001 * static_cast<double>(g_core->GetAppTimeMillisecs()));
|
* static_cast<double>(g_core->AppTimeMillisecs()));
|
||||||
BA_PYTHON_CATCH;
|
BA_PYTHON_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -497,7 +497,7 @@ static auto PyEvaluateLstr(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return PyUnicode_FromString(
|
return PyUnicode_FromString(
|
||||||
g_base->assets->CompileResourceString(value, "evaluate_lstr").c_str());
|
g_base->assets->CompileResourceString(value).c_str());
|
||||||
BA_PYTHON_CATCH;
|
BA_PYTHON_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,7 +533,7 @@ static auto PyGetStringHeight(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
}
|
}
|
||||||
s = g_base->python->GetPyLString(s_obj);
|
s = g_base->python->GetPyLString(s_obj);
|
||||||
#if BA_DEBUG_BUILD
|
#if BA_DEBUG_BUILD
|
||||||
if (g_base->assets->CompileResourceString(s, "get_string_height test") != s) {
|
if (g_base->assets->CompileResourceString(s) != s) {
|
||||||
BA_LOG_PYTHON_TRACE(
|
BA_LOG_PYTHON_TRACE(
|
||||||
"resource-string passed to get_string_height; this should be avoided");
|
"resource-string passed to get_string_height; this should be avoided");
|
||||||
}
|
}
|
||||||
@ -579,8 +579,7 @@ static auto PyGetStringWidth(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
}
|
}
|
||||||
s = g_base->python->GetPyLString(s_obj);
|
s = g_base->python->GetPyLString(s_obj);
|
||||||
#if BA_DEBUG_BUILD
|
#if BA_DEBUG_BUILD
|
||||||
if (g_base->assets->CompileResourceString(s, "get_string_width debug test")
|
if (g_base->assets->CompileResourceString(s) != s) {
|
||||||
!= s) {
|
|
||||||
BA_LOG_PYTHON_TRACE(
|
BA_LOG_PYTHON_TRACE(
|
||||||
"resource-string passed to get_string_width; this should be avoided");
|
"resource-string passed to get_string_width; this should be avoided");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ballistica/base/base.h"
|
#include "ballistica/base/base.h"
|
||||||
|
#include "ballistica/shared/math/vector3f.h"
|
||||||
|
|
||||||
namespace ballistica::base {
|
namespace ballistica::base {
|
||||||
|
|
||||||
@ -46,6 +47,11 @@ class ClassicSoftInterface {
|
|||||||
virtual auto GetV1AccountTypeIconString(int account_type) -> std::string = 0;
|
virtual auto GetV1AccountTypeIconString(int account_type) -> std::string = 0;
|
||||||
virtual auto V1AccountTypeToString(int account_type) -> std::string = 0;
|
virtual auto V1AccountTypeToString(int account_type) -> std::string = 0;
|
||||||
virtual void PlayMusic(const std::string& music_type, bool continuous) = 0;
|
virtual void PlayMusic(const std::string& music_type, bool continuous) = 0;
|
||||||
|
virtual void GetClassicChestDisplayInfo(const std::string& id,
|
||||||
|
std::string* texclosed,
|
||||||
|
std::string* texclosedtint,
|
||||||
|
Vector3f* color, Vector3f* tint,
|
||||||
|
Vector3f* tint2) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ballistica::base
|
} // namespace ballistica::base
|
||||||
|
|||||||
@ -15,6 +15,7 @@ namespace ballistica::base {
|
|||||||
// other mechanisms are set up to preserve and restore context before
|
// other mechanisms are set up to preserve and restore context before
|
||||||
// running, and objects can also be invalidated or otherwise cleaned up
|
// running, and objects can also be invalidated or otherwise cleaned up
|
||||||
// when the context they were created under dies.
|
// when the context they were created under dies.
|
||||||
|
//
|
||||||
// The end goal of all this is to support api styles for end users where
|
// The end goal of all this is to support api styles for end users where
|
||||||
// standalone snippets of code can be useful; ie: something like
|
// standalone snippets of code can be useful; ie: something like
|
||||||
// bs.newnode() to create something meaningful without having to worry
|
// bs.newnode() to create something meaningful without having to worry
|
||||||
@ -36,26 +37,27 @@ class ContextRef {
|
|||||||
ContextRef();
|
ContextRef();
|
||||||
explicit ContextRef(Context* sgc);
|
explicit ContextRef(Context* sgc);
|
||||||
|
|
||||||
/// ContextRefs are considered equal if both are pointing to the exact same
|
/// ContextRefs are considered equal if both are pointing to the exact
|
||||||
/// Context object (or both are pointing to no Context).
|
/// same Context object (or both are pointing to no Context).
|
||||||
auto operator==(const ContextRef& other) const -> bool;
|
auto operator==(const ContextRef& other) const -> bool;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto GetContextTyped() const -> T* {
|
auto GetContextTyped() const -> T* {
|
||||||
// Ew; dynamic cast.
|
// Ew; dynamic cast.
|
||||||
// Note: if it ever seems like speed is an issue here, we can
|
//
|
||||||
// cache the results with std::type_index entries. There should
|
// Note: if it ever seems like speed is an issue here, we can cache the
|
||||||
// generally be a very small number of types involved.
|
// results with std::type_index entries. There should generally be a
|
||||||
|
// very small number of types involved.
|
||||||
return dynamic_cast<T*>(target_.get());
|
return dynamic_cast<T*>(target_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An empty context-ref was explicitly set to an empty state.
|
/// An empty context-ref was explicitly set to an empty state. Note that
|
||||||
/// Note that this is different than an expired context-ref, which
|
/// this is different than an expired context-ref, which originally
|
||||||
/// originally pointed to some context that has since died.
|
/// pointed to some context that has since died.
|
||||||
auto IsEmpty() const { return empty_; }
|
auto IsEmpty() const { return empty_; }
|
||||||
|
|
||||||
/// Has this context died since it was set?
|
/// Has this context died since it was set? Note that a context created as
|
||||||
/// Note that a context created as empty is not considered expired.
|
/// empty is not considered expired.
|
||||||
auto IsExpired() const -> bool {
|
auto IsExpired() const -> bool {
|
||||||
if (empty_) {
|
if (empty_) {
|
||||||
return false; // Can't kill what was never alive.
|
return false; // Can't kill what was never alive.
|
||||||
@ -64,7 +66,8 @@ class ContextRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the context this ref points to. This will be nullptr for empty
|
/// Return the context this ref points to. This will be nullptr for empty
|
||||||
/// contexts. Throws an exception if a target context was set but has expired.
|
/// contexts. Throws an exception if a target context was set but has
|
||||||
|
/// expired.
|
||||||
auto Get() const -> Context* {
|
auto Get() const -> Context* {
|
||||||
auto* target = target_.get();
|
auto* target = target_.get();
|
||||||
if (target == nullptr && !empty_) {
|
if (target == nullptr && !empty_) {
|
||||||
@ -84,14 +87,13 @@ class ContextRef {
|
|||||||
bool empty_;
|
bool empty_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Object containing the actual context_ref data/information.
|
/// Object containing the actual context_ref data/information. App-modes can
|
||||||
/// App-modes can subclass this to provide the actual context_ref they desire,
|
/// subclass this to provide the actual context_ref they desire, and then
|
||||||
/// and then code can use CurrentTyped() to safely retrieve context_ref as that
|
/// code can use CurrentTyped() to safely retrieve context_ref as that type.
|
||||||
/// type.
|
|
||||||
class Context : public Object {
|
class Context : public Object {
|
||||||
public:
|
public:
|
||||||
/// Return the current context_ref cast to a desired type.
|
/// Return the current context_ref cast to a desired type. Throws an
|
||||||
/// Throws an Exception if the context_ref is unset or is another type.
|
/// Exception if the context_ref is unset or is another type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static auto CurrentTyped() -> T& {
|
static auto CurrentTyped() -> T& {
|
||||||
T* t = g_base->CurrentContext().GetContextTyped<T>();
|
T* t = g_base->CurrentContext().GetContextTyped<T>();
|
||||||
@ -102,13 +104,13 @@ class Context : public Object {
|
|||||||
return *t;
|
return *t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a PythonContextCall is created in this context_ref.
|
/// Called when a PythonContextCall is created in this context_ref. The
|
||||||
/// The context_ref class may want to store a weak-reference to the
|
/// context_ref class may want to store a weak-reference to the call and
|
||||||
/// call and inform the call when the context_ref is going down so that
|
/// inform the call when the context_ref is going down so that resources
|
||||||
/// resources may be freed. Other permanent contexts may not need to
|
/// may be freed. Other permanent contexts may not need to bother.
|
||||||
/// bother.
|
///
|
||||||
/// FIXME: This mechanism can probably be generalized so that other
|
/// FIXME: This mechanism can probably be generalized so that other things
|
||||||
/// things such as assets and timers can use it.
|
/// such as assets and timers can use it.
|
||||||
virtual void RegisterContextCall(PythonContextCall* call);
|
virtual void RegisterContextCall(PythonContextCall* call);
|
||||||
|
|
||||||
/// Return a short description of the context_ref; will be used when
|
/// Return a short description of the context_ref; will be used when
|
||||||
@ -118,9 +120,9 @@ class Context : public Object {
|
|||||||
|
|
||||||
/// Return whether this context should allow default timer-types to be
|
/// Return whether this context should allow default timer-types to be
|
||||||
/// created within it (AppTimer, DisplayTimer). Scene type contexts
|
/// created within it (AppTimer, DisplayTimer). Scene type contexts
|
||||||
/// generally have their own timer types which are better integrated
|
/// generally have their own timer types which are better integrated with
|
||||||
/// with scenes (responding to changes in game speed/etc.) so this can
|
/// scenes (responding to changes in game speed/etc.) so this can be used
|
||||||
/// be used to encourage/enforce usage of those timers.
|
/// to encourage/enforce usage of those timers.
|
||||||
virtual auto ContextAllowsDefaultTimerTypes() -> bool;
|
virtual auto ContextAllowsDefaultTimerTypes() -> bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1683,7 +1683,7 @@ auto DevConsole::PasteFromClipboard() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DevConsole::UpdateCarat_() {
|
void DevConsole::UpdateCarat_() {
|
||||||
last_carat_x_change_time_ = g_core->GetAppTimeMillisecs();
|
last_carat_x_change_time_ = g_core->AppTimeMillisecs();
|
||||||
auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjfwef");
|
auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjfwef");
|
||||||
auto unichars_clamped = unichars;
|
auto unichars_clamped = unichars;
|
||||||
|
|
||||||
|
|||||||
@ -370,7 +370,7 @@ void UI::SetUIInputDevice(InputDevice* input_device) {
|
|||||||
ui_input_device_ = input_device;
|
ui_input_device_ = input_device;
|
||||||
|
|
||||||
// So they dont get stolen from immediately.
|
// So they dont get stolen from immediately.
|
||||||
last_input_device_use_time_ = g_core->GetAppTimeMillisecs();
|
last_input_device_use_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::Reset() {
|
void UI::Reset() {
|
||||||
@ -432,7 +432,7 @@ auto UI::GetWidgetForInput(InputDevice* input_device) -> ui_v1::Widget* {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
millisecs_t time = g_core->GetAppTimeMillisecs();
|
millisecs_t time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
bool print_menu_owner{};
|
bool print_menu_owner{};
|
||||||
ui_v1::Widget* ret_val;
|
ui_v1::Widget* ret_val;
|
||||||
|
|||||||
@ -250,4 +250,11 @@ void ClassicFeatureSet::PlayMusic(const std::string& music_type,
|
|||||||
python->PlayMusic(music_type, continuous);
|
python->PlayMusic(music_type, continuous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassicFeatureSet::GetClassicChestDisplayInfo(
|
||||||
|
const std::string& id, std::string* texclosed, std::string* texclosedtint,
|
||||||
|
Vector3f* color, Vector3f* tint, Vector3f* tint2) {
|
||||||
|
python->GetClassicChestDisplayInfo(id, texclosed, texclosedtint, color, tint,
|
||||||
|
tint2);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ballistica::classic
|
} // namespace ballistica::classic
|
||||||
|
|||||||
@ -108,6 +108,9 @@ class ClassicFeatureSet : public FeatureSetNativeComponent,
|
|||||||
auto GetV1AccountTypeIconString(int account_type) -> std::string override;
|
auto GetV1AccountTypeIconString(int account_type) -> std::string override;
|
||||||
auto V1AccountTypeToString(int account_type) -> std::string override;
|
auto V1AccountTypeToString(int account_type) -> std::string override;
|
||||||
auto GetV1AccountType() -> int override;
|
auto GetV1AccountType() -> int override;
|
||||||
|
void GetClassicChestDisplayInfo(const std::string& id, std::string* texclosed,
|
||||||
|
std::string* texclosedtint, Vector3f* color,
|
||||||
|
Vector3f* tint, Vector3f* tint2) override;
|
||||||
|
|
||||||
ClassicPython* const python;
|
ClassicPython* const python;
|
||||||
V1Account* const v1_account;
|
V1Account* const v1_account;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "ballistica/base/python/base_python.h"
|
||||||
#include "ballistica/classic/python/methods/python_methods_classic.h"
|
#include "ballistica/classic/python/methods/python_methods_classic.h"
|
||||||
#include "ballistica/classic/support/classic_app_mode.h"
|
#include "ballistica/classic/support/classic_app_mode.h"
|
||||||
#include "ballistica/shared/python/python_command.h" // IWYU pragma: keep.
|
#include "ballistica/shared/python/python_command.h" // IWYU pragma: keep.
|
||||||
@ -30,6 +31,60 @@ extern "C" auto PyInit__baclassic() -> PyObject* {
|
|||||||
|
|
||||||
void ClassicPython::ImportPythonObjs() {
|
void ClassicPython::ImportPythonObjs() {
|
||||||
#include "ballistica/classic/mgen/pyembed/binding_classic.inc"
|
#include "ballistica/classic/mgen/pyembed/binding_classic.inc"
|
||||||
|
|
||||||
|
// Cache some basic display values for chests from the Python layer. This
|
||||||
|
// way C++ UI stuff doesn't have to call out to Python when drawing the
|
||||||
|
// root UI/etc.
|
||||||
|
|
||||||
|
// Pull default chest display info.
|
||||||
|
chest_display_default_ = {ChestDisplayFromPython(
|
||||||
|
objs().Get(ObjID::kChestAppearanceDisplayInfoDefault))};
|
||||||
|
|
||||||
|
// And overrides.
|
||||||
|
for (auto&& item :
|
||||||
|
objs().Get(ObjID::kChestAppearanceDisplayInfos).DictItems()) {
|
||||||
|
chest_displays_[item.first.GetAttr("value").ValueAsString()] =
|
||||||
|
ChestDisplayFromPython(item.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ClassicPython::ChestDisplayFromPython(const PythonRef& ref)
|
||||||
|
-> ChestDisplay_ {
|
||||||
|
ChestDisplay_ out;
|
||||||
|
|
||||||
|
out.texclosed = ref.GetAttr("texclosed").ValueAsString().c_str();
|
||||||
|
out.texclosedtint = ref.GetAttr("texclosedtint").ValueAsString().c_str();
|
||||||
|
out.color = base::BasePython::GetPyVector3f(ref.GetAttr("color").get());
|
||||||
|
out.tint = base::BasePython::GetPyVector3f(ref.GetAttr("tint").get());
|
||||||
|
out.tint2 = base::BasePython::GetPyVector3f(ref.GetAttr("tint2").get());
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicPython::GetClassicChestDisplayInfo(const std::string& id,
|
||||||
|
std::string* texclosed,
|
||||||
|
std::string* texclosedtint,
|
||||||
|
Vector3f* color, Vector3f* tint,
|
||||||
|
Vector3f* tint2) {
|
||||||
|
assert(texclosed);
|
||||||
|
assert(texclosedtint);
|
||||||
|
assert(color);
|
||||||
|
assert(tint);
|
||||||
|
assert(tint2);
|
||||||
|
auto&& display{chest_displays_.find(id)};
|
||||||
|
if (display != chest_displays_.end()) {
|
||||||
|
*texclosed = display->second.texclosed;
|
||||||
|
*texclosedtint = display->second.texclosedtint;
|
||||||
|
*color = display->second.color;
|
||||||
|
*tint = display->second.tint;
|
||||||
|
*tint2 = display->second.tint2;
|
||||||
|
} else {
|
||||||
|
*texclosed = chest_display_default_.texclosed;
|
||||||
|
*texclosedtint = chest_display_default_.texclosedtint;
|
||||||
|
*color = chest_display_default_.color;
|
||||||
|
*tint = chest_display_default_.tint;
|
||||||
|
*tint2 = chest_display_default_.tint2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicPython::PlayMusic(const std::string& music_type, bool continuous) {
|
void ClassicPython::PlayMusic(const std::string& music_type, bool continuous) {
|
||||||
|
|||||||
@ -4,9 +4,11 @@
|
|||||||
#define BALLISTICA_CLASSIC_PYTHON_CLASSIC_PYTHON_H_
|
#define BALLISTICA_CLASSIC_PYTHON_CLASSIC_PYTHON_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "ballistica/base/base.h"
|
#include "ballistica/base/base.h"
|
||||||
#include "ballistica/classic/classic.h"
|
#include "ballistica/classic/classic.h"
|
||||||
|
#include "ballistica/shared/math/vector3f.h"
|
||||||
#include "ballistica/shared/python/python_object_set.h"
|
#include "ballistica/shared/python/python_object_set.h"
|
||||||
|
|
||||||
namespace ballistica::classic {
|
namespace ballistica::classic {
|
||||||
@ -20,6 +22,8 @@ class ClassicPython {
|
|||||||
enum class ObjID {
|
enum class ObjID {
|
||||||
kDoPlayMusicCall,
|
kDoPlayMusicCall,
|
||||||
kGetInputDeviceMappedValueCall,
|
kGetInputDeviceMappedValueCall,
|
||||||
|
kChestAppearanceDisplayInfoDefault,
|
||||||
|
kChestAppearanceDisplayInfos,
|
||||||
kLast // Sentinel; must be at end.
|
kLast // Sentinel; must be at end.
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,7 +38,22 @@ class ClassicPython {
|
|||||||
|
|
||||||
const auto& objs() { return objs_; }
|
const auto& objs() { return objs_; }
|
||||||
|
|
||||||
|
void GetClassicChestDisplayInfo(const std::string& id, std::string* texclosed,
|
||||||
|
std::string* texclosedtint, Vector3f* color,
|
||||||
|
Vector3f* tint, Vector3f* tint2);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct ChestDisplay_ {
|
||||||
|
Vector3f color;
|
||||||
|
std::string texclosed;
|
||||||
|
std::string texclosedtint;
|
||||||
|
Vector3f tint;
|
||||||
|
Vector3f tint2;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ChestDisplayFromPython(const PythonRef& ref) -> ChestDisplay_;
|
||||||
|
ChestDisplay_ chest_display_default_;
|
||||||
|
std::unordered_map<std::string, ChestDisplay_> chest_displays_;
|
||||||
PythonObjectSet<ObjID> objs_;
|
PythonObjectSet<ObjID> objs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
#include "ballistica/classic/python/methods/python_methods_classic.h"
|
#include "ballistica/classic/python/methods/python_methods_classic.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -296,9 +295,9 @@ static auto PySetRootUIAccountValues(PyObject* self, PyObject* args,
|
|||||||
PyObject* keywds) -> PyObject* {
|
PyObject* keywds) -> PyObject* {
|
||||||
BA_PYTHON_TRY;
|
BA_PYTHON_TRY;
|
||||||
|
|
||||||
const char* tickets_text;
|
int tickets;
|
||||||
const char* tokens_text;
|
int tokens;
|
||||||
const char* league_rank_text;
|
int league_rank;
|
||||||
const char* league_type;
|
const char* league_type;
|
||||||
const char* achievements_percent_text;
|
const char* achievements_percent_text;
|
||||||
const char* level_text;
|
const char* level_text;
|
||||||
@ -308,19 +307,19 @@ static auto PySetRootUIAccountValues(PyObject* self, PyObject* args,
|
|||||||
const char* chest_1_appearance;
|
const char* chest_1_appearance;
|
||||||
const char* chest_2_appearance;
|
const char* chest_2_appearance;
|
||||||
const char* chest_3_appearance;
|
const char* chest_3_appearance;
|
||||||
float chest_0_unlock_time;
|
double chest_0_unlock_time;
|
||||||
float chest_1_unlock_time;
|
double chest_1_unlock_time;
|
||||||
float chest_2_unlock_time;
|
double chest_2_unlock_time;
|
||||||
float chest_3_unlock_time;
|
double chest_3_unlock_time;
|
||||||
float chest_0_ad_allow_time;
|
double chest_0_ad_allow_time;
|
||||||
float chest_1_ad_allow_time;
|
double chest_1_ad_allow_time;
|
||||||
float chest_2_ad_allow_time;
|
double chest_2_ad_allow_time;
|
||||||
float chest_3_ad_allow_time;
|
double chest_3_ad_allow_time;
|
||||||
int gold_pass{};
|
int gold_pass{};
|
||||||
|
|
||||||
static const char* kwlist[] = {"tickets_text",
|
static const char* kwlist[] = {"tickets",
|
||||||
"tokens_text",
|
"tokens",
|
||||||
"league_rank_text",
|
"league_rank",
|
||||||
"league_type",
|
"league_type",
|
||||||
"achievements_percent_text",
|
"achievements_percent_text",
|
||||||
"level_text",
|
"level_text",
|
||||||
@ -341,8 +340,8 @@ static auto PySetRootUIAccountValues(PyObject* self, PyObject* args,
|
|||||||
"chest_3_ad_allow_time",
|
"chest_3_ad_allow_time",
|
||||||
nullptr};
|
nullptr};
|
||||||
if (!PyArg_ParseTupleAndKeywords(
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
args, keywds, "sssssssspssssffffffff", const_cast<char**>(kwlist),
|
args, keywds, "iiissssspssssdddddddd", const_cast<char**>(kwlist),
|
||||||
&tickets_text, &tokens_text, &league_rank_text, &league_type,
|
&tickets, &tokens, &league_rank, &league_type,
|
||||||
&achievements_percent_text, &level_text, &xp_text, &inbox_count_text,
|
&achievements_percent_text, &level_text, &xp_text, &inbox_count_text,
|
||||||
&gold_pass, &chest_0_appearance, &chest_1_appearance,
|
&gold_pass, &chest_0_appearance, &chest_1_appearance,
|
||||||
&chest_2_appearance, &chest_3_appearance, &chest_0_unlock_time,
|
&chest_2_appearance, &chest_3_appearance, &chest_0_unlock_time,
|
||||||
@ -357,20 +356,21 @@ static auto PySetRootUIAccountValues(PyObject* self, PyObject* args,
|
|||||||
|
|
||||||
// Pass these all along to the app-mode which will store them and forward
|
// Pass these all along to the app-mode which will store them and forward
|
||||||
// them to any existing UI.
|
// them to any existing UI.
|
||||||
appmode->SetRootUITicketsMeterText(tickets_text);
|
appmode->SetRootUITicketsMeterValue(tickets);
|
||||||
appmode->SetRootUITokensMeterText(tokens_text);
|
appmode->SetRootUITokensMeterValue(tokens);
|
||||||
appmode->SetRootUILeagueRankText(league_rank_text);
|
appmode->SetRootUILeagueRankValue(league_rank);
|
||||||
appmode->SetRootUILeagueType(league_type);
|
appmode->SetRootUILeagueType(league_type);
|
||||||
appmode->SetRootUIAchievementsPercentText(achievements_percent_text);
|
appmode->SetRootUIAchievementsPercentText(achievements_percent_text);
|
||||||
appmode->SetRootUILevelText(level_text);
|
appmode->SetRootUILevelText(level_text);
|
||||||
appmode->SetRootUIXPText(xp_text);
|
appmode->SetRootUIXPText(xp_text);
|
||||||
appmode->SetRootUIInboxCountText(inbox_count_text);
|
appmode->SetRootUIInboxCountText(inbox_count_text);
|
||||||
appmode->SetRootUIGoldPass(gold_pass);
|
appmode->SetRootUIGoldPass(gold_pass);
|
||||||
appmode->SetRootUIChests(chest_0_appearance, chest_1_appearance,
|
appmode->SetRootUIChests(
|
||||||
chest_2_appearance, chest_3_appearance);
|
chest_0_appearance, chest_1_appearance, chest_2_appearance,
|
||||||
|
chest_3_appearance, chest_0_unlock_time, chest_1_unlock_time,
|
||||||
|
chest_2_unlock_time, chest_3_unlock_time, chest_0_ad_allow_time,
|
||||||
|
chest_1_ad_allow_time, chest_2_ad_allow_time, chest_3_ad_allow_time);
|
||||||
|
|
||||||
printf("WOULD SET TIMES TO %.2f %.2f\n", chest_0_unlock_time,
|
|
||||||
chest_0_ad_allow_time);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
BA_PYTHON_CATCH;
|
BA_PYTHON_CATCH;
|
||||||
}
|
}
|
||||||
@ -381,9 +381,9 @@ static PyMethodDef PySetRootUIAccountValuesDef = {
|
|||||||
METH_VARARGS | METH_KEYWORDS, // flags
|
METH_VARARGS | METH_KEYWORDS, // flags
|
||||||
|
|
||||||
"set_root_ui_account_values(*,\n"
|
"set_root_ui_account_values(*,\n"
|
||||||
" tickets_text: str,\n"
|
" tickets: int,\n"
|
||||||
" tokens_text: str,\n"
|
" tokens: int,\n"
|
||||||
" league_rank_text: str,\n"
|
" league_rank: int,\n"
|
||||||
" league_type: str,\n"
|
" league_type: str,\n"
|
||||||
" achievements_percent_text: str,\n"
|
" achievements_percent_text: str,\n"
|
||||||
" level_text: str,\n"
|
" level_text: str,\n"
|
||||||
|
|||||||
@ -149,10 +149,10 @@ void ClassicAppMode::Reset_() {
|
|||||||
// At this point uiv1 is in a reset-to-default state. Now plug in our
|
// At this point uiv1 is in a reset-to-default state. Now plug in our
|
||||||
// current values for everything.
|
// current values for everything.
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetTicketsMeterText(root_ui_tickets_meter_text_);
|
root_widget->SetTicketsMeterValue(root_ui_tickets_meter_value_);
|
||||||
root_widget->SetTokensMeterText(root_ui_tokens_meter_text_,
|
root_widget->SetTokensMeterValue(root_ui_tokens_meter_value_,
|
||||||
root_ui_gold_pass_);
|
root_ui_gold_pass_);
|
||||||
root_widget->SetLeagueRankText(root_ui_league_rank_text_);
|
root_widget->SetLeagueRankValue(root_ui_league_rank_value_);
|
||||||
root_widget->SetLeagueType(root_ui_league_type_);
|
root_widget->SetLeagueType(root_ui_league_type_);
|
||||||
root_widget->SetAchievementPercentText(root_ui_achievement_percent_text_);
|
root_widget->SetAchievementPercentText(root_ui_achievement_percent_text_);
|
||||||
root_widget->SetLevelText(root_ui_level_text_);
|
root_widget->SetLevelText(root_ui_level_text_);
|
||||||
@ -160,7 +160,11 @@ void ClassicAppMode::Reset_() {
|
|||||||
root_widget->SetInboxCountText(root_ui_inbox_count_text_);
|
root_widget->SetInboxCountText(root_ui_inbox_count_text_);
|
||||||
root_widget->SetChests(
|
root_widget->SetChests(
|
||||||
root_ui_chest_0_appearance_, root_ui_chest_1_appearance_,
|
root_ui_chest_0_appearance_, root_ui_chest_1_appearance_,
|
||||||
root_ui_chest_2_appearance_, root_ui_chest_3_appearance_);
|
root_ui_chest_2_appearance_, root_ui_chest_3_appearance_,
|
||||||
|
root_ui_chest_0_unlock_time_, root_ui_chest_1_unlock_time_,
|
||||||
|
root_ui_chest_2_unlock_time_, root_ui_chest_3_unlock_time_,
|
||||||
|
root_ui_chest_0_ad_allow_time_, root_ui_chest_1_ad_allow_time_,
|
||||||
|
root_ui_chest_2_ad_allow_time_, root_ui_chest_3_ad_allow_time_);
|
||||||
root_widget->SetHaveLiveValues(root_ui_have_live_values_);
|
root_widget->SetHaveLiveValues(root_ui_have_live_values_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,7 +336,7 @@ void ClassicAppMode::HostScanCycle() {
|
|||||||
&((reinterpret_cast<sockaddr_in*>(&from))->sin_addr),
|
&((reinterpret_cast<sockaddr_in*>(&from))->sin_addr),
|
||||||
buffer2, sizeof(buffer2));
|
buffer2, sizeof(buffer2));
|
||||||
entry.last_query_id = query_id;
|
entry.last_query_id = query_id;
|
||||||
entry.last_contact_time = g_core->GetAppTimeMillisecs();
|
entry.last_contact_time = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PruneScanResults_();
|
PruneScanResults_();
|
||||||
@ -357,7 +361,7 @@ void ClassicAppMode::EndHostScanning() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::PruneScanResults_() {
|
void ClassicAppMode::PruneScanResults_() {
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs();
|
millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
auto i = scan_results_.begin();
|
auto i = scan_results_.begin();
|
||||||
while (i != scan_results_.end()) {
|
while (i != scan_results_.end()) {
|
||||||
auto i_next = i;
|
auto i_next = i;
|
||||||
@ -516,8 +520,8 @@ auto ClassicAppMode::GetHeadlessNextDisplayTimeStep() -> microsecs_t {
|
|||||||
void ClassicAppMode::StepDisplayTime() {
|
void ClassicAppMode::StepDisplayTime() {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
auto startms{core::CorePlatform::GetCurrentMillisecs()};
|
auto startms{core::CorePlatform::TimeMonotonicMillisecs()};
|
||||||
millisecs_t app_time = g_core->GetAppTimeMillisecs();
|
millisecs_t app_time = g_core->AppTimeMillisecs();
|
||||||
g_core->platform->SetDebugKey("LastUpdateTime", std::to_string(startms));
|
g_core->platform->SetDebugKey("LastUpdateTime", std::to_string(startms));
|
||||||
in_update_ = true;
|
in_update_ = true;
|
||||||
|
|
||||||
@ -592,7 +596,7 @@ void ClassicAppMode::StepDisplayTime() {
|
|||||||
// Report excessively long updates.
|
// Report excessively long updates.
|
||||||
if (g_core->core_config().debug_timing
|
if (g_core->core_config().debug_timing
|
||||||
&& app_time >= next_long_update_report_time_) {
|
&& app_time >= next_long_update_report_time_) {
|
||||||
auto duration{core::CorePlatform::GetCurrentMillisecs() - startms};
|
auto duration{core::CorePlatform::TimeMonotonicMillisecs() - startms};
|
||||||
|
|
||||||
// Complain when our full update takes longer than 1/60th second.
|
// Complain when our full update takes longer than 1/60th second.
|
||||||
if (duration > (1000 / 60)) {
|
if (duration > (1000 / 60)) {
|
||||||
@ -762,7 +766,7 @@ void ClassicAppMode::UpdateKickVote_() {
|
|||||||
kick_vote_in_progress_ = false;
|
kick_vote_in_progress_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
millisecs_t current_time{g_core->GetAppTimeMillisecs()};
|
millisecs_t current_time{g_core->AppTimeMillisecs()};
|
||||||
int total_client_count = 0;
|
int total_client_count = 0;
|
||||||
int yes_votes = 0;
|
int yes_votes = 0;
|
||||||
int no_votes = 0;
|
int no_votes = 0;
|
||||||
@ -859,7 +863,7 @@ void ClassicAppMode::UpdateKickVote_() {
|
|||||||
void ClassicAppMode::StartKickVote(scene_v1::ConnectionToClient* starter,
|
void ClassicAppMode::StartKickVote(scene_v1::ConnectionToClient* starter,
|
||||||
scene_v1::ConnectionToClient* target) {
|
scene_v1::ConnectionToClient* target) {
|
||||||
// Restrict votes per client.
|
// Restrict votes per client.
|
||||||
millisecs_t current_time = g_core->GetAppTimeMillisecs();
|
millisecs_t current_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
if (starter == target) {
|
if (starter == target) {
|
||||||
// Don't let anyone kick themselves.
|
// Don't let anyone kick themselves.
|
||||||
@ -1413,7 +1417,7 @@ auto ClassicAppMode::ShouldAnnouncePartyJoinsAndLeaves() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ClassicAppMode::IsPlayerBanned(const scene_v1::PlayerSpec& spec) -> bool {
|
auto ClassicAppMode::IsPlayerBanned(const scene_v1::PlayerSpec& spec) -> bool {
|
||||||
millisecs_t current_time = g_core->GetAppTimeMillisecs();
|
millisecs_t current_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Now is a good time to prune no-longer-banned specs.
|
// Now is a good time to prune no-longer-banned specs.
|
||||||
while (!banned_players_.empty()
|
while (!banned_players_.empty()
|
||||||
@ -1431,7 +1435,7 @@ auto ClassicAppMode::IsPlayerBanned(const scene_v1::PlayerSpec& spec) -> bool {
|
|||||||
|
|
||||||
void ClassicAppMode::BanPlayer(const scene_v1::PlayerSpec& spec,
|
void ClassicAppMode::BanPlayer(const scene_v1::PlayerSpec& spec,
|
||||||
millisecs_t duration) {
|
millisecs_t duration) {
|
||||||
banned_players_.emplace_back(g_core->GetAppTimeMillisecs() + duration, spec);
|
banned_players_.emplace_back(g_core->AppTimeMillisecs() + duration, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::HandleQuitOnIdle_() {
|
void ClassicAppMode::HandleQuitOnIdle_() {
|
||||||
@ -1550,51 +1554,51 @@ void ClassicAppMode::RunMainMenu() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::SetRootUITicketsMeterText(const std::string text) {
|
void ClassicAppMode::SetRootUITicketsMeterValue(int value) {
|
||||||
BA_PRECONDITION(g_base->InLogicThread());
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
if (text == root_ui_tickets_meter_text_) {
|
if (value == root_ui_tickets_meter_value_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Store the value.
|
// Store the value.
|
||||||
root_ui_tickets_meter_text_ = text;
|
root_ui_tickets_meter_value_ = value;
|
||||||
|
|
||||||
// Apply it to any existing UI.
|
// Apply it to any existing UI.
|
||||||
if (uiv1_) {
|
if (uiv1_) {
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetTicketsMeterText(root_ui_tickets_meter_text_);
|
root_widget->SetTicketsMeterValue(root_ui_tickets_meter_value_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::SetRootUITokensMeterText(const std::string text) {
|
void ClassicAppMode::SetRootUITokensMeterValue(int value) {
|
||||||
BA_PRECONDITION(g_base->InLogicThread());
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
if (text == root_ui_tokens_meter_text_) {
|
if (value == root_ui_tokens_meter_value_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Store the value.
|
// Store the value.
|
||||||
root_ui_tokens_meter_text_ = text;
|
root_ui_tokens_meter_value_ = value;
|
||||||
|
|
||||||
// Apply it to any existing UI.
|
// Apply it to any existing UI.
|
||||||
if (uiv1_) {
|
if (uiv1_) {
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetTokensMeterText(root_ui_tokens_meter_text_,
|
root_widget->SetTokensMeterValue(root_ui_tokens_meter_value_,
|
||||||
root_ui_gold_pass_);
|
root_ui_gold_pass_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::SetRootUILeagueRankText(const std::string text) {
|
void ClassicAppMode::SetRootUILeagueRankValue(int value) {
|
||||||
BA_PRECONDITION(g_base->InLogicThread());
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
if (text == root_ui_league_rank_text_) {
|
if (value == root_ui_league_rank_value_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Store the value.
|
// Store the value.
|
||||||
root_ui_league_rank_text_ = text;
|
root_ui_league_rank_value_ = value;
|
||||||
|
|
||||||
// Apply it to any existing UI.
|
// Apply it to any existing UI.
|
||||||
if (uiv1_) {
|
if (uiv1_) {
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetLeagueRankText(root_ui_league_rank_text_);
|
root_widget->SetLeagueRankValue(root_ui_league_rank_value_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1694,8 +1698,8 @@ void ClassicAppMode::SetRootUIGoldPass(bool enabled) {
|
|||||||
// Apply it to any existing UI.
|
// Apply it to any existing UI.
|
||||||
if (uiv1_) {
|
if (uiv1_) {
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetTokensMeterText(root_ui_tokens_meter_text_,
|
root_widget->SetTokensMeterValue(root_ui_tokens_meter_value_,
|
||||||
root_ui_gold_pass_);
|
root_ui_gold_pass_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1716,15 +1720,28 @@ void ClassicAppMode::SetRootUIHaveLiveValues(bool have_live_values) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicAppMode::SetRootUIChests(const std::string& chest_0_appearance,
|
void ClassicAppMode::SetRootUIChests(
|
||||||
const std::string& chest_1_appearance,
|
const std::string& chest_0_appearance,
|
||||||
const std::string& chest_2_appearance,
|
const std::string& chest_1_appearance,
|
||||||
const std::string& chest_3_appearance) {
|
const std::string& chest_2_appearance,
|
||||||
|
const std::string& chest_3_appearance, seconds_t chest_0_unlock_time,
|
||||||
|
seconds_t chest_1_unlock_time, seconds_t chest_2_unlock_time,
|
||||||
|
seconds_t chest_3_unlock_time, seconds_t chest_0_ad_allow_time,
|
||||||
|
seconds_t chest_1_ad_allow_time, seconds_t chest_2_ad_allow_time,
|
||||||
|
seconds_t chest_3_ad_allow_time) {
|
||||||
BA_PRECONDITION(g_base->InLogicThread());
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
if (chest_0_appearance == root_ui_chest_0_appearance_
|
if (chest_0_appearance == root_ui_chest_0_appearance_
|
||||||
&& chest_1_appearance == root_ui_chest_1_appearance_
|
&& chest_1_appearance == root_ui_chest_1_appearance_
|
||||||
&& chest_2_appearance == root_ui_chest_2_appearance_
|
&& chest_2_appearance == root_ui_chest_2_appearance_
|
||||||
&& chest_3_appearance == root_ui_chest_3_appearance_) {
|
&& chest_3_appearance == root_ui_chest_3_appearance_
|
||||||
|
&& chest_0_unlock_time == root_ui_chest_0_unlock_time_
|
||||||
|
&& chest_1_unlock_time == root_ui_chest_1_unlock_time_
|
||||||
|
&& chest_2_unlock_time == root_ui_chest_2_unlock_time_
|
||||||
|
&& chest_3_unlock_time == root_ui_chest_3_unlock_time_
|
||||||
|
&& chest_0_ad_allow_time == root_ui_chest_0_ad_allow_time_
|
||||||
|
&& chest_1_ad_allow_time == root_ui_chest_1_ad_allow_time_
|
||||||
|
&& chest_2_ad_allow_time == root_ui_chest_2_ad_allow_time_
|
||||||
|
&& chest_3_ad_allow_time == root_ui_chest_3_ad_allow_time_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1733,13 +1750,25 @@ void ClassicAppMode::SetRootUIChests(const std::string& chest_0_appearance,
|
|||||||
root_ui_chest_1_appearance_ = chest_1_appearance;
|
root_ui_chest_1_appearance_ = chest_1_appearance;
|
||||||
root_ui_chest_2_appearance_ = chest_2_appearance;
|
root_ui_chest_2_appearance_ = chest_2_appearance;
|
||||||
root_ui_chest_3_appearance_ = chest_3_appearance;
|
root_ui_chest_3_appearance_ = chest_3_appearance;
|
||||||
|
root_ui_chest_0_unlock_time_ = chest_0_unlock_time;
|
||||||
|
root_ui_chest_1_unlock_time_ = chest_1_unlock_time;
|
||||||
|
root_ui_chest_2_unlock_time_ = chest_2_unlock_time;
|
||||||
|
root_ui_chest_3_unlock_time_ = chest_3_unlock_time;
|
||||||
|
root_ui_chest_0_ad_allow_time_ = chest_0_ad_allow_time;
|
||||||
|
root_ui_chest_1_ad_allow_time_ = chest_1_ad_allow_time;
|
||||||
|
root_ui_chest_2_ad_allow_time_ = chest_2_ad_allow_time;
|
||||||
|
root_ui_chest_3_ad_allow_time_ = chest_3_ad_allow_time;
|
||||||
|
|
||||||
// Apply it to any existing UI.
|
// Apply it to any existing UI.
|
||||||
if (uiv1_) {
|
if (uiv1_) {
|
||||||
if (auto* root_widget = uiv1_->root_widget()) {
|
if (auto* root_widget = uiv1_->root_widget()) {
|
||||||
root_widget->SetChests(
|
root_widget->SetChests(
|
||||||
root_ui_chest_0_appearance_, root_ui_chest_1_appearance_,
|
root_ui_chest_0_appearance_, root_ui_chest_1_appearance_,
|
||||||
root_ui_chest_2_appearance_, root_ui_chest_3_appearance_);
|
root_ui_chest_2_appearance_, root_ui_chest_3_appearance_,
|
||||||
|
root_ui_chest_0_unlock_time_, root_ui_chest_1_unlock_time_,
|
||||||
|
root_ui_chest_2_unlock_time_, root_ui_chest_3_unlock_time_,
|
||||||
|
root_ui_chest_0_ad_allow_time_, root_ui_chest_1_ad_allow_time_,
|
||||||
|
root_ui_chest_2_ad_allow_time_, root_ui_chest_3_ad_allow_time_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,19 +215,24 @@ class ClassicAppMode : public base::AppMode {
|
|||||||
public_party_public_address_ipv6_ = val;
|
public_party_public_address_ipv6_ = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRootUITicketsMeterText(const std::string text);
|
void SetRootUITicketsMeterValue(int value);
|
||||||
void SetRootUITokensMeterText(const std::string text);
|
void SetRootUITokensMeterValue(int value);
|
||||||
void SetRootUILeagueRankText(const std::string text);
|
void SetRootUILeagueRankValue(int value);
|
||||||
void SetRootUILeagueType(const std::string text);
|
void SetRootUILeagueType(const std::string text);
|
||||||
void SetRootUIAchievementsPercentText(const std::string text);
|
void SetRootUIAchievementsPercentText(const std::string text);
|
||||||
void SetRootUILevelText(const std::string text);
|
void SetRootUILevelText(const std::string text);
|
||||||
void SetRootUIXPText(const std::string text);
|
void SetRootUIXPText(const std::string text);
|
||||||
void SetRootUIInboxCountText(const std::string text);
|
void SetRootUIInboxCountText(const std::string text);
|
||||||
void SetRootUIGoldPass(bool enabled);
|
void SetRootUIGoldPass(bool enabled);
|
||||||
void SetRootUIChests(const std::string& chest_0_appearance,
|
void SetRootUIChests(
|
||||||
const std::string& chest_1_appearance,
|
const std::string& chest_0_appearance,
|
||||||
const std::string& chest_2_appearance,
|
const std::string& chest_1_appearance,
|
||||||
const std::string& chest_3_appearance);
|
const std::string& chest_2_appearance,
|
||||||
|
const std::string& chest_3_appearance, seconds_t chest_0_unlock_time,
|
||||||
|
seconds_t chest_1_unlock_time, seconds_t chest_2_unlock_time,
|
||||||
|
seconds_t chest_3_unlock_time, seconds_t chest_0_ad_allow_time,
|
||||||
|
seconds_t chest_1_ad_allow_time, seconds_t chest_2_ad_allow_time,
|
||||||
|
seconds_t chest_3_ad_allow_time);
|
||||||
void SetRootUIHaveLiveValues(bool val);
|
void SetRootUIHaveLiveValues(bool val);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -250,6 +255,15 @@ class ClassicAppMode : public base::AppMode {
|
|||||||
std::string root_ui_chest_1_appearance_;
|
std::string root_ui_chest_1_appearance_;
|
||||||
std::string root_ui_chest_2_appearance_;
|
std::string root_ui_chest_2_appearance_;
|
||||||
std::string root_ui_chest_3_appearance_;
|
std::string root_ui_chest_3_appearance_;
|
||||||
|
seconds_t root_ui_chest_0_unlock_time_;
|
||||||
|
seconds_t root_ui_chest_1_unlock_time_;
|
||||||
|
seconds_t root_ui_chest_2_unlock_time_;
|
||||||
|
seconds_t root_ui_chest_3_unlock_time_;
|
||||||
|
seconds_t root_ui_chest_0_ad_allow_time_;
|
||||||
|
seconds_t root_ui_chest_1_ad_allow_time_;
|
||||||
|
seconds_t root_ui_chest_2_ad_allow_time_;
|
||||||
|
seconds_t root_ui_chest_3_ad_allow_time_;
|
||||||
|
|
||||||
uint32_t next_scan_query_id_{};
|
uint32_t next_scan_query_id_{};
|
||||||
int scan_socket_{-1};
|
int scan_socket_{-1};
|
||||||
int host_protocol_version_{-1};
|
int host_protocol_version_{-1};
|
||||||
@ -301,6 +315,9 @@ class ClassicAppMode : public base::AppMode {
|
|||||||
int public_party_max_size_{8};
|
int public_party_max_size_{8};
|
||||||
int public_party_player_count_{0};
|
int public_party_player_count_{0};
|
||||||
int public_party_max_player_count_{8};
|
int public_party_max_player_count_{8};
|
||||||
|
int root_ui_tickets_meter_value_;
|
||||||
|
int root_ui_tokens_meter_value_;
|
||||||
|
int root_ui_league_rank_value_;
|
||||||
float debug_speed_mult_{1.0f};
|
float debug_speed_mult_{1.0f};
|
||||||
float replay_speed_mult_{1.0f};
|
float replay_speed_mult_{1.0f};
|
||||||
std::set<std::string> admin_public_ids_;
|
std::set<std::string> admin_public_ids_;
|
||||||
@ -308,9 +325,6 @@ class ClassicAppMode : public base::AppMode {
|
|||||||
std::string public_party_name_;
|
std::string public_party_name_;
|
||||||
std::string public_party_min_league_;
|
std::string public_party_min_league_;
|
||||||
std::string public_party_stats_url_;
|
std::string public_party_stats_url_;
|
||||||
std::string root_ui_tickets_meter_text_;
|
|
||||||
std::string root_ui_tokens_meter_text_;
|
|
||||||
std::string root_ui_league_rank_text_;
|
|
||||||
std::string root_ui_league_type_;
|
std::string root_ui_league_type_;
|
||||||
std::string root_ui_achievement_percent_text_;
|
std::string root_ui_achievement_percent_text_;
|
||||||
std::string root_ui_level_text_;
|
std::string root_ui_level_text_;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ void StressTest::ProcessInputs(int player_count) {
|
|||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
assert(player_count >= 0);
|
assert(player_count >= 0);
|
||||||
|
|
||||||
millisecs_t time = g_core->GetAppTimeMillisecs();
|
millisecs_t time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// FIXME: If we don't check for stress_test_last_leave_time_ we totally
|
// FIXME: If we don't check for stress_test_last_leave_time_ we totally
|
||||||
// confuse the game.. need to be able to survive that.
|
// confuse the game.. need to be able to survive that.
|
||||||
|
|||||||
@ -72,7 +72,7 @@ auto CoreFeatureSet::Import(const CoreConfig* config) -> CoreFeatureSet* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CoreFeatureSet::DoImport_(const CoreConfig& config) {
|
void CoreFeatureSet::DoImport_(const CoreConfig& config) {
|
||||||
millisecs_t start_millisecs = CorePlatform::GetCurrentMillisecs();
|
millisecs_t start_millisecs = CorePlatform::TimeMonotonicMillisecs();
|
||||||
|
|
||||||
assert(g_core == nullptr);
|
assert(g_core == nullptr);
|
||||||
g_core = new CoreFeatureSet(config);
|
g_core = new CoreFeatureSet(config);
|
||||||
@ -87,7 +87,7 @@ CoreFeatureSet::CoreFeatureSet(CoreConfig config)
|
|||||||
python{new CorePython()},
|
python{new CorePython()},
|
||||||
platform{CorePlatform::Create()},
|
platform{CorePlatform::Create()},
|
||||||
core_config_{std::move(config)},
|
core_config_{std::move(config)},
|
||||||
last_app_time_measure_microsecs_{CorePlatform::GetCurrentMicrosecs()},
|
last_app_time_measure_microsecs_{CorePlatform::TimeMonotonicMicrosecs()},
|
||||||
vr_mode_{config.vr_mode} {
|
vr_mode_{config.vr_mode} {
|
||||||
// We're a singleton. If there's already one of us, something's wrong.
|
// We're a singleton. If there's already one of us, something's wrong.
|
||||||
assert(g_core == nullptr);
|
assert(g_core == nullptr);
|
||||||
@ -313,7 +313,7 @@ auto CoreFeatureSet::SoftImportBase() -> BaseSoftInterface* {
|
|||||||
// // We include time-since-start as part of the message here.
|
// // We include time-since-start as part of the message here.
|
||||||
// char buffer[128];
|
// char buffer[128];
|
||||||
// snprintf(buffer, sizeof(buffer), "%s @ %.3fs.", msg,
|
// snprintf(buffer, sizeof(buffer), "%s @ %.3fs.", msg,
|
||||||
// g_core->GetAppTimeSeconds() + offset_seconds);
|
// g_core->AppTimeSeconds() + offset_seconds);
|
||||||
// Log(LogName::kBaLifecycle, LogLevel::kDebug, buffer);
|
// Log(LogName::kBaLifecycle, LogLevel::kDebug, buffer);
|
||||||
// } else {
|
// } else {
|
||||||
// Log(LogName::kBaLifecycle, LogLevel::kDebug, msg);
|
// Log(LogName::kBaLifecycle, LogLevel::kDebug, msg);
|
||||||
@ -355,23 +355,23 @@ static void WaitThenDie(millisecs_t wait, const std::string& action) {
|
|||||||
FatalError("Timed out waiting for " + action + ".");
|
FatalError("Timed out waiting for " + action + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CoreFeatureSet::GetAppTimeMillisecs() -> millisecs_t {
|
auto CoreFeatureSet::AppTimeMillisecs() -> millisecs_t {
|
||||||
UpdateAppTime_();
|
UpdateAppTime_();
|
||||||
return app_time_microsecs_ / 1000;
|
return app_time_microsecs_ / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CoreFeatureSet::GetAppTimeMicrosecs() -> microsecs_t {
|
auto CoreFeatureSet::AppTimeMicrosecs() -> microsecs_t {
|
||||||
UpdateAppTime_();
|
UpdateAppTime_();
|
||||||
return app_time_microsecs_;
|
return app_time_microsecs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CoreFeatureSet::GetAppTimeSeconds() -> seconds_t {
|
auto CoreFeatureSet::AppTimeSeconds() -> seconds_t {
|
||||||
UpdateAppTime_();
|
UpdateAppTime_();
|
||||||
return static_cast<seconds_t>(app_time_microsecs_) / 1000000;
|
return static_cast<seconds_t>(app_time_microsecs_) / 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreFeatureSet::UpdateAppTime_() {
|
void CoreFeatureSet::UpdateAppTime_() {
|
||||||
microsecs_t t = CorePlatform::GetCurrentMicrosecs();
|
microsecs_t t = CorePlatform::TimeMonotonicMicrosecs();
|
||||||
|
|
||||||
// If we're at a different time than our last query, do our funky math.
|
// If we're at a different time than our last query, do our funky math.
|
||||||
if (t != last_app_time_measure_microsecs_) {
|
if (t != last_app_time_measure_microsecs_) {
|
||||||
|
|||||||
@ -73,21 +73,21 @@ class CoreFeatureSet {
|
|||||||
/// App-time is basically the total time that the engine has been actively
|
/// App-time is basically the total time that the engine has been actively
|
||||||
/// running. (The 'App' here is a slight misnomer). It will stop
|
/// running. (The 'App' here is a slight misnomer). It will stop
|
||||||
/// progressing while the app is suspended and will never go backwards.
|
/// progressing while the app is suspended and will never go backwards.
|
||||||
auto GetAppTimeMillisecs() -> millisecs_t;
|
auto AppTimeMillisecs() -> millisecs_t;
|
||||||
|
|
||||||
/// Return current app-time in microseconds.
|
/// Return current app-time in microseconds.
|
||||||
///
|
///
|
||||||
/// App-time is basically the total time that the engine has been actively
|
/// App-time is basically the total time that the engine has been actively
|
||||||
/// running. (The 'App' here is a slight misnomer). It will stop
|
/// running. (The 'App' here is a slight misnomer). It will stop
|
||||||
/// progressing while the app is suspended and will never go backwards.
|
/// progressing while the app is suspended and will never go backwards.
|
||||||
auto GetAppTimeMicrosecs() -> microsecs_t;
|
auto AppTimeMicrosecs() -> microsecs_t;
|
||||||
|
|
||||||
/// Return current app-time in seconds.
|
/// Return current app-time in seconds.
|
||||||
///
|
///
|
||||||
/// App-time is basically the total time that the engine has been actively
|
/// App-time is basically the total time that the engine has been actively
|
||||||
/// running. (The 'App' here is a slight misnomer). It will stop
|
/// running. (The 'App' here is a slight misnomer). It will stop
|
||||||
/// progressing while the app is suspended and will never go backwards.
|
/// progressing while the app is suspended and will never go backwards.
|
||||||
auto GetAppTimeSeconds() -> seconds_t;
|
auto AppTimeSeconds() -> seconds_t;
|
||||||
|
|
||||||
/// Are we in the 'main' thread? The thread that first inited Core is
|
/// Are we in the 'main' thread? The thread that first inited Core is
|
||||||
/// considered the 'main' thread; on most platforms it is the one where
|
/// considered the 'main' thread; on most platforms it is the one where
|
||||||
|
|||||||
@ -116,7 +116,8 @@ void CorePlatform::LowLevelDebugLog(const std::string& msg) {
|
|||||||
HandleLowLevelDebugLog(msg);
|
HandleLowLevelDebugLog(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
CorePlatform::CorePlatform() : start_time_millisecs_(GetCurrentMillisecs()) {}
|
CorePlatform::CorePlatform()
|
||||||
|
: start_time_millisecs_(TimeMonotonicMillisecs()) {}
|
||||||
|
|
||||||
void CorePlatform::PostInit() {
|
void CorePlatform::PostInit() {
|
||||||
// Hmm; we seem to get some funky invalid utf8 out of
|
// Hmm; we seem to get some funky invalid utf8 out of
|
||||||
@ -960,8 +961,8 @@ auto CorePlatform::SetSocketNonBlocking(int sd) -> bool {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CorePlatform::GetTicks() const -> millisecs_t {
|
auto CorePlatform::TimeSinceLaunchMillisecs() const -> millisecs_t {
|
||||||
return GetCurrentMillisecs() - start_time_millisecs_;
|
return TimeMonotonicMillisecs() - start_time_millisecs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CorePlatform::GetPlatformName() -> std::string {
|
auto CorePlatform::GetPlatformName() -> std::string {
|
||||||
@ -1072,27 +1073,27 @@ void CorePlatform::SetDebugKey(const std::string& key,
|
|||||||
|
|
||||||
void CorePlatform::HandleLowLevelDebugLog(const std::string& msg) {}
|
void CorePlatform::HandleLowLevelDebugLog(const std::string& msg) {}
|
||||||
|
|
||||||
auto CorePlatform::GetCurrentMillisecs() -> millisecs_t {
|
auto CorePlatform::TimeMonotonicMillisecs() -> millisecs_t {
|
||||||
return std::chrono::time_point_cast<std::chrono::milliseconds>(
|
return std::chrono::time_point_cast<std::chrono::milliseconds>(
|
||||||
std::chrono::steady_clock::now())
|
std::chrono::steady_clock::now())
|
||||||
.time_since_epoch()
|
.time_since_epoch()
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CorePlatform::GetCurrentMicrosecs() -> millisecs_t {
|
auto CorePlatform::TimeMonotonicMicrosecs() -> millisecs_t {
|
||||||
return std::chrono::time_point_cast<std::chrono::microseconds>(
|
return std::chrono::time_point_cast<std::chrono::microseconds>(
|
||||||
std::chrono::steady_clock::now())
|
std::chrono::steady_clock::now())
|
||||||
.time_since_epoch()
|
.time_since_epoch()
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CorePlatform::GetSecondsSinceEpoch() -> double {
|
auto CorePlatform::TimeSinceEpochSeconds() -> double {
|
||||||
return std::chrono::duration<double>(
|
return std::chrono::duration<double>(
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CorePlatform::GetCurrentWholeSeconds() -> int64_t {
|
auto CorePlatform::TimeMonotonicWholeSeconds() -> int64_t {
|
||||||
return std::chrono::time_point_cast<std::chrono::seconds>(
|
return std::chrono::time_point_cast<std::chrono::seconds>(
|
||||||
std::chrono::steady_clock::now())
|
std::chrono::steady_clock::now())
|
||||||
.time_since_epoch()
|
.time_since_epoch()
|
||||||
|
|||||||
@ -346,31 +346,31 @@ class CorePlatform {
|
|||||||
/// monotonic. For most purposes, AppTime values are preferable since
|
/// monotonic. For most purposes, AppTime values are preferable since
|
||||||
/// their progression pauses during app suspension and they are 100%
|
/// their progression pauses during app suspension and they are 100%
|
||||||
/// guaranteed to not go backwards.
|
/// guaranteed to not go backwards.
|
||||||
auto GetTicks() const -> millisecs_t;
|
auto TimeSinceLaunchMillisecs() const -> millisecs_t;
|
||||||
|
|
||||||
/// Return a raw current milliseconds value. It *should* be monotonic. It
|
/// Return a raw current milliseconds value. It *should* be monotonic. It
|
||||||
/// is relative to an undefined start point; only use it for time
|
/// is relative to an undefined start point; only use it for time
|
||||||
/// differences. Generally the AppTime values are preferable since their
|
/// differences. Generally the AppTime values are preferable since their
|
||||||
/// progression pauses during app suspension and they are 100% guaranteed
|
/// progression pauses during app suspension and they are 100% guaranteed
|
||||||
/// to not go backwards.
|
/// to not go backwards.
|
||||||
static auto GetCurrentMillisecs() -> millisecs_t;
|
static auto TimeMonotonicMillisecs() -> millisecs_t;
|
||||||
|
|
||||||
/// Return a raw current microseconds value. It *should* be monotonic. It
|
/// Return a raw current microseconds value. It *should* be monotonic. It
|
||||||
/// is relative to an undefined start point; only use it for time
|
/// is relative to an undefined start point; only use it for time
|
||||||
/// differences. Generally the AppTime values are preferable since their
|
/// differences. Generally the AppTime values are preferable since their
|
||||||
/// progression pauses during app suspension and they are 100% guaranteed
|
/// progression pauses during app suspension and they are 100% guaranteed
|
||||||
/// to not go backwards.
|
/// to not go backwards.
|
||||||
static auto GetCurrentMicrosecs() -> microsecs_t;
|
static auto TimeMonotonicMicrosecs() -> microsecs_t;
|
||||||
|
|
||||||
/// Return a raw current seconds integer value. It *should* be monotonic.
|
/// Return a raw current seconds integer value. It *should* be monotonic.
|
||||||
/// It is relative to an undefined start point; only use it for time
|
/// It is relative to an undefined start point; only use it for time
|
||||||
/// differences. Generally the AppTime values are preferable since their
|
/// differences. Generally the AppTime values are preferable since their
|
||||||
/// progression pauses during app suspension and they are 100% guaranteed
|
/// progression pauses during app suspension and they are 100% guaranteed
|
||||||
/// to not go backwards.
|
/// to not go backwards.
|
||||||
static auto GetCurrentWholeSeconds() -> int64_t;
|
static auto TimeMonotonicWholeSeconds() -> int64_t;
|
||||||
|
|
||||||
/// Return seconds since the epoch; same as Python's time.time().
|
/// Return seconds since the epoch; same as Python's time.time().
|
||||||
static auto GetSecondsSinceEpoch() -> double;
|
static auto TimeSinceEpochSeconds() -> double;
|
||||||
|
|
||||||
static void SleepSeconds(seconds_t duration);
|
static void SleepSeconds(seconds_t duration);
|
||||||
static void SleepMillisecs(millisecs_t duration);
|
static void SleepMillisecs(millisecs_t duration);
|
||||||
|
|||||||
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
namespace ballistica::core {
|
namespace ballistica::core {
|
||||||
|
|
||||||
/// Collection of low level options for a run of the engine; passed
|
/// A collection of low level options for a run of the engine; passed when
|
||||||
/// when initing the core feature-set.
|
/// initing the core feature-set.
|
||||||
class CoreConfig {
|
class CoreConfig {
|
||||||
public:
|
public:
|
||||||
static auto ForArgsAndEnvVars(int argc, char** argv) -> CoreConfig;
|
static auto ForArgsAndEnvVars(int argc, char** argv) -> CoreConfig;
|
||||||
|
|||||||
@ -34,7 +34,7 @@ const int kPingMeasureInterval = 2000;
|
|||||||
|
|
||||||
Connection::Connection() {
|
Connection::Connection() {
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||||
creation_time_ = last_average_update_time_ = g_core->GetAppTimeMillisecs();
|
creation_time_ = last_average_update_time_ = g_core->AppTimeMillisecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::ProcessWaitingMessages() {
|
void Connection::ProcessWaitingMessages() {
|
||||||
@ -181,13 +181,13 @@ void Connection::HandleGamePacket(const std::vector<uint8_t>& data) {
|
|||||||
"Error: got invalid BA_SCENEPACKET_KEEPALIVE packet.");
|
"Error: got invalid BA_SCENEPACKET_KEEPALIVE packet.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
HandleResends(real_time, data, 1);
|
HandleResends(real_time, data, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BA_SCENEPACKET_MESSAGE: {
|
case BA_SCENEPACKET_MESSAGE: {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Expect 1 byte type, 2 byte num, 3 byte acks, at least 1 byte payload.
|
// Expect 1 byte type, 2 byte num, 3 byte acks, at least 1 byte payload.
|
||||||
if (data.size() < 7) {
|
if (data.size() < 7) {
|
||||||
@ -211,7 +211,7 @@ void Connection::HandleGamePacket(const std::vector<uint8_t>& data) {
|
|||||||
ReliableMessageIn& msg(in_messages_[num]);
|
ReliableMessageIn& msg(in_messages_[num]);
|
||||||
msg.data.resize(data.size() - 6);
|
msg.data.resize(data.size() - 6);
|
||||||
memcpy(&(msg.data[0]), &(data[6]), msg.data.size());
|
memcpy(&(msg.data[0]), &(data[6]), msg.data.size());
|
||||||
msg.arrival_time = g_core->GetAppTimeMillisecs();
|
msg.arrival_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Now run all in-order packets we've got.
|
// Now run all in-order packets we've got.
|
||||||
ProcessWaitingMessages();
|
ProcessWaitingMessages();
|
||||||
@ -308,7 +308,7 @@ void Connection::SendReliableMessage(const std::vector<uint8_t>& data) {
|
|||||||
assert(out_messages_.find(num) == out_messages_.end());
|
assert(out_messages_.find(num) == out_messages_.end());
|
||||||
ReliableMessageOut& msg(out_messages_[num]);
|
ReliableMessageOut& msg(out_messages_[num]);
|
||||||
|
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
msg.data = data;
|
msg.data = data;
|
||||||
msg.first_send_time = msg.last_send_time = real_time;
|
msg.first_send_time = msg.last_send_time = real_time;
|
||||||
@ -341,7 +341,7 @@ void Connection::SendUnreliableMessage(const std::vector<uint8_t>& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t num = next_out_unreliable_message_num_++;
|
uint16_t num = next_out_unreliable_message_num_++;
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Add our header/acks and go ahead and send this one out.
|
// Add our header/acks and go ahead and send this one out.
|
||||||
// 1 byte for type, 2 for packet-num, 2 for unreliable packet-num, 3 for acks.
|
// 1 byte for type, 2 for packet-num, 2 for unreliable packet-num, 3 for acks.
|
||||||
@ -367,7 +367,7 @@ void Connection::SendJMessage(cJSON* val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Connection::Update() {
|
void Connection::Update() {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Update our averages once per second.
|
// Update our averages once per second.
|
||||||
while (real_time - last_average_update_time_ > 1000) {
|
while (real_time - last_average_update_time_ > 1000) {
|
||||||
|
|||||||
@ -95,7 +95,7 @@ ConnectionToClient::~ConnectionToClient() {
|
|||||||
void ConnectionToClient::Update() {
|
void ConnectionToClient::Update() {
|
||||||
Connection::Update(); // Handles common stuff.
|
Connection::Update(); // Handles common stuff.
|
||||||
|
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// If we're waiting for handshake response still, keep sending out handshake
|
// If we're waiting for handshake response still, keep sending out handshake
|
||||||
// attempts.
|
// attempts.
|
||||||
@ -246,7 +246,7 @@ void ConnectionToClient::HandleGamePacket(const std::vector<uint8_t>& data) {
|
|||||||
|
|
||||||
// Don't allow fresh clients to start kick votes for a while.
|
// Don't allow fresh clients to start kick votes for a while.
|
||||||
next_kick_vote_allow_time_ =
|
next_kick_vote_allow_time_ =
|
||||||
g_core->GetAppTimeMillisecs() + kNewClientKickVoteDelay;
|
g_core->AppTimeMillisecs() + kNewClientKickVoteDelay;
|
||||||
|
|
||||||
// At this point we have their name, so lets announce their arrival.
|
// At this point we have their name, so lets announce their arrival.
|
||||||
if (appmode->ShouldAnnouncePartyJoinsAndLeaves()) {
|
if (appmode->ShouldAnnouncePartyJoinsAndLeaves()) {
|
||||||
@ -263,7 +263,7 @@ void ConnectionToClient::HandleGamePacket(const std::vector<uint8_t>& data) {
|
|||||||
// Also mark the time for flashing the 'someone just joined your
|
// Also mark the time for flashing the 'someone just joined your
|
||||||
// party' message in the corner.
|
// party' message in the corner.
|
||||||
appmode->set_last_connection_to_client_join_time(
|
appmode->set_last_connection_to_client_join_time(
|
||||||
g_core->GetAppTimeMillisecs());
|
g_core->AppTimeMillisecs());
|
||||||
|
|
||||||
// Added midway through protocol 29:
|
// Added midway through protocol 29:
|
||||||
// We now send a json dict of info about ourself first thing. This
|
// We now send a json dict of info about ourself first thing. This
|
||||||
@ -338,8 +338,7 @@ void ConnectionToClient::SendScreenMessage(const std::string& s, float r,
|
|||||||
// Older clients don't support the screen-message message, so in that case
|
// Older clients don't support the screen-message message, so in that case
|
||||||
// we just send it as a chat-message from <HOST>.
|
// we just send it as a chat-message from <HOST>.
|
||||||
if (build_number() < 14248) {
|
if (build_number() < 14248) {
|
||||||
std::string value =
|
std::string value = g_base->assets->CompileResourceString(s);
|
||||||
g_base->assets->CompileResourceString(s, "sendScreenMessage");
|
|
||||||
std::string our_spec_string =
|
std::string our_spec_string =
|
||||||
PlayerSpec::GetDummyPlayerSpec("<HOST>").GetSpecString();
|
PlayerSpec::GetDummyPlayerSpec("<HOST>").GetSpecString();
|
||||||
std::vector<uint8_t> msg_out(1 + 1 + our_spec_string.size() + value.size());
|
std::vector<uint8_t> msg_out(1 + 1 + our_spec_string.size() + value.size());
|
||||||
@ -500,7 +499,7 @@ void ConnectionToClient::HandleMessagePacket(
|
|||||||
|
|
||||||
case BA_MESSAGE_CHAT: {
|
case BA_MESSAGE_CHAT: {
|
||||||
// We got a chat message from a client.
|
// We got a chat message from a client.
|
||||||
millisecs_t now = g_core->GetAppTimeMillisecs();
|
millisecs_t now = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Ignore this if they're chat blocked.
|
// Ignore this if they're chat blocked.
|
||||||
if (now >= chat_block_time_) {
|
if (now >= chat_block_time_) {
|
||||||
@ -636,7 +635,7 @@ void ConnectionToClient::HandleMessagePacket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case BA_MESSAGE_REMOVE_REMOTE_PLAYER: {
|
case BA_MESSAGE_REMOVE_REMOTE_PLAYER: {
|
||||||
last_remove_player_time_ = g_core->GetAppTimeMillisecs();
|
last_remove_player_time_ = g_core->AppTimeMillisecs();
|
||||||
if (buffer.size() != 2) {
|
if (buffer.size() != 2) {
|
||||||
g_core->Log(LogName::kBaNetworking, LogLevel::kError,
|
g_core->Log(LogName::kBaNetworking, LogLevel::kError,
|
||||||
"Error: invalid remove-remote-player packet");
|
"Error: invalid remove-remote-player packet");
|
||||||
@ -693,7 +692,7 @@ void ConnectionToClient::HandleMessagePacket(
|
|||||||
// master-server info for this client, delay their join (we'll
|
// master-server info for this client, delay their join (we'll
|
||||||
// eventually give up and just give them a blank slate).
|
// eventually give up and just give them a blank slate).
|
||||||
if (still_waiting_for_auth
|
if (still_waiting_for_auth
|
||||||
&& (g_core->GetAppTimeMillisecs() - creation_time() < 10000)) {
|
&& (g_core->AppTimeMillisecs() - creation_time() < 10000)) {
|
||||||
SendScreenMessage(
|
SendScreenMessage(
|
||||||
"{\"v\":\"${A}...\",\"s\":[[\"${A}\",{\"r\":"
|
"{\"v\":\"${A}...\",\"s\":[[\"${A}\",{\"r\":"
|
||||||
"\"loadingTryAgainText\",\"f\":\"loadingText\"}]]}",
|
"\"loadingTryAgainText\",\"f\":\"loadingText\"}]]}",
|
||||||
|
|||||||
@ -58,7 +58,7 @@ ConnectionToHost::~ConnectionToHost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionToHost::Update() {
|
void ConnectionToHost::Update() {
|
||||||
millisecs_t real_time = g_core->GetAppTimeMillisecs();
|
millisecs_t real_time = g_core->AppTimeMillisecs();
|
||||||
|
|
||||||
// Send out null messages occasionally for ping measurement purposes.
|
// Send out null messages occasionally for ping measurement purposes.
|
||||||
// Note that we currently only do this from the client since we might not
|
// Note that we currently only do this from the client since we might not
|
||||||
|
|||||||
@ -514,7 +514,7 @@ void Dynamics::ProcessCollision_() {
|
|||||||
void Dynamics::Process() {
|
void Dynamics::Process() {
|
||||||
in_process_ = true;
|
in_process_ = true;
|
||||||
// Update this once so we can recycle results.
|
// Update this once so we can recycle results.
|
||||||
real_time_ = g_core->GetAppTimeMillisecs();
|
real_time_ = g_core->AppTimeMillisecs();
|
||||||
ProcessCollision_();
|
ProcessCollision_();
|
||||||
dWorldQuickStep(ode_world_, kGameStepSeconds);
|
dWorldQuickStep(ode_world_, kGameStepSeconds);
|
||||||
dJointGroupEmpty(ode_contact_group_);
|
dJointGroupEmpty(ode_contact_group_);
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class GlobalsNodeType : public NodeType {
|
|||||||
public:
|
public:
|
||||||
#define BA_NODE_TYPE_CLASS GlobalsNode
|
#define BA_NODE_TYPE_CLASS GlobalsNode
|
||||||
BA_NODE_CREATE_CALL(CreateGlobals);
|
BA_NODE_CREATE_CALL(CreateGlobals);
|
||||||
BA_INT64_ATTR_READONLY(real_time, GetAppTimeMillisecs);
|
BA_INT64_ATTR_READONLY(real_time, AppTimeMillisecs);
|
||||||
BA_INT64_ATTR_READONLY(time, GetTime);
|
BA_INT64_ATTR_READONLY(time, GetTime);
|
||||||
BA_INT64_ATTR_READONLY(step, GetStep);
|
BA_INT64_ATTR_READONLY(step, GetStep);
|
||||||
BA_FLOAT_ATTR(debris_friction, debris_friction, SetDebrisFriction);
|
BA_FLOAT_ATTR(debris_friction, debris_friction, SetDebrisFriction);
|
||||||
@ -206,7 +206,7 @@ auto GlobalsNode::IsCurrentGlobals() const -> bool {
|
|||||||
&& scene->globals_node() == this);
|
&& scene->globals_node() == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GlobalsNode::GetAppTimeMillisecs() -> millisecs_t {
|
auto GlobalsNode::AppTimeMillisecs() -> millisecs_t {
|
||||||
// Pull this from our scene so we return consistent values throughout a step.
|
// Pull this from our scene so we return consistent values throughout a step.
|
||||||
return scene()->last_step_real_time();
|
return scene()->last_step_real_time();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class GlobalsNode : public Node {
|
|||||||
~GlobalsNode() override;
|
~GlobalsNode() override;
|
||||||
void SetAsForeground();
|
void SetAsForeground();
|
||||||
auto IsCurrentGlobals() const -> bool;
|
auto IsCurrentGlobals() const -> bool;
|
||||||
auto GetAppTimeMillisecs() -> millisecs_t;
|
auto AppTimeMillisecs() -> millisecs_t;
|
||||||
auto GetTime() -> millisecs_t;
|
auto GetTime() -> millisecs_t;
|
||||||
auto GetStep() -> int64_t;
|
auto GetStep() -> int64_t;
|
||||||
auto debris_friction() const -> float { return debris_friction_; }
|
auto debris_friction() const -> float { return debris_friction_; }
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class SessionGlobalsNodeType : public NodeType {
|
|||||||
public:
|
public:
|
||||||
#define BA_NODE_TYPE_CLASS SessionGlobalsNode
|
#define BA_NODE_TYPE_CLASS SessionGlobalsNode
|
||||||
BA_NODE_CREATE_CALL(CreateSessionGlobals);
|
BA_NODE_CREATE_CALL(CreateSessionGlobals);
|
||||||
BA_INT64_ATTR_READONLY(real_time, GetAppTimeMillisecs);
|
BA_INT64_ATTR_READONLY(real_time, AppTimeMillisecs);
|
||||||
BA_INT64_ATTR_READONLY(time, GetTime);
|
BA_INT64_ATTR_READONLY(time, GetTime);
|
||||||
BA_INT64_ATTR_READONLY(step, GetStep);
|
BA_INT64_ATTR_READONLY(step, GetStep);
|
||||||
#undef BA_NODE_TYPE_CLASS
|
#undef BA_NODE_TYPE_CLASS
|
||||||
@ -38,7 +38,7 @@ SessionGlobalsNode::SessionGlobalsNode(Scene* scene) : Node(scene, node_type) {
|
|||||||
|
|
||||||
SessionGlobalsNode::~SessionGlobalsNode() = default;
|
SessionGlobalsNode::~SessionGlobalsNode() = default;
|
||||||
|
|
||||||
auto SessionGlobalsNode::GetAppTimeMillisecs() -> millisecs_t {
|
auto SessionGlobalsNode::AppTimeMillisecs() -> millisecs_t {
|
||||||
// Pull this from our scene so we return consistent values throughout a step.
|
// Pull this from our scene so we return consistent values throughout a step.
|
||||||
return scene()->last_step_real_time();
|
return scene()->last_step_real_time();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class SessionGlobalsNode : public Node {
|
|||||||
static auto InitType() -> NodeType*;
|
static auto InitType() -> NodeType*;
|
||||||
explicit SessionGlobalsNode(Scene* scene);
|
explicit SessionGlobalsNode(Scene* scene);
|
||||||
~SessionGlobalsNode() override;
|
~SessionGlobalsNode() override;
|
||||||
auto GetAppTimeMillisecs() -> millisecs_t;
|
auto AppTimeMillisecs() -> millisecs_t;
|
||||||
auto GetTime() -> millisecs_t;
|
auto GetTime() -> millisecs_t;
|
||||||
auto GetStep() -> int64_t;
|
auto GetStep() -> int64_t;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -142,7 +142,7 @@ void SoundNode::Step() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (positional_ && position_dirty_ && playing_) {
|
if (positional_ && position_dirty_ && playing_) {
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs();
|
millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
if (t - last_position_update_time_ > 100) {
|
if (t - last_position_update_time_ > 100) {
|
||||||
base::AudioSource* s = g_base->audio->SourceBeginExisting(play_id_, 107);
|
base::AudioSource* s = g_base->audio->SourceBeginExisting(play_id_, 107);
|
||||||
if (s) {
|
if (s) {
|
||||||
|
|||||||
@ -1797,7 +1797,7 @@ void SpazNode::DoFlyPress() {
|
|||||||
|
|
||||||
// Keep from doing too many sparkles.
|
// Keep from doing too many sparkles.
|
||||||
static millisecs_t last_sparkle_time = 0;
|
static millisecs_t last_sparkle_time = 0;
|
||||||
millisecs_t t = g_core->GetAppTimeMillisecs();
|
millisecs_t t = g_core->AppTimeMillisecs();
|
||||||
if (t - last_sparkle_time > 200) {
|
if (t - last_sparkle_time > 200) {
|
||||||
last_sparkle_time = t;
|
last_sparkle_time = t;
|
||||||
auto* s = g_base->audio->SourceBeginNew();
|
auto* s = g_base->audio->SourceBeginNew();
|
||||||
|
|||||||
@ -104,7 +104,7 @@ TerrainNode::~TerrainNode() {
|
|||||||
// without our reference.
|
// without our reference.
|
||||||
if (collision_mesh_.exists()) {
|
if (collision_mesh_.exists()) {
|
||||||
collision_mesh_->collision_mesh_data()->set_last_used_time(
|
collision_mesh_->collision_mesh_data()->set_last_used_time(
|
||||||
g_core->GetAppTimeMillisecs());
|
g_core->AppTimeMillisecs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ void TerrainNode::set_collision_mesh(SceneCollisionMesh* val) {
|
|||||||
// if we had an old one, mark its last-used time so caching works properly..
|
// if we had an old one, mark its last-used time so caching works properly..
|
||||||
if (collision_mesh_.exists()) {
|
if (collision_mesh_.exists()) {
|
||||||
collision_mesh_->collision_mesh_data()->set_last_used_time(
|
collision_mesh_->collision_mesh_data()->set_last_used_time(
|
||||||
g_core->GetAppTimeMillisecs());
|
g_core->AppTimeMillisecs());
|
||||||
}
|
}
|
||||||
collision_mesh_ = val;
|
collision_mesh_ = val;
|
||||||
|
|
||||||
|
|||||||
@ -117,8 +117,7 @@ void TextNode::SetText(const std::string& val) {
|
|||||||
|
|
||||||
if (do_format_check) {
|
if (do_format_check) {
|
||||||
bool valid;
|
bool valid;
|
||||||
g_base->assets->CompileResourceString(val, "setText format check",
|
g_base->assets->CompileResourceString(val, &valid);
|
||||||
&valid);
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
BA_LOG_ONCE(
|
BA_LOG_ONCE(
|
||||||
LogName::kBa, LogLevel::kError,
|
LogName::kBa, LogLevel::kError,
|
||||||
@ -354,8 +353,7 @@ void TextNode::Draw(base::FrameDef* frame_def) {
|
|||||||
|
|
||||||
// Apply subs/resources to get our actual text if need be.
|
// Apply subs/resources to get our actual text if need be.
|
||||||
if (text_translation_dirty_) {
|
if (text_translation_dirty_) {
|
||||||
text_translated_ =
|
text_translated_ = g_base->assets->CompileResourceString(text_raw_);
|
||||||
g_base->assets->CompileResourceString(text_raw_, "TextNode::OnDraw");
|
|
||||||
text_translation_dirty_ = false;
|
text_translation_dirty_ = false;
|
||||||
text_group_dirty_ = true;
|
text_group_dirty_ = true;
|
||||||
text_width_dirty_ = true;
|
text_width_dirty_ = true;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user