mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-11-07 17:36:15 +00:00
syncing changes from ballistica/master
This commit is contained in:
parent
2a07c0c840
commit
8913080562
227 changed files with 15756 additions and 12772 deletions
376
dist/ba_data/python/bascenev1lib/mainmenu.py
vendored
376
dist/ba_data/python/bascenev1lib/mainmenu.py
vendored
|
|
@ -1,7 +1,6 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Session and Activity for displaying the main menu bg."""
|
||||
# pylint: disable=too-many-lines
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -16,6 +15,8 @@ import bauiv1 as bui
|
|||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
import bacommon.bs
|
||||
|
||||
|
||||
class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
||||
"""Activity showing the rotating main menu bg stuff."""
|
||||
|
|
@ -43,55 +44,23 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
self._update_timer: bs.Timer | None = None
|
||||
self._news: NewsDisplay | None = None
|
||||
self._attract_mode_timer: bs.Timer | None = None
|
||||
self._logo_rotate_timer: bs.Timer | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
# pylint: disable=too-many-branches
|
||||
super().on_transition_in()
|
||||
random.seed(123)
|
||||
app = bs.app
|
||||
env = app.env
|
||||
assert app.classic is not None
|
||||
|
||||
plus = bui.app.plus
|
||||
plus = bs.app.plus
|
||||
assert plus is not None
|
||||
|
||||
# FIXME: We shouldn't be doing things conditionally based on whether
|
||||
# the host is VR mode or not (clients may differ in that regard).
|
||||
# Any differences need to happen at the engine level so everyone
|
||||
# sees things in their own optimal way.
|
||||
vr_mode = bs.app.env.vr
|
||||
|
||||
if not bs.app.ui_v1.use_toolbars:
|
||||
color = (1.0, 1.0, 1.0, 1.0) if vr_mode else (0.5, 0.6, 0.5, 0.6)
|
||||
|
||||
# FIXME: Need a node attr for vr-specific-scale.
|
||||
scale = (
|
||||
0.9
|
||||
if (app.ui_v1.uiscale is bs.UIScale.SMALL or vr_mode)
|
||||
else 0.7
|
||||
)
|
||||
self.my_name = bs.NodeActor(
|
||||
bs.newnode(
|
||||
'text',
|
||||
attrs={
|
||||
'v_attach': 'bottom',
|
||||
'h_align': 'center',
|
||||
'color': color,
|
||||
'flatness': 1.0,
|
||||
'shadow': 1.0 if vr_mode else 0.5,
|
||||
'scale': scale,
|
||||
'position': (0, 10),
|
||||
'vr_depth': -10,
|
||||
'text': '\xa9 2011-2024 Eric Froemling',
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Throw up some text that only clients can see so they know that the
|
||||
# host is navigating menus while they're just staring at an
|
||||
# Throw up some text that only clients can see so they know that
|
||||
# the host is navigating menus while they're just staring at an
|
||||
# empty-ish screen.
|
||||
tval = bs.Lstr(
|
||||
resource='hostIsNavigatingMenusText',
|
||||
|
|
@ -109,73 +78,16 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
},
|
||||
)
|
||||
)
|
||||
if not app.classic.main_menu_did_initial_transition and hasattr(
|
||||
self, 'my_name'
|
||||
if (
|
||||
not app.classic.main_menu_did_initial_transition
|
||||
and self.my_name is not None
|
||||
):
|
||||
assert self.my_name is not None
|
||||
assert self.my_name.node
|
||||
bs.animate(self.my_name.node, 'opacity', {2.3: 0, 3.0: 1.0})
|
||||
|
||||
# FIXME: We shouldn't be doing things conditionally based on whether
|
||||
# the host is vr mode or not (clients may not be or vice versa).
|
||||
# Any differences need to happen at the engine level so everyone sees
|
||||
# things in their own optimal way.
|
||||
vr_mode = app.env.vr
|
||||
uiscale = app.ui_v1.uiscale
|
||||
|
||||
# In cases where we're doing lots of dev work lets always show the
|
||||
# build number.
|
||||
force_show_build_number = False
|
||||
|
||||
if not bs.app.ui_v1.use_toolbars:
|
||||
if env.debug or env.test or force_show_build_number:
|
||||
if env.debug:
|
||||
text = bs.Lstr(
|
||||
value='${V} (${B}) (${D})',
|
||||
subs=[
|
||||
('${V}', app.env.engine_version),
|
||||
('${B}', str(app.env.engine_build_number)),
|
||||
('${D}', bs.Lstr(resource='debugText')),
|
||||
],
|
||||
)
|
||||
else:
|
||||
text = bs.Lstr(
|
||||
value='${V} (${B})',
|
||||
subs=[
|
||||
('${V}', app.env.engine_version),
|
||||
('${B}', str(app.env.engine_build_number)),
|
||||
],
|
||||
)
|
||||
else:
|
||||
text = bs.Lstr(
|
||||
value='${V}', subs=[('${V}', app.env.engine_version)]
|
||||
)
|
||||
scale = 0.9 if (uiscale is bs.UIScale.SMALL or vr_mode) else 0.7
|
||||
color = (1, 1, 1, 1) if vr_mode else (0.5, 0.6, 0.5, 0.7)
|
||||
self.version = bs.NodeActor(
|
||||
bs.newnode(
|
||||
'text',
|
||||
attrs={
|
||||
'v_attach': 'bottom',
|
||||
'h_attach': 'right',
|
||||
'h_align': 'right',
|
||||
'flatness': 1.0,
|
||||
'vr_depth': -10,
|
||||
'shadow': 1.0 if vr_mode else 0.5,
|
||||
'color': color,
|
||||
'scale': scale,
|
||||
'position': (-260, 10) if vr_mode else (-10, 10),
|
||||
'text': text,
|
||||
},
|
||||
)
|
||||
)
|
||||
if not app.classic.main_menu_did_initial_transition:
|
||||
assert self.version.node
|
||||
bs.animate(self.version.node, 'opacity', {2.3: 0, 3.0: 1.0})
|
||||
|
||||
# Throw in test build info.
|
||||
self.beta_info = self.beta_info_2 = None
|
||||
if env.test and not (env.demo or env.arcade):
|
||||
if env.test:
|
||||
pos = (230, 35)
|
||||
self.beta_info = bs.NodeActor(
|
||||
bs.newnode(
|
||||
|
|
@ -292,125 +204,20 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
self._update()
|
||||
|
||||
# Hopefully this won't hitch but lets space these out anyway.
|
||||
bui.add_clean_frame_callback(bs.WeakCall(self._start_preloads))
|
||||
bs.add_clean_frame_callback(bs.WeakCall(self._start_preloads))
|
||||
|
||||
random.seed()
|
||||
|
||||
if not (env.demo or env.arcade) and not app.ui_v1.use_toolbars:
|
||||
self._news = NewsDisplay(self)
|
||||
# Need to update this for toolbar mode; currenly doesn't fit.
|
||||
if bool(False):
|
||||
if not (env.demo or env.arcade):
|
||||
self._news = NewsDisplay(self)
|
||||
|
||||
self._attract_mode_timer = bs.Timer(
|
||||
3.12, self._update_attract_mode, repeat=True
|
||||
)
|
||||
|
||||
# Bring up the last place we were, or start at the main menu otherwise.
|
||||
with bs.ContextRef.empty():
|
||||
from bauiv1lib import specialoffer
|
||||
|
||||
assert bs.app.classic is not None
|
||||
if bui.app.env.headless:
|
||||
# UI stuff fails now in headless builds; avoid it.
|
||||
pass
|
||||
elif bool(False):
|
||||
uicontroller = bs.app.ui_v1.controller
|
||||
assert uicontroller is not None
|
||||
uicontroller.show_main_menu()
|
||||
else:
|
||||
main_menu_location = bs.app.ui_v1.get_main_menu_location()
|
||||
|
||||
# When coming back from a kiosk-mode game, jump to
|
||||
# the kiosk start screen.
|
||||
if env.demo or env.arcade:
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.kiosk import KioskWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
KioskWindow().get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
# ..or in normal cases go back to the main menu
|
||||
else:
|
||||
if main_menu_location == 'Gather':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.gather import GatherWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
GatherWindow(transition=None).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
elif main_menu_location == 'Watch':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.watch import WatchWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
WatchWindow(transition=None).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
elif main_menu_location == 'Team Game Select':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.playlist.browser import (
|
||||
PlaylistBrowserWindow,
|
||||
)
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
PlaylistBrowserWindow(
|
||||
sessiontype=bs.DualTeamSession, transition=None
|
||||
).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
elif main_menu_location == 'Free-for-All Game Select':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.playlist.browser import (
|
||||
PlaylistBrowserWindow,
|
||||
)
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
PlaylistBrowserWindow(
|
||||
sessiontype=bs.FreeForAllSession,
|
||||
transition=None,
|
||||
).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
elif main_menu_location == 'Coop Select':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.coop.browser import CoopBrowserWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
CoopBrowserWindow(
|
||||
transition=None
|
||||
).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
elif main_menu_location == 'Benchmarks & Stress Tests':
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.debug import DebugWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
DebugWindow(transition=None).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
else:
|
||||
# pylint: disable=cyclic-import
|
||||
from bauiv1lib.mainmenu import MainMenuWindow
|
||||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
MainMenuWindow(transition=None).get_root_widget(),
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
|
||||
# attempt to show any pending offers immediately.
|
||||
# If that doesn't work, try again in a few seconds
|
||||
# (we may not have heard back from the server)
|
||||
# ..if that doesn't work they'll just have to wait
|
||||
# until the next opportunity.
|
||||
if not specialoffer.show_offer():
|
||||
|
||||
def try_again() -> None:
|
||||
if not specialoffer.show_offer():
|
||||
# Try one last time..
|
||||
bui.apptimer(2.0, specialoffer.show_offer)
|
||||
|
||||
bui.apptimer(2.0, try_again)
|
||||
app.classic.invoke_main_menu_ui()
|
||||
|
||||
app.classic.main_menu_did_initial_transition = True
|
||||
|
||||
|
|
@ -445,7 +252,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
y = 20
|
||||
base_scale = 1.1
|
||||
self._word_actors = []
|
||||
base_delay = 1.0
|
||||
base_delay = 0.8
|
||||
delay = base_delay
|
||||
delay_inc = 0.02
|
||||
|
||||
|
|
@ -628,6 +435,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
word: str,
|
||||
x: float,
|
||||
y: float,
|
||||
*,
|
||||
scale: float = 1.0,
|
||||
delay: float = 0.0,
|
||||
vr_depth_offset: float = 0.0,
|
||||
|
|
@ -676,9 +484,8 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
)
|
||||
self._word_actors.append(word_obj)
|
||||
|
||||
# Add a bit of stop-motion-y jitter to the logo
|
||||
# (unless we're in VR mode in which case its best to
|
||||
# leave things still).
|
||||
# Add a bit of stop-motion-y jitter to the logo (unless we're in
|
||||
# VR mode in which case its best to leave things still).
|
||||
if not bs.app.env.vr:
|
||||
cmb: bs.Node | None
|
||||
cmb2: bs.Node | None
|
||||
|
|
@ -757,13 +564,13 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
y: float,
|
||||
scale: float,
|
||||
delay: float,
|
||||
*,
|
||||
custom_texture: str | None = None,
|
||||
jitter_scale: float = 1.0,
|
||||
rotate: float = 0.0,
|
||||
vr_depth_offset: float = 0.0,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
# Temp easter goodness.
|
||||
if custom_texture is None:
|
||||
custom_texture = self._get_custom_logo_tex_name()
|
||||
self._custom_logo_tex_name = custom_texture
|
||||
|
|
@ -776,60 +583,92 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
if custom_texture is not None
|
||||
else bs.getmesh('logoTransparent')
|
||||
)
|
||||
logo = bs.NodeActor(
|
||||
bs.newnode(
|
||||
'image',
|
||||
attrs={
|
||||
'texture': ltex,
|
||||
'mesh_opaque': mopaque,
|
||||
'mesh_transparent': mtrans,
|
||||
'vr_depth': -10 + vr_depth_offset,
|
||||
'rotate': rotate,
|
||||
'attach': 'center',
|
||||
'tilt_translate': 0.21,
|
||||
'absolute_scale': True,
|
||||
},
|
||||
)
|
||||
)
|
||||
logo_attrs = {
|
||||
'position': (x, y),
|
||||
'texture': ltex,
|
||||
'mesh_opaque': mopaque,
|
||||
'mesh_transparent': mtrans,
|
||||
'vr_depth': -10 + vr_depth_offset,
|
||||
'rotate': rotate,
|
||||
'attach': 'center',
|
||||
'tilt_translate': 0.21,
|
||||
'absolute_scale': True,
|
||||
}
|
||||
if custom_texture is None:
|
||||
logo_attrs['scale'] = (2000.0, 2000.0)
|
||||
logo = bs.NodeActor(bs.newnode('image', attrs=logo_attrs))
|
||||
self._logo_node = logo.node
|
||||
self._word_actors.append(logo)
|
||||
|
||||
# Add a bit of stop-motion-y jitter to the logo
|
||||
# (unless we're in VR mode in which case its best to
|
||||
# leave things still).
|
||||
# Add a bit of stop-motion-y jitter to the logo (unless we're in
|
||||
# VR mode in which case its best to leave things still).
|
||||
assert logo.node
|
||||
if not bs.app.env.vr:
|
||||
|
||||
def jitter() -> None:
|
||||
if not bs.app.env.vr:
|
||||
cmb = bs.newnode('combine', owner=logo.node, attrs={'size': 2})
|
||||
cmb.connectattr('output', logo.node, 'position')
|
||||
keys = {}
|
||||
time_v = 0.0
|
||||
|
||||
# Gen some random keys for that stop-motion-y look
|
||||
for _i in range(10):
|
||||
keys[time_v] = (
|
||||
x + (random.random() - 0.5) * 0.7 * jitter_scale
|
||||
)
|
||||
time_v += random.random() * 0.1
|
||||
bs.animate(cmb, 'input0', keys, loop=True)
|
||||
keys = {}
|
||||
time_v = 0.0
|
||||
for _i in range(10):
|
||||
keys[time_v * self._ts] = (
|
||||
y + (random.random() - 0.5) * 0.7 * jitter_scale
|
||||
)
|
||||
time_v += random.random() * 0.1
|
||||
bs.animate(cmb, 'input1', keys, loop=True)
|
||||
|
||||
# Do a fun spinny animation on the logo the first time in.
|
||||
if (
|
||||
custom_texture is None
|
||||
and bs.app.classic is not None
|
||||
and not bs.app.classic.main_menu_did_initial_transition
|
||||
):
|
||||
jitter()
|
||||
cmb = bs.newnode('combine', owner=logo.node, attrs={'size': 2})
|
||||
cmb.connectattr('output', logo.node, 'position')
|
||||
keys = {}
|
||||
time_v = 0.0
|
||||
|
||||
# Gen some random keys for that stop-motion-y look
|
||||
for _i in range(10):
|
||||
keys[time_v] = x + (random.random() - 0.5) * 0.7 * jitter_scale
|
||||
time_v += random.random() * 0.1
|
||||
bs.animate(cmb, 'input0', keys, loop=True)
|
||||
keys = {}
|
||||
time_v = 0.0
|
||||
for _i in range(10):
|
||||
keys[time_v * self._ts] = (
|
||||
y + (random.random() - 0.5) * 0.7 * jitter_scale
|
||||
)
|
||||
time_v += random.random() * 0.1
|
||||
bs.animate(cmb, 'input1', keys, loop=True)
|
||||
delay = 0.0
|
||||
keys = {
|
||||
delay: 5000.0 * scale,
|
||||
delay + 0.4: 530.0 * scale,
|
||||
delay + 0.45: 620.0 * scale,
|
||||
delay + 0.5: 590.0 * scale,
|
||||
delay + 0.55: 605.0 * scale,
|
||||
delay + 0.6: 600.0 * scale,
|
||||
}
|
||||
bs.animate(cmb, 'input0', keys)
|
||||
bs.animate(cmb, 'input1', keys)
|
||||
cmb.connectattr('output', logo.node, 'scale')
|
||||
|
||||
keys = {
|
||||
delay: 100.0,
|
||||
delay + 0.4: 370.0,
|
||||
delay + 0.45: 357.0,
|
||||
delay + 0.5: 360.0,
|
||||
}
|
||||
bs.animate(logo.node, 'rotate', keys)
|
||||
else:
|
||||
logo.node.position = (x, y)
|
||||
# For all other cases do a simple scale up animation.
|
||||
jitter()
|
||||
cmb = bs.newnode('combine', owner=logo.node, attrs={'size': 2})
|
||||
|
||||
cmb = bs.newnode('combine', owner=logo.node, attrs={'size': 2})
|
||||
|
||||
keys = {
|
||||
delay: 0.0,
|
||||
delay + 0.1: 700.0 * scale,
|
||||
delay + 0.2: 600.0 * scale,
|
||||
}
|
||||
bs.animate(cmb, 'input0', keys)
|
||||
bs.animate(cmb, 'input1', keys)
|
||||
cmb.connectattr('output', logo.node, 'scale')
|
||||
keys = {
|
||||
delay: 0.0,
|
||||
delay + 0.1: 700.0 * scale,
|
||||
delay + 0.2: 600.0 * scale,
|
||||
}
|
||||
bs.animate(cmb, 'input0', keys)
|
||||
bs.animate(cmb, 'input1', keys)
|
||||
cmb.connectattr('output', logo.node, 'scale')
|
||||
|
||||
def _start_preloads(self) -> None:
|
||||
# FIXME: The func that calls us back doesn't save/restore state
|
||||
|
|
@ -879,8 +718,8 @@ class NewsDisplay:
|
|||
self._used_phrases: list[str] = []
|
||||
self._phrase_change_timer: bs.Timer | None = None
|
||||
|
||||
# If we're signed in, fetch news immediately.
|
||||
# Otherwise wait until we are signed in.
|
||||
# If we're signed in, fetch news immediately. Otherwise wait
|
||||
# until we are signed in.
|
||||
self._fetch_timer: bs.Timer | None = bs.Timer(
|
||||
1.0, bs.WeakCall(self._try_fetching_news), repeat=True
|
||||
)
|
||||
|
|
@ -913,8 +752,8 @@ class NewsDisplay:
|
|||
app = bs.app
|
||||
assert app.classic is not None
|
||||
|
||||
# If our news is way out of date, lets re-request it;
|
||||
# otherwise, rotate our phrase.
|
||||
# If our news is way out of date, lets re-request it; otherwise,
|
||||
# rotate our phrase.
|
||||
assert app.classic.main_menu_last_news_fetch_time is not None
|
||||
if time.time() - app.classic.main_menu_last_news_fetch_time > 600.0:
|
||||
self._fetch_news()
|
||||
|
|
@ -981,17 +820,16 @@ class NewsDisplay:
|
|||
self._text.node.text = val
|
||||
|
||||
def _got_news(self, news: str) -> None:
|
||||
# Run this stuff in the context of our activity since we
|
||||
# need to make nodes and stuff.. should fix the serverget
|
||||
# call so it.
|
||||
# Run this stuff in the context of our activity since we need to
|
||||
# make nodes and stuff.. should fix the serverget call so it.
|
||||
activity = self._activity()
|
||||
if activity is None or activity.expired:
|
||||
return
|
||||
with activity.context:
|
||||
self._phrases.clear()
|
||||
|
||||
# Show upcoming achievements in non-vr versions
|
||||
# (currently too hard to read in vr).
|
||||
# Show upcoming achievements in non-vr versions (currently
|
||||
# too hard to read in vr).
|
||||
self._used_phrases = (['__ACH__'] if not bs.app.env.vr else []) + [
|
||||
s for s in news.split('<br>\n') if s != ''
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue