mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-31 11:46:58 +08:00
Merge branch 'efroemling:master' into master
This commit is contained in:
commit
3b7b1ea79c
42
.efrocachemap
generated
42
.efrocachemap
generated
@ -421,7 +421,7 @@
|
||||
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
|
||||
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
|
||||
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
|
||||
"build/assets/ba_data/data/langdata.json": "0d9f610cd2284cad4316cc2cb131a08b",
|
||||
"build/assets/ba_data/data/langdata.json": "8409781047f46ca6627eacdfc0b4d3d3",
|
||||
"build/assets/ba_data/data/languages/arabic.json": "2c2915e10124bb8f69206da9c608d57c",
|
||||
"build/assets/ba_data/data/languages/belarussian.json": "09954e550d13d3d9cb5a635a1d32a151",
|
||||
"build/assets/ba_data/data/languages/chinese.json": "bb51b5aa614830c561e8fe2542a9ab8a",
|
||||
@ -4061,26 +4061,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "88c4aa547dd4715a2e272f3738587b6d",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "f16453fcad766fec901df5b49c30f3c8",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b70afa60a1a41edab49b1aaa3a5c64bb",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "604ec018ae78313c48536ed729d27466",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "4902925ae1a5e1d985ce96071af3aade",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "d3d70106be65df66be7ac08a6b486e37",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "d086c930efa95aad560591f76188620e",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "55c591cc3150103361816404a6b39f93",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "3fc3fb6d92f28ac3a2cadf00e3a9a69b",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "403004d2b9a7a0a051e5943a8c1d423a",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "5de045f8c27357a3123f5e9f81a1019a",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "5dbea7c2327da665dd3ec3a99c81b3b2",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "89c5f534a3ebf919d3cf095f15abf2dd",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3b45bc9d1be09e8236a2b9f11331026e",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6e7174e340c82df192385b8a828a6dcd",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "5ddcb009ae84e70ef82dc13b4952f706",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fd35547e009f1f7237b057a1dc5ba043",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "6f68f2749227bc3c0774bc3e6b16d520",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "1073911522710591baa6d37fe0dbcb2c",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "a7986fae95855606844a9ad39bd0ec00",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "db921cf43e8ebf733712fb5bbc673f66",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "4be0f3a7a88da423847863af41ac9c63",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "7c92d738e7cc724de2ca31cb876224e6",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "c2f69ed83f77b602e2a2b2b1c1c78cc6",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b1c766d4ce567f965c53ff2a4c5c85f4",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "86ebbd9111f8a0fe7905cef7aba1f6db",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "8182f4e00ad579eb4c7be5ec1ddca8cb",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "3d9e0e7ad8706133e61fb7f7127c3ff5",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "20373ee90f8987bed980143d5377ae44",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "99d7d247a422eaa46737e3232408e879",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "079c4fd0b6f8aa50510064704466904b",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "216efc77915b75f39f0f15c2806bfbb9",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "204320756307e1833b284c3180e70319",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3e9e4e1761fd763eb584598fc0a3ad0a",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "b8f587f21f39f35072d6c83116c9ae96",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0c92e386ab7406da6a719131321bf592",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "ce48b60be52023e1942cb493bb2f58fb",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "d53ee4e8eed3e1a218db2f927a62c353",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "6597b00a07975230cb3f5b0fa19e0ed4",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "0ff41b8dc440c0490e9ae3bc22c3d201",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "56d6440f62c271c4ce9ef520400395a3",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d9865523059d8cf11b2bef4b9da9a8c9",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
### 1.7.33 (build 21777, api 8, 2024-03-13)
|
||||
### 1.7.33 (build 21778, api 8, 2024-03-13)
|
||||
- Stress test input-devices are now a bit smarter; they won't press any buttons
|
||||
while UIs are up (this could cause lots of chaos if it happened).
|
||||
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the
|
||||
@ -20,6 +20,8 @@
|
||||
languages; I feel it helps keep logic more understandable and should help us
|
||||
catch problems where a base class changes or removes a method and child
|
||||
classes forget to adapt to the change.
|
||||
- Respawn icons now have dotted steps showing decimal progress to assist
|
||||
players on calculating when they are gonna respawn. (Thanks 3alTemp!)
|
||||
- Replays now have rewind/fast-forward buttons!! (Thanks Dliwk, vishal332008!)
|
||||
- Custom spaz "curse_time" values now work properly. (Thanks Temp!)
|
||||
- Implemented `efro.dataclassio.IOMultiType` which will make my life a lot
|
||||
|
||||
@ -51,6 +51,10 @@
|
||||
### Rikko
|
||||
- Created the original "reject_recently_left_players" plugin
|
||||
|
||||
### SoK
|
||||
- Modder
|
||||
- BSE Heartbeat mechanic port
|
||||
|
||||
### Temp (3alTemp)
|
||||
- Original idea for customizable series length on GUI builds
|
||||
- Modder & Bug Fixer
|
||||
@ -59,5 +63,4 @@
|
||||
- Added support for joining using ipv6 address
|
||||
|
||||
### Loup Garou
|
||||
- Added sphinx documentation generation
|
||||
|
||||
- Added sphinx documentation generation
|
||||
@ -513,6 +513,7 @@
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/gamepadselect.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/graphics.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/keyboard.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/moddingtools.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/nettesting.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/plugins.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1lib/settings/__pycache__/pluginsettings.cpython-311.opt-1.pyc",
|
||||
@ -529,6 +530,7 @@
|
||||
"ba_data/python/bauiv1lib/settings/gamepadselect.py",
|
||||
"ba_data/python/bauiv1lib/settings/graphics.py",
|
||||
"ba_data/python/bauiv1lib/settings/keyboard.py",
|
||||
"ba_data/python/bauiv1lib/settings/moddingtools.py",
|
||||
"ba_data/python/bauiv1lib/settings/nettesting.py",
|
||||
"ba_data/python/bauiv1lib/settings/plugins.py",
|
||||
"ba_data/python/bauiv1lib/settings/pluginsettings.py",
|
||||
|
||||
@ -406,6 +406,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/gamepadselect.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/graphics.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/keyboard.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/moddingtools.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/nettesting.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/plugins.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/pluginsettings.py \
|
||||
@ -681,6 +682,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/gamepadselect.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/graphics.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/keyboard.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/moddingtools.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/nettesting.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/plugins.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1lib/settings/__pycache__/pluginsettings.cpython-311.opt-1.pyc \
|
||||
|
||||
@ -136,8 +136,11 @@ def create_user_system_scripts() -> None:
|
||||
path = f'{env.python_directory_user}/sys/{env.version}'
|
||||
pathtmp = path + '_tmp'
|
||||
if os.path.exists(path):
|
||||
print('Delete Existing User Scripts and try again.')
|
||||
_babase.screenmessage('Delete Existing User Scripts and try again.')
|
||||
print('Delete Existing User Scripts first!')
|
||||
_babase.screenmessage(
|
||||
'Delete Existing User Scripts first!',
|
||||
color=(1, 0, 0),
|
||||
)
|
||||
return
|
||||
if os.path.exists(pathtmp):
|
||||
shutil.rmtree(pathtmp)
|
||||
@ -161,7 +164,7 @@ def create_user_system_scripts() -> None:
|
||||
f"'\nRestart {_babase.appname()} to use them."
|
||||
f' (use babase.quit() to exit the game)'
|
||||
)
|
||||
_babase.screenmessage('Created User System Scripts')
|
||||
_babase.screenmessage('Created User System Scripts', color=(0, 1, 0))
|
||||
if app.classic is not None and app.classic.platform == 'android':
|
||||
print(
|
||||
'Note: the new files may not be visible via '
|
||||
@ -186,9 +189,14 @@ def delete_user_system_scripts() -> None:
|
||||
f'Restart {_babase.appname()} to use internal'
|
||||
f' scripts. (use babase.quit() to exit the game)'
|
||||
)
|
||||
_babase.screenmessage('Deleted User System Scripts')
|
||||
_babase.screenmessage('Deleted User System Scripts', color=(0, 1, 0))
|
||||
_babase.screenmessage(
|
||||
f'Restart {_babase.appname()} to take effect.',
|
||||
color=(0, 1, 0),
|
||||
)
|
||||
else:
|
||||
print(f"User system scripts not found at '{path}'.")
|
||||
_babase.screenmessage('User Scripts Not Found', color=(1, 0, 0))
|
||||
|
||||
# If the sys path is empty, kill it.
|
||||
dpath = env.python_directory_user + '/sys'
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21777
|
||||
TARGET_BALLISTICA_BUILD = 21778
|
||||
TARGET_BALLISTICA_VERSION = '1.7.33'
|
||||
|
||||
|
||||
|
||||
@ -22,7 +22,9 @@ class RespawnIcon:
|
||||
|
||||
def __init__(self, player: bs.Player, respawn_time: float):
|
||||
"""Instantiate with a Player and respawn_time (in seconds)."""
|
||||
# pylint: disable=too-many-locals
|
||||
self._visible = True
|
||||
self._dots_epic_only = False
|
||||
|
||||
on_right, offs_extra, respawn_icons = self._get_context(player)
|
||||
|
||||
@ -92,7 +94,7 @@ class RespawnIcon:
|
||||
assert self._name.node
|
||||
bs.animate(self._name.node, 'scale', {0: 0, 0.1: 0.5})
|
||||
|
||||
tpos = (-60 - h_offs if on_right else 60 + h_offs, -192 + offs)
|
||||
tpos = (-60 - h_offs if on_right else 60 + h_offs, -193 + offs)
|
||||
self._text: bs.NodeActor | None = bs.NodeActor(
|
||||
bs.newnode(
|
||||
'text',
|
||||
@ -109,11 +111,37 @@ class RespawnIcon:
|
||||
},
|
||||
)
|
||||
)
|
||||
dpos = [ipos[0] + (7 if on_right else -7), ipos[1] - 16]
|
||||
self._dec_text: bs.NodeActor | None = None
|
||||
if (
|
||||
self._dots_epic_only
|
||||
and bs.getactivity().globalsnode.slow_motion
|
||||
or not self._dots_epic_only
|
||||
):
|
||||
self._dec_text = bs.NodeActor(
|
||||
bs.newnode(
|
||||
'text',
|
||||
attrs={
|
||||
'position': dpos,
|
||||
'h_attach': 'right' if on_right else 'left',
|
||||
'h_align': 'right' if on_right else 'left',
|
||||
'scale': 0.65,
|
||||
'shadow': 0.5,
|
||||
'flatness': 0.5,
|
||||
'v_attach': 'top',
|
||||
'color': bs.safecolor(icon['tint_color']),
|
||||
'text': '',
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
assert self._text.node
|
||||
bs.animate(self._text.node, 'scale', {0: 0, 0.1: 0.9})
|
||||
if self._dec_text:
|
||||
bs.animate(self._dec_text.node, 'scale', {0: 0, 0.1: 0.65})
|
||||
|
||||
self._respawn_time = bs.time() + respawn_time
|
||||
self._dec_timer: bs.Timer | None = None
|
||||
self._update()
|
||||
self._timer: bs.Timer | None = bs.Timer(
|
||||
1.0, bs.WeakCall(self._update), repeat=True
|
||||
@ -128,7 +156,7 @@ class RespawnIcon:
|
||||
"""Return info on where we should be shown and stored."""
|
||||
activity = bs.getactivity()
|
||||
|
||||
if isinstance(bs.getsession(), bs.DualTeamSession):
|
||||
if isinstance(activity.session, bs.DualTeamSession):
|
||||
on_right = player.team.id % 2 == 1
|
||||
|
||||
# Store a list of icons in the team.
|
||||
@ -153,12 +181,43 @@ class RespawnIcon:
|
||||
offs_extra = -20
|
||||
return on_right, offs_extra, icons
|
||||
|
||||
def _dec_step(self, display: list) -> None:
|
||||
if not self._dec_text:
|
||||
self._dec_timer = None
|
||||
return
|
||||
old_text: bs.Lstr | str = self._dec_text.node.text
|
||||
iterate: int
|
||||
# Get the following display text using our current one.
|
||||
try:
|
||||
iterate = display.index(old_text) + 1
|
||||
# If we don't match any in the display list, we
|
||||
# can assume we've just started iterating.
|
||||
except ValueError:
|
||||
iterate = 0
|
||||
# Kill the timer if we're at the last iteration.
|
||||
if iterate >= len(display):
|
||||
self._dec_timer = None
|
||||
return
|
||||
self._dec_text.node.text = display[iterate]
|
||||
|
||||
def _update(self) -> None:
|
||||
remaining = int(round(self._respawn_time - bs.time()))
|
||||
|
||||
if remaining > 0:
|
||||
assert self._text is not None
|
||||
if self._text.node:
|
||||
self._text.node.text = str(remaining)
|
||||
if self._dec_text:
|
||||
# Display our decimal dots.
|
||||
self._dec_text.node.text = '...'
|
||||
# Start the timer to tick down.
|
||||
self._dec_timer = bs.Timer(
|
||||
0.25,
|
||||
bs.WeakCall(self._dec_step, ['..', '.', '']),
|
||||
repeat=True,
|
||||
)
|
||||
else:
|
||||
self._visible = False
|
||||
self._image = self._text = self._timer = self._name = None
|
||||
self._image = self._text = self._dec_text = self._timer = (
|
||||
self._name
|
||||
) = None
|
||||
|
||||
@ -776,7 +776,6 @@ class ChargerBotPro(ChargerBot):
|
||||
|
||||
color = PRO_BOT_COLOR
|
||||
highlight = PRO_BOT_HIGHLIGHT
|
||||
default_shields = True
|
||||
default_boxing_gloves = True
|
||||
points_mult = 3
|
||||
|
||||
|
||||
@ -190,6 +190,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
||||
self._lives_text: bs.NodeActor | None = None
|
||||
self._flawless = True
|
||||
self._time_bonus_timer: bs.Timer | None = None
|
||||
self._lives_hbtime: bs.Timer | None = None
|
||||
self._time_bonus_text: bs.NodeActor | None = None
|
||||
self._time_bonus_mult: float | None = None
|
||||
self._wave_text: bs.NodeActor | None = None
|
||||
@ -551,6 +552,20 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
||||
if self._lives == 0:
|
||||
self._bots.stop_moving()
|
||||
self.continue_or_end_game()
|
||||
|
||||
# Heartbeat behavior
|
||||
if self._lives < 5:
|
||||
hbtime = 0.39 + (0.21 * self._lives)
|
||||
self._lives_hbtime = bs.Timer(
|
||||
hbtime,
|
||||
lambda: self.heart_dyin(True, hbtime),
|
||||
repeat=True
|
||||
)
|
||||
self.heart_dyin(True)
|
||||
else:
|
||||
self._lives_hbtime = None
|
||||
self.heart_dyin(False)
|
||||
|
||||
assert self._lives_text is not None
|
||||
assert self._lives_text.node
|
||||
self._lives_text.node.text = str(self._lives)
|
||||
@ -1392,3 +1407,31 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
||||
|
||||
def _set_can_end_wave(self) -> None:
|
||||
self._can_end_wave = True
|
||||
|
||||
def heart_dyin(self,
|
||||
status: bool,
|
||||
time: float = 1.22) -> None:
|
||||
""" Makes the UI heart beat at low health. """
|
||||
assert self._lives_bg is not None
|
||||
if self._lives_bg.node.exists():
|
||||
return
|
||||
heart = self._lives_bg.node
|
||||
|
||||
# Make the heart beat intensely!
|
||||
if status:
|
||||
bs.animate_array(heart, 'scale', 2, {
|
||||
0:(90,90),
|
||||
time*0.1:(105,105),
|
||||
time*0.21:(88,88),
|
||||
time*0.42:(90,90),
|
||||
time*0.52:(105,105),
|
||||
time*0.63:(88,88),
|
||||
time:(90,90),
|
||||
})
|
||||
|
||||
# Neutralize heartbeat (Done did when dead.)
|
||||
else:
|
||||
bs.animate_array(heart, 'scale', 2, {
|
||||
0.0: list(heart.scale),
|
||||
time: (90,90),
|
||||
})
|
||||
|
||||
@ -43,7 +43,10 @@ class UIV1Subsystem(babase.AppSubsystem):
|
||||
|
||||
self._uiscale: babase.UIScale
|
||||
|
||||
interfacetype = env['ui_scale']
|
||||
interfacetype = babase.app.config.get('UI Scale', env['ui_scale'])
|
||||
if interfacetype == 'auto':
|
||||
interfacetype = env['ui_scale']
|
||||
|
||||
if interfacetype == 'large':
|
||||
self._uiscale = babase.UIScale.LARGE
|
||||
elif interfacetype == 'medium':
|
||||
|
||||
@ -454,7 +454,7 @@ class MainMenuWindow(bui.Window):
|
||||
resource='watchWindow.playbackSpeedText',
|
||||
subs=[('${SPEED}', str(1.23))],
|
||||
),
|
||||
position=(h, v + v_offs + 7 * t_scale),
|
||||
position=(h, v + v_offs + 15 * t_scale),
|
||||
h_align='center',
|
||||
v_align='center',
|
||||
size=(0, 0),
|
||||
@ -543,7 +543,8 @@ class MainMenuWindow(bui.Window):
|
||||
bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
draw_controller=btn,
|
||||
text='<<',
|
||||
# text='<<',
|
||||
text=bui.charstr(bui.SpecialChar.REWIND_BUTTON),
|
||||
position=(
|
||||
h - b_size - b_buffer_1 * 2,
|
||||
v - b_size * 0.5 - b_buffer_2 + 5 * t_scale + v_offs,
|
||||
@ -568,7 +569,8 @@ class MainMenuWindow(bui.Window):
|
||||
bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
draw_controller=btn,
|
||||
text='>>',
|
||||
# text='>>',
|
||||
text=bui.charstr(bui.SpecialChar.FAST_FORWARD_BUTTON),
|
||||
position=(
|
||||
h + b_size + b_buffer_1 * 2,
|
||||
v - b_size * 0.5 - b_buffer_2 + 5 * t_scale + v_offs,
|
||||
@ -1454,8 +1456,9 @@ class MainMenuWindow(bui.Window):
|
||||
def _resume(self) -> None:
|
||||
assert bui.app.classic is not None
|
||||
bui.app.classic.resume()
|
||||
if self._root_widget:
|
||||
bui.containerwidget(edit=self._root_widget, transition='out_right')
|
||||
# if self._root_widget:
|
||||
# bui.containerwidget(edit=self._root_widget,
|
||||
# transition='out_right')
|
||||
bui.app.ui_v1.clear_main_menu_window(transition='out_right')
|
||||
|
||||
# If there's callbacks waiting for this window to go away, call them.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""UI functionality for advanced settings."""
|
||||
# pylint: disable=too-many-lines
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@ -108,6 +109,7 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
if self._do_net_test_button:
|
||||
self._sub_height += self._extra_button_spacing
|
||||
self._sub_height += self._spacing * 2.0 # plugins
|
||||
self._sub_height += self._spacing * 2.0 # modding tools
|
||||
|
||||
self._r = 'settingsWindowAdvanced'
|
||||
|
||||
@ -192,6 +194,7 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
from bauiv1lib import promocode as _unused7
|
||||
from bauiv1lib import debug as _unused8
|
||||
from bauiv1lib.settings import plugins as _unused9
|
||||
from bauiv1lib.settings import moddingtools as _unused10
|
||||
|
||||
def _update_lang_status(self) -> None:
|
||||
if self._complete_langs_list is not None:
|
||||
@ -579,6 +582,19 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
bui.open_url, 'https://ballistica.net/wiki/modding-guide'
|
||||
),
|
||||
)
|
||||
|
||||
v -= self._spacing * 2.0
|
||||
|
||||
self._modding_tools_button = bui.buttonwidget(
|
||||
parent=self._subcontainer,
|
||||
position=(self._sub_width / 2 - this_button_width / 2, v - 10),
|
||||
size=(this_button_width, 60),
|
||||
autoselect=True,
|
||||
label=bui.Lstr(resource=f'{self._r}.moddingToolsText'),
|
||||
text_scale=1.0,
|
||||
on_activate_call=self._on_modding_tools_button_press,
|
||||
)
|
||||
|
||||
if self._show_always_use_internal_keyboard:
|
||||
assert self._always_use_internal_keyboard_check_box is not None
|
||||
bui.widget(
|
||||
@ -767,6 +783,24 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
from_window=self._root_widget,
|
||||
)
|
||||
|
||||
def _on_modding_tools_button_press(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.settings.moddingtools import ModdingToolsWindow
|
||||
|
||||
# no-op if our underlying widget is dead or on its way out.
|
||||
if not self._root_widget or self._root_widget.transitioning_out:
|
||||
return
|
||||
|
||||
self._save_state()
|
||||
bui.containerwidget(edit=self._root_widget, transition='out_left')
|
||||
assert bui.app.classic is not None
|
||||
bui.app.ui_v1.set_main_menu_window(
|
||||
ModdingToolsWindow(
|
||||
origin_widget=self._modding_tools_button
|
||||
).get_root_widget(),
|
||||
from_window=self._root_widget,
|
||||
)
|
||||
|
||||
def _on_promo_code_press(self) -> None:
|
||||
from bauiv1lib.promocode import PromoCodeWindow
|
||||
from bauiv1lib.account import show_sign_in_prompt
|
||||
@ -810,6 +844,7 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
|
||||
def _save_state(self) -> None:
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-statements
|
||||
try:
|
||||
sel = self._root_widget.get_selected_child()
|
||||
if sel == self._scrollwidget:
|
||||
@ -852,6 +887,8 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
sel_name = 'ShowUserMods'
|
||||
elif sel == self._plugins_button:
|
||||
sel_name = 'Plugins'
|
||||
elif sel == self._modding_tools_button:
|
||||
sel_name = 'ModdingTools'
|
||||
elif sel == self._modding_guide_button:
|
||||
sel_name = 'ModdingGuide'
|
||||
elif sel == self._language_inform_checkbox:
|
||||
@ -919,6 +956,8 @@ class AdvancedSettingsWindow(bui.Window):
|
||||
sel = self._show_user_mods_button
|
||||
elif sel_name == 'Plugins':
|
||||
sel = self._plugins_button
|
||||
elif sel_name == 'ModdingTools':
|
||||
sel = self._modding_tools_button
|
||||
elif sel_name == 'ModdingGuide':
|
||||
sel = self._modding_guide_button
|
||||
elif sel_name == 'LangInform':
|
||||
|
||||
207
src/assets/ba_data/python/bauiv1lib/settings/moddingtools.py
Normal file
207
src/assets/ba_data/python/bauiv1lib/settings/moddingtools.py
Normal file
@ -0,0 +1,207 @@
|
||||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""UI functionality for Modding Tools."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import babase
|
||||
import bauiv1 as bui
|
||||
from bauiv1lib.popup import PopupMenu
|
||||
from bauiv1lib.confirm import ConfirmWindow
|
||||
|
||||
|
||||
class ModdingToolsWindow(bui.Window):
|
||||
"""Window for accessing modding tools."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
transition: str = 'in_right',
|
||||
origin_widget: bui.Widget | None = None,
|
||||
):
|
||||
|
||||
app = bui.app
|
||||
assert app.classic is not None
|
||||
|
||||
# If they provided an origin-widget, scale up from that.
|
||||
scale_origin: tuple[float, float] | None
|
||||
if origin_widget is not None:
|
||||
self._transition_out = 'out_scale'
|
||||
scale_origin = origin_widget.get_screen_space_center()
|
||||
transition = 'in_scale'
|
||||
else:
|
||||
self._transition_out = 'out_right'
|
||||
scale_origin = None
|
||||
|
||||
uiscale = app.ui_v1.uiscale
|
||||
self._width = 970.0 if uiscale is bui.UIScale.SMALL else 670.0
|
||||
x_inset = 150 if uiscale is bui.UIScale.SMALL else 0
|
||||
self._height = (
|
||||
390.0
|
||||
if uiscale is bui.UIScale.SMALL
|
||||
else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0
|
||||
)
|
||||
|
||||
self._spacing = 32
|
||||
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
|
||||
|
||||
self._scroll_width = self._width - (100 + 2 * x_inset)
|
||||
self._scroll_height = self._height - 115.0
|
||||
self._sub_width = self._scroll_width * 0.95
|
||||
self._sub_height = 100.0
|
||||
|
||||
super().__init__(
|
||||
root_widget=bui.containerwidget(
|
||||
size=(self._width, self._height + top_extra),
|
||||
transition=transition,
|
||||
toolbar_visibility='menu_minimal',
|
||||
scale_origin_stack_offset=scale_origin,
|
||||
scale=(
|
||||
2.06
|
||||
if uiscale is bui.UIScale.SMALL
|
||||
else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0
|
||||
),
|
||||
stack_offset=(
|
||||
(0, -25) if uiscale is bui.UIScale.SMALL else (0, 0)
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
self._r = 'settingsModdingTools'
|
||||
|
||||
if app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
|
||||
bui.containerwidget(
|
||||
edit=self._root_widget, on_cancel_call=self._do_back
|
||||
)
|
||||
self._back_button = None
|
||||
else:
|
||||
self._back_button = bui.buttonwidget(
|
||||
parent=self._root_widget,
|
||||
position=(53 + x_inset, self._height - 60),
|
||||
size=(140, 60),
|
||||
scale=0.8,
|
||||
autoselect=True,
|
||||
label=bui.Lstr(resource='backText'),
|
||||
button_type='back',
|
||||
on_activate_call=self._do_back,
|
||||
)
|
||||
bui.containerwidget(
|
||||
edit=self._root_widget, cancel_button=self._back_button
|
||||
)
|
||||
|
||||
self._title_text = bui.textwidget(
|
||||
parent=self._root_widget,
|
||||
position=(0, self._height - 52),
|
||||
size=(self._width, 25),
|
||||
text=bui.Lstr(resource='moddingToolsTitleText'),
|
||||
color=app.ui_v1.title_color,
|
||||
h_align='center',
|
||||
v_align='top',
|
||||
)
|
||||
|
||||
if self._back_button is not None:
|
||||
bui.buttonwidget(
|
||||
edit=self._back_button,
|
||||
button_type='backSmall',
|
||||
size=(60, 60),
|
||||
label=bui.charstr(bui.SpecialChar.BACK),
|
||||
)
|
||||
|
||||
self._scrollwidget = bui.scrollwidget(
|
||||
parent=self._root_widget,
|
||||
position=(50 + x_inset, 50),
|
||||
simple_culling_v=20.0,
|
||||
highlight=False,
|
||||
size=(self._scroll_width, self._scroll_height),
|
||||
selection_loops_to_parent=True,
|
||||
)
|
||||
bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget)
|
||||
self._subcontainer = bui.containerwidget(
|
||||
parent=self._scrollwidget,
|
||||
size=(self._sub_width, self._sub_height),
|
||||
background=False,
|
||||
selection_loops_to_parent=True,
|
||||
)
|
||||
|
||||
v = self._sub_height - 35
|
||||
this_button_width = 410
|
||||
|
||||
v -= self._spacing * 1.2
|
||||
self._create_user_system_scripts_button = bui.buttonwidget(
|
||||
parent=self._subcontainer,
|
||||
position=(self._sub_width / 2 - this_button_width / 2, v - 10),
|
||||
size=(this_button_width, 60),
|
||||
autoselect=True,
|
||||
label=bui.Lstr(resource='createUserSystemScriptsText'),
|
||||
text_scale=1.0,
|
||||
on_activate_call=babase.modutils.create_user_system_scripts,
|
||||
)
|
||||
|
||||
v -= self._spacing * 2.5
|
||||
self._delete_user_system_scripts_button = bui.buttonwidget(
|
||||
parent=self._subcontainer,
|
||||
position=(self._sub_width / 2 - this_button_width / 2, v - 10),
|
||||
size=(this_button_width, 60),
|
||||
autoselect=True,
|
||||
label=bui.Lstr(resource='deleteUserSystemScriptsText'),
|
||||
text_scale=1.0,
|
||||
on_activate_call=lambda: ConfirmWindow(
|
||||
action=babase.modutils.delete_user_system_scripts,
|
||||
),
|
||||
)
|
||||
|
||||
v -= self._spacing * 2.5
|
||||
bui.textwidget(
|
||||
parent=self._subcontainer,
|
||||
position=(170, v + 10),
|
||||
size=(0, 0),
|
||||
text=bui.Lstr(value='UI SIZE :'),
|
||||
color=app.ui_v1.title_color,
|
||||
h_align='center',
|
||||
v_align='center',
|
||||
)
|
||||
|
||||
PopupMenu(
|
||||
parent=self._subcontainer,
|
||||
position=(230, v - 20),
|
||||
button_size=(200.0, 60.0),
|
||||
choices=[
|
||||
'auto',
|
||||
'small',
|
||||
'medium',
|
||||
'large',
|
||||
],
|
||||
choices_display=[
|
||||
bui.Lstr(resource='autoText'),
|
||||
bui.Lstr(resource='smallText'),
|
||||
bui.Lstr(resource='mediumText'),
|
||||
bui.Lstr(resource='largeText'),
|
||||
],
|
||||
current_choice=app.config.get('UI Scale', 'auto'),
|
||||
on_value_change_call=self._set_uiscale,
|
||||
)
|
||||
|
||||
def _set_uiscale(self, val: str) -> None:
|
||||
cfg = bui.app.config
|
||||
cfg['UI Scale'] = val
|
||||
cfg.apply_and_commit()
|
||||
if bui.app.ui_v1.uiscale.name != val.upper():
|
||||
bui.screenmessage(
|
||||
bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'),
|
||||
color=(1.0, 0.5, 0.0),
|
||||
)
|
||||
|
||||
def _do_back(self) -> None:
|
||||
from bauiv1lib.settings.advanced import AdvancedSettingsWindow
|
||||
|
||||
# no-op if our underlying widget is dead or on its way out.
|
||||
if not self._root_widget or self._root_widget.transitioning_out:
|
||||
return
|
||||
|
||||
bui.containerwidget(
|
||||
edit=self._root_widget, transition=self._transition_out
|
||||
)
|
||||
assert bui.app.classic is not None
|
||||
bui.app.ui_v1.set_main_menu_window(
|
||||
AdvancedSettingsWindow(transition='in_left').get_root_widget(),
|
||||
from_window=self._root_widget,
|
||||
)
|
||||
@ -47,6 +47,12 @@ TextGraphics::TextGraphics() {
|
||||
g.pen_offset_y -= 0.1f;
|
||||
}
|
||||
|
||||
// Bring Fast Forward & Rewind down and to the left a bit.
|
||||
if (index == 13 || index == 15) {
|
||||
g.pen_offset_y -= 0.055;
|
||||
g.pen_offset_x -= 0.01;
|
||||
}
|
||||
|
||||
// Shrink account logos and move them up a bit.
|
||||
if (index == 29 || index == 32 || index == 33 || index == 38
|
||||
|| index == 40 || index == 48 || index == 49) {
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21777;
|
||||
const int kEngineBuildNumber = 21778;
|
||||
const char* kEngineVersion = "1.7.33";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user