mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-10-20 00:00:39 +00:00
ba_data update
This commit is contained in:
parent
2174ae566d
commit
7ba24ecbcf
146 changed files with 1756 additions and 347 deletions
6
dist/ba_data/python/babase/__init__.py
vendored
6
dist/ba_data/python/babase/__init__.py
vendored
|
|
@ -48,6 +48,7 @@ from _babase import (
|
|||
fatal_error,
|
||||
get_display_resolution,
|
||||
get_immediate_return_code,
|
||||
get_input_idle_time,
|
||||
get_low_level_config_value,
|
||||
get_max_graphics_quality,
|
||||
get_replays_dir,
|
||||
|
|
@ -60,6 +61,7 @@ from _babase import (
|
|||
have_permission,
|
||||
in_logic_thread,
|
||||
increment_analytics_count,
|
||||
invoke_main_menu,
|
||||
is_os_playing_music,
|
||||
is_xcode_build,
|
||||
lock_all_input,
|
||||
|
|
@ -116,7 +118,6 @@ from babase._apputils import (
|
|||
get_remote_app_name,
|
||||
AppHealthMonitor,
|
||||
)
|
||||
from babase._cloud import CloudSubsystem
|
||||
from babase._devconsole import (
|
||||
DevConsoleTab,
|
||||
DevConsoleTabEntry,
|
||||
|
|
@ -211,7 +212,6 @@ __all__ = [
|
|||
'clipboard_has_text',
|
||||
'clipboard_is_supported',
|
||||
'clipboard_set_text',
|
||||
'CloudSubsystem',
|
||||
'commit_app_config',
|
||||
'ContextCall',
|
||||
'ContextError',
|
||||
|
|
@ -235,6 +235,7 @@ __all__ = [
|
|||
'garbage_collect',
|
||||
'get_display_resolution',
|
||||
'get_immediate_return_code',
|
||||
'get_input_idle_time',
|
||||
'get_ip_address_type',
|
||||
'get_low_level_config_value',
|
||||
'get_max_graphics_quality',
|
||||
|
|
@ -254,6 +255,7 @@ __all__ = [
|
|||
'increment_analytics_count',
|
||||
'InputDeviceNotFoundError',
|
||||
'InputType',
|
||||
'invoke_main_menu',
|
||||
'is_browser_likely_available',
|
||||
'is_browser_likely_available',
|
||||
'is_os_playing_music',
|
||||
|
|
|
|||
86
dist/ba_data/python/babase/_app.py
vendored
86
dist/ba_data/python/babase/_app.py
vendored
|
|
@ -1,15 +1,17 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
# pylint: disable=too-many-lines
|
||||
"""Functionality related to the high level state of the app."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import logging
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from functools import cached_property
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.call import tpartial
|
||||
|
||||
import _babase
|
||||
|
|
@ -26,7 +28,7 @@ from babase._devconsole import DevConsoleSubsystem
|
|||
|
||||
if TYPE_CHECKING:
|
||||
import asyncio
|
||||
from typing import Any, Callable, Coroutine
|
||||
from typing import Any, Callable, Coroutine, Generator, Awaitable
|
||||
from concurrent.futures import Future
|
||||
|
||||
import babase
|
||||
|
|
@ -42,6 +44,8 @@ if TYPE_CHECKING:
|
|||
|
||||
# __FEATURESET_APP_SUBSYSTEM_IMPORTS_END__
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class App:
|
||||
"""A class for high level app functionality and state.
|
||||
|
|
@ -124,6 +128,7 @@ class App:
|
|||
statically in a spinoff project.
|
||||
"""
|
||||
|
||||
@override
|
||||
def app_mode_for_intent(
|
||||
self, intent: AppIntent
|
||||
) -> type[AppMode] | None:
|
||||
|
|
@ -199,7 +204,8 @@ class App:
|
|||
self._called_on_running = False
|
||||
self._subsystem_registration_ended = False
|
||||
self._pending_apply_app_config = False
|
||||
self._aioloop: asyncio.AbstractEventLoop | None = None
|
||||
self._asyncio_loop: asyncio.AbstractEventLoop | None = None
|
||||
self._asyncio_tasks: set[asyncio.Task] = set()
|
||||
self._asyncio_timer: babase.AppTimer | None = None
|
||||
self._config: babase.AppConfig | None = None
|
||||
self._pending_intent: AppIntent | None = None
|
||||
|
|
@ -239,18 +245,68 @@ class App:
|
|||
return _babase.app_is_active()
|
||||
|
||||
@property
|
||||
def aioloop(self) -> asyncio.AbstractEventLoop:
|
||||
def asyncio_loop(self) -> asyncio.AbstractEventLoop:
|
||||
"""The logic thread's asyncio event loop.
|
||||
|
||||
This allow async tasks to be run in the logic thread.
|
||||
|
||||
Generally you should call App.create_async_task() to schedule
|
||||
async code to run instead of using this directly. That will
|
||||
handle retaining the task and logging errors automatically.
|
||||
Only schedule tasks onto asyncio_loop yourself when you intend
|
||||
to hold on to the returned task and await its results. Releasing
|
||||
the task reference can lead to subtle bugs such as unreported
|
||||
errors and garbage-collected tasks disappearing before their
|
||||
work is done.
|
||||
|
||||
Note that, at this time, the asyncio loop is encapsulated
|
||||
and explicitly stepped by the engine's logic thread loop and
|
||||
thus things like asyncio.get_running_loop() will not return this
|
||||
loop from most places in the logic thread; only from within a
|
||||
task explicitly created in this loop.
|
||||
thus things like asyncio.get_running_loop() will unintuitively
|
||||
*not* return this loop from most places in the logic thread;
|
||||
only from within a task explicitly created in this loop.
|
||||
Hopefully this situation will be improved in the future with a
|
||||
unified event loop.
|
||||
"""
|
||||
assert self._aioloop is not None
|
||||
return self._aioloop
|
||||
assert _babase.in_logic_thread()
|
||||
assert self._asyncio_loop is not None
|
||||
return self._asyncio_loop
|
||||
|
||||
def create_async_task(
|
||||
self,
|
||||
coro: Generator[Any, Any, T] | Coroutine[Any, Any, T],
|
||||
*,
|
||||
name: str | None = None,
|
||||
) -> None:
|
||||
"""Create a fully managed async task.
|
||||
|
||||
This will automatically retain and release a reference to the task
|
||||
and log any exceptions that occur in it. If you need to await a task
|
||||
or otherwise need more control, schedule a task directly using
|
||||
App.asyncio_loop.
|
||||
"""
|
||||
assert _babase.in_logic_thread()
|
||||
# Hold a strong reference to the task until it is done.
|
||||
# Otherwise it is possible for it to be garbage collected and
|
||||
# disappear midway if the caller does not hold on to the
|
||||
# returned task, which seems like a great way to introduce
|
||||
# hard-to-track bugs.
|
||||
task = self.asyncio_loop.create_task(coro, name=name)
|
||||
self._asyncio_tasks.add(task)
|
||||
task.add_done_callback(self._on_task_done)
|
||||
# return task
|
||||
|
||||
def _on_task_done(self, task: asyncio.Task) -> None:
|
||||
# Report any errors that occurred.
|
||||
try:
|
||||
exc = task.exception()
|
||||
if exc is not None:
|
||||
logging.error(
|
||||
"Error in async task '%s'.", task.get_name(), exc_info=exc
|
||||
)
|
||||
except Exception:
|
||||
logging.exception('Error reporting async task error.')
|
||||
|
||||
self._asyncio_tasks.remove(task)
|
||||
|
||||
@property
|
||||
def config(self) -> babase.AppConfig:
|
||||
|
|
@ -437,6 +493,12 @@ class App:
|
|||
self._native_shutdown_complete_called = True
|
||||
self._update_state()
|
||||
|
||||
def on_native_active_changed(self) -> None:
|
||||
"""Called by the native layer when the app active state changes."""
|
||||
assert _babase.in_logic_thread()
|
||||
if self._mode is not None:
|
||||
self._mode.on_app_active_changed()
|
||||
|
||||
def read_config(self) -> None:
|
||||
"""(internal)"""
|
||||
from babase._appconfig import read_app_config
|
||||
|
|
@ -588,7 +650,7 @@ class App:
|
|||
|
||||
_env.on_app_state_initing()
|
||||
|
||||
self._aioloop = _asyncio.setup_asyncio()
|
||||
self._asyncio_loop = _asyncio.setup_asyncio()
|
||||
self.health_monitor = AppHealthMonitor()
|
||||
|
||||
# __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__
|
||||
|
|
@ -868,8 +930,8 @@ class App:
|
|||
)
|
||||
|
||||
# Now kick off any async shutdown task(s).
|
||||
assert self._aioloop is not None
|
||||
self._shutdown_task = self._aioloop.create_task(self._shutdown())
|
||||
assert self._asyncio_loop is not None
|
||||
self._shutdown_task = self._asyncio_loop.create_task(self._shutdown())
|
||||
|
||||
def _on_shutdown_complete(self) -> None:
|
||||
"""(internal)"""
|
||||
|
|
|
|||
7
dist/ba_data/python/babase/_appmode.py
vendored
7
dist/ba_data/python/babase/_appmode.py
vendored
|
|
@ -52,3 +52,10 @@ class AppMode:
|
|||
|
||||
def on_deactivate(self) -> None:
|
||||
"""Called when the mode is being deactivated."""
|
||||
|
||||
def on_app_active_changed(self) -> None:
|
||||
"""Called when babase.app.active changes.
|
||||
|
||||
The app-mode may want to take action such as pausing a running
|
||||
game in such cases.
|
||||
"""
|
||||
|
|
|
|||
8
dist/ba_data/python/babase/_appsubsystem.py
vendored
8
dist/ba_data/python/babase/_appsubsystem.py
vendored
|
|
@ -40,16 +40,16 @@ class AppSubsystem:
|
|||
"""Called when the app reaches the running state."""
|
||||
|
||||
def on_app_suspend(self) -> None:
|
||||
"""Called when the app enters the paused state."""
|
||||
"""Called when the app enters the suspended state."""
|
||||
|
||||
def on_app_unsuspend(self) -> None:
|
||||
"""Called when the app exits the paused state."""
|
||||
"""Called when the app exits the suspended state."""
|
||||
|
||||
def on_app_shutdown(self) -> None:
|
||||
"""Called when the app is shutting down."""
|
||||
"""Called when the app begins shutting down."""
|
||||
|
||||
def on_app_shutdown_complete(self) -> None:
|
||||
"""Called when the app is done shutting down."""
|
||||
"""Called when the app completes shutting down."""
|
||||
|
||||
def do_apply_app_config(self) -> None:
|
||||
"""Called when the app config should be applied."""
|
||||
|
|
|
|||
5
dist/ba_data/python/babase/_apputils.py
vendored
5
dist/ba_data/python/babase/_apputils.py
vendored
|
|
@ -10,9 +10,11 @@ from threading import Thread
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.call import tpartial
|
||||
from efro.log import LogLevel
|
||||
from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json
|
||||
|
||||
import _babase
|
||||
from babase._appsubsystem import AppSubsystem
|
||||
|
||||
|
|
@ -386,6 +388,7 @@ class AppHealthMonitor(AppSubsystem):
|
|||
self._response = False
|
||||
self._first_check = True
|
||||
|
||||
@override
|
||||
def on_app_loading(self) -> None:
|
||||
# If any traceback dumps happened last run, log and clear them.
|
||||
log_dumped_app_state(from_previous_run=True)
|
||||
|
|
@ -449,10 +452,12 @@ class AppHealthMonitor(AppSubsystem):
|
|||
|
||||
self._first_check = False
|
||||
|
||||
@override
|
||||
def on_app_suspend(self) -> None:
|
||||
assert _babase.in_logic_thread()
|
||||
self._running = False
|
||||
|
||||
@override
|
||||
def on_app_unsuspend(self) -> None:
|
||||
assert _babase.in_logic_thread()
|
||||
self._running = True
|
||||
|
|
|
|||
4
dist/ba_data/python/babase/_devconsole.py
vendored
4
dist/ba_data/python/babase/_devconsole.py
vendored
|
|
@ -8,6 +8,8 @@ from typing import TYPE_CHECKING
|
|||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
import _babase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -96,6 +98,7 @@ class DevConsoleTab:
|
|||
class DevConsoleTabPython(DevConsoleTab):
|
||||
"""The Python dev-console tab."""
|
||||
|
||||
@override
|
||||
def refresh(self) -> None:
|
||||
self.python_terminal()
|
||||
|
||||
|
|
@ -103,6 +106,7 @@ class DevConsoleTabPython(DevConsoleTab):
|
|||
class DevConsoleTabTest(DevConsoleTab):
|
||||
"""Test dev-console tab."""
|
||||
|
||||
@override
|
||||
def refresh(self) -> None:
|
||||
import random
|
||||
|
||||
|
|
|
|||
6
dist/ba_data/python/babase/_emptyappmode.py
vendored
6
dist/ba_data/python/babase/_emptyappmode.py
vendored
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
from bacommon.app import AppExperience
|
||||
|
||||
import _babase
|
||||
|
|
@ -18,15 +19,18 @@ if TYPE_CHECKING:
|
|||
class EmptyAppMode(AppMode):
|
||||
"""An empty app mode that can be used as a fallback/etc."""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_app_experience(cls) -> AppExperience:
|
||||
return AppExperience.EMPTY
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def _supports_intent(cls, intent: AppIntent) -> bool:
|
||||
# We support default and exec intents currently.
|
||||
return isinstance(intent, AppIntentExec | AppIntentDefault)
|
||||
|
||||
@override
|
||||
def handle_intent(self, intent: AppIntent) -> None:
|
||||
if isinstance(intent, AppIntentExec):
|
||||
_babase.empty_app_mode_handle_intent_exec(intent.code)
|
||||
|
|
@ -34,10 +38,12 @@ class EmptyAppMode(AppMode):
|
|||
assert isinstance(intent, AppIntentDefault)
|
||||
_babase.empty_app_mode_handle_intent_default()
|
||||
|
||||
@override
|
||||
def on_activate(self) -> None:
|
||||
# Let the native layer do its thing.
|
||||
_babase.on_empty_app_mode_activate()
|
||||
|
||||
@override
|
||||
def on_deactivate(self) -> None:
|
||||
# Let the native layer do its thing.
|
||||
_babase.on_empty_app_mode_deactivate()
|
||||
|
|
|
|||
2
dist/ba_data/python/babase/_env.py
vendored
2
dist/ba_data/python/babase/_env.py
vendored
|
|
@ -9,6 +9,7 @@ import logging
|
|||
import warnings
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.log import LogLevel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -216,6 +217,7 @@ def _feed_logs_to_babase(log_handler: LogHandler) -> None:
|
|||
class _CustomHelper:
|
||||
"""Replacement 'help' that behaves better for our setup."""
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
return 'Type help(object) for help about object.'
|
||||
|
||||
|
|
|
|||
4
dist/ba_data/python/babase/_general.py
vendored
4
dist/ba_data/python/babase/_general.py
vendored
|
|
@ -10,6 +10,7 @@ import logging
|
|||
import inspect
|
||||
from typing import TYPE_CHECKING, TypeVar, Protocol, NewType
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.terminal import Clr
|
||||
|
||||
import _babase
|
||||
|
|
@ -178,6 +179,7 @@ class _WeakCall:
|
|||
def __call__(self, *args_extra: Any) -> Any:
|
||||
return self._call(*self._args + args_extra, **self._keywds)
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
'<ba.WeakCall object; _call='
|
||||
|
|
@ -224,6 +226,7 @@ class _Call:
|
|||
def __call__(self, *args_extra: Any) -> Any:
|
||||
return self._call(*self._args + args_extra, **self._keywds)
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
'<ba.Call object; _call='
|
||||
|
|
@ -268,6 +271,7 @@ class WeakMethod:
|
|||
return None
|
||||
return self._func(*((obj,) + args), **keywds)
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return '<ba.WeakMethod object; call=' + str(self._func) + '>'
|
||||
|
||||
|
|
|
|||
6
dist/ba_data/python/babase/_language.py
vendored
6
dist/ba_data/python/babase/_language.py
vendored
|
|
@ -8,6 +8,8 @@ import json
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, overload
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
import _babase
|
||||
from babase._appsubsystem import AppSubsystem
|
||||
|
||||
|
|
@ -217,6 +219,7 @@ class LanguageSubsystem(AppSubsystem):
|
|||
color=(0, 1, 0),
|
||||
)
|
||||
|
||||
@override
|
||||
def do_apply_app_config(self) -> None:
|
||||
assert _babase.in_logic_thread()
|
||||
assert isinstance(_babase.app.config, dict)
|
||||
|
|
@ -598,9 +601,11 @@ class Lstr:
|
|||
_error.print_exception('_get_json failed for', self.args)
|
||||
return 'JSON_ERR'
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return '<ba.Lstr: ' + self._get_json() + '>'
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
return '<ba.Lstr: ' + self._get_json() + '>'
|
||||
|
||||
|
|
@ -648,5 +653,6 @@ class AttrDict(dict):
|
|||
assert not isinstance(val, bytes)
|
||||
return val
|
||||
|
||||
@override
|
||||
def __setattr__(self, attr: str, value: Any) -> None:
|
||||
raise AttributeError()
|
||||
|
|
|
|||
3
dist/ba_data/python/babase/_login.py
vendored
3
dist/ba_data/python/babase/_login.py
vendored
|
|
@ -9,6 +9,7 @@ import logging
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, final
|
||||
|
||||
from typing_extensions import override
|
||||
from bacommon.login import LoginType
|
||||
|
||||
import _babase
|
||||
|
|
@ -353,6 +354,7 @@ class LoginAdapterNative(LoginAdapter):
|
|||
self._sign_in_attempt_num = 123
|
||||
self._sign_in_attempts: dict[int, Callable[[str | None], None]] = {}
|
||||
|
||||
@override
|
||||
def get_sign_in_token(
|
||||
self, completion_cb: Callable[[str | None], None]
|
||||
) -> None:
|
||||
|
|
@ -363,6 +365,7 @@ class LoginAdapterNative(LoginAdapter):
|
|||
self.login_type.value, attempt_id
|
||||
)
|
||||
|
||||
@override
|
||||
def on_back_end_active_change(self, active: bool) -> None:
|
||||
_babase.login_adapter_back_end_active_change(
|
||||
self.login_type.value, active
|
||||
|
|
|
|||
2
dist/ba_data/python/babase/_meta.py
vendored
2
dist/ba_data/python/babase/_meta.py
vendored
|
|
@ -26,7 +26,7 @@ EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = {
|
|||
'plugin': 'babase.Plugin',
|
||||
# DEPRECATED as of 12/2023. Currently am warning if finding these
|
||||
# but should take this out eventually.
|
||||
'keyboard': 'babase.Keyboard',
|
||||
'keyboard': 'bauiv1.Keyboard',
|
||||
}
|
||||
|
||||
T = TypeVar('T')
|
||||
|
|
|
|||
156
dist/ba_data/python/babase/_mgen/enums.py
vendored
156
dist/ba_data/python/babase/_mgen/enums.py
vendored
|
|
@ -149,78 +149,84 @@ class SpecialChar(Enum):
|
|||
PLAY_PAUSE_BUTTON = 13
|
||||
FAST_FORWARD_BUTTON = 14
|
||||
DPAD_CENTER_BUTTON = 15
|
||||
OUYA_BUTTON_O = 16
|
||||
OUYA_BUTTON_U = 17
|
||||
OUYA_BUTTON_Y = 18
|
||||
OUYA_BUTTON_A = 19
|
||||
OUYA_LOGO = 20
|
||||
LOGO = 21
|
||||
TICKET = 22
|
||||
GOOGLE_PLAY_GAMES_LOGO = 23
|
||||
GAME_CENTER_LOGO = 24
|
||||
DICE_BUTTON1 = 25
|
||||
DICE_BUTTON2 = 26
|
||||
DICE_BUTTON3 = 27
|
||||
DICE_BUTTON4 = 28
|
||||
GAME_CIRCLE_LOGO = 29
|
||||
PARTY_ICON = 30
|
||||
TEST_ACCOUNT = 31
|
||||
TICKET_BACKING = 32
|
||||
TROPHY1 = 33
|
||||
TROPHY2 = 34
|
||||
TROPHY3 = 35
|
||||
TROPHY0A = 36
|
||||
TROPHY0B = 37
|
||||
TROPHY4 = 38
|
||||
LOCAL_ACCOUNT = 39
|
||||
EXPLODINARY_LOGO = 40
|
||||
FLAG_UNITED_STATES = 41
|
||||
FLAG_MEXICO = 42
|
||||
FLAG_GERMANY = 43
|
||||
FLAG_BRAZIL = 44
|
||||
FLAG_RUSSIA = 45
|
||||
FLAG_CHINA = 46
|
||||
FLAG_UNITED_KINGDOM = 47
|
||||
FLAG_CANADA = 48
|
||||
FLAG_INDIA = 49
|
||||
FLAG_JAPAN = 50
|
||||
FLAG_FRANCE = 51
|
||||
FLAG_INDONESIA = 52
|
||||
FLAG_ITALY = 53
|
||||
FLAG_SOUTH_KOREA = 54
|
||||
FLAG_NETHERLANDS = 55
|
||||
FEDORA = 56
|
||||
HAL = 57
|
||||
CROWN = 58
|
||||
YIN_YANG = 59
|
||||
EYE_BALL = 60
|
||||
SKULL = 61
|
||||
HEART = 62
|
||||
DRAGON = 63
|
||||
HELMET = 64
|
||||
MUSHROOM = 65
|
||||
NINJA_STAR = 66
|
||||
VIKING_HELMET = 67
|
||||
MOON = 68
|
||||
SPIDER = 69
|
||||
FIREBALL = 70
|
||||
FLAG_UNITED_ARAB_EMIRATES = 71
|
||||
FLAG_QATAR = 72
|
||||
FLAG_EGYPT = 73
|
||||
FLAG_KUWAIT = 74
|
||||
FLAG_ALGERIA = 75
|
||||
FLAG_SAUDI_ARABIA = 76
|
||||
FLAG_MALAYSIA = 77
|
||||
FLAG_CZECH_REPUBLIC = 78
|
||||
FLAG_AUSTRALIA = 79
|
||||
FLAG_SINGAPORE = 80
|
||||
OCULUS_LOGO = 81
|
||||
STEAM_LOGO = 82
|
||||
NVIDIA_LOGO = 83
|
||||
FLAG_IRAN = 84
|
||||
FLAG_POLAND = 85
|
||||
FLAG_ARGENTINA = 86
|
||||
FLAG_PHILIPPINES = 87
|
||||
FLAG_CHILE = 88
|
||||
MIKIROG = 89
|
||||
V2_LOGO = 90
|
||||
PLAY_STATION_CROSS_BUTTON = 16
|
||||
PLAY_STATION_CIRCLE_BUTTON = 17
|
||||
PLAY_STATION_TRIANGLE_BUTTON = 18
|
||||
PLAY_STATION_SQUARE_BUTTON = 19
|
||||
PLAY_BUTTON = 20
|
||||
PAUSE_BUTTON = 21
|
||||
OUYA_BUTTON_O = 22
|
||||
OUYA_BUTTON_U = 23
|
||||
OUYA_BUTTON_Y = 24
|
||||
OUYA_BUTTON_A = 25
|
||||
OUYA_LOGO = 26
|
||||
LOGO = 27
|
||||
TICKET = 28
|
||||
GOOGLE_PLAY_GAMES_LOGO = 29
|
||||
GAME_CENTER_LOGO = 30
|
||||
DICE_BUTTON1 = 31
|
||||
DICE_BUTTON2 = 32
|
||||
DICE_BUTTON3 = 33
|
||||
DICE_BUTTON4 = 34
|
||||
GAME_CIRCLE_LOGO = 35
|
||||
PARTY_ICON = 36
|
||||
TEST_ACCOUNT = 37
|
||||
TICKET_BACKING = 38
|
||||
TROPHY1 = 39
|
||||
TROPHY2 = 40
|
||||
TROPHY3 = 41
|
||||
TROPHY0A = 42
|
||||
TROPHY0B = 43
|
||||
TROPHY4 = 44
|
||||
LOCAL_ACCOUNT = 45
|
||||
EXPLODINARY_LOGO = 46
|
||||
FLAG_UNITED_STATES = 47
|
||||
FLAG_MEXICO = 48
|
||||
FLAG_GERMANY = 49
|
||||
FLAG_BRAZIL = 50
|
||||
FLAG_RUSSIA = 51
|
||||
FLAG_CHINA = 52
|
||||
FLAG_UNITED_KINGDOM = 53
|
||||
FLAG_CANADA = 54
|
||||
FLAG_INDIA = 55
|
||||
FLAG_JAPAN = 56
|
||||
FLAG_FRANCE = 57
|
||||
FLAG_INDONESIA = 58
|
||||
FLAG_ITALY = 59
|
||||
FLAG_SOUTH_KOREA = 60
|
||||
FLAG_NETHERLANDS = 61
|
||||
FEDORA = 62
|
||||
HAL = 63
|
||||
CROWN = 64
|
||||
YIN_YANG = 65
|
||||
EYE_BALL = 66
|
||||
SKULL = 67
|
||||
HEART = 68
|
||||
DRAGON = 69
|
||||
HELMET = 70
|
||||
MUSHROOM = 71
|
||||
NINJA_STAR = 72
|
||||
VIKING_HELMET = 73
|
||||
MOON = 74
|
||||
SPIDER = 75
|
||||
FIREBALL = 76
|
||||
FLAG_UNITED_ARAB_EMIRATES = 77
|
||||
FLAG_QATAR = 78
|
||||
FLAG_EGYPT = 79
|
||||
FLAG_KUWAIT = 80
|
||||
FLAG_ALGERIA = 81
|
||||
FLAG_SAUDI_ARABIA = 82
|
||||
FLAG_MALAYSIA = 83
|
||||
FLAG_CZECH_REPUBLIC = 84
|
||||
FLAG_AUSTRALIA = 85
|
||||
FLAG_SINGAPORE = 86
|
||||
OCULUS_LOGO = 87
|
||||
STEAM_LOGO = 88
|
||||
NVIDIA_LOGO = 89
|
||||
FLAG_IRAN = 90
|
||||
FLAG_POLAND = 91
|
||||
FLAG_ARGENTINA = 92
|
||||
FLAG_PHILIPPINES = 93
|
||||
FLAG_CHILE = 94
|
||||
MIKIROG = 95
|
||||
V2_LOGO = 96
|
||||
|
|
|
|||
7
dist/ba_data/python/babase/_plugin.py
vendored
7
dist/ba_data/python/babase/_plugin.py
vendored
|
|
@ -8,6 +8,8 @@ import logging
|
|||
import importlib.util
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
import _babase
|
||||
from babase._appsubsystem import AppSubsystem
|
||||
|
||||
|
|
@ -158,6 +160,7 @@ class PluginSubsystem(AppSubsystem):
|
|||
if config_changed:
|
||||
_babase.app.config.commit()
|
||||
|
||||
@override
|
||||
def on_app_running(self) -> None:
|
||||
# Load up our plugins and go ahead and call their on_app_running
|
||||
# calls.
|
||||
|
|
@ -170,6 +173,7 @@ class PluginSubsystem(AppSubsystem):
|
|||
|
||||
_error.print_exception('Error in plugin on_app_running()')
|
||||
|
||||
@override
|
||||
def on_app_suspend(self) -> None:
|
||||
for plugin in self.active_plugins:
|
||||
try:
|
||||
|
|
@ -179,6 +183,7 @@ class PluginSubsystem(AppSubsystem):
|
|||
|
||||
_error.print_exception('Error in plugin on_app_suspend()')
|
||||
|
||||
@override
|
||||
def on_app_unsuspend(self) -> None:
|
||||
for plugin in self.active_plugins:
|
||||
try:
|
||||
|
|
@ -188,6 +193,7 @@ class PluginSubsystem(AppSubsystem):
|
|||
|
||||
_error.print_exception('Error in plugin on_app_unsuspend()')
|
||||
|
||||
@override
|
||||
def on_app_shutdown(self) -> None:
|
||||
for plugin in self.active_plugins:
|
||||
try:
|
||||
|
|
@ -197,6 +203,7 @@ class PluginSubsystem(AppSubsystem):
|
|||
|
||||
_error.print_exception('Error in plugin on_app_shutdown()')
|
||||
|
||||
@override
|
||||
def on_app_shutdown_complete(self) -> None:
|
||||
for plugin in self.active_plugins:
|
||||
try:
|
||||
|
|
|
|||
4
dist/ba_data/python/babase/_ui.py
vendored
4
dist/ba_data/python/babase/_ui.py
vendored
|
|
@ -5,6 +5,8 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from babase._stringedit import StringEditAdapter
|
||||
import _babase
|
||||
|
||||
|
|
@ -24,9 +26,11 @@ class DevConsoleStringEditAdapter(StringEditAdapter):
|
|||
description, initial_text, max_length, screen_space_center
|
||||
)
|
||||
|
||||
@override
|
||||
def _do_apply(self, new_text: str) -> None:
|
||||
_babase.set_dev_console_input_text(new_text)
|
||||
_babase.dev_console_input_adapter_finish()
|
||||
|
||||
@override
|
||||
def _do_cancel(self) -> None:
|
||||
_babase.dev_console_input_adapter_finish()
|
||||
|
|
|
|||
4
dist/ba_data/python/baclassic/_ads.py
vendored
4
dist/ba_data/python/baclassic/_ads.py
vendored
|
|
@ -229,9 +229,7 @@ class AdsSubsystem:
|
|||
await asyncio.sleep(1.0)
|
||||
payload.run(fallback=True)
|
||||
|
||||
_fallback_task = babase.app.aioloop.create_task(
|
||||
add_fallback_task()
|
||||
)
|
||||
babase.app.create_async_task(add_fallback_task())
|
||||
self.show_ad('between_game', on_completion_call=payload.run)
|
||||
else:
|
||||
babase.pushcall(call) # Just run the callback without the ad.
|
||||
|
|
|
|||
104
dist/ba_data/python/baclassic/_benchmark.py
vendored
104
dist/ba_data/python/baclassic/_benchmark.py
vendored
|
|
@ -4,8 +4,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
import bascenev1
|
||||
import _baclassic
|
||||
|
|
@ -42,70 +44,81 @@ def run_cpu_benchmark() -> None:
|
|||
cfg['Graphics Quality'] = self._old_quality
|
||||
cfg.apply()
|
||||
|
||||
@override
|
||||
def on_player_request(self, player: bascenev1.SessionPlayer) -> bool:
|
||||
return False
|
||||
|
||||
bascenev1.new_host_session(BenchmarkSession, benchmark_type='cpu')
|
||||
|
||||
|
||||
@dataclass
|
||||
class _StressTestArgs:
|
||||
playlist_type: str
|
||||
playlist_name: str
|
||||
player_count: int
|
||||
round_duration: int
|
||||
attract_mode: bool
|
||||
|
||||
|
||||
def run_stress_test(
|
||||
playlist_type: str = 'Random',
|
||||
playlist_name: str = '__default__',
|
||||
player_count: int = 8,
|
||||
round_duration: int = 30,
|
||||
attract_mode: bool = False,
|
||||
) -> None:
|
||||
"""Run a stress test."""
|
||||
|
||||
babase.screenmessage(
|
||||
"Beginning stress test.. use 'End Test' to stop testing.",
|
||||
color=(1, 1, 0),
|
||||
)
|
||||
with babase.ContextRef.empty():
|
||||
start_stress_test(
|
||||
{
|
||||
'playlist_type': playlist_type,
|
||||
'playlist_name': playlist_name,
|
||||
'player_count': player_count,
|
||||
'round_duration': round_duration,
|
||||
}
|
||||
if not attract_mode:
|
||||
babase.screenmessage(
|
||||
"Beginning stress test.. use 'End Test' to stop testing.",
|
||||
color=(1, 1, 0),
|
||||
)
|
||||
_start_stress_test(
|
||||
_StressTestArgs(
|
||||
playlist_type=playlist_type,
|
||||
playlist_name=playlist_name,
|
||||
player_count=player_count,
|
||||
round_duration=round_duration,
|
||||
attract_mode=attract_mode,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def stop_stress_test() -> None:
|
||||
"""End a running stress test."""
|
||||
|
||||
_baclassic.set_stress_testing(False, 0)
|
||||
assert babase.app.classic is not None
|
||||
try:
|
||||
if babase.app.classic.stress_test_reset_timer is not None:
|
||||
babase.screenmessage('Ending stress test...', color=(1, 1, 0))
|
||||
except Exception:
|
||||
pass
|
||||
babase.app.classic.stress_test_reset_timer = None
|
||||
|
||||
_baclassic.set_stress_testing(False, 0, False)
|
||||
babase.app.classic.stress_test_update_timer = None
|
||||
babase.app.classic.stress_test_update_timer_2 = None
|
||||
|
||||
|
||||
def start_stress_test(args: dict[str, Any]) -> None:
|
||||
def _start_stress_test(args: _StressTestArgs) -> None:
|
||||
"""(internal)"""
|
||||
from bascenev1 import DualTeamSession, FreeForAllSession
|
||||
|
||||
assert babase.app.classic is not None
|
||||
|
||||
appconfig = babase.app.config
|
||||
playlist_type = args['playlist_type']
|
||||
playlist_type = args.playlist_type
|
||||
if playlist_type == 'Random':
|
||||
if random.random() < 0.5:
|
||||
playlist_type = 'Teams'
|
||||
else:
|
||||
playlist_type = 'Free-For-All'
|
||||
babase.screenmessage(
|
||||
'Running Stress Test (listType="'
|
||||
+ playlist_type
|
||||
+ '", listName="'
|
||||
+ args['playlist_name']
|
||||
+ '")...'
|
||||
)
|
||||
if not args.attract_mode:
|
||||
babase.screenmessage(
|
||||
'Running Stress Test (listType="'
|
||||
+ playlist_type
|
||||
+ '", listName="'
|
||||
+ args.playlist_name
|
||||
+ '")...'
|
||||
)
|
||||
if playlist_type == 'Teams':
|
||||
appconfig['Team Tournament Playlist Selection'] = args['playlist_name']
|
||||
appconfig['Team Tournament Playlist Selection'] = args.playlist_name
|
||||
appconfig['Team Tournament Playlist Randomize'] = 1
|
||||
babase.apptimer(
|
||||
1.0,
|
||||
|
|
@ -115,7 +128,7 @@ def start_stress_test(args: dict[str, Any]) -> None:
|
|||
),
|
||||
)
|
||||
else:
|
||||
appconfig['Free-for-All Playlist Selection'] = args['playlist_name']
|
||||
appconfig['Free-for-All Playlist Selection'] = args.playlist_name
|
||||
appconfig['Free-for-All Playlist Randomize'] = 1
|
||||
babase.apptimer(
|
||||
1.0,
|
||||
|
|
@ -124,19 +137,38 @@ def start_stress_test(args: dict[str, Any]) -> None:
|
|||
babase.Call(bascenev1.new_host_session, FreeForAllSession),
|
||||
),
|
||||
)
|
||||
_baclassic.set_stress_testing(True, args['player_count'])
|
||||
babase.app.classic.stress_test_reset_timer = babase.AppTimer(
|
||||
args['round_duration'], babase.Call(_reset_stress_test, args)
|
||||
_baclassic.set_stress_testing(True, args.player_count, args.attract_mode)
|
||||
babase.app.classic.stress_test_update_timer = babase.AppTimer(
|
||||
args.round_duration, babase.Call(_reset_stress_test, args)
|
||||
)
|
||||
if args.attract_mode:
|
||||
babase.app.classic.stress_test_update_timer_2 = babase.AppTimer(
|
||||
0.48, babase.Call(_update_attract_mode_test, args), repeat=True
|
||||
)
|
||||
|
||||
|
||||
def _reset_stress_test(args: dict[str, Any]) -> None:
|
||||
_baclassic.set_stress_testing(False, args['player_count'])
|
||||
babase.screenmessage('Resetting stress test...')
|
||||
def _update_attract_mode_test(args: _StressTestArgs) -> None:
|
||||
if babase.get_input_idle_time() < 5.0:
|
||||
_reset_stress_test(args)
|
||||
|
||||
|
||||
def _reset_stress_test(args: _StressTestArgs) -> None:
|
||||
_baclassic.set_stress_testing(False, args.player_count, False)
|
||||
if not args.attract_mode:
|
||||
babase.screenmessage('Resetting stress test...')
|
||||
session = bascenev1.get_foreground_host_session()
|
||||
assert session is not None
|
||||
session.end()
|
||||
babase.apptimer(1.0, babase.Call(start_stress_test, args))
|
||||
|
||||
assert babase.app.classic is not None
|
||||
babase.app.classic.stress_test_update_timer = None
|
||||
babase.app.classic.stress_test_update_timer_2 = None
|
||||
|
||||
# For regular stress tests we keep the party going. For attract-mode
|
||||
# we just end back at the main menu. If things are idle there then
|
||||
# we'll get sent back to a new stress test.
|
||||
if not args.attract_mode:
|
||||
babase.apptimer(1.0, babase.Call(_start_stress_test, args))
|
||||
|
||||
|
||||
def run_gpu_benchmark() -> None:
|
||||
|
|
|
|||
2
dist/ba_data/python/baclassic/_net.py
vendored
2
dist/ba_data/python/baclassic/_net.py
vendored
|
|
@ -9,6 +9,7 @@ import threading
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
import bascenev1
|
||||
|
||||
|
|
@ -68,6 +69,7 @@ class MasterServerV1CallThread(threading.Thread):
|
|||
with self._context:
|
||||
self._callback(arg)
|
||||
|
||||
@override
|
||||
def run(self) -> None:
|
||||
# pylint: disable=consider-using-with
|
||||
# pylint: disable=too-many-branches
|
||||
|
|
|
|||
17
dist/ba_data/python/baclassic/_subsystem.py
vendored
17
dist/ba_data/python/baclassic/_subsystem.py
vendored
|
|
@ -8,6 +8,7 @@ import random
|
|||
import logging
|
||||
import weakref
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.dataclassio import dataclass_from_dict
|
||||
import babase
|
||||
import bauiv1
|
||||
|
|
@ -69,7 +70,8 @@ class ClassicSubsystem(babase.AppSubsystem):
|
|||
|
||||
# Misc.
|
||||
self.tips: list[str] = []
|
||||
self.stress_test_reset_timer: babase.AppTimer | None = None
|
||||
self.stress_test_update_timer: babase.AppTimer | None = None
|
||||
self.stress_test_update_timer_2: babase.AppTimer | None = None
|
||||
self.value_test_defaults: dict = {}
|
||||
self.special_offer: dict | None = None
|
||||
self.ping_thread_count = 0
|
||||
|
|
@ -148,6 +150,7 @@ class ClassicSubsystem(babase.AppSubsystem):
|
|||
assert isinstance(self._env['legacy_user_agent_string'], str)
|
||||
return self._env['legacy_user_agent_string']
|
||||
|
||||
@override
|
||||
def on_app_loading(self) -> None:
|
||||
from bascenev1lib.actor import spazappearance
|
||||
from bascenev1lib import maps as stdmaps
|
||||
|
|
@ -229,13 +232,16 @@ class ClassicSubsystem(babase.AppSubsystem):
|
|||
|
||||
self.accounts.on_app_loading()
|
||||
|
||||
@override
|
||||
def on_app_suspend(self) -> None:
|
||||
self.accounts.on_app_suspend()
|
||||
|
||||
@override
|
||||
def on_app_unsuspend(self) -> None:
|
||||
self.accounts.on_app_unsuspend()
|
||||
self.music.on_app_unsuspend()
|
||||
|
||||
@override
|
||||
def on_app_shutdown(self) -> None:
|
||||
self.music.on_app_shutdown()
|
||||
|
||||
|
|
@ -555,11 +561,18 @@ class ClassicSubsystem(babase.AppSubsystem):
|
|||
playlist_name: str = '__default__',
|
||||
player_count: int = 8,
|
||||
round_duration: int = 30,
|
||||
attract_mode: bool = False,
|
||||
) -> None:
|
||||
"""Run a stress test."""
|
||||
from baclassic._benchmark import run_stress_test as run
|
||||
|
||||
run(playlist_type, playlist_name, player_count, round_duration)
|
||||
run(
|
||||
playlist_type=playlist_type,
|
||||
playlist_name=playlist_name,
|
||||
player_count=player_count,
|
||||
round_duration=round_duration,
|
||||
attract_mode=attract_mode,
|
||||
)
|
||||
|
||||
def get_input_device_mapped_value(
|
||||
self, device: bascenev1.InputDevice, name: str
|
||||
|
|
|
|||
7
dist/ba_data/python/baclassic/macmusicapp.py
vendored
7
dist/ba_data/python/baclassic/macmusicapp.py
vendored
|
|
@ -8,6 +8,7 @@ import threading
|
|||
from collections import deque
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
from baclassic._music import MusicPlayer
|
||||
|
|
@ -27,6 +28,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
|
|||
self._thread = _MacMusicAppThread()
|
||||
self._thread.start()
|
||||
|
||||
@override
|
||||
def on_select_entry(
|
||||
self,
|
||||
callback: Callable[[Any], None],
|
||||
|
|
@ -40,6 +42,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
|
|||
callback, current_entry, selection_target_name
|
||||
)
|
||||
|
||||
@override
|
||||
def on_set_volume(self, volume: float) -> None:
|
||||
self._thread.set_volume(volume)
|
||||
|
||||
|
|
@ -47,6 +50,7 @@ class MacMusicAppMusicPlayer(MusicPlayer):
|
|||
"""Asynchronously fetch the list of available iTunes playlists."""
|
||||
self._thread.get_playlists(callback)
|
||||
|
||||
@override
|
||||
def on_play(self, entry: Any) -> None:
|
||||
assert babase.app.classic is not None
|
||||
music = babase.app.classic.music
|
||||
|
|
@ -59,9 +63,11 @@ class MacMusicAppMusicPlayer(MusicPlayer):
|
|||
entry_type,
|
||||
)
|
||||
|
||||
@override
|
||||
def on_stop(self) -> None:
|
||||
self._thread.play_playlist(None)
|
||||
|
||||
@override
|
||||
def on_app_shutdown(self) -> None:
|
||||
self._thread.shutdown()
|
||||
|
||||
|
|
@ -77,6 +83,7 @@ class _MacMusicAppThread(threading.Thread):
|
|||
self._current_playlist: str | None = None
|
||||
self._orig_volume: int | None = None
|
||||
|
||||
@override
|
||||
def run(self) -> None:
|
||||
"""Run the Music.app thread."""
|
||||
babase.set_thread_name('BA_MacMusicAppThread')
|
||||
|
|
|
|||
7
dist/ba_data/python/baclassic/osmusic.py
vendored
7
dist/ba_data/python/baclassic/osmusic.py
vendored
|
|
@ -9,6 +9,7 @@ import logging
|
|||
import threading
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
from baclassic._music import MusicPlayer
|
||||
|
|
@ -33,6 +34,7 @@ class OSMusicPlayer(MusicPlayer):
|
|||
# FIXME: should ask the C++ layer for these; just hard-coding for now.
|
||||
return ['mp3', 'ogg', 'm4a', 'wav', 'flac', 'mid']
|
||||
|
||||
@override
|
||||
def on_select_entry(
|
||||
self,
|
||||
callback: Callable[[Any], None],
|
||||
|
|
@ -48,9 +50,11 @@ class OSMusicPlayer(MusicPlayer):
|
|||
callback, current_entry, selection_target_name
|
||||
)
|
||||
|
||||
@override
|
||||
def on_set_volume(self, volume: float) -> None:
|
||||
babase.music_player_set_volume(volume)
|
||||
|
||||
@override
|
||||
def on_play(self, entry: Any) -> None:
|
||||
assert babase.app.classic is not None
|
||||
music = babase.app.classic.music
|
||||
|
|
@ -99,11 +103,13 @@ class OSMusicPlayer(MusicPlayer):
|
|||
self._actually_playing = True
|
||||
babase.music_player_play(result)
|
||||
|
||||
@override
|
||||
def on_stop(self) -> None:
|
||||
self._want_to_play = False
|
||||
self._actually_playing = False
|
||||
babase.music_player_stop()
|
||||
|
||||
@override
|
||||
def on_app_shutdown(self) -> None:
|
||||
babase.music_player_shutdown()
|
||||
|
||||
|
|
@ -120,6 +126,7 @@ class _PickFolderSongThread(threading.Thread):
|
|||
self._callback = callback
|
||||
self._path = path
|
||||
|
||||
@override
|
||||
def run(self) -> None:
|
||||
do_log_error = True
|
||||
try:
|
||||
|
|
|
|||
2
dist/ba_data/python/bacommon/build.py
vendored
2
dist/ba_data/python/bacommon/build.py
vendored
|
|
@ -21,7 +21,7 @@ class BuildInfoSet:
|
|||
|
||||
@dataclass
|
||||
class Entry:
|
||||
"""Info about a particular build."""
|
||||
"""Info about a particular app build."""
|
||||
|
||||
filename: Annotated[str, IOAttrs('fname')]
|
||||
size: Annotated[int, IOAttrs('size')]
|
||||
|
|
|
|||
31
dist/ba_data/python/bacommon/cloud.py
vendored
31
dist/ba_data/python/bacommon/cloud.py
vendored
|
|
@ -7,6 +7,7 @@ from dataclasses import dataclass, field
|
|||
from typing import TYPE_CHECKING, Annotated
|
||||
from enum import Enum
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.message import Message, Response
|
||||
from efro.dataclassio import ioprepped, IOAttrs
|
||||
from bacommon.transfer import DirectoryManifest
|
||||
|
|
@ -21,6 +22,7 @@ if TYPE_CHECKING:
|
|||
class LoginProxyRequestMessage(Message):
|
||||
"""Request send to the cloud to ask for a login-proxy."""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [LoginProxyRequestResponse]
|
||||
|
|
@ -49,6 +51,7 @@ class LoginProxyStateQueryMessage(Message):
|
|||
proxyid: Annotated[str, IOAttrs('p')]
|
||||
proxykey: Annotated[str, IOAttrs('k')]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [LoginProxyStateQueryResponse]
|
||||
|
|
@ -85,6 +88,7 @@ class LoginProxyCompleteMessage(Message):
|
|||
class PingMessage(Message):
|
||||
"""Standard ping."""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [PingResponse]
|
||||
|
|
@ -103,6 +107,7 @@ class TestMessage(Message):
|
|||
|
||||
testfoo: Annotated[int, IOAttrs('f')]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [TestResponse]
|
||||
|
|
@ -116,6 +121,28 @@ class TestResponse(Response):
|
|||
testfoo: Annotated[int, IOAttrs('f')]
|
||||
|
||||
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class PromoCodeMessage(Message):
|
||||
"""User is entering a promo code"""
|
||||
|
||||
code: Annotated[str, IOAttrs('c')]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [PromoCodeResponse]
|
||||
|
||||
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class PromoCodeResponse(Response):
|
||||
"""Applied that promo code for ya, boss."""
|
||||
|
||||
valid: Annotated[bool, IOAttrs('v')]
|
||||
message: Annotated[str | None, IOAttrs('m', store_default=False)] = None
|
||||
|
||||
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class WorkspaceFetchState:
|
||||
|
|
@ -136,6 +163,7 @@ class WorkspaceFetchMessage(Message):
|
|||
workspaceid: Annotated[str, IOAttrs('w')]
|
||||
state: Annotated[WorkspaceFetchState, IOAttrs('s')]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [WorkspaceFetchResponse]
|
||||
|
|
@ -162,6 +190,7 @@ class WorkspaceFetchResponse(Response):
|
|||
class MerchAvailabilityMessage(Message):
|
||||
"""Can we show merch link?"""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [MerchAvailabilityResponse]
|
||||
|
|
@ -187,6 +216,7 @@ class SignInMessage(Message):
|
|||
description: Annotated[str, IOAttrs('d', soft_default='-')]
|
||||
apptime: Annotated[float, IOAttrs('at', soft_default=-1.0)]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [SignInResponse]
|
||||
|
|
@ -205,6 +235,7 @@ class SignInResponse(Response):
|
|||
class ManageAccountMessage(Message):
|
||||
"""Message asking for a manage-account url."""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_response_types(cls) -> list[type[Response] | None]:
|
||||
return [ManageAccountResponse]
|
||||
|
|
|
|||
18
dist/ba_data/python/bacommon/transfer.py
vendored
18
dist/ba_data/python/bacommon/transfer.py
vendored
|
|
@ -31,7 +31,7 @@ class DirectoryManifest:
|
|||
|
||||
files: Annotated[dict[str, DirectoryManifestFile], IOAttrs('f')]
|
||||
|
||||
_empty_hash: str | None = None
|
||||
# _empty_hash: str | None = None
|
||||
|
||||
@classmethod
|
||||
def create_from_disk(cls, path: Path) -> DirectoryManifest:
|
||||
|
|
@ -92,12 +92,12 @@ class DirectoryManifest:
|
|||
)
|
||||
break # 1 error is enough for now.
|
||||
|
||||
@classmethod
|
||||
def get_empty_hash(cls) -> str:
|
||||
"""Return the hash for an empty file."""
|
||||
if cls._empty_hash is None:
|
||||
import hashlib
|
||||
# @classmethod
|
||||
# def get_empty_hash(cls) -> str:
|
||||
# """Return the hash for an empty file."""
|
||||
# if cls._empty_hash is None:
|
||||
# import hashlib
|
||||
|
||||
sha = hashlib.sha256()
|
||||
cls._empty_hash = sha.hexdigest()
|
||||
return cls._empty_hash
|
||||
# sha = hashlib.sha256()
|
||||
# cls._empty_hash = sha.hexdigest()
|
||||
# return cls._empty_hash
|
||||
|
|
|
|||
16
dist/ba_data/python/baenv.py
vendored
16
dist/ba_data/python/baenv.py
vendored
|
|
@ -52,8 +52,8 @@ if TYPE_CHECKING:
|
|||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21739
|
||||
TARGET_BALLISTICA_VERSION = '1.7.32'
|
||||
TARGET_BALLISTICA_BUILD = 21762
|
||||
TARGET_BALLISTICA_VERSION = '1.7.33'
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -350,9 +350,15 @@ def _setup_paths(
|
|||
# platforms where there is no write access to said built-in
|
||||
# stuff.
|
||||
check_dir = Path(user_python_dir, 'sys', TARGET_BALLISTICA_VERSION)
|
||||
if check_dir.is_dir():
|
||||
app_python_dir = str(check_dir)
|
||||
is_user_app_python_dir = True
|
||||
try:
|
||||
if check_dir.is_dir():
|
||||
app_python_dir = str(check_dir)
|
||||
is_user_app_python_dir = True
|
||||
except PermissionError:
|
||||
logging.warning(
|
||||
"PermissionError checking user-app-python-dir path '%s'.",
|
||||
check_dir,
|
||||
)
|
||||
|
||||
# Ok, now apply these to sys.path.
|
||||
|
||||
|
|
|
|||
2
dist/ba_data/python/baplus/__init__.py
vendored
2
dist/ba_data/python/baplus/__init__.py
vendored
|
|
@ -16,9 +16,11 @@ from __future__ import annotations
|
|||
|
||||
import logging
|
||||
|
||||
from baplus._cloud import CloudSubsystem
|
||||
from baplus._subsystem import PlusSubsystem
|
||||
|
||||
__all__ = [
|
||||
'CloudSubsystem',
|
||||
'PlusSubsystem',
|
||||
]
|
||||
|
||||
|
|
|
|||
214
dist/ba_data/python/baplus/_cloud.py
vendored
Normal file
214
dist/ba_data/python/baplus/_cloud.py
vendored
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Functionality related to the cloud."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, overload
|
||||
|
||||
import babase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Callable, Any
|
||||
|
||||
from efro.message import Message, Response
|
||||
import bacommon.cloud
|
||||
|
||||
DEBUG_LOG = False
|
||||
|
||||
# TODO: Should make it possible to define a protocol in bacommon.cloud and
|
||||
# autogenerate this. That would give us type safety between this and
|
||||
# internal protocols.
|
||||
|
||||
|
||||
class CloudSubsystem(babase.AppSubsystem):
|
||||
"""Manages communication with cloud components."""
|
||||
|
||||
@property
|
||||
def connected(self) -> bool:
|
||||
"""Property equivalent of CloudSubsystem.is_connected()."""
|
||||
return self.is_connected()
|
||||
|
||||
def is_connected(self) -> bool:
|
||||
"""Return whether a connection to the cloud is present.
|
||||
|
||||
This is a good indicator (though not for certain) that sending
|
||||
messages will succeed.
|
||||
"""
|
||||
return False # Needs to be overridden
|
||||
|
||||
def on_connectivity_changed(self, connected: bool) -> None:
|
||||
"""Called when cloud connectivity state changes."""
|
||||
if DEBUG_LOG:
|
||||
logging.debug('CloudSubsystem: Connectivity is now %s.', connected)
|
||||
|
||||
plus = babase.app.plus
|
||||
assert plus is not None
|
||||
|
||||
# Inform things that use this.
|
||||
# (TODO: should generalize this into some sort of registration system)
|
||||
plus.accounts.on_cloud_connectivity_changed(connected)
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.LoginProxyRequestMessage,
|
||||
on_response: Callable[
|
||||
[bacommon.cloud.LoginProxyRequestResponse | Exception], None
|
||||
],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.LoginProxyStateQueryMessage,
|
||||
on_response: Callable[
|
||||
[bacommon.cloud.LoginProxyStateQueryResponse | Exception], None
|
||||
],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.LoginProxyCompleteMessage,
|
||||
on_response: Callable[[None | Exception], None],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.PingMessage,
|
||||
on_response: Callable[[bacommon.cloud.PingResponse | Exception], None],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.SignInMessage,
|
||||
on_response: Callable[
|
||||
[bacommon.cloud.SignInResponse | Exception], None
|
||||
],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: bacommon.cloud.ManageAccountMessage,
|
||||
on_response: Callable[
|
||||
[bacommon.cloud.ManageAccountResponse | Exception], None
|
||||
],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
def send_message_cb(
|
||||
self,
|
||||
msg: Message,
|
||||
on_response: Callable[[Any], None],
|
||||
) -> None:
|
||||
"""Asynchronously send a message to the cloud from the logic thread.
|
||||
|
||||
The provided on_response call will be run in the logic thread
|
||||
and passed either the response or the error that occurred.
|
||||
"""
|
||||
|
||||
del msg # Unused.
|
||||
|
||||
babase.pushcall(
|
||||
babase.Call(
|
||||
on_response,
|
||||
RuntimeError('Cloud functionality is not available.'),
|
||||
)
|
||||
)
|
||||
|
||||
@overload
|
||||
def send_message(
|
||||
self, msg: bacommon.cloud.WorkspaceFetchMessage
|
||||
) -> bacommon.cloud.WorkspaceFetchResponse:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message(
|
||||
self, msg: bacommon.cloud.MerchAvailabilityMessage
|
||||
) -> bacommon.cloud.MerchAvailabilityResponse:
|
||||
...
|
||||
|
||||
@overload
|
||||
def send_message(
|
||||
self, msg: bacommon.cloud.TestMessage
|
||||
) -> bacommon.cloud.TestResponse:
|
||||
...
|
||||
|
||||
def send_message(self, msg: Message) -> Response | None:
|
||||
"""Synchronously send a message to the cloud.
|
||||
|
||||
Must be called from a background thread.
|
||||
"""
|
||||
raise RuntimeError('Cloud functionality is not available.')
|
||||
|
||||
@overload
|
||||
async def send_message_async(
|
||||
self, msg: bacommon.cloud.PromoCodeMessage
|
||||
) -> bacommon.cloud.PromoCodeResponse:
|
||||
...
|
||||
|
||||
@overload
|
||||
async def send_message_async(
|
||||
self, msg: bacommon.cloud.TestMessage
|
||||
) -> bacommon.cloud.TestResponse:
|
||||
...
|
||||
|
||||
async def send_message_async(self, msg: Message) -> Response | None:
|
||||
"""Synchronously send a message to the cloud.
|
||||
|
||||
Must be called from the logic thread.
|
||||
"""
|
||||
raise RuntimeError('Cloud functionality is not available.')
|
||||
|
||||
|
||||
def cloud_console_exec(code: str) -> None:
|
||||
"""Called by the cloud console to run code in the logic thread."""
|
||||
import sys
|
||||
import __main__
|
||||
|
||||
try:
|
||||
# First try it as eval.
|
||||
try:
|
||||
evalcode = compile(code, '<console>', 'eval')
|
||||
except SyntaxError:
|
||||
evalcode = None
|
||||
except Exception:
|
||||
# hmm; when we can't compile it as eval will we always get
|
||||
# syntax error?
|
||||
logging.exception(
|
||||
'unexpected error compiling code for cloud-console eval.'
|
||||
)
|
||||
evalcode = None
|
||||
if evalcode is not None:
|
||||
# pylint: disable=eval-used
|
||||
value = eval(evalcode, vars(__main__), vars(__main__))
|
||||
# For eval-able statements, print the resulting value if
|
||||
# it is not None (just like standard Python interpreter).
|
||||
if value is not None:
|
||||
print(repr(value), file=sys.stderr)
|
||||
|
||||
# Fall back to exec if we couldn't compile it as eval.
|
||||
else:
|
||||
execcode = compile(code, '<console>', 'exec')
|
||||
# pylint: disable=exec-used
|
||||
exec(execcode, vars(__main__), vars(__main__))
|
||||
except Exception:
|
||||
import traceback
|
||||
|
||||
apptime = babase.apptime()
|
||||
print(f'Exec error at time {apptime:.2f}.', file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
|
||||
# This helps the logging system ship stderr back to the
|
||||
# cloud promptly.
|
||||
sys.stderr.flush()
|
||||
9
dist/ba_data/python/baplus/_subsystem.py
vendored
9
dist/ba_data/python/baplus/_subsystem.py
vendored
|
|
@ -5,13 +5,17 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import _baplus
|
||||
from typing_extensions import override
|
||||
from babase import AppSubsystem
|
||||
|
||||
import _baplus
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Callable, Any
|
||||
|
||||
from babase import CloudSubsystem, AccountV2Subsystem
|
||||
from babase import AccountV2Subsystem
|
||||
|
||||
from baplus._cloud import CloudSubsystem
|
||||
|
||||
|
||||
class PlusSubsystem(AppSubsystem):
|
||||
|
|
@ -32,6 +36,7 @@ class PlusSubsystem(AppSubsystem):
|
|||
accounts: AccountV2Subsystem
|
||||
cloud: CloudSubsystem
|
||||
|
||||
@override
|
||||
def on_app_loading(self) -> None:
|
||||
_baplus.on_app_loading()
|
||||
self.accounts.on_app_loading()
|
||||
|
|
|
|||
6
dist/ba_data/python/bascenev1/__init__.py
vendored
6
dist/ba_data/python/bascenev1/__init__.py
vendored
|
|
@ -103,6 +103,7 @@ from _bascenev1 import (
|
|||
host_scan_cycle,
|
||||
InputDevice,
|
||||
is_in_replay,
|
||||
is_replay_paused,
|
||||
ls_input_devices,
|
||||
ls_objects,
|
||||
Material,
|
||||
|
|
@ -112,11 +113,13 @@ from _bascenev1 import (
|
|||
newactivity,
|
||||
newnode,
|
||||
Node,
|
||||
pause_replay,
|
||||
printnodes,
|
||||
protocol_version,
|
||||
release_gamepad_input,
|
||||
release_keyboard_input,
|
||||
reset_random_player_names,
|
||||
resume_replay,
|
||||
broadcastmessage,
|
||||
SessionData,
|
||||
SessionPlayer,
|
||||
|
|
@ -352,6 +355,7 @@ __all__ = [
|
|||
'IntSetting',
|
||||
'is_in_replay',
|
||||
'is_point_in_box',
|
||||
'is_replay_paused',
|
||||
'JoinActivity',
|
||||
'Level',
|
||||
'Lobby',
|
||||
|
|
@ -374,6 +378,7 @@ __all__ = [
|
|||
'normalized_color',
|
||||
'NotFoundError',
|
||||
'OutOfBoundsMessage',
|
||||
'pause_replay',
|
||||
'PickedUpMessage',
|
||||
'PickUpMessage',
|
||||
'Player',
|
||||
|
|
@ -394,6 +399,7 @@ __all__ = [
|
|||
'release_gamepad_input',
|
||||
'release_keyboard_input',
|
||||
'reset_random_player_names',
|
||||
'resume_replay',
|
||||
'safecolor',
|
||||
'screenmessage',
|
||||
'SceneV1AppMode',
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -34,11 +35,13 @@ class EndSessionActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
self.inherits_vr_camera_offset = True
|
||||
self.inherits_vr_overlay_center = True
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
babase.fade_screen(False)
|
||||
babase.lock_all_input()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
|
||||
|
|
@ -77,6 +80,7 @@ class JoinActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
self._tips_text: bascenev1.Actor | None = None
|
||||
self._join_info: JoinInfo | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bascenev1lib.actor.tipstext import TipsText
|
||||
|
|
@ -110,6 +114,7 @@ class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
super().__init__(settings)
|
||||
self._background: bascenev1.Actor | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bascenev1lib.actor.background import Background
|
||||
|
|
@ -119,6 +124,7 @@ class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
fade_time=0.5, start_faded=False, show_logo=False
|
||||
)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -152,6 +158,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
self._custom_continue_message: babase.Lstr | None = None
|
||||
self._server_transitioning: bool | None = None
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: EmptyPlayer) -> None:
|
||||
super().on_player_join(player)
|
||||
time_till_assign = max(
|
||||
|
|
@ -164,6 +171,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
time_till_assign, babase.WeakCall(self._safe_assign, player)
|
||||
)
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
from bascenev1lib.actor.tipstext import TipsText
|
||||
from bascenev1lib.actor.background import Background
|
||||
|
|
@ -176,6 +184,7 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]):
|
|||
self._tips_text = TipsText()
|
||||
setmusic(self.default_music)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bascenev1lib.actor.text import Text
|
||||
|
|
|
|||
21
dist/ba_data/python/bascenev1/_appmode.py
vendored
21
dist/ba_data/python/bascenev1/_appmode.py
vendored
|
|
@ -5,8 +5,15 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
from bacommon.app import AppExperience
|
||||
from babase import AppMode, AppIntentExec, AppIntentDefault
|
||||
from babase import (
|
||||
app,
|
||||
AppMode,
|
||||
AppIntentExec,
|
||||
AppIntentDefault,
|
||||
invoke_main_menu,
|
||||
)
|
||||
|
||||
import _bascenev1
|
||||
|
||||
|
|
@ -17,15 +24,18 @@ if TYPE_CHECKING:
|
|||
class SceneV1AppMode(AppMode):
|
||||
"""Our app-mode."""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_app_experience(cls) -> AppExperience:
|
||||
return AppExperience.MELEE
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def _supports_intent(cls, intent: AppIntent) -> bool:
|
||||
# We support default and exec intents currently.
|
||||
return isinstance(intent, AppIntentExec | AppIntentDefault)
|
||||
|
||||
@override
|
||||
def handle_intent(self, intent: AppIntent) -> None:
|
||||
if isinstance(intent, AppIntentExec):
|
||||
_bascenev1.handle_app_intent_exec(intent.code)
|
||||
|
|
@ -33,10 +43,19 @@ class SceneV1AppMode(AppMode):
|
|||
assert isinstance(intent, AppIntentDefault)
|
||||
_bascenev1.handle_app_intent_default()
|
||||
|
||||
@override
|
||||
def on_activate(self) -> None:
|
||||
# Let the native layer do its thing.
|
||||
_bascenev1.on_app_mode_activate()
|
||||
|
||||
@override
|
||||
def on_deactivate(self) -> None:
|
||||
# Let the native layer do its thing.
|
||||
_bascenev1.on_app_mode_deactivate()
|
||||
|
||||
@override
|
||||
def on_app_active_changed(self) -> None:
|
||||
# If we've gone inactive, bring up the main menu, which has the
|
||||
# side effect of pausing the action (when possible).
|
||||
if not app.active:
|
||||
invoke_main_menu()
|
||||
|
|
|
|||
4
dist/ba_data/python/bascenev1/_coopgame.py
vendored
4
dist/ba_data/python/bascenev1/_coopgame.py
vendored
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -31,6 +32,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
# We can assume our session is a CoopSession.
|
||||
session: bascenev1.CoopSession
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(
|
||||
cls, sessiontype: type[bascenev1.Session]
|
||||
|
|
@ -49,6 +51,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
self._life_warning_beep_timer: bascenev1.Timer | None = None
|
||||
self._warn_beeps_sound = _bascenev1.getsound('warnBeeps')
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -139,6 +142,7 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
)
|
||||
vval -= 55
|
||||
|
||||
@override
|
||||
def spawn_player_spaz(
|
||||
self,
|
||||
player: PlayerT,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -97,6 +98,7 @@ class CoopSession(Session):
|
|||
"""Get the game instance currently being played."""
|
||||
return self._current_game_instance
|
||||
|
||||
@override
|
||||
def should_allow_mid_activity_joins(
|
||||
self, activity: bascenev1.Activity
|
||||
) -> bool:
|
||||
|
|
@ -174,9 +176,11 @@ class CoopSession(Session):
|
|||
|
||||
self._tutorial_activity = _bascenev1.newactivity(TutorialActivity)
|
||||
|
||||
@override
|
||||
def get_custom_menu_entries(self) -> list[dict[str, Any]]:
|
||||
return self._custom_menu_ui
|
||||
|
||||
@override
|
||||
def on_player_leave(self, sessionplayer: bascenev1.SessionPlayer) -> None:
|
||||
super().on_player_leave(sessionplayer)
|
||||
|
||||
|
|
@ -256,6 +260,7 @@ class CoopSession(Session):
|
|||
activity.end(results={'outcome': 'restart'}, force=True)
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
@override
|
||||
def on_activity_end(
|
||||
self, activity: bascenev1.Activity, results: Any
|
||||
) -> None:
|
||||
|
|
|
|||
2
dist/ba_data/python/bascenev1/_dependency.py
vendored
2
dist/ba_data/python/bascenev1/_dependency.py
vendored
|
|
@ -7,6 +7,7 @@ from __future__ import annotations
|
|||
import weakref
|
||||
from typing import Generic, TypeVar, TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -313,6 +314,7 @@ class AssetPackage(DependencyComponent):
|
|||
self.package_id = entry.config
|
||||
print(f'LOADING ASSET PACKAGE {self.package_id}')
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def dep_is_present(cls, config: Any = None) -> bool:
|
||||
assert isinstance(config, str)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -32,6 +33,7 @@ class DualTeamSession(MultiTeamSession):
|
|||
babase.increment_analytics_count('Teams session start')
|
||||
super().__init__()
|
||||
|
||||
@override
|
||||
def _switch_to_score_screen(self, results: bascenev1.GameResults) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bascenev1lib.activity.multiteamvictory import (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -53,6 +54,7 @@ class FreeForAllSession(MultiTeamSession):
|
|||
babase.increment_analytics_count('Free-for-all session start')
|
||||
super().__init__()
|
||||
|
||||
@override
|
||||
def _switch_to_score_screen(self, results: bascenev1.GameResults) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from efro.util import asserttype
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -377,6 +378,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
|
|||
"""
|
||||
return ''
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
|
||||
|
|
@ -488,6 +490,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
|
|||
|
||||
self.end_game()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -536,12 +539,14 @@ class GameActivity(Activity[PlayerT, TeamT]):
|
|||
max(5, data_t[0]['timeRemaining'])
|
||||
)
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: PlayerT) -> None:
|
||||
super().on_player_join(player)
|
||||
|
||||
# By default, just spawn a dude.
|
||||
self.spawn_player(player)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, PlayerDiedMessage):
|
||||
# pylint: disable=cyclic-import
|
||||
|
|
@ -835,6 +840,7 @@ class GameActivity(Activity[PlayerT, TeamT]):
|
|||
animate(combine, 'input3', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
|
||||
_bascenev1.timer(5.0, tnode.delete)
|
||||
|
||||
@override
|
||||
def end(
|
||||
self, results: Any = None, delay: float = 0.0, force: bool = False
|
||||
) -> None:
|
||||
|
|
|
|||
2
dist/ba_data/python/bascenev1/_level.py
vendored
2
dist/ba_data/python/bascenev1/_level.py
vendored
|
|
@ -7,6 +7,7 @@ import copy
|
|||
import weakref
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -38,6 +39,7 @@ class Level:
|
|||
self._index: int | None = None
|
||||
self._score_version_string: str | None = None
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
cls = type(self)
|
||||
return f"<{cls.__module__}.{cls.__name__} '{self._name}'>"
|
||||
|
|
|
|||
2
dist/ba_data/python/bascenev1/_lobby.py
vendored
2
dist/ba_data/python/bascenev1/_lobby.py
vendored
|
|
@ -441,7 +441,7 @@ class Chooser:
|
|||
# list might have changed.
|
||||
input_device = self._sessionplayer.inputdevice
|
||||
is_remote = input_device.is_remote_client
|
||||
is_test_input = input_device.name.startswith('TestInput')
|
||||
is_test_input = input_device.is_test_input
|
||||
|
||||
# Pull this player's list of unlocked characters.
|
||||
if is_remote:
|
||||
|
|
|
|||
3
dist/ba_data/python/bascenev1/_map.py
vendored
3
dist/ba_data/python/bascenev1/_map.py
vendored
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -353,9 +354,11 @@ class Map(Actor):
|
|||
return self.flag_points_default[:3]
|
||||
return self.flag_points[team_index % len(self.flag_points)][:3]
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return bool(self.node)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
from bascenev1 import _messages
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
from bascenev1._session import Session
|
||||
|
||||
|
|
@ -70,6 +72,10 @@ class MultiTeamSession(Session):
|
|||
|
||||
show_tutorial = cfg.get('Show Tutorial', True)
|
||||
|
||||
# Special case: don't show tutorial while stress testing.
|
||||
if classic.stress_test_update_timer is not None:
|
||||
show_tutorial = False
|
||||
|
||||
self._tutorial_activity_instance: bascenev1.Activity | None
|
||||
if show_tutorial:
|
||||
from bascenev1lib.tutorial import TutorialActivity
|
||||
|
|
@ -164,6 +170,7 @@ class MultiTeamSession(Session):
|
|||
"""Returns which game in the series is currently being played."""
|
||||
return self._game_number
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: bascenev1.SessionTeam) -> None:
|
||||
team.customdata['previous_score'] = team.customdata['score'] = 0
|
||||
|
||||
|
|
@ -182,6 +189,7 @@ class MultiTeamSession(Session):
|
|||
self._next_game_spec['settings'],
|
||||
)
|
||||
|
||||
@override
|
||||
def on_activity_end(
|
||||
self, activity: bascenev1.Activity, results: Any
|
||||
) -> None:
|
||||
|
|
|
|||
4
dist/ba_data/python/bascenev1/_nodeactor.py
vendored
4
dist/ba_data/python/bascenev1/_nodeactor.py
vendored
|
|
@ -6,6 +6,8 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from bascenev1._messages import DieMessage
|
||||
from bascenev1._actor import Actor
|
||||
|
||||
|
|
@ -28,6 +30,7 @@ class NodeActor(Actor):
|
|||
super().__init__()
|
||||
self.node = node
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, DieMessage):
|
||||
if self.node:
|
||||
|
|
@ -35,5 +38,6 @@ class NodeActor(Actor):
|
|||
return None
|
||||
return super().handlemessage(msg)
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return bool(self.node)
|
||||
|
|
|
|||
2
dist/ba_data/python/bascenev1/_session.py
vendored
2
dist/ba_data/python/bascenev1/_session.py
vendored
|
|
@ -253,7 +253,7 @@ class Session:
|
|||
# Limit player counts *unless* we're in a stress test.
|
||||
if (
|
||||
babase.app.classic is not None
|
||||
and babase.app.classic.stress_test_reset_timer is None
|
||||
and babase.app.classic.stress_test_update_timer is None
|
||||
):
|
||||
if len(self.sessionplayers) >= self.max_players:
|
||||
# Print a rejection message *only* to the client trying to
|
||||
|
|
|
|||
9
dist/ba_data/python/bascenev1/_teamgame.py
vendored
9
dist/ba_data/python/bascenev1/_teamgame.py
vendored
|
|
@ -7,6 +7,7 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bascenev1
|
||||
|
|
@ -35,6 +36,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
bascenev1.Player has their own bascenev1.Team)
|
||||
"""
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(
|
||||
cls, sessiontype: type[bascenev1.Session]
|
||||
|
|
@ -57,6 +59,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
if isinstance(self.session, FreeForAllSession):
|
||||
self.show_kill_points = False
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=cyclic-import
|
||||
from bascenev1._coopsession import CoopSession
|
||||
|
|
@ -67,7 +70,9 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
# On the first game, show the controls UI momentarily.
|
||||
# (unless we're being run in co-op mode, in which case we leave
|
||||
# it up to them)
|
||||
if not isinstance(self.session, CoopSession):
|
||||
if not isinstance(self.session, CoopSession) and getattr(
|
||||
self, 'show_controls_guide', True
|
||||
):
|
||||
attrname = '_have_shown_ctrl_help_overlay'
|
||||
if not getattr(self.session, attrname, False):
|
||||
delay = 4.0
|
||||
|
|
@ -83,6 +88,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
).autoretain()
|
||||
setattr(self.session, attrname, True)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
try:
|
||||
|
|
@ -102,6 +108,7 @@ class TeamGameActivity(GameActivity[PlayerT, TeamT]):
|
|||
except Exception:
|
||||
logging.exception('Error in on_begin.')
|
||||
|
||||
@override
|
||||
def spawn_player_spaz(
|
||||
self,
|
||||
player: PlayerT,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ class CoopJoinActivity(bs.JoinActivity):
|
|||
session = self.session
|
||||
assert isinstance(session, bs.CoopSession)
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
from bascenev1lib.actor.controlsguide import ControlsGuide
|
||||
from bascenev1lib.actor.text import Text
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
from bacommon.login import LoginType
|
||||
import bascenev1 as bs
|
||||
import bauiv1 as bui
|
||||
|
|
@ -186,6 +187,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||
|
||||
self._victory: bool = settings['outcome'] == 'victory'
|
||||
|
||||
@override
|
||||
def __del__(self) -> None:
|
||||
super().__del__()
|
||||
|
||||
|
|
@ -194,6 +196,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||
with bui.ContextRef.empty():
|
||||
bui.containerwidget(edit=self._root_ui, transition='out_left')
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
from bascenev1lib.actor import background # FIXME NO BSSTD
|
||||
|
||||
|
|
@ -574,6 +577,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||
self._player_press,
|
||||
)
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: bs.Player) -> None:
|
||||
super().on_player_join(player)
|
||||
|
||||
|
|
@ -585,6 +589,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
|
|||
|
||||
bs.timer(time_till_assign, bs.WeakCall(self._safe_assign, player))
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# FIXME: Clean this up.
|
||||
# pylint: disable=too-many-statements
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
|
||||
from bascenev1lib.actor.zoomtext import ZoomText
|
||||
|
||||
|
|
@ -14,6 +16,7 @@ class DrawScoreScreenActivity(MultiTeamScoreScreenActivity):
|
|||
|
||||
default_music = None # Awkward silence...
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
bs.set_analytics_screen('Draw Score Screen')
|
||||
super().on_begin()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
|
||||
from bascenev1lib.actor.zoomtext import ZoomText
|
||||
|
||||
|
|
@ -17,6 +19,7 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
|
|||
self._winner: bs.SessionTeam = settings['winner']
|
||||
assert isinstance(self._winner, bs.SessionTeam)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
bs.set_analytics_screen('Teams Score Screen')
|
||||
super().on_begin()
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -23,6 +25,7 @@ class FreeForAllVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
|
|||
self.transition_time = 0.5
|
||||
self._cymbal_sound = bs.getsound('cymbal')
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.text import Text
|
||||
|
||||
|
||||
|
|
@ -15,6 +17,7 @@ class MultiTeamJoinActivity(bs.JoinActivity):
|
|||
super().__init__(settings)
|
||||
self._next_up_text: Text | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
from bascenev1lib.actor.controlsguide import ControlsGuide
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
"""Functionality related to teams mode score screen."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.text import Text
|
||||
from bascenev1lib.actor.image import Image
|
||||
|
||||
|
|
@ -18,6 +20,7 @@ class MultiTeamScoreScreenActivity(bs.ScoreScreenActivity):
|
|||
|
||||
self._show_up_next: bool = True
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
session = self.session
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.activity.multiteamscore import MultiTeamScoreScreenActivity
|
||||
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ class TeamSeriesVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
|
|||
self._tips_text = None
|
||||
self._default_show_tips = False
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-locals
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import weakref
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -104,6 +105,7 @@ class Background(bs.Actor):
|
|||
timeval += random.random() * 0.1
|
||||
bs.animate(cmb, 'input1', keys, loop=True)
|
||||
|
||||
@override
|
||||
def __del__(self) -> None:
|
||||
# Normal actors don't get sent DieMessages when their
|
||||
# activity is shutting down, but we still need to do so
|
||||
|
|
@ -138,6 +140,7 @@ class Background(bs.Actor):
|
|||
)
|
||||
bs.timer(self.fade_time + 0.1, self.node.delete)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
19
dist/ba_data/python/bascenev1lib/actor/bomb.py
vendored
19
dist/ba_data/python/bascenev1lib/actor/bomb.py
vendored
|
|
@ -10,7 +10,9 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -661,6 +663,7 @@ class Blast(bs.Actor):
|
|||
|
||||
bs.timer(0.4, _extra_debris_sound)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
|
||||
|
|
@ -935,6 +938,7 @@ class Bomb(bs.Actor):
|
|||
else None
|
||||
)
|
||||
|
||||
@override
|
||||
def on_expire(self) -> None:
|
||||
super().on_expire()
|
||||
|
||||
|
|
@ -1140,19 +1144,18 @@ class Bomb(bs.Actor):
|
|||
if msg.srcnode:
|
||||
pass
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, ExplodeMessage):
|
||||
self.explode()
|
||||
elif isinstance(msg, ImpactMessage):
|
||||
self._handle_impact()
|
||||
# Ok the logic below looks like it was backwards to me.
|
||||
# Disabling for now; can bring back if need be.
|
||||
# elif isinstance(msg, bs.PickedUpMessage):
|
||||
# # Change our source to whoever just picked us up *only* if it
|
||||
# # is None. This way we can get points for killing bots with their
|
||||
# # own bombs. Hmm would there be a downside to this?
|
||||
# if self._source_player is not None:
|
||||
# self._source_player = msg.node.source_player
|
||||
elif isinstance(msg, bs.PickedUpMessage):
|
||||
# Change our source to whoever just picked us up *only* if it
|
||||
# is None. This way we can get points for killing bots with their
|
||||
# own bombs. Hmm would there be a downside to this?
|
||||
if self._source_player is None:
|
||||
self._source_player = msg.node.source_player
|
||||
elif isinstance(msg, SplatMessage):
|
||||
self._handle_splat()
|
||||
elif isinstance(msg, bs.DroppedMessage):
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -547,9 +548,11 @@ class ControlsGuide(bs.Actor):
|
|||
self._update_timer = None
|
||||
self._dead = True
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return not self._dead
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ from __future__ import annotations
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
||||
|
|
@ -328,6 +330,7 @@ class Flag(bs.Actor):
|
|||
1.0, bs.WeakCall(self._hide_score_text)
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from __future__ import annotations
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -165,6 +166,7 @@ class Image(bs.Actor):
|
|||
bs.WeakCall(self.handlemessage, bs.DieMessage()),
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -72,6 +73,7 @@ class OnScreenCountdown(bs.Actor):
|
|||
)
|
||||
self._timer = bs.Timer(1.0, self._update, repeat=True)
|
||||
|
||||
@override
|
||||
def on_expire(self) -> None:
|
||||
super().on_expire()
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING
|
||||
import logging
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -93,6 +94,7 @@ class OnScreenTimer(bs.Actor):
|
|||
"""Shortcut for start time in seconds."""
|
||||
return self.getstarttime()
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# if we're asked to die, just kill our node/timer
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, TypeVar, overload
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.spaz import Spaz
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -183,6 +185,7 @@ class PlayerSpaz(Spaz):
|
|||
' non-connected player'
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# FIXME: Tidy this up.
|
||||
# pylint: disable=too-many-branches
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -118,6 +119,7 @@ class PopupText(bs.Actor):
|
|||
lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage())
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -278,6 +280,7 @@ class PowerupBox(bs.Actor):
|
|||
if self.node:
|
||||
self.node.flashing = True
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.bomb import Bomb, Blast
|
||||
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
|
||||
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence, Callable
|
||||
|
|
@ -228,9 +230,11 @@ class Spaz(bs.Actor):
|
|||
self.punch_callback: Callable[[Spaz], Any] | None = None
|
||||
self.pick_up_powerup_callback: Callable[[Spaz], Any] | None = None
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return bool(self.node)
|
||||
|
||||
@override
|
||||
def on_expire(self) -> None:
|
||||
super().on_expire()
|
||||
|
||||
|
|
@ -249,6 +253,7 @@ class Spaz(bs.Actor):
|
|||
assert not self.expired
|
||||
self._dropped_bomb_callbacks.append(call)
|
||||
|
||||
@override
|
||||
def is_alive(self) -> bool:
|
||||
"""
|
||||
Method override; returns whether ol' spaz is still kickin'.
|
||||
|
|
@ -694,6 +699,7 @@ class Spaz(bs.Actor):
|
|||
else:
|
||||
self.shield_decay_timer = None
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# pylint: disable=too-many-return-statements
|
||||
# pylint: disable=too-many-statements
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import weakref
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
from bascenev1lib.actor.spaz import Spaz
|
||||
|
||||
|
|
@ -489,6 +490,7 @@ class SpazBot(Spaz):
|
|||
self.on_punch_press()
|
||||
self.on_punch_release()
|
||||
|
||||
@override
|
||||
def on_punched(self, damage: int) -> None:
|
||||
"""
|
||||
Method override; sends bs.SpazBotPunchedMessage
|
||||
|
|
@ -496,6 +498,7 @@ class SpazBot(Spaz):
|
|||
"""
|
||||
bs.getactivity().handlemessage(SpazBotPunchedMessage(self, damage))
|
||||
|
||||
@override
|
||||
def on_expire(self) -> None:
|
||||
super().on_expire()
|
||||
|
||||
|
|
@ -503,6 +506,7 @@ class SpazBot(Spaz):
|
|||
# no chance of them keeping activities or other things alive.
|
||||
self.update_callback = None
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# pylint: disable=too-many-branches
|
||||
assert not self.expired
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from __future__ import annotations
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -221,6 +222,7 @@ class Text(bs.Actor):
|
|||
bs.WeakCall(self.handlemessage, bs.DieMessage()),
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -95,6 +96,7 @@ class TipsText(bs.Actor):
|
|||
)
|
||||
self.node.text = next_tip
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -158,6 +159,7 @@ class ZoomText(bs.Actor):
|
|||
if lifespan is not None:
|
||||
bs.timer(lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
assert not self.expired
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
|
|
|
|||
13
dist/ba_data/python/bascenev1lib/game/assault.py
vendored
13
dist/ba_data/python/bascenev1lib/game/assault.py
vendored
|
|
@ -10,11 +10,13 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.flag import Flag
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -71,10 +73,12 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -96,16 +100,19 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FORWARD_MARCH
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'Touch the enemy flag.'
|
||||
return 'Touch the enemy flag ${ARG1} times.', self._score_to_win
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'touch 1 flag'
|
||||
return 'touch ${ARG1} flags', self._score_to_win
|
||||
|
||||
@override
|
||||
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||
shared = SharedObjects.get()
|
||||
base_pos = self.map.get_flag_position(sessionteam.id)
|
||||
|
|
@ -151,16 +158,19 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
|
|||
|
||||
return team
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
# Can't do this in create_team because the team's color/etc. have
|
||||
# not been wired up yet at that point.
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
self.setup_standard_powerup_drops()
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
super().handlemessage(msg) # Augment standard.
|
||||
|
|
@ -249,6 +259,7 @@ class AssaultGame(bs.TeamGameActivity[Player, Team]):
|
|||
if player_team.score >= self._score_to_win:
|
||||
self.end_game()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.flag import (
|
||||
|
|
@ -19,7 +22,6 @@ from bascenev1lib.actor.flag import (
|
|||
FlagDroppedMessage,
|
||||
FlagDiedMessage,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -141,10 +143,12 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -173,16 +177,19 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FLAG_CATCHER
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'Steal the enemy flag.'
|
||||
return 'Steal the enemy flag ${ARG1} times.', self._score_to_win
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'return 1 flag'
|
||||
return 'return ${ARG1} flags', self._score_to_win
|
||||
|
||||
@override
|
||||
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||
# Create our team instance and its initial values.
|
||||
|
||||
|
|
@ -272,12 +279,14 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
|
||||
return team
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
# Can't do this in create_team because the team's color/etc. have
|
||||
# not been wired up yet at that point.
|
||||
self._spawn_flag_for_team(team)
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
|
@ -406,6 +415,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
if team.score >= self._score_to_win:
|
||||
self.end_game()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -532,6 +542,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.animate(light, 'intensity', {0.0: 0, 0.25: 2.0, 0.5: 0}, loop=True)
|
||||
bs.timer(length, light.delete)
|
||||
|
||||
@override
|
||||
def spawn_player_spaz(
|
||||
self,
|
||||
player: Player,
|
||||
|
|
@ -576,6 +587,7 @@ class CaptureTheFlagGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.score, self._score_to_win
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
super().handlemessage(msg) # Augment standard behavior.
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.flag import Flag
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -83,6 +85,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
|
|||
]
|
||||
scoreconfig = bs.ScoreConfig(label='Time Held')
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -121,20 +124,25 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.CHOSEN_ONE
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'There can be only one.'
|
||||
|
||||
@override
|
||||
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||
return Team(time_remaining=self._chosen_one_time)
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
super().on_player_leave(player)
|
||||
if self._get_chosen_one_player() is player:
|
||||
self._set_chosen_one_player(None)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
shared = SharedObjects.get()
|
||||
|
|
@ -251,6 +259,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
|
|||
logging.error('got nonexistent player as chosen one in _tick')
|
||||
self._set_chosen_one_player(None)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -335,6 +344,7 @@ class ChosenOneGame(bs.TeamGameActivity[Player, Team]):
|
|||
'position', light.node, 'position'
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.flag import Flag
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
from bascenev1lib.actor.respawnicon import RespawnIcon
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -108,10 +110,12 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -143,16 +147,20 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
),
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'Secure all ${ARG1} flags.', len(self.map.flag_points)
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return 'secure all ${ARG1} flags', len(self.map.flag_points)
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
if self.has_begun():
|
||||
self._update_scores()
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: Player) -> None:
|
||||
player.respawn_timer = None
|
||||
|
||||
|
|
@ -160,6 +168,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
if player.team.flags_held > 0:
|
||||
self.spawn_player(player)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
|
@ -221,6 +230,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.flags_held, len(self._flags)
|
||||
)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -272,6 +282,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
):
|
||||
self.spawn_player(otherplayer)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
@ -287,6 +298,7 @@ class ConquestGame(bs.TeamGameActivity[Player, Team]):
|
|||
else:
|
||||
super().handlemessage(msg)
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
# We spawn players at different places based on what flags are held.
|
||||
return self.spawn_player_spaz(
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -38,6 +40,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
|
|||
# Print messages when players die since it matters here.
|
||||
announce_player_deaths = True
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[bs.Session]
|
||||
|
|
@ -87,12 +90,14 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
|
|||
|
||||
return settings
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
|
||||
sessiontype, bs.FreeForAllSession
|
||||
)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -116,16 +121,20 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.TO_THE_DEATH
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'Crush ${ARG1} of your enemies.', self._score_to_win
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return 'kill ${ARG1} enemies', self._score_to_win
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
if self.has_begun():
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
|
@ -137,6 +146,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
|
|||
)
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
@ -197,6 +207,7 @@ class DeathMatchGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.score, self._score_to_win
|
||||
)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.bomb import Bomb
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.spazbot import SpazBotSet, BouncyBot, SpazBotDiedMessage
|
||||
|
|
@ -17,7 +20,6 @@ from bascenev1lib.actor.onscreencountdown import OnScreenCountdown
|
|||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.respawnicon import RespawnIcon
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
|
@ -51,11 +53,13 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
|
|||
scoreconfig = bs.ScoreConfig(label='Score', scoretype=bs.ScoreType.POINTS)
|
||||
|
||||
# We're currently hard-coded for one map.
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
return ['Tower D']
|
||||
|
||||
# We support teams, free-for-all, and co-op sessions.
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return (
|
||||
|
|
@ -93,11 +97,13 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FORWARD_MARCH
|
||||
)
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
if self.has_begun():
|
||||
self._update_scoreboard()
|
||||
|
||||
# Called when our game actually starts.
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
from bascenev1lib.maps import TowerD
|
||||
|
||||
|
|
@ -118,6 +124,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._spawn_evil_bunny()
|
||||
|
||||
# Overriding the default character spawning.
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
spaz = self.spawn_player_spaz(player)
|
||||
spaz.connect_controls_to_player()
|
||||
|
|
@ -191,6 +198,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._eggs.append(Egg(position=(xpos, ypos, zpos)))
|
||||
|
||||
# Various high-level game events come through this method.
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# Respawn dead players.
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
|
@ -231,6 +239,7 @@ class EasterEggHuntGame(bs.TeamGameActivity[Player, Team]):
|
|||
for team in self.teams:
|
||||
self._scoreboard.set_team_value(team, team.score)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -271,9 +280,11 @@ class Egg(bs.Actor):
|
|||
},
|
||||
)
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return bool(self.node)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
if self.node:
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -157,6 +159,7 @@ class Icon(bs.Actor):
|
|||
if lives == 0:
|
||||
bs.timer(0.6, self.update_for_lives)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
self.node.delete()
|
||||
|
|
@ -194,6 +197,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
|
||||
allow_mid_activity_joins = False
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[bs.Session]
|
||||
|
|
@ -238,12 +242,14 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
)
|
||||
return settings
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
|
||||
sessiontype, bs.FreeForAllSession
|
||||
)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -269,6 +275,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SURVIVAL
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return (
|
||||
'Last team standing wins.'
|
||||
|
|
@ -276,6 +283,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
else 'Last one standing wins.'
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return (
|
||||
'last team standing wins'
|
||||
|
|
@ -283,6 +291,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
else 'last one standing wins'
|
||||
)
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: Player) -> None:
|
||||
player.lives = self._lives_per_player
|
||||
|
||||
|
|
@ -299,6 +308,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
if self.has_begun():
|
||||
self._update_icons()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self._start_time = bs.time()
|
||||
|
|
@ -473,6 +483,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
return points[-1][1]
|
||||
return None
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
actor = self.spawn_player_spaz(player, self._get_spawn_point(player))
|
||||
if not self._solo_mode:
|
||||
|
|
@ -499,6 +510,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
position=player.node.position,
|
||||
).autoretain()
|
||||
|
||||
@override
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
super().on_player_leave(player)
|
||||
player.icons = []
|
||||
|
|
@ -522,6 +534,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
def _get_total_team_lives(self, team: Team) -> int:
|
||||
return sum(player.lives for player in team.players)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
@ -592,6 +605,7 @@ class EliminationGame(bs.TeamGameActivity[Player, Team]):
|
|||
and any(player.lives > 0 for player in team.players)
|
||||
]
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
if self.has_ended():
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
# pylint: disable=too-many-lines
|
||||
"""Implements football games (both co-op and teams varieties)."""
|
||||
|
||||
# ba_meta require api 8
|
||||
|
|
@ -12,6 +13,9 @@ import random
|
|||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.bomb import TNTSpawner
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
|
|
@ -39,7 +43,6 @@ from bascenev1lib.actor.spazbot import (
|
|||
StickyBot,
|
||||
ExplodeyBot,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -128,11 +131,13 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
# We only support two-team play.
|
||||
return issubclass(sessiontype, bs.DualTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -170,6 +175,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.FOOTBALL
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
touchdowns = self._score_to_win / 7
|
||||
|
||||
|
|
@ -181,6 +187,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
return 'Score ${ARG1} touchdowns.', touchdowns
|
||||
return 'Score a touchdown.'
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
touchdowns = self._score_to_win / 7
|
||||
touchdowns = math.ceil(touchdowns)
|
||||
|
|
@ -188,6 +195,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
return 'score ${ARG1} touchdowns', touchdowns
|
||||
return 'score a touchdown'
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
|
@ -224,6 +232,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._update_scoreboard()
|
||||
self._chant_sound.play()
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
self._update_scoreboard()
|
||||
|
||||
|
|
@ -285,6 +294,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.cameraflash(duration=10.0)
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -298,6 +308,7 @@ class FootballTeamGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.score, self._score_to_win
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, FlagPickedUpMessage):
|
||||
assert isinstance(msg.flag, FootballFlag)
|
||||
|
|
@ -379,9 +390,11 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
default_music = bs.MusicType.FOOTBALL
|
||||
|
||||
# FIXME: Need to update co-op games to use getscoreconfig.
|
||||
@override
|
||||
def get_score_type(self) -> str:
|
||||
return 'time'
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
touchdowns = self._score_to_win / 7
|
||||
touchdowns = math.ceil(touchdowns)
|
||||
|
|
@ -389,6 +402,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
return 'Score ${ARG1} touchdowns.', touchdowns
|
||||
return 'Score a touchdown.'
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
touchdowns = self._score_to_win / 7
|
||||
touchdowns = math.ceil(touchdowns)
|
||||
|
|
@ -444,6 +458,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
self._flag_respawn_light: bs.Actor | None = None
|
||||
self._flag: FootballFlag | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
self._scoreboard = Scoreboard()
|
||||
|
|
@ -480,6 +495,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
)
|
||||
self._chant_sound.play()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
# FIXME: Split this up a bit.
|
||||
# pylint: disable=too-many-statements
|
||||
|
|
@ -795,11 +811,13 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
if i == 0:
|
||||
bs.cameraflash(duration=10.0)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
bs.setmusic(None)
|
||||
self._bots.final_celebrate()
|
||||
bs.timer(0.001, bs.Call(self.do_end, 'defeat'))
|
||||
|
||||
@override
|
||||
def on_continue(self) -> None:
|
||||
# Subtract one touchdown from the bots and get them moving again.
|
||||
assert self._bot_team is not None
|
||||
|
|
@ -897,6 +915,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
},
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
"""handle high-level game messages"""
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
|
@ -959,6 +978,7 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
|
|||
del player # Unused.
|
||||
self._player_has_punched = True
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
spaz = self.spawn_player_spaz(
|
||||
player, position=self.map.get_start_position(player.team.id)
|
||||
|
|
|
|||
13
dist/ba_data/python/bascenev1lib/game/hockey.py
vendored
13
dist/ba_data/python/bascenev1lib/game/hockey.py
vendored
|
|
@ -9,11 +9,13 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -58,6 +60,7 @@ class Puck(bs.Actor):
|
|||
)
|
||||
bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1})
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
if self.node:
|
||||
|
|
@ -152,10 +155,12 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.BoolSetting('Epic Mode', default=False),
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -231,16 +236,19 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.HOCKEY
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'Score a goal.'
|
||||
return 'Score ${ARG1} goals.', self._score_to_win
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
if self._score_to_win == 1:
|
||||
return 'score a goal'
|
||||
return 'score ${ARG1} goals', self._score_to_win
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -281,6 +289,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._update_scoreboard()
|
||||
self._chant_sound.play()
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
self._update_scoreboard()
|
||||
|
||||
|
|
@ -364,6 +373,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.cameraflash(duration=10.0)
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -375,6 +385,7 @@ class HockeyGame(bs.TeamGameActivity[Player, Team]):
|
|||
for team in self.teams:
|
||||
self._scoreboard.set_team_value(team, team.score, winscore)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# Respawn dead players if they're still in the game.
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import logging
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.flag import (
|
||||
|
|
@ -19,7 +22,6 @@ from bascenev1lib.actor.flag import (
|
|||
FlagDiedMessage,
|
||||
FlagPickedUpMessage,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -86,12 +88,14 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
|
|||
]
|
||||
scoreconfig = bs.ScoreConfig(label='Time Held')
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
|
||||
sessiontype, bs.FreeForAllSession
|
||||
)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -129,18 +133,23 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.KEEP_AWAY
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'Carry the flag for ${ARG1} seconds.', self._hold_time
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return 'carry the flag for ${ARG1} seconds', self._hold_time
|
||||
|
||||
@override
|
||||
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||
return Team(timeremaining=self._hold_time)
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.setup_standard_time_limit(self._time_limit)
|
||||
|
|
@ -181,6 +190,7 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
|
|||
if scoreteam.timeremaining <= 0:
|
||||
self.end_game()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -268,6 +278,7 @@ class KeepAwayGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.timeremaining, self._hold_time, countdown=True
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ import weakref
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.flag import Flag
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -84,10 +86,12 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
|
|||
]
|
||||
scoreconfig = bs.ScoreConfig(label='Time Held')
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.MultiTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -144,15 +148,19 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SCARY
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
return 'Secure the flag for ${ARG1} seconds.', self._hold_time
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
return 'secure the flag for ${ARG1} seconds', self._hold_time
|
||||
|
||||
@override
|
||||
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||
return Team(time_remaining=self._hold_time)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
shared = SharedObjects.get()
|
||||
|
|
@ -223,6 +231,7 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
|
|||
if scoring_team.time_remaining <= 0:
|
||||
self.end_game()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -283,6 +292,7 @@ class KingOfTheHillGame(bs.TeamGameActivity[Player, Team]):
|
|||
team, team.time_remaining, self._hold_time, countdown=True
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
super().handlemessage(msg) # Augment default.
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.bomb import Bomb
|
||||
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -49,11 +51,13 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
allow_mid_activity_joins = False
|
||||
|
||||
# We're currently hard-coded for one map.
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
return ['Rampage']
|
||||
|
||||
# We support teams, free-for-all, and co-op sessions.
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return (
|
||||
|
|
@ -77,6 +81,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
if self._epic_mode:
|
||||
self.slow_motion = True
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -100,6 +105,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
# Check for immediate end (if we've only got 1 player, etc).
|
||||
bs.timer(5.0, self._check_end_game)
|
||||
|
||||
@override
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
# Augment default behavior.
|
||||
super().on_player_leave(player)
|
||||
|
|
@ -108,6 +114,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._check_end_game()
|
||||
|
||||
# overriding the default character spawning..
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
spaz = self.spawn_player_spaz(player)
|
||||
|
||||
|
|
@ -122,6 +129,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
return spaz
|
||||
|
||||
# Various high-level game events come through this method.
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment standard behavior.
|
||||
|
|
@ -213,6 +221,7 @@ class MeteorShowerGame(bs.TeamGameActivity[Player, Team]):
|
|||
def _decrement_meteor_time(self) -> None:
|
||||
self._meteor_time = max(0.01, self._meteor_time * 0.9)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
cur_time = bs.time()
|
||||
assert self._timer is not None
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.spazbot import (
|
||||
SpazBotSet,
|
||||
ChargerBot,
|
||||
SpazBotDiedMessage,
|
||||
)
|
||||
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
|
@ -44,6 +46,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
)
|
||||
default_music = bs.MusicType.TO_THE_DEATH
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
# For now we're hard-coding spawn positions and whatnot
|
||||
|
|
@ -51,6 +54,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
# a specific map.
|
||||
return ['Courtyard']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
# We currently support Co-Op only.
|
||||
|
|
@ -67,6 +71,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._preset = str(settings['preset'])
|
||||
|
||||
# Called when our game actually begins.
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
is_pro = self._preset == 'pro'
|
||||
|
|
@ -123,6 +128,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
)
|
||||
|
||||
# Called for each spawning player.
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
# Let's spawn close to the center.
|
||||
spawn_center = (0, 3, -2)
|
||||
|
|
@ -144,6 +150,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
self.end_game()
|
||||
|
||||
# Called for miscellaneous messages.
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# A player has died.
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
|
@ -166,6 +173,7 @@ class NinjaFightGame(bs.TeamGameActivity[Player, Team]):
|
|||
# When this is called, we should fill out results and end the game
|
||||
# *regardless* of whether is has been won. (this may be called due
|
||||
# to a tournament ending or other external reason).
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
# Stop our on-screen timer so players can see what they got.
|
||||
assert self._timer is not None
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ from enum import Enum, unique
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.popuptext import PopupText
|
||||
from bascenev1lib.actor.bomb import TNTSpawner
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpazHurtMessage
|
||||
|
|
@ -45,7 +48,6 @@ from bascenev1lib.actor.spazbot import (
|
|||
BrawlerBotPro,
|
||||
BomberBotProShielded,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -222,6 +224,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
self._land_mine_kills = 0
|
||||
self._tnt_kills = 0
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
customdata = bs.getsession().customdata
|
||||
|
|
@ -286,6 +289,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
label=bs.Lstr(resource='scoreText'), score_split=0.5
|
||||
)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
player_count = len(self.players)
|
||||
|
|
@ -825,6 +829,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
break
|
||||
entry_count += 1
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
# We keep track of who got hurt each wave for score purposes.
|
||||
player.has_been_hurt = False
|
||||
|
|
@ -1414,6 +1419,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
assert self._scoreboard is not None
|
||||
self._scoreboard.set_team_value(self.teams[0], score, max_score=None)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, PlayerSpazHurtMessage):
|
||||
msg.spaz.getplayer(Player, True).has_been_hurt = True
|
||||
|
|
@ -1526,6 +1532,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
def _set_can_end_wave(self) -> None:
|
||||
self._can_end_wave = True
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
# Tell our bots to celebrate just to rub it in.
|
||||
assert self._bots is not None
|
||||
|
|
@ -1534,6 +1541,7 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
|
|||
self.do_end('defeat', delay=2.0)
|
||||
bs.setmusic(None)
|
||||
|
||||
@override
|
||||
def on_continue(self) -> None:
|
||||
for player in self.players:
|
||||
if not player.is_alive():
|
||||
|
|
|
|||
16
dist/ba_data/python/bascenev1lib/game/race.py
vendored
16
dist/ba_data/python/bascenev1lib/game/race.py
vendored
|
|
@ -12,11 +12,13 @@ import logging
|
|||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.bomb import Bomb
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -84,6 +86,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
label='Time', lower_is_better=True, scoretype=bs.ScoreType.MILLISECONDS
|
||||
)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_available_settings(
|
||||
cls, sessiontype: type[bs.Session]
|
||||
|
|
@ -133,10 +136,12 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
)
|
||||
return settings
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
return issubclass(sessiontype, bs.MultiTeamSession)
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
assert bs.app.classic is not None
|
||||
|
|
@ -179,6 +184,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
bs.MusicType.EPIC_RACE if self._epic_mode else bs.MusicType.RACE
|
||||
)
|
||||
|
||||
@override
|
||||
def get_instance_description(self) -> str | Sequence:
|
||||
if (
|
||||
isinstance(self.session, bs.DualTeamSession)
|
||||
|
|
@ -192,11 +198,13 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
return 'Run ${ARG1} laps.' + t_str, self._laps
|
||||
return 'Run 1 lap.' + t_str
|
||||
|
||||
@override
|
||||
def get_instance_description_short(self) -> str | Sequence:
|
||||
if self._laps > 1:
|
||||
return 'run ${ARG1} laps', self._laps
|
||||
return 'run 1 lap'
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
shared = SharedObjects.get()
|
||||
|
|
@ -379,9 +387,11 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
except Exception:
|
||||
logging.exception('Error printing lap.')
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
self._update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
super().on_player_leave(player)
|
||||
|
||||
|
|
@ -442,6 +452,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
show_value=False,
|
||||
)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||
|
||||
|
|
@ -670,6 +681,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._flash_mine(m_index)
|
||||
bs.timer(0.95, bs.Call(self._make_mine, m_index))
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
if player.team.finished:
|
||||
# FIXME: This is not type-safe!
|
||||
|
|
@ -758,6 +770,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
self.end_game()
|
||||
return
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
# Stop updating our time text, and set it to show the exact last
|
||||
# finish time if we have one. (so users don't get upset if their
|
||||
|
|
@ -787,6 +800,7 @@ class RaceGame(bs.TeamGameActivity[Player, Team]):
|
|||
announce_winning_team=isinstance(self.session, bs.DualTeamSession),
|
||||
)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
# Augment default behavior.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ from enum import Enum
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.popuptext import PopupText
|
||||
from bascenev1lib.actor.bomb import TNTSpawner
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
|
|
@ -40,7 +43,6 @@ from bascenev1lib.actor.spazbot import (
|
|||
BomberBotPro,
|
||||
BrawlerBotPro,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -194,6 +196,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
self._flawless_bonus: int | None = None
|
||||
self._wave_update_timer: bs.Timer | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
self._scoreboard = Scoreboard(
|
||||
|
|
@ -211,6 +214,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
)
|
||||
)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
player_count = len(self.players)
|
||||
|
|
@ -571,6 +575,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
),
|
||||
)
|
||||
|
||||
@override
|
||||
def on_continue(self) -> None:
|
||||
self._lives = 3
|
||||
assert self._lives_text is not None
|
||||
|
|
@ -578,6 +583,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
self._lives_text.node.text = str(self._lives)
|
||||
self._bots.start_moving()
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
pos = (
|
||||
self._spawn_center[0] + random.uniform(-1.5, 1.5),
|
||||
|
|
@ -654,6 +660,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
),
|
||||
).autoretain()
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
bs.pushcall(bs.Call(self.do_end, 'defeat'))
|
||||
bs.setmusic(None)
|
||||
|
|
@ -1286,6 +1293,7 @@ class RunaroundGame(bs.CoopGameActivity[Player, Team]):
|
|||
# Revert to normal bot behavior otherwise..
|
||||
return False
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerScoredMessage):
|
||||
self._score += msg.score
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@ from __future__ import annotations
|
|||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
from bascenev1lib.actor.onscreencountdown import OnScreenCountdown
|
||||
from bascenev1lib.actor.bomb import Bomb
|
||||
from bascenev1lib.actor.popuptext import PopupText
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -49,10 +51,12 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
|
|||
]
|
||||
default_music = bs.MusicType.FORWARD_MARCH
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||
return ['Doom Shroom']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||
# We support any teams or versus sessions.
|
||||
|
|
@ -70,10 +74,12 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._enable_impact_bombs = bool(settings['Enable Impact Bombs'])
|
||||
self._enable_triple_bombs = bool(settings['Enable Triple Bombs'])
|
||||
|
||||
@override
|
||||
def on_team_join(self, team: Team) -> None:
|
||||
if self.has_begun():
|
||||
self.update_scoreboard()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
self.update_scoreboard()
|
||||
|
|
@ -86,6 +92,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
|
|||
self._countdown = OnScreenCountdown(60, endcall=self.end_game)
|
||||
bs.timer(4.0, self._countdown.start)
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
spawn_center = (0, 3, -5)
|
||||
pos = (
|
||||
|
|
@ -169,6 +176,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
|
|||
# Clear out targets that have died.
|
||||
self._targets = [t for t in self._targets if t]
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
# When players die, respawn them.
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
|
|
@ -188,6 +196,7 @@ class TargetPracticeGame(bs.TeamGameActivity[Player, Team]):
|
|||
for team in self.teams:
|
||||
self._scoreboard.set_team_value(team, team.score)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
results = bs.GameResults()
|
||||
for team in self.teams:
|
||||
|
|
@ -252,9 +261,11 @@ class Target(bs.Actor):
|
|||
bs.animate_array(loc3, 'size', 1, {0.1: [0.0], 0.3: [self._r3 * 2.0]})
|
||||
bs.getsound('laserReverse').play()
|
||||
|
||||
@override
|
||||
def exists(self) -> bool:
|
||||
return bool(self._nodes)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.DieMessage):
|
||||
for node in self._nodes:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import logging
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||
from bascenev1lib.actor.bomb import TNTSpawner
|
||||
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||
|
|
@ -29,7 +32,6 @@ from bascenev1lib.actor.spazbot import (
|
|||
StickyBot,
|
||||
ExplodeyBot,
|
||||
)
|
||||
import bascenev1 as bs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
|
|
@ -109,6 +111,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
|
|||
ExplodeyBot: SpawnInfo(0.05, 0.02, 0.002),
|
||||
}
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
bs.timer(1.3, self._new_wave_sound.play)
|
||||
|
|
@ -116,6 +119,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
|
|||
label=bs.Lstr(resource='scoreText'), score_split=0.5
|
||||
)
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -129,6 +133,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
|
|||
position=self._tntspawnpos, respawn_time=10.0
|
||||
)
|
||||
|
||||
@override
|
||||
def spawn_player(self, player: Player) -> bs.Actor:
|
||||
pos = (
|
||||
self._spawn_center[0] + random.uniform(-1.5, 1.5),
|
||||
|
|
@ -290,6 +295,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
|
|||
assert self._scoreboard is not None
|
||||
self._scoreboard.set_team_value(self.teams[0], score, max_score=None)
|
||||
|
||||
@override
|
||||
def handlemessage(self, msg: Any) -> Any:
|
||||
if isinstance(msg, bs.PlayerDiedMessage):
|
||||
player = msg.getplayer(Player)
|
||||
|
|
@ -327,6 +333,7 @@ class TheLastStandGame(bs.CoopGameActivity[Player, Team]):
|
|||
else:
|
||||
super().handlemessage(msg)
|
||||
|
||||
@override
|
||||
def end_game(self) -> None:
|
||||
# Tell our bots to celebrate just to rub it in.
|
||||
self._bots.final_celebrate()
|
||||
|
|
|
|||
34
dist/ba_data/python/bascenev1lib/mainmenu.py
vendored
34
dist/ba_data/python/bascenev1lib/mainmenu.py
vendored
|
|
@ -10,6 +10,7 @@ import random
|
|||
import weakref
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
import bauiv1 as bui
|
||||
|
||||
|
|
@ -42,7 +43,9 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
self._language: str | None = None
|
||||
self._update_timer: bs.Timer | None = None
|
||||
self._news: NewsDisplay | None = None
|
||||
self._attract_mode_timer: bs.Timer | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
|
|
@ -83,7 +86,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
'scale': scale,
|
||||
'position': (0, 10),
|
||||
'vr_depth': -10,
|
||||
'text': '\xa9 2011-2023 Eric Froemling',
|
||||
'text': '\xa9 2011-2024 Eric Froemling',
|
||||
},
|
||||
)
|
||||
)
|
||||
|
|
@ -295,6 +298,10 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
if not (env.demo or env.arcade) and not app.ui_v1.use_toolbars:
|
||||
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
|
||||
|
|
@ -387,7 +394,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
|
||||
bs.app.ui_v1.set_main_menu_window(
|
||||
MainMenuWindow(transition=None).get_root_widget(),
|
||||
from_window=None,
|
||||
from_window=False, # Disable check here.
|
||||
)
|
||||
|
||||
# attempt to show any pending offers immediately.
|
||||
|
|
@ -403,6 +410,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
bui.apptimer(2.0, specialoffer.show_offer)
|
||||
|
||||
bui.apptimer(2.0, try_again)
|
||||
|
||||
app.classic.main_menu_did_initial_transition = True
|
||||
|
||||
def _update(self) -> None:
|
||||
|
|
@ -836,6 +844,26 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
|
|||
|
||||
bui.apptimer(0.5, _start_menu_music)
|
||||
|
||||
def _update_attract_mode(self) -> None:
|
||||
if bui.app.classic is None:
|
||||
return
|
||||
|
||||
if not bui.app.config.resolve('Show Demos When Idle'):
|
||||
return
|
||||
|
||||
threshold = 20.0
|
||||
|
||||
# If we're idle *and* have been in this activity for that long,
|
||||
# flip over to our cpu demo.
|
||||
if bui.get_input_idle_time() > threshold and bs.time() > threshold:
|
||||
bui.app.classic.run_stress_test(
|
||||
playlist_type='Random',
|
||||
playlist_name='__default__',
|
||||
player_count=8,
|
||||
round_duration=20,
|
||||
attract_mode=True,
|
||||
)
|
||||
|
||||
|
||||
class NewsDisplay:
|
||||
"""Wrangles news display."""
|
||||
|
|
@ -1113,6 +1141,7 @@ class MainMenuSession(bs.Session):
|
|||
self._locked = False
|
||||
self.setactivity(bs.newactivity(MainMenuActivity))
|
||||
|
||||
@override
|
||||
def on_activity_end(self, activity: bs.Activity, results: Any) -> None:
|
||||
if self._locked:
|
||||
bui.unlock_all_input()
|
||||
|
|
@ -1120,6 +1149,7 @@ class MainMenuSession(bs.Session):
|
|||
# Any ending activity leads us into the main menu one.
|
||||
self.setactivity(bs.newactivity(MainMenuActivity))
|
||||
|
||||
@override
|
||||
def on_player_request(self, player: bs.SessionPlayer) -> bool:
|
||||
# Reject all player requests.
|
||||
return False
|
||||
|
|
|
|||
59
dist/ba_data/python/bascenev1lib/maps.py
vendored
59
dist/ba_data/python/bascenev1lib/maps.py
vendored
|
|
@ -7,7 +7,9 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.gameutils import SharedObjects
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -22,15 +24,18 @@ class HockeyStadium(bs.Map):
|
|||
|
||||
name = 'Hockey Stadium'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'hockey', 'team_flag', 'keep_away']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'hockeyStadiumPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -114,15 +119,18 @@ class FootballStadium(bs.Map):
|
|||
|
||||
name = 'Football Stadium'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'football', 'team_flag', 'keep_away']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'footballStadiumPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -164,6 +172,7 @@ class FootballStadium(bs.Map):
|
|||
gnode.vr_camera_offset = (0, -0.8, -1.1)
|
||||
gnode.vr_near_clip = 0.5
|
||||
|
||||
@override
|
||||
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
|
||||
box_position = self.defs.boxes['edge_box'][0:3]
|
||||
box_scale = self.defs.boxes['edge_box'][6:9]
|
||||
|
|
@ -181,16 +190,19 @@ class Bridgit(bs.Map):
|
|||
name = 'Bridgit'
|
||||
dataname = 'bridgit'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
# print('getting playtypes', cls._getdata()['play_types'])
|
||||
return ['melee', 'team_flag', 'keep_away']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'bridgitPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -286,6 +298,7 @@ class BigG(bs.Map):
|
|||
|
||||
name = 'Big G'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
|
|
@ -298,10 +311,12 @@ class BigG(bs.Map):
|
|||
'conquest',
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'bigGPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -397,15 +412,18 @@ class Roundabout(bs.Map):
|
|||
|
||||
name = 'Roundabout'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'roundaboutPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -502,15 +520,18 @@ class MonkeyFace(bs.Map):
|
|||
|
||||
name = 'Monkey Face'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'monkeyFacePreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -607,6 +628,7 @@ class ZigZag(bs.Map):
|
|||
|
||||
name = 'Zigzag'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
|
|
@ -618,10 +640,12 @@ class ZigZag(bs.Map):
|
|||
'king_of_the_hill',
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'zigzagPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -715,15 +739,18 @@ class ThePad(bs.Map):
|
|||
|
||||
name = 'The Pad'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'thePadPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -804,15 +831,18 @@ class DoomShroom(bs.Map):
|
|||
|
||||
name = 'Doom Shroom'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'doomShroomPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -881,6 +911,7 @@ class DoomShroom(bs.Map):
|
|||
gnode.vignette_outer = (0.76, 0.76, 0.76)
|
||||
gnode.vignette_inner = (0.95, 0.95, 0.99)
|
||||
|
||||
@override
|
||||
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
|
||||
xpos = point.x
|
||||
zpos = point.z
|
||||
|
|
@ -900,15 +931,18 @@ class LakeFrigid(bs.Map):
|
|||
|
||||
name = 'Lake Frigid'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag', 'race']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'lakeFrigidPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -987,15 +1021,18 @@ class TipTop(bs.Map):
|
|||
|
||||
name = 'Tip Top'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'tipTopPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1065,15 +1102,18 @@ class CragCastle(bs.Map):
|
|||
|
||||
name = 'Crag Castle'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag', 'conquest']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'cragCastlePreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1158,15 +1198,18 @@ class TowerD(bs.Map):
|
|||
|
||||
name = 'Tower D'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return []
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'towerDPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1256,6 +1299,7 @@ class TowerD(bs.Map):
|
|||
gnode.vignette_outer = (0.7, 0.73, 0.7)
|
||||
gnode.vignette_inner = (0.95, 0.95, 0.95)
|
||||
|
||||
@override
|
||||
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
|
||||
# see if we're within edge_box
|
||||
boxes = self.defs.boxes
|
||||
|
|
@ -1281,6 +1325,7 @@ class HappyThoughts(bs.Map):
|
|||
|
||||
name = 'Happy Thoughts'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
|
|
@ -1292,10 +1337,12 @@ class HappyThoughts(bs.Map):
|
|||
'king_of_the_hill',
|
||||
]
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'alwaysLandPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1310,6 +1357,7 @@ class HappyThoughts(bs.Map):
|
|||
}
|
||||
return data
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_music_type(cls) -> bs.MusicType:
|
||||
return bs.MusicType.FLYING
|
||||
|
|
@ -1397,15 +1445,18 @@ class StepRightUp(bs.Map):
|
|||
|
||||
name = 'Step Right Up'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag', 'conquest']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'stepRightUpPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1477,15 +1528,18 @@ class Courtyard(bs.Map):
|
|||
|
||||
name = 'Courtyard'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'courtyardPreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1576,6 +1630,7 @@ class Courtyard(bs.Map):
|
|||
gnode.vignette_outer = (0.6, 0.6, 0.64)
|
||||
gnode.vignette_inner = (0.95, 0.95, 0.93)
|
||||
|
||||
@override
|
||||
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
|
||||
# count anything off our ground level as safe (for our platforms)
|
||||
# see if we're within edge_box
|
||||
|
|
@ -1593,15 +1648,18 @@ class Rampage(bs.Map):
|
|||
|
||||
name = 'Rampage'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_play_types(cls) -> list[str]:
|
||||
"""Return valid play types for this map."""
|
||||
return ['melee', 'keep_away', 'team_flag']
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def get_preview_texture_name(cls) -> str:
|
||||
return 'rampagePreview'
|
||||
|
||||
@override
|
||||
@classmethod
|
||||
def on_preload(cls) -> Any:
|
||||
data: dict[str, Any] = {
|
||||
|
|
@ -1681,6 +1739,7 @@ class Rampage(bs.Map):
|
|||
gnode.vignette_outer = (0.62, 0.64, 0.69)
|
||||
gnode.vignette_inner = (0.97, 0.95, 0.93)
|
||||
|
||||
@override
|
||||
def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
|
||||
box_position = self.defs.boxes['edge_box'][0:3]
|
||||
box_scale = self.defs.boxes['edge_box'][6:9]
|
||||
|
|
|
|||
5
dist/ba_data/python/bascenev1lib/tutorial.py
vendored
5
dist/ba_data/python/bascenev1lib/tutorial.py
vendored
|
|
@ -19,6 +19,7 @@ import logging
|
|||
from collections import deque
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import bascenev1 as bs
|
||||
|
||||
from bascenev1lib.actor.spaz import Spaz
|
||||
|
|
@ -234,11 +235,13 @@ class TutorialActivity(bs.Activity[Player, Team]):
|
|||
self._read_entries_timer: bs.Timer | None = None
|
||||
self._entry_timer: bs.Timer | None = None
|
||||
|
||||
@override
|
||||
def on_transition_in(self) -> None:
|
||||
super().on_transition_in()
|
||||
bs.setmusic(bs.MusicType.CHAR_SELECT, continuous=True)
|
||||
self.map = self._map_type()
|
||||
|
||||
@override
|
||||
def on_begin(self) -> None:
|
||||
super().on_begin()
|
||||
|
||||
|
|
@ -2513,6 +2516,7 @@ class TutorialActivity(bs.Activity[Player, Team]):
|
|||
self._skip_text.color = (1, 1, 1)
|
||||
self._issued_warning = False
|
||||
|
||||
@override
|
||||
def on_player_join(self, player: Player) -> None:
|
||||
super().on_player_join(player)
|
||||
|
||||
|
|
@ -2527,6 +2531,7 @@ class TutorialActivity(bs.Activity[Player, Team]):
|
|||
bs.Call(self._player_pressed_button, player),
|
||||
)
|
||||
|
||||
@override
|
||||
def on_player_leave(self, player: Player) -> None:
|
||||
if not all(self.players):
|
||||
logging.error(
|
||||
|
|
|
|||
2
dist/ba_data/python/bauiv1/__init__.py
vendored
2
dist/ba_data/python/bauiv1/__init__.py
vendored
|
|
@ -47,6 +47,7 @@ from babase import (
|
|||
do_once,
|
||||
fade_screen,
|
||||
get_display_resolution,
|
||||
get_input_idle_time,
|
||||
get_ip_address_type,
|
||||
get_low_level_config_value,
|
||||
get_max_graphics_quality,
|
||||
|
|
@ -156,6 +157,7 @@ __all__ = [
|
|||
'do_once',
|
||||
'fade_screen',
|
||||
'get_display_resolution',
|
||||
'get_input_idle_time',
|
||||
'get_ip_address_type',
|
||||
'get_low_level_config_value',
|
||||
'get_max_graphics_quality',
|
||||
|
|
|
|||
3
dist/ba_data/python/bauiv1/_subsystem.py
vendored
3
dist/ba_data/python/bauiv1/_subsystem.py
vendored
|
|
@ -8,7 +8,9 @@ import logging
|
|||
import inspect
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bauiv1
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -82,6 +84,7 @@ class UIV1Subsystem(babase.AppSubsystem):
|
|||
"""Current ui scale for the app."""
|
||||
return self._uiscale
|
||||
|
||||
@override
|
||||
def on_app_loading(self) -> None:
|
||||
from bauiv1._uitypes import UIController, ui_upkeep
|
||||
|
||||
|
|
|
|||
3
dist/ba_data/python/bauiv1/_uitypes.py
vendored
3
dist/ba_data/python/bauiv1/_uitypes.py
vendored
|
|
@ -9,6 +9,7 @@ import weakref
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
import babase
|
||||
|
||||
import _bauiv1
|
||||
|
|
@ -264,12 +265,14 @@ class TextWidgetStringEditAdapter(babase.StringEditAdapter):
|
|||
description, initial_text, max_length, screen_space_center
|
||||
)
|
||||
|
||||
@override
|
||||
def _do_apply(self, new_text: str) -> None:
|
||||
if self.widget:
|
||||
_bauiv1.textwidget(
|
||||
edit=self.widget, text=new_text, adapter_finished=True
|
||||
)
|
||||
|
||||
@override
|
||||
def _do_cancel(self) -> None:
|
||||
if self.widget:
|
||||
_bauiv1.textwidget(edit=self.widget, adapter_finished=True)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING
|
||||
import logging
|
||||
|
||||
from bauiv1lib.popup import PopupWindow, PopupMenuWindow
|
||||
from typing_extensions import override
|
||||
import bauiv1 as bui
|
||||
|
||||
from bauiv1lib.popup import PopupWindow, PopupMenuWindow
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -596,6 +598,7 @@ class AccountViewerWindow(PopupWindow):
|
|||
self._transitioning_out = True
|
||||
bui.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
@override
|
||||
def on_popup_cancel(self) -> None:
|
||||
bui.getsound('swish').play()
|
||||
self._transition_out()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from bauiv1lib.popup import PopupWindow
|
||||
import bauiv1 as bui
|
||||
|
||||
|
|
@ -229,6 +231,7 @@ class AchievementsWindow(PopupWindow):
|
|||
self._transitioning_out = True
|
||||
bui.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
@override
|
||||
def on_popup_cancel(self) -> None:
|
||||
bui.getsound('swish').play()
|
||||
self._transition_out()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ from __future__ import annotations
|
|||
import math
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from bauiv1lib.popup import PopupWindow
|
||||
import bauiv1 as bui
|
||||
|
||||
|
|
@ -208,6 +210,7 @@ class CharacterPicker(PopupWindow):
|
|||
self._transitioning_out = True
|
||||
bui.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
@override
|
||||
def on_popup_cancel(self) -> None:
|
||||
bui.getsound('swish').play()
|
||||
self._transition_out()
|
||||
|
|
|
|||
4
dist/ba_data/python/bauiv1lib/colorpicker.py
vendored
4
dist/ba_data/python/bauiv1lib/colorpicker.py
vendored
|
|
@ -6,6 +6,8 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from bauiv1lib.popup import PopupWindow
|
||||
import bauiv1 as bui
|
||||
|
||||
|
|
@ -170,6 +172,7 @@ class ColorPicker(PopupWindow):
|
|||
self._delegate.color_picker_closing(self)
|
||||
bui.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
@override
|
||||
def on_popup_cancel(self) -> None:
|
||||
if not self._transitioning_out:
|
||||
bui.getsound('swish').play()
|
||||
|
|
@ -338,6 +341,7 @@ class ColorPickerExact(PopupWindow):
|
|||
self._delegate.color_picker_closing(self)
|
||||
bui.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
@override
|
||||
def on_popup_cancel(self) -> None:
|
||||
if not self._transitioning_out:
|
||||
bui.getsound('swish').play()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import logging
|
|||
from threading import Thread
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
import bauiv1 as bui
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -204,6 +206,7 @@ class FileSelectorWindow(bui.Window):
|
|||
self._callback = callback
|
||||
self._path = path
|
||||
|
||||
@override
|
||||
def run(self) -> None:
|
||||
try:
|
||||
starttime = time.time()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
from bauiv1lib.gather import GatherTab
|
||||
import bauiv1 as bui
|
||||
|
||||
|
|
@ -16,6 +18,7 @@ if TYPE_CHECKING:
|
|||
class AboutGatherTab(GatherTab):
|
||||
"""The about tab in the gather UI"""
|
||||
|
||||
@override
|
||||
def on_activate(
|
||||
self,
|
||||
parent_widget: bui.Widget,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from threading import Thread
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
from enum import Enum
|
||||
from threading import Thread
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, cast
|
||||
from bauiv1lib.gather import GatherTab
|
||||
|
||||
from typing_extensions import override
|
||||
import bauiv1 as bui
|
||||
import bascenev1 as bs
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ class _HostLookupThread(Thread):
|
|||
self._port = port
|
||||
self._call = call
|
||||
|
||||
@override
|
||||
def run(self) -> None:
|
||||
result: str | None
|
||||
try:
|
||||
|
|
@ -101,6 +102,7 @@ class ManualGatherTab(GatherTab):
|
|||
self._party_edit_port_text: bui.Widget | None = None
|
||||
self._no_parties_added_text: bui.Widget | None = None
|
||||
|
||||
@override
|
||||
def on_activate(
|
||||
self,
|
||||
parent_widget: bui.Widget,
|
||||
|
|
@ -180,10 +182,12 @@ class ManualGatherTab(GatherTab):
|
|||
|
||||
return self._container
|
||||
|
||||
@override
|
||||
def save_state(self) -> None:
|
||||
assert bui.app.classic is not None
|
||||
bui.app.ui_v1.window_states[type(self)] = State(sub_tab=self._sub_tab)
|
||||
|
||||
@override
|
||||
def restore_state(self) -> None:
|
||||
assert bui.app.classic is not None
|
||||
state = bui.app.ui_v1.window_states.get(type(self))
|
||||
|
|
@ -771,6 +775,7 @@ class ManualGatherTab(GatherTab):
|
|||
text=bui.Lstr(resource='gatherWindow.noPartiesAddedText'),
|
||||
)
|
||||
|
||||
@override
|
||||
def on_deactivate(self) -> None:
|
||||
self._access_check_timer = None
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ from __future__ import annotations
|
|||
import weakref
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bauiv1lib.gather import GatherTab
|
||||
from typing_extensions import override
|
||||
import bauiv1 as bui
|
||||
import bascenev1 as bs
|
||||
|
||||
from bauiv1lib.gather import GatherTab
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -104,6 +106,7 @@ class NearbyGatherTab(GatherTab):
|
|||
self._net_scanner: NetScanner | None = None
|
||||
self._container: bui.Widget | None = None
|
||||
|
||||
@override
|
||||
def on_activate(
|
||||
self,
|
||||
parent_widget: bui.Widget,
|
||||
|
|
@ -156,5 +159,6 @@ class NearbyGatherTab(GatherTab):
|
|||
bui.widget(edit=scrollw, autoselect=True, up_widget=tab_button)
|
||||
return self._container
|
||||
|
||||
@override
|
||||
def on_deactivate(self) -> None:
|
||||
self._net_scanner = None
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from enum import Enum
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
from typing_extensions import override
|
||||
from efro.dataclassio import dataclass_from_dict, dataclass_to_dict
|
||||
from bacommon.net import (
|
||||
PrivateHostingState,
|
||||
|
|
@ -81,6 +82,7 @@ class PrivateGatherTab(GatherTab):
|
|||
logging.exception('Error building hosting config.')
|
||||
self._hostingconfig = PrivateHostingConfig()
|
||||
|
||||
@override
|
||||
def on_activate(
|
||||
self,
|
||||
parent_widget: bui.Widget,
|
||||
|
|
@ -253,6 +255,7 @@ class PrivateGatherTab(GatherTab):
|
|||
|
||||
return hcfg
|
||||
|
||||
@override
|
||||
def on_deactivate(self) -> None:
|
||||
self._update_timer = None
|
||||
|
||||
|
|
@ -995,10 +998,12 @@ class PrivateGatherTab(GatherTab):
|
|||
self._debug_server_comm('got connect response error')
|
||||
bui.getsound('error').play()
|
||||
|
||||
@override
|
||||
def save_state(self) -> None:
|
||||
assert bui.app.classic is not None
|
||||
bui.app.ui_v1.window_states[type(self)] = copy.deepcopy(self._state)
|
||||
|
||||
@override
|
||||
def restore_state(self) -> None:
|
||||
assert bui.app.classic is not None
|
||||
state = bui.app.ui_v1.window_states.get(type(self))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue