mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-10-08 14:54:36 +00:00
parent
c2832136aa
commit
4eb520fa19
8 changed files with 873 additions and 355 deletions
11
README.md
11
README.md
|
|
@ -40,8 +40,14 @@ There are two different ways the plugin manager can be installed:
|
||||||
|
|
||||||
1. [Download plugin_manager.py][DownloadLink] to your mods directory (check it out by going into your game's
|
1. [Download plugin_manager.py][DownloadLink] to your mods directory (check it out by going into your game's
|
||||||
Settings -> Advanced -> Show Mods Folder). This is the recommended way (read next method to know why).
|
Settings -> Advanced -> Show Mods Folder). This is the recommended way (read next method to know why).
|
||||||
|
If you're on a newer version of Android (11 or above) and not rooted, it probably won't be possible to copy
|
||||||
|
mods to game's mods folder. In this case, you can connect your Android phone to a computer and push `plugin_manager.py`
|
||||||
|
[using `adb`](https://www.xda-developers.com/install-adb-windows-macos-linux/):
|
||||||
|
```bash
|
||||||
|
$ adb push plugin_manager.py /sdcard/Android/data/net.froemling.bombsquad/files/mods/plugin_manager.py
|
||||||
|
```
|
||||||
|
|
||||||
2. Another way is to add
|
3. Another way is to add
|
||||||
[plugin_manager.py](https://raw.githubusercontent.com/bombsquad-community/plugin-manager/main/plugin_manager.py)
|
[plugin_manager.py](https://raw.githubusercontent.com/bombsquad-community/plugin-manager/main/plugin_manager.py)
|
||||||
to your workspace. However, plugin manager self-updates will fail when installed using this way since the game
|
to your workspace. However, plugin manager self-updates will fail when installed using this way since the game
|
||||||
will overrwrite the updated plugin manager, with the older version from workspace on the next sync. However, you can
|
will overrwrite the updated plugin manager, with the older version from workspace on the next sync. However, you can
|
||||||
|
|
@ -193,7 +199,8 @@ That's it! Now you can make a [pull request](../../compare) with both the update
|
||||||
will also help us to notify the maintainers of any future breaking changes in plugin manager that could affect 3rd party
|
will also help us to notify the maintainers of any future breaking changes in plugin manager that could affect 3rd party
|
||||||
plugin sources.
|
plugin sources.
|
||||||
|
|
||||||
[rikkolovescats/sahilp-plugins](https://github.com/rikkolovescats/sahilp-plugins)
|
- [rikkolovescats/sahilp-plugins](https://github.com/rikkolovescats/sahilp-plugins)
|
||||||
|
- [Aeliux/arcane](https://github.com/Aeliux/arcane)
|
||||||
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"2.0.0": {
|
||||||
|
"api_version": 8,
|
||||||
|
"commit_sha": "1b14789",
|
||||||
|
"released_on": "02-07-2023",
|
||||||
|
"md5sum": "cb2a7700dd13febe6f68c3cd979b8b19"
|
||||||
|
},
|
||||||
"1.1.0": {
|
"1.1.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "40b70fe",
|
"commit_sha": "40b70fe",
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,25 @@
|
||||||
#
|
#
|
||||||
"""Elimination mini-game."""
|
"""Elimination mini-game."""
|
||||||
|
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
# (see https://ballistica.net/wiki/meta-tag-system)
|
# (see https://ballistica.net/wiki/meta-tag-system)
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
from bastd.actor.spazfactory import SpazFactory
|
import bauiv1 as bui
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
import bascenev1 as bs
|
||||||
|
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||||
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import (Any, Tuple, Type, List, Sequence, Optional,
|
from typing import (Any, Tuple, Type, List, Sequence, Optional,
|
||||||
Union)
|
Union)
|
||||||
|
|
||||||
|
|
||||||
class Icon(ba.Actor):
|
class Icon(bs.Actor):
|
||||||
"""Creates in in-game icon on screen."""
|
"""Creates in in-game icon on screen."""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
|
@ -37,10 +39,10 @@ class Icon(ba.Actor):
|
||||||
self._show_lives = show_lives
|
self._show_lives = show_lives
|
||||||
self._show_death = show_death
|
self._show_death = show_death
|
||||||
self._name_scale = name_scale
|
self._name_scale = name_scale
|
||||||
self._outline_tex = ba.gettexture('characterIconMask')
|
self._outline_tex = bs.gettexture('characterIconMask')
|
||||||
|
|
||||||
icon = player.get_icon()
|
icon = player.get_icon()
|
||||||
self.node = ba.newnode('image',
|
self.node = bs.newnode('image',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'texture': icon['texture'],
|
'texture': icon['texture'],
|
||||||
|
|
@ -53,12 +55,12 @@ class Icon(ba.Actor):
|
||||||
'absolute_scale': True,
|
'absolute_scale': True,
|
||||||
'attach': 'bottomCenter'
|
'attach': 'bottomCenter'
|
||||||
})
|
})
|
||||||
self._name_text = ba.newnode(
|
self._name_text = bs.newnode(
|
||||||
'text',
|
'text',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': ba.Lstr(value=player.getname()),
|
'text': babase.Lstr(value=player.getname()),
|
||||||
'color': ba.safecolor(player.team.color),
|
'color': babase.safecolor(player.team.color),
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_align': 'center',
|
'v_align': 'center',
|
||||||
'vr_depth': 410,
|
'vr_depth': 410,
|
||||||
|
|
@ -69,7 +71,7 @@ class Icon(ba.Actor):
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
if self._show_lives:
|
if self._show_lives:
|
||||||
self._lives_text = ba.newnode('text',
|
self._lives_text = bs.newnode('text',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': 'x0',
|
'text': 'x0',
|
||||||
|
|
@ -125,7 +127,7 @@ class Icon(ba.Actor):
|
||||||
if not self.node:
|
if not self.node:
|
||||||
return
|
return
|
||||||
if self._show_death:
|
if self._show_death:
|
||||||
ba.animate(
|
bs.animate(
|
||||||
self.node, 'opacity', {
|
self.node, 'opacity', {
|
||||||
0.00: 1.0,
|
0.00: 1.0,
|
||||||
0.05: 0.0,
|
0.05: 0.0,
|
||||||
|
|
@ -142,16 +144,16 @@ class Icon(ba.Actor):
|
||||||
})
|
})
|
||||||
lives = self._player.lives
|
lives = self._player.lives
|
||||||
if lives == 0:
|
if lives == 0:
|
||||||
ba.timer(0.6, self.update_for_lives)
|
bs.timer(0.6, self.update_for_lives)
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
return None
|
return None
|
||||||
return super().handlemessage(msg)
|
return super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
||||||
class Player(ba.Player['Team']):
|
class Player(bs.Player['Team']):
|
||||||
"""Our player type for this game."""
|
"""Our player type for this game."""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
@ -159,7 +161,7 @@ class Player(ba.Player['Team']):
|
||||||
self.icons: List[Icon] = []
|
self.icons: List[Icon] = []
|
||||||
|
|
||||||
|
|
||||||
class Team(ba.Team[Player]):
|
class Team(bs.Team[Player]):
|
||||||
"""Our team type for this game."""
|
"""Our team type for this game."""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
@ -167,14 +169,14 @@ class Team(ba.Team[Player]):
|
||||||
self.spawn_order: List[Player] = []
|
self.spawn_order: List[Player] = []
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
class AllianceEliminationGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Game type where last player(s) left alive win."""
|
"""Game type where last player(s) left alive win."""
|
||||||
|
|
||||||
name = 'Alliance Elimination'
|
name = 'Alliance Elimination'
|
||||||
description = 'Fight in groups of duo, trio, or more.\nLast remaining alive wins.'
|
description = 'Fight in groups of duo, trio, or more.\nLast remaining alive wins.'
|
||||||
scoreconfig = ba.ScoreConfig(label='Survived',
|
scoreconfig = bs.ScoreConfig(label='Survived',
|
||||||
scoretype=ba.ScoreType.SECONDS,
|
scoretype=bs.ScoreType.SECONDS,
|
||||||
none_is_winner=True)
|
none_is_winner=True)
|
||||||
# Show messages when players die since it's meaningful here.
|
# Show messages when players die since it's meaningful here.
|
||||||
announce_player_deaths = True
|
announce_player_deaths = True
|
||||||
|
|
@ -183,23 +185,23 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_settings(
|
def get_available_settings(
|
||||||
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
|
cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]:
|
||||||
settings = [
|
settings = [
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Lives Per Player',
|
'Lives Per Player',
|
||||||
default=1,
|
default=1,
|
||||||
min_value=1,
|
min_value=1,
|
||||||
max_value=10,
|
max_value=10,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Players Per Team In Arena',
|
'Players Per Team In Arena',
|
||||||
default=2,
|
default=2,
|
||||||
min_value=2,
|
min_value=2,
|
||||||
max_value=10,
|
max_value=10,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -211,7 +213,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -222,27 +224,27 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
if issubclass(sessiontype, ba.DualTeamSession):
|
if issubclass(sessiontype, bs.DualTeamSession):
|
||||||
settings.append(
|
settings.append(
|
||||||
ba.BoolSetting('Balance Total Lives', default=False))
|
bs.BoolSetting('Balance Total Lives', default=False))
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:
|
def supports_session_type(cls, sessiontype: Type[bs.Session]) -> bool:
|
||||||
return issubclass(sessiontype, ba.DualTeamSession)
|
return issubclass(sessiontype, bs.DualTeamSession)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:
|
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
|
||||||
return ba.getmaps('melee')
|
return bs.app.classic.getmaps('melee')
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._start_time: Optional[float] = None
|
self._start_time: Optional[float] = None
|
||||||
self._vs_text: Optional[ba.Actor] = None
|
self._vs_text: Optional[bs.Actor] = None
|
||||||
self._round_end_timer: Optional[ba.Timer] = None
|
self._round_end_timer: Optional[bs.Timer] = None
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
self._lives_per_player = int(settings['Lives Per Player'])
|
self._lives_per_player = int(settings['Lives Per Player'])
|
||||||
self._time_limit = float(settings['Time Limit'])
|
self._time_limit = float(settings['Time Limit'])
|
||||||
|
|
@ -253,16 +255,16 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Base class overrides:
|
# Base class overrides:
|
||||||
self.slow_motion = self._epic_mode
|
self.slow_motion = self._epic_mode
|
||||||
self.default_music = (ba.MusicType.EPIC
|
self.default_music = (bs.MusicType.EPIC
|
||||||
if self._epic_mode else ba.MusicType.SURVIVAL)
|
if self._epic_mode else bs.MusicType.SURVIVAL)
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
return 'Last team standing wins.' if isinstance(
|
return 'Last team standing wins.' if isinstance(
|
||||||
self.session, ba.DualTeamSession) else 'Last one standing wins.'
|
self.session, bs.DualTeamSession) else 'Last one standing wins.'
|
||||||
|
|
||||||
def get_instance_description_short(self) -> Union[str, Sequence]:
|
def get_instance_description_short(self) -> Union[str, Sequence]:
|
||||||
return 'last team standing wins' if isinstance(
|
return 'last team standing wins' if isinstance(
|
||||||
self.session, ba.DualTeamSession) else 'last one standing wins'
|
self.session, bs.DualTeamSession) else 'last one standing wins'
|
||||||
|
|
||||||
def on_player_join(self, player: Player) -> None:
|
def on_player_join(self, player: Player) -> None:
|
||||||
|
|
||||||
|
|
@ -275,9 +277,9 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if (self._get_total_team_lives(player.team) == 0
|
if (self._get_total_team_lives(player.team) == 0
|
||||||
and player.team.survival_seconds is None):
|
and player.team.survival_seconds is None):
|
||||||
player.team.survival_seconds = 0
|
player.team.survival_seconds = 0
|
||||||
ba.screenmessage(
|
bs.broadcastmessage(
|
||||||
ba.Lstr(resource='playerDelayedJoinText',
|
babase.Lstr(resource='playerDelayedJoinText',
|
||||||
subs=[('${PLAYER}', player.getname(full=True))]),
|
subs=[('${PLAYER}', player.getname(full=True))]),
|
||||||
color=(0, 1, 0),
|
color=(0, 1, 0),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -293,11 +295,11 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
self._start_time = ba.time()
|
self._start_time = bs.time()
|
||||||
self.setup_standard_time_limit(self._time_limit)
|
self.setup_standard_time_limit(self._time_limit)
|
||||||
self.setup_standard_powerup_drops()
|
self.setup_standard_powerup_drops()
|
||||||
self._vs_text = ba.NodeActor(
|
self._vs_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 92),
|
'position': (0, 92),
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -308,12 +310,12 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'scale': 0.6,
|
'scale': 0.6,
|
||||||
'v_attach': 'bottom',
|
'v_attach': 'bottom',
|
||||||
'color': (0.8, 0.8, 0.3, 1.0),
|
'color': (0.8, 0.8, 0.3, 1.0),
|
||||||
'text': ba.Lstr(resource='vsText')
|
'text': babase.Lstr(resource='vsText')
|
||||||
}))
|
}))
|
||||||
|
|
||||||
# If balance-team-lives is on, add lives to the smaller team until
|
# If balance-team-lives is on, add lives to the smaller team until
|
||||||
# total lives match.
|
# total lives match.
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._balance_total_lives and self.teams[0].players
|
and self._balance_total_lives and self.teams[0].players
|
||||||
and self.teams[1].players):
|
and self.teams[1].players):
|
||||||
if self._get_total_team_lives(
|
if self._get_total_team_lives(
|
||||||
|
|
@ -333,7 +335,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# We could check game-over conditions at explicit trigger points,
|
# We could check game-over conditions at explicit trigger points,
|
||||||
# but lets just do the simple thing and poll it.
|
# but lets just do the simple thing and poll it.
|
||||||
ba.timer(1.0, self._update, repeat=True)
|
bs.timer(1.0, self._update, repeat=True)
|
||||||
|
|
||||||
def _update_alliance_mode(self) -> None:
|
def _update_alliance_mode(self) -> None:
|
||||||
# For both teams, find the first player on the spawn order list with
|
# For both teams, find the first player on the spawn order list with
|
||||||
|
|
@ -391,10 +393,10 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
nplayers -= 1
|
nplayers -= 1
|
||||||
test_lives += 1
|
test_lives += 1
|
||||||
|
|
||||||
def _get_spawn_point(self, player: Player) -> Optional[ba.Vec3]:
|
def _get_spawn_point(self, player: Player) -> Optional[babase.Vec3]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
actor = self.spawn_player_spaz(player, self._get_spawn_point(player))
|
actor = self.spawn_player_spaz(player, self._get_spawn_point(player))
|
||||||
|
|
||||||
# If we have any icons, update their state.
|
# If we have any icons, update their state.
|
||||||
|
|
@ -403,7 +405,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
return actor
|
return actor
|
||||||
|
|
||||||
def _print_lives(self, player: Player) -> None:
|
def _print_lives(self, player: Player) -> None:
|
||||||
from bastd.actor import popuptext
|
from bascenev1lib.actor import popuptext
|
||||||
|
|
||||||
# We get called in a timer so it's possible our player has left/etc.
|
# We get called in a timer so it's possible our player has left/etc.
|
||||||
if not player or not player.is_alive() or not player.node:
|
if not player or not player.is_alive() or not player.node:
|
||||||
|
|
@ -426,20 +428,20 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Update icons in a moment since our team will be gone from the
|
# Update icons in a moment since our team will be gone from the
|
||||||
# list then.
|
# list then.
|
||||||
ba.timer(0, self._update_icons)
|
bs.timer(0, self._update_icons)
|
||||||
|
|
||||||
# If the player to leave was the last in spawn order and had
|
# If the player to leave was the last in spawn order and had
|
||||||
# their final turn currently in-progress, mark the survival time
|
# their final turn currently in-progress, mark the survival time
|
||||||
# for their team.
|
# for their team.
|
||||||
if self._get_total_team_lives(player.team) == 0:
|
if self._get_total_team_lives(player.team) == 0:
|
||||||
assert self._start_time is not None
|
assert self._start_time is not None
|
||||||
player.team.survival_seconds = int(ba.time() - self._start_time)
|
player.team.survival_seconds = int(bs.time() - self._start_time)
|
||||||
|
|
||||||
def _get_total_team_lives(self, team: Team) -> int:
|
def _get_total_team_lives(self, team: Team) -> int:
|
||||||
return sum(player.lives for player in team.players)
|
return sum(player.lives for player in team.players)
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
|
|
||||||
# Augment standard behavior.
|
# Augment standard behavior.
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
@ -447,7 +449,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
player.lives -= 1
|
player.lives -= 1
|
||||||
if player.lives < 0:
|
if player.lives < 0:
|
||||||
ba.print_error(
|
babase.print_error(
|
||||||
"Got lives < 0 in Alliance Elimination; this shouldn't happen.")
|
"Got lives < 0 in Alliance Elimination; this shouldn't happen.")
|
||||||
player.lives = 0
|
player.lives = 0
|
||||||
|
|
||||||
|
|
@ -458,14 +460,14 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# Play big death sound on our last death
|
# Play big death sound on our last death
|
||||||
# or for every one.
|
# or for every one.
|
||||||
if player.lives == 0:
|
if player.lives == 0:
|
||||||
ba.playsound(SpazFactory.get().single_player_death_sound)
|
SpazFactory.get().single_player_death_sound.play()
|
||||||
|
|
||||||
# If we hit zero lives, we're dead (and our team might be too).
|
# If we hit zero lives, we're dead (and our team might be too).
|
||||||
if player.lives == 0:
|
if player.lives == 0:
|
||||||
# If the whole team is now dead, mark their survival time.
|
# If the whole team is now dead, mark their survival time.
|
||||||
if self._get_total_team_lives(player.team) == 0:
|
if self._get_total_team_lives(player.team) == 0:
|
||||||
assert self._start_time is not None
|
assert self._start_time is not None
|
||||||
player.team.survival_seconds = int(ba.time() -
|
player.team.survival_seconds = int(bs.time() -
|
||||||
self._start_time)
|
self._start_time)
|
||||||
|
|
||||||
# Put ourself at the back of the spawn order.
|
# Put ourself at the back of the spawn order.
|
||||||
|
|
@ -493,7 +495,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# the game (allows the dust to settle and draws to occur if deaths
|
# the game (allows the dust to settle and draws to occur if deaths
|
||||||
# are close enough).
|
# are close enough).
|
||||||
if len(self._get_living_teams()) < 2:
|
if len(self._get_living_teams()) < 2:
|
||||||
self._round_end_timer = ba.Timer(0.5, self.end_game)
|
self._round_end_timer = bs.Timer(0.5, self.end_game)
|
||||||
|
|
||||||
def _get_living_teams(self) -> List[Team]:
|
def _get_living_teams(self) -> List[Team]:
|
||||||
return [
|
return [
|
||||||
|
|
@ -505,7 +507,7 @@ class AllianceEliminationGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
if self.has_ended():
|
if self.has_ended():
|
||||||
return
|
return
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
self._vs_text = None # Kill our 'vs' if its there.
|
self._vs_text = None # Kill our 'vs' if its there.
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.survival_seconds)
|
results.set_team_score(team, team.survival_seconds)
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
"2.0.0":null,
|
"2.0.0": {
|
||||||
|
"api_version": 8,
|
||||||
|
"commit_sha": "0c5ce76",
|
||||||
|
"released_on": "02-07-2023",
|
||||||
|
"md5sum": "8b05407fda379d853f5c75677b19fd85"
|
||||||
|
},
|
||||||
"1.2.1": {
|
"1.2.1": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "64e8a5c",
|
"commit_sha": "64e8a5c",
|
||||||
|
|
@ -417,7 +422,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
"2.0.0":null,
|
"2.0.0": {
|
||||||
|
"api_version": 8,
|
||||||
|
"commit_sha": "bf3e61b",
|
||||||
|
"released_on": "04-07-2023",
|
||||||
|
"md5sum": "289cc852b7f0ec1b254d08267c9921c2"
|
||||||
|
},
|
||||||
"1.0.1": {
|
"1.0.1": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "64e8a5c",
|
"commit_sha": "64e8a5c",
|
||||||
|
|
@ -443,7 +453,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
"2.0.0": null,
|
"2.0.0": {
|
||||||
|
"api_version": 8,
|
||||||
|
"commit_sha": "0c5ce76",
|
||||||
|
"released_on": "02-07-2023",
|
||||||
|
"md5sum": "bb5d85fb528020e809eaebb17a388e32"
|
||||||
|
},
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "ff4de19",
|
"commit_sha": "ff4de19",
|
||||||
|
|
@ -507,7 +522,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
"2.0.0":null,
|
"2.0.0": {
|
||||||
|
"api_version": 8,
|
||||||
|
"commit_sha": "a0239a9",
|
||||||
|
"released_on": "04-07-2023",
|
||||||
|
"md5sum": "187a9894158721c8fa1ecee9e3e38e73"
|
||||||
|
},
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "41e239c",
|
"commit_sha": "41e239c",
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ from bascenev1 import _lobby
|
||||||
from bascenev1lib.actor.spazappearance import *
|
from bascenev1lib.actor.spazappearance import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, vpos: float, sessionplayer: bs.SessionPlayer,
|
def __init__(self, vpos: float, sessionplayer: bs.SessionPlayer,
|
||||||
lobby: 'Lobby') -> None:
|
lobby: 'Lobby') -> None:
|
||||||
self._deek_sound = bs.getsound('deek')
|
self._deek_sound = bs.getsound('deek')
|
||||||
|
|
@ -113,25 +112,25 @@ def __init__(self, vpos: float, sessionplayer: bs.SessionPlayer,
|
||||||
self._profilename = self._profilenames[self._profileindex]
|
self._profilename = self._profilenames[self._profileindex]
|
||||||
|
|
||||||
self._text_node = bs.newnode('text',
|
self._text_node = bs.newnode('text',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (-100, self._vpos),
|
'position': (-100, self._vpos),
|
||||||
'maxwidth': 190,
|
'maxwidth': 190,
|
||||||
'shadow': 0.5,
|
'shadow': 0.5,
|
||||||
'vr_depth': -20,
|
'vr_depth': -20,
|
||||||
'h_align': 'left',
|
'h_align': 'left',
|
||||||
'v_align': 'center',
|
'v_align': 'center',
|
||||||
'v_attach': 'top'
|
'v_attach': 'top'
|
||||||
})
|
})
|
||||||
bs.animate(self._text_node, 'scale', {0: 0, 0.1: 1.0})
|
bs.animate(self._text_node, 'scale', {0: 0, 0.1: 1.0})
|
||||||
self.icon = bs.newnode('image',
|
self.icon = bs.newnode('image',
|
||||||
owner=self._text_node,
|
owner=self._text_node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (-130, self._vpos + 20),
|
'position': (-130, self._vpos + 20),
|
||||||
'mask_texture': self._mask_texture,
|
'mask_texture': self._mask_texture,
|
||||||
'vr_depth': -10,
|
'vr_depth': -10,
|
||||||
'attach': 'topCenter'
|
'attach': 'topCenter'
|
||||||
})
|
})
|
||||||
|
|
||||||
bs.animate_array(self.icon, 'scale', 2, {0: (0, 0), 0.1: (45, 45)})
|
bs.animate_array(self.icon, 'scale', 2, {0: (0, 0), 0.1: (45, 45)})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ def is_game_version_lower_than(version):
|
||||||
return game_version < version
|
return game_version < version
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def updateBannedServersCache():
|
def updateBannedServersCache():
|
||||||
response = None
|
response = None
|
||||||
config = babase.app.config
|
config = babase.app.config
|
||||||
|
|
@ -112,7 +111,7 @@ class _HostLookupThread(threading.Thread):
|
||||||
except Exception:
|
except Exception:
|
||||||
result = None
|
result = None
|
||||||
babase.pushcall(lambda: self._call(result, self._port),
|
babase.pushcall(lambda: self._call(result, self._port),
|
||||||
from_other_thread=True)
|
from_other_thread=True)
|
||||||
|
|
||||||
|
|
||||||
def newbuild_favorites_tab(self, region_height: float) -> None:
|
def newbuild_favorites_tab(self, region_height: float) -> None:
|
||||||
|
|
@ -148,45 +147,45 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
|
||||||
# ================= smoothy =============
|
# ================= smoothy =============
|
||||||
|
|
||||||
bui.textwidget(parent=self._container,
|
bui.textwidget(parent=self._container,
|
||||||
position=(90 if uiscale is babase.UIScale.SMALL else 120, btnv +
|
position=(90 if uiscale is babase.UIScale.SMALL else 120, btnv +
|
||||||
120 if uiscale is babase.UIScale.SMALL else btnv+90),
|
120 if uiscale is babase.UIScale.SMALL else btnv+90),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
color=(0.8, 0.8, 0.8),
|
color=(0.8, 0.8, 0.8),
|
||||||
v_align='top',
|
v_align='top',
|
||||||
text="Auto")
|
text="Auto")
|
||||||
btnv += 50 if uiscale is babase.UIScale.SMALL else 0
|
btnv += 50 if uiscale is babase.UIScale.SMALL else 0
|
||||||
|
|
||||||
bui.buttonwidget(parent=self._container,
|
bui.buttonwidget(parent=self._container,
|
||||||
size=(30, 30),
|
size=(30, 30),
|
||||||
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
||||||
btnv+10),
|
btnv+10),
|
||||||
|
|
||||||
color=(0.6, 0.53, 0.63),
|
color=(0.6, 0.53, 0.63),
|
||||||
textcolor=(0.75, 0.7, 0.8),
|
textcolor=(0.75, 0.7, 0.8),
|
||||||
on_activate_call=self.auto_retry_dec,
|
on_activate_call=self.auto_retry_dec,
|
||||||
text_scale=1.3 if uiscale is babase.UIScale.SMALL else 1.2,
|
text_scale=1.3 if uiscale is babase.UIScale.SMALL else 1.2,
|
||||||
label="-",
|
label="-",
|
||||||
autoselect=True)
|
autoselect=True)
|
||||||
self.retry_inter_text = bui.textwidget(parent=self._container,
|
self.retry_inter_text = bui.textwidget(parent=self._container,
|
||||||
position=(
|
position=(
|
||||||
90 if uiscale is babase.UIScale.SMALL else 120, btnv+25),
|
90 if uiscale is babase.UIScale.SMALL else 120, btnv+25),
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
color=(0.8, 0.8, 0.8),
|
color=(0.8, 0.8, 0.8),
|
||||||
v_align='center',
|
v_align='center',
|
||||||
text=str(self.retry_inter) if self.retry_inter > 0.0 else 'off')
|
text=str(self.retry_inter) if self.retry_inter > 0.0 else 'off')
|
||||||
bui.buttonwidget(parent=self._container,
|
bui.buttonwidget(parent=self._container,
|
||||||
size=(30, 30),
|
size=(30, 30),
|
||||||
position=(125 if uiscale is babase.UIScale.SMALL else 155,
|
position=(125 if uiscale is babase.UIScale.SMALL else 155,
|
||||||
btnv+10),
|
btnv+10),
|
||||||
|
|
||||||
color=(0.6, 0.53, 0.63),
|
color=(0.6, 0.53, 0.63),
|
||||||
textcolor=(0.75, 0.7, 0.8),
|
textcolor=(0.75, 0.7, 0.8),
|
||||||
on_activate_call=self.auto_retry_inc,
|
on_activate_call=self.auto_retry_inc,
|
||||||
text_scale=1.3 if uiscale is babase.UIScale.SMALL else 1.2,
|
text_scale=1.3 if uiscale is babase.UIScale.SMALL else 1.2,
|
||||||
label="+",
|
label="+",
|
||||||
autoselect=True)
|
autoselect=True)
|
||||||
|
|
||||||
btnv -= b_height + b_space_extra
|
btnv -= b_height + b_space_extra
|
||||||
|
|
||||||
|
|
@ -203,31 +202,31 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
|
||||||
autoselect=True)
|
autoselect=True)
|
||||||
if uiscale is babase.UIScale.SMALL and bui.app.ui_v1.use_toolbars:
|
if uiscale is babase.UIScale.SMALL and bui.app.ui_v1.use_toolbars:
|
||||||
bui.widget(edit=btn1,
|
bui.widget(edit=btn1,
|
||||||
left_widget=bui.get_special_widget('back_button'))
|
left_widget=bui.get_special_widget('back_button'))
|
||||||
btnv -= b_height + b_space_extra
|
btnv -= b_height + b_space_extra
|
||||||
bui.buttonwidget(parent=self._container,
|
bui.buttonwidget(parent=self._container,
|
||||||
size=(b_width, b_height),
|
size=(b_width, b_height),
|
||||||
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
||||||
btnv),
|
btnv),
|
||||||
button_type='square',
|
button_type='square',
|
||||||
color=(0.6, 0.53, 0.63),
|
color=(0.6, 0.53, 0.63),
|
||||||
textcolor=(0.75, 0.7, 0.8),
|
textcolor=(0.75, 0.7, 0.8),
|
||||||
on_activate_call=self._on_favorites_edit_press,
|
on_activate_call=self._on_favorites_edit_press,
|
||||||
text_scale=1.0 if uiscale is babase.UIScale.SMALL else 1.2,
|
text_scale=1.0 if uiscale is babase.UIScale.SMALL else 1.2,
|
||||||
label=babase.Lstr(resource='editText'),
|
label=babase.Lstr(resource='editText'),
|
||||||
autoselect=True)
|
autoselect=True)
|
||||||
btnv -= b_height + b_space_extra
|
btnv -= b_height + b_space_extra
|
||||||
bui.buttonwidget(parent=self._container,
|
bui.buttonwidget(parent=self._container,
|
||||||
size=(b_width, b_height),
|
size=(b_width, b_height),
|
||||||
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
position=(25 if uiscale is babase.UIScale.SMALL else 40,
|
||||||
btnv),
|
btnv),
|
||||||
button_type='square',
|
button_type='square',
|
||||||
color=(0.6, 0.53, 0.63),
|
color=(0.6, 0.53, 0.63),
|
||||||
textcolor=(0.75, 0.7, 0.8),
|
textcolor=(0.75, 0.7, 0.8),
|
||||||
on_activate_call=self._on_favorite_delete_press,
|
on_activate_call=self._on_favorite_delete_press,
|
||||||
text_scale=1.0 if uiscale is babase.UIScale.SMALL else 1.2,
|
text_scale=1.0 if uiscale is babase.UIScale.SMALL else 1.2,
|
||||||
label=babase.Lstr(resource='deleteText'),
|
label=babase.Lstr(resource='deleteText'),
|
||||||
autoselect=True)
|
autoselect=True)
|
||||||
|
|
||||||
v -= sub_scroll_height + 23
|
v -= sub_scroll_height + 23
|
||||||
self._scrollwidget = scrlw = bui.scrollwidget(
|
self._scrollwidget = scrlw = bui.scrollwidget(
|
||||||
|
|
@ -236,12 +235,12 @@ def newbuild_favorites_tab(self, region_height: float) -> None:
|
||||||
size=(sub_scroll_width, sub_scroll_height),
|
size=(sub_scroll_width, sub_scroll_height),
|
||||||
claims_left_right=True)
|
claims_left_right=True)
|
||||||
bui.widget(edit=self._favorites_connect_button,
|
bui.widget(edit=self._favorites_connect_button,
|
||||||
right_widget=self._scrollwidget)
|
right_widget=self._scrollwidget)
|
||||||
self._columnwidget = bui.columnwidget(parent=scrlw,
|
self._columnwidget = bui.columnwidget(parent=scrlw,
|
||||||
left_border=10,
|
left_border=10,
|
||||||
border=2,
|
border=2,
|
||||||
margin=0,
|
margin=0,
|
||||||
claims_left_right=True)
|
claims_left_right=True)
|
||||||
|
|
||||||
self._favorite_selected = None
|
self._favorite_selected = None
|
||||||
self._refresh_favorites()
|
self._refresh_favorites()
|
||||||
|
|
@ -327,133 +326,133 @@ def _clear(self) -> None:
|
||||||
widget.delete()
|
widget.delete()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
|
def update(self, index: int, party: PartyEntry, sub_scroll_width: float,
|
||||||
sub_scroll_height: float, lineheight: float,
|
sub_scroll_height: float, lineheight: float,
|
||||||
columnwidget: bui.Widget, join_text: bui.Widget,
|
columnwidget: bui.Widget, join_text: bui.Widget,
|
||||||
filter_text: bui.Widget, existing_selection: Optional[Selection],
|
filter_text: bui.Widget, existing_selection: Optional[Selection],
|
||||||
tab: PublicGatherTab) -> None:
|
tab: PublicGatherTab) -> None:
|
||||||
"""Update for the given data."""
|
"""Update for the given data."""
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
|
|
||||||
# Quick-out: if we've been marked clean for a certain index and
|
# Quick-out: if we've been marked clean for a certain index and
|
||||||
# we're still at that index, we're done.
|
# we're still at that index, we're done.
|
||||||
plus = bui.app.plus
|
plus = bui.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
|
|
||||||
# Quick-out: if we've been marked clean for a certain index and
|
# Quick-out: if we've been marked clean for a certain index and
|
||||||
# we're still at that index, we're done.
|
# we're still at that index, we're done.
|
||||||
if party.clean_display_index == index:
|
if party.clean_display_index == index:
|
||||||
return
|
return
|
||||||
|
|
||||||
ping_good = plus.get_v1_account_misc_read_val('pingGood', 100)
|
ping_good = plus.get_v1_account_misc_read_val('pingGood', 100)
|
||||||
ping_med = plus.get_v1_account_misc_read_val('pingMed', 500)
|
ping_med = plus.get_v1_account_misc_read_val('pingMed', 500)
|
||||||
|
|
||||||
self._clear()
|
self._clear()
|
||||||
hpos = 20
|
hpos = 20
|
||||||
vpos = sub_scroll_height - lineheight * index - 50
|
vpos = sub_scroll_height - lineheight * index - 50
|
||||||
self._name_widget = bui.textwidget(
|
self._name_widget = bui.textwidget(
|
||||||
text=bui.Lstr(value=party.name),
|
text=bui.Lstr(value=party.name),
|
||||||
|
parent=columnwidget,
|
||||||
|
size=(sub_scroll_width * 0.63, 20),
|
||||||
|
position=(0 + hpos, 4 + vpos),
|
||||||
|
selectable=True,
|
||||||
|
on_select_call=bui.WeakCall(
|
||||||
|
tab.set_public_party_selection,
|
||||||
|
Selection(party.get_key(), SelectionComponent.NAME),
|
||||||
|
),
|
||||||
|
on_activate_call=bui.WeakCall(tab.on_public_party_activate, party),
|
||||||
|
click_activate=True,
|
||||||
|
maxwidth=sub_scroll_width * 0.45,
|
||||||
|
corner_scale=1.4,
|
||||||
|
autoselect=True,
|
||||||
|
color=(1, 1, 1, 0.3 if party.ping is None else 1.0),
|
||||||
|
h_align='left',
|
||||||
|
v_align='center',
|
||||||
|
)
|
||||||
|
bui.widget(
|
||||||
|
edit=self._name_widget,
|
||||||
|
left_widget=join_text,
|
||||||
|
show_buffer_top=64.0,
|
||||||
|
show_buffer_bottom=64.0,
|
||||||
|
)
|
||||||
|
if existing_selection == Selection(
|
||||||
|
party.get_key(), SelectionComponent.NAME
|
||||||
|
):
|
||||||
|
bui.containerwidget(
|
||||||
|
edit=columnwidget, selected_child=self._name_widget
|
||||||
|
)
|
||||||
|
if party.stats_addr or True:
|
||||||
|
url = party.stats_addr.replace(
|
||||||
|
'${ACCOUNT}',
|
||||||
|
plus.get_v1_account_misc_read_val_2(
|
||||||
|
'resolvedAccountID', 'UNKNOWN'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self._stats_button = bui.buttonwidget(
|
||||||
|
color=(0.3, 0.6, 0.94),
|
||||||
|
textcolor=(1.0, 1.0, 1.0),
|
||||||
|
label='....',
|
||||||
parent=columnwidget,
|
parent=columnwidget,
|
||||||
size=(sub_scroll_width * 0.63, 20),
|
autoselect=True,
|
||||||
position=(0 + hpos, 4 + vpos),
|
on_activate_call=bui.Call(bui.open_url, url),
|
||||||
selectable=True,
|
|
||||||
on_select_call=bui.WeakCall(
|
on_select_call=bui.WeakCall(
|
||||||
tab.set_public_party_selection,
|
tab.set_public_party_selection,
|
||||||
Selection(party.get_key(), SelectionComponent.NAME),
|
Selection(party.get_key(), SelectionComponent.STATS_BUTTON),
|
||||||
),
|
),
|
||||||
on_activate_call=bui.WeakCall(tab.on_public_party_activate, party),
|
size=(120, 40),
|
||||||
click_activate=True,
|
position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
|
||||||
maxwidth=sub_scroll_width * 0.45,
|
scale=0.9,
|
||||||
corner_scale=1.4,
|
|
||||||
autoselect=True,
|
|
||||||
color=(1, 1, 1, 0.3 if party.ping is None else 1.0),
|
|
||||||
h_align='left',
|
|
||||||
v_align='center',
|
|
||||||
)
|
|
||||||
bui.widget(
|
|
||||||
edit=self._name_widget,
|
|
||||||
left_widget=join_text,
|
|
||||||
show_buffer_top=64.0,
|
|
||||||
show_buffer_bottom=64.0,
|
|
||||||
)
|
)
|
||||||
|
bui.buttonwidget(edit=self._stats_button, on_activate_call=bui.WeakCall(
|
||||||
|
self.on_stats_click, self._stats_button, party))
|
||||||
if existing_selection == Selection(
|
if existing_selection == Selection(
|
||||||
party.get_key(), SelectionComponent.NAME
|
party.get_key(), SelectionComponent.STATS_BUTTON
|
||||||
):
|
):
|
||||||
bui.containerwidget(
|
bui.containerwidget(
|
||||||
edit=columnwidget, selected_child=self._name_widget
|
edit=columnwidget, selected_child=self._stats_button
|
||||||
)
|
)
|
||||||
if party.stats_addr or True:
|
|
||||||
url = party.stats_addr.replace(
|
|
||||||
'${ACCOUNT}',
|
|
||||||
plus.get_v1_account_misc_read_val_2(
|
|
||||||
'resolvedAccountID', 'UNKNOWN'
|
|
||||||
),
|
|
||||||
)
|
|
||||||
self._stats_button = bui.buttonwidget(
|
|
||||||
color=(0.3, 0.6, 0.94),
|
|
||||||
textcolor=(1.0, 1.0, 1.0),
|
|
||||||
label='....',
|
|
||||||
parent=columnwidget,
|
|
||||||
autoselect=True,
|
|
||||||
on_activate_call=bui.Call(bui.open_url, url),
|
|
||||||
on_select_call=bui.WeakCall(
|
|
||||||
tab.set_public_party_selection,
|
|
||||||
Selection(party.get_key(), SelectionComponent.STATS_BUTTON),
|
|
||||||
),
|
|
||||||
size=(120, 40),
|
|
||||||
position=(sub_scroll_width * 0.66 + hpos, 1 + vpos),
|
|
||||||
scale=0.9,
|
|
||||||
)
|
|
||||||
bui.buttonwidget(edit=self._stats_button, on_activate_call=bui.WeakCall(
|
|
||||||
self.on_stats_click, self._stats_button, party))
|
|
||||||
if existing_selection == Selection(
|
|
||||||
party.get_key(), SelectionComponent.STATS_BUTTON
|
|
||||||
):
|
|
||||||
bui.containerwidget(
|
|
||||||
edit=columnwidget, selected_child=self._stats_button
|
|
||||||
)
|
|
||||||
|
|
||||||
self._size_widget = bui.textwidget(
|
self._size_widget = bui.textwidget(
|
||||||
text=str(party.size) + '/' + str(party.size_max),
|
text=str(party.size) + '/' + str(party.size_max),
|
||||||
parent=columnwidget,
|
parent=columnwidget,
|
||||||
size=(0, 0),
|
size=(0, 0),
|
||||||
position=(sub_scroll_width * 0.86 + hpos, 20 + vpos),
|
position=(sub_scroll_width * 0.86 + hpos, 20 + vpos),
|
||||||
scale=0.7,
|
scale=0.7,
|
||||||
color=(0.8, 0.8, 0.8),
|
color=(0.8, 0.8, 0.8),
|
||||||
h_align='right',
|
h_align='right',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
|
)
|
||||||
|
|
||||||
|
if index == 0:
|
||||||
|
bui.widget(edit=self._name_widget, up_widget=filter_text)
|
||||||
|
if self._stats_button:
|
||||||
|
bui.widget(edit=self._stats_button, up_widget=filter_text)
|
||||||
|
|
||||||
|
self._ping_widget = bui.textwidget(
|
||||||
|
parent=columnwidget,
|
||||||
|
size=(0, 0),
|
||||||
|
position=(sub_scroll_width * 0.94 + hpos, 20 + vpos),
|
||||||
|
scale=0.7,
|
||||||
|
h_align='right',
|
||||||
|
v_align='center',
|
||||||
|
)
|
||||||
|
if party.ping is None:
|
||||||
|
bui.textwidget(
|
||||||
|
edit=self._ping_widget, text='-', color=(0.5, 0.5, 0.5)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
bui.textwidget(
|
||||||
|
edit=self._ping_widget,
|
||||||
|
text=str(int(party.ping)),
|
||||||
|
color=(0, 1, 0)
|
||||||
|
if party.ping <= ping_good
|
||||||
|
else (1, 1, 0)
|
||||||
|
if party.ping <= ping_med
|
||||||
|
else (1, 0, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
if index == 0:
|
party.clean_display_index = index
|
||||||
bui.widget(edit=self._name_widget, up_widget=filter_text)
|
|
||||||
if self._stats_button:
|
|
||||||
bui.widget(edit=self._stats_button, up_widget=filter_text)
|
|
||||||
|
|
||||||
self._ping_widget = bui.textwidget(
|
|
||||||
parent=columnwidget,
|
|
||||||
size=(0, 0),
|
|
||||||
position=(sub_scroll_width * 0.94 + hpos, 20 + vpos),
|
|
||||||
scale=0.7,
|
|
||||||
h_align='right',
|
|
||||||
v_align='center',
|
|
||||||
)
|
|
||||||
if party.ping is None:
|
|
||||||
bui.textwidget(
|
|
||||||
edit=self._ping_widget, text='-', color=(0.5, 0.5, 0.5)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
bui.textwidget(
|
|
||||||
edit=self._ping_widget,
|
|
||||||
text=str(int(party.ping)),
|
|
||||||
color=(0, 1, 0)
|
|
||||||
if party.ping <= ping_good
|
|
||||||
else (1, 1, 0)
|
|
||||||
if party.ping <= ping_med
|
|
||||||
else (1, 0, 0),
|
|
||||||
)
|
|
||||||
|
|
||||||
party.clean_display_index = index
|
|
||||||
|
|
||||||
def _get_popup_window_scale() -> float:
|
def _get_popup_window_scale() -> float:
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
|
@ -501,7 +500,7 @@ def popup_menu_selected_choice(self, window: popup.PopupMenu,
|
||||||
url = _party.stats_addr.replace(
|
url = _party.stats_addr.replace(
|
||||||
'${ACCOUNT}',
|
'${ACCOUNT}',
|
||||||
plus.get_v1_account_misc_read_val_2('resolvedAccountID',
|
plus.get_v1_account_misc_read_val_2('resolvedAccountID',
|
||||||
'UNKNOWN'))
|
'UNKNOWN'))
|
||||||
bui.open_url(url)
|
bui.open_url(url)
|
||||||
elif choice == 'connect':
|
elif choice == 'connect':
|
||||||
PartyQuickConnect(_party.address, _party.port)
|
PartyQuickConnect(_party.address, _party.port)
|
||||||
|
|
@ -614,17 +613,17 @@ class PartyQuickConnect(bui.Window):
|
||||||
scale=(1.4 if uiscale is babase.UIScale.SMALL else
|
scale=(1.4 if uiscale is babase.UIScale.SMALL else
|
||||||
1.2 if uiscale is babase.UIScale.MEDIUM else 1.0)))
|
1.2 if uiscale is babase.UIScale.MEDIUM else 1.0)))
|
||||||
self._cancel_button = bui.buttonwidget(parent=self._root_widget,
|
self._cancel_button = bui.buttonwidget(parent=self._root_widget,
|
||||||
scale=1.0,
|
scale=1.0,
|
||||||
position=(60, self._height - 80),
|
position=(60, self._height - 80),
|
||||||
size=(50, 50),
|
size=(50, 50),
|
||||||
label='',
|
label='',
|
||||||
on_activate_call=self.close,
|
on_activate_call=self.close,
|
||||||
autoselect=True,
|
autoselect=True,
|
||||||
color=(0.45, 0.63, 0.15),
|
color=(0.45, 0.63, 0.15),
|
||||||
icon=bui.gettexture('crossOut'),
|
icon=bui.gettexture('crossOut'),
|
||||||
iconscale=1.2)
|
iconscale=1.2)
|
||||||
bui.containerwidget(edit=self._root_widget,
|
bui.containerwidget(edit=self._root_widget,
|
||||||
cancel_button=self._cancel_button)
|
cancel_button=self._cancel_button)
|
||||||
|
|
||||||
self.IP = bui.textwidget(
|
self.IP = bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,23 @@ import _baplus
|
||||||
import babase
|
import babase
|
||||||
|
|
||||||
|
|
||||||
|
def is_game_version_lower_than(version):
|
||||||
|
"""
|
||||||
|
Returns a boolean value indicating whether the current game
|
||||||
|
version is lower than the passed version. Useful for addressing
|
||||||
|
any breaking changes within game versions.
|
||||||
|
"""
|
||||||
|
game_version = tuple(map(int, babase.app.version.split(".")))
|
||||||
|
version = tuple(map(int, version.split(".")))
|
||||||
|
return game_version < version
|
||||||
|
|
||||||
|
|
||||||
|
if is_game_version_lower_than("1.7.20"):
|
||||||
|
original_get_purchased = _baplus.get_purchased
|
||||||
|
else:
|
||||||
|
assert bs.app.plus is not None
|
||||||
|
original_get_purchased = bs.app.plus.get_purchased
|
||||||
|
|
||||||
original_get_purchased = _baplus.get_purchased
|
|
||||||
|
|
||||||
def get_purchased(item):
|
def get_purchased(item):
|
||||||
if item.startswith('characters.') or item.startswith('icons.'):
|
if item.startswith('characters.') or item.startswith('icons.'):
|
||||||
|
|
@ -17,5 +32,8 @@ def get_purchased(item):
|
||||||
class Unlock(babase.Plugin):
|
class Unlock(babase.Plugin):
|
||||||
def on_app_running(self):
|
def on_app_running(self):
|
||||||
babase.app.classic.accounts.have_pro = lambda: True
|
babase.app.classic.accounts.have_pro = lambda: True
|
||||||
_baplus.get_purchased = get_purchased
|
if is_game_version_lower_than("1.7.20"):
|
||||||
|
_baplus.get_purchased = get_purchased
|
||||||
|
else:
|
||||||
|
assert bs.app.plus is not None
|
||||||
|
bs.app.plus.get_purchased = get_purchased
|
||||||
|
|
|
||||||
|
|
@ -1,108 +1,575 @@
|
||||||
# -*- coding: utf-8 -*-
|
# discord @mr.smoothy#5824
|
||||||
# ba_meta require api 8
|
|
||||||
'''
|
# ba_meta require api 8
|
||||||
Server Switch Plugin by My.Smoothy
|
|
||||||
Let you switch recently joined servers very quickly
|
from __future__ import annotations
|
||||||
+ Added button to quicky look into public server list without leaving current game.
|
import copy
|
||||||
|
import time
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
discord: mr.smoothy
|
|
||||||
https://discord.gg/ucyaesh
|
|
||||||
Youtube : Hey Smoothy
|
|
||||||
Download more mods from
|
|
||||||
https://bombsquad-community.web.app/mods
|
|
||||||
'''
|
|
||||||
import babase
|
import babase
|
||||||
import bauiv1lib.mainmenu as bastd_ui_mainmenu
|
|
||||||
import bauiv1 as bui
|
import bauiv1 as bui
|
||||||
import bascenev1 as bs
|
import bascenev1 as bs
|
||||||
current_server_ip = "127.0.0.1"
|
import _bascenev1 as _bs
|
||||||
current_server_port = 43210
|
import time
|
||||||
servers = []
|
import threading
|
||||||
def _refresh_in_game(func):
|
from enum import Enum
|
||||||
def wrapper(self, *args, **kwargs):
|
from dataclasses import dataclass
|
||||||
returnValue = func(self, *args, **kwargs)
|
if TYPE_CHECKING:
|
||||||
uiscale = bui.app.ui_v1.uiscale
|
from typing import Any, Optional, Dict, List, Tuple, Type
|
||||||
bui.containerwidget(
|
import bascenev1 as bs
|
||||||
edit=self._root_widget,
|
from bauiv1lib.gather import GatherWindow
|
||||||
size=(self._width*2, self._height), # double the width
|
|
||||||
scale=(
|
from bauiv1lib.confirm import ConfirmWindow
|
||||||
2.15
|
|
||||||
if uiscale is bui.UIScale.SMALL
|
import bauiv1lib.mainmenu as bastd_ui_mainmenu
|
||||||
else 1.6
|
|
||||||
if uiscale is bui.UIScale.MEDIUM
|
connect = bs.connect_to_party
|
||||||
else 1.0
|
disconnect = bs.disconnect_from_host
|
||||||
),
|
|
||||||
)
|
server = []
|
||||||
h = 125
|
|
||||||
v = self._height - 60.0
|
ip_add = "private"
|
||||||
bui.textwidget(
|
p_port = 44444
|
||||||
|
p_name = "nothing here"
|
||||||
|
|
||||||
|
|
||||||
|
def newconnect_to_party(address, port=43210, print_progress=False):
|
||||||
|
global ip_add
|
||||||
|
global p_port
|
||||||
|
dd = _bs.get_connection_to_host_info()
|
||||||
|
if (dd != {}):
|
||||||
|
_bs.disconnect_from_host()
|
||||||
|
|
||||||
|
ip_add = address
|
||||||
|
p_port = port
|
||||||
|
connect(address, port, print_progress)
|
||||||
|
else:
|
||||||
|
|
||||||
|
ip_add = address
|
||||||
|
p_port = port
|
||||||
|
# print(ip_add,p_port)
|
||||||
|
connect(ip_add, port, print_progress)
|
||||||
|
|
||||||
|
|
||||||
|
def newdisconnect_from_host():
|
||||||
|
try:
|
||||||
|
name = _bs.get_connection_to_host_info()['name']
|
||||||
|
global server
|
||||||
|
global ip_add
|
||||||
|
global p_port
|
||||||
|
pojo = {"name": name, "ip": ip_add, "port": p_port}
|
||||||
|
if pojo not in server:
|
||||||
|
server.insert(0, pojo)
|
||||||
|
server = server[:3]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
def printip():
|
||||||
|
bs.screenmessage("ip address is"+ip_add)
|
||||||
|
|
||||||
|
|
||||||
|
def new_refresh_in_game(
|
||||||
|
self, positions: List[Tuple[float, float,
|
||||||
|
float]]) -> Tuple[float, float, float]:
|
||||||
|
# pylint: disable=too-many-branches
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
|
custom_menu_entries: List[Dict[str, Any]] = []
|
||||||
|
session = _bs.get_foreground_host_session()
|
||||||
|
if session is not None:
|
||||||
|
try:
|
||||||
|
custom_menu_entries = session.get_custom_menu_entries()
|
||||||
|
for cme in custom_menu_entries:
|
||||||
|
if (not isinstance(cme, dict) or 'label' not in cme
|
||||||
|
or not isinstance(cme['label'], (str, bs.Lstr))
|
||||||
|
or 'call' not in cme or not callable(cme['call'])):
|
||||||
|
raise ValueError('invalid custom menu entry: ' +
|
||||||
|
str(cme))
|
||||||
|
except Exception:
|
||||||
|
custom_menu_entries = []
|
||||||
|
babase.print_exception(
|
||||||
|
f'Error getting custom menu entries for {session}')
|
||||||
|
self._width = 250.0
|
||||||
|
self._height = 250.0 if self._input_player else 180.0
|
||||||
|
if (self._is_demo or self._is_arcade) and self._input_player:
|
||||||
|
self._height -= 40
|
||||||
|
if not self._have_settings_button:
|
||||||
|
self._height -= 50
|
||||||
|
if self._connected_to_remote_player:
|
||||||
|
# In this case we have a leave *and* a disconnect button.
|
||||||
|
self._height += 50
|
||||||
|
self._height += 50 * (len(custom_menu_entries))
|
||||||
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
bui.containerwidget(
|
||||||
|
edit=self._root_widget,
|
||||||
|
size=(self._width*2, self._height),
|
||||||
|
scale=(2.15 if uiscale is bui.UIScale.SMALL else
|
||||||
|
1.6 if uiscale is bui.UIScale.MEDIUM else 1.0))
|
||||||
|
h = 125.0
|
||||||
|
v = (self._height - 80.0 if self._input_player else self._height - 60)
|
||||||
|
h_offset = 0
|
||||||
|
d_h_offset = 0
|
||||||
|
v_offset = -50
|
||||||
|
for _i in range(6 + len(custom_menu_entries)):
|
||||||
|
positions.append((h, v, 1.0))
|
||||||
|
v += v_offset
|
||||||
|
h += h_offset
|
||||||
|
h_offset += d_h_offset
|
||||||
|
self._start_button = None
|
||||||
|
bui.app.pause()
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
bui.textwidget(
|
||||||
parent=self._root_widget,
|
parent=self._root_widget,
|
||||||
draw_controller=None,
|
draw_controller=None,
|
||||||
text="IP: "+current_server_ip+" PORT: "+str(current_server_port),
|
text="IP: "+ip_add+" PORT: "+str(p_port),
|
||||||
position=(h-self._button_width/2 + 130 , v+60),
|
position=(h+self._button_width-80, v+60),
|
||||||
h_align='center',
|
h_align='center',
|
||||||
v_align='center',
|
v_align='center',
|
||||||
size=(20, 60),
|
size=(20, 60),
|
||||||
scale=0.6)
|
scale=0.6)
|
||||||
self._public_servers = bui.buttonwidget(
|
v_h = v
|
||||||
color=(0.8, 0.45, 1),
|
|
||||||
parent=self._root_widget,
|
|
||||||
position=(h+self._button_width-10, v+60+20),
|
|
||||||
size=(self._button_width/4, self._button_height/2),
|
|
||||||
scale=1.0,
|
|
||||||
autoselect=self._use_autoselect,
|
|
||||||
label="~~~",
|
|
||||||
on_activate_call=bs.Call(public_servers))
|
|
||||||
for server in servers:
|
|
||||||
self._server_button = bui.buttonwidget(
|
|
||||||
color=(0.8, 0, 1),
|
|
||||||
parent=self._root_widget,
|
|
||||||
position=( (h- self._button_width / 2 ) + self._button_width + 20, v),
|
|
||||||
size=(self._button_width, self._button_height),
|
|
||||||
scale=1.0,
|
|
||||||
autoselect=self._use_autoselect,
|
|
||||||
label=server["name"][0:22],
|
|
||||||
on_activate_call=bs.Call(bs.connect_to_party, server["ip"], server["port"]))
|
|
||||||
|
|
||||||
v -= 50
|
global server
|
||||||
|
|
||||||
return returnValue
|
def con(address, port):
|
||||||
return wrapper
|
global ip_add
|
||||||
|
global p_port
|
||||||
|
if (address == ip_add and port == p_port):
|
||||||
|
self._resume()
|
||||||
|
else:
|
||||||
|
_bs.disconnect_from_host()
|
||||||
|
_bs.connect_to_party(address, port)
|
||||||
|
if len(server) == 0:
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
draw_controller=None,
|
||||||
|
text="Nothing in \n recents",
|
||||||
|
position=(h + self._button_width * scale, v-30),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
size=(20, 60),
|
||||||
|
scale=1)
|
||||||
|
for ser in server:
|
||||||
|
self._server_button = bui.buttonwidget(
|
||||||
|
color=(0.8, 0, 1),
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h + self._button_width * scale - 80, v_h),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=ser["name"][0:22],
|
||||||
|
|
||||||
connect = bs.connect_to_party
|
on_activate_call=bs.Call(con, ser["ip"], ser["port"]))
|
||||||
def connect_to_party(address, port=43210, print_progress=False):
|
v_h = v_h-50
|
||||||
global current_server_ip
|
|
||||||
global current_server_port
|
|
||||||
if (bs.get_connection_to_host_info() != {}):
|
|
||||||
bs.disconnect_from_host()
|
|
||||||
current_server_ip = address
|
|
||||||
current_server_port = port
|
|
||||||
connect(address, port, print_progress)
|
|
||||||
babase.apptimer(1, check_connect_status)
|
|
||||||
|
|
||||||
def check_connect_status():
|
# Player name if applicable.
|
||||||
global servers
|
if self._input_player:
|
||||||
global current_server_ip
|
player_name = self._input_player.getname()
|
||||||
global current_server_port
|
h, v, scale = positions[self._p_index]
|
||||||
if (bs.get_connection_to_host_info() != {}):
|
v += 35
|
||||||
if (not bs.get_connection_to_host_info()['name']):
|
bui.textwidget(parent=self._root_widget,
|
||||||
babase.apptimer(1, check_connect_status)
|
position=(h - self._button_width / 2, v),
|
||||||
return
|
size=(self._button_width, self._button_height),
|
||||||
new_server = {"name": bs.get_connection_to_host_info()['name'], "ip": current_server_ip, "port": current_server_port}
|
color=(1, 1, 1, 0.5),
|
||||||
if new_server not in servers:
|
scale=0.7,
|
||||||
servers.append(new_server)
|
h_align='center',
|
||||||
servers = servers[-3:]
|
text=bs.Lstr(value=player_name))
|
||||||
else:
|
else:
|
||||||
print("connection failed falling back to gather window")
|
player_name = ''
|
||||||
public_servers()
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
btn = bui.buttonwidget(parent=self._root_widget,
|
||||||
|
position=(h - self._button_width / 2, v),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
label=bs.Lstr(resource=self._r + '.resumeText'),
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
on_activate_call=self._resume)
|
||||||
|
bui.containerwidget(edit=self._root_widget, cancel_button=btn)
|
||||||
|
|
||||||
|
# Add any custom options defined by the current game.
|
||||||
|
for entry in custom_menu_entries:
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
|
||||||
|
# Ask the entry whether we should resume when we call
|
||||||
|
# it (defaults to true).
|
||||||
|
resume = bool(entry.get('resume_on_call', True))
|
||||||
|
|
||||||
|
if resume:
|
||||||
|
call = bs.Call(self._resume_and_call, entry['call'])
|
||||||
|
else:
|
||||||
|
call = bs.Call(entry['call'], bs.WeakCall(self._resume))
|
||||||
|
|
||||||
|
bui.buttonwidget(parent=self._root_widget,
|
||||||
|
position=(h - self._button_width / 2, v),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
on_activate_call=call,
|
||||||
|
label=entry['label'],
|
||||||
|
autoselect=self._use_autoselect)
|
||||||
|
# Add a 'leave' button if the menu-owner has a player.
|
||||||
|
if ((self._input_player or self._connected_to_remote_player)
|
||||||
|
and not (self._is_demo or self._is_arcade)):
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
btn = bui.buttonwidget(parent=self._root_widget,
|
||||||
|
position=(h - self._button_width / 2, v),
|
||||||
|
size=(self._button_width,
|
||||||
|
self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
on_activate_call=self._leave,
|
||||||
|
label='',
|
||||||
|
autoselect=self._use_autoselect)
|
||||||
|
|
||||||
|
if (player_name != '' and player_name[0] != '<'
|
||||||
|
and player_name[-1] != '>'):
|
||||||
|
txt = bs.Lstr(resource=self._r + '.justPlayerText',
|
||||||
|
subs=[('${NAME}', player_name)])
|
||||||
|
else:
|
||||||
|
txt = bs.Lstr(value=player_name)
|
||||||
|
bui.textwidget(parent=self._root_widget,
|
||||||
|
position=(h, v + self._button_height *
|
||||||
|
(0.64 if player_name != '' else 0.5)),
|
||||||
|
size=(0, 0),
|
||||||
|
text=bs.Lstr(resource=self._r + '.leaveGameText'),
|
||||||
|
scale=(0.83 if player_name != '' else 1.0),
|
||||||
|
color=(0.75, 1.0, 0.7),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
draw_controller=btn,
|
||||||
|
maxwidth=self._button_width * 0.9)
|
||||||
|
bui.textwidget(parent=self._root_widget,
|
||||||
|
position=(h, v + self._button_height * 0.27),
|
||||||
|
size=(0, 0),
|
||||||
|
text=txt,
|
||||||
|
color=(0.75, 1.0, 0.7),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
draw_controller=btn,
|
||||||
|
scale=0.45,
|
||||||
|
maxwidth=self._button_width * 0.9)
|
||||||
|
return h, v, scale
|
||||||
|
|
||||||
|
|
||||||
|
def new_refresh(self) -> None:
|
||||||
|
# pylint: disable=too-many-branches
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
|
global server
|
||||||
|
print(server)
|
||||||
|
from bauiv1lib.confirm import QuitWindow
|
||||||
|
from bauiv1lib.store.button import StoreButton
|
||||||
|
import bascenev1 as bs
|
||||||
|
import _bascenev1 as _bs
|
||||||
|
import bauiv1 as bui
|
||||||
|
import _baplus
|
||||||
|
# Clear everything that was there.
|
||||||
|
children = self._root_widget.get_children()
|
||||||
|
for child in children:
|
||||||
|
child.delete()
|
||||||
|
|
||||||
|
self._tdelay = 0.0
|
||||||
|
self._t_delay_inc = 0.0
|
||||||
|
self._t_delay_play = 0.0
|
||||||
|
self._button_width = 200.0
|
||||||
|
self._button_height = 45.0
|
||||||
|
|
||||||
|
self._r = 'mainMenu'
|
||||||
|
|
||||||
|
assert bs.app.classic is not None
|
||||||
|
app = bs.app.classic
|
||||||
|
self._have_quit_button = (bui.app.ui_v1.uiscale is bui.UIScale.LARGE
|
||||||
|
or (app.platform == 'windows'
|
||||||
|
and app.subplatform == 'oculus'))
|
||||||
|
|
||||||
|
self._have_store_button = not self._in_game
|
||||||
|
|
||||||
|
self._have_settings_button = (
|
||||||
|
(not self._in_game or not bui.app.toolbar_test)
|
||||||
|
and not (self._is_demo or self._is_arcade or self._is_iircade))
|
||||||
|
|
||||||
|
self._input_device = input_device = _bs.get_ui_input_device()
|
||||||
|
self._input_player = input_device.player if input_device else None
|
||||||
|
self._connected_to_remote_player = (
|
||||||
|
input_device.is_attached_to_player()
|
||||||
|
if input_device else False)
|
||||||
|
|
||||||
|
positions: List[Tuple[float, float, float]] = []
|
||||||
|
self._p_index = 0
|
||||||
|
|
||||||
|
if self._in_game:
|
||||||
|
h, v, scale = self._refresh_in_game(positions)
|
||||||
|
print("refreshing in GAME", ip_add)
|
||||||
|
# btn = bui.buttonwidget(parent=self._root_widget,
|
||||||
|
# position=(80,270),
|
||||||
|
# size=(100, 90),
|
||||||
|
# scale=1.2,
|
||||||
|
# label=ip_add,
|
||||||
|
# autoselect=None,
|
||||||
|
# on_activate_call=printip)
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
draw_controller=None,
|
||||||
|
text="IP: "+ip_add+" PORT: "+str(p_port),
|
||||||
|
position=(150, 270),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
size=(20, 60),
|
||||||
|
scale=1)
|
||||||
|
self._server_button = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h * 3.2 + 20 - self._button_width * scale, v),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.settingsText'),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
on_activate_call=self._settings)
|
||||||
|
self._server_button2 = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h * 3.2 + 20 - self._button_width * scale, v-50),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.settingsText'),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
on_activate_call=self._settings)
|
||||||
|
self._server_button3 = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h * 3.2 + 20 - self._button_width * scale, v-100),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.settingsText'),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
on_activate_call=self._settings)
|
||||||
|
|
||||||
|
else:
|
||||||
|
h, v, scale = self._refresh_not_in_game(positions)
|
||||||
|
|
||||||
|
if self._have_settings_button:
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
self._settings_button = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h - self._button_width * 0.5 * scale, v),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.settingsText'),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
on_activate_call=self._settings)
|
||||||
|
|
||||||
|
# Scattered eggs on easter.
|
||||||
|
if _baplus.get_v1_account_misc_read_val('easter',
|
||||||
|
False) and not self._in_game:
|
||||||
|
icon_size = 34
|
||||||
|
bui.imagewidget(parent=self._root_widget,
|
||||||
|
position=(h - icon_size * 0.5 - 15,
|
||||||
|
v + self._button_height * scale -
|
||||||
|
icon_size * 0.24 + 1.5),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
size=(icon_size, icon_size),
|
||||||
|
texture=bui.gettexture('egg3'),
|
||||||
|
tilt_scale=0.0)
|
||||||
|
|
||||||
|
self._tdelay += self._t_delay_inc
|
||||||
|
|
||||||
|
if self._in_game:
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
|
||||||
|
# If we're in a replay, we have a 'Leave Replay' button.
|
||||||
|
if _bs.is_in_replay():
|
||||||
|
bui.buttonwidget(parent=self._root_widget,
|
||||||
|
position=(h - self._button_width * 0.5 * scale,
|
||||||
|
v),
|
||||||
|
scale=scale,
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource='replayEndText'),
|
||||||
|
on_activate_call=self._confirm_end_replay)
|
||||||
|
elif _bs.get_foreground_host_session() is not None:
|
||||||
|
bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h - self._button_width * 0.5 * scale, v),
|
||||||
|
scale=scale,
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.endGameText'),
|
||||||
|
on_activate_call=self._confirm_end_game)
|
||||||
|
# Assume we're in a client-session.
|
||||||
|
else:
|
||||||
|
bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h - self._button_width * 0.5 * scale, v),
|
||||||
|
scale=scale,
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
label=bs.Lstr(resource=self._r + '.leavePartyText'),
|
||||||
|
on_activate_call=self._confirm_leave_party)
|
||||||
|
|
||||||
|
self._store_button: Optional[bui.Widget]
|
||||||
|
if self._have_store_button:
|
||||||
|
this_b_width = self._button_width
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
|
||||||
|
sbtn = self._store_button_instance = StoreButton(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h - this_b_width * 0.5 * scale, v),
|
||||||
|
size=(this_b_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
on_activate_call=bs.WeakCall(self._on_store_pressed),
|
||||||
|
sale_scale=1.3,
|
||||||
|
transition_delay=self._tdelay)
|
||||||
|
self._store_button = store_button = sbtn.get_button()
|
||||||
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
icon_size = (55 if uiscale is bui.UIScale.SMALL else
|
||||||
|
55 if uiscale is bui.UIScale.MEDIUM else 70)
|
||||||
|
bui.imagewidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h - icon_size * 0.5,
|
||||||
|
v + self._button_height * scale - icon_size * 0.23),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
size=(icon_size, icon_size),
|
||||||
|
texture=bui.gettexture(self._store_char_tex),
|
||||||
|
tilt_scale=0.0,
|
||||||
|
draw_controller=store_button)
|
||||||
|
|
||||||
|
self._tdelay += self._t_delay_inc
|
||||||
|
else:
|
||||||
|
self._store_button = None
|
||||||
|
|
||||||
|
self._quit_button: Optional[bui.Widget]
|
||||||
|
if not self._in_game and self._have_quit_button:
|
||||||
|
h, v, scale = positions[self._p_index]
|
||||||
|
self._p_index += 1
|
||||||
|
self._quit_button = quit_button = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
autoselect=self._use_autoselect,
|
||||||
|
position=(h - self._button_width * 0.5 * scale, v),
|
||||||
|
size=(self._button_width, self._button_height),
|
||||||
|
scale=scale,
|
||||||
|
label=bs.Lstr(resource=self._r +
|
||||||
|
('.quitText' if 'Mac' in
|
||||||
|
bs.app.classic.legacy_user_agent_string else '.exitGameText')),
|
||||||
|
on_activate_call=self._quit,
|
||||||
|
transition_delay=self._tdelay)
|
||||||
|
|
||||||
|
# Scattered eggs on easter.
|
||||||
|
if _baplus.get_v1_account_misc_read_val('easter', False):
|
||||||
|
icon_size = 30
|
||||||
|
bui.imagewidget(parent=self._root_widget,
|
||||||
|
position=(h - icon_size * 0.5 + 25,
|
||||||
|
v + self._button_height * scale -
|
||||||
|
icon_size * 0.24 + 1.5),
|
||||||
|
transition_delay=self._tdelay,
|
||||||
|
size=(icon_size, icon_size),
|
||||||
|
texture=bui.gettexture('egg1'),
|
||||||
|
tilt_scale=0.0)
|
||||||
|
|
||||||
|
bui.containerwidget(edit=self._root_widget,
|
||||||
|
cancel_button=quit_button)
|
||||||
|
self._tdelay += self._t_delay_inc
|
||||||
|
else:
|
||||||
|
self._quit_button = None
|
||||||
|
|
||||||
|
# If we're not in-game, have no quit button, and this is android,
|
||||||
|
# we want back presses to quit our activity.
|
||||||
|
if (not self._in_game and not self._have_quit_button
|
||||||
|
and bs.app.classic.platform == 'android'):
|
||||||
|
|
||||||
|
def _do_quit() -> None:
|
||||||
|
QuitWindow(swish=True, back=True)
|
||||||
|
|
||||||
|
bui.containerwidget(edit=self._root_widget,
|
||||||
|
on_cancel_call=_do_quit)
|
||||||
|
|
||||||
|
# Add speed-up/slow-down buttons for replays.
|
||||||
|
# (ideally this should be part of a fading-out playback bar like most
|
||||||
|
# media players but this works for now).
|
||||||
|
if _bs.is_in_replay():
|
||||||
|
b_size = 50.0
|
||||||
|
b_buffer = 10.0
|
||||||
|
t_scale = 0.75
|
||||||
|
uiscale = bui.app.ui_v1.uiscale
|
||||||
|
if uiscale is bui.UIScale.SMALL:
|
||||||
|
b_size *= 0.6
|
||||||
|
b_buffer *= 1.0
|
||||||
|
v_offs = -40
|
||||||
|
t_scale = 0.5
|
||||||
|
elif uiscale is bui.UIScale.MEDIUM:
|
||||||
|
v_offs = -70
|
||||||
|
else:
|
||||||
|
v_offs = -100
|
||||||
|
self._replay_speed_text = bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
text=bs.Lstr(resource='watchWindow.playbackSpeedText',
|
||||||
|
subs=[('${SPEED}', str(1.23))]),
|
||||||
|
position=(h, v + v_offs + 7 * t_scale),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
size=(0, 0),
|
||||||
|
scale=t_scale)
|
||||||
|
|
||||||
|
# Update to current value.
|
||||||
|
self._change_replay_speed(0)
|
||||||
|
|
||||||
|
# Keep updating in a timer in case it gets changed elsewhere.
|
||||||
|
self._change_replay_speed_timer = bs.Timer(
|
||||||
|
0.25,
|
||||||
|
bs.WeakCall(self._change_replay_speed, 0),
|
||||||
|
repeat=True)
|
||||||
|
btn = bui.buttonwidget(parent=self._root_widget,
|
||||||
|
position=(h - b_size - b_buffer,
|
||||||
|
v - b_size - b_buffer + v_offs),
|
||||||
|
button_type='square',
|
||||||
|
size=(b_size, b_size),
|
||||||
|
label='',
|
||||||
|
autoselect=True,
|
||||||
|
on_activate_call=bs.Call(
|
||||||
|
self._change_replay_speed, -1))
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
draw_controller=btn,
|
||||||
|
text='-',
|
||||||
|
position=(h - b_size * 0.5 - b_buffer,
|
||||||
|
v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
size=(0, 0),
|
||||||
|
scale=3.0 * t_scale)
|
||||||
|
btn = bui.buttonwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
position=(h + b_buffer, v - b_size - b_buffer + v_offs),
|
||||||
|
button_type='square',
|
||||||
|
size=(b_size, b_size),
|
||||||
|
label='',
|
||||||
|
autoselect=True,
|
||||||
|
on_activate_call=bs.Call(self._change_replay_speed, 1))
|
||||||
|
bui.textwidget(
|
||||||
|
parent=self._root_widget,
|
||||||
|
draw_controller=btn,
|
||||||
|
text='+',
|
||||||
|
position=(h + b_size * 0.5 + b_buffer,
|
||||||
|
v - b_size * 0.5 - b_buffer + 5 * t_scale + v_offs),
|
||||||
|
h_align='center',
|
||||||
|
v_align='center',
|
||||||
|
size=(0, 0),
|
||||||
|
scale=3.0 * t_scale)
|
||||||
|
|
||||||
def public_servers(origin = None):
|
|
||||||
from bauiv1lib.gather import GatherWindow
|
|
||||||
bui.app.ui_v1.set_main_menu_window( GatherWindow(origin_widget=origin).get_root_widget())
|
|
||||||
|
|
||||||
# ba_meta export plugin
|
# ba_meta export plugin
|
||||||
class bySmoothy(babase.Plugin):
|
class bySmoothy(babase.Plugin):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
bastd_ui_mainmenu.MainMenuWindow._refresh_in_game = _refresh_in_game(bastd_ui_mainmenu.MainMenuWindow._refresh_in_game)
|
if babase.env().get("build_number", 0) >= 21140:
|
||||||
bs.connect_to_party = connect_to_party
|
bastd_ui_mainmenu.MainMenuWindow._refresh_in_game = new_refresh_in_game
|
||||||
|
bs.connect_to_party = newconnect_to_party
|
||||||
|
bs.disconnect_from_host = newdisconnect_from_host
|
||||||
|
else:
|
||||||
|
print("Server Switch only works on bs 1.7.20 and above")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue