mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-27 09:23:12 +08:00
Merge pull request #640 from EraOSBeta/master
QoL for Teams Sessions, FFA Sessions, and Servers
This commit is contained in:
commit
1f811a2f52
10
CHANGELOG.md
10
CHANGELOG.md
@ -31,7 +31,7 @@
|
||||
(Thanks 3alTemp!).
|
||||
- Leaving the game or dying while touching your team's flag will no longer recover
|
||||
& return it indefinitely in a teams game of Capture the Flag. (Thanks 3alTemp!)
|
||||
|
||||
|
||||
### 1.7.32 (build 21741, api 8, 2023-12-20)
|
||||
- Fixed a screen message that no one will ever see (Thanks vishal332008?...)
|
||||
- Plugins window now displays 'No Plugins Installed' when no plugins are present (Thanks vishal332008!)
|
||||
@ -74,7 +74,7 @@
|
||||
intended. Now, however, such commands get scheduled to a current
|
||||
'ui-operation' and then run *almost* immediately, which should prevent such
|
||||
situations. Please holler if you run into any UI weirdness at this point.
|
||||
|
||||
|
||||
### 1.7.30 (build 21697, api 8, 2023-12-08)
|
||||
- Continued work on the big 1.7.28 update.
|
||||
- Got the Android version back up and running. There's been lots of cleanup and
|
||||
@ -351,7 +351,7 @@
|
||||
- Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when
|
||||
the text is selected. The default is 'gradient' but there is now a 'uniform'
|
||||
option which may look better in some circumstances.
|
||||
|
||||
|
||||
### 1.7.27 (build 21282, api 8, 2023-08-30)
|
||||
|
||||
- Fixed a rare crash that could occur if the app shuts down while a background
|
||||
@ -472,7 +472,7 @@
|
||||
Visual Studio Code (and potentially other editors), so am seeing if it is
|
||||
worth officially supporting in addition to or as a replacement for Mypy. See
|
||||
`tools/pcommand pyright`
|
||||
|
||||
|
||||
### 1.7.24 (build 21199, api 8, 2023-07-27)
|
||||
|
||||
- Fixed an issue where respawn icons could disappear in epic mode (Thanks for
|
||||
@ -527,7 +527,7 @@
|
||||
can be useful for core engine code to directly and clearly point out problems
|
||||
that cannot be recovered from (Exceptions in such cases can tend to be
|
||||
'handled' which leads to a broken or crashing app).
|
||||
|
||||
|
||||
### 1.7.23 (build 21178, api 8, 2023-07-19)
|
||||
|
||||
- Network security improvements. (Thanks Dliwk!)
|
||||
|
||||
@ -37,12 +37,12 @@
|
||||
- Added feature
|
||||
|
||||
### Vishal332008
|
||||
- Bug Fixer
|
||||
- QoL and Bug Fixer
|
||||
- Modder
|
||||
|
||||
### Era0S
|
||||
- Community Suggestions Implementer
|
||||
- Bug Fixer
|
||||
- QoL and Bug Fixer
|
||||
- Modder
|
||||
|
||||
### VinniTR
|
||||
@ -52,6 +52,7 @@
|
||||
- Created the original "reject_recently_left_players" plugin
|
||||
|
||||
### Temp (3alTemp)
|
||||
- Original idea for customizable series length on GUI builds
|
||||
- Modder & Bug Fixer
|
||||
|
||||
### brostos
|
||||
|
||||
@ -406,6 +406,10 @@ class ServerController:
|
||||
else:
|
||||
raise RuntimeError(f'Unknown session type {sessiontype}')
|
||||
|
||||
appcfg['Teams Series Length'] = self._config.teams_series_length
|
||||
appcfg['FFA Series Length'] = self._config.ffa_series_length
|
||||
|
||||
# deprecated, left here in order to not break mods
|
||||
classic.teams_series_length = self._config.teams_series_length
|
||||
classic.ffa_series_length = self._config.ffa_series_length
|
||||
|
||||
@ -427,6 +431,10 @@ class ServerController:
|
||||
self._config.player_rejoin_cooldown
|
||||
)
|
||||
|
||||
bascenev1.set_max_players_override(
|
||||
self._config.session_max_players_override
|
||||
)
|
||||
|
||||
# And here.. we.. go.
|
||||
if self._config.stress_test_players is not None:
|
||||
# Special case: run a stress test.
|
||||
|
||||
@ -103,8 +103,8 @@ class ClassicSubsystem(babase.AppSubsystem):
|
||||
self.maps: dict[str, type[bascenev1.Map]] = {}
|
||||
|
||||
# Gameplay.
|
||||
self.teams_series_length = 7
|
||||
self.ffa_series_length = 24
|
||||
self.teams_series_length = 7 # deprecated, left for old mods
|
||||
self.ffa_series_length = 24 # deprecated, left for old mods
|
||||
self.coop_session_args: dict = {}
|
||||
|
||||
# UI.
|
||||
|
||||
@ -231,7 +231,9 @@ from bascenev1._settings import (
|
||||
IntSetting,
|
||||
Setting,
|
||||
)
|
||||
from bascenev1._session import Session, set_player_rejoin_cooldown
|
||||
from bascenev1._session import (
|
||||
Session, set_player_rejoin_cooldown, set_max_players_override
|
||||
)
|
||||
from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats
|
||||
from bascenev1._team import SessionTeam, Team, EmptyTeam
|
||||
from bascenev1._teamgame import TeamGameActivity
|
||||
@ -426,6 +428,7 @@ __all__ = [
|
||||
'set_public_party_queue_enabled',
|
||||
'set_public_party_stats_url',
|
||||
'set_player_rejoin_cooldown',
|
||||
'set_max_players_override',
|
||||
'set_replay_speed_exponent',
|
||||
'set_touchscreen_editing',
|
||||
'setmusic',
|
||||
|
||||
@ -67,8 +67,8 @@ class MultiTeamSession(Session):
|
||||
max_players=self.get_max_players(),
|
||||
)
|
||||
|
||||
self._series_length: int = classic.teams_series_length
|
||||
self._ffa_series_length: int = classic.ffa_series_length
|
||||
self._series_length: int = int(cfg.get('Teams Series Length', 7))
|
||||
self._ffa_series_length: int = int(cfg.get('FFA Series Length', 24))
|
||||
|
||||
show_tutorial = cfg.get('Show Tutorial', True)
|
||||
|
||||
|
||||
@ -23,6 +23,9 @@ if TYPE_CHECKING:
|
||||
# such as skipping respawn waits.
|
||||
_g_player_rejoin_cooldown: float = 0.0
|
||||
|
||||
# overrides the session's decision of max_players
|
||||
_max_players_override: int | None = None
|
||||
|
||||
|
||||
def set_player_rejoin_cooldown(cooldown: float) -> None:
|
||||
"""Set the cooldown for individual players rejoining after leaving."""
|
||||
@ -30,6 +33,12 @@ def set_player_rejoin_cooldown(cooldown: float) -> None:
|
||||
_g_player_rejoin_cooldown = max(0.0, cooldown)
|
||||
|
||||
|
||||
def set_max_players_override(max_players: int | None) -> None:
|
||||
"""Set the override for how many players can join a session"""
|
||||
global _max_players_override # pylint: disable=global-statement
|
||||
_max_players_override = max_players
|
||||
|
||||
|
||||
class Session:
|
||||
"""Defines a high level series of bascenev1.Activity-es.
|
||||
|
||||
@ -161,7 +170,11 @@ class Session:
|
||||
self.sessionteams = []
|
||||
self.sessionplayers = []
|
||||
self.min_players = min_players
|
||||
self.max_players = max_players
|
||||
self.max_players = (
|
||||
max_players
|
||||
if _max_players_override is None
|
||||
else _max_players_override
|
||||
)
|
||||
|
||||
self.customdata = {}
|
||||
self._in_set_activity = False
|
||||
@ -255,7 +268,7 @@ class Session:
|
||||
babase.app.classic is not None
|
||||
and babase.app.classic.stress_test_update_timer is None
|
||||
):
|
||||
if len(self.sessionplayers) >= self.max_players:
|
||||
if len(self.sessionplayers) >= self.max_players >= 0:
|
||||
# Print a rejection message *only* to the client trying to
|
||||
# join (prevents spamming everyone else in the game).
|
||||
_bascenev1.getsound('error').play()
|
||||
|
||||
@ -94,6 +94,8 @@ class ConfigNumberEdit:
|
||||
changesound: bool = True,
|
||||
textscale: float = 1.0,
|
||||
as_percent: bool = False,
|
||||
fallback_value: float = 0.0,
|
||||
f: int = 1,
|
||||
):
|
||||
if displayname is None:
|
||||
displayname = configkey
|
||||
@ -103,8 +105,12 @@ class ConfigNumberEdit:
|
||||
self._maxval = maxval
|
||||
self._increment = increment
|
||||
self._callback = callback
|
||||
self._value = bui.app.config.resolve(configkey)
|
||||
try:
|
||||
self._value = bui.app.config.resolve(configkey)
|
||||
except ValueError:
|
||||
self._value = bui.app.config.get(configkey, fallback_value)
|
||||
self._as_percent = as_percent
|
||||
self._f = f
|
||||
|
||||
self.nametext = bui.textwidget(
|
||||
parent=parent,
|
||||
@ -171,5 +177,5 @@ class ConfigNumberEdit:
|
||||
if self._as_percent:
|
||||
val = f'{round(self._value*100.0)}%'
|
||||
else:
|
||||
val = f'{self._value:.1f}'
|
||||
val = f'{self._value:.{self._f}f}'
|
||||
bui.textwidget(edit=self.valuetext, text=val)
|
||||
|
||||
@ -33,6 +33,7 @@ class PlayOptionsWindow(PopupWindow):
|
||||
# pylint: disable=too-many-locals
|
||||
from bascenev1 import filter_playlist, get_map_class
|
||||
from bauiv1lib.playlist import PlaylistTypeVars
|
||||
from bauiv1lib.config import ConfigNumberEdit
|
||||
|
||||
self._r = 'gameListWindow'
|
||||
self._delegate = delegate
|
||||
@ -52,7 +53,7 @@ class PlayOptionsWindow(PopupWindow):
|
||||
self._playlist = playlist
|
||||
|
||||
self._width = 500.0
|
||||
self._height = 330.0 - 50.0
|
||||
self._height = 370.0 - 50.0
|
||||
|
||||
# In teams games, show the custom names/colors button.
|
||||
if self._sessiontype is bs.DualTeamSession:
|
||||
@ -275,13 +276,37 @@ class PlayOptionsWindow(PopupWindow):
|
||||
texture=bui.gettexture('lock'),
|
||||
)
|
||||
|
||||
y_offs = 50 if show_shuffle_check_box else 0
|
||||
|
||||
# Series Length
|
||||
y_offs2 = 40 if self._sessiontype is bs.DualTeamSession else 0
|
||||
self._series_length_numedit = ConfigNumberEdit(
|
||||
parent=self.root_widget,
|
||||
position=(100, 200 + y_offs + y_offs2),
|
||||
configkey=(
|
||||
'FFA' if self._sessiontype is bs.FreeForAllSession else 'Teams'
|
||||
) + ' Series Length',
|
||||
displayname=bui.Lstr(
|
||||
resource=self._r + (
|
||||
'.pointsToWinText'
|
||||
if self._sessiontype is bs.FreeForAllSession
|
||||
else '.seriesLengthText'
|
||||
)
|
||||
),
|
||||
minval=1.0,
|
||||
increment=1.0 if self._sessiontype is bs.FreeForAllSession else 2.0,
|
||||
fallback_value=(
|
||||
24 if self._sessiontype is bs.FreeForAllSession else 7
|
||||
),
|
||||
f=0,
|
||||
)
|
||||
|
||||
# Team names/colors.
|
||||
self._custom_colors_names_button: bui.Widget | None
|
||||
if self._sessiontype is bs.DualTeamSession:
|
||||
y_offs = 50 if show_shuffle_check_box else 0
|
||||
self._custom_colors_names_button = bui.buttonwidget(
|
||||
parent=self.root_widget,
|
||||
position=(100, 200 + y_offs),
|
||||
position=(100, 195 + y_offs),
|
||||
size=(290, 35),
|
||||
on_activate_call=bui.WeakCall(self._custom_colors_names_press),
|
||||
autoselect=True,
|
||||
|
||||
@ -47,10 +47,14 @@ class ServerConfig:
|
||||
# Max devices in the party. Note that this does *NOT* mean max players.
|
||||
# Any device in the party can have more than one player on it if they have
|
||||
# multiple controllers. Also, this number currently includes the server so
|
||||
# generally make it 1 bigger than you need. Max-players is not currently
|
||||
# exposed but I'll try to add that soon.
|
||||
# generally make it 1 bigger than you need.
|
||||
max_party_size: int = 6
|
||||
|
||||
# Max players that can join a session. If present this will override the
|
||||
# session's preferred max_players. if a value below 0 is given player limit
|
||||
# will be removed.
|
||||
session_max_players_override: int | None = None
|
||||
|
||||
# Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative)
|
||||
# This value is ignored if you supply a playlist_code (see below).
|
||||
session_type: str = 'ffa'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user