groundwork for generalized messaging functionality

This commit is contained in:
Eric Froemling 2021-08-16 19:20:24 +02:00
parent 63a835a1f4
commit 7417ac0103
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
51 changed files with 541 additions and 237 deletions

View File

@ -565,7 +565,7 @@
"assets/build/ba_data/models/bridgitLevelBottom.bob": "https://files.ballistica.net/cache/ba1/1e/f4/8e8c6b86081aecc89888677b1dda", "assets/build/ba_data/models/bridgitLevelBottom.bob": "https://files.ballistica.net/cache/ba1/1e/f4/8e8c6b86081aecc89888677b1dda",
"assets/build/ba_data/models/bridgitLevelCollide.cob": "https://files.ballistica.net/cache/ba1/9c/19/b3f44e34a9153e645ae6e05bed9e", "assets/build/ba_data/models/bridgitLevelCollide.cob": "https://files.ballistica.net/cache/ba1/9c/19/b3f44e34a9153e645ae6e05bed9e",
"assets/build/ba_data/models/bridgitLevelRailingCollide.cob": "https://files.ballistica.net/cache/ba1/91/18/1fe3cd097d0b1e01ff76a531990f", "assets/build/ba_data/models/bridgitLevelRailingCollide.cob": "https://files.ballistica.net/cache/ba1/91/18/1fe3cd097d0b1e01ff76a531990f",
"assets/build/ba_data/models/bridgitLevelTop.bob": "https://files.ballistica.net/cache/ba1/c2/d7/dadd52531f7eb9c5a1165bc30edb", "assets/build/ba_data/models/bridgitLevelTop.bob": "https://files.ballistica.net/cache/ba1/8a/ff/e930989beb9e741c86fbc9d8b9c5",
"assets/build/ba_data/models/bunnyForeArm.bob": "https://files.ballistica.net/cache/ba1/7f/0c/31eb734e202a206b27df16f0bce3", "assets/build/ba_data/models/bunnyForeArm.bob": "https://files.ballistica.net/cache/ba1/7f/0c/31eb734e202a206b27df16f0bce3",
"assets/build/ba_data/models/bunnyHand.bob": "https://files.ballistica.net/cache/ba1/48/36/a7172c3d3660811d3c660719ab9a", "assets/build/ba_data/models/bunnyHand.bob": "https://files.ballistica.net/cache/ba1/48/36/a7172c3d3660811d3c660719ab9a",
"assets/build/ba_data/models/bunnyHead.bob": "https://files.ballistica.net/cache/ba1/81/1e/999f5c55663b73c3a3506864f226", "assets/build/ba_data/models/bunnyHead.bob": "https://files.ballistica.net/cache/ba1/81/1e/999f5c55663b73c3a3506864f226",
@ -911,7 +911,7 @@
"assets/build/ba_data/models/witchUpperLeg.bob": "https://files.ballistica.net/cache/ba1/da/f3/83bf5f77abce88e0ba7ddd3bfbde", "assets/build/ba_data/models/witchUpperLeg.bob": "https://files.ballistica.net/cache/ba1/da/f3/83bf5f77abce88e0ba7ddd3bfbde",
"assets/build/ba_data/models/wizardForeArm.bob": "https://files.ballistica.net/cache/ba1/7e/20/824b45fd56ef923d61ea7b91a904", "assets/build/ba_data/models/wizardForeArm.bob": "https://files.ballistica.net/cache/ba1/7e/20/824b45fd56ef923d61ea7b91a904",
"assets/build/ba_data/models/wizardHand.bob": "https://files.ballistica.net/cache/ba1/66/bd/6059a0dcf1c14eb4dc47904aec94", "assets/build/ba_data/models/wizardHand.bob": "https://files.ballistica.net/cache/ba1/66/bd/6059a0dcf1c14eb4dc47904aec94",
"assets/build/ba_data/models/wizardHead.bob": "https://files.ballistica.net/cache/ba1/81/e6/04e09e74169c7582d433eb972f01", "assets/build/ba_data/models/wizardHead.bob": "https://files.ballistica.net/cache/ba1/8b/64/918cea6808d80f53a57ccee2029b",
"assets/build/ba_data/models/wizardLowerLeg.bob": "https://files.ballistica.net/cache/ba1/f4/9a/d8f380aba0775bff0fd35f98ba9a", "assets/build/ba_data/models/wizardLowerLeg.bob": "https://files.ballistica.net/cache/ba1/f4/9a/d8f380aba0775bff0fd35f98ba9a",
"assets/build/ba_data/models/wizardPelvis.bob": "https://files.ballistica.net/cache/ba1/63/e7/f5940cc4598d1dbeece261ea6c82", "assets/build/ba_data/models/wizardPelvis.bob": "https://files.ballistica.net/cache/ba1/63/e7/f5940cc4598d1dbeece261ea6c82",
"assets/build/ba_data/models/wizardToes.bob": "https://files.ballistica.net/cache/ba1/a2/c0/9b550223f1df470b6bfc2df23f71", "assets/build/ba_data/models/wizardToes.bob": "https://files.ballistica.net/cache/ba1/a2/c0/9b550223f1df470b6bfc2df23f71",
@ -3936,50 +3936,50 @@
"assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e",
"assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/72/82/86956fae909ac2fe2a1abd84a361", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/72/82/86956fae909ac2fe2a1abd84a361",
"ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a",
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/78/d0/f3bf896c369ca302fb24129ac652", "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/14/65/e76d6db4acf8d4aa4911cc9d028a",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/1d/fc9e33e565475daaac80da5252f0", "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/1d/fc9e33e565475daaac80da5252f0",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/01/e8/469e2da917853f6dc96e4aaadb12", "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bf/7d/77c00ddc1c099b369ba2b8df28d9",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/b8/a3fa9d99d4720d188f28f577704e", "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1b/7c/ce10fe8508a295a677560861c586",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/bd/9d8561a74476b704ad252c5c9807", "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/27/ce/334457db385ce15f76b33c42d382",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/7b/ac1a200be0f37078af0991faca3b", "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/7b/ac1a200be0f37078af0991faca3b",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/03/26b9ff129007266c48f1a45277a5", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/2b/d2610ee3521acca45dc010d96940",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ff/20/5a1d6f82f1903395f70e6ff9c165", "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/74/1d/142b429f823320491387ed97d877",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/48/af1ff6b22ef9622fa823c3fb45d8", "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/9e/d9/c7e3bd2adee613ca901238c26bb8",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/95/77/d72b460cd5af4045d2805120cb39", "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/86/a4/c4b4a6e6d5dda42199e4dac5184a",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/bb/526cda66921b0578144adfeb7ee1", "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b7/5a/60fdcd55840cebc736673ff32416",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/ac/1c69bcacc277bca5b07501f7df57", "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/6f/1af3830bdcf69fba8078b2866fd1",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/04/52/60c5ea5e91cf8583d4837bdcee47", "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0d/08/8c329bd71c2df09ead449bac480a",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a7/08/8f990244433ba4264dabdcd72299", "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3b/2f/ef7a91e2b36e29f124febca5c62a",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b2/1e/3fdeab959e3eeae775920c4920d7", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/20/c0/942cd20ac2265769b1a1f14f0d17",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/00/e0/f5aa9e8948b991dc0e0a208070c2", "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3f/e0/f462366cd16674ebeea4e2463d69",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/fa/2f/6d5d9d34651aef7b36bfa941d9aa", "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/04/36/24006cd9c69d896fa09294f1c551",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b6/c5/6b54d23c72ef591eb6937df71ed1", "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/82/42/2f8d90b396536430bac4e8f9e1a6",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/bb/f6/8f6c63c971af7bac231a637aea7f", "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/64/bf/7f5e32cc0ccfa83fac033c7f6e3e",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/f7/fb/8ac747420042532ebd9e3b77c81d", "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/e2/d7/2a22130c82126c06debcd2e07d9a",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c8/2b/f877075b157d502c658a4cd0d866", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/8c/8844f896ae2f2e23fc7de8ebf83e",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/d9/0ac2d149b9815a6fcd816114df18", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/34/c5f471383506bec47851780c51fa",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d3/00/b495df3471f5eddc94a60c88f654", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ef/05/a7b311b98f8eb082352f89c0467b",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ad/65/ac79287366619dce16152d45d207", "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1c/be/12c89e97422620f979482dee9be2",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9b/d2/893807bc441d9b85ac0df6e4d7e5", "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/23/a0ca2d8114858f9d73e6fe1e3a49",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f4/a7/8956e8178655dd4ab9366b404ac3", "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ab/ab/7773aa505ac380b7aa17e5a01d7d",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/44/5dc62136e984a157688359a4ff31", "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/37/b3af9d6405c1dbe08b1ab9d0c5e0",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/71/ed/81eb2fd97f23894690c67ab063e2", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/65/86ccbcdf8ca0f1aeb97607271f7b",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/32/f3/41b621fdee9487b24e83cc2fd173", "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/74/b91237a1c27491892ac77448e684",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e3/b5/0c8a61c5d6d277fe4575292ce40f", "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/9b/5b5b5d663cef540a9462ef2a37d0",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bf/09/946527282b82da7bb41c44c33c4e", "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/ff/1e06dd40fd61042e36e83cecdb38",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/c0/c26053fe27dc6a23f7c4e33d9887", "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/55/39ac5c3257e9767512671bf80272",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/82/3c20d2819811068477eb4f82d530", "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b7/0c/848465c86d4933a025e45eaa1148",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/05/31/854b99de8afa01e8f59998c5325b", "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/7f/419770d849f568a170d956081452",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f0/92/e2e41ac2c731b49e55b2afb11d59", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2d/6e/d4665bf704a16f4df850df6b3fa7",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/13/f6/1e9ff73e247539fcfedc9665046a", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/04/d3/7cbe365469441b408e8b1b537e97",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/93/4c/b134b1185befb63ee9891ff790f2", "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/6e/f3/3084e35e36e378a31efcd5322475",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/d4/35/7de64b81ec626a06f224f2c7b352", "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/bc/68/170b706d3424ae63d087038c8132",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/60/67/def358beedd594c91009a8810480", "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/ed/7e/efc93d28f9540a66998d3981d8d2",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/35/50/302253b0fdab74a9fa1722e90d91", "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/bb/8d/212edd7de31aa73920ddad2a6c45",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/0e/11/914ca2032a70cc70a5552d60b6f8", "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/e6/8a/df58e0d6ab23f9242b7ca806f084",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/25/3e/9402625d0f5db5756fcc73e83998", "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/b2/80/d6f4f629e96bc2ead3921c20e2cf",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/2f/4f/8d6a2d6548753e01119b6b2c14ed", "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5f/f8/f14410dbaeffbb1e8cb1ca24a293",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/cb/ce/cb22f47b9efca8e08d776dd8c876", "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/a9/7a/2ec01f037c3a5ac14cf99c0bbe74",
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/fc/b5/62133319c6df8567aecfd29b1204", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/fc/b5/62133319c6df8567aecfd29b1204",
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/8d/96/c1516dee7d458c9065597e0aede6" "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/8d/96/c1516dee7d458c9065597e0aede6"
} }

View File

@ -532,6 +532,7 @@
<w>devel</w> <w>devel</w>
<w>devicename</w> <w>devicename</w>
<w>devtool</w> <w>devtool</w>
<w>dffc</w>
<w>dgram</w> <w>dgram</w>
<w>dhave</w> <w>dhave</w>
<w>dheadless</w> <w>dheadless</w>
@ -705,6 +706,7 @@
<w>excludetypes</w> <w>excludetypes</w>
<w>excstr</w> <w>excstr</w>
<w>execcode</w> <w>execcode</w>
<w>execing</w>
<w>execlocals</w> <w>execlocals</w>
<w>executils</w> <w>executils</w>
<w>exhash</w> <w>exhash</w>
@ -746,6 +748,7 @@
<w>feedparser</w> <w>feedparser</w>
<w>ffaeff</w> <w>ffaeff</w>
<w>ffap</w> <w>ffap</w>
<w>ffbbdf</w>
<w>fflush</w> <w>fflush</w>
<w>fhash</w> <w>fhash</w>
<w>fhashes</w> <w>fhashes</w>
@ -1285,6 +1288,7 @@
<w>lprop</w> <w>lprop</w>
<w>lsbo</w> <w>lsbo</w>
<w>lsbt</w> <w>lsbt</w>
<w>lshort</w>
<w>lsprof</w> <w>lsprof</w>
<w>lsqlite</w> <w>lsqlite</w>
<w>lssl</w> <w>lssl</w>
@ -1295,6 +1299,7 @@
<w>lsval</w> <w>lsval</w>
<w>ltex</w> <w>ltex</w>
<w>ltypes</w> <w>ltypes</w>
<w>lubyte</w>
<w>lzma</w> <w>lzma</w>
<w>lzmamodule</w> <w>lzmamodule</w>
<w>macappstore</w> <w>macappstore</w>
@ -1855,6 +1860,7 @@
<w>realpath</w> <w>realpath</w>
<w>realsies</w> <w>realsies</w>
<w>recache</w> <w>recache</w>
<w>recv</w>
<w>redist</w> <w>redist</w>
<w>redistributables</w> <w>redistributables</w>
<w>relpath</w> <w>relpath</w>

View File

