mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-06 15:47:06 +08:00
Merge pull request #640 from EraOSBeta/master
QoL for Teams Sessions, FFA Sessions, and Servers
This commit is contained in:
commit
1f811a2f52
@ -37,12 +37,12 @@
|
|||||||
- Added feature
|
- Added feature
|
||||||
|
|
||||||
### Vishal332008
|
### Vishal332008
|
||||||
- Bug Fixer
|
- QoL and Bug Fixer
|
||||||
- Modder
|
- Modder
|
||||||
|
|
||||||
### Era0S
|
### Era0S
|
||||||
- Community Suggestions Implementer
|
- Community Suggestions Implementer
|
||||||
- Bug Fixer
|
- QoL and Bug Fixer
|
||||||
- Modder
|
- Modder
|
||||||
|
|
||||||
### VinniTR
|
### VinniTR
|
||||||
@ -52,6 +52,7 @@
|
|||||||
- Created the original "reject_recently_left_players" plugin
|
- Created the original "reject_recently_left_players" plugin
|
||||||
|
|
||||||
### Temp (3alTemp)
|
### Temp (3alTemp)
|
||||||
|
- Original idea for customizable series length on GUI builds
|
||||||
- Modder & Bug Fixer
|
- Modder & Bug Fixer
|
||||||
|
|
||||||
### brostos
|
### brostos
|
||||||
|
|||||||
@ -406,6 +406,10 @@ class ServerController:
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError(f'Unknown session type {sessiontype}')
|
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.teams_series_length = self._config.teams_series_length
|
||||||
classic.ffa_series_length = self._config.ffa_series_length
|
classic.ffa_series_length = self._config.ffa_series_length
|
||||||
|
|
||||||
@ -427,6 +431,10 @@ class ServerController:
|
|||||||
self._config.player_rejoin_cooldown
|
self._config.player_rejoin_cooldown
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bascenev1.set_max_players_override(
|
||||||
|
self._config.session_max_players_override
|
||||||
|
)
|
||||||
|
|
||||||
# And here.. we.. go.
|
# And here.. we.. go.
|
||||||
if self._config.stress_test_players is not None:
|
if self._config.stress_test_players is not None:
|
||||||
# Special case: run a stress test.
|
# Special case: run a stress test.
|
||||||
|
|||||||
@ -103,8 +103,8 @@ class ClassicSubsystem(babase.AppSubsystem):
|
|||||||
self.maps: dict[str, type[bascenev1.Map]] = {}
|
self.maps: dict[str, type[bascenev1.Map]] = {}
|
||||||
|
|
||||||
# Gameplay.
|
# Gameplay.
|
||||||
self.teams_series_length = 7
|
self.teams_series_length = 7 # deprecated, left for old mods
|
||||||
self.ffa_series_length = 24
|
self.ffa_series_length = 24 # deprecated, left for old mods
|
||||||
self.coop_session_args: dict = {}
|
self.coop_session_args: dict = {}
|
||||||
|
|
||||||
# UI.
|
# UI.
|
||||||
|
|||||||
@ -231,7 +231,9 @@ from bascenev1._settings import (
|
|||||||
IntSetting,
|
IntSetting,
|
||||||
Setting,
|
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._stats import PlayerScoredMessage, PlayerRecord, Stats
|
||||||
from bascenev1._team import SessionTeam, Team, EmptyTeam
|
from bascenev1._team import SessionTeam, Team, EmptyTeam
|
||||||
from bascenev1._teamgame import TeamGameActivity
|
from bascenev1._teamgame import TeamGameActivity
|
||||||
@ -426,6 +428,7 @@ __all__ = [
|
|||||||
'set_public_party_queue_enabled',
|
'set_public_party_queue_enabled',
|
||||||
'set_public_party_stats_url',
|
'set_public_party_stats_url',
|
||||||
'set_player_rejoin_cooldown',
|
'set_player_rejoin_cooldown',
|
||||||
|
'set_max_players_override',
|
||||||
'set_replay_speed_exponent',
|
'set_replay_speed_exponent',
|
||||||
'set_touchscreen_editing',
|
'set_touchscreen_editing',
|
||||||
'setmusic',
|
'setmusic',
|
||||||
|
|||||||
@ -67,8 +67,8 @@ class MultiTeamSession(Session):
|
|||||||
max_players=self.get_max_players(),
|
max_players=self.get_max_players(),
|
||||||
)
|
)
|
||||||
|
|
||||||
self._series_length: int = classic.teams_series_length
|
self._series_length: int = int(cfg.get('Teams Series Length', 7))
|
||||||
self._ffa_series_length: int = classic.ffa_series_length
|
self._ffa_series_length: int = int(cfg.get('FFA Series Length', 24))
|
||||||
|
|
||||||
show_tutorial = cfg.get('Show Tutorial', True)
|
show_tutorial = cfg.get('Show Tutorial', True)
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,9 @@ if TYPE_CHECKING:
|
|||||||
# such as skipping respawn waits.
|
# such as skipping respawn waits.
|
||||||
_g_player_rejoin_cooldown: float = 0.0
|
_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:
|
def set_player_rejoin_cooldown(cooldown: float) -> None:
|
||||||
"""Set the cooldown for individual players rejoining after leaving."""
|
"""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)
|
_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:
|
class Session:
|
||||||
"""Defines a high level series of bascenev1.Activity-es.
|
"""Defines a high level series of bascenev1.Activity-es.
|
||||||
|
|
||||||
@ -161,7 +170,11 @@ class Session:
|
|||||||
self.sessionteams = []
|
self.sessionteams = []
|
||||||
self.sessionplayers = []
|
self.sessionplayers = []
|
||||||
self.min_players = min_players
|
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.customdata = {}
|
||||||
self._in_set_activity = False
|
self._in_set_activity = False
|
||||||
@ -255,7 +268,7 @@ class Session:
|
|||||||
babase.app.classic is not None
|
babase.app.classic is not None
|
||||||
and babase.app.classic.stress_test_update_timer is 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
|
# Print a rejection message *only* to the client trying to
|
||||||
# join (prevents spamming everyone else in the game).
|
# join (prevents spamming everyone else in the game).
|
||||||
_bascenev1.getsound('error').play()
|
_bascenev1.getsound('error').play()
|
||||||
|
|||||||
@ -94,6 +94,8 @@ class ConfigNumberEdit:
|
|||||||
changesound: bool = True,
|
changesound: bool = True,
|
||||||
textscale: float = 1.0,
|
textscale: float = 1.0,
|
||||||
as_percent: bool = False,
|
as_percent: bool = False,
|
||||||
|
fallback_value: float = 0.0,
|
||||||
|
f: int = 1,
|
||||||
):
|
):
|
||||||
if displayname is None:
|
if displayname is None:
|
||||||
displayname = configkey
|
displayname = configkey
|
||||||
@ -103,8 +105,12 @@ class ConfigNumberEdit:
|
|||||||
self._maxval = maxval
|
self._maxval = maxval
|
||||||
self._increment = increment
|
self._increment = increment
|
||||||
self._callback = callback
|
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._as_percent = as_percent
|
||||||
|
self._f = f
|
||||||
|
|
||||||
self.nametext = bui.textwidget(
|
self.nametext = bui.textwidget(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
@ -171,5 +177,5 @@ class ConfigNumberEdit:
|
|||||||
if self._as_percent:
|
if self._as_percent:
|
||||||
val = f'{round(self._value*100.0)}%'
|
val = f'{round(self._value*100.0)}%'
|
||||||
else:
|
else:
|
||||||
val = f'{self._value:.1f}'
|
val = f'{self._value:.{self._f}f}'
|
||||||
bui.textwidget(edit=self.valuetext, text=val)
|
bui.textwidget(edit=self.valuetext, text=val)
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class PlayOptionsWindow(PopupWindow):
|
|||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
from bascenev1 import filter_playlist, get_map_class
|
from bascenev1 import filter_playlist, get_map_class
|
||||||
from bauiv1lib.playlist import PlaylistTypeVars
|
from bauiv1lib.playlist import PlaylistTypeVars
|
||||||
|
from bauiv1lib.config import ConfigNumberEdit
|
||||||
|
|
||||||
self._r = 'gameListWindow'
|
self._r = 'gameListWindow'
|
||||||
self._delegate = delegate
|
self._delegate = delegate
|
||||||
@ -52,7 +53,7 @@ class PlayOptionsWindow(PopupWindow):
|
|||||||
self._playlist = playlist
|
self._playlist = playlist
|
||||||
|
|
||||||
self._width = 500.0
|
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.
|
# In teams games, show the custom names/colors button.
|
||||||
if self._sessiontype is bs.DualTeamSession:
|
if self._sessiontype is bs.DualTeamSession:
|
||||||
@ -275,13 +276,37 @@ class PlayOptionsWindow(PopupWindow):
|
|||||||
texture=bui.gettexture('lock'),
|
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.
|
# Team names/colors.
|
||||||
self._custom_colors_names_button: bui.Widget | None
|
self._custom_colors_names_button: bui.Widget | None
|
||||||
if self._sessiontype is bs.DualTeamSession:
|
if self._sessiontype is bs.DualTeamSession:
|
||||||
y_offs = 50 if show_shuffle_check_box else 0
|
|
||||||
self._custom_colors_names_button = bui.buttonwidget(
|
self._custom_colors_names_button = bui.buttonwidget(
|
||||||
parent=self.root_widget,
|
parent=self.root_widget,
|
||||||
position=(100, 200 + y_offs),
|
position=(100, 195 + y_offs),
|
||||||
size=(290, 35),
|
size=(290, 35),
|
||||||
on_activate_call=bui.WeakCall(self._custom_colors_names_press),
|
on_activate_call=bui.WeakCall(self._custom_colors_names_press),
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
|
|||||||
@ -47,10 +47,14 @@ class ServerConfig:
|
|||||||
# Max devices in the party. Note that this does *NOT* mean max players.
|
# 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
|
# 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
|
# multiple controllers. Also, this number currently includes the server so
|
||||||
# generally make it 1 bigger than you need. Max-players is not currently
|
# generally make it 1 bigger than you need.
|
||||||
# exposed but I'll try to add that soon.
|
|
||||||
max_party_size: int = 6
|
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)
|
# Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative)
|
||||||
# This value is ignored if you supply a playlist_code (see below).
|
# This value is ignored if you supply a playlist_code (see below).
|
||||||
session_type: str = 'ffa'
|
session_type: str = 'ffa'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user