@ -39,7 +39,7 @@
- Fixed a potential crash-on-exit due to statically allocated colliders/caches in `ode_collision_trimesh.cpp` getting torn down while in use - Fixed a potential crash-on-exit due to statically allocated colliders/caches in `ode_collision_trimesh.cpp` getting torn down while in use
- Better randomization for player free-for-all starting locations - Better randomization for player free-for-all starting locations
- Plugins can now register to be called for pause, resume, and shutdown events in addition to launch - Plugins can now register to be called for pause, resume, and shutdown events in addition to launch
- Added ba.app.state holding the overall state of the app (running, paused, etc) - Added ba.app.state holding the overall state of the app (running, paused, etc.)
- renamed the efro.dataclasses module to efro.dataclassio and added significant functionality - renamed the efro.dataclasses module to efro.dataclassio and added significant functionality
- command-line input no longer errors on commands longer than 4k bytes. - command-line input no longer errors on commands longer than 4k bytes.
- added show-tutorial option to the server wrapper config - added show-tutorial option to the server wrapper config
@ -84,7 +84,7 @@
- Android asset-sync phase (completing install...) now emits log output for debugging. - Android asset-sync phase (completing install...) now emits log output for debugging.
### 1.5.24 (20163) ### 1.5.24 (20163)
- Upgraded Python from version 3.7 to 3.8. This is a substantial change (though nothing like the previous update from 2.7 to 3.7) so please holler if anything is broken. These updates will happen once every year or two now.. - Upgraded Python from version 3.7 to 3.8. This is a substantial change (though nothing like the previous update from 2.7 to 3.7) so please holler if anything is broken. These updates will happen once every year or two now...
- Windows debug builds now use Python debug libraries. This should hopefully catch more errors that would otherwise go undetected and potentially cause crashes. - Windows debug builds now use Python debug libraries. This should hopefully catch more errors that would otherwise go undetected and potentially cause crashes.
- Switched windows builds to use 'fast' mode math instead of 'strict'. This should make the game run more efficiently (similar modes are already in use on other platforms) but holler if any odd breakage happens such as things falling through floors (more often than the occasional random fluke-y case that happens now). - Switched windows builds to use 'fast' mode math instead of 'strict'. This should make the game run more efficiently (similar modes are already in use on other platforms) but holler if any odd breakage happens such as things falling through floors (more often than the occasional random fluke-y case that happens now).
- Added `_ba.can_display_full_unicode()` for any code that wants to avoid printing things that won't show up locally. - Added `_ba.can_display_full_unicode()` for any code that wants to avoid printing things that won't show up locally.
@ -123,13 +123,13 @@
- Fixed a case where an early fatal error could lead to a hung app and no error dialog. - Fixed a case where an early fatal error could lead to a hung app and no error dialog.
- Added environment variables which can override UI scale for testing. Set `BA_FORCE_UI_SCALE` to small, medium or large. - Added environment variables which can override UI scale for testing. Set `BA_FORCE_UI_SCALE` to small, medium or large.
- Added a ba.UIScale enum. The value at ba.app.uiscale replaces the old `ba.app.interface_type`, `ba.app.small_ui`, and `ba.app.med_ui` values. - Added a ba.UIScale enum. The value at ba.app.uiscale replaces the old `ba.app.interface_type`, `ba.app.small_ui`, and `ba.app.med_ui` values.
- Emoji no longer display in-game with a washed-out appearance. If there are any places in-game where bright colored emoji become distracting, please holler. - Emoji no longer display in-game with a washed-out appearance. If there are any places in-game where bright-colored emoji become distracting, please holler.
- `_ba.get_game_roster()` now includes `account_id` which is the validated account id of all clients (will be None until completes). Also a few keys are renamed: `specString->spec_string` and `displayString->display_string`. - `_ba.get_game_roster()` now includes `account_id` which is the validated account id of all clients (will be None until completes). Also, a few keys are renamed: `specString->spec_string` and `displayString->display_string`.
### 1.5.19 (20123) ### 1.5.19 (20123)
- Cleaned up some bomb logic to avoid weird corner-cases such as land-mine explosions behaving like punches when set off by punches or bombs potentially resulting in multiple explosions when triggered by multiple other bombs simultaneously. Holler if anything explosion-related seems off now. - Cleaned up some bomb logic to avoid weird corner-cases such as land-mine explosions behaving like punches when set off by punches or bombs potentially resulting in multiple explosions when triggered by multiple other bombs simultaneously. Holler if anything explosion-related seems off now.
- Reactivated and cleaned up fatal-error message dialogs; they should now show up more consistently and on more platforms when something really bad happens instead of getting a silent crash. - Reactivated and cleaned up fatal-error message dialogs; they should now show up more consistently and on more platforms when something catastrophic happens instead of getting a silent crash.
- Certain hardware buttons on Android which stopped working in 1.5 should now be working again.. - Certain hardware buttons on Android which stopped working in 1.5 should now be working again...
### 1.5.18 (20108) ### 1.5.18 (20108)
- A bit of project cleanup; tools/snippets is now tools/pcommand, etc. - A bit of project cleanup; tools/snippets is now tools/pcommand, etc.
@ -137,7 +137,7 @@
### 1.5.17 (20102) ### 1.5.17 (20102)
- More cleanup to logging and crash reporting system. - More cleanup to logging and crash reporting system.
- Various other minor bug fixes.. - Various other minor bug fixes...
### 1.5.16 (20099) ### 1.5.16 (20099)
- Hopefully finally fixed that pesky crash bug on score submissions. - Hopefully finally fixed that pesky crash bug on score submissions.
@ -185,7 +185,7 @@
- Lots of low level input handling cleanup, also related to Android 1.5 version. Please holler if keyboard/game-controllers/etc. are behaving odd on any platforms. - Lots of low level input handling cleanup, also related to Android 1.5 version. Please holler if keyboard/game-controllers/etc. are behaving odd on any platforms.
- Now including Android test builds for the first time since 1.5. These have not been thoroughly tested yet so please holler with anything that is obviously broken. - Now including Android test builds for the first time since 1.5. These have not been thoroughly tested yet so please holler with anything that is obviously broken.
- Mouse wheel now works in manual camera mode on more platforms. - Mouse wheel now works in manual camera mode on more platforms.
- Server scripts now run in opt mode in release builds so they can use bundled .opt-1.pyc files. - Server scripts now run in opt mode in release builds, so they can use bundled .opt-1.pyc files.
- Fixes a potential crash in the local network browser. - Fixes a potential crash in the local network browser.
- Fixes an issue where Hockey Pucks would not show up in network games. - Fixes an issue where Hockey Pucks would not show up in network games.
- More misc bug fixes and tidying. - More misc bug fixes and tidying.
@ -196,11 +196,11 @@
### 1.5.4 (20067) ### 1.5.4 (20067)
- Should now work properly with non-ascii paths on Windows (for real this time). - Should now work properly with non-ascii paths on Windows (for real this time).
- Note that Windows game data is now stored under 'Local' appdata instead of 'Roaming'; if you have an old install with data you want to preserve, you may want to move it over manually. - Note that Windows game data is now stored under 'Local' appdata instead of 'Roaming'; if you have an old installation with data you want to preserve, you may want to move it over manually.
- Misc cleanup and minor bug fixes. - Misc cleanup and minor bug fixes.
### 1.5.3 (20065) ### 1.5.3 (20065)
- Improved handling of non-ascii characters in file paths on windows. - Improved handling of non-ascii characters in file paths on Windows.
### 1.5.2 (20063) ### 1.5.2 (20063)
- Fixes an issue with controls not working correctly in net-play between 1.4.x and 1.5.x. - Fixes an issue with controls not working correctly in net-play between 1.4.x and 1.5.x.
@ -208,15 +208,15 @@
- Fixes various other minor bugs. - Fixes various other minor bugs.
### 1.5.1 (20062) ### 1.5.1 (20062)
- Windows server now properly displays color when run by double clicking the .bat file. - Windows server now properly displays color when run by double-clicking the .bat file.
- Misc bug fixes. - Misc bug fixes.
### 1.5.0 (20001) ### 1.5.0 (20001)
- This build contains about 2 years worth of MAJOR internal refactoring to prepare for the future of BombSquad. As a player this should not (yet) look different from 1.4, but for modders there is a lot new. See the rest of these change entries or visit [ballistica.net](https://ballistica.net) for more info. - This build contains about 2 years worth of MAJOR internal refactoring to prepare for the future of BombSquad. As a player this should not (yet) look different from 1.4, but for modders there is a lot new. See the rest of these change entries or visit [ballistica.net](https://ballistica.net) for more info.
- Ported the entire scripting layer from Python 2 to to Python 3 (currently at 3.7, and I intend to keep this updated to the latest widely-available release). There's some significant changes going from python 2 to 3 (new print statement, string behavior, etc), but these are well documented online, so please read up as needed. This should provide us some nice benefits and future-proofs everything. (my janky 2.7 custom Python builds were getting a little long in the tooth). - Ported the entire scripting layer from Python 2 to Python 3 (currently at 3.7, and I intend to keep this updated to the latest widely-available release). There's some significant changes going from python 2 to 3 (new print statement, string behavior, etc.), but these are well documented online, so please read up as needed. This should provide us some nice benefits and future-proofs everything. (my janky 2.7 custom Python builds were getting a little long in the tooth).
- Refactored all script code to be PEP8 compliant (Python coding standards). Basically, this means that stuff that was camel-case (fooBar) is now a single word or underscores (`foobar` / `foo_bar`). There are a few minor exceptions such as existing resource and media filenames, but in general old code can be ported by taking a pass through and killing the camel-case. I know this is a bit of a pain in the ass, but it'll let us use things like Pylint and just be more consistent with the rest of the Python world. - Refactored all script code to be PEP8 compliant (Python coding standards). Basically, this means that stuff that was camel-case (fooBar) is now a single word or underscores (`foobar` / `foo_bar`). There are a few minor exceptions such as existing resource and media filenames, but in general old code can be ported by taking a pass through and killing the camel-case. I know this is a bit of a pain in the ass, but it'll let us use things like Pylint and just be more consistent with the rest of the Python world.
- On a related note, I'm now using 'yapf' to keep my Python code formatted nicely (using pep8 style); I'd recommend checking it out if you're doing a lot of scripting as its a great time-saver. - On a related note, I'm now using 'yapf' to keep my Python code formatted nicely (using pep8 style); I'd recommend checking it out if you're doing a lot of scripting as it's a great time-saver.
- On another related note, I'm trying to confirm to Google's recommendations for Python code (search 'Google Python Style Guide'). There are some good bits of wisdom in there so I recommend at least skimming through it. - On another related note, I'm trying to confirm to Google's recommendations for Python code (search 'Google Python Style Guide'). There are some good bits of wisdom in there, so I recommend at least skimming through it.
- And as one last related note, I'm now running Pylint on all my own Python code. Highly recommended if you are doing serious scripting, as it can make Python almost feel as type-safe as C++. - And as one last related note, I'm now running Pylint on all my own Python code. Highly recommended if you are doing serious scripting, as it can make Python almost feel as type-safe as C++.
- The minimum required android version will now be 5.0 (a requirement of the Python 3 builds I'm using) - The minimum required android version will now be 5.0 (a requirement of the Python 3 builds I'm using)
- Minimum required macOS version is now 10.13 (for similar reasons) - Minimum required macOS version is now 10.13 (for similar reasons)
@ -227,13 +227,13 @@
- Renamed 'exceptionOnNone' arg to 'doraise' in various calls. - Renamed 'exceptionOnNone' arg to 'doraise' in various calls.
- bs.emitBGDynamics() is now ba.emitfx() - bs.emitBGDynamics() is now ba.emitfx()
- bs.shakeCamera() is now ba.camerashake() - bs.shakeCamera() is now ba.camerashake()
- Various other minor name changes (bs.getUIBounds() -> ba.app.uibounds, etc). I'm keeping old and new Python API docs around for now so you can compare as needed. - Various other minor name changes (bs.getUIBounds() -> ba.app.uibounds, etc.). I'm keeping old and new Python API docs around for now, so you can compare as needed.
- Renamed bot classes based on their actions instead of their appearances (ie: PirateBot -> ExplodeyBot) - Renamed bot classes based on their actions instead of their appearances (ie: PirateBot -> ExplodeyBot)
- bs.getSharedObject() is now ba.stdobj() - bs.getSharedObject() is now ba.stdobj()
- Removed bs.uni(), bs.utf8(), `bs.uni_to_ints()`, and `bs.uni_from_ints()` which are no longer needed due to Python 3's better string handling. - Removed bs.uni(), bs.utf8(), `bs.uni_to_ints()`, and `bs.uni_from_ints()` which are no longer needed due to Python 3's better string handling.
- Removed bs.SecureInt since it didn't do much to slow down hackers and hurts code readability. - Removed bs.SecureInt since it didn't do much to slow down hackers and hurts code readability.
- Renamed 'finalize' to 'expire' for actors and activities. 'Finalize' sounds too much like a destructor, which is not really what that is. - Renamed 'finalize' to 'expire' for actors and activities. 'Finalize' sounds too much like a destructor, which is not really what that is.
- bs.getMapsSupportingPlayType() is now simply ba.getmaps(). I might want to add more filter options to it besides just play-type, hence the rename. - bs.getMapsSupportingPlayType() is now simply ba.getmaps(). I might want to add more filter options to it besides just play-type, hence the renaming.
- Changed the concept of 'game', 'net', and 'real' times to 'sim', 'base', and 'real'. See time function docs for specifics. Also cleared up a few ambiguities over what can be used where. - Changed the concept of 'game', 'net', and 'real' times to 'sim', 'base', and 'real'. See time function docs for specifics. Also cleared up a few ambiguities over what can be used where.
- I'm converting all scripting functions to operate on floating-point seconds by default instead of integer milliseconds. This will let us support more accurate simulations later and is just cleaner I feel. To keep existing calls working you should be able to add timeformat='ms' and you'll get the old behavior (or multiply your time values by 0.001). Specific notes listed below. - I'm converting all scripting functions to operate on floating-point seconds by default instead of integer milliseconds. This will let us support more accurate simulations later and is just cleaner I feel. To keep existing calls working you should be able to add timeformat='ms' and you'll get the old behavior (or multiply your time values by 0.001). Specific notes listed below.
- ba.Timer now takes its 'time' arg as seconds instead of milliseconds. To port old calls, add: timeformat='ms' to each call (or multiply your input by 0.001) - ba.Timer now takes its 'time' arg as seconds instead of milliseconds. To port old calls, add: timeformat='ms' to each call (or multiply your input by 0.001)
@ -251,18 +251,18 @@
- bs.getRealTime() is no more. Pass timetype='real' and timeformat='ms' to ba.time() if you need to recreate its behavior. - bs.getRealTime() is no more. Pass timetype='real' and timeformat='ms' to ba.time() if you need to recreate its behavior.
- bs.getTimeString() is now just ba.timestring(), and accepts seconds by default (pass timeformat='ms' to keep old calls working). - bs.getTimeString() is now just ba.timestring(), and accepts seconds by default (pass timeformat='ms' to keep old calls working).
- bs.callInGameThread() has been replaced by an optional `from_other_thread` arg for ba.pushcall() - bs.callInGameThread() has been replaced by an optional `from_other_thread` arg for ba.pushcall()
- There is now a special ba.UNHANDLED value that handlemessage() calls should return any time they don't handle a passed message. This will allow fallback message types and other nice things in the future. - There is now a special `ba.UNHANDLED` value that handlemessage() calls should return any time they don't handle a passed message. This will allow fallback message types and other nice things in the future.
- Wired the boolean operator up to ba.Actor's exists() method, so now a simple "if mynode" will do the right thing for both Actors and None values instead of having to explicitly check for both. - Wired the boolean operator up to ba.Actor's exists() method, so now a simple "if mynode" will do the right thing for both Actors and None values instead of having to explicitly check for both.
- Ditto for ba.Node; you can now just do 'if mynode' which will do the right thing for both a dead Node or None. - Ditto for ba.Node; you can now just do 'if mynode' which will do the right thing for both a dead Node or None.
- Ditto for ba.InputDevice, ba.Widget, ba.Player - Ditto for ba.InputDevice, ba.Widget, ba.Player
- Added a bs.App class accessible via ba.app; will be migrating global app values there instead of littering python modules with globals. The only remaining module globals should be all-caps public 'constants' - Added a bs.App class accessible via ba.app; will be migrating global app values there instead of littering python modules with globals. The only remaining module globals should be all-caps public 'constants'
- 'Internal' methods and classes living in `_ba` and elsewhere no longer start with underscores. They are now simply marked with '(internal)' in their docstrings. 'Internal' bits are likely to have janky interfaces and can change without warning, so be wary of using them. If you find yourself depending on some internal thing often, please let me know and I can try to clean it up and make it 'public'. - 'Internal' methods and classes living in `_ba` and elsewhere no longer start with underscores. They are now simply marked with '(internal)' in their docstrings. 'Internal' bits are likely to have janky interfaces and can change without warning, so be wary of using them. If you find yourself depending on some internal thing often, please let me know, and I can try to clean it up and make it 'public'.
- bs.getLanguage() is no more; that value is now accessible via ba.app.language - bs.getLanguage() is no more; that value is now accessible via ba.app.language
- bs.Actor now accepts an optional 'node' arg which it will store as self.node if passed. Its default DieMessage() and exists() handlers will use self.node if it exists. This removes the need for a separate NodeActor() for simple cases. - bs.Actor now accepts an optional 'node' arg which it will store as `self.node` if passed. Its default DieMessage() and exists() handlers will use `self.node` if it exists. This removes the need for a separate NodeActor() for simple cases.
- bs.NodeActor is no more (it can simply be replaced with ba.Actor()) - bs.NodeActor is no more (it can simply be replaced with ba.Actor())
- bs.playMusic() is now ba.setmusic() which better fits its functionality (it sometimes just continues playing or stops playing). - bs.playMusic() is now ba.setmusic() which better fits its functionality (it sometimes just continues playing or stops playing).
- The bs.Vector class is no more; in its place is a shiny new ba.Vec3 which is implemented internally in C++ so its nice and speedy. Will probably update certain things like vector node attrs to support this class in the future since it makes vector math nice and convenient. - The bs.Vector class is no more; in its place is a shiny new ba.Vec3 which is implemented internally in C++ so its nice and speedy. Will probably update certain things like vector node attrs to support this class in the future since it makes vector math nice and convenient.
- Ok you get the point.. see [ballistica.net](https://ballistica.net) for more info on these changes. - Ok you get the point... see [ballistica.net](https://ballistica.net) for more info on these changes.
### 1.4.155 (14377) ### 1.4.155 (14377)
- Added protection against a repeated-input attack in lobbies. - Added protection against a repeated-input attack in lobbies.
@ -282,7 +282,7 @@
### 1.4.147 (14364) ### 1.4.147 (14364)
- Fixes an issue where a client rejoining a server after being kicked could get stuck in limbo - Fixes an issue where a client rejoining a server after being kicked could get stuck in limbo
- Language updates - Language updates
- Increased security on games that list themselves as public. All joining players must now be validated by the master server or they will be kicked. This will let me globally ban accounts or ip addresses from joining games to avoid things like ad spam bots (which has been a problem this week). - Increased security on games that list themselves as public. All joining players must now be validated by the master server, or they will be kicked. This will let me globally ban accounts or ip addresses from joining games to avoid things like ad spam-bots (which has been a problem this week).
- Added a max chat message length of 100 - Added a max chat message length of 100
- Clients sending abnormal amounts of data to the server will now be auto-kicked - Clients sending abnormal amounts of data to the server will now be auto-kicked
@ -319,7 +319,7 @@
### 1.4.137 (14331) ### 1.4.137 (14331)
- Lots of internal code cleanup and reorganization before I dig into networking rework (hopefully didn't break too much) - Lots of internal code cleanup and reorganization before I dig into networking rework (hopefully didn't break too much)
- Slowly cleaning up Python files (hoping to move closer to to PEP 8 standards and eventually Python 3) - Slowly cleaning up Python files (hoping to move closer to PEP 8 standards and eventually Python 3)
- Added Hindi language - Added Hindi language
- Cleared out some old build types (farewell OUYA; thanks for the memories) - Cleared out some old build types (farewell OUYA; thanks for the memories)
- Added support for meshes with > 65535 verts (though turns out OpenGL ES2 doesn't support this so moot at the moment) - Added support for meshes with > 65535 verts (though turns out OpenGL ES2 doesn't support this so moot at the moment)
@ -330,7 +330,7 @@
- Fixed an issue where 'report this player' window would show up behind the window that spawned it - Fixed an issue where 'report this player' window would show up behind the window that spawned it
### 1.4.135 (14324) ### 1.4.135 (14324)
- Updated various SDKs for the android build (now building against api 27, removed inmobi ads, etc) - Updated various SDKs for the android build (now building against api 27, removed inmobi ads, etc.)
### 1.4.134 (14322) ### 1.4.134 (14322)
- Fixed an issue where the internal keyboard would sometimes show up behind game windows - Fixed an issue where the internal keyboard would sometimes show up behind game windows
@ -350,8 +350,8 @@
- Replay speed can now be controlled with -/= keys (on devices with keyboards) - Replay speed can now be controlled with -/= keys (on devices with keyboards)
- Added Serbian language - Added Serbian language
- Remote app connections are now disabled by default on server builds - Remote app connections are now disabled by default on server builds
- Server wrapper script now supports python 3 in addition to python 2. (Python 3 support in the actual game will still be a while) - Server wrapper script now supports python 3 in addition to python 2. (Python 3 support in the actual game will still be awhile)
- Added better crash reporting on Android so I can hopefully fix bugs quicker - Added better crash reporting on Android, so I can hopefully fix bugs more quickly.
- bs.Lstr() can now take a 'fallbackResource' or 'fallbackValue' argument; the old 'fallback' argument is deprecated - bs.Lstr() can now take a 'fallbackResource' or 'fallbackValue' argument; the old 'fallback' argument is deprecated
- Removed the long-since-deprecated bs.translate() and bs.getResource() calls (bs.Lstr() should be used for all that stuff now) - Removed the long-since-deprecated bs.translate() and bs.getResource() calls (bs.Lstr() should be used for all that stuff now)
- Removed some deprecated functions from GameActivity: getInstanceScoreBoardNameLocalized(), getInstanceNameLocalized(), getConfigDescriptionLocalized() - Removed some deprecated functions from GameActivity: getInstanceScoreBoardNameLocalized(), getInstanceNameLocalized(), getConfigDescriptionLocalized()
@ -382,7 +382,7 @@
- Added support for account unlinking - Added support for account unlinking
### 1.4.118 (14298) ### 1.4.118 (14298)
- Added 64 bit arm binary to Android builds - Added 64-bit arm binary to Android builds
### 1.4.111 (14286) ### 1.4.111 (14286)
- BallisticaCore Pro now unlocks 2 additional characters - BallisticaCore Pro now unlocks 2 additional characters
@ -398,15 +398,15 @@
- added a 'playlistCode' option in the server config which corresponds with playlist codes added in Ballisticacore 1.4.100 (used for sharing playlists with friends). Now you can create a custom playlist, grab a code for it, and easily use it in a dedicated server. - added a 'playlistCode' option in the server config which corresponds with playlist codes added in Ballisticacore 1.4.100 (used for sharing playlists with friends). Now you can create a custom playlist, grab a code for it, and easily use it in a dedicated server.
### 1.4.99 (14252) ### 1.4.99 (14252)
- there is now a forced 10 second delay between a player leaving the game and another player from that same client joining the game. This should fix the exploit where players were leaving and re-joining to avoid spawn times. - there is now a forced 10-second delay between a player leaving the game and another player from that same client joining the game. This should fix the exploit where players were leaving and re-joining to avoid spawn times.
- most in-game text is now set as bs.Lstr() values so that they show up in the client's own language instead of the server's There are currently a few exceptions such as time values which I need to address. - most in-game text is now set as bs.Lstr() values so that they show up in the client's own language instead of the server's There are currently a few exceptions such as time values which I need to address.
### 1.4.98 (14248) ### 1.4.98 (14248)
- added kick-votes that can be started by any client. currently a client must type '0' or '1' in chat to vote, but i'll add buttons for them soon. - added kick-votes that can be started by any client. Currently, a client must type '0' or '1' in chat to vote, but I'll add buttons for them soon.
- modified text nodes so they can display in each client's own language. (most text nodes don't do this yet but the capability is there). However this means older clients can't connect to 1.4.98 servers, so you may want to stick with an older server for a bit until the userbase gets more updated. - modified text nodes so that they can display in each client's own language. (most text nodes don't do this yet but the capability is there). However, this means older clients can't connect to 1.4.98 servers, so you may want to stick with an older server for a bit until the userbase gets more updated.
### 1.4.97 (14247) ### 1.4.97 (14247)
- back to displaying long names in more places; mainly just the in-game ones are clamped.. trying to find a good balance.. - back to displaying long names in more places; mainly just the in-game ones are clamped... trying to find a good balance...
### 1.4.97 (14246) ### 1.4.97 (14246)
- public party names will now show up for clients as the title of their party windows instead of "My Party" and also during connect/disconnect (requires client 14246+) - public party names will now show up for clients as the title of their party windows instead of "My Party" and also during connect/disconnect (requires client 14246+)
@ -420,16 +420,16 @@
- server now clamps in-game names to 8 characters so there's some hope of reading them in-game. Can loosen this or add controls for how clamping happens if need be. - server now clamps in-game names to 8 characters so there's some hope of reading them in-game. Can loosen this or add controls for how clamping happens if need be.
### 1.4.96 (14241) ### 1.4.96 (14241)
- added an automatic chat-block to combat chat spammers. Blocks start at 10 seconds and double in duration for each repeat offense - added an automatic chat-block to combat chat spammers. Block durations start at 10 seconds and double with each repeat offense
### 1.4.95 (14240) ### 1.4.95 (14240)
- fixed an issue where a single account could not be used to host multiple parties at once - fixed an issue where a single account could not be used to host multiple parties at once
### 1.4.95 (14236) ### 1.4.95 (14236)
- added a port option to the config so its now possible to host multiple parties on one machine (note that ballisticacore 1.4.95+ is required to connect ports aside from 43210) - added a port option to the config, so it's now possible to host multiple parties on one machine (note that ballisticacore 1.4.95+ is required to connect ports aside from 43210)
### 1.4.95 (14234) ### 1.4.95 (14234)
- fixed a bug that could cause the windows version to freeze randomly after a while - fixed a bug that could cause the Windows version to freeze randomly after a while
### 1.4.95 (14233) ### 1.4.95 (14233)
- ballisticacore (both `bs_headless` and regular) now reads commands from standard input, making it easier to run commands via scripts or the terminal - ballisticacore (both `bs_headless` and regular) now reads commands from standard input, making it easier to run commands via scripts or the terminal
@ -439,7 +439,7 @@
- added more options such as the ability to set game series lengths and to host a non-public party - added more options such as the ability to set game series lengths and to host a non-public party
### 1.4.94 ### 1.4.94
- now have mac, windows, and both 32 and 64 bit linux server builds - now have mac, windows, and both 32 and 64-bit linux server builds
- added an optional config.py file that can be used instead of modifying the server script itself - added an optional config.py file that can be used instead of modifying the server script itself
- added an autoBalanceTeams option for teams games - added an autoBalanceTeams option for teams games
- people joining and leaving the party are no longer announced (too much noise) - people joining and leaving the party are no longer announced (too much noise)

View File

@ -705,6 +705,11 @@ test-dataclassio:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \ @tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \
tests/test_efro/test_dataclassio.py tests/test_efro/test_dataclassio.py
# Individual test with extra output enabled.
test-message:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \
tests/test_efro/test_message.py
# Individual test with extra output enabled. # Individual test with extra output enabled.
test-entity: test-entity:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \ @tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \

View File

@ -499,6 +499,7 @@
"ba_data/python/efro/__pycache__/dataclassio.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/dataclassio.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/message.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc",
"ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc",
@ -520,6 +521,7 @@
"ba_data/python/efro/entity/util.py", "ba_data/python/efro/entity/util.py",
"ba_data/python/efro/error.py", "ba_data/python/efro/error.py",
"ba_data/python/efro/json.py", "ba_data/python/efro/json.py",
"ba_data/python/efro/message.py",
"ba_data/python/efro/net.py", "ba_data/python/efro/net.py",
"ba_data/python/efro/terminal.py", "ba_data/python/efro/terminal.py",
"ba_data/python/efro/util.py", "ba_data/python/efro/util.py",

View File

@ -652,6 +652,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \
build/ba_data/python/efro/entity/util.py \ build/ba_data/python/efro/entity/util.py \
build/ba_data/python/efro/error.py \ build/ba_data/python/efro/error.py \
build/ba_data/python/efro/json.py \ build/ba_data/python/efro/json.py \
build/ba_data/python/efro/message.py \
build/ba_data/python/efro/net.py \ build/ba_data/python/efro/net.py \
build/ba_data/python/efro/terminal.py \ build/ba_data/python/efro/terminal.py \
build/ba_data/python/efro/util.py build/ba_data/python/efro/util.py
@ -674,6 +675,7 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \
build/ba_data/python/efro/entity/__pycache__/util.cpython-38.opt-1.pyc \ build/ba_data/python/efro/entity/__pycache__/util.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/message.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc \
build/ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc build/ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc

View File

@ -1 +1 @@
3589099007368754607207796662508579801 119796669300700074719883839459258868842

View File

@ -256,6 +256,7 @@
<w>dernit</w> <w>dernit</w>
<w>dets</w> <w>dets</w>
<w>dfba</w> <w>dfba</w>
<w>dffc</w>
<w>dfff</w> <w>dfff</w>
<w>dfmt</w> <w>dfmt</w>
<w>dictval</w> <w>dictval</w>
@ -326,6 +327,7 @@
<w>ewwwww</w> <w>ewwwww</w>
<w>exctype</w> <w>exctype</w>
<w>execinfo</w> <w>execinfo</w>
<w>execing</w>
<w>exhash</w> <w>exhash</w>
<w>exhashstr</w> <w>exhashstr</w>
<w>expbool</w> <w>expbool</w>
@ -347,6 +349,7 @@
<w>fdirz</w> <w>fdirz</w>
<w>fenv</w> <w>fenv</w>
<w>fesetround</w> <w>fesetround</w>
<w>ffbbdf</w>
<w>ffff</w> <w>ffff</w>
<w>ffffff</w> <w>ffffff</w>
<w>fffffff</w> <w>fffffff</w>
@ -577,9 +580,11 @@
<w>lpsockaddr</w> <w>lpsockaddr</w>
<w>lrintf</w> <w>lrintf</w>
<w>lscope</w> <w>lscope</w>
<w>lshort</w>
<w>lstr</w> <w>lstr</w>
<w>lsync</w> <w>lsync</w>
<w>ltypes</w> <w>ltypes</w>
<w>lubyte</w>
<w>lvec</w> <w>lvec</w>
<w>lvoid</w> <w>lvoid</w>
<w>macbuild</w> <w>macbuild</w>
@ -626,6 +631,7 @@
<w>mmask</w> <w>mmask</w>
<w>mmdevapi</w> <w>mmdevapi</w>
<w>modder</w> <w>modder</w>
<w>modders</w>
<w>modelview</w> <w>modelview</w>
<w>moduletype</w> <w>moduletype</w>
<w>momemtary</w> <w>momemtary</w>
@ -845,6 +851,7 @@
<w>reallocations</w> <w>reallocations</w>
<w>realtimers</w> <w>realtimers</w>
<w>recalc</w> <w>recalc</w>
<w>recv</w>
<w>recvfrom</w> <w>recvfrom</w>
<w>redundants</w> <w>redundants</w>
<w>refcounted</w> <w>refcounted</w>

View File

@ -11,10 +11,12 @@
</inspection_tool> </inspection_tool>
<inspection_tool class="ConstructionIsNotAllowed" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="ConstructionIsNotAllowed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateSwitchCase" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="DuplicateSwitchCase" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GrazieInspection" enabled="false" level="TYPO" enabled_by_default="false" />
<inspection_tool class="ImplicitPointerAndIntegerConversion" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="ImplicitPointerAndIntegerConversion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IncompatibleTypes" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="IncompatibleTypes" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InitializationIssue" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="InitializationIssue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InterfaceHasNoImplementation" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="InterfaceHasNoImplementation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LocalValueEscapesScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoopDoesntUseConditionVariable" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="LoopDoesntUseConditionVariable" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MemberFunctionCanBeStatic" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="MemberFunctionCanBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MemberVisibility" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="MemberVisibility" enabled="false" level="ERROR" enabled_by_default="false" />
@ -31,6 +33,9 @@
<inspection_tool class="OtherCpp" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="OtherCpp" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="OtherObjC" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="OtherObjC" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="PointerTypeRequired" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="PointerTypeRequired" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="PreprocessorComment" enabled="true" level="WARNING" enabled_by_default="true">
<scope name="Ignored" level="WARNING" enabled="false" />
</inspection_tool>
<inspection_tool class="Simplify" enabled="false" level="WARNING" enabled_by_default="false"> <inspection_tool class="Simplify" enabled="false" level="WARNING" enabled_by_default="false">
<option name="clangTidyCheckOptions"> <option name="clangTidyCheckOptions">
<list> <list>

View File

@ -5,13 +5,14 @@
</component> </component>
<component name="CidrRootsConfiguration"> <component name="CidrRootsConfiguration">
<excludeRoots> <excludeRoots>
<file path="$PROJECT_DIR$/.idea" />
<file path="$PROJECT_DIR$/../.assetcache" /> <file path="$PROJECT_DIR$/../.assetcache" />
<file path="$PROJECT_DIR$/../.cache" /> <file path="$PROJECT_DIR$/../.cache" />
<file path="$PROJECT_DIR$/../.mypy_cache" /> <file path="$PROJECT_DIR$/../.mypy_cache" />
<file path="$PROJECT_DIR$/../.pytest_cache" /> <file path="$PROJECT_DIR$/../.pytest_cache" />
<file path="$PROJECT_DIR$/../assets" /> <file path="$PROJECT_DIR$/../assets" />
<file path="$PROJECT_DIR$/../ballisticacore-android" /> <file path="$PROJECT_DIR$/../ballisticacore-android" />
<file path="$PROJECT_DIR$/.idea" /> <file path="$PROJECT_DIR$/../.idea" />
<file path="$PROJECT_DIR$/../src/external" /> <file path="$PROJECT_DIR$/../src/external" />
<file path="$PROJECT_DIR$/../src/external/darwiinremote-ef" /> <file path="$PROJECT_DIR$/../src/external/darwiinremote-ef" />
<file path="$PROJECT_DIR$/../src/external/libogg-1.2.2" /> <file path="$PROJECT_DIR$/../src/external/libogg-1.2.2" />
@ -27,6 +28,26 @@
<file path="$PROJECT_DIR$/../src/external/tremor" /> <file path="$PROJECT_DIR$/../src/external/tremor" />
<file path="$PROJECT_DIR$/../src/external/windows" /> <file path="$PROJECT_DIR$/../src/external/windows" />
<file path="$PROJECT_DIR$/../src/ballistica/generated" /> <file path="$PROJECT_DIR$/../src/ballistica/generated" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_amazon.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_arcade.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_cardboard.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_common.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_demo.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_generic.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_google.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_iircade.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_oculus.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_template.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_common.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_generic.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_headless.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_oculus.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_common.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_ios.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_ios_legacy.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_mac.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_mac_legacy.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_xcode_tvos.h" />
<file path="$PROJECT_DIR$/../ballisticacore-ios.xcodeproj" /> <file path="$PROJECT_DIR$/../ballisticacore-ios.xcodeproj" />
<file path="$PROJECT_DIR$/../ballisticacore-mac.xcodeproj" /> <file path="$PROJECT_DIR$/../ballisticacore-mac.xcodeproj" />
<file path="$PROJECT_DIR$/../ballisticacore-windows" /> <file path="$PROJECT_DIR$/../ballisticacore-windows" />
@ -42,4 +63,4 @@
<component name="JavaScriptSettings"> <component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" /> <option name="languageLevel" value="ES6" />
</component> </component>
</project> </project>

View File

@ -0,0 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Ignored" pattern="file[BallisticaCore]:src/ballistica/config/*&amp;&amp;!file:src/ballistica/config/config_cmake.h&amp;&amp;!file:src/ballistica/config/config_common.h" />
</component>

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND --> <!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2021-07-01 for Ballistica version 1.6.5 build 20388</em></h4> <h4><em>last updated on 2021-08-16 for Ballistica version 1.6.5 build 20391</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module, <p>This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p> which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr> <hr>

View File

@ -31,9 +31,9 @@ App::App(Thread* thread)
void App::PostInit() { void App::PostInit() {
// If we've got a nice themed hardware cursor, show it. // If we've got a nice themed hardware cursor, show it.
// Otherwise hide the hardware cursor; we'll draw it in software. // Otherwise, hide the hardware cursor; we'll draw it in software.
// (need to run this in postinit because SDL/etc may not be inited yet // (need to run this in postinit because SDL/etc. may not be inited yet
// as of App::App(). // as of App::App()).
g_platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor()); g_platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor());
} }
@ -72,7 +72,7 @@ void App::RebuildLostGLContext() {
void App::DrawFrame(bool during_resize) { void App::DrawFrame(bool during_resize) {
assert(InMainThread()); assert(InMainThread());
// Its possible to receive frames before we're ready to draw. // It's possible to receive frames before we're ready to draw.
if (!g_graphics_server || !g_graphics_server->renderer()) { if (!g_graphics_server || !g_graphics_server->renderer()) {
return; return;
} }
@ -157,7 +157,7 @@ void App::OnPause() {
g_graphics->SetGyroEnabled(false); g_graphics->SetGyroEnabled(false);
// IMPORTANT: Any on-pause related stuff that threads need to do must // IMPORTANT: Any on-pause related stuff that threads need to do must
// must be done from their HandleThreadPause(). If we push runnables to them // be done from their HandleThreadPause(). If we push runnables to them,
// they may or may not be called before the thread is actually paused. // they may or may not be called before the thread is actually paused.
Thread::SetThreadsPaused(true); Thread::SetThreadsPaused(true);
@ -191,7 +191,7 @@ void App::OnResume() {
} }
// Also let the Python layer do what it needs to // Also let the Python layer do what it needs to
// (starting/stopping music, etc). // (starting/stopping music, etc.).
g_python->PushObjCall(Python::ObjID::kHandleAppResumeCall); g_python->PushObjCall(Python::ObjID::kHandleAppResumeCall);
g_game->PushOnAppResumeCall(); g_game->PushOnAppResumeCall();

View File

@ -57,9 +57,9 @@ auto Audio::SourceBeginNew() -> AudioSource* {
AudioSource* s = nullptr; AudioSource* s = nullptr;
{ {
// Gotta make sure to hold this until we've locked the source. // Got to make sure to hold this until we've locked the source.
// Otherwise theoretically the audio thread could make our source available // Otherwise, theoretically, the audio thread could make our source
// again before we can use it. // available again before we can use it.
std::lock_guard<std::mutex> lock(available_sources_mutex_); std::lock_guard<std::mutex> lock(available_sources_mutex_);
// If there's an available source, reserve and return it. // If there's an available source, reserve and return it.
@ -99,7 +99,7 @@ auto Audio::SourceBeginExisting(uint32_t play_id, int debug_id)
// Ok, the audio thread fills in this source list, // Ok, the audio thread fills in this source list,
// so theoretically a client could call this before the audio thread // so theoretically a client could call this before the audio thread
// has set it up. However no one should be trying to get a playing // has set it up. However, no one should be trying to get a playing
// sound unless they've already started playing one which implies // sound unless they've already started playing one which implies
// everything was set up already. I think we're good. // everything was set up already. I think we're good.
assert(g_audio->client_sources_.size() > source_id); assert(g_audio->client_sources_.size() > source_id);

View File

@ -27,7 +27,7 @@ class Audio {
// Return a pointer to a locked sound source, or nullptr if they're all busy. // Return a pointer to a locked sound source, or nullptr if they're all busy.
// The sound source will be reset to standard settings (no loop, fade 1, pos // The sound source will be reset to standard settings (no loop, fade 1, pos
// 0,0,0, etc). // 0,0,0, etc.).
// Send the source any immediate commands and then unlock it. // Send the source any immediate commands and then unlock it.
// For later modifications, re-retrieve the sound with GetPlayingSound() // For later modifications, re-retrieve the sound with GetPlayingSound()
auto SourceBeginNew() -> AudioSource*; auto SourceBeginNew() -> AudioSource*;

View File

@ -255,7 +255,7 @@ void AudioServer::PushSourcePlayCall(uint32_t play_id,
ThreadSource* s = GetPlayingSound(play_id); ThreadSource* s = GetPlayingSound(play_id);
// If this play command is valid, pass it along. // If this play command is valid, pass it along.
// Otherwise return it immediately for deletion. // Otherwise, return it immediately for deletion.
if (s) { if (s) {
s->Play(sound); s->Play(sound);
} else { } else {
@ -325,7 +325,7 @@ AudioServer::AudioServer(Thread* thread)
impl_{new AudioServer::Impl()} impl_{new AudioServer::Impl()}
// impl_{std::make_unique<AudioServer::Impl>()} // impl_{std::make_unique<AudioServer::Impl>()}
{ {
// we're a singleton.. // we're a singleton...
assert(g_audio_server == nullptr); assert(g_audio_server == nullptr);
g_audio_server = this; g_audio_server = this;
@ -441,7 +441,7 @@ void AudioServer::UpdateAvailableSources() {
i->UpdateAvailability(); i->UpdateAvailability();
} }
// Some sanity checking. Every now and then lets go through our sources // Some sanity checking. Occasionally lets go through our sources
// 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)
@ -511,7 +511,7 @@ auto AudioServer::GetPlayingSound(uint32_t play_id)
// not return it here. // not return it here.
sources_[source]->UpdateAvailability(); sources_[source]->UpdateAvailability();
// If it still looks like its ours, return it.. // If it still looks like it's ours, return it...
if (count == sources_[source]->play_count()) { if (count == sources_[source]->play_count()) {
return sources_[source]; return sources_[source];
} }
@ -743,7 +743,7 @@ void AudioServer::ThreadSource::UpdateAvailability() {
assert(InAudioThread()); assert(InAudioThread());
// If its waiting to be picked up by a client or has pending client commands, // If it's waiting to be picked up by a client or has pending client commands,
// skip. // skip.
if (!client_source_->TryLock(6)) { if (!client_source_->TryLock(6)) {
return; return;
@ -757,15 +757,15 @@ void AudioServer::ThreadSource::UpdateAvailability() {
// We consider ourselves busy if there's an active looping play command // We consider ourselves busy if there's an active looping play command
// (regardless of its actual physical play state - music could be turned off, // (regardless of its actual physical play state - music could be turned off,
// stuttering, etc). // stuttering, etc.).
// If its non-looping, we check its play state and snatch it if its not // If it's non-looping, we check its play state and snatch it if it's not
// playing. // playing.
bool busy; bool busy;
if (looping_ || (is_streamed_ && streamer_.exists() && streamer_->loops())) { if (looping_ || (is_streamed_ && streamer_.exists() && streamer_->loops())) {
busy = want_to_play_; busy = want_to_play_;
} else { } else {
// If our context is paused, we know nothing is playing // If our context is paused, we know nothing is playing
// (and we cant ask AL cuz we have no context). // (and we can't ask AL cuz we have no context).
if (g_audio_server->paused()) { if (g_audio_server->paused()) {
busy = false; busy = false;
} else { } else {
@ -778,7 +778,7 @@ void AudioServer::ThreadSource::UpdateAvailability() {
// Ok, now if we can get a lock on the availability list, go ahead and // Ok, now if we can get a lock on the availability list, go ahead and
// make this guy available; give him a new play id and reset his state. // make this guy available; give him a new play id and reset his state.
// If we can't get a lock its no biggie.. we'll come back to this guy later. // If we can't get a lock it's no biggie... we'll come back to this guy later.
if (!busy) { if (!busy) {
if (g_audio->available_sources_mutex().try_lock()) { if (g_audio->available_sources_mutex().try_lock()) {
@ -903,7 +903,7 @@ void AudioServer::ThreadSource::ExecPlay() {
audio_thread_->streaming_sources_.push_back(this); audio_thread_->streaming_sources_.push_back(this);
// Make sure stereo sounds aren't positional. // Make sure stereo sounds aren't positional.
// This is default behavior on Mac/Win but we enforce it for linux. // This is default behavior on Mac/Win, but we enforce it for linux.
// (though currently linux stereo sounds play in mono... eww)) // (though currently linux stereo sounds play in mono... eww))
bool do_normal = true; bool do_normal = true;
@ -927,7 +927,7 @@ void AudioServer::ThreadSource::ExecPlay() {
} else { // Not streamed } else { // Not streamed
// Make sure stereo sounds aren't positional. // Make sure stereo sounds aren't positional.
// This is default behavior on Mac/Win but we enforce it for linux. // This is default behavior on Mac/Win, but we enforce it for linux.
// (though currently linux stereo sounds play in mono... eww)) // (though currently linux stereo sounds play in mono... eww))
if ((**source_sound_).format() == AL_FORMAT_STEREO16) { if ((**source_sound_).format() == AL_FORMAT_STEREO16) {
SetPositional(false); SetPositional(false);
@ -957,8 +957,8 @@ auto AudioServer::ThreadSource::Play(const Object::Ref<SoundData>* sound)
source_sound_ = sound; source_sound_ = sound;
if (!g_audio_server->paused()) { if (!g_audio_server->paused()) {
// Ok, here's where we might start needing to access our media.. can't hold // Ok, here's where we might start needing to access our media... can't hold
// off any longer.. // off any longer...
(**source_sound_).Load(); (**source_sound_).Load();
is_streamed_ = (**source_sound_).is_streamed(); is_streamed_ = (**source_sound_).is_streamed();
@ -973,7 +973,7 @@ auto AudioServer::ThreadSource::Play(const Object::Ref<SoundData>* sound)
CHECK_AL_ERROR; CHECK_AL_ERROR;
// Always update our volume and pitch here (we may be changing from music to // Always update our volume and pitch here (we may be changing from music to
// nonMusic, etc) // nonMusic, etc.)
UpdateVolume(); UpdateVolume();
UpdatePitch(); UpdatePitch();
@ -1015,7 +1015,7 @@ void AudioServer::ThreadSource::ExecStop() {
#endif // BA_ENABLE_AUDIO #endif // BA_ENABLE_AUDIO
} }
// Do a complete stop.. take us off the music list, detach our source, etc. // Do a complete stop... take us off the music list, detach our source, etc.
void AudioServer::ThreadSource::Stop() { void AudioServer::ThreadSource::Stop() {
#if BA_ENABLE_AUDIO #if BA_ENABLE_AUDIO
assert(g_audio_server); assert(g_audio_server);
@ -1031,7 +1031,7 @@ void AudioServer::ThreadSource::Stop() {
} }
// If we've got an attached sound, toss it back to the main thread // If we've got an attached sound, toss it back to the main thread
// to free up... // to free up...
// (we can't kill media-refs outside of the main thread) // (we can't kill media-refs outside the main thread)
if (source_sound_) { if (source_sound_) {
assert(g_media); assert(g_media);
g_audio_server->AddSoundRefDelete(source_sound_); g_audio_server->AddSoundRefDelete(source_sound_);
@ -1096,12 +1096,12 @@ void AudioServer::PushSetPausedCall(bool pause) {
void AudioServer::PushComponentUnloadCall( void AudioServer::PushComponentUnloadCall(
const std::vector<Object::Ref<MediaComponentData>*>& components) { const std::vector<Object::Ref<MediaComponentData>*>& components) {
PushCall([this, components] { PushCall([this, components] {
// Unload all components we were passed.. // Unload all components we were passed...
for (auto&& i : components) { for (auto&& i : components) {
(**i).Unload(); (**i).Unload();
} }
// ..and then ship these pointers back to the game thread so it can free the // ...and then ship these pointers back to the game thread, so it can free
// references // the references.
g_game->PushFreeMediaComponentRefsCall(components); g_game->PushFreeMediaComponentRefsCall(components);
}); });
} }

View File

@ -72,8 +72,8 @@ auto AudioSource::Play(SoundData* ptr_in) -> uint32_t {
// allocate a new reference to this guy and pass it along // allocate a new reference to this guy and pass it along
// to the thread... (these refs can't be created or destroyed // to the thread... (these refs can't be created or destroyed
// or have their ref-counts changed outside of the main thread...) // or have their ref-counts changed outside the main thread...)
// the thread will then send back this allocated ptr when its done // the thread will then send back this allocated ptr when it's done
// with it for the main thread to destroy. // with it for the main thread to destroy.
ptr_in->UpdatePlayTime(); ptr_in->UpdatePlayTime();

View File

@ -21,7 +21,7 @@
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kAppBuildNumber = 20390; const int kAppBuildNumber = 20391;
const char* kAppVersion = "1.6.5"; const char* kAppVersion = "1.6.5";
// Our standalone globals. // Our standalone globals.
@ -59,11 +59,11 @@ TextGraphics* g_text_graphics{};
// should exist at the end of this step (if it is going to exist). // should exist at the end of this step (if it is going to exist).
// Threads should not be talking to each other yet at this point. // Threads should not be talking to each other yet at this point.
// 2: The system is set in motion. Game thread is told to load/apply the config. // 2: The system is set in motion. Game thread is told to load/apply the config.
// This kicks off an initial-screen-creation message sent to the // This event kicks off an initial-screen-creation message sent to the
// graphics-server thread. Other systems are informed that bootstrapping // graphics-server thread. Other systems are informed that bootstrapping
// is complete and they are free to talk to each other. Initial input-devices // is complete and that they are free to talk to each other. Initial
// are added, media loads can begin (at least ones not dependent on the // input-devices are added, media loads can begin (at least ones not
// screen/renderer), etc. // dependent on the screen/renderer), etc.
// 3: The initial screen is created on the graphics-server thread in response // 3: The initial screen is created on the graphics-server thread in response
// to the message sent from the game thread. A completion notice is sent // to the message sent from the game thread. A completion notice is sent
// back to the game thread when done. // back to the game thread when done.
@ -145,7 +145,7 @@ auto BallisticaMain(int argc, char** argv) -> int {
} else { } else {
// In this case we'll now simply return and let the OS feed us events // In this case we'll now simply return and let the OS feed us events
// until the app quits. // until the app quits.
// However we may need to 'prime the pump' first. For instance, // However, we may need to 'prime the pump' first. For instance,
// if the main thread event loop is driven by frame draws, it may need to // if the main thread event loop is driven by frame draws, it may need to
// manually pump events until drawing begins (otherwise it will never // manually pump events until drawing begins (otherwise it will never
// process the 'create-screen' event and wind up deadlocked). // process the 'create-screen' event and wind up deadlocked).
@ -185,13 +185,13 @@ auto GetRealTime() -> millisecs_t {
std::lock_guard<std::mutex> lock(g_app_globals->real_time_mutex); std::lock_guard<std::mutex> lock(g_app_globals->real_time_mutex);
millisecs_t passed = t - g_app_globals->last_real_time_ticks; millisecs_t passed = t - g_app_globals->last_real_time_ticks;
// GetTicks() is supposed to be monotonic but I've seen 'passed' // GetTicks() is supposed to be monotonic, but I've seen 'passed'
// equal -1 even when it is using std::chrono::steady_clock. Let's do // equal -1 even when it is using std::chrono::steady_clock. Let's do
// our own filtering here to make 100% sure we don't go backwards. // our own filtering here to make 100% sure we don't go backwards.
if (passed < 0) { if (passed < 0) {
passed = 0; passed = 0;
} else { } else {
// Super big times-passed probably means we went to sleep or something; // Very large times-passed probably means we went to sleep or something;
// clamp to a reasonable value. // clamp to a reasonable value.
if (passed > 250) { if (passed > 250) {
passed = 250; passed = 250;
@ -289,7 +289,7 @@ auto GetCurrentThreadName() -> std::string {
auto IsBootstrapped() -> bool { return g_app_globals->is_bootstrapped; } auto IsBootstrapped() -> bool { return g_app_globals->is_bootstrapped; }
// Used by our built in exception type. // Used by our built-in exception type.
void SetPythonException(PyExcType python_type, const char* description) { void SetPythonException(PyExcType python_type, const char* description) {
Python::SetPythonException(python_type, description); Python::SetPythonException(python_type, description);
} }

View File

@ -60,7 +60,7 @@ namespace ballistica {
#define BA_OSTYPE_LINUX 0 #define BA_OSTYPE_LINUX 0
#endif #endif
// On windows, are we built as a console app (vs a gui app)? // On Windows, are we built as a console app (vs a gui app)?
#ifndef BA_WINDOWS_CONSOLE_BUILD #ifndef BA_WINDOWS_CONSOLE_BUILD
#define BA_WINDOWS_CONSOLE_BUILD 1 #define BA_WINDOWS_CONSOLE_BUILD 1
#endif #endif
@ -91,7 +91,7 @@ namespace ballistica {
#endif #endif
// Does this build use our 'min-sdl' types? // Does this build use our 'min-sdl' types?
// (basic SDL types we define ourself; no actual SDL dependency) // (basic SDL types we define ourselves; no actual SDL dependency)
#ifndef BA_MINSDL_BUILD #ifndef BA_MINSDL_BUILD
#define BA_MINSDL_BUILD 0 #define BA_MINSDL_BUILD 0
#endif #endif
@ -189,7 +189,7 @@ typedef BA_SOCKET_SEND_LENGTH_TYPE socket_send_length_t;
bool InlineDebugExplicitBool(bool val); bool InlineDebugExplicitBool(bool val);
// Little hack so we avoid 'value is always true/false' and // Little hack so that we avoid 'value is always true/false' and
// 'code will never/always be run' type warnings when using these in debug // 'code will never/always be run' type warnings when using these in debug
// builds. // builds.
#if BA_DEBUG_BUILD #if BA_DEBUG_BUILD

View File

@ -25,7 +25,7 @@ auto Module::CheckPushSafety() -> bool {
if (std::this_thread::get_id() == thread()->thread_id()) { if (std::this_thread::get_id() == thread()->thread_id()) {
// behave the same as the thread-message safety check for // behave the same as the thread-message safety check for
// module messages. // module messages.
return (runnables_.size() < kThreadMessageSafetyThreadhold); return (runnables_.size() < kThreadMessageSafetyThreshold);
} else { } else {
return thread_->CheckPushModuleRunnableSafety(); return thread_->CheckPushModuleRunnableSafety();
} }

View File

@ -17,7 +17,7 @@
namespace ballistica { namespace ballistica {
const int kThreadMessageSafetyThreadhold{500}; const int kThreadMessageSafetyThreshold{500};
// A thread with a built-in event loop. // A thread with a built-in event loop.
class Thread { class Thread {
@ -167,7 +167,7 @@ class Thread {
auto CheckPushModuleRunnableSafety() -> bool { auto CheckPushModuleRunnableSafety() -> bool {
// We first complain when we get to 1000 queued messages so // We first complain when we get to 1000 queued messages so
// let's consider things unsafe when we're halfway there. // let's consider things unsafe when we're halfway there.
return (thread_message_count_ < kThreadMessageSafetyThreadhold); return (thread_message_count_ < kThreadMessageSafetyThreshold);
} }
// Register a timer to run on the thread. // Register a timer to run on the thread.

View File

@ -182,7 +182,7 @@ void BGDynamics::Draw(FrameDef* frame_def) {
sparks_mesh_->SetData( sparks_mesh_->SetData(
Object::Ref<MeshBuffer<VertexSprite>>(ds->spark_vertices)); Object::Ref<MeshBuffer<VertexSprite>>(ds->spark_vertices));
// In high-quality we draw in the overlay pass so we don't get wiped // In high-quality, we draw in the overlay pass so that we don't get wiped
// out by depth-of-field. // out by depth-of-field.
bool draw_in_overlay = (frame_def->quality() >= GraphicsQuality::kHigh); bool draw_in_overlay = (frame_def->quality() >= GraphicsQuality::kHigh);
SpriteComponent c(draw_in_overlay ? frame_def->overlay_3d_pass() SpriteComponent c(draw_in_overlay ? frame_def->overlay_3d_pass()
@ -284,7 +284,7 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
return; return;
} }
// Draw ourself into the beauty pass. // Draw ourselves into the beauty pass.
ModelData* model; ModelData* model;
switch (chunk_type) { switch (chunk_type) {
case BGDynamicsChunkType::kFlagStand: case BGDynamicsChunkType::kFlagStand:

View File

@ -54,7 +54,7 @@ class BGDynamics {
void Step(const Vector3f& cam_pos); void Step(const Vector3f& cam_pos);
// can be called to inform the bg dynamics thread to kill off some // can be called to inform the bg dynamics thread to kill off some
// smoke/chunks/etc if rendering is chugging or whatnot. // smoke/chunks/etc. if rendering is chugging or whatnot.
void TooSlow(); void TooSlow();
// Draws the last snapshot the bg-dynamics-server has delivered to us // Draws the last snapshot the bg-dynamics-server has delivered to us

View File

@ -21,7 +21,7 @@ class BGDynamicsDrawSnapshot {
}; };
// These are created in the bg-dynamics thread, and object ownership // These are created in the bg-dynamics thread, and object ownership
// needs to be switched back the the game-thread default when it is passed // needs to be switched back to the game-thread default when it is passed
// over or else the debug thread-access-checks will error. // over or else the debug thread-access-checks will error.
void SetGameThreadOwnership() { void SetGameThreadOwnership() {
if (g_buildconfig.debug_build()) { if (g_buildconfig.debug_build()) {

View File

@ -10,7 +10,7 @@ BGDynamicsFuse::BGDynamicsFuse() {
assert(g_bg_dynamics_server); assert(g_bg_dynamics_server);
assert(InGameThread()); assert(InGameThread());
// Allocate our data. We'll pass this to the BGDynamics thread and // Allocate our data. We'll pass this to the BGDynamics thread, and
// it'll then own it. // it'll then own it.
data_ = new BGDynamicsFuseData(); data_ = new BGDynamicsFuseData();
g_bg_dynamics_server->PushAddFuseCall(data_); g_bg_dynamics_server->PushAddFuseCall(data_);
@ -21,8 +21,8 @@ BGDynamicsFuse::~BGDynamicsFuse() {
assert(InGameThread()); assert(InGameThread());
// Let the data know the client side is dead // Let the data know the client side is dead
// so we're no longer included in step messages. // so that we're no longer included in step messages.
// (since by the time the worker gets the the data will be gone). // (since by the time the worker gets it the data will be gone).
data_->client_dead_ = true; data_->client_dead_ = true;
g_bg_dynamics_server->PushRemoveFuseCall(data_); g_bg_dynamics_server->PushRemoveFuseCall(data_);
} }

View File

@ -19,7 +19,7 @@ struct BGDynamicsFuseData {
} }
void Update(BGDynamicsServer* dyn) { void Update(BGDynamicsServer* dyn) {
// Do nothing if we havn't received an initial transform. // Do nothing if we haven't received an initial transform.
if (!have_transform_worker_) { if (!have_transform_worker_) {
return; return;
} }
@ -37,7 +37,7 @@ struct BGDynamicsFuseData {
} }
initial_position_set_ = true; initial_position_set_ = true;
} else { } else {
// ..otherwise dynamically update it. // ...otherwise dynamically update it.
Vector3f pt = transform_worker_.GetTranslate(); Vector3f pt = transform_worker_.GetTranslate();
target_pts_[0] = dyn_pts_[0] = pt; target_pts_[0] = dyn_pts_[0] = pt;
auto up = Vector3f(&transform_worker_.m[4]); auto up = Vector3f(&transform_worker_.m[4]);

View File

@ -16,7 +16,7 @@
namespace ballistica { namespace ballistica {
// Some triangle-on-box cases generate tons of contacts; lets try limiting it // Some triangle-on-box cases generate tons of contacts; lets try limiting it
// this way.. If that doesn't work we'll crank this up and add collision // this way... If that doesn't work we'll crank this up and add collision
// simplification. // simplification.
const int kMaxBGDynamicsContacts = 20; const int kMaxBGDynamicsContacts = 20;
@ -43,7 +43,7 @@ struct DebugLine {
Vector3f color; Vector3f color;
}; };
// Eww these aren't thread-safe but they're just for debugging so whatever. // Eww; these aren't thread-safe, but they're just for debugging so whatever.
std::vector<DebugLine> g_debug_lines; std::vector<DebugLine> g_debug_lines;
std::vector<Vector3f> g_debug_points; std::vector<Vector3f> g_debug_points;
#endif // BA_DEBUG_BUILD #endif // BA_DEBUG_BUILD
@ -173,9 +173,9 @@ class BGDynamicsServer::Tendril {
Vector3f diff_norm = diff.Normalized(); Vector3f diff_norm = diff.Normalized();
p_distorted += diff_norm * mag; p_distorted += diff_norm * mag;
// Also apply a very slight amount of actual outward force to ourself // Also apply a very slight amount of actual outward force to
// (only if we're kinda old though - otherwise it screws with our // ourselves (only if we're kinda old though - otherwise it screws
// initial shape too much). // with our initial shape too much).
if (age > 400) { if (age > 400) {
v += Vector3f(diff_norm.x * 0.03f, diff_norm.y * 0.01f, v += Vector3f(diff_norm.x * 0.03f, diff_norm.y * 0.01f,
diff_norm.z * 0.03f) diff_norm.z * 0.03f)
@ -190,7 +190,7 @@ class BGDynamicsServer::Tendril {
for (auto&& li : d.volume_lights_) { for (auto&& li : d.volume_lights_) {
BGDynamicsVolumeLightData& l(*li); BGDynamicsVolumeLightData& l(*li);
Vector3f& pLight(l.pos_worker); Vector3f& pLight(l.pos_worker);
float light_rad = l.radius_worker * 9.0f; // Lets grow it a bit. float light_rad = l.radius_worker * 9.0f; // Let's grow it a bit.
float light_rad_squared = light_rad * light_rad; float light_rad_squared = light_rad * light_rad;
float dist_squared = (pLight - p).LengthSquared(); float dist_squared = (pLight - p).LengthSquared();
if (dist_squared <= light_rad_squared) { if (dist_squared <= light_rad_squared) {
@ -274,7 +274,7 @@ class BGDynamicsServer::Tendril {
shadow_density_ = blend * shadow_density_ shadow_density_ = blend * shadow_density_
+ (1.0f - blend) * (i->p1.fade + i->p2.fade) * 0.5f; + (1.0f - blend) * (i->p1.fade + i->p2.fade) * 0.5f;
count++; count++;
if (count > 4) break; // only use first few.. if (count > 4) break; // only use first few...
i++; i++;
} }
} }
@ -355,7 +355,7 @@ class BGDynamicsServer::TendrilController {
tendril_->SetController(this); tendril_->SetController(this);
} }
~TendrilController() { ~TendrilController() {
// If we have a tendril, tell it we're dying and that its done emitting. // If we have a tendril, tell it we're dying and that it's done emitting.
if (tendril_) { if (tendril_) {
tendril_->SetController(nullptr); tendril_->SetController(nullptr);
tendril_->emit_rate_ = 0.0f; tendril_->emit_rate_ = 0.0f;
@ -591,7 +591,7 @@ void BGDynamicsServer::ParticleSet::UpdateAndCreateSnapshot(
p_dst->flicker = 1.0f; p_dst->flicker = 1.0f;
} }
// Render this point if its got a positive size. // Render this point if it's got a positive size.
if (p_dst->flicker > 0.0f && p_dst->size > 0.0f) { if (p_dst->flicker > 0.0f && p_dst->size > 0.0f) {
p_count_rendered++; p_count_rendered++;
@ -647,7 +647,7 @@ void BGDynamicsServer::ParticleSet::UpdateAndCreateSnapshot(
if (p_count != p_count_rendered) { if (p_count != p_count_rendered) {
// If we dropped all the way to zero, return empty. // If we dropped all the way to zero, return empty.
// Otherwise return a downsized buffer. // Otherwise, return a downsized buffer.
if (p_count_rendered == 0) { if (p_count_rendered == 0) {
*index_buffer = Object::Ref<MeshIndexBuffer16>(); *index_buffer = Object::Ref<MeshIndexBuffer16>();
*buffer = Object::Ref<MeshBufferVertexSprite>(); *buffer = Object::Ref<MeshBufferVertexSprite>();
@ -725,7 +725,7 @@ void BGDynamicsServer::UpdateTendrils() {
// Step existing tendril points. // Step existing tendril points.
t.UpdateSlices(this); t.UpdateSlices(this);
// Update the tendrils physics if it is not being controlled. // Update the tendrils' physics if it is not being controlled.
if (t.controller_ == nullptr) { if (t.controller_ == nullptr) {
t.prev_pos_ = t.position_; t.prev_pos_ = t.position_;
t.velocity_ += Vector3f(0, -0.1f, 0); // Gravity. t.velocity_ += Vector3f(0, -0.1f, 0); // Gravity.
@ -782,7 +782,7 @@ void BGDynamicsServer::UpdateTendrils() {
float inherit_velocity = 0.015f; float inherit_velocity = 0.015f;
// If this is our first step, drop down a span immediately. // If this is our first step, drop a span immediately.
if (!t.has_updated_) { if (!t.has_updated_) {
Vector3f r_uniform = Utils::Sphrand(0.2f * t.slice_rand_scale_); Vector3f r_uniform = Utils::Sphrand(0.2f * t.slice_rand_scale_);
float density = emit_rate > 0.1f ? 1.0f : emit_rate / 0.1f; float density = emit_rate > 0.1f ? 1.0f : emit_rate / 0.1f;
@ -1088,7 +1088,7 @@ void BGDynamicsServer::Emit(const BGDynamicsEmission& def) {
} }
} }
} else { } else {
// For debris, start scaling back once we pass 50.. at chunk_max lets // For debris, start scaling back once we pass 50... at chunk_max lets
// stop. // stop.
if (chunk_count_ >= chunk_max) { if (chunk_count_ >= chunk_max) {
emit_count = 0; emit_count = 0;
@ -1161,7 +1161,7 @@ void BGDynamicsServer::Emit(const BGDynamicsEmission& def) {
do_tendril = true; do_tendril = true;
} }
// If we're emitting sparks, every now and then give one of them a // If we're emitting sparks, occasionally give one of them a
// smoke tendril. // smoke tendril.
if (do_tendril) { if (do_tendril) {
// Create a tendril, create a controller for it, and store it // Create a tendril, create a controller for it, and store it
@ -1246,7 +1246,7 @@ void BGDynamicsServer::Emit(const BGDynamicsEmission& def) {
if (dCollide(ray, t_geom, 1, &contact[0].geom, sizeof(dContact))) { if (dCollide(ray, t_geom, 1, &contact[0].geom, sizeof(dContact))) {
pos = Vector3f(contact[0].geom.pos); pos = Vector3f(contact[0].geom.pos);
vel = Reflect(dir, Vector3f(contact[0].geom.normal)); vel = Reflect(dir, Vector3f(contact[0].geom.normal));
// bias direction up a bit.. this way it'll hopefully be less // bias direction up a bit... this way it'll hopefully be less
// likely to point underground when we smash it down on the // likely to point underground when we smash it down on the
// camera plane // camera plane
vel.y += RandomFloat() * def.spread * 1.0f; vel.y += RandomFloat() * def.spread * 1.0f;
@ -1256,7 +1256,7 @@ void BGDynamicsServer::Emit(const BGDynamicsEmission& def) {
} }
if (!hit) { if (!hit) {
// since dbias pushes us all in a direction away from a surface, // since dbias pushes us all in a direction away from a surface,
// nudge our start pos in the opposite dir a bit so we butt up // nudge our start pos in the opposite dir a bit so that we butt up
// against the surface more // against the surface more
pos = def.position + d_bias * RandomFloat() * -0.3f; pos = def.position + d_bias * RandomFloat() * -0.3f;
vel = dir; vel = dir;
@ -1908,7 +1908,7 @@ auto BGDynamicsServer::CreateDrawSnapshot() -> BGDynamicsDrawSnapshot* {
ss->shadow_indices.Clear(); ss->shadow_indices.Clear();
ss->shadow_vertices.Clear(); ss->shadow_vertices.Clear();
} else if (shadow_drawn_count != shadow_max_count) { } else if (shadow_drawn_count != shadow_max_count) {
// Otherwise resize our buffers down to what we actually used. // Otherwise, resize our buffers down to what we actually used.
assert(s_index - (&ss->shadow_indices->elements[0]) assert(s_index - (&ss->shadow_indices->elements[0])
== shadow_drawn_count * 6); == shadow_drawn_count * 6);
assert(s_vertex - (&ss->shadow_vertices->elements[0]) assert(s_vertex - (&ss->shadow_vertices->elements[0])
@ -1930,7 +1930,7 @@ auto BGDynamicsServer::CreateDrawSnapshot() -> BGDynamicsDrawSnapshot* {
ss->light_indices.Clear(); ss->light_indices.Clear();
ss->light_vertices.Clear(); ss->light_vertices.Clear();
} else if (light_drawn_count != light_max_count) { } else if (light_drawn_count != light_max_count) {
// Otherwise resize our buffers down to what we actually used. // Otherwise, resize our buffers down to what we actually used.
assert(l_index - (&ss->light_indices->elements[0]) assert(l_index - (&ss->light_indices->elements[0])
== light_drawn_count * 6); == light_drawn_count * 6);
assert(l_vertex - (&ss->light_vertices->elements[0]) assert(l_vertex - (&ss->light_vertices->elements[0])
@ -2167,7 +2167,7 @@ auto BGDynamicsServer::CreateDrawSnapshot() -> BGDynamicsDrawSnapshot* {
Vector3f from_cam = (cam_pos_ - fuse.dyn_pts_[0]).Normalized() * 0.2f; Vector3f from_cam = (cam_pos_ - fuse.dyn_pts_[0]).Normalized() * 0.2f;
Vector3f side{}; Vector3f side{};
// We push fuse points slightly towards cam so they're less likely to // We push fuse points slightly towards cam, so they're less likely to
// get occluded by stuff. // get occluded by stuff.
Vector3f cam_offs = {0.0f, 0.0f, 0.0f}; Vector3f cam_offs = {0.0f, 0.0f, 0.0f};
@ -2258,7 +2258,7 @@ void BGDynamicsServer::Step(StepData* step_data) {
assert(InBGDynamicsThread()); assert(InBGDynamicsThread());
assert(step_data); assert(step_data);
// Grab a ref to the raw StepData pointer we were passed.. we now own the // Grab a ref to the raw StepData pointer we were passed... we now own the
// data. // data.
auto ref(Object::MakeRefCounted(step_data)); auto ref(Object::MakeRefCounted(step_data));
@ -2310,7 +2310,7 @@ void BGDynamicsServer::Step(StepData* step_data) {
// Step the world. // Step the world.
dWorldQuickStep(ode_world_, kGameStepSeconds); dWorldQuickStep(ode_world_, kGameStepSeconds);
// Now generate a snapshot of our state and send it to the game thread // Now generate a snapshot of our state and send it to the game thread,
// so they can draw us. // so they can draw us.
BGDynamicsDrawSnapshot* snapshot = CreateDrawSnapshot(); BGDynamicsDrawSnapshot* snapshot = CreateDrawSnapshot();
g_game->PushCall([snapshot] { g_game->PushCall([snapshot] {
@ -2541,7 +2541,7 @@ void BGDynamicsServer::UpdateChunks() {
float vel_squared = vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]; float vel_squared = vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2];
// Slow down fast if we're going fast. // Slow down fast if we're going fast.
// Otherwise slow down more gradually. // Otherwise, slow down more gradually.
if (vel_squared > 14) { if (vel_squared > 14) {
dBodySetLinearVel(body, vel[0] * 0.94f, 0.13f + vel[1] * 0.94f, dBodySetLinearVel(body, vel[0] * 0.94f, 0.13f + vel[1] * 0.94f,
vel[2] * 0.94f); vel[2] * 0.94f);
@ -2557,7 +2557,7 @@ void BGDynamicsServer::UpdateChunks() {
float vel_squared = vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]; float vel_squared = vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2];
// Slow down fast if we're going fast. // Slow down fast if we're going fast.
// Otherwise slow down more gradually. // Otherwise, slow down more gradually.
if (vel_squared > 14) { if (vel_squared > 14) {
dBodySetLinearVel(body, vel[0] * 0.93f, 0.13f + vel[1] * 0.93f, dBodySetLinearVel(body, vel[0] * 0.93f, 0.13f + vel[1] * 0.93f,
vel[2] * 0.93f); vel[2] * 0.93f);
@ -2576,7 +2576,7 @@ void BGDynamicsServer::UpdateChunks() {
} else { } else {
const dReal* vel = dBodyGetAngularVel(body); const dReal* vel = dBodyGetAngularVel(body);
if (vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] > 500) { if (vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] > 500) {
// Drastic slowdown for super fast stuff. // Drastic slowdown for super-fast stuff.
dBodySetAngularVel(body, vel[0] * 0.75f, vel[1] * 0.75f, dBodySetAngularVel(body, vel[0] * 0.75f, vel[1] * 0.75f,
vel[2] * 0.75f); vel[2] * 0.75f);
} else { } else {
@ -2587,7 +2587,7 @@ void BGDynamicsServer::UpdateChunks() {
// If this chunk is disabled, we don't need to do anything // If this chunk is disabled, we don't need to do anything
// (since no terrain ever moves to wake us back up). // (since no terrain ever moves to wake us back up).
// Also we skip sweat since that neither casts shadows or collides. // Also, we skip sweat since that neither casts shadows nor collides.
if (dBodyIsEnabled(body) && type != BGDynamicsChunkType::kSweat) { if (dBodyIsEnabled(body) && type != BGDynamicsChunkType::kSweat) {
// Move our shadow ray to where we are and reset our shadow length. // Move our shadow ray to where we are and reset our shadow length.
const dReal* pos = dGeomGetPosition(geom); const dReal* pos = dGeomGetPosition(geom);

View File

@ -11,8 +11,8 @@ namespace ballistica {
BGDynamicsShadow::BGDynamicsShadow(float height_scaling) { BGDynamicsShadow::BGDynamicsShadow(float height_scaling) {
assert(InGameThread()); assert(InGameThread());
// allocate our shadow data.. we'll pass this to the BGDynamics thread // allocate our shadow data... we'll pass this to the BGDynamics thread,
// and it'll then own it // which will then own it.
data_ = new BGDynamicsShadowData(height_scaling); data_ = new BGDynamicsShadowData(height_scaling);
assert(g_bg_dynamics_server); assert(g_bg_dynamics_server);
g_bg_dynamics_server->PushAddShadowCall(data_); g_bg_dynamics_server->PushAddShadowCall(data_);
@ -22,9 +22,9 @@ BGDynamicsShadow::~BGDynamicsShadow() {
assert(InGameThread()); assert(InGameThread());
assert(g_bg_dynamics_server); assert(g_bg_dynamics_server);
// let the data know the client side is dead // let the data know the client side is dead,
// so we're no longer included in step messages // so we're no longer included in step messages
// (since by the time the worker gets the the data will be gone) // (since by the time the worker gets it the data will be gone)
data_->client_dead = true; data_->client_dead = true;
g_bg_dynamics_server->PushRemoveShadowCall(data_); g_bg_dynamics_server->PushRemoveShadowCall(data_);
} }

View File

@ -8,8 +8,8 @@ namespace ballistica {
BGDynamicsVolumeLight::BGDynamicsVolumeLight() { BGDynamicsVolumeLight::BGDynamicsVolumeLight() {
assert(InGameThread()); assert(InGameThread());
// allocate our light data.. we'll pass this to the BGDynamics thread // allocate our light data... we'll pass this to the BGDynamics thread,
// and it'll then own it // which will then own it
data_ = new BGDynamicsVolumeLightData(); data_ = new BGDynamicsVolumeLightData();
assert(g_bg_dynamics_server); assert(g_bg_dynamics_server);
g_bg_dynamics_server->PushAddVolumeLightCall(data_); g_bg_dynamics_server->PushAddVolumeLightCall(data_);
@ -18,9 +18,9 @@ BGDynamicsVolumeLight::BGDynamicsVolumeLight() {
BGDynamicsVolumeLight::~BGDynamicsVolumeLight() { BGDynamicsVolumeLight::~BGDynamicsVolumeLight() {
assert(InGameThread()); assert(InGameThread());
// let the data know the client side is dead // let the data know the client side is dead,
// so we're no longer included in step messages // so we're no longer included in step messages
// (since by the time the worker gets the the data will be gone) // (since by the time the worker gets it the data will be gone)
data_->client_dead = true; data_->client_dead = true;
assert(g_bg_dynamics_server); assert(g_bg_dynamics_server);

View File

@ -146,7 +146,7 @@ void CollisionCache::CollideAgainstGeom(dGeomID g1, void* data,
if (dirty_) Update(); if (dirty_) Update();
// Do a quick out if its not within our cache bounds at all. // Do a quick out if it's not within our cache bounds at all.
dReal* bounds1 = g1->aabb; dReal* bounds1 = g1->aabb;
if (bounds1[0] > x_max_ || bounds1[1] < x_min_ || bounds1[2] > y_max_ if (bounds1[0] > x_max_ || bounds1[1] < x_min_ || bounds1[2] > y_max_
|| bounds1[3] < y_min_ || bounds1[4] > z_max_ || bounds1[5] < z_min_) { || bounds1[3] < y_min_ || bounds1[4] > z_max_ || bounds1[5] < z_min_) {
@ -212,7 +212,7 @@ void CollisionCache::TestCell(size_t cell_index, int x, int z) {
float bottom = (cells_[cell_index].height_confirmed_collide_ + top) * 0.5f; float bottom = (cells_[cell_index].height_confirmed_collide_ + top) * 0.5f;
float height = top - bottom; float height = top - bottom;
// Don't wanna test with too thin a box.. may miss stuff. // Don't want to test with too thin a box... may miss stuff.
float box_height = std::max(1.0f, height); float box_height = std::max(1.0f, height);
if (height > 0.01f) { if (height > 0.01f) {
glow_[cell_index] = 1; glow_[cell_index] = 1;
@ -245,7 +245,7 @@ void CollisionCache::TestCell(size_t cell_index, int x, int z) {
cells_[cell_index].height_confirmed_empty_ = cells_[cell_index].height_confirmed_empty_ =
std::min(cells_[cell_index].height_confirmed_empty_, bottom); std::min(cells_[cell_index].height_confirmed_empty_, bottom);
} }
// This shouldn' happen but just in case. // This shouldn't happen but just in case.
cells_[cell_index].height_confirmed_empty_ = cells_[cell_index].height_confirmed_empty_ =
std::max(cells_[cell_index].height_confirmed_empty_, std::max(cells_[cell_index].height_confirmed_empty_,
cells_[cell_index].height_confirmed_collide_); cells_[cell_index].height_confirmed_collide_);
@ -254,7 +254,7 @@ void CollisionCache::TestCell(size_t cell_index, int x, int z) {
void CollisionCache::CollideAgainstSpace(dSpaceID space, void* data, void CollisionCache::CollideAgainstSpace(dSpaceID space, void* data,
dNearCallback* callback) { dNearCallback* callback) {
// We handle our own testing against trimeshes so we can bring our fancy // We handle our own testing against trimeshes, so we can bring our fancy
// caching into play. // caching into play.
if (!geoms_.empty()) { if (!geoms_.empty()) {
// Intersect all geoms in the space against all terrains. // Intersect all geoms in the space against all terrains.

View File

@ -31,7 +31,7 @@ class Account {
auto GetLoginState(int* state_num = nullptr) -> LoginState; auto GetLoginState(int* state_num = nullptr) -> LoginState;
// An extra value included when passing our account info to the server // An extra value included when passing our account info to the server
// ..(can be used for platform-specific install-signature stuff, etc). // ...(can be used for platform-specific install-signature stuff, etc.).
auto SetExtra(const std::string& extra) -> void; auto SetExtra(const std::string& extra) -> void;
auto SetExtra2(const std::string& extra) -> void; auto SetExtra2(const std::string& extra) -> void;
auto SetToken(const std::string& account_id, const std::string& token) auto SetToken(const std::string& account_id, const std::string& token)

View File

@ -432,7 +432,10 @@ auto Utils::GetRandomNameList() -> const std::list<std::string>& {
// Clion incorrectly thinks this might be null. // Clion incorrectly thinks this might be null.
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma ide diagnostic ignored "NullDereferences" #pragma ide diagnostic ignored "NullDereferences"
return *g_random_names_list; if (g_random_names_list != nullptr) {
return *g_random_names_list;
}
throw Exception("random name list uninited");
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }

View File

@ -325,7 +325,7 @@ void Camera::UpdatePosition() {
} }
// Now, for camera aiming purposes, add some of their velocity and // Now, for camera aiming purposes, add some of their velocity and
// clamp to bounds, taking their radius into account. if our AOI // clamp to the bounds, taking their radius into account. if our AOI
// sphere is bigger than a given dimension, center it; otherwise // sphere is bigger than a given dimension, center it; otherwise
// clamp to the box inset by our radius. // clamp to the box inset by our radius.
float x_clamped, y_clamped, z_clamped, x_mirrored_clamped; float x_clamped, y_clamped, z_clamped, x_mirrored_clamped;
@ -453,7 +453,7 @@ void Camera::UpdatePosition() {
SetTarget(position_.x + p.v[0], position_.y + p.v[1], SetTarget(position_.x + p.v[0], position_.y + p.v[1],
position_.z + p.v[2]); position_.z + p.v[2]);
// Now the same for cam up/down. // Now the same for camera up/down.
// Note: technically we should recalc angles since we just rotated, // Note: technically we should recalc angles since we just rotated,
// but this should be close enough. // but this should be close enough.
Vector3f p2(target_.x - position_.x, target_.y - position_.y, Vector3f p2(target_.x - position_.x, target_.y - position_.y,
@ -734,7 +734,7 @@ void Camera::Update(millisecs_t elapsed) {
// Update audio position more often in vr since we can whip our head around. // Update audio position more often in vr since we can whip our head around.
uint32_t interval = IsVRMode() ? 50 : 100; uint32_t interval = IsVRMode() ? 50 : 100;
// Every now and then, update microphone position for audio. // Occasionally, update microphone position for audio.
if (real_time - last_listener_update_time_ > interval) { if (real_time - last_listener_update_time_ > interval) {
last_listener_update_time_ = real_time; last_listener_update_time_ = real_time;
bool do_regular_update = true; bool do_regular_update = true;
@ -872,7 +872,7 @@ void Camera::DeleteAreaOfInterest(AreaOfInterest* a) {
void Camera::SetManual(bool enable) { void Camera::SetManual(bool enable) {
manual_ = enable; manual_ = enable;
if (manual_) { if (manual_) {
// Reset our target settings to our current smoothed ones // Reset our target settings to our current smoothed ones,
// so we don't see an instant jump to the target. // so we don't see an instant jump to the target.
target_.x = target_smoothed_.x; target_.x = target_smoothed_.x;
target_.y = target_smoothed_.y; target_.y = target_smoothed_.y;
@ -912,7 +912,7 @@ void Camera::ApplyToFrameDef(FrameDef* frame_def) {
nullptr nullptr
}; };
// Currently our x/y fovs are simply enough to fit everything. // Currently, our x/y fovs are simply enough to fit everything.
// Check the aspect ratio of what we're rendering to and fit them. // Check the aspect ratio of what we're rendering to and fit them.
// Add a few degrees just to keep things away from the edges a bit // Add a few degrees just to keep things away from the edges a bit
@ -972,7 +972,7 @@ void Camera::ApplyToFrameDef(FrameDef* frame_def) {
} }
// Also store original positions with the frame_def in case we want to muck // Also store original positions with the frame_def in case we want to muck
// with them later (VR, etc). // with them later (VR, etc.).
frame_def->set_cam_original(Vector3f(position_.x + extra_pos_2_.x, frame_def->set_cam_original(Vector3f(position_.x + extra_pos_2_.x,
position_.y + extra_pos_2_.y, position_.y + extra_pos_2_.y,
position_.z + extra_pos_2_.z)); position_.z + extra_pos_2_.z));

View File

@ -11,7 +11,7 @@
namespace ballistica { namespace ballistica {
// Hmm this shouldn't be here. // Hmm; this shouldn't be here.
const float kHappyThoughtsZPlane = -5.52f; const float kHappyThoughtsZPlane = -5.52f;
// Default horizontal camera field of view. // Default horizontal camera field of view.
@ -32,7 +32,7 @@ class Camera : public Object {
// Update the camera position values - done once per render // Update the camera position values - done once per render
void UpdatePosition(); void UpdatePosition();
// Update camera velocities/etc - done as often as possible. // Update camera velocities/etc. This is done as often as possible.
void Update(millisecs_t elapsed); void Update(millisecs_t elapsed);
void SetPosition(float x, float y, float z); void SetPosition(float x, float y, float z);
void SetTarget(float x, float y, float z); void SetTarget(float x, float y, float z);

View File

@ -13,7 +13,7 @@ ClientInputDevice::ClientInputDevice(int remote_device_id,
: remote_device_id_(remote_device_id), : remote_device_id_(remote_device_id),
connection_to_client_(connection_to_client) {} connection_to_client_(connection_to_client) {}
// Hmm do we need to send a remote-detach in this case? // Hmm; do we need to send a remote-detach in this case?
// I don't think so; if we're dying it means the connection is dying // I don't think so; if we're dying it means the connection is dying
// which means we probably couldn't communicate anyway and // which means we probably couldn't communicate anyway and
// the other end will free the input-device up // the other end will free the input-device up

View File

@ -548,6 +548,9 @@ static void Init() {
g_platform->GetUserPythonDirectory(); g_platform->GetUserPythonDirectory();
} }
#pragma clang diagnostic push
#pragma ide diagnostic ignored "NullDereferences"
static void HandleArgs(int argc, char** argv) { static void HandleArgs(int argc, char** argv) {
assert(!g_app_globals->args_handled); assert(!g_app_globals->args_handled);
g_app_globals->args_handled = true; g_app_globals->args_handled = true;
@ -558,6 +561,7 @@ static void HandleArgs(int argc, char** argv) {
fflush(stdout); fflush(stdout);
exit(0); exit(0);
} }
int dummyval{};
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
// In our rift build, a '-2d' arg causes us to run in regular 2d mode. // In our rift build, a '-2d' arg causes us to run in regular 2d mode.
if (g_buildconfig.rift_build() && !strcmp(argv[i], "-2d")) { if (g_buildconfig.rift_build() && !strcmp(argv[i], "-2d")) {
@ -571,7 +575,6 @@ static void HandleArgs(int argc, char** argv) {
exit(-1); exit(-1);
} }
} else if (!strcmp(argv[i], "--crash")) { } else if (!strcmp(argv[i], "--crash")) {
int dummyval{};
int* invalid_ptr{&dummyval}; int* invalid_ptr{&dummyval};
// A bit of obfuscation to try and keep linters quiet. // A bit of obfuscation to try and keep linters quiet.
@ -605,6 +608,7 @@ static void HandleArgs(int argc, char** argv) {
} }
} }
} }
#pragma clang diagnostic pop
// In Android's case we have to pull our exec arg from the java/kotlin layer. // In Android's case we have to pull our exec arg from the java/kotlin layer.
if (g_buildconfig.ostype_android()) { if (g_buildconfig.ostype_android()) {
@ -1129,7 +1133,7 @@ auto Platform::MacMusicAppPlayPlaylist(const std::string& playlist) -> bool {
} }
auto Platform::MacMusicAppGetPlaylists() -> std::list<std::string> { auto Platform::MacMusicAppGetPlaylists() -> std::list<std::string> {
Log("MacMusicAppGetPlaylists() unimplemented"); Log("MacMusicAppGetPlaylists() unimplemented");
return std::list<std::string>(); return {};
} }
void Platform::StartListeningForWiiRemotes() { void Platform::StartListeningForWiiRemotes() {

View File

@ -190,22 +190,21 @@ auto PythonClassNode::GetDelegate(PythonClassNode* self, PyObject* args,
PyObject* keywds) -> PyObject* { PyObject* keywds) -> PyObject* {
BA_PYTHON_TRY; BA_PYTHON_TRY;
static const char* kwlist[] = {"type", "doraise", nullptr}; static const char* kwlist[] = {"type", "doraise", nullptr};
PyObject* type_obj{}; PyObject* tp_obj{};
int doraise{}; int doraise{};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|p", if (!PyArg_ParseTupleAndKeywords(
const_cast<char**>(kwlist), &type_obj, args, keywds, "O|p", const_cast<char**>(kwlist), &tp_obj, &doraise)) {
&doraise)) {
return nullptr; return nullptr;
} }
Node* node = self->node_->get(); Node* node = self->node_->get();
if (!node) { if (!node) {
throw Exception(PyExcType::kNodeNotFound); throw Exception(PyExcType::kNodeNotFound);
} }
if (!PyType_Check(type_obj)) { if (!PyType_Check(tp_obj)) {
throw Exception("Passed type arg is not a type.", PyExcType::kType); throw Exception("Passed type arg is not a type.", PyExcType::kType);
} }
if (PyObject* obj = node->GetDelegate()) { if (PyObject* obj = node->GetDelegate()) {
int isinst = PyObject_IsInstance(obj, type_obj); int isinst = PyObject_IsInstance(obj, tp_obj);
if (isinst == -1) { if (isinst == -1) {
return nullptr; return nullptr;
} }
@ -216,7 +215,7 @@ auto PythonClassNode::GetDelegate(PythonClassNode* self, PyObject* args,
if (doraise) { if (doraise) {
throw Exception("Requested delegate type not found on '" throw Exception("Requested delegate type not found on '"
+ node->type()->name() + node->type()->name()
+ "' node. (type=" + Python::ObjToString(type_obj) + "' node. (type=" + Python::ObjToString(tp_obj)
+ ", delegate=" + Python::ObjToString(obj) + ")", + ", delegate=" + Python::ObjToString(obj) + ")",
PyExcType::kDelegateNotFound); PyExcType::kDelegateNotFound);
} }

View File

@ -118,7 +118,7 @@ auto AnimCurveNode::GetOut() -> float {
} }
} }
} else { } else {
// No keyframes?.. hmm just go with 0. // No keyframes?.. hmm, just go with 0.
if (keyframes_.empty()) { if (keyframes_.empty()) {
out_ = 0.0f; out_ = 0.0f;
} else { } else {

View File

@ -41,7 +41,7 @@ BombNode::BombNode(Scene* scene) : PropNode(scene, node_type) {}
void BombNode::OnCreate() { void BombNode::OnCreate() {
// We can't do this in our constructor because // We can't do this in our constructor because
// it would prevent the user from setting density/etc attrs. // it would prevent the user from setting density/etc. attrs.
// (user attrs get applied after constructors fire) // (user attrs get applied after constructors fire)
SetBody("sphere"); SetBody("sphere");
} }

View File

@ -9,7 +9,7 @@
namespace ballistica { namespace ballistica {
// An node used to combine individual input values into one array output value // A node used to combine individual input values into one array output value
class CombineNode : public Node { class CombineNode : public Node {
public: public:
static auto InitType() -> NodeType*; static auto InitType() -> NodeType*;

View File

@ -207,7 +207,7 @@ void ButtonWidget::Draw(RenderPass* pass, bool draw_transparent) {
float b = 0; float b = 0;
float t = b + height_; float t = b + height_;
// Use these to pick styles so style doesnt // Use these to pick styles so style doesn't
// change during mouse-over, etc. // change during mouse-over, etc.
float l_orig = l; float l_orig = l;
float r_orig = r; float r_orig = r;
@ -558,7 +558,7 @@ void ButtonWidget::DoActivate(bool isRepeat) {
return; return;
} }
// We dont want holding down a repeat-button to keep flashing it. // We don't want holding down a repeat-button to keep flashing it.
if (!isRepeat) { if (!isRepeat) {
last_activate_time_ = g_game->master_time(); last_activate_time_ = g_game->master_time();
} }
@ -573,8 +573,8 @@ void ButtonWidget::DoActivate(bool isRepeat) {
} }
} }
if (on_activate_call_.exists()) { if (on_activate_call_.exists()) {
// Call this in the next cycle (don't wanna risk mucking with UI from // Call this in the next cycle (don't want to risk mucking with UI from
// within a UI loop. // within a UI loop.)
g_game->PushPythonWeakCall( g_game->PushPythonWeakCall(
Object::WeakRef<PythonContextCall>(on_activate_call_)); Object::WeakRef<PythonContextCall>(on_activate_call_));
return; return;

View File

@ -135,7 +135,7 @@ class ButtonWidget : public Widget {
float tint2_color_green_{1.0f}; float tint2_color_green_{1.0f};
float tint2_color_blue_{1.0f}; float tint2_color_blue_{1.0f};
// Keep these at the bottom so they're torn down first. // Keep these at the bottom, so they're torn down first.
Object::Ref<TextWidget> text_; Object::Ref<TextWidget> text_;
Object::Ref<PythonContextCall> on_activate_call_; Object::Ref<PythonContextCall> on_activate_call_;
Object::Ref<RealTimer<ButtonWidget> > repeat_timer_; Object::Ref<RealTimer<ButtonWidget> > repeat_timer_;

View File

@ -243,8 +243,8 @@ void CheckBoxWidget::Activate() {
PythonRef args(Py_BuildValue("(O)", checked_ ? Py_True : Py_False), PythonRef args(Py_BuildValue("(O)", checked_ ? Py_True : Py_False),
PythonRef::kSteal); PythonRef::kSteal);
// Call this in the next cycle (don't wanna risk mucking with UI from within // Call this in the next cycle (don't want to risk mucking with UI from
// a UI loop) // within a UI loop)
g_game->PushPythonWeakCallArgs( g_game->PushPythonWeakCallArgs(
Object::WeakRef<PythonContextCall>(on_value_change_call_), args); Object::WeakRef<PythonContextCall>(on_value_change_call_), args);
} }

View File

@ -83,7 +83,7 @@ class CheckBoxWidget : public Widget {
bool pressed_{}; bool pressed_{};
bool is_radio_button_{}; bool is_radio_button_{};
// Keep these at the bottom so they're torn down first. // Keep these at the bottom, so they'll be torn down first.
Object::Ref<PythonContextCall> on_value_change_call_; Object::Ref<PythonContextCall> on_value_change_call_;
}; };

View File

@ -19,7 +19,7 @@ ColumnWidget::~ColumnWidget() = default;
auto ColumnWidget::HandleMessage(const WidgetMessage& m) -> bool { auto ColumnWidget::HandleMessage(const WidgetMessage& m) -> bool {
switch (m.type) { switch (m.type) {
case WidgetMessage::Type::kShow: { case WidgetMessage::Type::kShow: {
// Told to show something.. send this along to our parent (we can't do // Told to show something... send this along to our parent (we can't do
// anything). // anything).
Widget* w = parent_widget(); Widget* w = parent_widget();
if (w) { if (w) {

View File

@ -0,0 +1,34 @@
# Released under the MIT License. See LICENSE for details.
#
"""Testing message functionality."""
from __future__ import annotations
from typing import TYPE_CHECKING
# import pytest
from efro.message import MessageProtocol, MessageSender
if TYPE_CHECKING:
pass
def test_message_sending() -> None:
"""Test simple message sending."""
protocol = MessageProtocol(message_types={})
class TestClass:
"""Test."""
def _send_raw_message(self, data: bytes) -> bytes:
"""Test."""
print(f'WOULD SEND RAW MSG OF SIZE {len(data)}')
return b''
msg = MessageSender(protocol, _send_raw_message)
obj = TestClass()
print(f'MADE TEST OBJ {obj}')
obj.msg.send('foo')

View File

@ -56,6 +56,9 @@ class PrivateHostingConfig:
custom_team_colors: Optional[Tuple[Tuple[float, float, float], custom_team_colors: Optional[Tuple[Tuple[float, float, float],
Tuple[float, float, float]]] = None Tuple[float, float, float]]] = None
playlist: Optional[List[Dict[str, Any]]] = None playlist: Optional[List[Dict[str, Any]]] = None
exit_minutes: float = 120.0
exit_minutes_unclean: float = 180.0
exit_minutes_idle: float = 10.0
@ioprepped @ioprepped

View File

@ -13,8 +13,6 @@ from efro.error import CleanError
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import List from typing import List
PROJROOT = Path(__file__).resolve().parents[1]
def _parse_lprop_file(local_properties_path: str) -> str: def _parse_lprop_file(local_properties_path: str) -> str:
with open(local_properties_path) as infile: with open(local_properties_path) as infile:
@ -126,7 +124,7 @@ def run(projroot: str, args: List[str]) -> None:
# as external python builds still ask for this. So now we just pull it from # as external python builds still ask for this. So now we just pull it from
# the project gradle file where we set it explicitly. # the project gradle file where we set it explicitly.
if command == 'get-ndk-path': if command == 'get-ndk-path':
gradlepath = Path(PROJROOT, 'ballisticacore-android/build.gradle') gradlepath = Path(projroot, 'ballisticacore-android/build.gradle')
with gradlepath.open() as infile: with gradlepath.open() as infile:
lines = [ lines = [
l for l in infile.readlines() l for l in infile.readlines()

View File

@ -31,8 +31,8 @@ class PipRequirement:
# Note: we look directly for modules when possible instead of just pip # Note: we look directly for modules when possible instead of just pip
# entries; this accounts for manual installations or other nonstandard setups. # entries; this accounts for manual installations or other nonstandard setups.
PIP_REQUIREMENTS = [ PIP_REQUIREMENTS = [
PipRequirement(modulename='pylint', minversion=[2, 9, 1]), PipRequirement(modulename='pylint', minversion=[2, 9, 6]),
PipRequirement(modulename='mypy', minversion=[0, 902]), PipRequirement(modulename='mypy', minversion=[0, 910]),
PipRequirement(modulename='yapf', minversion=[0, 31, 0]), PipRequirement(modulename='yapf', minversion=[0, 31, 0]),
PipRequirement(modulename='cpplint', minversion=[1, 5, 5]), PipRequirement(modulename='cpplint', minversion=[1, 5, 5]),
PipRequirement(modulename='pytest', minversion=[6, 2, 4]), PipRequirement(modulename='pytest', minversion=[6, 2, 4]),
@ -293,31 +293,43 @@ def gen_fulltest_buildfile_android() -> None:
extras = SPARSE_TEST_BUILDS[dayoffset % len(SPARSE_TEST_BUILDS)] extras = SPARSE_TEST_BUILDS[dayoffset % len(SPARSE_TEST_BUILDS)]
extras = [e for e in extras if e.startswith('android.')] extras = [e for e in extras if e.startswith('android.')]
cspre = 'tools/cloudshell linbeast --env android --' cspre = 'tools/cloudshell linbeast --env android --'
# This is currently broken; turning off.
do_py_android = False
for extra in extras: for extra in extras:
if extra == 'android.pylibs.arm': if extra == 'android.pylibs.arm':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android arm') lines.append(f'{cspre} tools/pcommand'
f' python_build_android arm')
elif extra == 'android.pylibs.arm.debug': elif extra == 'android.pylibs.arm.debug':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android_debug arm') lines.append(f'{cspre} tools/pcommand'
f' python_build_android_debug arm')
elif extra == 'android.pylibs.arm64': elif extra == 'android.pylibs.arm64':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android arm64') lines.append(f'{cspre} tools/pcommand'
f' python_build_android arm64')
elif extra == 'android.pylibs.arm64.debug': elif extra == 'android.pylibs.arm64.debug':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android_debug arm64') lines.append(f'{cspre} tools/pcommand'
f' python_build_android_debug arm64')
elif extra == 'android.pylibs.x86': elif extra == 'android.pylibs.x86':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android x86') lines.append(f'{cspre} tools/pcommand'
f' python_build_android x86')
elif extra == 'android.pylibs.x86.debug': elif extra == 'android.pylibs.x86.debug':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android_debug x86') lines.append(f'{cspre} tools/pcommand'
f' python_build_android_debug x86')
elif extra == 'android.pylibs.x86_64': elif extra == 'android.pylibs.x86_64':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android x86_64') lines.append(f'{cspre} tools/pcommand'
f' python_build_android x86_64')
elif extra == 'android.pylibs.x86_64.debug': elif extra == 'android.pylibs.x86_64.debug':
lines.append(f'{cspre} tools/pcommand' if do_py_android:
f' python_build_android_debug x86_64') lines.append(f'{cspre} tools/pcommand'
f' python_build_android_debug x86_64')
elif extra == 'android.package': elif extra == 'android.package':
lines.append('make android-cloud-package') lines.append('make android-cloud-package')
else: else:

184
tools/efro/message.py Normal file
View File

@ -0,0 +1,184 @@
# Released under the MIT License. See LICENSE for details.
#
"""Functionality for sending and responding to messages.
Supports static typing for message types and possible return types.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Dict, Type, Tuple, List, Any, Callable, Optional
class MessageProtocol:
"""Wrangles a set of message types, formats, and response types.
Both endpoints must be using the same Protocol (even if one side
is newer) for communication to succeed.
"""
def __init__(
self,
message_types: Dict[int, Tuple[Type, List[Type]]],
type_key: str = '_t',
) -> None:
"""Create a protocol with the given settings.
Each entry for message_types should contain an ID, a message type,
and all possible response types.
"""
@classmethod
def create_sender_module(cls, classname: str) -> str:
""""Create a Python module defining a MessageSender subclass.
This class is primarily for type checking and will contain overrides
for the varieties of send calls for message/response types defined
in the protocol.
"""
@classmethod
def create_receiver_module(cls, classname: str) -> str:
""""Create a Python module defining a MessageReceiver subclass.
This class is primarily for type checking and will contain overrides
for the register method for message/response types defined in
the protocol.
"""
class TransportError(Exception):
"""Error occurring for all transport related errors in messaging.
This covers anything network-related going wrong in the sending
of data or receiving of the response. This error does not imply
that the message was not received on the other end; only that a
complete response round trip was not completed.
"""
class MessageSender:
"""Facilitates sending messages to a target and receiving responses.
This is instantiated at the class level and used to register unbound
class methods to handle raw message sending.
Example:
class MyClass:
def send_raw_message(self, message: bytes) -> bytes:
# Actually send the message here.
msg = MyMessageSender(some_protocol, send_raw_message)
# MyMessageSender class should provide overloads for send(), send_bg(),
# etc. to ensure all sending happens with valid types.
obj = MyClass()
obj.msg.send(SomeMessageType())
"""
def __init__(
self, protocol: MessageProtocol,
send_raw_message: Optional[Callable[[Any, bytes], bytes]]) -> None:
self._protocol = protocol
self._send_raw_message = send_raw_message
def __get__(self, obj: Any, type_in: Any = None) -> Any:
if obj is None:
raise RuntimeError('Must be called on an instance, not a type.')
print(f'HELLO FROM GET {obj}')
return self
def send(self, message: Any) -> Any:
"""Send a message and receive a response.
Will encode the message for transport and call dispatch_raw_message()
"""
if self._send_raw_message is None:
raise RuntimeError('Unimplemented!')
print(f'WOULD CONVERT MSG TO RAW: {message}')
return self._send_raw_message(None, b'')
def send_bg(self, message: Any) -> Any:
"""Send a message asynchronously and receive a future.
The message will be encoded for transport and passed to
dispatch_raw_message from a background thread.
"""
raise RuntimeError('Unimplemented!')
def send_async(self, message: Any) -> Any:
"""Send a message asynchronously using asyncio.
The message will be encoded for transport and passed to
dispatch_raw_message_async.
"""
raise RuntimeError('Unimplemented!')
# def send_raw_message(self, msg: bytes) -> bytes:
# """Send a message and get a response synchronously.
# Should be overridden by child classes if supported.
# Gets called by send() or in a bg thread by send_bg().
# """
# raise TransportError('Unimplemented for this dispatch type.')
# async def send_raw_message_async(self, msg: bytes) -> bytes:
# """Send a message and get a response via asyncio.
# Should be overridden by child classes if supported.
# """
# raise TransportError('Unimplemented for this dispatch type.')
class MessageReceiver:
"""Facilitates receiving & responding to messages from a remote source.
This is instantiated at the class level with unbound methods registered
as handlers for different message types in the protocol.
Example:
class MyClass:
receiver = MyMessageReceiver()
# MyMessageReceiver should provide overloads to register_handler()
# to ensure all registered handlers have valid types/return-types.
@receiver.register_handler
def handle_some_message_type(self, message: SomeType) -> AnotherType:
# Deal with this message type here.
# This will be passed along to the registered handler.
obj = MyClass()
obj.receiver.handle_raw_message(some_raw_data)
"""
def __init__(self, protocol: MessageProtocol) -> None:
pass
def register(self, call: Callable) -> None:
"""Register a call to handle a message type in the protocol."""
def handle_raw_message(self, msg: bytes) -> bytes:
"""Should be called when the receiver gets a message.
The return value is the raw response to the message.
"""
async def handle_raw_message_async(self, msg: bytes) -> bytes:
"""Should be called when the receiver gets a message.
The return value is the raw response to the message.
"""
# class SubTest(MessageSender):
# """Test."""
# if TYPE_CHECKING:
# @overload
# def send(self, message: str) -> str:
# pass
# @overload
# def send(self, message: bool) -> bool:
# pass
# def send(self, message: Any) -> Any:
# pass
# blah = SubTest(protocol=MessageProtocol(message_types={}))
# blah.send('foo')

View File

@ -10,7 +10,7 @@ from typing import TYPE_CHECKING
from efrotools import PYVER, run, readfile, writefile, replace_one from efrotools import PYVER, run, readfile, writefile, replace_one
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import List, Dict, Any from typing import List, Dict, Any, Optional
ENABLE_OPENSSL = True ENABLE_OPENSSL = True
PY38 = True PY38 = True
@ -96,7 +96,7 @@ def build_apple(arch: str, debug: bool = False) -> None:
'_codecs_jp cjkcodecs/_codecs_jp.c', '_codecs_jp cjkcodecs/_codecs_jp.c',
'_codecs_kr cjkcodecs/_codecs_kr.c', '_codecs_kr cjkcodecs/_codecs_kr.c',
'_codecs_tw cjkcodecs/_codecs_tw.c', '_codecs_tw cjkcodecs/_codecs_tw.c',
'_lsprof _lsprof.o rotatingtree.c', '_lsprof _lsprof.c rotatingtree.c',
'_multibytecodec cjkcodecs/multibytecodec.c', '_multibytecodec cjkcodecs/multibytecodec.c',
'_multiprocessing _multiprocessing/multiprocessing.c', '_multiprocessing _multiprocessing/multiprocessing.c',
'_opcode _opcode.c', '_opcode _opcode.c',
@ -309,11 +309,17 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
# Set these to particular releases to use those. # Set these to particular releases to use those.
# py_commit = '580fbb018fd0844806119614d752b41fc69660f9' # 3.8.5 # py_commit = '580fbb018fd0844806119614d752b41fc69660f9' # 3.8.5
py_commit = '6503f05dd59e26a9986bdea097b3da9b3546f45b' # 3.8.7 # py_commit = '6503f05dd59e26a9986bdea097b3da9b3546f45b' # 3.8.7
py_commit = 'c3ffbbdf3d5645ee07c22649f2028f9dffc762ba' # 3.8.11
# cpython-source-deps stuff started failing for OpenSSL on Jan 8 2021. # cpython-source-deps stuff started failing for OpenSSL on Jan 8 2021.
# Pinning it to an older one for now. # Pinning it to an older one for now.
py_ssl_commit = '7f34c3085feb4692bbbb6c8b19d053ebc5049dad' # From 6/12/20 if bool(False):
# From 6/12/20
py_ssl_commit: Optional[str] = (
'7f34c3085feb4692bbbb6c8b19d053ebc5049dad')
else:
py_ssl_commit = None
commit_lines = '' commit_lines = ''
if py_commit is not None: if py_commit is not None:
@ -322,11 +328,21 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
" run_in_dir(['git', 'checkout', '" + " run_in_dir(['git', 'checkout', '" +
py_commit + "'], self.source_dir)\n") py_commit + "'], self.source_dir)\n")
if py_ssl_commit is not None: if py_ssl_commit is not None:
commit_lines += (' if self.source_url == ' commit_lines += (f' if self.source_url == '
"'https://github.com/python/cpython-source-deps'" f"'https://github.com/python/cpython-source-deps'"
" and self.branch == 'openssl-1.1.1':\n" f" and self.branch == 'openssl-1.1.1':\n"
" run_in_dir(['git', 'checkout', '" + f" run_in_dir(['git', 'checkout', '"
py_ssl_commit + "'], self.source_dir)\n") f"{py_ssl_commit}'], self.source_dir)\n")
# Complaint about patch already being applied...
if bool(True):
ftxt = readfile('pybuild/packages/openssl.py')
ftxt = replace_one(
ftxt,
' LocalPatch(\'lld-issue32518\'),\n',
' # LocalPatch(\'lld-issue32518\'),\n',
)
writefile('pybuild/packages/openssl.py', ftxt)
ftxt = readfile('pybuild/source.py') ftxt = readfile('pybuild/source.py')