mirror of
https://github.com/bombsquad-community/plugin-manager.git
synced 2025-10-08 14:54:36 +00:00
Needs some testing
This commit is contained in:
parent
1bce1d7d76
commit
4719c3e718
23 changed files with 2124 additions and 1626 deletions
|
|
@ -68,10 +68,10 @@ class ForestMap(bs.Map):
|
||||||
def on_preload(cls) -> any:
|
def on_preload(cls) -> any:
|
||||||
data: dict[str, any] = {
|
data: dict[str, any] = {
|
||||||
'mesh': bs.getmesh('natureBackground'),
|
'mesh': bs.getmesh('natureBackground'),
|
||||||
'tex': bui.gettexture('natureBackgroundColor'),
|
'tex': bs.gettexture('natureBackgroundColor'),
|
||||||
'collision_mesh': bs.getcollisionmesh('natureBackgroundCollide'),
|
'collision_mesh': bs.getcollisionmesh('natureBackgroundCollide'),
|
||||||
'bgmesh': bs.getmesh('thePadBG'),
|
'bgmesh': bs.getmesh('thePadBG'),
|
||||||
'bgtex': bui.gettexture('menuBG')
|
'bgtex': bs.gettexture('menuBG')
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ class ForestMap(bs.Map):
|
||||||
attrs={
|
attrs={
|
||||||
'mesh': self.preloaddata['mesh'],
|
'mesh': self.preloaddata['mesh'],
|
||||||
'color_texture': self.preloaddata['tex'],
|
'color_texture': self.preloaddata['tex'],
|
||||||
'collide_mesh': self.preloaddata['collide_mesh'],
|
'collision_mesh': self.preloaddata['collision_mesh'],
|
||||||
'materials': [shared.footing_material]
|
'materials': [shared.footing_material]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2fda676",
|
"commit_sha": "2fda676",
|
||||||
|
|
@ -92,10 +93,11 @@
|
||||||
{
|
{
|
||||||
"name": "JoseAng3l",
|
"name": "JoseAng3l",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "! JoseANG3L#0268"
|
"discord": "joseang3l"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2fda676",
|
"commit_sha": "2fda676",
|
||||||
|
|
@ -111,10 +113,11 @@
|
||||||
{
|
{
|
||||||
"name": "JoseAng3l",
|
"name": "JoseAng3l",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "! JoseANG3L#0268"
|
"discord": "joseang3l"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2fda676",
|
"commit_sha": "2fda676",
|
||||||
|
|
@ -130,10 +133,11 @@
|
||||||
{
|
{
|
||||||
"name": "JoseAng3l",
|
"name": "JoseAng3l",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "! JoseANG3L#0268"
|
"discord": "joseang3l"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2fda676",
|
"commit_sha": "2fda676",
|
||||||
|
|
@ -149,7 +153,7 @@
|
||||||
{
|
{
|
||||||
"name": "JoseAng3l",
|
"name": "JoseAng3l",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "! JoseANG3L#0268"
|
"discord": "joseang3l"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
|
@ -178,6 +182,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.1.0": null,
|
||||||
"1.0.1": {
|
"1.0.1": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "d511c15",
|
"commit_sha": "d511c15",
|
||||||
|
|
@ -199,10 +204,11 @@
|
||||||
{
|
{
|
||||||
"name": "Cross Joy",
|
"name": "Cross Joy",
|
||||||
"email": "cross.joy.official@gmail.com",
|
"email": "cross.joy.official@gmail.com",
|
||||||
"discord": "Cross Joy#0721"
|
"discord": "crossjoy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.0": null,
|
||||||
"2.0.0": {
|
"2.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "8b257b3",
|
"commit_sha": "8b257b3",
|
||||||
|
|
@ -328,6 +334,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "0841b9e",
|
"commit_sha": "0841b9e",
|
||||||
|
|
@ -343,7 +350,7 @@
|
||||||
{
|
{
|
||||||
"name": "SEBASTIAN2059",
|
"name": "SEBASTIAN2059",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "SEBASTIAN2059#5751"
|
"discord": "sebastian2059"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "zPanxo",
|
"name": "zPanxo",
|
||||||
|
|
@ -373,10 +380,11 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "52094fc",
|
"commit_sha": "52094fc",
|
||||||
|
|
@ -392,7 +400,7 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
|
@ -417,10 +425,11 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2aa1e50",
|
"commit_sha": "2aa1e50",
|
||||||
|
|
@ -436,7 +445,7 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
|
@ -455,10 +464,11 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "2aa1e50",
|
"commit_sha": "2aa1e50",
|
||||||
|
|
@ -474,10 +484,11 @@
|
||||||
{
|
{
|
||||||
"name": "Mr.Smoothy",
|
"name": "Mr.Smoothy",
|
||||||
"email": "smoothy@bombsquad.ga",
|
"email": "smoothy@bombsquad.ga",
|
||||||
"discord": "mr.smoothy#5824"
|
"discord": "mr.smoothy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "52094fc",
|
"commit_sha": "52094fc",
|
||||||
|
|
@ -534,7 +545,7 @@
|
||||||
{
|
{
|
||||||
"name": "JoseAng3l",
|
"name": "JoseAng3l",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "! JoseANG3L#0268"
|
"discord": "joseang3l"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
|
@ -588,6 +599,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "7219487",
|
"commit_sha": "7219487",
|
||||||
|
|
@ -603,10 +615,11 @@
|
||||||
{
|
{
|
||||||
"name": "ThePersonMan",
|
"name": "ThePersonMan",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "ThePersonMan#0276"
|
"discord": "the.personman"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "7219487",
|
"commit_sha": "7219487",
|
||||||
|
|
@ -622,10 +635,11 @@
|
||||||
{
|
{
|
||||||
"name": "Dliwk",
|
"name": "Dliwk",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "Dliwk#7961"
|
"discord": "dliwk"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "7219487",
|
"commit_sha": "7219487",
|
||||||
|
|
@ -645,6 +659,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "7219487",
|
"commit_sha": "7219487",
|
||||||
|
|
@ -660,10 +675,11 @@
|
||||||
{
|
{
|
||||||
"name": "SEBASTIAN2059",
|
"name": "SEBASTIAN2059",
|
||||||
"email": "",
|
"email": "",
|
||||||
"discord": "SEBASTIAN2059#5751"
|
"discord": "sebastian2059"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
"1.0.1": null,
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
"api_version": 7,
|
"api_version": 7,
|
||||||
"commit_sha": "7219487",
|
"commit_sha": "7219487",
|
||||||
|
|
@ -698,7 +714,7 @@
|
||||||
{
|
{
|
||||||
"name": "Cross Joy",
|
"name": "Cross Joy",
|
||||||
"email": "cross.joy.official@gmail.com",
|
"email": "cross.joy.official@gmail.com",
|
||||||
"discord": "Cross Joy#0721"
|
"discord": "crossjoy"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": {
|
"versions": {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
# BY Stary_Agent
|
# BY Stary_Agent
|
||||||
"""Hockey game and support classes."""
|
"""Hockey game and support classes."""
|
||||||
|
|
||||||
# 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
|
||||||
import _ba
|
import bascenev1 as bs
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
from bastd.actor.powerupbox import PowerupBoxFactory
|
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
||||||
|
|
@ -32,13 +33,13 @@ def create_slope(self):
|
||||||
x = 5
|
x = 5
|
||||||
y = 12
|
y = 12
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
x = x+0.3
|
x = x+0.3
|
||||||
y = y+0.1
|
y = y+0.1
|
||||||
|
|
||||||
|
|
||||||
class Puck(ba.Actor):
|
class Puck(bs.Actor):
|
||||||
"""A lovely giant hockey puck."""
|
"""A lovely giant hockey puck."""
|
||||||
|
|
||||||
def __init__(self, position: Sequence[float] = (0.0, 13.0, 0.0)):
|
def __init__(self, position: Sequence[float] = (0.0, 13.0, 0.0)):
|
||||||
|
|
@ -53,10 +54,10 @@ class Puck(ba.Actor):
|
||||||
assert activity is not None
|
assert activity is not None
|
||||||
assert isinstance(activity, HockeyGame)
|
assert isinstance(activity, HockeyGame)
|
||||||
pmats = [shared.object_material, activity.puck_material]
|
pmats = [shared.object_material, activity.puck_material]
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'model': activity.puck_model,
|
'mesh': activity.puck_mesh,
|
||||||
'color_texture': activity.puck_tex,
|
'color_texture': activity.puck_tex,
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
|
|
@ -67,10 +68,10 @@ class Puck(ba.Actor):
|
||||||
'position': self._spawn_pos,
|
'position': self._spawn_pos,
|
||||||
'materials': pmats
|
'materials': pmats
|
||||||
})
|
})
|
||||||
ba.animate(self.node, 'model_scale', {0: 0, 0.2: 1.3, 0.26: 1})
|
bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: 1.3, 0.26: 1})
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
activity = self._activity()
|
activity = self._activity()
|
||||||
|
|
@ -78,11 +79,11 @@ class Puck(ba.Actor):
|
||||||
activity.handlemessage(PuckDiedMessage(self))
|
activity.handlemessage(PuckDiedMessage(self))
|
||||||
|
|
||||||
# If we go out of bounds, move back to where we started.
|
# If we go out of bounds, move back to where we started.
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
self.node.position = self._spawn_pos
|
self.node.position = self._spawn_pos
|
||||||
|
|
||||||
elif isinstance(msg, ba.HitMessage):
|
elif isinstance(msg, bs.HitMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
assert msg.force_direction is not None
|
assert msg.force_direction is not None
|
||||||
self.node.handlemessage(
|
self.node.handlemessage(
|
||||||
|
|
@ -103,31 +104,31 @@ class Puck(ba.Actor):
|
||||||
super().handlemessage(msg)
|
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."""
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.score = 0
|
self.score = 0
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
class AirSoccerGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Ice hockey game."""
|
"""Ice hockey game."""
|
||||||
|
|
||||||
name = 'Epic Air Soccer'
|
name = 'Epic Air Soccer'
|
||||||
description = 'Score some goals.'
|
description = 'Score some goals.'
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Score to Win',
|
'Score to Win',
|
||||||
min_value=1,
|
min_value=1,
|
||||||
default=1,
|
default=1,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -139,7 +140,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.1),
|
('Shorter', 0.1),
|
||||||
|
|
@ -151,14 +152,14 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
default_music = ba.MusicType.HOCKEY
|
default_music = bs.MusicType.HOCKEY
|
||||||
|
|
||||||
@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 ['Creative Thoughts']
|
return ['Creative Thoughts']
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
|
|
@ -166,16 +167,16 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self.slow_motion = True
|
self.slow_motion = True
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._cheer_sound = ba.getsound('cheer')
|
self._cheer_sound = bs.getsound('cheer')
|
||||||
self._chant_sound = ba.getsound('crowdChant')
|
self._chant_sound = bs.getsound('crowdChant')
|
||||||
self._foghorn_sound = ba.getsound('foghorn')
|
self._foghorn_sound = bs.getsound('foghorn')
|
||||||
self._swipsound = ba.getsound('swip')
|
self._swipsound = bs.getsound('swip')
|
||||||
self._whistle_sound = ba.getsound('refWhistle')
|
self._whistle_sound = bs.getsound('refWhistle')
|
||||||
self.puck_model = ba.getmodel('bomb')
|
self.puck_mesh = bs.getmesh('bomb')
|
||||||
self.puck_tex = ba.gettexture('landMine')
|
self.puck_tex = bs.gettexture('landMine')
|
||||||
self.puck_scored_tex = ba.gettexture('landMineLit')
|
self.puck_scored_tex = bs.gettexture('landMineLit')
|
||||||
self._puck_sound = ba.getsound('metalHit')
|
self._puck_sound = bs.getsound('metalHit')
|
||||||
self.puck_material = ba.Material()
|
self.puck_material = bs.Material()
|
||||||
self.puck_material.add_actions(actions=(('modify_part_collision',
|
self.puck_material.add_actions(actions=(('modify_part_collision',
|
||||||
'friction', 0.5)))
|
'friction', 0.5)))
|
||||||
self.puck_material.add_actions(conditions=('they_have_material',
|
self.puck_material.add_actions(conditions=('they_have_material',
|
||||||
|
|
@ -194,7 +195,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
shared.footing_material),
|
shared.footing_material),
|
||||||
actions=('impact_sound',
|
actions=('impact_sound',
|
||||||
self._puck_sound, 0.2, 5))
|
self._puck_sound, 0.2, 5))
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._real_wall_material.add_actions(
|
self._real_wall_material.add_actions(
|
||||||
|
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -210,7 +211,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
|
|
||||||
))
|
))
|
||||||
self._goal_post_material = ba.Material()
|
self._goal_post_material = bs.Material()
|
||||||
self._goal_post_material.add_actions(
|
self._goal_post_material.add_actions(
|
||||||
|
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -237,15 +238,15 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
conditions=('they_have_material',
|
conditions=('they_have_material',
|
||||||
PowerupBoxFactory.get().powerup_material),
|
PowerupBoxFactory.get().powerup_material),
|
||||||
actions=(('modify_part_collision', 'physical', False),
|
actions=(('modify_part_collision', 'physical', False),
|
||||||
('message', 'their_node', 'at_connect', ba.DieMessage())))
|
('message', 'their_node', 'at_connect', bs.DieMessage())))
|
||||||
self._score_region_material = ba.Material()
|
self._score_region_material = bs.Material()
|
||||||
self._score_region_material.add_actions(
|
self._score_region_material.add_actions(
|
||||||
conditions=('they_have_material', self.puck_material),
|
conditions=('they_have_material', self.puck_material),
|
||||||
actions=(('modify_part_collision', 'collide',
|
actions=(('modify_part_collision', 'collide',
|
||||||
True), ('modify_part_collision', 'physical', False),
|
True), ('modify_part_collision', 'physical', False),
|
||||||
('call', 'at_connect', self._handle_score)))
|
('call', 'at_connect', self._handle_score)))
|
||||||
self._puck_spawn_pos: Optional[Sequence[float]] = None
|
self._puck_spawn_pos: Optional[Sequence[float]] = None
|
||||||
self._score_regions: Optional[List[ba.NodeActor]] = None
|
self._score_regions: Optional[List[bs.NodeActor]] = None
|
||||||
self._puck: Optional[Puck] = None
|
self._puck: Optional[Puck] = None
|
||||||
self._score_to_win = int(settings['Score to Win'])
|
self._score_to_win = int(settings['Score to Win'])
|
||||||
self._time_limit = float(settings['Time Limit'])
|
self._time_limit = float(settings['Time Limit'])
|
||||||
|
|
@ -273,8 +274,8 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
defs = self.map.defs
|
defs = self.map.defs
|
||||||
self._score_regions = []
|
self._score_regions = []
|
||||||
self._score_regions.append(
|
self._score_regions.append(
|
||||||
ba.NodeActor(
|
bs.NodeActor(
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (17, 14.5, -5.52),
|
'position': (17, 14.5, -5.52),
|
||||||
'scale': (1, 3, 1),
|
'scale': (1, 3, 1),
|
||||||
|
|
@ -282,8 +283,8 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'materials': [self._score_region_material]
|
'materials': [self._score_region_material]
|
||||||
})))
|
})))
|
||||||
self._score_regions.append(
|
self._score_regions.append(
|
||||||
ba.NodeActor(
|
bs.NodeActor(
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (-17, 14.5, -5.52),
|
'position': (-17, 14.5, -5.52),
|
||||||
'scale': (1, 3, 1),
|
'scale': (1, 3, 1),
|
||||||
|
|
@ -291,36 +292,36 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'materials': [self._score_region_material]
|
'materials': [self._score_region_material]
|
||||||
})))
|
})))
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
ba.playsound(self._chant_sound)
|
self._chant_sound.play()
|
||||||
|
|
||||||
def on_team_join(self, team: Team) -> None:
|
def on_team_join(self, team: Team) -> None:
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
||||||
def _handle_puck_player_collide(self) -> None:
|
def _handle_puck_player_collide(self) -> None:
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
try:
|
try:
|
||||||
puck = collision.sourcenode.getdelegate(Puck, True)
|
puck = collision.sourcenode.getdelegate(Puck, True)
|
||||||
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
||||||
True).getplayer(
|
True).getplayer(
|
||||||
Player, True)
|
Player, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
|
|
||||||
puck.last_players_to_touch[player.team.id] = player
|
puck.last_players_to_touch[player.team.id] = player
|
||||||
|
|
||||||
def make_map(self):
|
def make_map(self):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
_ba.get_foreground_host_activity()._map.leftwall.materials = [
|
bs.get_foreground_host_activity()._map.leftwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.rightwall.materials = [
|
bs.get_foreground_host_activity()._map.rightwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.topwall.materials = [
|
bs.get_foreground_host_activity()._map.topwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
self.floorwall = ba.newnode('region', attrs={'position': (0, 5, -5.52), 'scale': (
|
self.floorwall = bs.newnode('region', attrs={'position': (0, 5, -5.52), 'scale': (
|
||||||
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (
|
||||||
0, 5, -5.52), 'color': (0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
0, 5, -5.52), 'color': (0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
||||||
|
|
||||||
self.create_goal_post(-16.65, 12.69)
|
self.create_goal_post(-16.65, 12.69)
|
||||||
|
|
@ -343,9 +344,9 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
floor += "_ "
|
floor += "_ "
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
step = {}
|
step = {}
|
||||||
step["r"] = ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
step["r"] = bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
||||||
3, 0.1, 6), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
3, 0.1, 6), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (
|
||||||
x, y, -5.52), 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (3, 0.1, 2)})
|
x, y, -5.52), 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (3, 0.1, 2)})
|
||||||
|
|
||||||
return step
|
return step
|
||||||
|
|
@ -359,10 +360,10 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
floor = ""
|
floor = ""
|
||||||
for i in range(0, 4):
|
for i in range(0, 4):
|
||||||
floor += "_ "
|
floor += "_ "
|
||||||
ba.newnode('region', attrs={'position': (x-0.2, y, -5.52), 'scale': (1.8, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x-0.2, y, -5.52), 'scale': (1.8, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._goal_post_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._goal_post_material]})
|
||||||
|
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (
|
||||||
x-0.2, y, -5.52), 'color': color, 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (1.8, 0.1, 2)})
|
x-0.2, y, -5.52), 'color': color, 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (1.8, 0.1, 2)})
|
||||||
|
|
||||||
def create_vertical(self, x, y):
|
def create_vertical(self, x, y):
|
||||||
|
|
@ -370,9 +371,9 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
floor = ""
|
floor = ""
|
||||||
for i in range(0, 4):
|
for i in range(0, 4):
|
||||||
floor += "|\n"
|
floor += "|\n"
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.1, 2.8, 1),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.1, 2.8, 1),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (
|
||||||
x, y, -5.52), 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 2.8, 2)})
|
x, y, -5.52), 'color': (1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 2.8, 2)})
|
||||||
|
|
||||||
def spawn_player_spaz(self,
|
def spawn_player_spaz(self,
|
||||||
|
|
@ -402,7 +403,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if self._puck.scored:
|
if self._puck.scored:
|
||||||
return
|
return
|
||||||
|
|
||||||
region = ba.getcollision().sourcenode
|
region = bs.getcollision().sourcenode
|
||||||
index = 0
|
index = 0
|
||||||
for index in range(len(self._score_regions)):
|
for index in range(len(self._score_regions)):
|
||||||
if region == self._score_regions[index].node:
|
if region == self._score_regions[index].node:
|
||||||
|
|
@ -416,7 +417,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# Tell all players to celebrate.
|
# Tell all players to celebrate.
|
||||||
for player in team.players:
|
for player in team.players:
|
||||||
if player.actor:
|
if player.actor:
|
||||||
player.actor.handlemessage(ba.CelebrateMessage(2.0))
|
player.actor.handlemessage(bs.CelebrateMessage(2.0))
|
||||||
|
|
||||||
# If we've got the player from the scoring team that last
|
# If we've got the player from the scoring team that last
|
||||||
# touched us, give them points.
|
# touched us, give them points.
|
||||||
|
|
@ -431,30 +432,30 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if team.score >= self._score_to_win:
|
if team.score >= self._score_to_win:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
||||||
ba.playsound(self._foghorn_sound)
|
self._foghorn_sound.play()
|
||||||
ba.playsound(self._cheer_sound)
|
self._cheer_sound.play()
|
||||||
|
|
||||||
self._puck.scored = True
|
self._puck.scored = True
|
||||||
|
|
||||||
# Change puck texture to something cool
|
# Change puck texture to something cool
|
||||||
self._puck.node.color_texture = self.puck_scored_tex
|
self._puck.node.color_texture = self.puck_scored_tex
|
||||||
# Kill the puck (it'll respawn itself shortly).
|
# Kill the puck (it'll respawn itself shortly).
|
||||||
ba.timer(1.0, self._kill_puck)
|
bs.timer(1.0, self._kill_puck)
|
||||||
|
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': ba.getcollision().position,
|
'position': bs.getcollision().position,
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'color': (1, 0, 0)
|
'color': (1, 0, 0)
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True)
|
bs.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
ba.cameraflash(duration=10.0)
|
bs.cameraflash(duration=10.0)
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.score)
|
results.set_team_score(team, team.score)
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
@ -467,7 +468,7 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
|
|
||||||
# Respawn dead players if they're still in the game.
|
# Respawn dead players if they're still in the game.
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
# Augment standard behavior...
|
# Augment standard behavior...
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
self.respawn_player(msg.getplayer(Player))
|
self.respawn_player(msg.getplayer(Player))
|
||||||
|
|
@ -475,23 +476,23 @@ class AirSoccerGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# Respawn dead pucks.
|
# Respawn dead pucks.
|
||||||
elif isinstance(msg, PuckDiedMessage):
|
elif isinstance(msg, PuckDiedMessage):
|
||||||
if not self.has_ended():
|
if not self.has_ended():
|
||||||
ba.timer(3.0, self._spawn_puck)
|
bs.timer(3.0, self._spawn_puck)
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
def _flash_puck_spawn(self) -> None:
|
def _flash_puck_spawn(self) -> None:
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': self._puck_spawn_pos,
|
'position': self._puck_spawn_pos,
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'color': (1, 0, 0)
|
'color': (1, 0, 0)
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True)
|
bs.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
def _spawn_puck(self) -> None:
|
def _spawn_puck(self) -> None:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
ba.playsound(self._whistle_sound)
|
self._whistle_sound.play()
|
||||||
self._flash_puck_spawn()
|
self._flash_puck_spawn()
|
||||||
assert self._puck_spawn_pos is not None
|
assert self._puck_spawn_pos is not None
|
||||||
self._puck = Puck(position=self._puck_spawn_pos)
|
self._puck = Puck(position=self._puck_spawn_pos)
|
||||||
|
|
@ -541,7 +542,7 @@ class mapdefs:
|
||||||
0.5245740665, 0.5245740665, 0.01941146064)
|
0.5245740665, 0.5245740665, 0.01941146064)
|
||||||
|
|
||||||
|
|
||||||
class CreativeThoughts(ba.Map):
|
class CreativeThoughts(bs.Map):
|
||||||
"""Freaking map by smoothy."""
|
"""Freaking map by smoothy."""
|
||||||
|
|
||||||
defs = mapdefs
|
defs = mapdefs
|
||||||
|
|
@ -562,26 +563,26 @@ class CreativeThoughts(ba.Map):
|
||||||
@classmethod
|
@classmethod
|
||||||
def on_preload(cls) -> Any:
|
def on_preload(cls) -> Any:
|
||||||
data: Dict[str, Any] = {
|
data: Dict[str, Any] = {
|
||||||
'model': ba.getmodel('alwaysLandLevel'),
|
'mesh': bs.getmesh('alwaysLandLevel'),
|
||||||
'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
|
'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
|
||||||
'bgmodel': ba.getmodel('alwaysLandBG'),
|
'bgmesh': bs.getmesh('alwaysLandBG'),
|
||||||
'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
|
'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
|
||||||
'tex': ba.gettexture('alwaysLandLevelColor'),
|
'tex': bs.gettexture('alwaysLandLevelColor'),
|
||||||
'bgtex': ba.gettexture('alwaysLandBGColor'),
|
'bgtex': bs.gettexture('alwaysLandBGColor'),
|
||||||
'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
|
'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
|
||||||
'vr_fill_mound_tex': ba.gettexture('vrFillMound')
|
'vr_fill_mound_tex': bs.gettexture('vrFillMound')
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_music_type(cls) -> ba.MusicType:
|
def get_music_type(cls) -> bs.MusicType:
|
||||||
return ba.MusicType.FLYING
|
return bs.MusicType.FLYING
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._fake_wall_material = ba.Material()
|
self._fake_wall_material = bs.Material()
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._fake_wall_material.add_actions(
|
self._fake_wall_material.add_actions(
|
||||||
conditions=(('they_are_younger_than', 9000), 'and',
|
conditions=(('they_are_younger_than', 9000), 'and',
|
||||||
('they_have_material', shared.player_material)),
|
('they_have_material', shared.player_material)),
|
||||||
|
|
@ -597,29 +598,29 @@ class CreativeThoughts(ba.Map):
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
|
|
||||||
))
|
))
|
||||||
self.background = ba.newnode(
|
self.background = bs.newnode(
|
||||||
'terrain',
|
'terrain',
|
||||||
attrs={
|
attrs={
|
||||||
'model': self.preloaddata['bgmodel'],
|
'mesh': self.preloaddata['bgmesh'],
|
||||||
'lighting': False,
|
'lighting': False,
|
||||||
'background': True,
|
'background': True,
|
||||||
'color_texture': ba.gettexture("rampageBGColor")
|
'color_texture': bs.gettexture("rampageBGColor")
|
||||||
})
|
})
|
||||||
|
|
||||||
self.leftwall = ba.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
self.leftwall = bs.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.rightwall = ba.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
self.rightwall = bs.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.topwall = ba.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
self.topwall = bs.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
||||||
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
||||||
|
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.happy_thoughts_mode = True
|
gnode.happy_thoughts_mode = True
|
||||||
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
||||||
gnode.tint = (1.3, 1.23, 1.0)
|
gnode.tint = (1.3, 1.23, 1.0)
|
||||||
|
|
@ -630,9 +631,9 @@ class CreativeThoughts(ba.Map):
|
||||||
self.is_flying = True
|
self.is_flying = True
|
||||||
|
|
||||||
# throw out some tips on flying
|
# throw out some tips on flying
|
||||||
txt = ba.newnode('text',
|
txt = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': ba.Lstr(resource='pressJumpToFlyText'),
|
'text': babase.Lstr(resource='pressJumpToFlyText'),
|
||||||
'scale': 1.2,
|
'scale': 1.2,
|
||||||
'maxwidth': 800,
|
'maxwidth': 800,
|
||||||
'position': (0, 200),
|
'position': (0, 200),
|
||||||
|
|
@ -641,7 +642,7 @@ class CreativeThoughts(ba.Map):
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
cmb = ba.newnode('combine',
|
cmb = bs.newnode('combine',
|
||||||
owner=txt,
|
owner=txt,
|
||||||
attrs={
|
attrs={
|
||||||
'size': 4,
|
'size': 4,
|
||||||
|
|
@ -649,12 +650,12 @@ class CreativeThoughts(ba.Map):
|
||||||
'input1': 0.9,
|
'input1': 0.9,
|
||||||
'input2': 0.0
|
'input2': 0.0
|
||||||
})
|
})
|
||||||
ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
||||||
cmb.connectattr('output', txt, 'color')
|
cmb.connectattr('output', txt, 'color')
|
||||||
ba.timer(10.0, txt.delete)
|
bs.timer(10.0, txt.delete)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ba._map.register_map(CreativeThoughts)
|
bs._map.register_map(CreativeThoughts)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
# 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
|
||||||
import _ba
|
import bauiv1 as bui
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
import bascenev1 as bs
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
import _babase
|
||||||
from bastd.actor.powerupbox import PowerupBoxFactory
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
from bastd.actor import playerspaz as ps
|
from bascenev1lib.actor.powerupbox import PowerupBoxFactory
|
||||||
from bastd import maps
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
from bascenev1lib.actor import playerspaz as ps
|
||||||
|
from bascenev1lib import maps
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
||||||
|
|
@ -22,7 +25,7 @@ bsuSpaz = None
|
||||||
|
|
||||||
|
|
||||||
def getlanguage(text, sub: str = ''):
|
def getlanguage(text, sub: str = ''):
|
||||||
lang = _ba.app.lang.language
|
lang = bs.app.lang.language
|
||||||
translate = {
|
translate = {
|
||||||
"Name":
|
"Name":
|
||||||
{"Spanish": "Baloncesto",
|
{"Spanish": "Baloncesto",
|
||||||
|
|
@ -60,7 +63,7 @@ class BallDiedMessage:
|
||||||
self.ball = ball
|
self.ball = ball
|
||||||
|
|
||||||
|
|
||||||
class Ball(ba.Actor):
|
class Ball(bs.Actor):
|
||||||
def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)):
|
def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
|
|
@ -76,10 +79,10 @@ class Ball(ba.Actor):
|
||||||
assert isinstance(activity, BasketGame)
|
assert isinstance(activity, BasketGame)
|
||||||
|
|
||||||
pmats = [shared.object_material, activity.ball_material]
|
pmats = [shared.object_material, activity.ball_material]
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'model': activity.ball_model,
|
'mesh': activity.ball_mesh,
|
||||||
'color_texture': activity.ball_tex,
|
'color_texture': activity.ball_tex,
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
|
|
@ -92,22 +95,22 @@ class Ball(ba.Actor):
|
||||||
'velocity': velocty,
|
'velocity': velocty,
|
||||||
'materials': pmats})
|
'materials': pmats})
|
||||||
self.scale = scale = 0.25 * _scale
|
self.scale = scale = 0.25 * _scale
|
||||||
ba.animate(self.node, 'model_scale', {0: 0, 0.2: scale*1.3, 0.26: scale})
|
bs.animate(self.node, 'mesh_scale', {0: 0, 0.2: scale*1.3, 0.26: scale})
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
activity = self._activity()
|
activity = self._activity()
|
||||||
if activity and not msg.immediate:
|
if activity and not msg.immediate:
|
||||||
activity.handlemessage(BallDiedMessage(self))
|
activity.handlemessage(BallDiedMessage(self))
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
self.node.position = self._spawn_pos
|
self.node.position = self._spawn_pos
|
||||||
self.node.velocity = (0.0, 0.0, 0.0)
|
self.node.velocity = (0.0, 0.0, 0.0)
|
||||||
|
|
||||||
elif isinstance(msg, ba.HitMessage):
|
elif isinstance(msg, bs.HitMessage):
|
||||||
assert self.node
|
assert self.node
|
||||||
assert msg.force_direction is not None
|
assert msg.force_direction is not None
|
||||||
self.node.handlemessage(
|
self.node.handlemessage(
|
||||||
|
|
@ -127,11 +130,11 @@ class Ball(ba.Actor):
|
||||||
super().handlemessage(msg)
|
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."""
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -144,21 +147,21 @@ class Points:
|
||||||
postes['pal_0'] = (10.64702320098877, 0.0000000000000000, 0.0000000000000000)
|
postes['pal_0'] = (10.64702320098877, 0.0000000000000000, 0.0000000000000000)
|
||||||
postes['pal_1'] = (-10.64702320098877, 0.0000000000000000, 0.0000000000000000)
|
postes['pal_1'] = (-10.64702320098877, 0.0000000000000000, 0.0000000000000000)
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class BasketGame(ba.TeamGameActivity[Player, Team]):
|
class BasketGame(bs.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
name = getlanguage('Name')
|
name = getlanguage('Name')
|
||||||
description = getlanguage('Info')
|
description = getlanguage('Info')
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Score to Win',
|
'Score to Win',
|
||||||
min_value=1,
|
min_value=1,
|
||||||
default=1,
|
default=1,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -170,7 +173,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -181,38 +184,38 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(getlanguage('S: Powerups'), default=True),
|
bs.BoolSetting(getlanguage('S: Powerups'), default=True),
|
||||||
ba.BoolSetting(getlanguage('S: Velocity'), default=False),
|
bs.BoolSetting(getlanguage('S: Velocity'), default=False),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
default_music = ba.MusicType.HOCKEY
|
default_music = bs.MusicType.HOCKEY
|
||||||
|
|
||||||
@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 ['BasketBall Stadium', 'BasketBall Stadium V2']
|
return ['BasketBall Stadium', 'BasketBall Stadium V2']
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._cheer_sound = ba.getsound('cheer')
|
self._cheer_sound = bs.getsound('cheer')
|
||||||
self._chant_sound = ba.getsound('crowdChant')
|
self._chant_sound = bs.getsound('crowdChant')
|
||||||
self._foghorn_sound = ba.getsound('foghorn')
|
self._foghorn_sound = bs.getsound('foghorn')
|
||||||
self._swipsound = ba.getsound('swip')
|
self._swipsound = bs.getsound('swip')
|
||||||
self._whistle_sound = ba.getsound('refWhistle')
|
self._whistle_sound = bs.getsound('refWhistle')
|
||||||
self.ball_model = ba.getmodel('shield')
|
self.ball_mesh = bs.getmesh('shield')
|
||||||
self.ball_tex = ba.gettexture('fontExtras3')
|
self.ball_tex = bs.gettexture('fontExtras3')
|
||||||
self._ball_sound = ba.getsound('bunnyJump')
|
self._ball_sound = bs.getsound('bunnyJump')
|
||||||
self._powerups = bool(settings[getlanguage('S: Powerups')])
|
self._powerups = bool(settings[getlanguage('S: Powerups')])
|
||||||
self._speed = bool(settings[getlanguage('S: Velocity')])
|
self._speed = bool(settings[getlanguage('S: Velocity')])
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
self.slow_motion = self._epic_mode
|
self.slow_motion = self._epic_mode
|
||||||
|
|
||||||
self.ball_material = ba.Material()
|
self.ball_material = bs.Material()
|
||||||
self.ball_material.add_actions(actions=(('modify_part_collision',
|
self.ball_material.add_actions(actions=(('modify_part_collision',
|
||||||
'friction', 0.5)))
|
'friction', 0.5)))
|
||||||
self.ball_material.add_actions(conditions=('they_have_material',
|
self.ball_material.add_actions(conditions=('they_have_material',
|
||||||
|
|
@ -238,14 +241,14 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
actions=(('call', 'at_connect',
|
actions=(('call', 'at_connect',
|
||||||
self._handle_ball_player_collide), ))
|
self._handle_ball_player_collide), ))
|
||||||
|
|
||||||
self._score_region_material = ba.Material()
|
self._score_region_material = bs.Material()
|
||||||
self._score_region_material.add_actions(
|
self._score_region_material.add_actions(
|
||||||
conditions=('they_have_material', self.ball_material),
|
conditions=('they_have_material', self.ball_material),
|
||||||
actions=(('modify_part_collision', 'collide',
|
actions=(('modify_part_collision', 'collide',
|
||||||
True), ('modify_part_collision', 'physical', False),
|
True), ('modify_part_collision', 'physical', False),
|
||||||
('call', 'at_connect', self._handle_score)))
|
('call', 'at_connect', self._handle_score)))
|
||||||
self._ball_spawn_pos: Optional[Sequence[float]] = None
|
self._ball_spawn_pos: Optional[Sequence[float]] = None
|
||||||
self._score_regions: Optional[List[ba.NodeActor]] = None
|
self._score_regions: Optional[List[bs.NodeActor]] = None
|
||||||
self._ball: Optional[Ball] = None
|
self._ball: Optional[Ball] = None
|
||||||
self._score_to_win = int(settings['Score to Win'])
|
self._score_to_win = int(settings['Score to Win'])
|
||||||
self._time_limit = float(settings['Time Limit'])
|
self._time_limit = float(settings['Time Limit'])
|
||||||
|
|
@ -270,8 +273,8 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
defs = self.map.defs
|
defs = self.map.defs
|
||||||
self._score_regions = []
|
self._score_regions = []
|
||||||
self._score_regions.append(
|
self._score_regions.append(
|
||||||
ba.NodeActor(
|
bs.NodeActor(
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': defs.boxes['goal1'][0:3],
|
'position': defs.boxes['goal1'][0:3],
|
||||||
'scale': defs.boxes['goal1'][6:9],
|
'scale': defs.boxes['goal1'][6:9],
|
||||||
|
|
@ -279,8 +282,8 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'materials': []
|
'materials': []
|
||||||
})))
|
})))
|
||||||
self._score_regions.append(
|
self._score_regions.append(
|
||||||
ba.NodeActor(
|
bs.NodeActor(
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': defs.boxes['goal2'][0:3],
|
'position': defs.boxes['goal2'][0:3],
|
||||||
'scale': defs.boxes['goal2'][6:9],
|
'scale': defs.boxes['goal2'][6:9],
|
||||||
|
|
@ -288,7 +291,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'materials': []
|
'materials': []
|
||||||
})))
|
})))
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
ba.playsound(self._chant_sound)
|
self._chant_sound.play()
|
||||||
|
|
||||||
for id, team in enumerate(self.teams):
|
for id, team in enumerate(self.teams):
|
||||||
self.postes(id)
|
self.postes(id)
|
||||||
|
|
@ -297,13 +300,13 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
||||||
def _handle_ball_player_collide(self) -> None:
|
def _handle_ball_player_collide(self) -> None:
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
try:
|
try:
|
||||||
ball = collision.sourcenode.getdelegate(Ball, True)
|
ball = collision.sourcenode.getdelegate(Ball, True)
|
||||||
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
||||||
True).getplayer(
|
True).getplayer(
|
||||||
Player, True)
|
Player, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
|
|
||||||
ball.last_players_to_touch[player.team.id] = player
|
ball.last_players_to_touch[player.team.id] = player
|
||||||
|
|
@ -318,7 +321,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if self._ball.scored:
|
if self._ball.scored:
|
||||||
return
|
return
|
||||||
|
|
||||||
region = ba.getcollision().sourcenode
|
region = bs.getcollision().sourcenode
|
||||||
index = 0
|
index = 0
|
||||||
for index in range(len(self._score_regions)):
|
for index in range(len(self._score_regions)):
|
||||||
if region == self._score_regions[index].node:
|
if region == self._score_regions[index].node:
|
||||||
|
|
@ -334,7 +337,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
for player in team.players:
|
for player in team.players:
|
||||||
if player.actor:
|
if player.actor:
|
||||||
player.actor.handlemessage(ba.CelebrateMessage(2.0))
|
player.actor.handlemessage(bs.CelebrateMessage(2.0))
|
||||||
|
|
||||||
if (scoring_team.id in self._ball.last_players_to_touch
|
if (scoring_team.id in self._ball.last_players_to_touch
|
||||||
and self._ball.last_players_to_touch[scoring_team.id]):
|
and self._ball.last_players_to_touch[scoring_team.id]):
|
||||||
|
|
@ -345,28 +348,28 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if team.score >= self._score_to_win:
|
if team.score >= self._score_to_win:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
||||||
# ba.playsound(self._foghorn_sound)
|
# self._foghorn_sound.play()
|
||||||
ba.playsound(self._cheer_sound)
|
self._cheer_sound.play()
|
||||||
|
|
||||||
self._ball.scored = True
|
self._ball.scored = True
|
||||||
|
|
||||||
# Kill the ball (it'll respawn itself shortly).
|
# Kill the ball (it'll respawn itself shortly).
|
||||||
ba.timer(1.0, self._kill_ball)
|
bs.timer(1.0, self._kill_ball)
|
||||||
|
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': ba.getcollision().position,
|
'position': bs.getcollision().position,
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'color': (1, 0, 0)
|
'color': (1, 0, 0)
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True)
|
bs.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
ba.cameraflash(duration=10.0)
|
bs.cameraflash(duration=10.0)
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.score)
|
results.set_team_score(team, team.score)
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
@ -377,7 +380,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._scoreboard.set_team_value(team, team.score, winscore)
|
self._scoreboard.set_team_value(team, team.score, winscore)
|
||||||
# self.postes(id)
|
# self.postes(id)
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
if bsuSpaz is None:
|
if bsuSpaz is None:
|
||||||
spaz = self.spawn_player_spaz(player)
|
spaz = self.spawn_player_spaz(player)
|
||||||
else:
|
else:
|
||||||
|
|
@ -390,12 +393,12 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
return spaz
|
return spaz
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
self.respawn_player(msg.getplayer(Player))
|
self.respawn_player(msg.getplayer(Player))
|
||||||
elif isinstance(msg, BallDiedMessage):
|
elif isinstance(msg, BallDiedMessage):
|
||||||
if not self.has_ended():
|
if not self.has_ended():
|
||||||
ba.timer(3.0, self._spawn_ball)
|
bs.timer(3.0, self._spawn_ball)
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
@ -407,24 +410,24 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
|
||||||
str(team_id)]).autoretain())
|
str(team_id)]).autoretain())
|
||||||
|
|
||||||
def _flash_ball_spawn(self) -> None:
|
def _flash_ball_spawn(self) -> None:
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': self._ball_spawn_pos,
|
'position': self._ball_spawn_pos,
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'color': (1, 0, 0)
|
'color': (1, 0, 0)
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True)
|
bs.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
def _spawn_ball(self) -> None:
|
def _spawn_ball(self) -> None:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
ba.playsound(self._whistle_sound)
|
self._whistle_sound.play()
|
||||||
self._flash_ball_spawn()
|
self._flash_ball_spawn()
|
||||||
assert self._ball_spawn_pos is not None
|
assert self._ball_spawn_pos is not None
|
||||||
self._ball = Ball(position=self._ball_spawn_pos)
|
self._ball = Ball(position=self._ball_spawn_pos)
|
||||||
|
|
||||||
|
|
||||||
class Aro(ba.Actor):
|
class Aro(bs.Actor):
|
||||||
def __init__(self, team: int = 0,
|
def __init__(self, team: int = 0,
|
||||||
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
@ -434,16 +437,16 @@ class Aro(ba.Actor):
|
||||||
setattr(self, 'locs', [])
|
setattr(self, 'locs', [])
|
||||||
|
|
||||||
# Material Para; Traspasar Objetos
|
# Material Para; Traspasar Objetos
|
||||||
self.no_collision = ba.Material()
|
self.no_collision = bs.Material()
|
||||||
self.no_collision.add_actions(
|
self.no_collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', False)))
|
actions=(('modify_part_collision', 'collide', False)))
|
||||||
|
|
||||||
self.collision = ba.Material()
|
self.collision = bs.Material()
|
||||||
self.collision.add_actions(
|
self.collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', True)))
|
actions=(('modify_part_collision', 'collide', True)))
|
||||||
|
|
||||||
# Score
|
# Score
|
||||||
self._score_region_material = ba.Material()
|
self._score_region_material = bs.Material()
|
||||||
self._score_region_material.add_actions(
|
self._score_region_material.add_actions(
|
||||||
conditions=('they_have_material', act.ball_material),
|
conditions=('they_have_material', act.ball_material),
|
||||||
actions=(('modify_part_collision', 'collide',
|
actions=(('modify_part_collision', 'collide',
|
||||||
|
|
@ -454,14 +457,14 @@ class Aro(ba.Actor):
|
||||||
self._materials_region0 = [self.collision,
|
self._materials_region0 = [self.collision,
|
||||||
shared.footing_material]
|
shared.footing_material]
|
||||||
|
|
||||||
model = None
|
mesh = None
|
||||||
tex = ba.gettexture('null')
|
tex = bs.gettexture('null')
|
||||||
|
|
||||||
pmats = [self.no_collision]
|
pmats = [self.no_collision]
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'model': model,
|
'mesh': mesh,
|
||||||
'color_texture': tex,
|
'color_texture': tex,
|
||||||
'body': 'box',
|
'body': 'box',
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
|
|
@ -471,17 +474,17 @@ class Aro(ba.Actor):
|
||||||
'materials': pmats})
|
'materials': pmats})
|
||||||
|
|
||||||
self.scale = scale = 1.4
|
self.scale = scale = 1.4
|
||||||
ba.animate(self.node, 'model_scale', {0: 0})
|
bs.animate(self.node, 'mesh_scale', {0: 0})
|
||||||
|
|
||||||
pos = (position[0], position[1]+0.6, position[2])
|
pos = (position[0], position[1]+0.6, position[2])
|
||||||
self.regions: List[ba.Node] = [
|
self.regions: List[bs.Node] = [
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={'position': position,
|
attrs={'position': position,
|
||||||
'scale': (0.6, 0.05, 0.6),
|
'scale': (0.6, 0.05, 0.6),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
'materials': self._materials_region0}),
|
'materials': self._materials_region0}),
|
||||||
|
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={'position': pos,
|
attrs={'position': pos,
|
||||||
'scale': (0.5, 0.3, 0.9),
|
'scale': (0.5, 0.3, 0.9),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
|
|
@ -502,7 +505,7 @@ class Aro(ba.Actor):
|
||||||
while locs_count > 1:
|
while locs_count > 1:
|
||||||
scale = (1.5 * 0.1 * locs_count) + 0.8
|
scale = (1.5 * 0.1 * locs_count) + 0.8
|
||||||
|
|
||||||
self.locs.append(ba.newnode('locator',
|
self.locs.append(bs.newnode('locator',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={'shape': 'circleOutline',
|
attrs={'shape': 'circleOutline',
|
||||||
'position': pos,
|
'position': pos,
|
||||||
|
|
@ -528,14 +531,14 @@ class Aro(ba.Actor):
|
||||||
act._handle_score(self.team)
|
act._handle_score(self.team)
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
||||||
class Cuadro(ba.Actor):
|
class Cuadro(bs.Actor):
|
||||||
def __init__(self, team: int = 0,
|
def __init__(self, team: int = 0,
|
||||||
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
@ -543,19 +546,19 @@ class Cuadro(ba.Actor):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
setattr(self, 'locs', [])
|
setattr(self, 'locs', [])
|
||||||
|
|
||||||
self.collision = ba.Material()
|
self.collision = bs.Material()
|
||||||
self.collision.add_actions(
|
self.collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', True)))
|
actions=(('modify_part_collision', 'collide', True)))
|
||||||
|
|
||||||
pos = (position[0], position[1]+0.9, position[2]+1.5)
|
pos = (position[0], position[1]+0.9, position[2]+1.5)
|
||||||
self.region: ba.Node = ba.newnode('region',
|
self.region: bs.Node = bs.newnode('region',
|
||||||
attrs={'position': pos,
|
attrs={'position': pos,
|
||||||
'scale': (0.5, 2.7, 2.5),
|
'scale': (0.5, 2.7, 2.5),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
'materials': [self.collision,
|
'materials': [self.collision,
|
||||||
shared.footing_material]})
|
shared.footing_material]})
|
||||||
|
|
||||||
# self.shield = ba.newnode('shield', attrs={'radius': 1.0, 'color': (0,10,0)})
|
# self.shield = bs.newnode('shield', attrs={'radius': 1.0, 'color': (0,10,0)})
|
||||||
# self.region.connectattr('position', self.shield, 'position')
|
# self.region.connectattr('position', self.shield, 'position')
|
||||||
|
|
||||||
position = (position[0], position[1], position[2]+0.09)
|
position = (position[0], position[1], position[2]+0.09)
|
||||||
|
|
@ -578,7 +581,7 @@ class Cuadro(ba.Actor):
|
||||||
pos[2] += 0.19
|
pos[2] += 0.19
|
||||||
|
|
||||||
self.locs.append(
|
self.locs.append(
|
||||||
ba.newnode('locator',
|
bs.newnode('locator',
|
||||||
owner=self.region,
|
owner=self.region,
|
||||||
attrs={'shape': 'circle',
|
attrs={'shape': 'circle',
|
||||||
'position': pos,
|
'position': pos,
|
||||||
|
|
@ -595,14 +598,14 @@ class Cuadro(ba.Actor):
|
||||||
count_y -= 1
|
count_y -= 1
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
||||||
class Palos(ba.Actor):
|
class Palos(bs.Actor):
|
||||||
def __init__(self, team: int = 0,
|
def __init__(self, team: int = 0,
|
||||||
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
position: Sequence[float] = (0.0, 1.0, 0.0)):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
@ -613,26 +616,26 @@ class Palos(ba.Actor):
|
||||||
self.cua = None
|
self.cua = None
|
||||||
|
|
||||||
# Material Para; Traspasar Objetos
|
# Material Para; Traspasar Objetos
|
||||||
self.no_collision = ba.Material()
|
self.no_collision = bs.Material()
|
||||||
self.no_collision.add_actions(
|
self.no_collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', False)))
|
actions=(('modify_part_collision', 'collide', False)))
|
||||||
|
|
||||||
#
|
#
|
||||||
self.collision = ba.Material()
|
self.collision = bs.Material()
|
||||||
self.collision.add_actions(
|
self.collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', True)))
|
actions=(('modify_part_collision', 'collide', True)))
|
||||||
|
|
||||||
# Spawn just above the provided point.
|
# Spawn just above the provided point.
|
||||||
self._spawn_pos = (position[0], position[2]+2.5, position[2])
|
self._spawn_pos = (position[0], position[2]+2.5, position[2])
|
||||||
|
|
||||||
model = ba.getmodel('flagPole')
|
mesh = bs.getmesh('flagPole')
|
||||||
tex = ba.gettexture('flagPoleColor')
|
tex = bs.gettexture('flagPoleColor')
|
||||||
|
|
||||||
pmats = [self.no_collision]
|
pmats = [self.no_collision]
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'model': model,
|
'mesh': mesh,
|
||||||
'color_texture': tex,
|
'color_texture': tex,
|
||||||
'body': 'puck',
|
'body': 'puck',
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
|
|
@ -643,9 +646,9 @@ class Palos(ba.Actor):
|
||||||
'materials': pmats
|
'materials': pmats
|
||||||
})
|
})
|
||||||
self.scale = scale = 4.0
|
self.scale = scale = 4.0
|
||||||
ba.animate(self.node, 'model_scale', {0: scale})
|
bs.animate(self.node, 'mesh_scale', {0: scale})
|
||||||
|
|
||||||
self.loc = ba.newnode('locator',
|
self.loc = bs.newnode('locator',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={'shape': 'circle',
|
attrs={'shape': 'circle',
|
||||||
'position': position,
|
'position': position,
|
||||||
|
|
@ -657,7 +660,7 @@ class Palos(ba.Actor):
|
||||||
self._y = _y = 0.30
|
self._y = _y = 0.30
|
||||||
_x = -0.25 if team == 1 else 0.25
|
_x = -0.25 if team == 1 else 0.25
|
||||||
_pos = (position[0]+_x, position[1]-1.5 + _y, position[2])
|
_pos = (position[0]+_x, position[1]-1.5 + _y, position[2])
|
||||||
self.region = ba.newnode('region',
|
self.region = bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': _pos,
|
'position': _pos,
|
||||||
'scale': (0.4, 8, 0.4),
|
'scale': (0.4, 8, 0.4),
|
||||||
|
|
@ -680,7 +683,7 @@ class Palos(ba.Actor):
|
||||||
self.cua = Cuadro(team, pos).autoretain()
|
self.cua = Cuadro(team, pos).autoretain()
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
else:
|
else:
|
||||||
|
|
@ -698,7 +701,7 @@ class BasketMap(maps.FootballStadium):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.tint = [(0.806, 0.8, 1.0476), (1.3, 1.2, 1.0)][0]
|
gnode.tint = [(0.806, 0.8, 1.0476), (1.3, 1.2, 1.0)][0]
|
||||||
gnode.ambient_color = (1.3, 1.2, 1.0)
|
gnode.ambient_color = (1.3, 1.2, 1.0)
|
||||||
gnode.vignette_outer = (0.57, 0.57, 0.57)
|
gnode.vignette_outer = (0.57, 0.57, 0.57)
|
||||||
|
|
@ -715,21 +718,21 @@ class BasketMapV2(maps.HockeyStadium):
|
||||||
|
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self.node.materials = [shared.footing_material]
|
self.node.materials = [shared.footing_material]
|
||||||
self.node.collide_model = ba.getcollidemodel('footballStadiumCollide')
|
self.node.collision_mesh = bs.getcollisionmesh('footballStadiumCollide')
|
||||||
self.node.model = None
|
self.node.mesh = None
|
||||||
self.stands.model = None
|
self.stands.mesh = None
|
||||||
self.floor.reflection = 'soft'
|
self.floor.reflection = 'soft'
|
||||||
self.floor.reflection_scale = [1.6]
|
self.floor.reflection_scale = [1.6]
|
||||||
self.floor.color = (1.1, 0.05, 0.8)
|
self.floor.color = (1.1, 0.05, 0.8)
|
||||||
|
|
||||||
self.background = ba.newnode('terrain',
|
self.background = bs.newnode('terrain',
|
||||||
attrs={'model': ba.getmodel('thePadBG'),
|
attrs={'mesh': bs.getmesh('thePadBG'),
|
||||||
'lighting': False,
|
'lighting': False,
|
||||||
'background': True,
|
'background': True,
|
||||||
'color': (1.0, 0.2, 1.0),
|
'color': (1.0, 0.2, 1.0),
|
||||||
'color_texture': ba.gettexture('menuBG')})
|
'color_texture': bs.gettexture('menuBG')})
|
||||||
|
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.floor_reflection = True
|
gnode.floor_reflection = True
|
||||||
gnode.debris_friction = 0.3
|
gnode.debris_friction = 0.3
|
||||||
gnode.debris_kill_height = -0.3
|
gnode.debris_kill_height = -0.3
|
||||||
|
|
@ -742,24 +745,24 @@ class BasketMapV2(maps.HockeyStadium):
|
||||||
self.is_hockey = False
|
self.is_hockey = False
|
||||||
|
|
||||||
##################
|
##################
|
||||||
self.collision = ba.Material()
|
self.collision = bs.Material()
|
||||||
self.collision.add_actions(
|
self.collision.add_actions(
|
||||||
actions=(('modify_part_collision', 'collide', True)))
|
actions=(('modify_part_collision', 'collide', True)))
|
||||||
|
|
||||||
self.regions: List[ba.Node] = [
|
self.regions: List[bs.Node] = [
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={'position': (12.676897048950195, 0.2997918128967285, 5.583303928375244),
|
attrs={'position': (12.676897048950195, 0.2997918128967285, 5.583303928375244),
|
||||||
'scale': (1.01, 12, 28),
|
'scale': (1.01, 12, 28),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
'materials': [self.collision]}),
|
'materials': [self.collision]}),
|
||||||
|
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={'position': (11.871315956115723, 0.29975247383117676, 5.711406707763672),
|
attrs={'position': (11.871315956115723, 0.29975247383117676, 5.711406707763672),
|
||||||
'scale': (50, 12, 0.9),
|
'scale': (50, 12, 0.9),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
'materials': [self.collision]}),
|
'materials': [self.collision]}),
|
||||||
|
|
||||||
ba.newnode('region',
|
bs.newnode('region',
|
||||||
attrs={'position': (-12.776557922363281, 0.30036890506744385, 4.96237850189209),
|
attrs={'position': (-12.776557922363281, 0.30036890506744385, 4.96237850189209),
|
||||||
'scale': (1.01, 12, 28),
|
'scale': (1.01, 12, 28),
|
||||||
'type': 'box',
|
'type': 'box',
|
||||||
|
|
@ -767,5 +770,5 @@ class BasketMapV2(maps.HockeyStadium):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
ba._map.register_map(BasketMap)
|
bs._map.register_map(BasketMap)
|
||||||
ba._map.register_map(BasketMapV2)
|
bs._map.register_map(BasketMapV2)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
|
|
@ -8,24 +9,24 @@ Youtube: https://www.youtube.com/c/HeySmoothy
|
||||||
Website: https://bombsquad-community.web.app
|
Website: https://bombsquad-community.web.app
|
||||||
Github: https://github.com/bombsquad-community
|
Github: https://github.com/bombsquad-community
|
||||||
"""
|
"""
|
||||||
# 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
|
||||||
import _ba
|
import bascenev1 as bs
|
||||||
|
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.game.keepaway import KeepAwayGame, FlagState, Player
|
from bascenev1lib.game.keepaway import KeepAwayGame, FlagState, Player
|
||||||
from bastd.actor import spaz
|
from bascenev1lib.actor import spaz
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class ChooseQueen(KeepAwayGame):
|
class ChooseQueen(KeepAwayGame):
|
||||||
|
|
@ -33,11 +34,11 @@ class ChooseQueen(KeepAwayGame):
|
||||||
description = 'Carry the queen for a set length of time'
|
description = 'Carry the queen for a set length of time'
|
||||||
|
|
||||||
@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 ['Creative Thoughts']
|
return ['Creative Thoughts']
|
||||||
|
|
||||||
def get_instance_description(self) -> str | Sequence:
|
def get_instance_description(self) -> str | Sequence:
|
||||||
|
|
@ -50,13 +51,13 @@ class ChooseQueen(KeepAwayGame):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self.lifts = {}
|
self.lifts = {}
|
||||||
self._room_wall_material = ba.Material()
|
self._room_wall_material = bs.Material()
|
||||||
self._room_wall_material.add_actions(
|
self._room_wall_material.add_actions(
|
||||||
actions=(
|
actions=(
|
||||||
('modify_part_collision', 'collide', False),
|
('modify_part_collision', 'collide', False),
|
||||||
('modify_part_collision', 'physical', False)
|
('modify_part_collision', 'physical', False)
|
||||||
))
|
))
|
||||||
self._queen_material = ba.Material()
|
self._queen_material = bs.Material()
|
||||||
self._queen_material.add_actions(
|
self._queen_material.add_actions(
|
||||||
conditions=('they_have_material', self._room_wall_material),
|
conditions=('they_have_material', self._room_wall_material),
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -74,7 +75,7 @@ class ChooseQueen(KeepAwayGame):
|
||||||
('modify_part_collision', 'collide', True),
|
('modify_part_collision', 'collide', True),
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
))
|
))
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._real_wall_material.add_actions(
|
self._real_wall_material.add_actions(
|
||||||
actions=(
|
actions=(
|
||||||
('modify_part_collision', 'collide', True),
|
('modify_part_collision', 'collide', True),
|
||||||
|
|
@ -90,17 +91,17 @@ class ChooseQueen(KeepAwayGame):
|
||||||
))
|
))
|
||||||
|
|
||||||
def on_begin(self):
|
def on_begin(self):
|
||||||
ba.getactivity().globalsnode.happy_thoughts_mode = True
|
bs.getactivity().globalsnode.happy_thoughts_mode = True
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
self.make_map()
|
self.make_map()
|
||||||
|
|
||||||
def _spawn_flag(self) -> None:
|
def _spawn_flag(self) -> None:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
self._flash_flag_spawn()
|
self._flash_flag_spawn()
|
||||||
assert self._flag_spawn_pos is not None
|
assert self._flag_spawn_pos is not None
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._flag = spaz.Spaz((0, 0, 0), character="Pixel").autoretain()
|
self._flag = spaz.Spaz((0, 0, 0), character="Pixel").autoretain()
|
||||||
self._flag.handlemessage(ba.StandMessage((0, 14.63, -5.52), 93))
|
self._flag.handlemessage(bs.StandMessage((0, 14.63, -5.52), 93))
|
||||||
self._flag.node.hold_position_pressed = True
|
self._flag.node.hold_position_pressed = True
|
||||||
self._flag.node.materials = (self._queen_material, shared.object_material)
|
self._flag.node.materials = (self._queen_material, shared.object_material)
|
||||||
# self._flag.node.extras_material= tuple(list(self._flag.node.extras_material).append(self._queen_materia))
|
# self._flag.node.extras_material= tuple(list(self._flag.node.extras_material).append(self._queen_materia))
|
||||||
|
|
@ -108,7 +109,7 @@ class ChooseQueen(KeepAwayGame):
|
||||||
self._flag.hitpoints_max = 5000
|
self._flag.hitpoints_max = 5000
|
||||||
|
|
||||||
self._flag_state = FlagState.NEW
|
self._flag_state = FlagState.NEW
|
||||||
self._flag_light = ba.newnode(
|
self._flag_light = bs.newnode(
|
||||||
'light',
|
'light',
|
||||||
owner=self._flag.node,
|
owner=self._flag.node,
|
||||||
attrs={'intensity': 0.2, 'radius': 0.3, 'color': (0.2, 0.2, 0.2)},
|
attrs={'intensity': 0.2, 'radius': 0.3, 'color': (0.2, 0.2, 0.2)},
|
||||||
|
|
@ -136,7 +137,7 @@ class ChooseQueen(KeepAwayGame):
|
||||||
player.actor.node.hold_node == self._flag.node
|
player.actor.node.hold_node == self._flag.node
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error checking hold flag.')
|
babase.print_exception('Error checking hold flag.')
|
||||||
if holdingflag:
|
if holdingflag:
|
||||||
self._holding_players.append(player)
|
self._holding_players.append(player)
|
||||||
player.team.holdingflag = True
|
player.team.holdingflag = True
|
||||||
|
|
@ -158,43 +159,43 @@ class ChooseQueen(KeepAwayGame):
|
||||||
self._scoring_team = None
|
self._scoring_team = None
|
||||||
|
|
||||||
if self._flag_state != prevstate:
|
if self._flag_state != prevstate:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
|
|
||||||
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)
|
||||||
self.respawn_player(msg.getplayer(Player))
|
self.respawn_player(msg.getplayer(Player))
|
||||||
elif isinstance(msg, (ba.PickedUpMessage, ba.DroppedMessage)):
|
elif isinstance(msg, (bs.PickedUpMessage, bs.DroppedMessage)):
|
||||||
self._update_flag_state()
|
self._update_flag_state()
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
def make_map(self):
|
def make_map(self):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
_ba.get_foreground_host_activity()._map.leftwall.materials = [
|
bs.get_foreground_host_activity()._map.leftwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.rightwall.materials = [
|
bs.get_foreground_host_activity()._map.rightwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.topwall.materials = [
|
bs.get_foreground_host_activity()._map.topwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
self.floorwall1 = ba.newnode('region', attrs={'position': (-10, 5, -5.52), 'scale':
|
self.floorwall1 = bs.newnode('region', attrs={'position': (-10, 5, -5.52), 'scale':
|
||||||
(15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
(15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.floorwall2 = ba.newnode('region', attrs={'position': (10, 5, -5.52), 'scale': (
|
self.floorwall2 = bs.newnode('region', attrs={'position': (10, 5, -5.52), 'scale': (
|
||||||
15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
|
|
||||||
self.wall1 = ba.newnode('region', attrs={'position': (0, 11, -6.90), 'scale': (
|
self.wall1 = bs.newnode('region', attrs={'position': (0, 11, -6.90), 'scale': (
|
||||||
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.wall2 = ba.newnode('region', attrs={'position': (0, 11, -4.14), 'scale': (
|
self.wall2 = bs.newnode('region', attrs={'position': (0, 11, -4.14), 'scale': (
|
||||||
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
|
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (-10, 5, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (-10, 5, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
||||||
|
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (10, 5, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (10, 5, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
||||||
|
|
||||||
self.create_static_step(0, 14.29)
|
self.create_static_step(0, 14.29)
|
||||||
|
|
@ -219,25 +220,25 @@ class ChooseQueen(KeepAwayGame):
|
||||||
self.create_static_step(-3, 10)
|
self.create_static_step(-3, 10)
|
||||||
|
|
||||||
# create queen personal room
|
# create queen personal room
|
||||||
self.room_wall_left = ba.newnode('region', attrs={'position': (-3.633, 16.63, -5.52), 'scale':
|
self.room_wall_left = bs.newnode('region', attrs={'position': (-3.633, 16.63, -5.52), 'scale':
|
||||||
(2, 4, 5), 'type': 'box', 'materials': [shared.footing_material, self._room_wall_material]})
|
(2, 4, 5), 'type': 'box', 'materials': [shared.footing_material, self._room_wall_material]})
|
||||||
self.room_wall_right = ba.newnode('region', attrs={'position': (3.533, 16.63, -5.52), 'scale':
|
self.room_wall_right = bs.newnode('region', attrs={'position': (3.533, 16.63, -5.52), 'scale':
|
||||||
(2, 4, 5), 'type': 'box', 'materials': [shared.footing_material, self._room_wall_material]})
|
(2, 4, 5), 'type': 'box', 'materials': [shared.footing_material, self._room_wall_material]})
|
||||||
|
|
||||||
def create_static_step(self, x, y):
|
def create_static_step(self, x, y):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (5.5, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (5.5, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
||||||
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (5.5, 0.1, 2)})
|
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (5.5, 0.1, 2)})
|
||||||
|
|
||||||
def create_slope(self, x, y, backslash):
|
def create_slope(self, x, y, backslash):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
|
|
||||||
for _ in range(0, 21):
|
for _ in range(0, 21):
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
||||||
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.2, 0.1, 2)})
|
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.2, 0.1, 2)})
|
||||||
if backslash:
|
if backslash:
|
||||||
x = x + 0.1
|
x = x + 0.1
|
||||||
|
|
@ -291,7 +292,7 @@ class mapdefs:
|
||||||
0.5245740665, 0.5245740665, 0.01941146064)
|
0.5245740665, 0.5245740665, 0.01941146064)
|
||||||
|
|
||||||
|
|
||||||
class CreativeThoughts(ba.Map):
|
class CreativeThoughts(bs.Map):
|
||||||
"""Freaking map by smoothy."""
|
"""Freaking map by smoothy."""
|
||||||
|
|
||||||
defs = mapdefs
|
defs = mapdefs
|
||||||
|
|
@ -312,26 +313,26 @@ class CreativeThoughts(ba.Map):
|
||||||
@classmethod
|
@classmethod
|
||||||
def on_preload(cls) -> Any:
|
def on_preload(cls) -> Any:
|
||||||
data: Dict[str, Any] = {
|
data: Dict[str, Any] = {
|
||||||
'model': ba.getmodel('alwaysLandLevel'),
|
'mesh': bs.getmesh('alwaysLandLevel'),
|
||||||
'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
|
'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
|
||||||
'bgmodel': ba.getmodel('alwaysLandBG'),
|
'bgmesh': bs.getmesh('alwaysLandBG'),
|
||||||
'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
|
'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
|
||||||
'tex': ba.gettexture('alwaysLandLevelColor'),
|
'tex': bs.gettexture('alwaysLandLevelColor'),
|
||||||
'bgtex': ba.gettexture('alwaysLandBGColor'),
|
'bgtex': bs.gettexture('alwaysLandBGColor'),
|
||||||
'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
|
'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
|
||||||
'vr_fill_mound_tex': ba.gettexture('vrFillMound')
|
'vr_fill_mound_tex': bs.gettexture('vrFillMound')
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_music_type(cls) -> ba.MusicType:
|
def get_music_type(cls) -> bs.MusicType:
|
||||||
return ba.MusicType.FLYING
|
return bs.MusicType.FLYING
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._fake_wall_material = ba.Material()
|
self._fake_wall_material = bs.Material()
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._fake_wall_material.add_actions(
|
self._fake_wall_material.add_actions(
|
||||||
conditions=(('they_are_younger_than', 9000), 'and',
|
conditions=(('they_are_younger_than', 9000), 'and',
|
||||||
('they_have_material', shared.player_material)),
|
('they_have_material', shared.player_material)),
|
||||||
|
|
@ -347,29 +348,29 @@ class CreativeThoughts(ba.Map):
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
|
|
||||||
))
|
))
|
||||||
self.background = ba.newnode(
|
self.background = bs.newnode(
|
||||||
'terrain',
|
'terrain',
|
||||||
attrs={
|
attrs={
|
||||||
'model': self.preloaddata['bgmodel'],
|
'mesh': self.preloaddata['bgmesh'],
|
||||||
'lighting': False,
|
'lighting': False,
|
||||||
'background': True,
|
'background': True,
|
||||||
'color_texture': ba.gettexture("rampageBGColor")
|
'color_texture': bs.gettexture("rampageBGColor")
|
||||||
})
|
})
|
||||||
|
|
||||||
self.leftwall = ba.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
self.leftwall = bs.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.rightwall = ba.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
self.rightwall = bs.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.topwall = ba.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
self.topwall = bs.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
||||||
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
||||||
|
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.happy_thoughts_mode = True
|
gnode.happy_thoughts_mode = True
|
||||||
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
||||||
gnode.tint = (1.3, 1.23, 1.0)
|
gnode.tint = (1.3, 1.23, 1.0)
|
||||||
|
|
@ -380,9 +381,9 @@ class CreativeThoughts(ba.Map):
|
||||||
self.is_flying = True
|
self.is_flying = True
|
||||||
|
|
||||||
# throw out some tips on flying
|
# throw out some tips on flying
|
||||||
txt = ba.newnode('text',
|
txt = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': ba.Lstr(resource='pressJumpToFlyText'),
|
'text': babase.Lstr(resource='pressJumpToFlyText'),
|
||||||
'scale': 1.2,
|
'scale': 1.2,
|
||||||
'maxwidth': 800,
|
'maxwidth': 800,
|
||||||
'position': (0, 200),
|
'position': (0, 200),
|
||||||
|
|
@ -391,7 +392,7 @@ class CreativeThoughts(ba.Map):
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
cmb = ba.newnode('combine',
|
cmb = bs.newnode('combine',
|
||||||
owner=txt,
|
owner=txt,
|
||||||
attrs={
|
attrs={
|
||||||
'size': 4,
|
'size': 4,
|
||||||
|
|
@ -399,12 +400,12 @@ class CreativeThoughts(ba.Map):
|
||||||
'input1': 0.9,
|
'input1': 0.9,
|
||||||
'input2': 0.0
|
'input2': 0.0
|
||||||
})
|
})
|
||||||
ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
||||||
cmb.connectattr('output', txt, 'color')
|
cmb.connectattr('output', txt, 'color')
|
||||||
ba.timer(10.0, txt.delete)
|
bs.timer(10.0, txt.delete)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ba._map.register_map(CreativeThoughts)
|
bs._map.register_map(CreativeThoughts)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
|
|
@ -8,22 +9,22 @@ Youtube: https://www.youtube.com/c/HeySmoothy
|
||||||
Website: https://bombsquad-community.web.app
|
Website: https://bombsquad-community.web.app
|
||||||
Github: https://github.com/bombsquad-community
|
Github: https://github.com/bombsquad-community
|
||||||
"""
|
"""
|
||||||
# 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
|
||||||
import _ba
|
import bascenev1 as bs
|
||||||
from ba._generated.enums import InputType
|
from babase._mgen.enums import InputType
|
||||||
from bastd.actor.bomb import Blast
|
from bascenev1lib.actor.bomb import Blast
|
||||||
|
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
from bastd.actor.playerspaz import PlayerSpaz, PlayerType
|
from bascenev1lib.actor.playerspaz import PlayerSpaz, PlayerT
|
||||||
from bastd.game.deathmatch import DeathMatchGame, Player
|
from bascenev1lib.game.deathmatch import DeathMatchGame, Player
|
||||||
from bastd.actor import spaz
|
from bascenev1lib.actor import spaz
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
||||||
|
|
||||||
|
|
@ -33,11 +34,11 @@ STORAGE_ATTR_NAME = f'_shared_{__name__}_factory'
|
||||||
# use drone as long as you want , unlike floater which dies after being idle.
|
# use drone as long as you want , unlike floater which dies after being idle.
|
||||||
|
|
||||||
|
|
||||||
class Drone(ba.Actor):
|
class Drone(bs.Actor):
|
||||||
def __init__(self, spaz):
|
def __init__(self, spaz):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._drone_material = ba.Material()
|
self._drone_material = bs.Material()
|
||||||
self.loop_ascend = None
|
self.loop_ascend = None
|
||||||
self.loop_descend = None
|
self.loop_descend = None
|
||||||
self.loop_lr = None
|
self.loop_lr = None
|
||||||
|
|
@ -59,45 +60,45 @@ class Drone(ba.Actor):
|
||||||
('they_have_material',
|
('they_have_material',
|
||||||
self._drone_material)),
|
self._drone_material)),
|
||||||
actions=('modify_part_collision', 'physical', False))
|
actions=('modify_part_collision', 'physical', False))
|
||||||
self.node = ba.newnode(
|
self.node = bs.newnode(
|
||||||
'prop',
|
'prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
owner=None,
|
owner=None,
|
||||||
attrs={
|
attrs={
|
||||||
'position': spaz.node.position,
|
'position': spaz.node.position,
|
||||||
'model': ba.getmodel('landMine'),
|
'mesh': bs.getmesh('landMine'),
|
||||||
'light_model': ba.getmodel('landMine'),
|
'light_mesh': bs.getmesh('landMine'),
|
||||||
'body': 'landMine',
|
'body': 'landMine',
|
||||||
'body_scale': 1,
|
'body_scale': 1,
|
||||||
'model_scale': 1,
|
'mesh_scale': 1,
|
||||||
'shadow_size': 0.25,
|
'shadow_size': 0.25,
|
||||||
'density': 999999,
|
'density': 999999,
|
||||||
'gravity_scale': 0.0,
|
'gravity_scale': 0.0,
|
||||||
'color_texture': ba.gettexture('achievementCrossHair'),
|
'color_texture': bs.gettexture('achievementCrossHair'),
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
'reflection_scale': [0.25],
|
'reflection_scale': [0.25],
|
||||||
'materials': [shared.footing_material, self._drone_material]
|
'materials': [shared.footing_material, self._drone_material]
|
||||||
})
|
})
|
||||||
self.grab_node = ba.newnode(
|
self.grab_node = bs.newnode(
|
||||||
'prop',
|
'prop',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 0, 0),
|
'position': (0, 0, 0),
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'model': None,
|
'mesh': None,
|
||||||
'color_texture': None,
|
'color_texture': None,
|
||||||
'body_scale': 0.2,
|
'body_scale': 0.2,
|
||||||
'reflection': 'powerup',
|
'reflection': 'powerup',
|
||||||
'density': 999999,
|
'density': 999999,
|
||||||
'reflection_scale': [1.0],
|
'reflection_scale': [1.0],
|
||||||
'model_scale': 0.2,
|
'mesh_scale': 0.2,
|
||||||
'gravity_scale': 0,
|
'gravity_scale': 0,
|
||||||
'shadow_size': 0.1,
|
'shadow_size': 0.1,
|
||||||
'is_area_of_interest': True,
|
'is_area_of_interest': True,
|
||||||
'materials': [shared.object_material, self._drone_material]
|
'materials': [shared.object_material, self._drone_material]
|
||||||
})
|
})
|
||||||
self.node.connectattr('position', self.grab_node, 'position')
|
self.node.connectattr('position', self.grab_node, 'position')
|
||||||
self._rcombine = ba.newnode('combine',
|
self._rcombine = bs.newnode('combine',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input0': self.spaz.node.position[0],
|
'input0': self.spaz.node.position[0],
|
||||||
|
|
@ -119,12 +120,12 @@ class Drone(ba.Actor):
|
||||||
def ascend(self):
|
def ascend(self):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input1', {
|
bs.animate(self._rcombine, 'input1', {
|
||||||
0: self.node.position[1],
|
0: self.node.position[1],
|
||||||
1: self.node.position[1] + 2
|
1: self.node.position[1] + 2
|
||||||
})
|
})
|
||||||
loop()
|
loop()
|
||||||
self.loop_ascend = ba.Timer(1, loop, repeat=True)
|
self.loop_ascend = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def pause_movement(self):
|
def pause_movement(self):
|
||||||
self.loop_ascend = None
|
self.loop_ascend = None
|
||||||
|
|
@ -132,12 +133,12 @@ class Drone(ba.Actor):
|
||||||
def decend(self):
|
def decend(self):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input1', {
|
bs.animate(self._rcombine, 'input1', {
|
||||||
0: self.node.position[1],
|
0: self.node.position[1],
|
||||||
1: self.node.position[1] - 2
|
1: self.node.position[1] - 2
|
||||||
})
|
})
|
||||||
loop()
|
loop()
|
||||||
self.loop_ascend = ba.Timer(1, loop, repeat=True)
|
self.loop_ascend = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def pause_lr(self):
|
def pause_lr(self):
|
||||||
self.loop_lr = None
|
self.loop_lr = None
|
||||||
|
|
@ -148,7 +149,7 @@ class Drone(ba.Actor):
|
||||||
def left_(self, value=-1):
|
def left_(self, value=-1):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input0', {
|
bs.animate(self._rcombine, 'input0', {
|
||||||
0: self.node.position[0],
|
0: self.node.position[0],
|
||||||
1: self.node.position[0] + 2 * value
|
1: self.node.position[0] + 2 * value
|
||||||
})
|
})
|
||||||
|
|
@ -158,12 +159,12 @@ class Drone(ba.Actor):
|
||||||
self.x_direction = value
|
self.x_direction = value
|
||||||
self.z_direction = 0
|
self.z_direction = 0
|
||||||
loop()
|
loop()
|
||||||
self.loop_lr = ba.Timer(1, loop, repeat=True)
|
self.loop_lr = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def right_(self, value=1):
|
def right_(self, value=1):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input0', {
|
bs.animate(self._rcombine, 'input0', {
|
||||||
0: self.node.position[0],
|
0: self.node.position[0],
|
||||||
1: self.node.position[0] + 2 * value
|
1: self.node.position[0] + 2 * value
|
||||||
})
|
})
|
||||||
|
|
@ -173,12 +174,12 @@ class Drone(ba.Actor):
|
||||||
self.x_direction = value
|
self.x_direction = value
|
||||||
self.z_direction = 0
|
self.z_direction = 0
|
||||||
loop()
|
loop()
|
||||||
self.loop_lr = ba.Timer(1, loop, repeat=True)
|
self.loop_lr = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def up_(self, value=1):
|
def up_(self, value=1):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input2', {
|
bs.animate(self._rcombine, 'input2', {
|
||||||
0: self.node.position[2],
|
0: self.node.position[2],
|
||||||
1: self.node.position[2] - 2 * value
|
1: self.node.position[2] - 2 * value
|
||||||
})
|
})
|
||||||
|
|
@ -188,12 +189,12 @@ class Drone(ba.Actor):
|
||||||
self.x_direction = 0
|
self.x_direction = 0
|
||||||
self.z_direction = - value
|
self.z_direction = - value
|
||||||
loop()
|
loop()
|
||||||
self.loop_ud = ba.Timer(1, loop, repeat=True)
|
self.loop_ud = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def down_(self, value=-1):
|
def down_(self, value=-1):
|
||||||
def loop():
|
def loop():
|
||||||
if self.node.exists():
|
if self.node.exists():
|
||||||
ba.animate(self._rcombine, 'input2', {
|
bs.animate(self._rcombine, 'input2', {
|
||||||
0: self.node.position[2],
|
0: self.node.position[2],
|
||||||
1: self.node.position[2] - 2 * value
|
1: self.node.position[2] - 2 * value
|
||||||
})
|
})
|
||||||
|
|
@ -203,17 +204,17 @@ class Drone(ba.Actor):
|
||||||
self.x_direction = 0
|
self.x_direction = 0
|
||||||
self.z_direction = - value
|
self.z_direction = - value
|
||||||
loop()
|
loop()
|
||||||
self.loop_ud = ba.Timer(1, loop, repeat=True)
|
self.loop_ud = bs.Timer(1, loop, repeat=True)
|
||||||
|
|
||||||
def handlemessage(self, msg):
|
def handlemessage(self, msg):
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
self.grab_node.delete()
|
self.grab_node.delete()
|
||||||
self.loop_ascend = None
|
self.loop_ascend = None
|
||||||
self.loop_ud = None
|
self.loop_ud = None
|
||||||
self.loop_lr = None
|
self.loop_lr = None
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
@ -224,7 +225,7 @@ class RocketFactory:
|
||||||
"""Quake Rocket factory"""
|
"""Quake Rocket factory"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.ball_material = ba.Material()
|
self.ball_material = bs.Material()
|
||||||
|
|
||||||
self.ball_material.add_actions(
|
self.ball_material.add_actions(
|
||||||
conditions=((('we_are_younger_than', 5), 'or',
|
conditions=((('we_are_younger_than', 5), 'or',
|
||||||
|
|
@ -251,7 +252,7 @@ class RocketFactory:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls):
|
def get(cls):
|
||||||
"""Get factory if exists else create new"""
|
"""Get factory if exists else create new"""
|
||||||
activity = ba.getactivity()
|
activity = bs.getactivity()
|
||||||
if hasattr(activity, STORAGE_ATTR_NAME):
|
if hasattr(activity, STORAGE_ATTR_NAME):
|
||||||
return getattr(activity, STORAGE_ATTR_NAME)
|
return getattr(activity, STORAGE_ATTR_NAME)
|
||||||
factory = cls()
|
factory = cls()
|
||||||
|
|
@ -263,30 +264,30 @@ class RocketLauncher:
|
||||||
"""Very dangerous weapon"""
|
"""Very dangerous weapon"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.last_shot = ba.time()
|
self.last_shot = bs.time()
|
||||||
|
|
||||||
def give(self, spaz: spaz.Spaz) -> None:
|
def give(self, spaz: spaz.Spaz) -> None:
|
||||||
"""Give spaz a rocket launcher"""
|
"""Give spaz a rocket launcher"""
|
||||||
spaz.punch_callback = self.shot
|
spaz.punch_callback = self.shot
|
||||||
self.last_shot = ba.time()
|
self.last_shot = bs.time()
|
||||||
|
|
||||||
# FIXME
|
# FIXME
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
def shot(self, spaz, x, z, position) -> None:
|
def shot(self, spaz, x, z, position) -> None:
|
||||||
"""Release a rocket"""
|
"""Release a rocket"""
|
||||||
time = ba.time()
|
time = bs.time()
|
||||||
if time - self.last_shot > 0.6:
|
if time - self.last_shot > 0.6:
|
||||||
self.last_shot = time
|
self.last_shot = time
|
||||||
|
|
||||||
direction = [x, 0, z]
|
direction = [x, 0, z]
|
||||||
direction[1] = 0.0
|
direction[1] = 0.0
|
||||||
|
|
||||||
mag = 10.0 / 1 if ba.Vec3(*direction).length() == 0 else ba.Vec3(*direction).length()
|
mag = 10.0 / 1 if babase.Vec3(*direction).length() == 0 else babase.Vec3(*direction).length()
|
||||||
vel = [v * mag for v in direction]
|
vel = [v * mag for v in direction]
|
||||||
Rocket(position=position,
|
Rocket(position=position,
|
||||||
velocity=vel,
|
velocity=vel,
|
||||||
owner=spaz.getplayer(ba.Player),
|
owner=spaz.getplayer(bs.Player),
|
||||||
source_player=spaz.getplayer(ba.Player),
|
source_player=spaz.getplayer(bs.Player),
|
||||||
color=spaz.node.color).autoretain()
|
color=spaz.node.color).autoretain()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -294,7 +295,7 @@ class ImpactMessage:
|
||||||
"""Rocket touched something"""
|
"""Rocket touched something"""
|
||||||
|
|
||||||
|
|
||||||
class Rocket(ba.Actor):
|
class Rocket(bs.Actor):
|
||||||
"""Epic rocket from rocket launcher"""
|
"""Epic rocket from rocket launcher"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
|
@ -309,16 +310,16 @@ class Rocket(ba.Actor):
|
||||||
self._color = color
|
self._color = color
|
||||||
factory = RocketFactory.get()
|
factory = RocketFactory.get()
|
||||||
|
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position': position,
|
'position': position,
|
||||||
'velocity': velocity,
|
'velocity': velocity,
|
||||||
'model': ba.getmodel('impactBomb'),
|
'mesh': bs.getmesh('impactBomb'),
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'color_texture': ba.gettexture(
|
'color_texture': bs.gettexture(
|
||||||
'bunnyColor'),
|
'bunnyColor'),
|
||||||
'model_scale': 0.2,
|
'mesh_scale': 0.2,
|
||||||
'is_area_of_interest': True,
|
'is_area_of_interest': True,
|
||||||
'body_scale': 0.8,
|
'body_scale': 0.8,
|
||||||
'materials': [
|
'materials': [
|
||||||
|
|
@ -328,17 +329,17 @@ class Rocket(ba.Actor):
|
||||||
self.node.extra_acceleration = (self.node.velocity[0] * 200, 0,
|
self.node.extra_acceleration = (self.node.velocity[0] * 200, 0,
|
||||||
self.node.velocity[2] * 200)
|
self.node.velocity[2] * 200)
|
||||||
|
|
||||||
self._life_timer = ba.Timer(
|
self._life_timer = bs.Timer(
|
||||||
5, ba.WeakCall(self.handlemessage, ba.DieMessage()))
|
5, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||||
|
|
||||||
self._emit_timer = ba.Timer(0.001, ba.WeakCall(self.emit), repeat=True)
|
self._emit_timer = bs.Timer(0.001, bs.WeakCall(self.emit), repeat=True)
|
||||||
self.base_pos_y = self.node.position[1]
|
self.base_pos_y = self.node.position[1]
|
||||||
|
|
||||||
ba.camerashake(5.0)
|
bs.camerashake(5.0)
|
||||||
|
|
||||||
def emit(self) -> None:
|
def emit(self) -> None:
|
||||||
"""Emit a trace after rocket"""
|
"""Emit a trace after rocket"""
|
||||||
ba.emitfx(position=self.node.position,
|
bs.emitfx(position=self.node.position,
|
||||||
scale=0.4,
|
scale=0.4,
|
||||||
spread=0.01,
|
spread=0.01,
|
||||||
chunk_type='spark')
|
chunk_type='spark')
|
||||||
|
|
@ -346,7 +347,7 @@ class Rocket(ba.Actor):
|
||||||
return
|
return
|
||||||
self.node.position = (self.node.position[0], self.base_pos_y,
|
self.node.position = (self.node.position[0], self.base_pos_y,
|
||||||
self.node.position[2]) # ignore y
|
self.node.position[2]) # ignore y
|
||||||
ba.newnode('explosion',
|
bs.newnode('explosion',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': self.node.position,
|
'position': self.node.position,
|
||||||
|
|
@ -358,9 +359,9 @@ class Rocket(ba.Actor):
|
||||||
"""Message handling for rocket"""
|
"""Message handling for rocket"""
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
if isinstance(msg, ImpactMessage):
|
if isinstance(msg, ImpactMessage):
|
||||||
self.node.handlemessage(ba.DieMessage())
|
self.node.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
elif isinstance(msg, ba.DieMessage):
|
elif isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
Blast(position=self.node.position,
|
Blast(position=self.node.position,
|
||||||
blast_radius=2,
|
blast_radius=2,
|
||||||
|
|
@ -369,25 +370,25 @@ class Rocket(ba.Actor):
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
self._emit_timer = None
|
self._emit_timer = None
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class ChooseQueen(DeathMatchGame):
|
class ChooseQueen(DeathMatchGame):
|
||||||
name = 'Drone War'
|
name = 'Drone War'
|
||||||
|
|
||||||
@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 ['Football Stadium']
|
return ['Football Stadium']
|
||||||
|
|
||||||
def spawn_player_spaz(
|
def spawn_player_spaz(
|
||||||
self,
|
self,
|
||||||
player: PlayerType,
|
player: PlayerT,
|
||||||
position: Sequence[float] | None = None,
|
position: Sequence[float] | None = None,
|
||||||
angle: float | None = None,
|
angle: float | None = None,
|
||||||
) -> PlayerSpaz:
|
) -> PlayerSpaz:
|
||||||
|
|
@ -398,29 +399,29 @@ class ChooseQueen(DeathMatchGame):
|
||||||
def on_begin(self):
|
def on_begin(self):
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self.ground_material = ba.Material()
|
self.ground_material = bs.Material()
|
||||||
self.ground_material.add_actions(
|
self.ground_material.add_actions(
|
||||||
conditions=('they_have_material', shared.player_material),
|
conditions=('they_have_material', shared.player_material),
|
||||||
actions=(
|
actions=(
|
||||||
('modify_part_collision', 'collide', True),
|
('modify_part_collision', 'collide', True),
|
||||||
('call', 'at_connect', ba.Call(self._handle_player_collide)),
|
('call', 'at_connect', babase.Call(self._handle_player_collide)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
pos = (0, 0.1, -5)
|
pos = (0, 0.1, -5)
|
||||||
self.main_region = ba.newnode('region', attrs={'position': pos, 'scale': (
|
self.main_region = bs.newnode('region', attrs={'position': pos, 'scale': (
|
||||||
30, 0.001, 23), 'type': 'box', 'materials': [shared.footing_material, self.ground_material]})
|
30, 0.001, 23), 'type': 'box', 'materials': [shared.footing_material, self.ground_material]})
|
||||||
|
|
||||||
def _handle_player_collide(self):
|
def _handle_player_collide(self):
|
||||||
try:
|
try:
|
||||||
player = ba.getcollision().opposingnode.getdelegate(
|
player = bs.getcollision().opposingnode.getdelegate(
|
||||||
PlayerSpaz, True)
|
PlayerSpaz, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
player.shatter(True)
|
player.shatter(True)
|
||||||
|
|
||||||
def spawn_drone(self, spaz):
|
def spawn_drone(self, spaz):
|
||||||
with ba.Context(_ba.get_foreground_host_activity()):
|
with bs.get_foreground_host_activity().context:
|
||||||
|
|
||||||
drone = Drone(spaz)
|
drone = Drone(spaz)
|
||||||
r_launcher = RocketLauncher()
|
r_launcher = RocketLauncher()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Hot Potato by TheMikirog#1984
|
Hot Potato by TheMikirog#1984
|
||||||
|
|
@ -13,20 +14,23 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
# Define only what we need and nothing more
|
# Define only what we need and nothing more
|
||||||
import ba
|
from baenv import TARGET_BALLISTICA_BUILD as build_number
|
||||||
from bastd.actor.spaz import SpazFactory
|
import babase
|
||||||
from bastd.actor.spaz import PickupMessage
|
import bauiv1 as bui
|
||||||
from bastd.actor.spaz import BombDiedMessage
|
import bascenev1 as bs
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.spaz import SpazFactory
|
||||||
from bastd.actor.bomb import Bomb
|
from bascenev1lib.actor.spaz import PickupMessage
|
||||||
from bastd.actor.bomb import Blast
|
from bascenev1lib.actor.spaz import BombDiedMessage
|
||||||
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
|
from bascenev1lib.actor.bomb import Bomb
|
||||||
|
from bascenev1lib.actor.bomb import Blast
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
@ -72,7 +76,7 @@ class PlayerState(Enum):
|
||||||
# Here's the behavior of each icon.
|
# Here's the behavior of each icon.
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -88,11 +92,11 @@ class Icon(ba.Actor):
|
||||||
self._player = player
|
self._player = player
|
||||||
self._name_scale = name_scale
|
self._name_scale = name_scale
|
||||||
|
|
||||||
self._outline_tex = ba.gettexture('characterIconMask')
|
self._outline_tex = bui.gettexture('characterIconMask')
|
||||||
|
|
||||||
# Character portrait
|
# Character portrait
|
||||||
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'],
|
||||||
|
|
@ -106,12 +110,12 @@ class Icon(ba.Actor):
|
||||||
'attach': 'bottomCenter'
|
'attach': 'bottomCenter'
|
||||||
})
|
})
|
||||||
# Player name
|
# Player name
|
||||||
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,
|
||||||
|
|
@ -122,7 +126,7 @@ class Icon(ba.Actor):
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
# Status text (such as Marked!, Stunned! and You're Out!)
|
# Status text (such as Marked!, Stunned! and You're Out!)
|
||||||
self._marked_text = ba.newnode(
|
self._marked_text = bs.newnode(
|
||||||
'text',
|
'text',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
|
|
@ -137,11 +141,11 @@ class Icon(ba.Actor):
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
# Status icon overlaying the character portrait
|
# Status icon overlaying the character portrait
|
||||||
self._marked_icon = ba.newnode(
|
self._marked_icon = bs.newnode(
|
||||||
'text',
|
'text',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': ba.charstr(ba.SpecialChar.HAL),
|
'text': babase.charstr(babase.SpecialChar.HAL),
|
||||||
'color': (1, 1, 1),
|
'color': (1, 1, 1),
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_align': 'center',
|
'v_align': 'center',
|
||||||
|
|
@ -169,7 +173,7 @@ class Icon(ba.Actor):
|
||||||
self.node.color = (1.0, 1.0, 1.0)
|
self.node.color = (1.0, 1.0, 1.0)
|
||||||
# Marked players get ALL of the attention - red portrait, red text and icon overlaying the portrait
|
# Marked players get ALL of the attention - red portrait, red text and icon overlaying the portrait
|
||||||
elif type is PlayerState.MARKED:
|
elif type is PlayerState.MARKED:
|
||||||
self._marked_icon.text = ba.charstr(ba.SpecialChar.HAL)
|
self._marked_icon.text = babase.charstr(babase.SpecialChar.HAL)
|
||||||
self._marked_icon.position = (pos[0] - 1, pos[1] - 13)
|
self._marked_icon.position = (pos[0] - 1, pos[1] - 13)
|
||||||
self._marked_icon.opacity = 1.0
|
self._marked_icon.opacity = 1.0
|
||||||
self._marked_text.text = 'Marked!'
|
self._marked_text.text = 'Marked!'
|
||||||
|
|
@ -179,7 +183,7 @@ class Icon(ba.Actor):
|
||||||
self.node.color = (1.0, 0.2, 0.2)
|
self.node.color = (1.0, 0.2, 0.2)
|
||||||
# Stunned players are just as important - yellow portrait, yellow text and moon icon.
|
# Stunned players are just as important - yellow portrait, yellow text and moon icon.
|
||||||
elif type is PlayerState.STUNNED:
|
elif type is PlayerState.STUNNED:
|
||||||
self._marked_icon.text = ba.charstr(ba.SpecialChar.MOON)
|
self._marked_icon.text = babase.charstr(babase.SpecialChar.MOON)
|
||||||
self._marked_icon.position = (pos[0] - 2, pos[1] - 12)
|
self._marked_icon.position = (pos[0] - 2, pos[1] - 12)
|
||||||
self._marked_icon.opacity = 1.0
|
self._marked_icon.opacity = 1.0
|
||||||
self._marked_text.text = 'Stunned!'
|
self._marked_text.text = 'Stunned!'
|
||||||
|
|
@ -189,17 +193,17 @@ class Icon(ba.Actor):
|
||||||
# Eliminated players get special treatment.
|
# Eliminated players get special treatment.
|
||||||
# We make the portrait semi-transparent, while adding some visual flair with an fading skull icon and text.
|
# We make the portrait semi-transparent, while adding some visual flair with an fading skull icon and text.
|
||||||
elif type is PlayerState.ELIMINATED:
|
elif type is PlayerState.ELIMINATED:
|
||||||
self._marked_icon.text = ba.charstr(ba.SpecialChar.SKULL)
|
self._marked_icon.text = babase.charstr(babase.SpecialChar.SKULL)
|
||||||
self._marked_icon.position = (pos[0] - 2, pos[1] - 12)
|
self._marked_icon.position = (pos[0] - 2, pos[1] - 12)
|
||||||
self._marked_text.text = 'You\'re Out!'
|
self._marked_text.text = 'You\'re Out!'
|
||||||
self._marked_text.color = (0.5, 0.5, 0.5)
|
self._marked_text.color = (0.5, 0.5, 0.5)
|
||||||
|
|
||||||
# Animate text and icon
|
# Animate text and icon
|
||||||
animation_end_time = 1.5 if bool(self.activity.settings['Epic Mode']) else 3.0
|
animation_end_time = 1.5 if bool(self.activity.settings['Epic Mode']) else 3.0
|
||||||
ba.animate(self._marked_icon, 'opacity', {
|
bs.animate(self._marked_icon, 'opacity', {
|
||||||
0: 1.0,
|
0: 1.0,
|
||||||
animation_end_time: 0.0})
|
animation_end_time: 0.0})
|
||||||
ba.animate(self._marked_text, 'opacity', {
|
bs.animate(self._marked_text, 'opacity', {
|
||||||
0: 1.0,
|
0: 1.0,
|
||||||
animation_end_time: 0.0})
|
animation_end_time: 0.0})
|
||||||
|
|
||||||
|
|
@ -235,7 +239,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
self.dropped_bombs = [] # we use this to track bombs thrown by the player
|
self.dropped_bombs = [] # we use this to track bombs thrown by the player
|
||||||
|
|
||||||
# Define a marked light
|
# Define a marked light
|
||||||
self.marked_light = ba.newnode('light',
|
self.marked_light = bs.newnode('light',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={'position': self.node.position,
|
attrs={'position': self.node.position,
|
||||||
'radius': 0.15,
|
'radius': 0.15,
|
||||||
|
|
@ -244,7 +248,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
'color': (1.0, 0.0, 0.0)})
|
'color': (1.0, 0.0, 0.0)})
|
||||||
|
|
||||||
# Pulsing red light when the player is Marked
|
# Pulsing red light when the player is Marked
|
||||||
ba.animate(self.marked_light, 'radius', {
|
bs.animate(self.marked_light, 'radius', {
|
||||||
0: 0.1,
|
0: 0.1,
|
||||||
0.3: 0.15,
|
0.3: 0.15,
|
||||||
0.6: 0.1},
|
0.6: 0.1},
|
||||||
|
|
@ -252,12 +256,12 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
self.node.connectattr('position_center', self.marked_light, 'position')
|
self.node.connectattr('position_center', self.marked_light, 'position')
|
||||||
|
|
||||||
# Marked timer. It should be above our head, so we attach the text to the offset that's attached to the player.
|
# Marked timer. It should be above our head, so we attach the text to the offset that's attached to the player.
|
||||||
self.marked_timer_offset = ba.newnode('math', owner=self.node, attrs={
|
self.marked_timer_offset = bs.newnode('math', owner=self.node, attrs={
|
||||||
'input1': (0, 1.2, 0),
|
'input1': (0, 1.2, 0),
|
||||||
'operation': 'add'})
|
'operation': 'add'})
|
||||||
self.node.connectattr('torso_position', self.marked_timer_offset, 'input2')
|
self.node.connectattr('torso_position', self.marked_timer_offset, 'input2')
|
||||||
|
|
||||||
self.marked_timer_text = ba.newnode('text', owner=self.node, attrs={
|
self.marked_timer_text = bs.newnode('text', owner=self.node, attrs={
|
||||||
'text': '',
|
'text': '',
|
||||||
'in_world': True,
|
'in_world': True,
|
||||||
'shadow': 0.4,
|
'shadow': 0.4,
|
||||||
|
|
@ -278,7 +282,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# Add our bomb to the list of our tracked bombs
|
# Add our bomb to the list of our tracked bombs
|
||||||
self.dropped_bombs.append(bomb)
|
self.dropped_bombs.append(bomb)
|
||||||
# Bring a light
|
# Bring a light
|
||||||
bomb.bomb_marked_light = ba.newnode('light',
|
bomb.bomb_marked_light = bs.newnode('light',
|
||||||
owner=bomb.node,
|
owner=bomb.node,
|
||||||
attrs={'position': bomb.node.position,
|
attrs={'position': bomb.node.position,
|
||||||
'radius': 0.04,
|
'radius': 0.04,
|
||||||
|
|
@ -291,7 +295,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
self.set_bombs_marked()
|
self.set_bombs_marked()
|
||||||
# When the bomb physics node dies, call a function.
|
# When the bomb physics node dies, call a function.
|
||||||
bomb.node.add_death_action(
|
bomb.node.add_death_action(
|
||||||
ba.WeakCall(self.bomb_died, bomb))
|
bs.WeakCall(self.bomb_died, bomb))
|
||||||
|
|
||||||
# Here's the function that gets called when one of the player's bombs dies.
|
# Here's the function that gets called when one of the player's bombs dies.
|
||||||
# We reference the player's dropped_bombs list and remove the bomb that died.
|
# We reference the player's dropped_bombs list and remove the bomb that died.
|
||||||
|
|
@ -309,7 +313,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# Since our gamemode relies heavily on players passing the mark to other players
|
# Since our gamemode relies heavily on players passing the mark to other players
|
||||||
# we need to have access to this message. This gets called when the player takes damage for any reason.
|
# we need to have access to this message. This gets called when the player takes damage for any reason.
|
||||||
def handlemessage(self, msg):
|
def handlemessage(self, msg):
|
||||||
if isinstance(msg, ba.HitMessage):
|
if isinstance(msg, bs.HitMessage):
|
||||||
# This is basically the same HitMessage code as in the original Spaz.
|
# This is basically the same HitMessage code as in the original Spaz.
|
||||||
# The only difference is that there is no health bar and you can't die with punches or bombs.
|
# The only difference is that there is no health bar and you can't die with punches or bombs.
|
||||||
# Also some useless or redundant code was removed.
|
# Also some useless or redundant code was removed.
|
||||||
|
|
@ -326,9 +330,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# If the attacker is healthy and we're stunned, do a flash and play a sound, then ignore the rest of the code.
|
# If the attacker is healthy and we're stunned, do a flash and play a sound, then ignore the rest of the code.
|
||||||
if self.source_player.state == PlayerState.STUNNED and msg._source_player != PlayerState.MARKED:
|
if self.source_player.state == PlayerState.STUNNED and msg._source_player != PlayerState.MARKED:
|
||||||
self.node.handlemessage('flash')
|
self.node.handlemessage('flash')
|
||||||
ba.playsound(SpazFactory.get().block_sound,
|
SpazFactory.get().block_sound.play(1.0, position=self.node.position)
|
||||||
1.0,
|
|
||||||
position=self.node.position)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Here's all the damage and force calculations unchanged from the source.
|
# Here's all the damage and force calculations unchanged from the source.
|
||||||
|
|
@ -360,11 +362,11 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
sound = SpazFactory.get().punch_sound
|
sound = SpazFactory.get().punch_sound
|
||||||
else:
|
else:
|
||||||
sound = SpazFactory.get().punch_sound_weak
|
sound = SpazFactory.get().punch_sound_weak
|
||||||
ba.playsound(sound, 1.0, position=self.node.position)
|
sound.play(1.0, position=self.node.position)
|
||||||
|
|
||||||
# Throw up some chunks.
|
# Throw up some chunks.
|
||||||
assert msg.force_direction is not None
|
assert msg.force_direction is not None
|
||||||
ba.emitfx(position=msg.pos,
|
bs.emitfx(position=msg.pos,
|
||||||
velocity=(msg.force_direction[0] * 0.5,
|
velocity=(msg.force_direction[0] * 0.5,
|
||||||
msg.force_direction[1] * 0.5,
|
msg.force_direction[1] * 0.5,
|
||||||
msg.force_direction[2] * 0.5),
|
msg.force_direction[2] * 0.5),
|
||||||
|
|
@ -372,7 +374,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
scale=0.3,
|
scale=0.3,
|
||||||
spread=0.03)
|
spread=0.03)
|
||||||
|
|
||||||
ba.emitfx(position=msg.pos,
|
bs.emitfx(position=msg.pos,
|
||||||
chunk_type='sweat',
|
chunk_type='sweat',
|
||||||
velocity=(msg.force_direction[0] * 1.3,
|
velocity=(msg.force_direction[0] * 1.3,
|
||||||
msg.force_direction[1] * 1.3 + 5.0,
|
msg.force_direction[1] * 1.3 + 5.0,
|
||||||
|
|
@ -387,7 +389,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
msg.pos[1] + msg.force_direction[1] * 0.02,
|
msg.pos[1] + msg.force_direction[1] * 0.02,
|
||||||
msg.pos[2] + msg.force_direction[2] * 0.02)
|
msg.pos[2] + msg.force_direction[2] * 0.02)
|
||||||
flash_color = (1.0, 0.8, 0.4)
|
flash_color = (1.0, 0.8, 0.4)
|
||||||
light = ba.newnode(
|
light = bs.newnode(
|
||||||
'light',
|
'light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': punchpos,
|
'position': punchpos,
|
||||||
|
|
@ -396,20 +398,20 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'color': flash_color
|
'color': flash_color
|
||||||
})
|
})
|
||||||
ba.timer(0.06, light.delete)
|
bs.timer(0.06, light.delete)
|
||||||
|
|
||||||
flash = ba.newnode('flash',
|
flash = bs.newnode('flash',
|
||||||
attrs={
|
attrs={
|
||||||
'position': punchpos,
|
'position': punchpos,
|
||||||
'size': 0.17 + 0.17 * hurtiness,
|
'size': 0.17 + 0.17 * hurtiness,
|
||||||
'color': flash_color
|
'color': flash_color
|
||||||
})
|
})
|
||||||
ba.timer(0.06, flash.delete)
|
bs.timer(0.06, flash.delete)
|
||||||
|
|
||||||
# Physics collision particles.
|
# Physics collision particles.
|
||||||
if msg.hit_type == 'impact':
|
if msg.hit_type == 'impact':
|
||||||
assert msg.force_direction is not None
|
assert msg.force_direction is not None
|
||||||
ba.emitfx(position=msg.pos,
|
bs.emitfx(position=msg.pos,
|
||||||
velocity=(msg.force_direction[0] * 2.0,
|
velocity=(msg.force_direction[0] * 2.0,
|
||||||
msg.force_direction[1] * 2.0,
|
msg.force_direction[1] * 2.0,
|
||||||
msg.force_direction[2] * 2.0),
|
msg.force_direction[2] * 2.0),
|
||||||
|
|
@ -435,9 +437,9 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
|
|
||||||
# Let's get all collision data if we can. Otherwise cancel.
|
# Let's get all collision data if we can. Otherwise cancel.
|
||||||
try:
|
try:
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
opposingnode = collision.opposingnode
|
opposingnode = collision.opposingnode
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Our grabber needs to be a Spaz
|
# Our grabber needs to be a Spaz
|
||||||
|
|
@ -447,9 +449,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# It's the same sound and flashing behavior as hitting a stunned player as a healthy player.
|
# It's the same sound and flashing behavior as hitting a stunned player as a healthy player.
|
||||||
if (opposingnode.source_player.state == PlayerState.STUNNED and self.source_player.state != PlayerState.MARKED):
|
if (opposingnode.source_player.state == PlayerState.STUNNED and self.source_player.state != PlayerState.MARKED):
|
||||||
opposingnode.handlemessage('flash')
|
opposingnode.handlemessage('flash')
|
||||||
ba.playsound(SpazFactory.get().block_sound,
|
SpazFactory.get().block_sound.play(1.0, position=opposingnode.position)
|
||||||
1.0,
|
|
||||||
position=opposingnode.position)
|
|
||||||
return True
|
return True
|
||||||
# If they're marked and we're healthy or stunned, pass that mark along to us.
|
# If they're marked and we're healthy or stunned, pass that mark along to us.
|
||||||
elif opposingnode.source_player.state in [PlayerState.REGULAR, PlayerState.STUNNED] and self.source_player.state == PlayerState.MARKED:
|
elif opposingnode.source_player.state in [PlayerState.REGULAR, PlayerState.STUNNED] and self.source_player.state == PlayerState.MARKED:
|
||||||
|
|
@ -458,10 +458,10 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# Our work is done. Continue with the rest of the grabbing behavior as usual.
|
# Our work is done. Continue with the rest of the grabbing behavior as usual.
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
# Dying is important in this gamemode and as such we need to address this behavior.
|
# Dying is important in this gamemode and as such we need to address this behavior.
|
||||||
elif isinstance(msg, ba.DieMessage):
|
elif isinstance(msg, bs.DieMessage):
|
||||||
|
|
||||||
# If a player left the game, inform our gamemode logic.
|
# If a player left the game, inform our gamemode logic.
|
||||||
if msg.how == ba.DeathType.LEFT_GAME:
|
if msg.how == bs.DeathType.LEFT_GAME:
|
||||||
self.activity.player_left(self.source_player)
|
self.activity.player_left(self.source_player)
|
||||||
|
|
||||||
# If a MARKED or STUNNED player dies, hide the text from the previous spaz.
|
# If a MARKED or STUNNED player dies, hide the text from the previous spaz.
|
||||||
|
|
@ -470,7 +470,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
self.marked_timer_text.color[1],
|
self.marked_timer_text.color[1],
|
||||||
self.marked_timer_text.color[2],
|
self.marked_timer_text.color[2],
|
||||||
0.0)
|
0.0)
|
||||||
ba.animate(self.marked_light, 'intensity', {
|
bs.animate(self.marked_light, 'intensity', {
|
||||||
0: self.marked_light.intensity,
|
0: self.marked_light.intensity,
|
||||||
0.5: 0.0})
|
0.5: 0.0})
|
||||||
|
|
||||||
|
|
@ -483,7 +483,7 @@ class PotatoPlayerSpaz(PlayerSpaz):
|
||||||
# A concept of a player is very useful to reference if we don't have a player character present (maybe they died).
|
# A concept of a player is very useful to reference if we don't have a player character present (maybe they died).
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -535,8 +535,8 @@ class Player(ba.Player['Team']):
|
||||||
|
|
||||||
self.stunned_time_remaining = stun_time # Set our stun time remaining
|
self.stunned_time_remaining = stun_time # Set our stun time remaining
|
||||||
# Remove our stun once the time is up
|
# Remove our stun once the time is up
|
||||||
self.stunned_timer = ba.Timer(stun_time + 0.1, ba.Call(self.stun_remove))
|
self.stunned_timer = bs.Timer(stun_time + 0.1, babase.Call(self.stun_remove))
|
||||||
self.stunned_update_timer = ba.Timer(0.1, ba.Call(
|
self.stunned_update_timer = bs.Timer(0.1, babase.Call(
|
||||||
self.stunned_timer_tick), repeat=True) # Call a function every 0.1 seconds
|
self.stunned_timer_tick), repeat=True) # Call a function every 0.1 seconds
|
||||||
self.fall_times += 1 # Increase the amount of times we fell by one
|
self.fall_times += 1 # Increase the amount of times we fell by one
|
||||||
# Change the text above the Spaz's head to total stun time
|
# Change the text above the Spaz's head to total stun time
|
||||||
|
|
@ -579,8 +579,8 @@ class Player(ba.Player['Team']):
|
||||||
self.icon.set_marked_icon(state) # Update our icon
|
self.icon.set_marked_icon(state) # Update our icon
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
class HotPotato(bs.TeamGameActivity[Player, bs.Team]):
|
||||||
|
|
||||||
# Let's define the basics like the name of the game, description and some tips that should appear at the start of a match.
|
# Let's define the basics like the name of the game, description and some tips that should appear at the start of a match.
|
||||||
name = 'Hot Potato'
|
name = 'Hot Potato'
|
||||||
|
|
@ -604,8 +604,8 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
|
|
||||||
# We're gonna distribute end of match session scores based on who dies first and who survives.
|
# We're gonna distribute end of match session scores based on who dies first and who survives.
|
||||||
# First place gets most points, then second, then third.
|
# First place gets most points, then second, then third.
|
||||||
scoreconfig = ba.ScoreConfig(label='Place',
|
scoreconfig = bs.ScoreConfig(label='Place',
|
||||||
scoretype=ba.ScoreType.POINTS,
|
scoretype=bs.ScoreType.POINTS,
|
||||||
lower_is_better=True)
|
lower_is_better=True)
|
||||||
|
|
||||||
# These variables are self explanatory too.
|
# These variables are self explanatory too.
|
||||||
|
|
@ -614,25 +614,25 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
|
|
||||||
# Let's define some settings the user can mess around with to fit their needs.
|
# Let's define some settings the user can mess around with to fit their needs.
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.IntSetting('Elimination Timer',
|
bs.IntSetting('Elimination Timer',
|
||||||
min_value=5,
|
min_value=5,
|
||||||
default=15,
|
default=15,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Marked Players use Impact Bombs', default=False),
|
bs.BoolSetting('Marked Players use Impact Bombs', default=False),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Hot Potato is strictly a Free-For-All gamemode, so only picking the gamemode in FFA playlists.
|
# Hot Potato is strictly a Free-For-All gamemode, so only picking the gamemode in FFA playlists.
|
||||||
@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.FreeForAllSession)
|
return issubclass(sessiontype, bs.FreeForAllSession)
|
||||||
|
|
||||||
# Most maps should work in Hot Potato. Generally maps marked as 'melee' are the most versatile map types of them all.
|
# Most maps should work in Hot Potato. Generally maps marked as 'melee' are the most versatile map types of them all.
|
||||||
# As the name implies, fisticuffs are common forms of engagement.
|
# As the name implies, fisticuffs are common forms of engagement.
|
||||||
@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')
|
||||||
|
|
||||||
# Here we define everything the gamemode needs, like sounds and settings.
|
# Here we define everything the gamemode needs, like sounds and settings.
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
|
|
@ -640,22 +640,22 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
|
|
||||||
# Let's define all of the sounds we need.
|
# Let's define all of the sounds we need.
|
||||||
self._tick_sound = ba.getsound('tick')
|
self._tick_sound = bui.getsound('tick')
|
||||||
self._player_eliminated_sound = ba.getsound('playerDeath')
|
self._player_eliminated_sound = bui.getsound('playerDeath')
|
||||||
# These next sounds are arrays instead of single sounds.
|
# These next sounds are arrays instead of single sounds.
|
||||||
# We'll use that fact later.
|
# We'll use that fact later.
|
||||||
self._danger_tick_sounds = [ba.getsound('orchestraHit'),
|
self._danger_tick_sounds = [bui.getsound('orchestraHit'),
|
||||||
ba.getsound('orchestraHit2'),
|
bui.getsound('orchestraHit2'),
|
||||||
ba.getsound('orchestraHit3')]
|
bui.getsound('orchestraHit3')]
|
||||||
self._marked_sounds = [ba.getsound('powerdown01'),
|
self._marked_sounds = [bui.getsound('powerdown01'),
|
||||||
ba.getsound('activateBeep'),
|
bui.getsound('activateBeep'),
|
||||||
ba.getsound('hiss')]
|
bui.getsound('hiss')]
|
||||||
|
|
||||||
# Normally play KOTH music, but switch to Epic music if we're in slow motion.
|
# Normally play KOTH music, but switch to Epic music if we're in slow motion.
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
self.slow_motion = self._epic_mode
|
self.slow_motion = self._epic_mode
|
||||||
self.default_music = (ba.MusicType.EPIC if self._epic_mode else
|
self.default_music = (bs.MusicType.EPIC if self._epic_mode else
|
||||||
ba.MusicType.SCARY)
|
bs.MusicType.SCARY)
|
||||||
|
|
||||||
# This description appears below the title card after it comes crashing when the game begins.
|
# This description appears below the title card after it comes crashing when the game begins.
|
||||||
def get_instance_description(self) -> str | Sequence:
|
def get_instance_description(self) -> str | Sequence:
|
||||||
|
|
@ -680,7 +680,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# Returns every single marked player.
|
# Returns every single marked player.
|
||||||
# This piece of info is used excensively in this gamemode, so it's advantageous to have a function to cut on
|
# This piece of info is used excensively in this gamemode, so it's advantageous to have a function to cut on
|
||||||
# work and make the gamemode easier to maintain
|
# work and make the gamemode easier to maintain
|
||||||
def get_marked_players(self) -> Sequence[ba.Player]:
|
def get_marked_players(self) -> Sequence[bs.Player]:
|
||||||
marked_players = []
|
marked_players = []
|
||||||
for p in self.players:
|
for p in self.players:
|
||||||
if p.state == PlayerState.MARKED:
|
if p.state == PlayerState.MARKED:
|
||||||
|
|
@ -691,7 +691,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
def mark(self, target: Player) -> None:
|
def mark(self, target: Player) -> None:
|
||||||
target.set_state(PlayerState.MARKED)
|
target.set_state(PlayerState.MARKED)
|
||||||
|
|
||||||
ba.emitfx(position=target.actor.node.position,
|
bs.emitfx(position=target.actor.node.position,
|
||||||
velocity=target.actor.node.velocity,
|
velocity=target.actor.node.velocity,
|
||||||
chunk_type='spark',
|
chunk_type='spark',
|
||||||
count=int(20.0+random.random()*20),
|
count=int(20.0+random.random()*20),
|
||||||
|
|
@ -738,7 +738,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
sound_volume = 1.0 / marked_player_amount
|
sound_volume = 1.0 / marked_player_amount
|
||||||
|
|
||||||
for target in marked_players:
|
for target in marked_players:
|
||||||
ba.playsound(self._tick_sound, sound_volume, target.actor.node.position)
|
self._tick_sound.play(sound_volume, target.actor.node.position)
|
||||||
target.actor.marked_timer_text.text = str(self.elimination_timer_display)
|
target.actor.marked_timer_text.text = str(self.elimination_timer_display)
|
||||||
|
|
||||||
# When counting down 3, 2, 1 play some dramatic sounds
|
# When counting down 3, 2, 1 play some dramatic sounds
|
||||||
|
|
@ -746,7 +746,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# We store our dramatic sounds in an array, so we target a specific element on the array
|
# We store our dramatic sounds in an array, so we target a specific element on the array
|
||||||
# depending on time remaining. Arrays start at index 0, so we need to decrease
|
# depending on time remaining. Arrays start at index 0, so we need to decrease
|
||||||
# our variable by 1 to get the element index.
|
# our variable by 1 to get the element index.
|
||||||
ba.playsound(self._danger_tick_sounds[self.elimination_timer_display - 1], 1.5)
|
self._danger_tick_sounds[self.elimination_timer_display - 1].play(1.5)
|
||||||
else:
|
else:
|
||||||
# Elimination timer is up! Let's eliminate all marked players.
|
# Elimination timer is up! Let's eliminate all marked players.
|
||||||
self.elimination_timer_display -= 1 # Decrease our timer by one second.
|
self.elimination_timer_display -= 1 # Decrease our timer by one second.
|
||||||
|
|
@ -763,18 +763,18 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
velocity=target.actor.node.velocity,
|
velocity=target.actor.node.velocity,
|
||||||
blast_radius=3.0,
|
blast_radius=3.0,
|
||||||
source_player=target).autoretain()
|
source_player=target).autoretain()
|
||||||
ba.emitfx(position=target.actor.node.position,
|
bs.emitfx(position=target.actor.node.position,
|
||||||
velocity=target.actor.node.velocity,
|
velocity=target.actor.node.velocity,
|
||||||
count=int(16.0+random.random()*60),
|
count=int(16.0+random.random()*60),
|
||||||
scale=1.5,
|
scale=1.5,
|
||||||
spread=2,
|
spread=2,
|
||||||
chunk_type='spark')
|
chunk_type='spark')
|
||||||
target.actor.handlemessage(ba.DieMessage(how='marked_elimination'))
|
target.actor.handlemessage(bs.DieMessage(how='marked_elimination'))
|
||||||
target.actor.shatter(extreme=True)
|
target.actor.shatter(extreme=True)
|
||||||
|
|
||||||
self.match_placement.append(target.team)
|
self.match_placement.append(target.team)
|
||||||
|
|
||||||
ba.playsound(self._player_eliminated_sound, 1.0)
|
self._player_eliminated_sound.play(1.0)
|
||||||
|
|
||||||
# Let the gamemode know a Marked
|
# Let the gamemode know a Marked
|
||||||
self.marked_players_died()
|
self.marked_players_died()
|
||||||
|
|
@ -788,13 +788,13 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# Let's add our lone survivor to the match placement list.
|
# Let's add our lone survivor to the match placement list.
|
||||||
self.match_placement.append(alive_players[0].team)
|
self.match_placement.append(alive_players[0].team)
|
||||||
# Wait a while to let this sink in before we announce our victor.
|
# Wait a while to let this sink in before we announce our victor.
|
||||||
self._end_game_timer = ba.Timer(1.25, ba.Call(self.end_game))
|
self._end_game_timer = bs.Timer(1.25, babase.Call(self.end_game))
|
||||||
else:
|
else:
|
||||||
# There's still players remaining, so let's wait a while before marking a new player.
|
# There's still players remaining, so let's wait a while before marking a new player.
|
||||||
self.new_mark_timer = ba.Timer(2.0 if self.slow_motion else 4.0, ba.Call(self.new_mark))
|
self.new_mark_timer = bs.Timer(2.0 if self.slow_motion else 4.0, babase.Call(self.new_mark))
|
||||||
|
|
||||||
# Another extensively used function that returns all alive players.
|
# Another extensively used function that returns all alive players.
|
||||||
def get_alive_players(self) -> Sequence[ba.Player]:
|
def get_alive_players(self) -> Sequence[bs.Player]:
|
||||||
alive_players = []
|
alive_players = []
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
if player.state == PlayerState.ELIMINATED:
|
if player.state == PlayerState.ELIMINATED:
|
||||||
|
|
@ -829,14 +829,14 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# Set time until marked players explode
|
# Set time until marked players explode
|
||||||
self.elimination_timer_display = self.settings['Elimination Timer']
|
self.elimination_timer_display = self.settings['Elimination Timer']
|
||||||
# Set a timer that calls _eliminate_tick every second
|
# Set a timer that calls _eliminate_tick every second
|
||||||
self.marked_tick_timer = ba.Timer(1.0, ba.Call(self._eliminate_tick), repeat=True)
|
self.marked_tick_timer = bs.Timer(1.0, babase.Call(self._eliminate_tick), repeat=True)
|
||||||
# Mark all chosen victims and play a sound
|
# Mark all chosen victims and play a sound
|
||||||
for new_victim in all_victims:
|
for new_victim in all_victims:
|
||||||
# _marked_sounds is an array.
|
# _marked_sounds is an array.
|
||||||
# To make a nice marked sound effect, I play multiple sounds at once
|
# To make a nice marked sound effect, I play multiple sounds at once
|
||||||
# All of them are contained in the array.
|
# All of them are contained in the array.
|
||||||
for sound in self._marked_sounds:
|
for sound in self._marked_sounds:
|
||||||
ba.playsound(sound, 1.0, new_victim.actor.node.position)
|
sound.play(1.0, new_victim.actor.node.position)
|
||||||
self.mark(new_victim)
|
self.mark(new_victim)
|
||||||
|
|
||||||
# This function is called when the gamemode first loads.
|
# This function is called when the gamemode first loads.
|
||||||
|
|
@ -849,10 +849,10 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# End the game if there's only one player
|
# End the game if there's only one player
|
||||||
if len(self.players) < 2:
|
if len(self.players) < 2:
|
||||||
self.match_placement.append(self.players[0].team)
|
self.match_placement.append(self.players[0].team)
|
||||||
self._round_end_timer = ba.Timer(0.5, self.end_game)
|
self._round_end_timer = bs.Timer(0.5, self.end_game)
|
||||||
else:
|
else:
|
||||||
# Pick random player(s) to get marked
|
# Pick random player(s) to get marked
|
||||||
self.new_mark_timer = ba.Timer(2.0 if self.slow_motion else 5.2, ba.Call(self.new_mark))
|
self.new_mark_timer = bs.Timer(2.0 if self.slow_motion else 5.2, babase.Call(self.new_mark))
|
||||||
|
|
||||||
self._update_icons() # Create player state icons
|
self._update_icons() # Create player state icons
|
||||||
|
|
||||||
|
|
@ -873,17 +873,17 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# I'm gonna modify this function to move the tip text above the icons.
|
# I'm gonna modify this function to move the tip text above the icons.
|
||||||
def _show_tip(self) -> None:
|
def _show_tip(self) -> None:
|
||||||
|
|
||||||
from ba._gameutils import animate, GameTip
|
from bascenev1._gameutils import animate, GameTip
|
||||||
from ba._generated.enums import SpecialChar
|
from babase._mgen.enums import SpecialChar
|
||||||
from ba._language import Lstr
|
from babase._language import Lstr
|
||||||
|
|
||||||
# If there's any tips left on the list, display one.
|
# If there's any tips left on the list, display one.
|
||||||
if self.tips:
|
if self.tips:
|
||||||
tip = self.tips.pop(random.randrange(len(self.tips)))
|
tip = self.tips.pop(random.randrange(len(self.tips)))
|
||||||
tip_title = Lstr(value='${A}:',
|
tip_title = Lstr(value='${A}:',
|
||||||
subs=[('${A}', Lstr(resource='tipText'))])
|
subs=[('${A}', Lstr(resource='tipText'))])
|
||||||
icon: ba.Texture | None = None
|
icon: babase.Texture | None = None
|
||||||
sound: ba.Sound | None = None
|
sound: babase.Sound | None = None
|
||||||
if isinstance(tip, GameTip):
|
if isinstance(tip, GameTip):
|
||||||
icon = tip.icon
|
icon = tip.icon
|
||||||
sound = tip.sound
|
sound = tip.sound
|
||||||
|
|
@ -893,15 +893,15 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# Do a few replacements.
|
# Do a few replacements.
|
||||||
tip_lstr = Lstr(translate=('tips', tip),
|
tip_lstr = Lstr(translate=('tips', tip),
|
||||||
subs=[('${PICKUP}',
|
subs=[('${PICKUP}',
|
||||||
ba.charstr(SpecialChar.TOP_BUTTON))])
|
babase.charstr(SpecialChar.TOP_BUTTON))])
|
||||||
base_position = (75, 50)
|
base_position = (75, 50)
|
||||||
tip_scale = 0.8
|
tip_scale = 0.8
|
||||||
tip_title_scale = 1.2
|
tip_title_scale = 1.2
|
||||||
vrmode = ba.app.vr_mode
|
vrmode = babase.app.vr_mode if build_number < 21282 else babase.app.env.vr
|
||||||
|
|
||||||
t_offs = -350.0
|
t_offs = -350.0
|
||||||
height_offs = 100.0
|
height_offs = 100.0
|
||||||
tnode = ba.newnode('text',
|
tnode = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': tip_lstr,
|
'text': tip_lstr,
|
||||||
'scale': tip_scale,
|
'scale': tip_scale,
|
||||||
|
|
@ -917,7 +917,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
})
|
})
|
||||||
t2pos = (base_position[0] + t_offs - (20 if icon is None else 82),
|
t2pos = (base_position[0] + t_offs - (20 if icon is None else 82),
|
||||||
base_position[1] + 2 + height_offs)
|
base_position[1] + 2 + height_offs)
|
||||||
t2node = ba.newnode('text',
|
t2node = bs.newnode('text',
|
||||||
owner=tnode,
|
owner=tnode,
|
||||||
attrs={
|
attrs={
|
||||||
'text': tip_title,
|
'text': tip_title,
|
||||||
|
|
@ -933,7 +933,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
})
|
})
|
||||||
if icon is not None:
|
if icon is not None:
|
||||||
ipos = (base_position[0] + t_offs - 40, base_position[1] + 1 + height_offs)
|
ipos = (base_position[0] + t_offs - 40, base_position[1] + 1 + height_offs)
|
||||||
img = ba.newnode('image',
|
img = bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'texture': icon,
|
'texture': icon,
|
||||||
'position': ipos,
|
'position': ipos,
|
||||||
|
|
@ -945,11 +945,11 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
'attach': 'bottomCenter'
|
'attach': 'bottomCenter'
|
||||||
})
|
})
|
||||||
animate(img, 'opacity', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
|
animate(img, 'opacity', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
|
||||||
ba.timer(5.0, img.delete)
|
bs.timer(5.0, img.delete)
|
||||||
if sound is not None:
|
if sound is not None:
|
||||||
ba.playsound(sound)
|
sound.play()
|
||||||
|
|
||||||
combine = ba.newnode('combine',
|
combine = bs.newnode('combine',
|
||||||
owner=tnode,
|
owner=tnode,
|
||||||
attrs={
|
attrs={
|
||||||
'input0': 1.0,
|
'input0': 1.0,
|
||||||
|
|
@ -960,7 +960,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
combine.connectattr('output', tnode, 'color')
|
combine.connectattr('output', tnode, 'color')
|
||||||
combine.connectattr('output', t2node, 'color')
|
combine.connectattr('output', t2node, 'color')
|
||||||
animate(combine, 'input3', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
|
animate(combine, 'input3', {0: 0, 1.0: 1, 4.0: 1, 5.0: 0})
|
||||||
ba.timer(5.0, tnode.delete)
|
bs.timer(5.0, tnode.delete)
|
||||||
|
|
||||||
# This function is called when a player leaves the game.
|
# This function is called when a player leaves the game.
|
||||||
# This is only called when the player already joined with a character.
|
# This is only called when the player already joined with a character.
|
||||||
|
|
@ -985,7 +985,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
player.set_state(PlayerState.ELIMINATED)
|
player.set_state(PlayerState.ELIMINATED)
|
||||||
|
|
||||||
# This function is called every time a player spawns
|
# This function is called every time a player spawns
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
position = self.map.get_ffa_start_position(self.players)
|
position = self.map.get_ffa_start_position(self.players)
|
||||||
position = (position[0],
|
position = (position[0],
|
||||||
position[1] - 0.3, # Move the spawn a bit lower
|
position[1] - 0.3, # Move the spawn a bit lower
|
||||||
|
|
@ -993,8 +993,8 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
|
|
||||||
name = player.getname()
|
name = player.getname()
|
||||||
|
|
||||||
light_color = ba.normalized_color(player.color)
|
light_color = babase.normalized_color(player.color)
|
||||||
display_color = ba.safecolor(player.color, target_intensity=0.75)
|
display_color = babase.safecolor(player.color, target_intensity=0.75)
|
||||||
|
|
||||||
# Here we actually crate the player character
|
# Here we actually crate the player character
|
||||||
spaz = PotatoPlayerSpaz(color=player.color,
|
spaz = PotatoPlayerSpaz(color=player.color,
|
||||||
|
|
@ -1009,20 +1009,20 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
spaz.connect_controls_to_player()
|
spaz.connect_controls_to_player()
|
||||||
|
|
||||||
# Move to the stand position and add a flash of light
|
# Move to the stand position and add a flash of light
|
||||||
spaz.handlemessage(ba.StandMessage(position, random.uniform(0, 360)))
|
spaz.handlemessage(bs.StandMessage(position, random.uniform(0, 360)))
|
||||||
t = ba.time(ba.TimeType.BASE)
|
t = bs.time()
|
||||||
ba.playsound(self._spawn_sound, 1.0, position=spaz.node.position)
|
self._spawn_sound.play(1.0, position=spaz.node.position)
|
||||||
light = ba.newnode('light', attrs={'color': light_color})
|
light = bs.newnode('light', attrs={'color': light_color})
|
||||||
spaz.node.connectattr('position', light, 'position')
|
spaz.node.connectattr('position', light, 'position')
|
||||||
ba.animate(light, 'intensity', {0: 0,
|
bs.animate(light, 'intensity', {0: 0,
|
||||||
0.25: 1,
|
0.25: 1,
|
||||||
0.5: 0})
|
0.5: 0})
|
||||||
ba.timer(0.5, light.delete)
|
bs.timer(0.5, light.delete)
|
||||||
|
|
||||||
# Game reacts to various events
|
# Game reacts to various events
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
# This is called if the player dies.
|
# This is called if the player dies.
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
|
|
||||||
|
|
@ -1046,7 +1046,7 @@ class HotPotato(ba.TeamGameActivity[Player, ba.Team]):
|
||||||
# Proceed only if the game hasn't ended yet.
|
# Proceed only if the game hasn't ended yet.
|
||||||
if self.has_ended():
|
if self.has_ended():
|
||||||
return
|
return
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
# By this point our match placement list should be filled with all players.
|
# By this point our match placement list should be filled with all players.
|
||||||
# Players that died/left earliest should be the first entries.
|
# Players that died/left earliest should be the first entries.
|
||||||
# We're gonna use array indexes to decide match placements.
|
# We're gonna use array indexes to decide match placements.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
# By itsre3
|
# By itsre3
|
||||||
|
|
@ -6,39 +7,41 @@
|
||||||
# Besides that, enjoy.......!!
|
# Besides that, enjoy.......!!
|
||||||
"""Provides the chosen-one mini-game."""
|
"""Provides the chosen-one 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.flag import Flag
|
import bauiv1 as bui
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
import bascenev1 as bs
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.flag import Flag
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Type, List, Dict, Optional, Sequence, Union
|
from typing import Any, Type, List, Dict, Optional, Sequence, Union
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.chosen_light: Optional[ba.NodeActor] = None
|
self.chosen_light: Optional[bs.NodeActor] = None
|
||||||
|
|
||||||
|
|
||||||
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, time_remaining: int) -> None:
|
def __init__(self, time_remaining: int) -> None:
|
||||||
self.time_remaining = time_remaining
|
self.time_remaining = time_remaining
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
class InvicibleOneGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""
|
"""
|
||||||
Game involving trying to remain the one 'invisible one'
|
Game involving trying to remain the one 'invisible one'
|
||||||
for a set length of time while everyone else tries to
|
for a set length of time while everyone else tries to
|
||||||
|
|
@ -49,15 +52,15 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
description = ('Be the invisible one for a length of time to win.\n'
|
description = ('Be the invisible one for a length of time to win.\n'
|
||||||
'Kill the invisible one to become it.')
|
'Kill the invisible one to become it.')
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Invicible One Time',
|
'Invicible One Time',
|
||||||
min_value=10,
|
min_value=10,
|
||||||
default=30,
|
default=30,
|
||||||
increment=10,
|
increment=10,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Invicible one is lazy', default=True),
|
bs.BoolSetting('Invicible one is lazy', default=True),
|
||||||
ba.BoolSetting('Night mode', default=False),
|
bs.BoolSetting('Night mode', default=False),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -69,7 +72,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -80,35 +83,35 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
scoreconfig = ba.ScoreConfig(label='Time Held')
|
scoreconfig = bs.ScoreConfig(label='Time Held')
|
||||||
|
|
||||||
@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('keep_away')
|
return bs.app.classic.getmaps('keep_away')
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._invicible_one_player: Optional[Player] = None
|
self._invicible_one_player: Optional[Player] = None
|
||||||
self._swipsound = ba.getsound('swip')
|
self._swipsound = bs.getsound('swip')
|
||||||
self._countdownsounds: Dict[int, ba.Sound] = {
|
self._countdownsounds: Dict[int, babase.Sound] = {
|
||||||
10: ba.getsound('announceTen'),
|
10: bs.getsound('announceTen'),
|
||||||
9: ba.getsound('announceNine'),
|
9: bs.getsound('announceNine'),
|
||||||
8: ba.getsound('announceEight'),
|
8: bs.getsound('announceEight'),
|
||||||
7: ba.getsound('announceSeven'),
|
7: bs.getsound('announceSeven'),
|
||||||
6: ba.getsound('announceSix'),
|
6: bs.getsound('announceSix'),
|
||||||
5: ba.getsound('announceFive'),
|
5: bs.getsound('announceFive'),
|
||||||
4: ba.getsound('announceFour'),
|
4: bs.getsound('announceFour'),
|
||||||
3: ba.getsound('announceThree'),
|
3: bs.getsound('announceThree'),
|
||||||
2: ba.getsound('announceTwo'),
|
2: bs.getsound('announceTwo'),
|
||||||
1: ba.getsound('announceOne')
|
1: bs.getsound('announceOne')
|
||||||
}
|
}
|
||||||
self._flag_spawn_pos: Optional[Sequence[float]] = None
|
self._flag_spawn_pos: Optional[Sequence[float]] = None
|
||||||
self._reset_region_material: Optional[ba.Material] = None
|
self._reset_region_material: Optional[bs.Material] = None
|
||||||
self._flag: Optional[Flag] = None
|
self._flag: Optional[Flag] = None
|
||||||
self._reset_region: Optional[ba.Node] = None
|
self._reset_region: Optional[bs.Node] = None
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
self._invicible_one_time = int(settings['Invicible One Time'])
|
self._invicible_one_time = int(settings['Invicible One Time'])
|
||||||
self._time_limit = float(settings['Time Limit'])
|
self._time_limit = float(settings['Time Limit'])
|
||||||
|
|
@ -117,13 +120,13 @@ class InvicibleOneGame(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.CHOSEN_ONE)
|
if self._epic_mode else bs.MusicType.CHOSEN_ONE)
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
return 'Show your invisibility powers.'
|
return 'Show your invisibility powers.'
|
||||||
|
|
||||||
def create_team(self, sessionteam: ba.SessionTeam) -> Team:
|
def create_team(self, sessionteam: bs.SessionTeam) -> Team:
|
||||||
return Team(time_remaining=self._invicible_one_time)
|
return Team(time_remaining=self._invicible_one_time)
|
||||||
|
|
||||||
def on_team_join(self, team: Team) -> None:
|
def on_team_join(self, team: Team) -> None:
|
||||||
|
|
@ -143,13 +146,13 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
Flag.project_stand(self._flag_spawn_pos)
|
Flag.project_stand(self._flag_spawn_pos)
|
||||||
self._set_invicible_one_player(None)
|
self._set_invicible_one_player(None)
|
||||||
if self._night_mode:
|
if self._night_mode:
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.tint = (0.4, 0.4, 0.4)
|
gnode.tint = (0.4, 0.4, 0.4)
|
||||||
|
|
||||||
pos = self._flag_spawn_pos
|
pos = self._flag_spawn_pos
|
||||||
ba.timer(1.0, call=self._tick, repeat=True)
|
bs.timer(1.0, call=self._tick, repeat=True)
|
||||||
|
|
||||||
mat = self._reset_region_material = ba.Material()
|
mat = self._reset_region_material = bs.Material()
|
||||||
mat.add_actions(
|
mat.add_actions(
|
||||||
conditions=(
|
conditions=(
|
||||||
'they_have_material',
|
'they_have_material',
|
||||||
|
|
@ -159,11 +162,11 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('modify_part_collision', 'collide', True),
|
('modify_part_collision', 'collide', True),
|
||||||
('modify_part_collision', 'physical', False),
|
('modify_part_collision', 'physical', False),
|
||||||
('call', 'at_connect',
|
('call', 'at_connect',
|
||||||
ba.WeakCall(self._handle_reset_collide)),
|
bs.WeakCall(self._handle_reset_collide)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
self._reset_region = ba.newnode('region',
|
self._reset_region = bs.newnode('region',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (pos[0], pos[1] + 0.75,
|
'position': (pos[0], pos[1] + 0.75,
|
||||||
pos[2]),
|
pos[2]),
|
||||||
|
|
@ -185,24 +188,24 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Attempt to get a Player controlling a Spaz that we hit.
|
# Attempt to get a Player controlling a Spaz that we hit.
|
||||||
try:
|
try:
|
||||||
player = ba.getcollision().opposingnode.getdelegate(
|
player = bs.getcollision().opposingnode.getdelegate(
|
||||||
PlayerSpaz, True).getplayer(Player, True)
|
PlayerSpaz, True).getplayer(Player, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
|
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
self._set_invicible_one_player(player)
|
self._set_invicible_one_player(player)
|
||||||
|
|
||||||
def _flash_flag_spawn(self) -> None:
|
def _flash_flag_spawn(self) -> None:
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': self._flag_spawn_pos,
|
'position': self._flag_spawn_pos,
|
||||||
'color': (1, 1, 1),
|
'color': (1, 1, 1),
|
||||||
'radius': 0.3,
|
'radius': 0.3,
|
||||||
'height_attenuated': False
|
'height_attenuated': False
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.25: 0.5, 0.5: 0}, loop=True)
|
bs.animate(light, 'intensity', {0: 0, 0.25: 0.5, 0.5: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
def _tick(self) -> None:
|
def _tick(self) -> None:
|
||||||
|
|
||||||
|
|
@ -212,7 +215,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# This shouldn't happen, but just in case.
|
# This shouldn't happen, but just in case.
|
||||||
if not player.is_alive():
|
if not player.is_alive():
|
||||||
ba.print_error('got dead player as chosen one in _tick')
|
babase.print_error('got dead player as chosen one in _tick')
|
||||||
self._set_invicible_one_player(None)
|
self._set_invicible_one_player(None)
|
||||||
else:
|
else:
|
||||||
scoring_team = player.team
|
scoring_team = player.team
|
||||||
|
|
@ -229,9 +232,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# announce numbers we have sounds for
|
# announce numbers we have sounds for
|
||||||
if scoring_team.time_remaining in self._countdownsounds:
|
if scoring_team.time_remaining in self._countdownsounds:
|
||||||
ba.playsound(
|
self._countdownsounds[scoring_team.time_remaining].play()
|
||||||
self._countdownsounds[scoring_team.time_remaining])
|
|
||||||
|
|
||||||
# Winner!
|
# Winner!
|
||||||
if scoring_team.time_remaining <= 0:
|
if scoring_team.time_remaining <= 0:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
@ -242,11 +243,11 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# (Chosen-one player ceasing to exist should
|
# (Chosen-one player ceasing to exist should
|
||||||
# trigger on_player_leave which resets chosen-one)
|
# trigger on_player_leave which resets chosen-one)
|
||||||
if self._invicible_one_player is not None:
|
if self._invicible_one_player is not None:
|
||||||
ba.print_error('got nonexistent player as chosen one in _tick')
|
babase.print_error('got nonexistent player as chosen one in _tick')
|
||||||
self._set_invicible_one_player(None)
|
self._set_invicible_one_player(None)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team,
|
results.set_team_score(team,
|
||||||
self._invicible_one_time - team.time_remaining)
|
self._invicible_one_time - team.time_remaining)
|
||||||
|
|
@ -256,7 +257,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
existing = self._get_invicible_one_player()
|
existing = self._get_invicible_one_player()
|
||||||
if existing:
|
if existing:
|
||||||
existing.chosen_light = None
|
existing.chosen_light = None
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
if not player:
|
if not player:
|
||||||
assert self._flag_spawn_pos is not None
|
assert self._flag_spawn_pos is not None
|
||||||
self._flag = Flag(color=(1, 0.9, 0.2),
|
self._flag = Flag(color=(1, 0.9, 0.2),
|
||||||
|
|
@ -266,7 +267,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Create a light to highlight the flag;
|
# Create a light to highlight the flag;
|
||||||
# this will go away when the flag dies.
|
# this will go away when the flag dies.
|
||||||
ba.newnode('light',
|
bs.newnode('light',
|
||||||
owner=self._flag.node,
|
owner=self._flag.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': self._flag_spawn_pos,
|
'position': self._flag_spawn_pos,
|
||||||
|
|
@ -287,18 +288,18 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if self._invicible_one_is_lazy:
|
if self._invicible_one_is_lazy:
|
||||||
player.actor.connect_controls_to_player(
|
player.actor.connect_controls_to_player(
|
||||||
enable_punch=False, enable_pickup=False, enable_bomb=False)
|
enable_punch=False, enable_pickup=False, enable_bomb=False)
|
||||||
if player.actor.node.torso_model != None:
|
if player.actor.node.torso_mesh != None:
|
||||||
player.actor.node.color_mask_texture = None
|
player.actor.node.color_mask_texture = None
|
||||||
player.actor.node.color_texture = None
|
player.actor.node.color_texture = None
|
||||||
player.actor.node.head_model = None
|
player.actor.node.head_mesh = None
|
||||||
player.actor.node.torso_model = None
|
player.actor.node.torso_mesh = None
|
||||||
player.actor.node.upper_arm_model = None
|
player.actor.node.upper_arm_mesh = None
|
||||||
player.actor.node.forearm_model = None
|
player.actor.node.forearm_mesh = None
|
||||||
player.actor.node.pelvis_model = None
|
player.actor.node.pelvis_mesh = None
|
||||||
player.actor.node.toes_model = None
|
player.actor.node.toes_mesh = None
|
||||||
player.actor.node.upper_leg_model = None
|
player.actor.node.upper_leg_mesh = None
|
||||||
player.actor.node.lower_leg_model = None
|
player.actor.node.lower_leg_mesh = None
|
||||||
player.actor.node.hand_model = None
|
player.actor.node.hand_mesh = None
|
||||||
player.actor.node.style = 'cyborg'
|
player.actor.node.style = 'cyborg'
|
||||||
invi_sound = []
|
invi_sound = []
|
||||||
player.actor.node.jump_sounds = invi_sound
|
player.actor.node.jump_sounds = invi_sound
|
||||||
|
|
@ -311,7 +312,7 @@ class InvicibleOneGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.actor.node.name = ''
|
player.actor.node.name = ''
|
||||||
|
|
||||||
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)
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
# ba_meta require api 7
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
|
# ba_meta require api 8
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
import ba
|
import babase
|
||||||
import _ba
|
import bauiv1 as bui
|
||||||
|
import bascenev1 as bs
|
||||||
|
import _babase
|
||||||
import random
|
import random
|
||||||
from bastd.actor.spaz import Spaz
|
from bascenev1lib.actor.spaz import Spaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
|
||||||
|
|
||||||
class Player(ba.Player['Team']):
|
class Player(bs.Player['Team']):
|
||||||
"""Our player type for this game."""
|
"""Our player type for this game."""
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -39,7 +42,7 @@ class ChooseingSpaz(Spaz):
|
||||||
super().__init__(color, highlight, "Spaz", None, True, True, False, False)
|
super().__init__(color, highlight, "Spaz", None, True, True, False, False)
|
||||||
self.last_player_attacked_by = None
|
self.last_player_attacked_by = None
|
||||||
self.stand(pos)
|
self.stand(pos)
|
||||||
self.loc = ba.newnode(
|
self.loc = bs.newnode(
|
||||||
'locator',
|
'locator',
|
||||||
attrs={
|
attrs={
|
||||||
'shape': 'circleOutline',
|
'shape': 'circleOutline',
|
||||||
|
|
@ -51,37 +54,37 @@ class ChooseingSpaz(Spaz):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.node.connectattr("position", self.loc, "position")
|
self.node.connectattr("position", self.loc, "position")
|
||||||
ba.animate_array(self.loc, "size", 1, keys={0: [0.5,], 1: [2,], 1.5: [0.5]}, loop=True)
|
bs.animate_array(self.loc, "size", 1, keys={0: [0.5,], 1: [2,], 1.5: [0.5]}, loop=True)
|
||||||
|
|
||||||
def handlemessage(self, msg):
|
def handlemessage(self, msg):
|
||||||
if isinstance(msg, ba.FreezeMessage):
|
if isinstance(msg, bs.FreezeMessage):
|
||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(msg, ba.PowerupMessage):
|
if isinstance(msg, bs.PowerupMessage):
|
||||||
if not (msg.poweruptype == "health"):
|
if not (msg.poweruptype == "health"):
|
||||||
return
|
return
|
||||||
|
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
if isinstance(msg, ba.HitMessage):
|
if isinstance(msg, bs.HitMessage):
|
||||||
self.handlemessage(ba.PowerupMessage("health"))
|
self.handlemessage(bs.PowerupMessage("health"))
|
||||||
|
|
||||||
player = msg.get_source_player(Player)
|
player = msg.get_source_player(Player)
|
||||||
if self.is_alive():
|
if self.is_alive():
|
||||||
self.activity.handlemessage(ChooseingSpazHitMessage(player))
|
self.activity.handlemessage(ChooseingSpazHitMessage(player))
|
||||||
self.last_player_attacked_by = player
|
self.last_player_attacked_by = player
|
||||||
|
|
||||||
elif isinstance(msg, ba.DieMessage):
|
elif isinstance(msg, bs.DieMessage):
|
||||||
player = self.last_player_attacked_by
|
player = self.last_player_attacked_by
|
||||||
|
|
||||||
if msg.how.value != ba.DeathType.GENERIC.value:
|
if msg.how.value != bs.DeathType.GENERIC.value:
|
||||||
self._dead = True
|
self._dead = True
|
||||||
self.activity.handlemessage(ChooseingSpazDieMessage(player))
|
self.activity.handlemessage(ChooseingSpazDieMessage(player))
|
||||||
|
|
||||||
self.loc.delete()
|
self.loc.delete()
|
||||||
|
|
||||||
def stand(self, pos=(0, 0, 0), angle=0):
|
def stand(self, pos=(0, 0, 0), angle=0):
|
||||||
self.handlemessage(ba.StandMessage(pos, angle))
|
self.handlemessage(bs.StandMessage(pos, angle))
|
||||||
|
|
||||||
def recolor(self, color, highlight=(1, 1, 1)):
|
def recolor(self, color, highlight=(1, 1, 1)):
|
||||||
self.node.color = color
|
self.node.color = color
|
||||||
|
|
@ -89,14 +92,14 @@ class ChooseingSpaz(Spaz):
|
||||||
self.loc.color = color
|
self.loc.color = color
|
||||||
|
|
||||||
|
|
||||||
class ChooseBilbord(ba.Actor):
|
class ChooseBilbord(bs.Actor):
|
||||||
def __init__(self, player: Player, delay=0.1) -> None:
|
def __init__(self, player: Player, delay=0.1) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
icon = player.get_icon()
|
icon = player.get_icon()
|
||||||
self.scale = 100
|
self.scale = 100
|
||||||
|
|
||||||
self.node = ba.newnode(
|
self.node = bs.newnode(
|
||||||
'image',
|
'image',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
|
|
@ -111,13 +114,13 @@ class ChooseBilbord(ba.Actor):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.name_node = ba.newnode(
|
self.name_node = bs.newnode(
|
||||||
'text',
|
'text',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (60, -185),
|
'position': (60, -185),
|
||||||
'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,
|
||||||
|
|
@ -128,26 +131,26 @@ class ChooseBilbord(ba.Actor):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ba.animate_array(self.node, "scale", keys={
|
bs.animate_array(self.node, "scale", keys={
|
||||||
0 + delay: [0, 0], 0.05 + delay: [self.scale, self.scale]}, size=1)
|
0 + delay: [0, 0], 0.05 + delay: [self.scale, self.scale]}, size=1)
|
||||||
ba.animate(self.name_node, "scale", {0 + delay: 0, 0.07 + delay: 1})
|
bs.animate(self.name_node, "scale", {0 + delay: 0, 0.07 + delay: 1})
|
||||||
|
|
||||||
def handlemessage(self, msg):
|
def handlemessage(self, msg):
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
ba.animate_array(self.node, "scale", keys={0: self.node.scale, 0.05: [0, 0]}, size=1)
|
bs.animate_array(self.node, "scale", keys={0: self.node.scale, 0.05: [0, 0]}, size=1)
|
||||||
ba.animate(self.name_node, "scale", {0: self.name_node.scale, 0.07: 0})
|
bs.animate(self.name_node, "scale", {0: self.name_node.scale, 0.07: 0})
|
||||||
|
|
||||||
def __delete():
|
def __delete():
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
self.name_node.delete()
|
self.name_node.delete()
|
||||||
|
|
||||||
ba.timer(0.2, __delete)
|
bs.timer(0.2, __delete)
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class LastPunchStand(ba.TeamGameActivity[Player, Team]):
|
class LastPunchStand(bs.TeamGameActivity[Player, Team]):
|
||||||
name = "Last Punch Stand"
|
name = "Last Punch Stand"
|
||||||
description = "Last one punchs the choosing spaz wins"
|
description = "Last one punchs the choosing spaz wins"
|
||||||
tips = [
|
tips = [
|
||||||
|
|
@ -156,11 +159,11 @@ class LastPunchStand(ba.TeamGameActivity[Player, Team]):
|
||||||
"evry time you punch the choosing spaz, you will get one point",
|
"evry time you punch the choosing spaz, you will get one point",
|
||||||
]
|
]
|
||||||
|
|
||||||
default_music = ba.MusicType.TO_THE_DEATH
|
default_music = bs.MusicType.TO_THE_DEATH
|
||||||
|
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.FloatSetting("min time limit (in seconds)", 50.0, min_value=30.0),
|
bs.FloatSetting("min time limit (in seconds)", 50.0, min_value=30.0),
|
||||||
ba.FloatSetting("max time limit (in seconds)", 160.0, 60),
|
bs.FloatSetting("max time limit (in seconds)", 160.0, 60),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -203,12 +206,12 @@ class LastPunchStand(ba.TeamGameActivity[Player, Team]):
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
time_limit = random.randint(self._min_timelimit, self._max_timelimit)
|
time_limit = random.randint(self._min_timelimit, self._max_timelimit)
|
||||||
self.spaw_bot()
|
self.spaw_bot()
|
||||||
ba.timer(time_limit, self.times_up)
|
bs.timer(time_limit, self.times_up)
|
||||||
|
|
||||||
self.setup_standard_powerup_drops(False)
|
self.setup_standard_powerup_drops(False)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
if self.choosed_player and (team.id == self.choosed_player.team.id):
|
if self.choosed_player and (team.id == self.choosed_player.team.id):
|
||||||
team.score += 100
|
team.score += 100
|
||||||
|
|
@ -261,7 +264,7 @@ class LastPunchStand(ba.TeamGameActivity[Player, Team]):
|
||||||
self.spaw_bot()
|
self.spaw_bot()
|
||||||
self.change_choosed_player(None)
|
self.change_choosed_player(None)
|
||||||
|
|
||||||
elif isinstance(msg, ba.PlayerDiedMessage):
|
elif isinstance(msg, bs.PlayerDiedMessage):
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
if not (self.has_ended() or self.times_uped):
|
if not (self.has_ended() or self.times_uped):
|
||||||
self.respawn_player(player, 0)
|
self.respawn_player(player, 0)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# ba_meta require api 7
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
|
# 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
|
||||||
|
|
@ -6,15 +7,17 @@ from __future__ import annotations
|
||||||
import random
|
import random
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
from bastd.actor.bomb import Bomb
|
import bauiv1 as bui
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
import bascenev1 as bs
|
||||||
|
from bascenev1lib.actor.bomb import Bomb
|
||||||
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence
|
from typing import Any, Sequence
|
||||||
|
|
||||||
|
|
||||||
lang = ba.app.lang.language
|
lang = bs.app.lang.language
|
||||||
|
|
||||||
if lang == 'Spanish':
|
if lang == 'Spanish':
|
||||||
name = 'Lluvia de Meteoritos v2'
|
name = 'Lluvia de Meteoritos v2'
|
||||||
|
|
@ -48,7 +51,7 @@ else:
|
||||||
random_rain = 'Random Rain'
|
random_rain = 'Random Rain'
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -56,18 +59,18 @@ class Player(ba.Player['Team']):
|
||||||
self.death_time: float | None = None
|
self.death_time: float | None = None
|
||||||
|
|
||||||
|
|
||||||
class Team(ba.Team[Player]):
|
class Team(bs.Team[Player]):
|
||||||
"""Our team type for this game."""
|
"""Our team type for this game."""
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
class MeteorShowerv2Game(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Minigame involving dodging falling bombs."""
|
"""Minigame involving dodging falling bombs."""
|
||||||
|
|
||||||
name = name
|
name = name
|
||||||
description = 'Dodge the falling bombs.'
|
description = 'Dodge the falling bombs.'
|
||||||
scoreconfig = ba.ScoreConfig(
|
scoreconfig = bs.ScoreConfig(
|
||||||
label='Survived', scoretype=ba.ScoreType.MILLISECONDS, version='B'
|
label='Survived', scoretype=bs.ScoreType.MILLISECONDS, version='B'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Print messages when players die (since its meaningful in this game).
|
# Print messages when players die (since its meaningful in this game).
|
||||||
|
|
@ -79,10 +82,10 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_settings(
|
def get_available_settings(
|
||||||
cls, sessiontype: type[ba.Session]
|
cls, sessiontype: type[bs.Session]
|
||||||
) -> list[ba.Setting]:
|
) -> list[babase.Setting]:
|
||||||
settings = [
|
settings = [
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
bomb_type,
|
bomb_type,
|
||||||
choices=[
|
choices=[
|
||||||
('normal', 0),
|
('normal', 0),
|
||||||
|
|
@ -95,22 +98,22 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
# We're currently hard-coded for one map.
|
# We're currently hard-coded for one map.
|
||||||
@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 ['Rampage']
|
return ['Rampage']
|
||||||
|
|
||||||
# We support teams, free-for-all, and co-op sessions.
|
# We support teams, free-for-all, and co-op sessions.
|
||||||
@classmethod
|
@classmethod
|
||||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||||
return (
|
return (
|
||||||
issubclass(sessiontype, ba.DualTeamSession)
|
issubclass(sessiontype, bs.DualTeamSession)
|
||||||
or issubclass(sessiontype, ba.FreeForAllSession)
|
or issubclass(sessiontype, bs.FreeForAllSession)
|
||||||
or issubclass(sessiontype, ba.CoopSession)
|
or issubclass(sessiontype, bs.CoopSession)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
|
|
@ -138,7 +141,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Some base class overrides:
|
# Some base class overrides:
|
||||||
self.default_music = (
|
self.default_music = (
|
||||||
ba.MusicType.EPIC if self._epic_mode else ba.MusicType.SURVIVAL
|
bs.MusicType.EPIC if self._epic_mode else bs.MusicType.SURVIVAL
|
||||||
)
|
)
|
||||||
if self._epic_mode:
|
if self._epic_mode:
|
||||||
self.slow_motion = True
|
self.slow_motion = True
|
||||||
|
|
@ -152,19 +155,19 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
delay = 5.0 if len(self.players) > 2 else 2.5
|
delay = 5.0 if len(self.players) > 2 else 2.5
|
||||||
if self._epic_mode:
|
if self._epic_mode:
|
||||||
delay *= 0.25
|
delay *= 0.25
|
||||||
ba.timer(delay, self._decrement_meteor_time, repeat=True)
|
bs.timer(delay, self._decrement_meteor_time, repeat=True)
|
||||||
|
|
||||||
# Kick off the first wave in a few seconds.
|
# Kick off the first wave in a few seconds.
|
||||||
delay = 3.0
|
delay = 3.0
|
||||||
if self._epic_mode:
|
if self._epic_mode:
|
||||||
delay *= 0.25
|
delay *= 0.25
|
||||||
ba.timer(delay, self._set_meteor_timer)
|
bs.timer(delay, self._set_meteor_timer)
|
||||||
|
|
||||||
self._timer = OnScreenTimer()
|
self._timer = OnScreenTimer()
|
||||||
self._timer.start()
|
self._timer.start()
|
||||||
|
|
||||||
# Check for immediate end (if we've only got 1 player, etc).
|
# Check for immediate end (if we've only got 1 player, etc).
|
||||||
ba.timer(5.0, self._check_end_game)
|
bs.timer(5.0, self._check_end_game)
|
||||||
|
|
||||||
def on_player_leave(self, player: Player) -> None:
|
def on_player_leave(self, player: Player) -> None:
|
||||||
# Augment default behavior.
|
# Augment default behavior.
|
||||||
|
|
@ -174,7 +177,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
self._check_end_game()
|
self._check_end_game()
|
||||||
|
|
||||||
# overriding the default character spawning..
|
# overriding the default character spawning..
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
spaz = self.spawn_player_spaz(player)
|
spaz = self.spawn_player_spaz(player)
|
||||||
|
|
||||||
# Let's reconnect this player's controls to this
|
# Let's reconnect this player's controls to this
|
||||||
|
|
@ -189,12 +192,12 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Various high-level game events come through this method.
|
# Various high-level game events come through this method.
|
||||||
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)
|
||||||
|
|
||||||
curtime = ba.time()
|
curtime = bs.time()
|
||||||
|
|
||||||
# Record the player's moment of death.
|
# Record the player's moment of death.
|
||||||
# assert isinstance(msg.spaz.player
|
# assert isinstance(msg.spaz.player
|
||||||
|
|
@ -204,15 +207,15 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
# (more accurate looking).
|
# (more accurate looking).
|
||||||
# In teams/ffa, allow a one-second fudge-factor so we can
|
# In teams/ffa, allow a one-second fudge-factor so we can
|
||||||
# get more draws if players die basically at the same time.
|
# get more draws if players die basically at the same time.
|
||||||
if isinstance(self.session, ba.CoopSession):
|
if isinstance(self.session, bs.CoopSession):
|
||||||
# Teams will still show up if we check now.. check in
|
# Teams will still show up if we check now.. check in
|
||||||
# the next cycle.
|
# the next cycle.
|
||||||
ba.pushcall(self._check_end_game)
|
babase.pushcall(self._check_end_game)
|
||||||
|
|
||||||
# Also record this for a final setting of the clock.
|
# Also record this for a final setting of the clock.
|
||||||
self._last_player_death_time = curtime
|
self._last_player_death_time = curtime
|
||||||
else:
|
else:
|
||||||
ba.timer(1.0, self._check_end_game)
|
bs.timer(1.0, self._check_end_game)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Default handler:
|
# Default handler:
|
||||||
|
|
@ -229,7 +232,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# In co-op, we go till everyone is dead.. otherwise we go
|
# In co-op, we go till everyone is dead.. otherwise we go
|
||||||
# until one team remains.
|
# until one team remains.
|
||||||
if isinstance(self.session, ba.CoopSession):
|
if isinstance(self.session, bs.CoopSession):
|
||||||
if living_team_count <= 0:
|
if living_team_count <= 0:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
else:
|
else:
|
||||||
|
|
@ -237,7 +240,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
||||||
def _set_meteor_timer(self) -> None:
|
def _set_meteor_timer(self) -> None:
|
||||||
ba.timer(
|
bs.timer(
|
||||||
(1.0 + 0.2 * random.random()) * self._meteor_time,
|
(1.0 + 0.2 * random.random()) * self._meteor_time,
|
||||||
self._drop_bomb_cluster,
|
self._drop_bomb_cluster,
|
||||||
)
|
)
|
||||||
|
|
@ -248,10 +251,10 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
# and debug things.
|
# and debug things.
|
||||||
loc_test = False
|
loc_test = False
|
||||||
if loc_test:
|
if loc_test:
|
||||||
ba.newnode('locator', attrs={'position': (8, 6, -5.5)})
|
bs.newnode('locator', attrs={'position': (8, 6, -5.5)})
|
||||||
ba.newnode('locator', attrs={'position': (8, 6, -2.3)})
|
bs.newnode('locator', attrs={'position': (8, 6, -2.3)})
|
||||||
ba.newnode('locator', attrs={'position': (-7.3, 6, -5.5)})
|
bs.newnode('locator', attrs={'position': (-7.3, 6, -5.5)})
|
||||||
ba.newnode('locator', attrs={'position': (-7.3, 6, -2.3)})
|
bs.newnode('locator', attrs={'position': (-7.3, 6, -2.3)})
|
||||||
|
|
||||||
# Drop several bombs in series.
|
# Drop several bombs in series.
|
||||||
delay = 0.0
|
delay = 0.0
|
||||||
|
|
@ -269,7 +272,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
random.uniform(-3.066, -4.12),
|
random.uniform(-3.066, -4.12),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
ba.timer(delay, ba.Call(self._drop_bomb, pos, vel))
|
bs.timer(delay, babase.Call(self._drop_bomb, pos, vel))
|
||||||
delay += 0.1
|
delay += 0.1
|
||||||
self._set_meteor_timer()
|
self._set_meteor_timer()
|
||||||
|
|
||||||
|
|
@ -294,7 +297,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
self._meteor_time = max(0.01, self._meteor_time * 0.9)
|
self._meteor_time = max(0.01, self._meteor_time * 0.9)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
cur_time = ba.time()
|
cur_time = bs.time()
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
start_time = self._timer.getstarttime()
|
start_time = self._timer.getstarttime()
|
||||||
|
|
||||||
|
|
@ -325,7 +328,7 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Ok now calc game results: set a score for each team and then tell
|
# Ok now calc game results: set a score for each team and then tell
|
||||||
# the game to end.
|
# the game to end.
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
|
|
||||||
# Remember that 'free-for-all' mode is simply a special form
|
# Remember that 'free-for-all' mode is simply a special form
|
||||||
# of 'teams' mode where each player gets their own team, so we can
|
# of 'teams' mode where each player gets their own team, so we can
|
||||||
|
|
@ -346,58 +349,58 @@ class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export plugin
|
# ba_meta export plugin
|
||||||
class MeteorShowerv2Coop(ba.Plugin):
|
class MeteorShowerv2Coop(babase.Plugin):
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
normal_rain,
|
normal_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 0},
|
settings={bomb_type: 0},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
frozen_rain,
|
frozen_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 1},
|
settings={bomb_type: 1},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
sticky_rain,
|
sticky_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 2},
|
settings={bomb_type: 2},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
impact_rain,
|
impact_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 3},
|
settings={bomb_type: 3},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
mine_rain,
|
mine_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 4},
|
settings={bomb_type: 4},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
tnt_rain,
|
tnt_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 5},
|
settings={bomb_type: 5},
|
||||||
preview_texture_name='rampagePreview',
|
preview_texture_name='rampagePreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
random_rain,
|
random_rain,
|
||||||
gametype=MeteorShowerv2Game,
|
gametype=MeteorShowerv2Game,
|
||||||
settings={bomb_type: 6},
|
settings={bomb_type: 6},
|
||||||
|
|
|
||||||
441
plugins/minigames/port_7_to_8.py
Normal file
441
plugins/minigames/port_7_to_8.py
Normal file
|
|
@ -0,0 +1,441 @@
|
||||||
|
# Usage: port_7_to_8.py <client/server type of mod> <plugin-name>
|
||||||
|
|
||||||
|
# You'll have to manually update the following:
|
||||||
|
# with ba.Context(_ba.foreground_host_activity()):
|
||||||
|
# To:
|
||||||
|
# with _ba.foreground_host_activity().context:
|
||||||
|
#
|
||||||
|
# ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
|
||||||
|
# To:
|
||||||
|
# ba.time() * 1000
|
||||||
|
#
|
||||||
|
# ba.Timer((POWERUP_WEAR_OFF_TIME - 2000),ba.WeakCall(self._multi_bomb_wear_off_flash),timeformat=ba.TimeFormat.MILLISECONDS)
|
||||||
|
# To:
|
||||||
|
# ba.Timer((POWERUP_WEAR_OFF_TIME - 2000 / 1000),ba.WeakCall(self._multi_bomb_wear_off_flash))
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import codecs
|
||||||
|
|
||||||
|
def detect_encoding(filename):
|
||||||
|
encodings = ['utf-8', 'latin-1', 'ascii', 'cp1252']
|
||||||
|
for encoding in encodings:
|
||||||
|
try:
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
f.read().decode(encoding)
|
||||||
|
return encoding
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
filename = sys.argv[2]
|
||||||
|
encoding = detect_encoding(filename)
|
||||||
|
if encoding:
|
||||||
|
with open(filename, 'r', encoding=encoding) as f:
|
||||||
|
print("Porting "+ sys.argv[2])
|
||||||
|
content = f.read()
|
||||||
|
else:
|
||||||
|
print('Could not detect encoding')
|
||||||
|
|
||||||
|
content = content.replace("# ba_meta require api 7", "# ba_meta require api 8")
|
||||||
|
content = content.replace("# ba_meta export game", "# ba_meta export bascenev1.GameActivity")
|
||||||
|
|
||||||
|
|
||||||
|
content = content.replace("user_agent_string", "legacy_user_agent_string")
|
||||||
|
content = re.sub(r'^(import\s+[\w]+(\s*,\s*[\w]+)+)', lambda match: re.sub(r'\s*,\s*', '\nimport ', match.group()), content, flags=re.MULTILINE)
|
||||||
|
content = content.replace("_ba.", "_babase.")
|
||||||
|
content = content.replace("_ba.", "_babase.")
|
||||||
|
content = content.replace("ba.", "babase.")
|
||||||
|
content = content.replace("import _ba", "import _babase")
|
||||||
|
content = content.replace("from ba import", "from babase import")
|
||||||
|
content = content.replace("from _ba import", "from _babase import")
|
||||||
|
content = re.sub(r'\bimport _ba\b', "import _babase", content)
|
||||||
|
content = re.sub(r'\bimport ba(\b|\.(\w+))', "import babase\nimport bauiv1\nimport bascenev1", content)
|
||||||
|
match = re.search(r'^(import\s+[\w]+(\s*,\s*[\w]+)*)', content, flags=re.MULTILINE)
|
||||||
|
affected_methods = ["build_number", "device_name", "config_file_path", "version", "debug_build", "test_build", "data_directory", "python_directory_user", "python_directory_app", "python_directory_app_site", "api_version", "on_tv", "vr_mode","toolbar_test", "arcade_test", "headless_mode", "demo_mode", "protocol_version", "get_connection_to_host_info"]
|
||||||
|
for word in affected_methods:
|
||||||
|
if f".{word}" in content:
|
||||||
|
first_import_index = match.start()
|
||||||
|
content = content[:first_import_index] + 'from baenv import TARGET_BALLISTICA_BUILD as build_number\n' + content[first_import_index:]
|
||||||
|
content = content.replace("babase.app.ui", "bauiv1.app.ui_v1")
|
||||||
|
content = content.replace("babase.app.accounts_v1", "bauiv1.app.classic.accounts")
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
# Comment out one of these as per your requirements, depending whether to
|
||||||
|
# stay local or if it'll also be needed to transmitted to the clients.
|
||||||
|
|
||||||
|
## For local:
|
||||||
|
if sys.argv[1] == "client":
|
||||||
|
content = content.replace("_babase.screenmessage", "bauiv1.screenmessage")
|
||||||
|
content = content.replace("babase.screenmessage", "bauiv1.screenmessage")
|
||||||
|
content = content.replace("babase.getsound", "bauiv1.getsound")
|
||||||
|
content = content.replace("_babase.gettexture", "bauiv1.gettexture")
|
||||||
|
content = content.replace("babase.gettexture", "bauiv1.gettexture")
|
||||||
|
content = content.replace("babase.getmesh", "bauiv1.getmesh")
|
||||||
|
content = content.replace("babase.getcollisionmesh", "bauiv1.getcollisionmesh")
|
||||||
|
else:
|
||||||
|
## For transmission:
|
||||||
|
content = content.replace("_babase.screenmessage", "bascenev1.broadcastmessage")
|
||||||
|
content = content.replace("babase.screenmessage", "bascenev1.broadcastmessage")
|
||||||
|
content = content.replace("babase.getsound", "bascenev1.getsound")
|
||||||
|
content = content.replace("_babase.gettexture", "bascenev1.gettexture")
|
||||||
|
content = content.replace("babase.gettexture", "bascenev1.gettexture")
|
||||||
|
content = content.replace("babase.getmesh", "bascenev1.getmesh")
|
||||||
|
content = content.replace("babase.getcollisionmesh", "bascenev1.getcollisionmesh")
|
||||||
|
###################################################################################
|
||||||
|
content = content.replace("babase.getcollidemesh", "bascenev1.getcollisionmesh")
|
||||||
|
content = content.replace("collide_mesh", "collision_mesh")
|
||||||
|
content = content.replace("babase.open_url", "bauiv1.open_url")
|
||||||
|
content = content.replace("babase.IntSetting", "bascenev1.IntSetting")
|
||||||
|
content = content.replace("babase.IntChoiceSetting", "bascenev1.IntChoiceSetting")
|
||||||
|
content = content.replace("babase.FloatChoiceSetting", "bascenev1.FloatChoiceSetting")
|
||||||
|
content = content.replace("babase.BoolSetting", "bascenev1.BoolSetting")
|
||||||
|
content = content.replace("babase.Actor", "bascenev1.Actor")
|
||||||
|
content = content.replace("babase.Player", "bascenev1.Player")
|
||||||
|
content = content.replace("babase.PlayerDiedMessage", "bascenev1.PlayerDiedMessage")
|
||||||
|
content = content.replace("babase.time", "bascenev1.time")
|
||||||
|
content = content.replace("babase.Timer", "bascenev1.Timer")
|
||||||
|
content = content.replace("babase.newnode", "bascenev1.newnode")
|
||||||
|
content = content.replace("babase.Node", "bascenev1.Node")
|
||||||
|
content = content.replace("babase.emitfx", "bascenev1.emitfx")
|
||||||
|
content = content.replace("babase.animate", "bascenev1.animate")
|
||||||
|
content = content.replace("babase.FreeForAllSession", "bascenev1.FreeForAllSession")
|
||||||
|
content = content.replace("babase.DualTeamSession", "bascenev1.DualTeamSession")
|
||||||
|
content = content.replace("babase.MultiTeamSession", "bascenev1.MultiTeamSession")
|
||||||
|
content = content.replace("babase.EndSession", "bascenev1.EndSession")
|
||||||
|
content = content.replace("babase.CoopSession", "bascenev1.CoopSession")
|
||||||
|
content = content.replace("babase.TeamGameActivity", "bascenev1.TeamGameActivity")
|
||||||
|
content = content.replace("babase.Team", "bascenev1.Team")
|
||||||
|
content = content.replace("babase.Session", "bascenev1.Session")
|
||||||
|
content = content.replace("babase.getsession", "bascenev1.getsession")
|
||||||
|
content = content.replace("babase.Material", "bascenev1.Material")
|
||||||
|
content = content.replace("babase.WeakCall", "bascenev1.WeakCall")
|
||||||
|
content = content.replace("babase.DieMessage", "bascenev1.DieMessage")
|
||||||
|
content = content.replace("babase.OutOfBoundsMessage", "bascenev1.OutOfBoundsMessage")
|
||||||
|
content = content.replace("babase.DroppedMessage", "bascenev1.DroppedMessage")
|
||||||
|
content = content.replace("babase.HitMessage", "bascenev1.HitMessage")
|
||||||
|
content = content.replace("babase.ThawMessage", "bascenev1.ThawMessage")
|
||||||
|
content = content.replace("babase.NotFoundError", "bascenev1.NotFoundError")
|
||||||
|
content = content.replace("babase.getcollision", "bascenev1.getcollision")
|
||||||
|
content = content.replace("babase.app.lang", "bascenev1.app.lang")
|
||||||
|
content = content.replace("babase.MusicType", "bascenev1.MusicType")
|
||||||
|
content = content.replace("babase.getactivity", "bascenev1.getactivity")
|
||||||
|
content = content.replace("babase.getactivity", "bascenev1.getactivity")
|
||||||
|
content = content.replace("babase.CelebrateMessage", "bascenev1.CelebrateMessage")
|
||||||
|
content = content.replace("babase.ScoreConfig", "bascenev1.ScoreConfig")
|
||||||
|
content = content.replace("babase.ScoreType", "bascenev1.ScoreType")
|
||||||
|
content = content.replace("babase.GameResults", "bascenev1.GameResults")
|
||||||
|
content = content.replace("babase.getmaps", "bascenev1.app.classic.getmaps")
|
||||||
|
content = content.replace("babase.cameraflash", "bascenev1.cameraflash")
|
||||||
|
content = content.replace("babase.getmodel", "bascenev1.getmesh")
|
||||||
|
content = content.replace("babase.Map", "bascenev1.Map")
|
||||||
|
content = content.replace("babase.DeathType", "bascenev1.DeathType")
|
||||||
|
content = content.replace("babase.GameActivity", "bascenev1.GameActivity")
|
||||||
|
content = content.replace("_babase.app.stress_test_reset_timer", "_babase.app.classic.stress_test_reset_timer")
|
||||||
|
content = content.replace("babase.app.stress_test_reset_timer", "_babase.app.classic.stress_test_reset_timer")
|
||||||
|
content = content.replace("babase._map", "bascenev1._map")
|
||||||
|
content = content.replace("babase._session.", "bascenev1._session.")
|
||||||
|
content = content.replace("babase._activity", "bascenev1._activity")
|
||||||
|
content = content.replace("_babase.get_client_public_device_uuid", "_bascenev1.get_client_public_device_uuid")
|
||||||
|
content = content.replace("babase.PickedUpMessage", "bascenev1.PickedUpMessage")
|
||||||
|
content = content.replace("babase.PowerupMessage", "bascenev1.PowerupMessage")
|
||||||
|
content = content.replace("babase.FreezeMessage", "bascenev1.FreezeMessage")
|
||||||
|
content = content.replace("with babase.ContextRef(activity):", "with activity.context:")
|
||||||
|
content = content.replace("babase.Context", "babase.ContextRef")
|
||||||
|
content = content.replace("babase._dualteamsession", "bascenev1._dualteamsession")
|
||||||
|
content = content.replace("babase._freeforallsession", "bascenev1._freeforallsession")
|
||||||
|
content = content.replace("babase._multiteamsession", "bascenev1._multiteamsession")
|
||||||
|
content = content.replace("babase._gameactivity", "bascenev1._gameactivity")
|
||||||
|
content = content.replace("babase._powerup", "bascenev1._powerup")
|
||||||
|
content = content.replace("babase.Chooser", "bascenev1.Chooser")
|
||||||
|
content = content.replace("babase._lobby", "bascenev1._lobby")
|
||||||
|
content = content.replace("babase._stats", "bascenev1._stats")
|
||||||
|
content = content.replace("babase._team", "bascenev1._team")
|
||||||
|
content = content.replace("PlayerType", "PlayerT")
|
||||||
|
content = content.replace("babase.app.spaz_appearances", "babase.app.classic.spaz_appearances")
|
||||||
|
content = content.replace("babase._coopsession", "bascenev1._coopsession")
|
||||||
|
content = content.replace("babase._servermode", "baclassic._servermode")
|
||||||
|
content = content.replace("_babase.app.server", "babase.app.classic.server")
|
||||||
|
content = content.replace("_babase.chatmessage", "bascenev1.chatmessage")
|
||||||
|
content = content.replace("_babase.disconnect_client", "_bascenev1.disconnect_client")
|
||||||
|
content = content.replace("_babase.get_game_roster", "bascenev1.get_game_roster")
|
||||||
|
content = content.replace("_babase.get_public_party_max_size", "bascenev1.get_public_party_max_size")
|
||||||
|
content = content.replace("_babase.new_host_session", "bascenev1.new_host_session")
|
||||||
|
content = content.replace("babase._playlist", "bascenev1._playlist")
|
||||||
|
content = content.replace("model", "mesh")
|
||||||
|
content = content.replace("TimeType.REAL", "use `bascenev1.apptimer` in `activity.context` instead")
|
||||||
|
content = content.replace("_babase.app.coop_session_args", "babase.app.classic.coop_session_args")
|
||||||
|
content = content.replace("_babase.app.campaigns", "babase.app.classic.campaigns")
|
||||||
|
|
||||||
|
content = content.replace("_babase.newactivity", "bascenev1.newactivity")
|
||||||
|
content = content.replace("babase.Window", "bauiv1.Window")
|
||||||
|
content = content.replace("babase.Widget", "bauiv1.Widget")
|
||||||
|
content = content.replace("babase.widget", "bauiv1.widget")
|
||||||
|
content = content.replace("babase.containerwidget", "bauiv1.containerwidget")
|
||||||
|
content = content.replace("babase.scrollwidget", "bauiv1.scrollwidget")
|
||||||
|
content = content.replace("babase.buttonwidget", "bauiv1.buttonwidget")
|
||||||
|
content = content.replace("babase.textwidget", "bauiv1.textwidget")
|
||||||
|
content = content.replace("babase.checkboxwidget", "bauiv1.checkboxwidget")
|
||||||
|
content = content.replace("babase.imagewidget", "bauiv1.imagewidget")
|
||||||
|
content = content.replace("babase.uicleanupcheck", "bauiv1.uicleanupcheck")
|
||||||
|
content = content.replace("_babase.set_public_party_max_size", "bascenev1.set_public_party_max_size")
|
||||||
|
content = content.replace("_bauiv1", "bauiv1")
|
||||||
|
content = content.replace("babase.show_damage_count", "bascenev1.show_damage_count")
|
||||||
|
content = content.replace("babase._gameutils", "bascenev1._gameutils")
|
||||||
|
content = content.replace("babase.StandMessage", "bascenev1.StandMessage")
|
||||||
|
content = content.replace("babase.PowerupAcceptMessage", "bascenev1.PowerupAcceptMessage")
|
||||||
|
content = content.replace("babase._gameutils", "bascenev1._gameutils")
|
||||||
|
content = content.replace("babase.camerashake", "bascenev1.camerashake")
|
||||||
|
content = content.replace("babase.app.add_coop_practice_level", "babase.app.classic.add_coop_practice_level")
|
||||||
|
content = content.replace("babase._campaign", "bascenev1._campaign")
|
||||||
|
content = content.replace("babase.Level", "bascenev1._level.Level")
|
||||||
|
content = content.replace("babase.app.cloud.send_message_cb", "bauiv1.app.plus.cloud.send_message_cb")
|
||||||
|
content = content.replace("_babase.get_special_widget", "bauiv1.get_special_widget")
|
||||||
|
|
||||||
|
content = content.replace(".app.platform", ".app.classic.platform")
|
||||||
|
content = content.replace(".app.subplatform", ".app.classic.subplatform")
|
||||||
|
content = content.replace(".getlog", ".get_v1_cloud_log")
|
||||||
|
# Converting `ba.playsound(abc)` to `abc.play()` is tricky.
|
||||||
|
# Do it manually in case regex substitution fails.# Do it manually in case regex substitution fails. Are you sure!!
|
||||||
|
#! FIXME May cause syntax warning on 3.12
|
||||||
|
content = re.sub(
|
||||||
|
r'babase\.playsound\(\s*([^,\n]+),\s*([^,\n]+)\)',
|
||||||
|
r'\1.play(\2)',
|
||||||
|
content,
|
||||||
|
flags=re.MULTILINE
|
||||||
|
)
|
||||||
|
content = re.sub(
|
||||||
|
r'babase\.playsound\(\s*([^,\n]+),\s*([^,\n]+),\s*position=([^,\n]+)\)',
|
||||||
|
r'\1.play(\2, position=\3)',
|
||||||
|
content,
|
||||||
|
flags=re.MULTILINE
|
||||||
|
)
|
||||||
|
content = re.sub("babase\.playsound\((.+?), (.+?), (.+?)\)", "\\1.play(\\2, \\3)", content)
|
||||||
|
content = re.sub(
|
||||||
|
r'babase\.playsound\(([^,\n]+),\s*position=([^,\n]+)\)',
|
||||||
|
r'\1.play(position=\2)',
|
||||||
|
content
|
||||||
|
)
|
||||||
|
content = re.sub("babase\.playsound\((.*)\)", "\\1.play()", content)
|
||||||
|
|
||||||
|
content = content.replace("babase.internal.add_transaction", "bauiv1.app.plus.add_v1_account_transaction")
|
||||||
|
content = content.replace("babase.internal.run_transaction", "bauiv1.app.plus.run_v1_account_transaction")
|
||||||
|
content = content.replace("_babase.add_transaction", "bauiv1.app.plus.add_v1_account_transaction")
|
||||||
|
content = content.replace("_babase.run_transactions", "bauiv1.app.plus.run_v1_account_transactions")
|
||||||
|
content = content.replace("babase._store.get_store_layout", "bauiv1.app.classic.store.get_store_layout")
|
||||||
|
content = content.replace("babase.internal.get_store_layout", "bauiv1.app.classic.store.get_store_layout")
|
||||||
|
content = content.replace("babase.internal.connect_to_party", "bascenev1.connect_to_party")
|
||||||
|
content = content.replace("babase.internal.get_default_powerup_distribution", "bascenev1._powerup.get_default_powerup_distribution")
|
||||||
|
content = content.replace("babase.internal.DEFAULT_REQUEST_TIMEOUT_SECONDS", "babase.DEFAULT_REQUEST_TIMEOUT_SECONDS")
|
||||||
|
content = content.replace("babase.internal.DEFAULT_TEAM_COLORS", "bascenev1.DEFAULT_TEAM_COLORS")
|
||||||
|
content = content.replace("babase.internal.DEFAULT_TEAM_NAMES", "bascenev1.DEFAULT_TEAM_NAMES")
|
||||||
|
content = content.replace("babase.internal.JoinActivity", "bascenev1.JoinActivity")
|
||||||
|
content = content.replace("babase.internal.LoginAdapter", "babase._login.LoginAdapter")
|
||||||
|
content = content.replace("babase.internal.PlayerProfilesChangedMessage", "bascenev1._messages.PlayerProfilesChangedMessage")
|
||||||
|
content = content.replace("babase.internal.ScoreScreenActivity", "bascenev1.ScoreScreenActivity")
|
||||||
|
content = content.replace("babase.internal.add_clean_frame_callback", "babase.add_clean_frame_callback")
|
||||||
|
content = content.replace("babase.internal.android_get_external_files_dir", "babase.android_get_external_files_dir")
|
||||||
|
content = content.replace("babase.internal.appname", "babase.appname")
|
||||||
|
content = content.replace("babase.internal.appnameupper", "babase.appnameupper")
|
||||||
|
content = content.replace("babase.internal.capture_gamepad_input", "bascenev1.capture_gamepad_input")
|
||||||
|
content = content.replace("babase.internal.capture_keyboard_input", "bascenev1.capture_keyboard_input")
|
||||||
|
content = content.replace("babase.internal.charstr", "babase.charstr")
|
||||||
|
content = content.replace("babase.internal.chatmessage", "bascenev1.chatmessage")
|
||||||
|
content = content.replace("babase.internal.commit_app_config", "bauiv1.commit_app_config")
|
||||||
|
content = content.replace("babase.internal.disconnect_client", "bascenev1.disconnect_client")
|
||||||
|
content = content.replace("babase.internal.disconnect_from_host", "bascenev1.disconnect_from_host")
|
||||||
|
content = content.replace("babase.internal.do_play_music", "babase.app.classic.music.do_play_music")
|
||||||
|
content = content.replace("babase.internal.end_host_scanning", "bascenev1.end_host_scanning")
|
||||||
|
content = content.replace("babase.internal.fade_screen", "bauiv1.fade_screen")
|
||||||
|
content = content.replace("babase.internal.filter_playlist", "bascenev1.filter_playlist")
|
||||||
|
content = content.replace("babase.internal.game_service_has_leaderboard", "_baplus.game_service_has_leaderboard")
|
||||||
|
content = content.replace("babase.internal.get_available_purchase_count", "bauiv1.app.classic.store.get_available_purchase_count")
|
||||||
|
content = content.replace("babase.internal.get_available_sale_time", "bauiv1.app.classic.store.get_available_sale_time")
|
||||||
|
content = content.replace("babase.internal.get_chat_messages", "bascenev1.get_chat_messages")
|
||||||
|
content = content.replace("babase.internal.get_clean_price", "bauiv1.app.classic.store.get_clean_price")
|
||||||
|
content = content.replace("babase.internal.get_connection_to_host_info", "bascenev1.get_connection_to_host_info_2")
|
||||||
|
content = content.replace("babase.internal.get_default_free_for_all_playlist", "bascenev1._playlist.get_default_free_for_all_playlist")
|
||||||
|
content = content.replace("babase.internal.get_default_teams_playlist", "bascenev1._playlist.get_default_teams_playlist")
|
||||||
|
content = content.replace("babase.internal.get_display_resolution", "babase.get_display_resolution")
|
||||||
|
content = content.replace("babase.internal.get_filtered_map_name", "bascenev1._map.get_filtered_map_name")
|
||||||
|
content = content.replace("babase.internal.get_foreground_host_session", "bascenev1.get_foreground_host_session")
|
||||||
|
content = content.replace("babase.internal.get_game_port", "bascenev1.get_game_port")
|
||||||
|
content = content.replace("babase.internal.get_game_roster", "bascenev1.get_game_roster")
|
||||||
|
content = content.replace("babase.internal.get_input_device_config", "bauiv1.app.classic.get_input_device_config")
|
||||||
|
content = content.replace("babase.internal.get_ip_address_type", "babase.get_ip_address_type")
|
||||||
|
content = content.replace("babase.internal.get_local_active_input_devices_count", "bascenev1.get_local_active_input_devices_count")
|
||||||
|
content = content.replace("babase.internal.get_low_level_config_value", "bauiv1.get_low_level_config_value")
|
||||||
|
content = content.replace("babase.internal.get_map_class", "bascenev1.get_map_class")
|
||||||
|
content = content.replace("babase.internal.get_map_display_string", "bascenev1.get_map_display_string")
|
||||||
|
content = content.replace("babase.internal.get_master_server_address", "bauiv1.app.plus.get_master_server_address")
|
||||||
|
content = content.replace("babase.internal.get_max_graphics_quality", "babase.get_max_graphics_quality")
|
||||||
|
content = content.replace("babase.internal.get_news_show", "_babase.app.plus.get_news_show")
|
||||||
|
content = content.replace("babase.internal.get_next_tip", "bascenev1.app.classic.get_next_tip")
|
||||||
|
content = content.replace("babase.internal.get_player_colors", "bascenev1.get_player_colors")
|
||||||
|
content = content.replace("babase.internal.get_player_profile_colors", "bascenev1.get_player_profile_colors")
|
||||||
|
content = content.replace("babase.internal.get_player_profile_icon", "bascenev1.get_player_profile_icon")
|
||||||
|
content = content.replace("babase.internal.get_price", "bauiv1.app.plus.get_price")
|
||||||
|
content = content.replace("babase.internal.get_public_party_enabled", "bascenev1.get_public_party_enabled")
|
||||||
|
content = content.replace("babase.internal.get_public_party_max_size", "bascenev1.get_public_party_max_size")
|
||||||
|
content = content.replace("babase.internal.get_purchased", "bauiv1.app.plus.get_purchased")
|
||||||
|
content = content.replace("babase.internal.get_purchases_state", "_baplus.get_purchases_state")
|
||||||
|
content = content.replace("babase.internal.get_qrcode_texture", "bauiv1.get_qrcode_texture")
|
||||||
|
content = content.replace("babase.internal.get_random_names", "bascenev1.get_random_names")
|
||||||
|
content = content.replace("babase.internal.get_remote_app_name", "bascenev1.get_remote_app_name")
|
||||||
|
content = content.replace("babase.internal.get_replay_speed_exponent", "bascenev1.get_replay_speed_exponent")
|
||||||
|
content = content.replace("babase.internal.get_replays_dir", "babase.get_replays_dir")
|
||||||
|
content = content.replace("babase.internal.get_special_widget", "bauiv1.get_special_widget")
|
||||||
|
content = content.replace("babase.internal.get_store_item", "babase.app.classic.store.get_store_item")
|
||||||
|
content = content.replace("babase.internal.get_store_item_display_size", "babase.app.classic.store.get_store_item_display_size")
|
||||||
|
content = content.replace("babase.internal.get_store_item_name_translated", "babase.app.classic.store.get_store_item_name_translated")
|
||||||
|
content = content.replace("babase.internal.get_string_height", "babase.get_string_height")
|
||||||
|
content = content.replace("babase.internal.get_string_width", "babase.get_string_width")
|
||||||
|
content = content.replace("babase.internal.get_tournament_prize_strings", "bascenev1.app.classic.get_tournament_prize_strings")
|
||||||
|
content = content.replace("babase.internal.get_trophy_string", "bascenev1.get_trophy_string")
|
||||||
|
content = content.replace("babase.internal.get_type_name", "babase.get_type_name")
|
||||||
|
content = content.replace("babase.internal.get_ui_input_device", "bascenev1.get_ui_input_device")
|
||||||
|
content = content.replace("babase.internal.get_unowned_game_types", "babase.app.classic.store.get_unowned_game_types")
|
||||||
|
content = content.replace("babase.internal.get_unowned_maps", "babase.app.classic.store.get_unowned_maps")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_display_string", "bauiv1.app.plus.get_v1_account_display_string")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_misc_read_val", "bauiv1.app.plus.get_v1_account_misc_read_val")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_misc_read_val_2", "bauiv1.app.plus.get_v1_account_misc_read_val_2")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_misc_val", "bauiv1.app.plus.get_v1_account_misc_val")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_name", "bauiv1.app.plus.get_v1_account_name")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_state", "bauiv1.app.plus.get_v1_account_state")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_state_num", "bauiv1.app.plus.get_v1_account_state_num")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_ticket_count", "bauiv1.app.plus.get_v1_account_ticket_count")
|
||||||
|
content = content.replace("babase.internal.get_v1_account_type", "bauiv1.app.plus.get_v1_account_type")
|
||||||
|
content = content.replace("babase.internal.get_v2_fleet", "_baplus.get_v2_fleet")
|
||||||
|
content = content.replace("babase.internal.getcampaign", "bauiv1.app.classic.getcampaign")
|
||||||
|
content = content.replace("babase.internal.getclass", "babase.getclass")
|
||||||
|
content = content.replace("babase.internal.getinputdevice", "bascenev1.getinputdevice")
|
||||||
|
content = content.replace("babase.internal.has_gamma_control", "babase.has_gamma_control")
|
||||||
|
content = content.replace("babase.internal.has_video_ads", "bauiv1.has_video_ads")
|
||||||
|
content = content.replace("babase.internal.have_incentivized_ad", "bauiv1.have_incentivized_ad")
|
||||||
|
content = content.replace("babase.internal.have_permission", "babase.have_permission")
|
||||||
|
content = content.replace("babase.internal.have_touchscreen_input", "bascenev1.have_touchscreen_input")
|
||||||
|
content = content.replace("babase.internal.host_scan_cycle", "bascenev1.host_scan_cycle")
|
||||||
|
content = content.replace("babase.internal.in_game_purchase", "bui.app.plus.in_game_purchase")
|
||||||
|
content = content.replace("babase.internal.increment_analytics_count", "babase.increment_analytics_count")
|
||||||
|
content = content.replace("babase.internal.is_blessed", "bui.app.plus.is_blessed")
|
||||||
|
content = content.replace("babase.internal.is_browser_likely_available", "bauiv1.is_browser_likely_available")
|
||||||
|
content = content.replace("babase.internal.is_in_replay", "bascenev1.is_in_replay")
|
||||||
|
content = content.replace("babase.internal.is_party_icon_visible", "bauiv1.is_party_icon_visible")
|
||||||
|
content = content.replace("babase.internal.is_running_on_fire_tv", "babase.is_running_on_fire_tv")
|
||||||
|
content = content.replace("babase.internal.is_xcode_build", "babase.is_xcode_build")
|
||||||
|
content = content.replace("babase.internal.json_prep", "babase.json_prep")
|
||||||
|
content = content.replace("babase.internal.lock_all_input", "babase.lock_all_input")
|
||||||
|
content = content.replace("babase.internal.mark_config_dirty", "_babase.app.plus.mark_config_dirty")
|
||||||
|
content = content.replace("babase.internal.new_host_session", "bascenev1.new_host_session")
|
||||||
|
content = content.replace("babase.internal.new_replay_session", "bascenev1.new_replay_session")
|
||||||
|
content = content.replace("babase.internal.open_file_externally", "bauiv1.open_file_externally")
|
||||||
|
content = content.replace("babase.internal.power_ranking_query", "_baplus.power_ranking_query")
|
||||||
|
content = content.replace("babase.internal.preload_map_preview_media", "bauiv1.app.classic.preload_map_preview_media")
|
||||||
|
content = content.replace("babase.internal.purchase", "_baplus.purchase")
|
||||||
|
content = content.replace("babase.internal.register_map", "bascenev1.register_map")
|
||||||
|
content = content.replace("babase.internal.release_gamepad_input", "bascenev1.release_gamepad_input")
|
||||||
|
content = content.replace("babase.internal.release_keyboard_input", "bascenev1.release_keyboard_input")
|
||||||
|
content = content.replace("babase.internal.report_achievement", "babase.app.plus.report_achievement")
|
||||||
|
content = content.replace("babase.internal.request_permission", "babase.request_permission")
|
||||||
|
content = content.replace("babase.internal.reset_achievements", "_baplus.reset_achievements")
|
||||||
|
content = content.replace("babase.internal.reset_random_player_names", "bascenev1.reset_random_player_names")
|
||||||
|
content = content.replace("babase.internal.restore_purchases", "_baplus.restore_purchases")
|
||||||
|
content = content.replace("babase.internal.run_cpu_benchmark", "baclassic._benchmark.run_cpu_benchmark")
|
||||||
|
content = content.replace("babase.internal.run_gpu_benchmark", "baclassic._benchmark.run_gpu_benchmark")
|
||||||
|
content = content.replace("babase.internal.run_media_reload_benchmark", "baclassic._benchmark.run_media_reload_benchmark")
|
||||||
|
content = content.replace("babase.internal.run_stress_test", "babase.app.classic.run_stress_test")
|
||||||
|
content = content.replace("babase.internal.set_authenticate_clients", "bascenev1.set_authenticate_clients")
|
||||||
|
content = content.replace("babase.internal.set_debug_speed_exponent", "bascenev1.set_debug_speed_exponent")
|
||||||
|
content = content.replace("babase.internal.set_low_level_config_value", "babase.set_low_level_config_value")
|
||||||
|
content = content.replace("babase.internal.set_party_icon_always_visible", "bauiv1.set_party_icon_always_visible")
|
||||||
|
content = content.replace("babase.internal.set_party_window_open", "bauiv1.set_party_window_open")
|
||||||
|
content = content.replace("babase.internal.set_public_party_enabled", "bascenev1.set_public_party_enabled")
|
||||||
|
content = content.replace("babase.internal.set_public_party_max_size", "bascenev1.set_public_party_max_size")
|
||||||
|
content = content.replace("babase.internal.set_public_party_name", "bascenev1.set_public_party_name")
|
||||||
|
content = content.replace("babase.internal.set_public_party_queue_enabled", "bascenev1.set_public_party_queue_enabled")
|
||||||
|
content = content.replace("babase.internal.set_replay_speed_exponent", "bascenev1.set_replay_speed_exponent")
|
||||||
|
content = content.replace("babase.internal.set_touchscreen_editing", "bascenev1.set_touchscreen_editing")
|
||||||
|
content = content.replace("babase.internal.set_ui_input_device", "babase.set_ui_input_device")
|
||||||
|
content = content.replace("babase.internal.should_submit_debug_info", "babase._apputils.should_submit_debug_info")
|
||||||
|
content = content.replace("babase.internal.show_online_score_ui", "bauiv1.show_online_score_ui")
|
||||||
|
content = content.replace("babase.internal.sign_in_v1", "babase.app.plus.sign_in_v1")
|
||||||
|
content = content.replace("babase.internal.sign_out_v1", "babase.app.plus.sign_out_v1")
|
||||||
|
content = content.replace("babase.internal.submit_score", "bascenev1.app.plus.submit_score")
|
||||||
|
content = content.replace("babase.internal.tournament_query", "_baplus.tournament_query")
|
||||||
|
content = content.replace("babase.internal.unlock_all_input", "babase.unlock_all_input")
|
||||||
|
content = content.replace("babase.internal.value_test", "bauiv1.app.classic.value_test")
|
||||||
|
content = content.replace("babase.internal.workspaces_in_use", "babase.workspaces_in_use")
|
||||||
|
content = content.replace("babase.internal.dump_tracebacks", "babase._apputils.dump_app_state")
|
||||||
|
content = content.replace("babase.internal.show_app_invite", "_bauiv1.show_app_invite")
|
||||||
|
content = content.replace("babase._generated", "babase._mgen")
|
||||||
|
content = content.replace("_babase.disconnect_from_host", "bascenev1.disconnect_from_host")
|
||||||
|
content = content.replace("babase.disconnect_from_host", "bascenev1.disconnect_from_host")
|
||||||
|
content = content.replace("_babase.connect_to_party", "bascenev1.connect_to_party")
|
||||||
|
content = content.replace("babase.connect_to_party", "bascenev1.connect_to_party")
|
||||||
|
content = content.replace("babase.set_party_window_open", "bauiv1.set_party_window_open")
|
||||||
|
content = content.replace("babase.set_party_window_open", "bauiv1.set_party_window_open")
|
||||||
|
content = content.replace("babase.getcollidemesh", "bascenev1.getcollisionmesh")
|
||||||
|
content = content.replace("collide_mesh", "collision_mesh")
|
||||||
|
content = content.replace("babase.FloatSetting", "bascenev1.FloatSetting")
|
||||||
|
# Removed in API 8:
|
||||||
|
# content = content.replace("babase.internal.set_telnet_access_enabled", "")
|
||||||
|
|
||||||
|
content = content.replace("babase.internal.master_server_get", "babase.app.classic.master_server_v1_get")
|
||||||
|
content = content.replace("babase.internal.master_server_post", "babase.app.classic.master_server_v1_post")
|
||||||
|
content = content.replace("babase.internal.log_dumped_tracebacks", "babase._apputils.log_dumped_app_state")
|
||||||
|
content = content.replace("babase.internal.have_outstanding_transactions", "bauiv1.app.plus.have_outstanding_v1_account_transactions")
|
||||||
|
content = content.replace("babase.internal.get_public_login_id", "bauiv1.app.plus.get_v1_account_public_login_id")
|
||||||
|
content = content.replace("babase.internal.get_input_map_hash", "bauiv1.app.classic.get_input_device_map_hash")
|
||||||
|
content = content.replace("babase.internal.get_device_value", "bauiv1.app.classic.get_input_device_mapped_value")
|
||||||
|
|
||||||
|
# Depracations
|
||||||
|
content = content.replace("babase.app.build_number", "babase.app.build_number if build_number < 21282 else babase.app.env.build_number")
|
||||||
|
content = content.replace("babase.app.device_name", "babase.app.device_name if build_number < 21282 else babase.app.env.device_name")
|
||||||
|
content = content.replace("babase.app.config_file_path", "babase.app.config_file_path if build_number < 21282 else babase.app.env.config_file_path")
|
||||||
|
content = content.replace("babase.app.version", "babase.app.version if build_number < 21282 else babase.app.env")
|
||||||
|
content = content.replace("babase.app.debug_build", "babase.app.debug_build if build_number < 21282 else babase.app.env.debug_build")
|
||||||
|
content = content.replace("babase.app.test_build", "babase.app.test_build if build_number < 21282 else babase.app.env.test_build")
|
||||||
|
content = content.replace("babase.app.data_directory", "babase.app.data_directory if build_number < 21282 else babase.app.env.data_directory")
|
||||||
|
content = content.replace("babase.app.python_directory_user", "babase.app.python_directory_user if build_number < 21282 else babase.app.env.python_directory_user")
|
||||||
|
content = content.replace("babase.app.python_directory_app", "babase.app.env")
|
||||||
|
content = content.replace("babase.app.python_directory_app_site", "babase.app.python_directory_app_site if build_number < 21282 else babase.app.env.python_directory_app_site")
|
||||||
|
content = content.replace("babase.app.api_version", "babase.app.api_version if build_number < 21282 else babase.app.env.api_version")
|
||||||
|
content = content.replace("babase.app.on_tv", "babase.app.on_tv if build_number < 21282 else babase.app.env.on_tv")
|
||||||
|
content = content.replace("babase.app.vr_mode", "babase.app.vr_mode if build_number < 21282 else babase.app.env.vr")
|
||||||
|
content = content.replace("babase.app.toolbar_test", "babase.app.toolbar_test if build_number < 21282 else babase.app.env.toolbar_test")
|
||||||
|
content = content.replace("babase.app.arcade_mode", "babase.app.arcade_mode if build_number < 21282 else babase.app.env.arcade_mode")
|
||||||
|
content = content.replace("babase.app.headless_mode", "babase.app.headless_mode if build_number < 21282 else babase.app.env.headless_mode")
|
||||||
|
content = content.replace("babase.app.demo_mode", "babase.app.demo_mode if build_number < 21282 else babase.app.env.demo_mode")
|
||||||
|
content = content.replace("babase.app.protocol_version", "babase.app.protocol_version if build_number < 21282 else babase.app.env.protocol_version")
|
||||||
|
content = content.replace("bascenev1.get_connection_to_host_info", "bascenev1.get_connection_to_host_info if build_number < 21697 else bascenev1.get_connection_to_host_info_2")
|
||||||
|
|
||||||
|
content = content.replace("babase._store", "bauiv1.app.classic.store")
|
||||||
|
# content = content.replace("babase.internal", "")
|
||||||
|
content = content.replace("bastd.ui", "bauiv1lib")
|
||||||
|
content = content.replace("bastd", "bascenev1lib")
|
||||||
|
content = content.replace("timetype=","")
|
||||||
|
content = content.replace("babase.columnwidget", "bauiv1.columnwidget")
|
||||||
|
content = content.replace("_babase.get_game_port", "bascenev1.get_game_port")
|
||||||
|
content = content.replace("_babase.get_chat_messages", "bascenev1.get_chat_messages")
|
||||||
|
content = content.replace("_babase.get_foreground_host_session", "bascenev1.get_foreground_host_session")
|
||||||
|
content = content.replace("_babase.get_foreground_host_activity", "bascenev1.get_foreground_host_activity")
|
||||||
|
content = content.replace("bascenev1.SessionPlayerNotFoundError", "babase.SessionPlayerNotFoundError")
|
||||||
|
content = content.replace("bascenev1", "bs")
|
||||||
|
content = content.replace("bauiv1", "bui")
|
||||||
|
content = content.replace("import bs", "import bascenev1 as bs")
|
||||||
|
content = content.replace("import bui", "import bauiv1 as bui")
|
||||||
|
content = content.replace("bslib", "bascenev1lib")
|
||||||
|
content = content.replace("builib", "bauiv1lib")
|
||||||
|
content = content.replace("from bs.", "from bascenev1.")
|
||||||
|
content = content.replace("from bui.", "from bauiv1.")
|
||||||
|
content = content.replace("import bascenev1 as bascenev1lib", "import bascenev1lib")
|
||||||
|
content = content.replace("import bauiv1 as bauiv1lib", "import bauiv1lib")
|
||||||
|
content = content.replace("# ba_meta export bs.GameActivity", "# ba_meta export bascenev1.GameActivity")
|
||||||
|
content = content.replace("_bs", "bs")
|
||||||
|
|
||||||
|
content = re.sub(r'bs\.Timer\(([^)]*)\bTimeType\.REAL\b([^)]*)\)', r'babase.AppTimer(\1\2)', content)
|
||||||
|
trademark = "# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)\n"
|
||||||
|
with open(sys.argv[2], "w", encoding=encoding) as f:
|
||||||
|
f.write(trademark + content)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
"""Quake Game Activity"""
|
"""Quake Game Activity"""
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import enum
|
import enum
|
||||||
import ba
|
import babase
|
||||||
import _ba
|
import bauiv1 as bui
|
||||||
|
import bascenev1 as bs
|
||||||
|
import _babase
|
||||||
|
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
from bastd.actor.powerupbox import PowerupBox
|
from bascenev1lib.actor.powerupbox import PowerupBox
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
# from rocket
|
# from rocket
|
||||||
from bastd.actor.bomb import Blast
|
from bascenev1lib.actor.bomb import Blast
|
||||||
|
|
||||||
# from railgun
|
# from railgun
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.spaz import Spaz
|
from bascenev1lib.actor.spaz import Spaz
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -33,7 +36,7 @@ class RocketFactory:
|
||||||
"""Quake Rocket factory"""
|
"""Quake Rocket factory"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.ball_material = ba.Material()
|
self.ball_material = bs.Material()
|
||||||
|
|
||||||
self.ball_material.add_actions(
|
self.ball_material.add_actions(
|
||||||
conditions=((('we_are_younger_than', 5), 'or',
|
conditions=((('we_are_younger_than', 5), 'or',
|
||||||
|
|
@ -60,7 +63,7 @@ class RocketFactory:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls):
|
def get(cls):
|
||||||
"""Get factory if exists else create new"""
|
"""Get factory if exists else create new"""
|
||||||
activity = ba.getactivity()
|
activity = bs.getactivity()
|
||||||
if hasattr(activity, STORAGE_ATTR_NAME):
|
if hasattr(activity, STORAGE_ATTR_NAME):
|
||||||
return getattr(activity, STORAGE_ATTR_NAME)
|
return getattr(activity, STORAGE_ATTR_NAME)
|
||||||
factory = cls()
|
factory = cls()
|
||||||
|
|
@ -77,13 +80,13 @@ class RocketLauncher:
|
||||||
def give(self, spaz: Spaz) -> None:
|
def give(self, spaz: Spaz) -> None:
|
||||||
"""Give spaz a rocket launcher"""
|
"""Give spaz a rocket launcher"""
|
||||||
spaz.punch_callback = self.shot
|
spaz.punch_callback = self.shot
|
||||||
self.last_shot = ba.time()
|
self.last_shot = bs.time()
|
||||||
|
|
||||||
# FIXME
|
# FIXME
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
def shot(self, spaz: Spaz) -> None:
|
def shot(self, spaz: Spaz) -> None:
|
||||||
"""Release a rocket"""
|
"""Release a rocket"""
|
||||||
time = ba.time()
|
time = bs.time()
|
||||||
if time - self.last_shot > 0.6:
|
if time - self.last_shot > 0.6:
|
||||||
self.last_shot = time
|
self.last_shot = time
|
||||||
center = spaz.node.position_center
|
center = spaz.node.position_center
|
||||||
|
|
@ -92,12 +95,12 @@ class RocketLauncher:
|
||||||
center[2] - forward[2]]
|
center[2] - forward[2]]
|
||||||
direction[1] = 0.0
|
direction[1] = 0.0
|
||||||
|
|
||||||
mag = 10.0 / ba.Vec3(*direction).length()
|
mag = 10.0 / babase.Vec3(*direction).length()
|
||||||
vel = [v * mag for v in direction]
|
vel = [v * mag for v in direction]
|
||||||
Rocket(position=spaz.node.position,
|
Rocket(position=spaz.node.position,
|
||||||
velocity=vel,
|
velocity=vel,
|
||||||
owner=spaz.getplayer(ba.Player),
|
owner=spaz.getplayer(bs.Player),
|
||||||
source_player=spaz.getplayer(ba.Player),
|
source_player=spaz.getplayer(bs.Player),
|
||||||
color=spaz.node.color).autoretain()
|
color=spaz.node.color).autoretain()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -105,7 +108,7 @@ class ImpactMessage:
|
||||||
"""Rocket touched something"""
|
"""Rocket touched something"""
|
||||||
|
|
||||||
|
|
||||||
class Rocket(ba.Actor):
|
class Rocket(bs.Actor):
|
||||||
"""Epic rocket from rocket launcher"""
|
"""Epic rocket from rocket launcher"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
|
@ -120,16 +123,16 @@ class Rocket(ba.Actor):
|
||||||
self._color = color
|
self._color = color
|
||||||
factory = RocketFactory.get()
|
factory = RocketFactory.get()
|
||||||
|
|
||||||
self.node = ba.newnode('prop',
|
self.node = bs.newnode('prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position': position,
|
'position': position,
|
||||||
'velocity': velocity,
|
'velocity': velocity,
|
||||||
'model': ba.getmodel('impactBomb'),
|
'mesh': bs.getmesh('impactBomb'),
|
||||||
'body': 'sphere',
|
'body': 'sphere',
|
||||||
'color_texture': ba.gettexture(
|
'color_texture': bs.gettexture(
|
||||||
'bunnyColor'),
|
'bunnyColor'),
|
||||||
'model_scale': 0.2,
|
'mesh_scale': 0.2,
|
||||||
'is_area_of_interest': True,
|
'is_area_of_interest': True,
|
||||||
'body_scale': 0.8,
|
'body_scale': 0.8,
|
||||||
'materials': [
|
'materials': [
|
||||||
|
|
@ -139,17 +142,17 @@ class Rocket(ba.Actor):
|
||||||
self.node.extra_acceleration = (self.node.velocity[0] * 200, 0,
|
self.node.extra_acceleration = (self.node.velocity[0] * 200, 0,
|
||||||
self.node.velocity[2] * 200)
|
self.node.velocity[2] * 200)
|
||||||
|
|
||||||
self._life_timer = ba.Timer(
|
self._life_timer = bs.Timer(
|
||||||
5, ba.WeakCall(self.handlemessage, ba.DieMessage()))
|
5, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||||
|
|
||||||
self._emit_timer = ba.Timer(0.001, ba.WeakCall(self.emit), repeat=True)
|
self._emit_timer = bs.Timer(0.001, bs.WeakCall(self.emit), repeat=True)
|
||||||
self.base_pos_y = self.node.position[1]
|
self.base_pos_y = self.node.position[1]
|
||||||
|
|
||||||
ba.camerashake(5.0)
|
bs.camerashake(5.0)
|
||||||
|
|
||||||
def emit(self) -> None:
|
def emit(self) -> None:
|
||||||
"""Emit a trace after rocket"""
|
"""Emit a trace after rocket"""
|
||||||
ba.emitfx(position=self.node.position,
|
bs.emitfx(position=self.node.position,
|
||||||
scale=0.4,
|
scale=0.4,
|
||||||
spread=0.01,
|
spread=0.01,
|
||||||
chunk_type='spark')
|
chunk_type='spark')
|
||||||
|
|
@ -157,7 +160,7 @@ class Rocket(ba.Actor):
|
||||||
return
|
return
|
||||||
self.node.position = (self.node.position[0], self.base_pos_y,
|
self.node.position = (self.node.position[0], self.base_pos_y,
|
||||||
self.node.position[2]) # ignore y
|
self.node.position[2]) # ignore y
|
||||||
ba.newnode('explosion',
|
bs.newnode('explosion',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': self.node.position,
|
'position': self.node.position,
|
||||||
|
|
@ -169,9 +172,9 @@ class Rocket(ba.Actor):
|
||||||
"""Message handling for rocket"""
|
"""Message handling for rocket"""
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
if isinstance(msg, ImpactMessage):
|
if isinstance(msg, ImpactMessage):
|
||||||
self.node.handlemessage(ba.DieMessage())
|
self.node.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
elif isinstance(msg, ba.DieMessage):
|
elif isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
Blast(position=self.node.position,
|
Blast(position=self.node.position,
|
||||||
blast_radius=2,
|
blast_radius=2,
|
||||||
|
|
@ -180,8 +183,8 @@ class Rocket(ba.Actor):
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
self._emit_timer = None
|
self._emit_timer = None
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
# -------------------Rocket--------------------------
|
# -------------------Rocket--------------------------
|
||||||
|
|
||||||
|
|
@ -196,13 +199,13 @@ class Railgun:
|
||||||
def give(self, spaz: Spaz) -> None:
|
def give(self, spaz: Spaz) -> None:
|
||||||
"""Give spaz a railgun"""
|
"""Give spaz a railgun"""
|
||||||
spaz.punch_callback = self.shot
|
spaz.punch_callback = self.shot
|
||||||
self.last_shot = ba.time()
|
self.last_shot = bs.time()
|
||||||
|
|
||||||
# FIXME
|
# FIXME
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
def shot(self, spaz: Spaz) -> None:
|
def shot(self, spaz: Spaz) -> None:
|
||||||
"""Release a rocket"""
|
"""Release a rocket"""
|
||||||
time = ba.time()
|
time = bs.time()
|
||||||
if time - self.last_shot > 0.6:
|
if time - self.last_shot > 0.6:
|
||||||
self.last_shot = time
|
self.last_shot = time
|
||||||
center = spaz.node.position_center
|
center = spaz.node.position_center
|
||||||
|
|
@ -215,8 +218,8 @@ class Railgun:
|
||||||
|
|
||||||
RailBullet(position=spaz.node.position,
|
RailBullet(position=spaz.node.position,
|
||||||
direction=direction,
|
direction=direction,
|
||||||
owner=spaz.getplayer(ba.Player),
|
owner=spaz.getplayer(bs.Player),
|
||||||
source_player=spaz.getplayer(ba.Player),
|
source_player=spaz.getplayer(bs.Player),
|
||||||
color=spaz.node.color).autoretain()
|
color=spaz.node.color).autoretain()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -227,7 +230,7 @@ class TouchedToSpazMessage:
|
||||||
self.spaz = spaz
|
self.spaz = spaz
|
||||||
|
|
||||||
|
|
||||||
class RailBullet(ba.Actor):
|
class RailBullet(bs.Actor):
|
||||||
"""Railgun bullet"""
|
"""Railgun bullet"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
|
@ -239,23 +242,23 @@ class RailBullet(ba.Actor):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._color = color
|
self._color = color
|
||||||
|
|
||||||
self.node = ba.newnode('light',
|
self.node = bs.newnode('light',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position': position,
|
'position': position,
|
||||||
'color': self._color
|
'color': self._color
|
||||||
})
|
})
|
||||||
ba.animate(self.node, 'radius', {0: 0, 0.1: 0.5, 0.5: 0})
|
bs.animate(self.node, 'radius', {0: 0, 0.1: 0.5, 0.5: 0})
|
||||||
|
|
||||||
self.source_player = source_player
|
self.source_player = source_player
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self._life_timer = ba.Timer(
|
self._life_timer = bs.Timer(
|
||||||
0.5, ba.WeakCall(self.handlemessage, ba.DieMessage()))
|
0.5, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||||
|
|
||||||
pos = position
|
pos = position
|
||||||
vel = tuple(i / 5 for i in ba.Vec3(direction).normalized())
|
vel = tuple(i / 5 for i in babase.Vec3(direction).normalized())
|
||||||
for _ in range(500): # Optimization :(
|
for _ in range(500): # Optimization :(
|
||||||
ba.newnode('explosion',
|
bs.newnode('explosion',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': pos,
|
'position': pos,
|
||||||
|
|
@ -264,25 +267,25 @@ class RailBullet(ba.Actor):
|
||||||
})
|
})
|
||||||
pos = (pos[0] + vel[0], pos[1] + vel[1], pos[2] + vel[2])
|
pos = (pos[0] + vel[0], pos[1] + vel[1], pos[2] + vel[2])
|
||||||
|
|
||||||
for node in _ba.getnodes():
|
for node in _babase.getnodes():
|
||||||
if node and node.getnodetype() == 'spaz':
|
if node and node.getnodetype() == 'spaz':
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
m3 = ba.Vec3(position)
|
m3 = babase.Vec3(position)
|
||||||
a = ba.Vec3(direction[2], direction[1], direction[0])
|
a = babase.Vec3(direction[2], direction[1], direction[0])
|
||||||
m1 = ba.Vec3(node.position)
|
m1 = babase.Vec3(node.position)
|
||||||
# pylint: enable=invalid-name
|
# pylint: enable=invalid-name
|
||||||
# distance between node and line
|
# distance between node and line
|
||||||
dist = (a * (m1 - m3)).length() / a.length()
|
dist = (a * (m1 - m3)).length() / a.length()
|
||||||
if dist < 0.3:
|
if dist < 0.3:
|
||||||
if node and node != self.owner and node.getdelegate(
|
if node and node != self.owner and node.getdelegate(
|
||||||
PlayerSpaz, True).getplayer(
|
PlayerSpaz, True).getplayer(
|
||||||
ba.Player, True).team != self.owner.team:
|
bs.Player, True).team != self.owner.team:
|
||||||
node.handlemessage(ba.FreezeMessage())
|
node.handlemessage(bs.FreezeMessage())
|
||||||
pos = self.node.position
|
pos = self.node.position
|
||||||
hit_dir = (0, 10, 0)
|
hit_dir = (0, 10, 0)
|
||||||
|
|
||||||
node.handlemessage(
|
node.handlemessage(
|
||||||
ba.HitMessage(pos=pos,
|
bs.HitMessage(pos=pos,
|
||||||
magnitude=50,
|
magnitude=50,
|
||||||
velocity_magnitude=50,
|
velocity_magnitude=50,
|
||||||
radius=0,
|
radius=0,
|
||||||
|
|
@ -292,21 +295,21 @@ class RailBullet(ba.Actor):
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
# ------------------Railgun-------------------------
|
# ------------------Railgun-------------------------
|
||||||
|
|
||||||
|
|
||||||
class Player(ba.Player['Team']):
|
class Player(bs.Player['Team']):
|
||||||
"""Our player"""
|
"""Our player"""
|
||||||
|
|
||||||
|
|
||||||
class Team(ba.Team[Player]):
|
class Team(bs.Team[Player]):
|
||||||
"""Our team"""
|
"""Our team"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
@ -326,91 +329,91 @@ class ObstaclesForm(enum.Enum):
|
||||||
RANDOM = 2
|
RANDOM = 2
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
class QuakeGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Quake Team Game Activity"""
|
"""Quake Team Game Activity"""
|
||||||
name = 'Quake'
|
name = 'Quake'
|
||||||
description = 'Kill a set number of enemies to win.'
|
description = 'Kill a set number of enemies to win.'
|
||||||
available_settings = [
|
available_settings = [
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Kills to Win Per Player',
|
'Kills to Win Per Player',
|
||||||
default=15,
|
default=15,
|
||||||
min_value=1,
|
min_value=1,
|
||||||
increment=1,
|
increment=1,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
|
choices=[('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
|
||||||
('5 Minutes', 300), ('10 Minutes', 600),
|
('5 Minutes', 300), ('10 Minutes', 600),
|
||||||
('20 Minutes', 1200)],
|
('20 Minutes', 1200)],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[('At once', 0.0), ('Shorter', 0.25), ('Short', 0.5),
|
choices=[('At once', 0.0), ('Shorter', 0.25), ('Short', 0.5),
|
||||||
('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)],
|
('Normal', 1.0), ('Long', 2.0), ('Longer', 4.0)],
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Speed',
|
'Speed',
|
||||||
default=True,
|
default=True,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Enable Jump',
|
'Enable Jump',
|
||||||
default=True,
|
default=True,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Enable Pickup',
|
'Enable Pickup',
|
||||||
default=True,
|
default=True,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Enable Bomb',
|
'Enable Bomb',
|
||||||
default=False,
|
default=False,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Obstacles',
|
'Obstacles',
|
||||||
default=True,
|
default=True,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Obstacles Form',
|
'Obstacles Form',
|
||||||
choices=[('Cube', ObstaclesForm.CUBE.value),
|
choices=[('Cube', ObstaclesForm.CUBE.value),
|
||||||
('Sphere', ObstaclesForm.SPHERE.value),
|
('Sphere', ObstaclesForm.SPHERE.value),
|
||||||
('Random', ObstaclesForm.RANDOM.value)],
|
('Random', ObstaclesForm.RANDOM.value)],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Weapon Type',
|
'Weapon Type',
|
||||||
choices=[('Rocket', WeaponType.ROCKET.value),
|
choices=[('Rocket', WeaponType.ROCKET.value),
|
||||||
('Railgun', WeaponType.RAILGUN.value)],
|
('Railgun', WeaponType.RAILGUN.value)],
|
||||||
default=WeaponType.ROCKET.value,
|
default=WeaponType.ROCKET.value,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Obstacles Mirror Shots',
|
'Obstacles Mirror Shots',
|
||||||
default=False,
|
default=False,
|
||||||
),
|
),
|
||||||
ba.IntSetting(
|
bs.IntSetting(
|
||||||
'Obstacles Count',
|
'Obstacles Count',
|
||||||
default=16,
|
default=16,
|
||||||
min_value=0,
|
min_value=0,
|
||||||
increment=2,
|
increment=2,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Random Obstacles Color',
|
'Random Obstacles Color',
|
||||||
default=True,
|
default=True,
|
||||||
),
|
),
|
||||||
ba.BoolSetting(
|
bs.BoolSetting(
|
||||||
'Epic Mode',
|
'Epic Mode',
|
||||||
default=False,
|
default=False,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@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.MultiTeamSession) or issubclass(
|
return issubclass(sessiontype, bs.MultiTeamSession) or issubclass(
|
||||||
sessiontype, ba.FreeForAllSession)
|
sessiontype, bs.FreeForAllSession)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:
|
def get_supported_maps(cls, sessiontype: Type[bs.Session]) -> List[str]:
|
||||||
# TODO add more maps
|
# TODO add more maps
|
||||||
return ['Football Stadium', 'Monkey Face', 'Doom Shroom']
|
return ['Football Stadium', 'Monkey Face', 'Doom Shroom']
|
||||||
|
|
||||||
|
|
@ -426,15 +429,15 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._pickup_enabled = self.settings_raw['Enable Pickup']
|
self._pickup_enabled = self.settings_raw['Enable Pickup']
|
||||||
self._jump_enabled = self.settings_raw['Enable Jump']
|
self._jump_enabled = self.settings_raw['Enable Jump']
|
||||||
self._weapon_type = WeaponType(self.settings_raw['Weapon Type'])
|
self._weapon_type = WeaponType(self.settings_raw['Weapon Type'])
|
||||||
self.default_music = (ba.MusicType.EPIC
|
self.default_music = (bs.MusicType.EPIC
|
||||||
if self._epic_mode else ba.MusicType.GRAND_ROMP)
|
if self._epic_mode else bs.MusicType.GRAND_ROMP)
|
||||||
self.slow_motion = self._epic_mode
|
self.slow_motion = self._epic_mode
|
||||||
|
|
||||||
self.announce_player_deaths = True
|
self.announce_player_deaths = True
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._ding_sound = ba.getsound('dingSmall')
|
self._ding_sound = bs.getsound('dingSmall')
|
||||||
|
|
||||||
self._shield_dropper: Optional[ba.Timer] = None
|
self._shield_dropper: Optional[bs.Timer] = None
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
return 'Kill ${ARG1} enemies.', self._score_to_win
|
return 'Kill ${ARG1} enemies.', self._score_to_win
|
||||||
|
|
@ -445,11 +448,11 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
ba.TeamGameActivity.on_begin(self)
|
bs.TeamGameActivity.on_begin(self)
|
||||||
ba.getactivity().globalsnode.tint = (0.5, 0.7, 1)
|
bs.getactivity().globalsnode.tint = (0.5, 0.7, 1)
|
||||||
self.drop_shield()
|
self.drop_shield()
|
||||||
self._shield_dropper = ba.Timer(8,
|
self._shield_dropper = bs.Timer(8,
|
||||||
ba.WeakCall(self.drop_shield),
|
bs.WeakCall(self.drop_shield),
|
||||||
repeat=True)
|
repeat=True)
|
||||||
self.setup_standard_time_limit(self._time_limit)
|
self.setup_standard_time_limit(self._time_limit)
|
||||||
if self._obstacles_enabled:
|
if self._obstacles_enabled:
|
||||||
|
|
@ -483,9 +486,9 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
position=(random.uniform(-10, 10), 6,
|
position=(random.uniform(-10, 10), 6,
|
||||||
random.uniform(-5, 5))).autoretain()
|
random.uniform(-5, 5))).autoretain()
|
||||||
|
|
||||||
ba.playsound(self._ding_sound)
|
self._ding_sound.play()
|
||||||
|
|
||||||
p_light = ba.newnode('light',
|
p_light = bs.newnode('light',
|
||||||
owner=shield.node,
|
owner=shield.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 0, 0),
|
'position': (0, 0, 0),
|
||||||
|
|
@ -497,7 +500,7 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
shield.node.connectattr('position', p_light, 'position')
|
shield.node.connectattr('position', p_light, 'position')
|
||||||
|
|
||||||
ba.animate(p_light, 'intensity', {0: 2, 8: 0})
|
bs.animate(p_light, 'intensity', {0: 2, 8: 0})
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> None:
|
def spawn_player(self, player: Player) -> None:
|
||||||
spaz = self.spawn_player_spaz(player)
|
spaz = self.spawn_player_spaz(player)
|
||||||
|
|
@ -511,7 +514,7 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
enable_fly=False)
|
enable_fly=False)
|
||||||
|
|
||||||
spaz.node.hockey = self._speed_enabled
|
spaz.node.hockey = self._speed_enabled
|
||||||
spaz.spaz_light = ba.newnode('light',
|
spaz.spaz_light = bs.newnode('light',
|
||||||
owner=spaz.node,
|
owner=spaz.node,
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 0, 0),
|
'position': (0, 0, 0),
|
||||||
|
|
@ -524,8 +527,8 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
spaz.node.connectattr('position', spaz.spaz_light, 'position')
|
spaz.node.connectattr('position', spaz.spaz_light, 'position')
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
ba.TeamGameActivity.handlemessage(self, msg)
|
bs.TeamGameActivity.handlemessage(self, msg)
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
self.respawn_player(player)
|
self.respawn_player(player)
|
||||||
killer = msg.getkillerplayer(Player)
|
killer = msg.getkillerplayer(Player)
|
||||||
|
|
@ -535,20 +538,20 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# handle team-kills
|
# handle team-kills
|
||||||
if killer.team is player.team:
|
if killer.team is player.team:
|
||||||
# in free-for-all, killing yourself loses you a point
|
# in free-for-all, killing yourself loses you a point
|
||||||
if isinstance(self.session, ba.FreeForAllSession):
|
if isinstance(self.session, bs.FreeForAllSession):
|
||||||
new_score = player.team.score - 1
|
new_score = player.team.score - 1
|
||||||
new_score = max(0, new_score)
|
new_score = max(0, new_score)
|
||||||
player.team.score = new_score
|
player.team.score = new_score
|
||||||
# in teams-mode it gives a point to the other team
|
# in teams-mode it gives a point to the other team
|
||||||
else:
|
else:
|
||||||
ba.playsound(self._ding_sound)
|
self._ding_sound.play()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
if team is not killer.team:
|
if team is not killer.team:
|
||||||
team.score += 1
|
team.score += 1
|
||||||
# killing someone on another team nets a kill
|
# killing someone on another team nets a kill
|
||||||
else:
|
else:
|
||||||
killer.team.score += 1
|
killer.team.score += 1
|
||||||
ba.playsound(self._ding_sound)
|
self._ding_sound.play()
|
||||||
# in FFA show our score since its hard to find on
|
# in FFA show our score since its hard to find on
|
||||||
# the scoreboard
|
# the scoreboard
|
||||||
assert killer.actor is not None
|
assert killer.actor is not None
|
||||||
|
|
@ -564,10 +567,10 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# (allows the dust to clear and draws to occur if
|
# (allows the dust to clear and draws to occur if
|
||||||
# deaths are close enough)
|
# deaths are close enough)
|
||||||
if any(team.score >= self._score_to_win for team in self.teams):
|
if any(team.score >= self._score_to_win for team in self.teams):
|
||||||
ba.timer(0.5, self.end_game)
|
bs.timer(0.5, self.end_game)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ba.TeamGameActivity.handlemessage(self, msg)
|
bs.TeamGameActivity.handlemessage(self, msg)
|
||||||
|
|
||||||
def _update_scoreboard(self) -> None:
|
def _update_scoreboard(self) -> None:
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
|
|
@ -575,51 +578,51 @@ class QuakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._score_to_win)
|
self._score_to_win)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.score)
|
results.set_team_score(team, team.score)
|
||||||
|
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
||||||
|
|
||||||
class Obstacle(ba.Actor):
|
class Obstacle(bs.Actor):
|
||||||
"""Scene object"""
|
"""Scene object"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
position,
|
position,
|
||||||
form=ObstaclesForm.CUBE,
|
form=ObstaclesForm.CUBE,
|
||||||
mirror=False) -> None:
|
mirror=False) -> None:
|
||||||
ba.Actor.__init__(self)
|
bs.Actor.__init__(self)
|
||||||
|
|
||||||
if form == ObstaclesForm.CUBE:
|
if form == ObstaclesForm.CUBE:
|
||||||
model = 'tnt'
|
mesh = 'tnt'
|
||||||
body = 'crate'
|
body = 'crate'
|
||||||
elif form == ObstaclesForm.SPHERE:
|
elif form == ObstaclesForm.SPHERE:
|
||||||
model = 'bomb'
|
mesh = 'bomb'
|
||||||
body = 'sphere'
|
body = 'sphere'
|
||||||
else: # ObstaclesForm.RANDOM:
|
else: # ObstaclesForm.RANDOM:
|
||||||
model = random.choice(['tnt', 'bomb'])
|
mesh = random.choice(['tnt', 'bomb'])
|
||||||
body = 'sphere' if model == 'bomb' else 'crate'
|
body = 'sphere' if mesh == 'bomb' else 'crate'
|
||||||
|
|
||||||
self.node = ba.newnode(
|
self.node = bs.newnode(
|
||||||
'prop',
|
'prop',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
'position':
|
'position':
|
||||||
position,
|
position,
|
||||||
'model':
|
'mesh':
|
||||||
ba.getmodel(model),
|
bs.getmesh(mesh),
|
||||||
'body':
|
'body':
|
||||||
body,
|
body,
|
||||||
'body_scale':
|
'body_scale':
|
||||||
1.3,
|
1.3,
|
||||||
'model_scale':
|
'mesh_scale':
|
||||||
1.3,
|
1.3,
|
||||||
'reflection':
|
'reflection':
|
||||||
'powerup',
|
'powerup',
|
||||||
'reflection_scale': [0.7],
|
'reflection_scale': [0.7],
|
||||||
'color_texture':
|
'color_texture':
|
||||||
ba.gettexture('bunnyColor'),
|
bs.gettexture('bunnyColor'),
|
||||||
'materials': [SharedObjects.get().footing_material]
|
'materials': [SharedObjects.get().footing_material]
|
||||||
if mirror else [
|
if mirror else [
|
||||||
SharedObjects.get().object_material,
|
SharedObjects.get().object_material,
|
||||||
|
|
@ -628,15 +631,15 @@ class Obstacle(ba.Actor):
|
||||||
})
|
})
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
elif isinstance(msg, ba.HitMessage):
|
elif isinstance(msg, bs.HitMessage):
|
||||||
self.node.handlemessage('impulse', msg.pos[0], msg.pos[1],
|
self.node.handlemessage('impulse', msg.pos[0], msg.pos[1],
|
||||||
msg.pos[2], msg.velocity[0],
|
msg.pos[2], msg.velocity[0],
|
||||||
msg.velocity[1], msg.velocity[2],
|
msg.velocity[1], msg.velocity[2],
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,43 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
"""DeathMatch game and support classes."""
|
"""DeathMatch game and support classes."""
|
||||||
|
|
||||||
# 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
|
||||||
import _ba
|
import bascenev1 as bs
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.game.deathmatch import DeathMatchGame, Player
|
||||||
from bastd.game.deathmatch import DeathMatchGame, Player, Team
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
from bastd.gameutils import SharedObjects
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
from typing import Any, Sequence, Dict, Type, List, Optional, Union
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class ShimlaGame(DeathMatchGame):
|
class ShimlaGame(DeathMatchGame):
|
||||||
name = 'Shimla'
|
name = 'Shimla'
|
||||||
|
|
||||||
@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 ['Creative Thoughts']
|
return ['Creative Thoughts']
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self.lifts = {}
|
self.lifts = {}
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._real_wall_material.add_actions(
|
self._real_wall_material.add_actions(
|
||||||
|
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -53,7 +53,7 @@ class ShimlaGame(DeathMatchGame):
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
|
|
||||||
))
|
))
|
||||||
self._lift_material = ba.Material()
|
self._lift_material = bs.Material()
|
||||||
self._lift_material.add_actions(
|
self._lift_material.add_actions(
|
||||||
|
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -71,14 +71,14 @@ class ShimlaGame(DeathMatchGame):
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_begin(self):
|
def on_begin(self):
|
||||||
ba.getactivity().globalsnode.happy_thoughts_mode = False
|
bs.getactivity().globalsnode.happy_thoughts_mode = False
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
|
|
||||||
self.make_map()
|
self.make_map()
|
||||||
ba.timer(2, self.disable_fly)
|
bs.timer(2, self.disable_fly)
|
||||||
|
|
||||||
def disable_fly(self):
|
def disable_fly(self):
|
||||||
activity = _ba.get_foreground_host_activity()
|
activity = bs.get_foreground_host_activity()
|
||||||
|
|
||||||
for players in activity.players:
|
for players in activity.players:
|
||||||
players.actor.node.fly = False
|
players.actor.node.fly = False
|
||||||
|
|
@ -102,29 +102,29 @@ class ShimlaGame(DeathMatchGame):
|
||||||
|
|
||||||
def make_map(self):
|
def make_map(self):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
_ba.get_foreground_host_activity()._map.leftwall.materials = [
|
bs.get_foreground_host_activity()._map.leftwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.rightwall.materials = [
|
bs.get_foreground_host_activity()._map.rightwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
_ba.get_foreground_host_activity()._map.topwall.materials = [
|
bs.get_foreground_host_activity()._map.topwall.materials = [
|
||||||
shared.footing_material, self._real_wall_material]
|
shared.footing_material, self._real_wall_material]
|
||||||
|
|
||||||
self.floorwall1 = ba.newnode('region', attrs={'position': (-10, 5, -5.52), 'scale':
|
self.floorwall1 = bs.newnode('region', attrs={'position': (-10, 5, -5.52), 'scale':
|
||||||
(15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
(15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.floorwall2 = ba.newnode('region', attrs={'position': (10, 5, -5.52), 'scale': (
|
self.floorwall2 = bs.newnode('region', attrs={'position': (10, 5, -5.52), 'scale': (
|
||||||
15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
15, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
|
|
||||||
self.wall1 = ba.newnode('region', attrs={'position': (0, 11, -6.90), 'scale': (
|
self.wall1 = bs.newnode('region', attrs={'position': (0, 11, -6.90), 'scale': (
|
||||||
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.wall2 = ba.newnode('region', attrs={'position': (0, 11, -4.14), 'scale': (
|
self.wall2 = bs.newnode('region', attrs={'position': (0, 11, -4.14), 'scale': (
|
||||||
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 20, 1), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
|
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (-10, 5, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (-10, 5, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
||||||
|
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (10, 5, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (10, 5, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (15, 0.2, 2)})
|
||||||
self.create_lift(-16.65, 8)
|
self.create_lift(-16.65, 8)
|
||||||
|
|
||||||
|
|
@ -151,32 +151,32 @@ class ShimlaGame(DeathMatchGame):
|
||||||
|
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
|
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (5.5, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (5.5, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
||||||
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (5.5, 0.1, 2)})
|
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (5.5, 0.1, 2)})
|
||||||
|
|
||||||
def create_lift(self, x, y):
|
def create_lift(self, x, y):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
color = (0.7, 0.6, 0.5)
|
color = (0.7, 0.6, 0.5)
|
||||||
|
|
||||||
floor = ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
floor = bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
||||||
1.8, 0.1, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material, self._lift_material]})
|
1.8, 0.1, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material, self._lift_material]})
|
||||||
|
|
||||||
cleaner = ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
cleaner = bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (
|
||||||
2, 0.3, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
2, 0.3, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
|
|
||||||
lift = ba.newnode('locator', attrs={'shape': 'box', 'position': (
|
lift = bs.newnode('locator', attrs={'shape': 'box', 'position': (
|
||||||
x, y, -5.52), 'color': color, 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (1.8, 3.7, 2)})
|
x, y, -5.52), 'color': color, 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (1.8, 3.7, 2)})
|
||||||
|
|
||||||
_tcombine = ba.newnode('combine',
|
_tcombine = bs.newnode('combine',
|
||||||
owner=floor,
|
owner=floor,
|
||||||
attrs={
|
attrs={
|
||||||
'input0': x,
|
'input0': x,
|
||||||
'input2': -5.5,
|
'input2': -5.5,
|
||||||
'size': 3
|
'size': 3
|
||||||
})
|
})
|
||||||
mnode = ba.newnode('math',
|
mnode = bs.newnode('math',
|
||||||
owner=lift,
|
owner=lift,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': (0, 2, 0),
|
'input1': (0, 2, 0),
|
||||||
|
|
@ -184,7 +184,7 @@ class ShimlaGame(DeathMatchGame):
|
||||||
})
|
})
|
||||||
_tcombine.connectattr('output', mnode, 'input2')
|
_tcombine.connectattr('output', mnode, 'input2')
|
||||||
|
|
||||||
_cleaner_combine = ba.newnode('combine',
|
_cleaner_combine = bs.newnode('combine',
|
||||||
owner=cleaner,
|
owner=cleaner,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': 5.6,
|
'input1': 5.6,
|
||||||
|
|
@ -192,10 +192,10 @@ class ShimlaGame(DeathMatchGame):
|
||||||
'size': 3
|
'size': 3
|
||||||
})
|
})
|
||||||
_cleaner_combine.connectattr('output', cleaner, 'position')
|
_cleaner_combine.connectattr('output', cleaner, 'position')
|
||||||
ba.animate(_tcombine, 'input1', {
|
bs.animate(_tcombine, 'input1', {
|
||||||
0: 5.1,
|
0: 5.1,
|
||||||
})
|
})
|
||||||
ba.animate(_cleaner_combine, 'input0', {
|
bs.animate(_cleaner_combine, 'input0', {
|
||||||
0: -19 if x < 0 else 19,
|
0: -19 if x < 0 else 19,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -205,29 +205,29 @@ class ShimlaGame(DeathMatchGame):
|
||||||
"cleaner": _cleaner_combine, 'leftLift': x < 0}
|
"cleaner": _cleaner_combine, 'leftLift': x < 0}
|
||||||
|
|
||||||
def _handle_lift(self):
|
def _handle_lift(self):
|
||||||
region = ba.getcollision().sourcenode
|
region = bs.getcollision().sourcenode
|
||||||
lift = self.lifts[region]
|
lift = self.lifts[region]
|
||||||
|
|
||||||
def clean(lift):
|
def clean(lift):
|
||||||
ba.animate(lift["cleaner"], 'input0', {
|
bs.animate(lift["cleaner"], 'input0', {
|
||||||
0: -19 if lift["leftLift"] else 19,
|
0: -19 if lift["leftLift"] else 19,
|
||||||
2: -16 if lift["leftLift"] else 16,
|
2: -16 if lift["leftLift"] else 16,
|
||||||
4.3: -19 if lift["leftLift"] else 19
|
4.3: -19 if lift["leftLift"] else 19
|
||||||
})
|
})
|
||||||
if lift["state"] == "origin":
|
if lift["state"] == "origin":
|
||||||
lift["state"] = "transition"
|
lift["state"] = "transition"
|
||||||
ba.animate(lift["lift"], 'input1', {
|
bs.animate(lift["lift"], 'input1', {
|
||||||
0: 5.1,
|
0: 5.1,
|
||||||
1.3: 5.1,
|
1.3: 5.1,
|
||||||
6: 5+12,
|
6: 5+12,
|
||||||
9: 5+12,
|
9: 5+12,
|
||||||
15: 5.1
|
15: 5.1
|
||||||
})
|
})
|
||||||
ba.timer(16, ba.Call(lambda lift: lift.update({'state': 'end'}), lift))
|
bs.timer(16, babase.Call(lambda lift: lift.update({'state': 'end'}), lift))
|
||||||
ba.timer(12, ba.Call(clean, lift))
|
bs.timer(12, babase.Call(clean, lift))
|
||||||
|
|
||||||
def _handle_lift_disconnect(self):
|
def _handle_lift_disconnect(self):
|
||||||
region = ba.getcollision().sourcenode
|
region = bs.getcollision().sourcenode
|
||||||
lift = self.lifts[region]
|
lift = self.lifts[region]
|
||||||
if lift["state"] == 'end':
|
if lift["state"] == 'end':
|
||||||
lift["state"] = "origin"
|
lift["state"] = "origin"
|
||||||
|
|
@ -236,9 +236,9 @@ class ShimlaGame(DeathMatchGame):
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
|
|
||||||
for i in range(0, 21):
|
for i in range(0, 21):
|
||||||
ba.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
bs.newnode('region', attrs={'position': (x, y, -5.52), 'scale': (0.2, 0.1, 6),
|
||||||
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (x, y, -5.52), 'color': (
|
||||||
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.2, 0.1, 2)})
|
1, 1, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.2, 0.1, 2)})
|
||||||
if backslash:
|
if backslash:
|
||||||
x = x+0.1
|
x = x+0.1
|
||||||
|
|
@ -292,7 +292,7 @@ class mapdefs:
|
||||||
0.5245740665, 0.5245740665, 0.01941146064)
|
0.5245740665, 0.5245740665, 0.01941146064)
|
||||||
|
|
||||||
|
|
||||||
class CreativeThoughts(ba.Map):
|
class CreativeThoughts(bs.Map):
|
||||||
"""Freaking map by smoothy."""
|
"""Freaking map by smoothy."""
|
||||||
|
|
||||||
defs = mapdefs
|
defs = mapdefs
|
||||||
|
|
@ -313,26 +313,26 @@ class CreativeThoughts(ba.Map):
|
||||||
@classmethod
|
@classmethod
|
||||||
def on_preload(cls) -> Any:
|
def on_preload(cls) -> Any:
|
||||||
data: Dict[str, Any] = {
|
data: Dict[str, Any] = {
|
||||||
'model': ba.getmodel('alwaysLandLevel'),
|
'mesh': bs.getmesh('alwaysLandLevel'),
|
||||||
'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
|
'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
|
||||||
'bgmodel': ba.getmodel('alwaysLandBG'),
|
'bgmesh': bs.getmesh('alwaysLandBG'),
|
||||||
'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
|
'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
|
||||||
'tex': ba.gettexture('alwaysLandLevelColor'),
|
'tex': bs.gettexture('alwaysLandLevelColor'),
|
||||||
'bgtex': ba.gettexture('alwaysLandBGColor'),
|
'bgtex': bs.gettexture('alwaysLandBGColor'),
|
||||||
'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
|
'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
|
||||||
'vr_fill_mound_tex': ba.gettexture('vrFillMound')
|
'vr_fill_mound_tex': bs.gettexture('vrFillMound')
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_music_type(cls) -> ba.MusicType:
|
def get_music_type(cls) -> bs.MusicType:
|
||||||
return ba.MusicType.FLYING
|
return bs.MusicType.FLYING
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
self._fake_wall_material = ba.Material()
|
self._fake_wall_material = bs.Material()
|
||||||
self._real_wall_material = ba.Material()
|
self._real_wall_material = bs.Material()
|
||||||
self._fake_wall_material.add_actions(
|
self._fake_wall_material.add_actions(
|
||||||
conditions=(('they_are_younger_than', 9000), 'and',
|
conditions=(('they_are_younger_than', 9000), 'and',
|
||||||
('they_have_material', shared.player_material)),
|
('they_have_material', shared.player_material)),
|
||||||
|
|
@ -348,29 +348,29 @@ class CreativeThoughts(ba.Map):
|
||||||
('modify_part_collision', 'physical', True)
|
('modify_part_collision', 'physical', True)
|
||||||
|
|
||||||
))
|
))
|
||||||
self.background = ba.newnode(
|
self.background = bs.newnode(
|
||||||
'terrain',
|
'terrain',
|
||||||
attrs={
|
attrs={
|
||||||
'model': self.preloaddata['bgmodel'],
|
'mesh': self.preloaddata['bgmesh'],
|
||||||
'lighting': False,
|
'lighting': False,
|
||||||
'background': True,
|
'background': True,
|
||||||
'color_texture': ba.gettexture("rampageBGColor")
|
'color_texture': bs.gettexture("rampageBGColor")
|
||||||
})
|
})
|
||||||
|
|
||||||
self.leftwall = ba.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
self.leftwall = bs.newnode('region', attrs={'position': (-17.75152479, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.rightwall = ba.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
self.rightwall = bs.newnode('region', attrs={'position': (17.75, 13, -5.52), 'scale': (
|
||||||
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
0.1, 15.5, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
self.topwall = ba.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
self.topwall = bs.newnode('region', attrs={'position': (0, 21.0, -5.52), 'scale': (
|
||||||
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
35.4, 0.2, 2), 'type': 'box', 'materials': [shared.footing_material, self._real_wall_material]})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (-17.75152479, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (17.75, 13, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (0.1, 15.5, 2)})
|
||||||
ba.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
bs.newnode('locator', attrs={'shape': 'box', 'position': (0, 21.0, -5.52), 'color': (
|
||||||
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
0, 0, 0), 'opacity': 1, 'draw_beauty': True, 'additive': False, 'size': (35.4, 0.2, 2)})
|
||||||
|
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.happy_thoughts_mode = True
|
gnode.happy_thoughts_mode = True
|
||||||
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
gnode.shadow_offset = (0.0, 8.0, 5.0)
|
||||||
gnode.tint = (1.3, 1.23, 1.0)
|
gnode.tint = (1.3, 1.23, 1.0)
|
||||||
|
|
@ -381,9 +381,9 @@ class CreativeThoughts(ba.Map):
|
||||||
self.is_flying = True
|
self.is_flying = True
|
||||||
|
|
||||||
# throw out some tips on flying
|
# throw out some tips on flying
|
||||||
txt = ba.newnode('text',
|
txt = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': ba.Lstr(resource='pressJumpToFlyText'),
|
'text': babase.Lstr(resource='pressJumpToFlyText'),
|
||||||
'scale': 1.2,
|
'scale': 1.2,
|
||||||
'maxwidth': 800,
|
'maxwidth': 800,
|
||||||
'position': (0, 200),
|
'position': (0, 200),
|
||||||
|
|
@ -392,7 +392,7 @@ class CreativeThoughts(ba.Map):
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
'v_attach': 'bottom'
|
'v_attach': 'bottom'
|
||||||
})
|
})
|
||||||
cmb = ba.newnode('combine',
|
cmb = bs.newnode('combine',
|
||||||
owner=txt,
|
owner=txt,
|
||||||
attrs={
|
attrs={
|
||||||
'size': 4,
|
'size': 4,
|
||||||
|
|
@ -400,12 +400,12 @@ class CreativeThoughts(ba.Map):
|
||||||
'input1': 0.9,
|
'input1': 0.9,
|
||||||
'input2': 0.0
|
'input2': 0.0
|
||||||
})
|
})
|
||||||
ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
|
||||||
cmb.connectattr('output', txt, 'color')
|
cmb.connectattr('output', txt, 'color')
|
||||||
ba.timer(10.0, txt.delete)
|
bs.timer(10.0, txt.delete)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ba._map.register_map(CreativeThoughts)
|
bs._map.register_map(CreativeThoughts)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# SimonSays
|
# SimonSays
|
||||||
# you had really better do what Simon says...
|
# you had really better do what Simon says...
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
@ -8,19 +9,21 @@ from typing import TYPE_CHECKING
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Union, Sequence
|
from typing import Any, Union, Sequence
|
||||||
|
|
||||||
from ba import _gameutils
|
from bascenev1 import _gameutils
|
||||||
import ba
|
import babase
|
||||||
|
import bauiv1 as bui
|
||||||
|
import bascenev1 as bs
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
class CustomText(ba.Actor):
|
class CustomText(bs.Actor):
|
||||||
"""Text that pops up above a position to denote something special.
|
"""Text that pops up above a position to denote something special.
|
||||||
|
|
||||||
category: Gameplay Classes
|
category: Gameplay Classes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
text: Union[str, ba.Lstr],
|
text: Union[str, babase.Lstr],
|
||||||
position: Sequence[float] = (0.0, 0.0, 0.0),
|
position: Sequence[float] = (0.0, 0.0, 0.0),
|
||||||
color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
|
color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
|
||||||
random_offset: float = 0.5,
|
random_offset: float = 0.5,
|
||||||
|
|
@ -34,7 +37,7 @@ class CustomText(ba.Actor):
|
||||||
(0.5 - random.random()), position[1] + offset[0] +
|
(0.5 - random.random()), position[1] + offset[0] +
|
||||||
random_offset * (0.5 - random.random()), position[2] +
|
random_offset * (0.5 - random.random()), position[2] +
|
||||||
offset[0] + random_offset * (0.5 - random.random()))
|
offset[0] + random_offset * (0.5 - random.random()))
|
||||||
self.node = ba.newnode('text',
|
self.node = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': text,
|
'text': text,
|
||||||
'in_world': True,
|
'in_world': True,
|
||||||
|
|
@ -42,27 +45,27 @@ class CustomText(ba.Actor):
|
||||||
'flatness': 1.0,
|
'flatness': 1.0,
|
||||||
'h_align': 'center'}, delegate=self)
|
'h_align': 'center'}, delegate=self)
|
||||||
lifespan = duration
|
lifespan = duration
|
||||||
ba.animate(
|
bs.animate(
|
||||||
self.node, 'scale', {
|
self.node, 'scale', {
|
||||||
0: 0.0,
|
0: 0.0,
|
||||||
lifespan * 0.11: 0.020 * 0.7 * scale,
|
lifespan * 0.11: 0.020 * 0.7 * scale,
|
||||||
lifespan * 0.16: 0.013 * 0.7 * scale,
|
lifespan * 0.16: 0.013 * 0.7 * scale,
|
||||||
lifespan * 0.25: 0.014 * 0.7 * scale
|
lifespan * 0.25: 0.014 * 0.7 * scale
|
||||||
})
|
})
|
||||||
self._tcombine = ba.newnode('combine',
|
self._tcombine = bs.newnode('combine',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input0': pos[0],
|
'input0': pos[0],
|
||||||
'input2': pos[2],
|
'input2': pos[2],
|
||||||
'size': 3
|
'size': 3
|
||||||
})
|
})
|
||||||
ba.animate(self._tcombine, 'input1', {
|
bs.animate(self._tcombine, 'input1', {
|
||||||
0: pos[1] + 1.5,
|
0: pos[1] + 1.5,
|
||||||
lifespan: pos[1] + 2.0
|
lifespan: pos[1] + 2.0
|
||||||
})
|
})
|
||||||
self._tcombine.connectattr('output', self.node, 'position')
|
self._tcombine.connectattr('output', self.node, 'position')
|
||||||
# fade our opacity in/out
|
# fade our opacity in/out
|
||||||
self._combine = ba.newnode('combine',
|
self._combine = bs.newnode('combine',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input0': color[0],
|
'input0': color[0],
|
||||||
|
|
@ -71,64 +74,64 @@ class CustomText(ba.Actor):
|
||||||
'size': 4
|
'size': 4
|
||||||
})
|
})
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
ba.animate(
|
bs.animate(
|
||||||
self._combine, 'input' + str(i), {
|
self._combine, 'input' + str(i), {
|
||||||
0.13 * lifespan: color[i],
|
0.13 * lifespan: color[i],
|
||||||
0.18 * lifespan: 4.0 * color[i],
|
0.18 * lifespan: 4.0 * color[i],
|
||||||
0.22 * lifespan: color[i]})
|
0.22 * lifespan: color[i]})
|
||||||
ba.animate(self._combine, 'input3', {
|
bs.animate(self._combine, 'input3', {
|
||||||
0: 0,
|
0: 0,
|
||||||
0.1 * lifespan: color[3],
|
0.1 * lifespan: color[3],
|
||||||
0.7 * lifespan: color[3],
|
0.7 * lifespan: color[3],
|
||||||
lifespan: 0})
|
lifespan: 0})
|
||||||
self._combine.connectattr('output', self.node, 'color')
|
self._combine.connectattr('output', self.node, 'color')
|
||||||
self._die_timer = ba.Timer(
|
self._die_timer = bs.Timer(
|
||||||
lifespan, ba.WeakCall(self.handlemessage, ba.DieMessage()))
|
lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage()))
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
assert not self.expired
|
assert not self.expired
|
||||||
if isinstance(msg, ba.DieMessage):
|
if isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
self.node.delete()
|
self.node.delete()
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
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:
|
||||||
self.score = 0
|
self.score = 0
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.score = 0
|
self.score = 0
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class SimonSays(ba.TeamGameActivity[Player, Team]):
|
class SimonSays(bs.TeamGameActivity[Player, Team]):
|
||||||
name = "Simon Says"
|
name = "Simon Says"
|
||||||
description = "You have to better do what Simon says!"
|
description = "You have to better do what Simon says!"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_settings(cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
|
def get_available_settings(cls, sessiontype: Type[bs.Session]) -> List[babase.Setting]:
|
||||||
settings = [
|
settings = [
|
||||||
ba.BoolSetting("Epic Mode", default=False),
|
bs.BoolSetting("Epic Mode", default=False),
|
||||||
ba.BoolSetting("Enable Jumping", default=False),
|
bs.BoolSetting("Enable Jumping", default=False),
|
||||||
ba.BoolSetting("Enable Punching", default=False),
|
bs.BoolSetting("Enable Punching", default=False),
|
||||||
ba.BoolSetting("Enable Picking Up", default=False),
|
bs.BoolSetting("Enable Picking Up", default=False),
|
||||||
ba.IntChoiceSetting("Timer Speed",
|
bs.IntChoiceSetting("Timer Speed",
|
||||||
choices=[("Snaily", 1200),
|
choices=[("Snaily", 1200),
|
||||||
("Slow", 900),
|
("Slow", 900),
|
||||||
("Normal", 655),
|
("Normal", 655),
|
||||||
("Fast", 544),
|
("Fast", 544),
|
||||||
("Turbo", 460)], default=655),
|
("Turbo", 460)], default=655),
|
||||||
|
|
||||||
ba.FloatChoiceSetting("Text Duration",
|
bs.FloatChoiceSetting("Text Duration",
|
||||||
choices=[("Slow", 2.5),
|
choices=[("Slow", 2.5),
|
||||||
("Normal", 1.5),
|
("Normal", 1.5),
|
||||||
("Mediocre", 1.0),
|
("Mediocre", 1.0),
|
||||||
|
|
@ -136,12 +139,12 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
@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 ["Courtyard"]
|
return ["Courtyard"]
|
||||||
|
|
||||||
@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.FreeForAllSession)
|
return issubclass(sessiontype, bs.FreeForAllSession)
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
|
|
@ -157,7 +160,7 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
self.counter_loop = None
|
self.counter_loop = None
|
||||||
self.time = 5000
|
self.time = 5000
|
||||||
self._r1 = 2
|
self._r1 = 2
|
||||||
self.ct_text = ba.newnode('text', attrs={
|
self.ct_text = bs.newnode('text', attrs={
|
||||||
'in_world': True,
|
'in_world': True,
|
||||||
'text': '......',
|
'text': '......',
|
||||||
'shadow': 1.0,
|
'shadow': 1.0,
|
||||||
|
|
@ -165,44 +168,44 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
'flatness': 0.5,
|
'flatness': 0.5,
|
||||||
'position': (-5.627144702, 3.3275475, -9.572879116),
|
'position': (-5.627144702, 3.3275475, -9.572879116),
|
||||||
'scale': 0.05})
|
'scale': 0.05})
|
||||||
self.n1 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, -6),
|
self.n1 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, -6),
|
||||||
'color': (1, 0, 0), 'opacity': 0.5,
|
'color': (1, 0, 0), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n2 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, -6),
|
self.n2 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, -6),
|
||||||
'color': (0, 1, 0), 'opacity': 0.5,
|
'color': (0, 1, 0), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n3 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, -6),
|
self.n3 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, -6),
|
||||||
'color': (0, 0, 1), 'opacity': 0.5,
|
'color': (0, 0, 1), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n4 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, -2),
|
self.n4 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, -2),
|
||||||
'color': (1, 1, 0), 'opacity': 0.5,
|
'color': (1, 1, 0), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n5 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, -2),
|
self.n5 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, -2),
|
||||||
'color': (0, 1, 1), 'opacity': 0.5,
|
'color': (0, 1, 1), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n6 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, -2),
|
self.n6 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, -2),
|
||||||
'color': (1, 0, 1), 'opacity': 0.5,
|
'color': (1, 0, 1), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n7 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, 2),
|
self.n7 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (-4, 0, 2),
|
||||||
'color': (.5, .5, .5), 'opacity': 0.5,
|
'color': (.5, .5, .5), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n8 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, 2),
|
self.n8 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (0, 0, 2),
|
||||||
'color': (.5, .325, 0), 'opacity': 0.5,
|
'color': (.5, .325, 0), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.n9 = ba.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, 2),
|
self.n9 = bs.newnode('locator', attrs={'shape': 'circle', 'position': (4, 0, 2),
|
||||||
'color': (1, 1, 1), 'opacity': 0.5,
|
'color': (1, 1, 1), 'opacity': 0.5,
|
||||||
'draw_beauty': True, 'additive': True})
|
'draw_beauty': True, 'additive': True})
|
||||||
self.options = ["red", "green", "blue", "yellow", "teal", "purple", "gray", "orange",
|
self.options = ["red", "green", "blue", "yellow", "teal", "purple", "gray", "orange",
|
||||||
"white", "top", "bottom", "middle row", "left", "right", "center column", "outside"]
|
"white", "top", "bottom", "middle row", "left", "right", "center column", "outside"]
|
||||||
self.default_music = ba.MusicType.FLAG_CATCHER
|
self.default_music = bs.MusicType.FLAG_CATCHER
|
||||||
|
|
||||||
def get_instance_description(self) -> str:
|
def get_instance_description(self) -> str:
|
||||||
return 'Follow the commands... but only when \"Simon says!"'
|
return 'Follow the commands... but only when \"Simon says!"'
|
||||||
|
|
||||||
def on_player_join(self, player: Player) -> None:
|
def on_player_join(self, player: Player) -> None:
|
||||||
if self.has_begun():
|
if self.has_begun():
|
||||||
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
|
||||||
|
|
@ -227,11 +230,11 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
player.score = 0
|
player.score = 0
|
||||||
# check for immediate end if theres only 1 player
|
# check for immediate end if theres only 1 player
|
||||||
if len(self.players) == 1:
|
if len(self.players) == 1:
|
||||||
ba.timer(4000, lambda: self.check_end(), timeformat=ba.TimeFormat.MILLISECONDS)
|
bs.timer(4000/1000, lambda: self.check_end())
|
||||||
else:
|
else:
|
||||||
ba.timer(6000, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS)
|
bs.timer(6000/1000, self.call_round)
|
||||||
|
|
||||||
def spawn_player(self, player: PlayerType) -> ba.Actor:
|
def spawn_player(self, player: PlayerT) -> bs.Actor:
|
||||||
assert player
|
assert player
|
||||||
spaz = self.spawn_player_spaz(player, position=(
|
spaz = self.spawn_player_spaz(player, position=(
|
||||||
0 + random.uniform(-3.6, 3.6), 2.9, -2 + random.uniform(-3.6, 3.6)))
|
0 + random.uniform(-3.6, 3.6), 2.9, -2 + random.uniform(-3.6, 3.6)))
|
||||||
|
|
@ -291,12 +294,11 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
self.string = "0"
|
self.string = "0"
|
||||||
self.ct_text.text = self.string
|
self.ct_text.text = self.string
|
||||||
self.counter_loop = None
|
self.counter_loop = None
|
||||||
ba.timer(1, dummy_check, timeformat=ba.TimeFormat.MILLISECONDS)
|
bs.timer(1/1000, dummy_check)
|
||||||
else:
|
else:
|
||||||
self.ct_text.text = str(self.now)
|
self.ct_text.text = str(self.now)
|
||||||
ba.playsound(ba.getsound('tick'))
|
bs.getsound('tick').play()
|
||||||
self.counter_loop = ba.Timer(self.speed, set_counter,
|
self.counter_loop = bs.Timer(self.speed/1000, set_counter, repeat=True)
|
||||||
timeformat=ba.TimeFormat.MILLISECONDS, repeat=True)
|
|
||||||
|
|
||||||
def check_round(self) -> None:
|
def check_round(self) -> None:
|
||||||
if self.ended:
|
if self.ended:
|
||||||
|
|
@ -307,8 +309,8 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
player.actor.node.position_center) else False
|
player.actor.node.position_center) else False
|
||||||
if ((self.simon and safe == False) or ((not self.simon) and safe == True)):
|
if ((self.simon and safe == False) or ((not self.simon) and safe == True)):
|
||||||
player.team.score = self.round_num
|
player.team.score = self.round_num
|
||||||
player.actor.handlemessage(ba.DieMessage())
|
player.actor.handlemessage(bs.DieMessage())
|
||||||
ba.timer(1633, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS)
|
bs.timer(1633/1000, self.call_round)
|
||||||
|
|
||||||
def in_circle(self, pos) -> None:
|
def in_circle(self, pos) -> None:
|
||||||
circles = []
|
circles = []
|
||||||
|
|
@ -349,14 +351,14 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
return circles
|
return circles
|
||||||
|
|
||||||
def handlemessage(self, msg) -> None:
|
def handlemessage(self, msg) -> None:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
self.check_end()
|
self.check_end()
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
self.ended = True
|
self.ended = True
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.score)
|
results.set_team_score(team, team.score)
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
@ -367,4 +369,4 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
i += 1
|
i += 1
|
||||||
if i <= 2:
|
if i <= 2:
|
||||||
ba.timer(0.6, lambda: self.end_game())
|
bs.timer(0.6, lambda: self.end_game())
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
# y me (: itsre3
|
# y me (: itsre3
|
||||||
# =>2<=
|
# =>2<=
|
||||||
|
|
@ -5,7 +6,7 @@
|
||||||
#
|
#
|
||||||
"""Defines Race mini-game."""
|
"""Defines Race 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
|
||||||
|
|
@ -14,17 +15,17 @@ import random
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
import _ba
|
import bascenev1 as bs
|
||||||
from bastd.actor.bomb import Bomb
|
from bascenev1lib.actor.bomb import Bomb
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import (Any, Type, Tuple, List, Sequence, Optional, Dict,
|
from typing import (Any, Type, Tuple, List, Sequence, Optional, Dict,
|
||||||
Union)
|
Union)
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -34,7 +35,7 @@ class RaceMine:
|
||||||
mine: Optional[Bomb]
|
mine: Optional[Bomb]
|
||||||
|
|
||||||
|
|
||||||
class RaceRegion(ba.Actor):
|
class RaceRegion(bs.Actor):
|
||||||
"""Region used to track progress during a race."""
|
"""Region used to track progress during a race."""
|
||||||
|
|
||||||
def __init__(self, pt: Sequence[float], index: int):
|
def __init__(self, pt: Sequence[float], index: int):
|
||||||
|
|
@ -43,7 +44,7 @@ class RaceRegion(ba.Actor):
|
||||||
assert isinstance(activity, RaceGame)
|
assert isinstance(activity, RaceGame)
|
||||||
self.pos = pt
|
self.pos = pt
|
||||||
self.index = index
|
self.index = index
|
||||||
self.node = ba.newnode(
|
self.node = bs.newnode(
|
||||||
'region',
|
'region',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
|
|
@ -54,11 +55,11 @@ class RaceRegion(ba.Actor):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.distance_txt: Optional[ba.Node] = None
|
self.distance_txt: Optional[bs.Node] = None
|
||||||
self.last_region = 0
|
self.last_region = 0
|
||||||
self.lap = 0
|
self.lap = 0
|
||||||
self.distance = 0.0
|
self.distance = 0.0
|
||||||
|
|
@ -66,7 +67,7 @@ class Player(ba.Player['Team']):
|
||||||
self.rank: Optional[int] = None
|
self.rank: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -75,22 +76,22 @@ class Team(ba.Team[Player]):
|
||||||
self.finished = False
|
self.finished = False
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
class SleepRaceGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Game of racing around a track."""
|
"""Game of racing around a track."""
|
||||||
|
|
||||||
name = 'Sleep Race'
|
name = 'Sleep Race'
|
||||||
description = 'Can you run while sleeping?'
|
description = 'Can you run while sleeping?'
|
||||||
scoreconfig = ba.ScoreConfig(label='Time',
|
scoreconfig = bs.ScoreConfig(label='Time',
|
||||||
lower_is_better=True,
|
lower_is_better=True,
|
||||||
scoretype=ba.ScoreType.MILLISECONDS)
|
scoretype=bs.ScoreType.MILLISECONDS)
|
||||||
|
|
||||||
@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('Laps', min_value=1, default=2, increment=1),
|
bs.IntSetting('Laps', min_value=1, default=2, increment=1),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
default=0,
|
default=0,
|
||||||
choices=[
|
choices=[
|
||||||
|
|
@ -102,7 +103,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('20 Minutes', 1200),
|
('20 Minutes', 1200),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Mine Spawning',
|
'Mine Spawning',
|
||||||
default=4000,
|
default=4000,
|
||||||
choices=[
|
choices=[
|
||||||
|
|
@ -112,7 +113,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('2 Seconds', 2000),
|
('2 Seconds', 2000),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Bomb Spawning',
|
'Bomb Spawning',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -123,7 +124,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=2000,
|
default=2000,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Knockout Time',
|
'Knockout Time',
|
||||||
choices=[
|
choices=[
|
||||||
('8 Seconds', 8000),
|
('8 Seconds', 8000),
|
||||||
|
|
@ -131,48 +132,48 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=5000,
|
default=5000,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
ba.BoolSetting('Credits', default=True),
|
bs.BoolSetting('Credits', default=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
# We have some specific settings in teams mode.
|
# We have some specific settings in teams mode.
|
||||||
if issubclass(sessiontype, ba.DualTeamSession):
|
if issubclass(sessiontype, bs.DualTeamSession):
|
||||||
settings.append(
|
settings.append(
|
||||||
ba.BoolSetting('Entire Team Must Finish', default=False))
|
bs.BoolSetting('Entire Team Must Finish', 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.MultiTeamSession)
|
return issubclass(sessiontype, bs.MultiTeamSession)
|
||||||
|
|
||||||
@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('race')
|
return bs.app.classic.getmaps('race')
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
self._race_started = False
|
self._race_started = False
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._score_sound = ba.getsound('score')
|
self._score_sound = bs.getsound('score')
|
||||||
self._swipsound = ba.getsound('swip')
|
self._swipsound = bs.getsound('swip')
|
||||||
self._last_team_time: Optional[float] = None
|
self._last_team_time: Optional[float] = None
|
||||||
self._front_race_region: Optional[int] = None
|
self._front_race_region: Optional[int] = None
|
||||||
self._nub_tex = ba.gettexture('nub')
|
self._nub_tex = bs.gettexture('nub')
|
||||||
self._beep_1_sound = ba.getsound('raceBeep1')
|
self._beep_1_sound = bs.getsound('raceBeep1')
|
||||||
self._beep_2_sound = ba.getsound('raceBeep2')
|
self._beep_2_sound = bs.getsound('raceBeep2')
|
||||||
self.race_region_material: Optional[ba.Material] = None
|
self.race_region_material: Optional[bs.Material] = None
|
||||||
self._regions: List[RaceRegion] = []
|
self._regions: List[RaceRegion] = []
|
||||||
self._team_finish_pts: Optional[int] = None
|
self._team_finish_pts: Optional[int] = None
|
||||||
self._time_text: Optional[ba.Actor] = None
|
self._time_text: Optional[bs.Actor] = None
|
||||||
self._cd_text: Optional[ba.Actor] = None
|
self._cd_text: Optional[bs.Actor] = None
|
||||||
self._timer: Optional[OnScreenTimer] = None
|
self._timer: Optional[OnScreenTimer] = None
|
||||||
self._race_mines: Optional[List[RaceMine]] = None
|
self._race_mines: Optional[List[RaceMine]] = None
|
||||||
self._race_mine_timer: Optional[ba.Timer] = None
|
self._race_mine_timer: Optional[bs.Timer] = None
|
||||||
self._scoreboard_timer: Optional[ba.Timer] = None
|
self._scoreboard_timer: Optional[bs.Timer] = None
|
||||||
self._player_order_update_timer: Optional[ba.Timer] = None
|
self._player_order_update_timer: Optional[bs.Timer] = None
|
||||||
self._start_lights: Optional[List[ba.Node]] = None
|
self._start_lights: Optional[List[bs.Node]] = None
|
||||||
self._bomb_spawn_timer: Optional[ba.Timer] = None
|
self._bomb_spawn_timer: Optional[bs.Timer] = None
|
||||||
self._knockout_timer: Optional[ba.Timer] = None
|
self._knockout_timer: Optional[bs.Timer] = None
|
||||||
self._laps = int(settings['Laps'])
|
self._laps = int(settings['Laps'])
|
||||||
self._entire_team_must_finish = bool(
|
self._entire_team_must_finish = bool(
|
||||||
settings.get('Entire Team Must Finish', False))
|
settings.get('Entire Team Must Finish', False))
|
||||||
|
|
@ -185,11 +186,11 @@ class SleepRaceGame(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_RACE
|
self.default_music = (bs.MusicType.EPIC_RACE
|
||||||
if self._epic_mode else ba.MusicType.RACE)
|
if self._epic_mode else bs.MusicType.RACE)
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
t_str = ' Your entire team has to finish.'
|
t_str = ' Your entire team has to finish.'
|
||||||
else:
|
else:
|
||||||
|
|
@ -208,7 +209,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
super().on_transition_in()
|
super().on_transition_in()
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
pts = self.map.get_def_points('race_point')
|
pts = self.map.get_def_points('race_point')
|
||||||
mat = self.race_region_material = ba.Material()
|
mat = self.race_region_material = bs.Material()
|
||||||
mat.add_actions(conditions=('they_have_material',
|
mat.add_actions(conditions=('they_have_material',
|
||||||
shared.player_material),
|
shared.player_material),
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -224,28 +225,28 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
assert player.actor.node
|
assert player.actor.node
|
||||||
pos = player.actor.node.position
|
pos = player.actor.node.position
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': pos,
|
'position': pos,
|
||||||
'color': (1, 1, 0),
|
'color': (1, 1, 0),
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'radius': 0.4
|
'radius': 0.4
|
||||||
})
|
})
|
||||||
ba.timer(0.5, light.delete)
|
bs.timer(0.5, light.delete)
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.1: 1.0 * scale, 0.5: 0})
|
bs.animate(light, 'intensity', {0: 0, 0.1: 1.0 * scale, 0.5: 0})
|
||||||
|
|
||||||
def _handle_race_point_collide(self) -> None:
|
def _handle_race_point_collide(self) -> None:
|
||||||
# FIXME: Tidy this up.
|
# FIXME: Tidy this up.
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-nested-blocks
|
# pylint: disable=too-many-nested-blocks
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
try:
|
try:
|
||||||
region = collision.sourcenode.getdelegate(RaceRegion, True)
|
region = collision.sourcenode.getdelegate(RaceRegion, True)
|
||||||
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
||||||
True).getplayer(
|
True).getplayer(
|
||||||
Player, True)
|
Player, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
|
|
||||||
last_region = player.last_region
|
last_region = player.last_region
|
||||||
|
|
@ -259,8 +260,8 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if this_region > last_region + 2:
|
if this_region > last_region + 2:
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
assert player.actor
|
assert player.actor
|
||||||
player.actor.handlemessage(ba.DieMessage())
|
player.actor.handlemessage(bs.DieMessage())
|
||||||
ba.screenmessage(ba.Lstr(
|
bs.broadcastmessage(babase.Lstr(
|
||||||
translate=('statements', 'Killing ${NAME} for'
|
translate=('statements', 'Killing ${NAME} for'
|
||||||
' skipping part of the track!'),
|
' skipping part of the track!'),
|
||||||
subs=[('${NAME}', player.getname(full=True))]),
|
subs=[('${NAME}', player.getname(full=True))]),
|
||||||
|
|
@ -279,7 +280,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# In teams mode with all-must-finish on, the team lap
|
# In teams mode with all-must-finish on, the team lap
|
||||||
# value is the min of all team players.
|
# value is the min of all team players.
|
||||||
# Otherwise its the max.
|
# Otherwise its the max.
|
||||||
if isinstance(self.session, ba.DualTeamSession
|
if isinstance(self.session, bs.DualTeamSession
|
||||||
) and self._entire_team_must_finish:
|
) and self._entire_team_must_finish:
|
||||||
team.lap = min([p.lap for p in team.players])
|
team.lap = min([p.lap for p in team.players])
|
||||||
else:
|
else:
|
||||||
|
|
@ -290,7 +291,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# In teams mode, hand out points based on the order
|
# In teams mode, hand out points based on the order
|
||||||
# players come in.
|
# players come in.
|
||||||
if isinstance(self.session, ba.DualTeamSession):
|
if isinstance(self.session, bs.DualTeamSession):
|
||||||
assert self._team_finish_pts is not None
|
assert self._team_finish_pts is not None
|
||||||
if self._team_finish_pts > 0:
|
if self._team_finish_pts > 0:
|
||||||
self.stats.player_scored(player,
|
self.stats.player_scored(player,
|
||||||
|
|
@ -303,7 +304,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.finished = True
|
player.finished = True
|
||||||
assert player.actor
|
assert player.actor
|
||||||
player.actor.handlemessage(
|
player.actor.handlemessage(
|
||||||
ba.DieMessage(immediate=True))
|
bs.DieMessage(immediate=True))
|
||||||
|
|
||||||
# Makes sure noone behind them passes them in rank
|
# Makes sure noone behind them passes them in rank
|
||||||
# while finishing.
|
# while finishing.
|
||||||
|
|
@ -311,26 +312,26 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# If the whole team has finished the race.
|
# If the whole team has finished the race.
|
||||||
if team.lap == self._laps:
|
if team.lap == self._laps:
|
||||||
ba.playsound(self._score_sound)
|
self._score_sound.play()
|
||||||
player.team.finished = True
|
player.team.finished = True
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
elapsed = ba.time() - self._timer.getstarttime()
|
elapsed = bs.time() - self._timer.getstarttime()
|
||||||
self._last_team_time = player.team.time = elapsed
|
self._last_team_time = player.team.time = elapsed
|
||||||
self._check_end_game()
|
self._check_end_game()
|
||||||
|
|
||||||
# Team has yet to finish.
|
# Team has yet to finish.
|
||||||
else:
|
else:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
|
|
||||||
# They've just finished a lap but not the race.
|
# They've just finished a lap but not the race.
|
||||||
else:
|
else:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
self._flash_player(player, 0.3)
|
self._flash_player(player, 0.3)
|
||||||
|
|
||||||
# Print their lap number over their head.
|
# Print their lap number over their head.
|
||||||
try:
|
try:
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
mathnode = ba.newnode('math',
|
mathnode = bs.newnode('math',
|
||||||
owner=player.actor.node,
|
owner=player.actor.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': (0, 1.9, 0),
|
'input1': (0, 1.9, 0),
|
||||||
|
|
@ -338,12 +339,12 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
})
|
})
|
||||||
player.actor.node.connectattr(
|
player.actor.node.connectattr(
|
||||||
'torso_position', mathnode, 'input2')
|
'torso_position', mathnode, 'input2')
|
||||||
tstr = ba.Lstr(resource='lapNumberText',
|
tstr = babase.Lstr(resource='lapNumberText',
|
||||||
subs=[('${CURRENT}',
|
subs=[('${CURRENT}',
|
||||||
str(player.lap + 1)),
|
str(player.lap + 1)),
|
||||||
('${TOTAL}', str(self._laps))
|
('${TOTAL}', str(self._laps))
|
||||||
])
|
])
|
||||||
txtnode = ba.newnode('text',
|
txtnode = bs.newnode('text',
|
||||||
owner=mathnode,
|
owner=mathnode,
|
||||||
attrs={
|
attrs={
|
||||||
'text': tstr,
|
'text': tstr,
|
||||||
|
|
@ -353,15 +354,15 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'h_align': 'center'
|
'h_align': 'center'
|
||||||
})
|
})
|
||||||
mathnode.connectattr('output', txtnode, 'position')
|
mathnode.connectattr('output', txtnode, 'position')
|
||||||
ba.animate(txtnode, 'scale', {
|
bs.animate(txtnode, 'scale', {
|
||||||
0.0: 0,
|
0.0: 0,
|
||||||
0.2: 0.019,
|
0.2: 0.019,
|
||||||
2.0: 0.019,
|
2.0: 0.019,
|
||||||
2.2: 0
|
2.2: 0
|
||||||
})
|
})
|
||||||
ba.timer(2.3, mathnode.delete)
|
bs.timer(2.3, mathnode.delete)
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error printing lap.')
|
babase.print_exception('Error printing lap.')
|
||||||
|
|
||||||
def on_team_join(self, team: Team) -> None:
|
def on_team_join(self, team: Team) -> None:
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
@ -372,9 +373,9 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# A player leaving disqualifies the team if 'Entire Team Must Finish'
|
# A player leaving disqualifies the team if 'Entire Team Must Finish'
|
||||||
# is on (otherwise in teams mode everyone could just leave except the
|
# is on (otherwise in teams mode everyone could just leave except the
|
||||||
# leading player to win).
|
# leading player to win).
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
ba.screenmessage(ba.Lstr(
|
bs.broadcastmessage(babase.Lstr(
|
||||||
translate=('statements',
|
translate=('statements',
|
||||||
'${TEAM} is disqualified because ${PLAYER} left'),
|
'${TEAM} is disqualified because ${PLAYER} left'),
|
||||||
subs=[('${TEAM}', player.team.name),
|
subs=[('${TEAM}', player.team.name),
|
||||||
|
|
@ -383,18 +384,18 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.team.finished = True
|
player.team.finished = True
|
||||||
player.team.time = None
|
player.team.time = None
|
||||||
player.team.lap = 0
|
player.team.lap = 0
|
||||||
ba.playsound(ba.getsound('boo'))
|
bs.getsound('boo').play()
|
||||||
for otherplayer in player.team.players:
|
for otherplayer in player.team.players:
|
||||||
otherplayer.lap = 0
|
otherplayer.lap = 0
|
||||||
otherplayer.finished = True
|
otherplayer.finished = True
|
||||||
try:
|
try:
|
||||||
if otherplayer.actor is not None:
|
if otherplayer.actor is not None:
|
||||||
otherplayer.actor.handlemessage(ba.DieMessage())
|
otherplayer.actor.handlemessage(bs.DieMessage())
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error sending DieMessage.')
|
babase.print_exception('Error sending DieMessage.')
|
||||||
|
|
||||||
# Defer so team/player lists will be updated.
|
# Defer so team/player lists will be updated.
|
||||||
ba.pushcall(self._check_end_game)
|
babase.pushcall(self._check_end_game)
|
||||||
|
|
||||||
def _update_scoreboard(self) -> None:
|
def _update_scoreboard(self) -> None:
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
|
|
@ -402,7 +403,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if not distances:
|
if not distances:
|
||||||
teams_dist = 0.0
|
teams_dist = 0.0
|
||||||
else:
|
else:
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
teams_dist = min(distances)
|
teams_dist = min(distances)
|
||||||
else:
|
else:
|
||||||
|
|
@ -415,14 +416,14 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
show_value=False)
|
show_value=False)
|
||||||
|
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
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._team_finish_pts = 100
|
self._team_finish_pts = 100
|
||||||
if self._credits:
|
if self._credits:
|
||||||
self._cd_text = ba.NodeActor(
|
self._cd_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 0),
|
'position': (0, 0),
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -437,8 +438,8 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
}))
|
}))
|
||||||
|
|
||||||
# Throw a timer up on-screen.
|
# Throw a timer up on-screen.
|
||||||
self._time_text = ba.NodeActor(
|
self._time_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'v_attach': 'top',
|
'v_attach': 'top',
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -458,14 +459,14 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
for p in self.map.get_def_points('race_mine')
|
for p in self.map.get_def_points('race_mine')
|
||||||
]
|
]
|
||||||
if self._race_mines:
|
if self._race_mines:
|
||||||
self._race_mine_timer = ba.Timer(0.001 * self._mine_spawning,
|
self._race_mine_timer = bs.Timer(0.001 * self._mine_spawning,
|
||||||
self._update_race_mine,
|
self._update_race_mine,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
self._scoreboard_timer = ba.Timer(0.25,
|
self._scoreboard_timer = bs.Timer(0.25,
|
||||||
self._update_scoreboard,
|
self._update_scoreboard,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
self._player_order_update_timer = ba.Timer(0.25,
|
self._player_order_update_timer = bs.Timer(0.25,
|
||||||
self._update_player_order,
|
self._update_player_order,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
|
|
@ -478,30 +479,30 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
lstart = 7.1 * t_scale
|
lstart = 7.1 * t_scale
|
||||||
inc = 1.25 * t_scale
|
inc = 1.25 * t_scale
|
||||||
|
|
||||||
ba.timer(lstart, self._do_light_1)
|
bs.timer(lstart, self._do_light_1)
|
||||||
ba.timer(lstart + inc, self._do_light_2)
|
bs.timer(lstart + inc, self._do_light_2)
|
||||||
ba.timer(lstart + 2 * inc, self._do_light_3)
|
bs.timer(lstart + 2 * inc, self._do_light_3)
|
||||||
ba.timer(lstart + 3 * inc, self._start_race)
|
bs.timer(lstart + 3 * inc, self._start_race)
|
||||||
|
|
||||||
self._start_lights = []
|
self._start_lights = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
lnub = ba.newnode('image',
|
lnub = bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'texture': ba.gettexture('nub'),
|
'texture': bs.gettexture('nub'),
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
'absolute_scale': True,
|
'absolute_scale': True,
|
||||||
'position': (-75 + i * 50, light_y),
|
'position': (-75 + i * 50, light_y),
|
||||||
'scale': (50, 50),
|
'scale': (50, 50),
|
||||||
'attach': 'center'
|
'attach': 'center'
|
||||||
})
|
})
|
||||||
ba.animate(
|
bs.animate(
|
||||||
lnub, 'opacity', {
|
lnub, 'opacity', {
|
||||||
4.0 * t_scale: 0,
|
4.0 * t_scale: 0,
|
||||||
5.0 * t_scale: 1.0,
|
5.0 * t_scale: 1.0,
|
||||||
12.0 * t_scale: 1.0,
|
12.0 * t_scale: 1.0,
|
||||||
12.5 * t_scale: 0.0
|
12.5 * t_scale: 0.0
|
||||||
})
|
})
|
||||||
ba.timer(13.0 * t_scale, lnub.delete)
|
bs.timer(13.0 * t_scale, lnub.delete)
|
||||||
self._start_lights.append(lnub)
|
self._start_lights.append(lnub)
|
||||||
|
|
||||||
self._start_lights[0].color = (0.2, 0, 0)
|
self._start_lights[0].color = (0.2, 0, 0)
|
||||||
|
|
@ -512,45 +513,45 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _do_light_1(self) -> None:
|
def _do_light_1(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[0].color = (1.0, 0, 0)
|
self._start_lights[0].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_2(self) -> None:
|
def _do_light_2(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[1].color = (1.0, 0, 0)
|
self._start_lights[1].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_3(self) -> None:
|
def _do_light_3(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[2].color = (1.0, 0.3, 0)
|
self._start_lights[2].color = (1.0, 0.3, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _start_race(self) -> None:
|
def _start_race(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[3].color = (0.0, 1.0, 0)
|
self._start_lights[3].color = (0.0, 1.0, 0)
|
||||||
ba.playsound(self._beep_2_sound)
|
self._beep_2_sound.play()
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
if player.actor is not None:
|
if player.actor is not None:
|
||||||
try:
|
try:
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
player.actor.connect_controls_to_player()
|
player.actor.connect_controls_to_player()
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error in race player connects.')
|
babase.print_exception('Error in race player connects.')
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
self._timer.start()
|
self._timer.start()
|
||||||
|
|
||||||
if self._bomb_spawning != 0:
|
if self._bomb_spawning != 0:
|
||||||
self._bomb_spawn_timer = ba.Timer(0.001 * self._bomb_spawning,
|
self._bomb_spawn_timer = bs.Timer(0.001 * self._bomb_spawning,
|
||||||
self._spawn_bomb,
|
self._spawn_bomb,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
def knock_players():
|
def knock_players():
|
||||||
activity = _ba.get_foreground_host_activity()
|
activity = bs.get_foreground_host_activity()
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
for players in activity.players:
|
for players in activity.players:
|
||||||
gnode.tint = (0.5, 0.5, 0.5)
|
gnode.tint = (0.5, 0.5, 0.5)
|
||||||
node = players.actor.node
|
node = players.actor.node
|
||||||
node.handlemessage('knockout', 600.0)
|
node.handlemessage('knockout', 600.0)
|
||||||
self.text_offset = ba.newnode('math',
|
self.text_offset = bs.newnode('math',
|
||||||
owner=node,
|
owner=node,
|
||||||
attrs={'input1': (-0.5, 0.5, 0.25),
|
attrs={'input1': (-0.5, 0.5, 0.25),
|
||||||
'operation': 'add'})
|
'operation': 'add'})
|
||||||
|
|
@ -558,7 +559,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'torso_position',
|
'torso_position',
|
||||||
self.text_offset,
|
self.text_offset,
|
||||||
'input2')
|
'input2')
|
||||||
self.text = ba.newnode('text',
|
self.text = bs.newnode('text',
|
||||||
owner=node,
|
owner=node,
|
||||||
attrs={
|
attrs={
|
||||||
'h_align': 'right',
|
'h_align': 'right',
|
||||||
|
|
@ -571,12 +572,12 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'output',
|
'output',
|
||||||
self.text,
|
self.text,
|
||||||
'position')
|
'position')
|
||||||
ba.animate(self.text, 'scale', {0: 0.0, 1.0: 0.01})
|
bs.animate(self.text, 'scale', {0: 0.0, 1.0: 0.01})
|
||||||
ba.timer(2, self.text.delete)
|
bs.timer(2, self.text.delete)
|
||||||
|
|
||||||
if self._knockout_time != 0:
|
if self._knockout_time != 0:
|
||||||
knock_time = 0.001 * self._knockout_time
|
knock_time = 0.001 * self._knockout_time
|
||||||
self._knockout_timer = ba.Timer(knock_time,
|
self._knockout_timer = bs.Timer(knock_time,
|
||||||
knock_players,
|
knock_players,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
|
|
@ -586,18 +587,18 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Calc all player distances.
|
# Calc all player distances.
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
pos: Optional[ba.Vec3]
|
pos: Optional[babase.Vec3]
|
||||||
try:
|
try:
|
||||||
pos = player.position
|
pos = player.position
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
pos = None
|
pos = None
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
r_index = player.last_region
|
r_index = player.last_region
|
||||||
rg1 = self._regions[r_index]
|
rg1 = self._regions[r_index]
|
||||||
r1pt = ba.Vec3(rg1.pos[:3])
|
r1pt = babase.Vec3(rg1.pos[:3])
|
||||||
rg2 = self._regions[0] if r_index == len(
|
rg2 = self._regions[0] if r_index == len(
|
||||||
self._regions) - 1 else self._regions[r_index + 1]
|
self._regions) - 1 else self._regions[r_index + 1]
|
||||||
r2pt = ba.Vec3(rg2.pos[:3])
|
r2pt = babase.Vec3(rg2.pos[:3])
|
||||||
r2dist = (pos - r2pt).length()
|
r2dist = (pos - r2pt).length()
|
||||||
amt = 1.0 - (r2dist / (r2pt - r1pt).length())
|
amt = 1.0 - (r2dist / (r2pt - r1pt).length())
|
||||||
amt = player.lap + (r_index + amt) * (1.0 / len(self._regions))
|
amt = player.lap + (r_index + amt) * (1.0 / len(self._regions))
|
||||||
|
|
@ -628,8 +629,8 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
(-region_scale * pos[5], region_scale * pos[5]))
|
(-region_scale * pos[5], region_scale * pos[5]))
|
||||||
pos = (pos[0] + random.uniform(*x_range), pos[1] + 1.0,
|
pos = (pos[0] + random.uniform(*x_range), pos[1] + 1.0,
|
||||||
pos[2] + random.uniform(*z_range))
|
pos[2] + random.uniform(*z_range))
|
||||||
ba.timer(random.uniform(0.0, 2.0),
|
bs.timer(random.uniform(0.0, 2.0),
|
||||||
ba.WeakCall(self._spawn_bomb_at_pos, pos))
|
bs.WeakCall(self._spawn_bomb_at_pos, pos))
|
||||||
|
|
||||||
def _spawn_bomb_at_pos(self, pos: Sequence[float]) -> None:
|
def _spawn_bomb_at_pos(self, pos: Sequence[float]) -> None:
|
||||||
if self.has_ended():
|
if self.has_ended():
|
||||||
|
|
@ -645,15 +646,15 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _flash_mine(self, i: int) -> None:
|
def _flash_mine(self, i: int) -> None:
|
||||||
assert self._race_mines is not None
|
assert self._race_mines is not None
|
||||||
rmine = self._race_mines[i]
|
rmine = self._race_mines[i]
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': rmine.point[:3],
|
'position': rmine.point[:3],
|
||||||
'color': (1, 0.2, 0.2),
|
'color': (1, 0.2, 0.2),
|
||||||
'radius': 0.1,
|
'radius': 0.1,
|
||||||
'height_attenuated': False
|
'height_attenuated': False
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0.0: 0, 0.1: 1.0, 0.2: 0}, loop=True)
|
bs.animate(light, 'intensity', {0.0: 0, 0.1: 1.0, 0.2: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
def _update_race_mine(self) -> None:
|
def _update_race_mine(self) -> None:
|
||||||
assert self._race_mines is not None
|
assert self._race_mines is not None
|
||||||
|
|
@ -667,9 +668,9 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
assert rmine is not None
|
assert rmine is not None
|
||||||
if not rmine.mine:
|
if not rmine.mine:
|
||||||
self._flash_mine(m_index)
|
self._flash_mine(m_index)
|
||||||
ba.timer(0.95, ba.Call(self._make_mine, m_index))
|
bs.timer(0.95, babase.Call(self._make_mine, m_index))
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
if player.team.finished:
|
if player.team.finished:
|
||||||
# FIXME: This is not type-safe!
|
# FIXME: This is not type-safe!
|
||||||
# This call is expected to always return an Actor!
|
# This call is expected to always return an Actor!
|
||||||
|
|
@ -692,7 +693,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# Prevent controlling of characters before the start of the race.
|
# Prevent controlling of characters before the start of the race.
|
||||||
if not self._race_started:
|
if not self._race_started:
|
||||||
spaz.disconnect_controls_from_player()
|
spaz.disconnect_controls_from_player()
|
||||||
mathnode = ba.newnode('math',
|
mathnode = bs.newnode('math',
|
||||||
owner=spaz.node,
|
owner=spaz.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': (0, 1.4, 0),
|
'input1': (0, 1.4, 0),
|
||||||
|
|
@ -700,7 +701,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
})
|
})
|
||||||
spaz.node.connectattr('torso_position', mathnode, 'input2')
|
spaz.node.connectattr('torso_position', mathnode, 'input2')
|
||||||
|
|
||||||
distance_txt = ba.newnode('text',
|
distance_txt = bs.newnode('text',
|
||||||
owner=spaz.node,
|
owner=spaz.node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': '',
|
'text': '',
|
||||||
|
|
@ -730,14 +731,14 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# In teams mode its over as soon as any team finishes the race
|
# In teams mode its over as soon as any team finishes the race
|
||||||
|
|
||||||
# FIXME: The get_ffa_point_awards code looks dangerous.
|
# FIXME: The get_ffa_point_awards code looks dangerous.
|
||||||
if isinstance(session, ba.DualTeamSession):
|
if isinstance(session, bs.DualTeamSession):
|
||||||
self.end_game()
|
self.end_game()
|
||||||
else:
|
else:
|
||||||
# In ffa we keep the race going while there's still any points
|
# In ffa we keep the race going while there's still any points
|
||||||
# to be handed out. Find out how many points we have to award
|
# to be handed out. Find out how many points we have to award
|
||||||
# and how many teams have finished, and once that matches
|
# and how many teams have finished, and once that matches
|
||||||
# we're done.
|
# we're done.
|
||||||
assert isinstance(session, ba.FreeForAllSession)
|
assert isinstance(session, bs.FreeForAllSession)
|
||||||
points_to_award = len(session.get_ffa_point_awards())
|
points_to_award = len(session.get_ffa_point_awards())
|
||||||
if teams_completed >= points_to_award - teams_completed:
|
if teams_completed >= points_to_award - teams_completed:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
@ -754,7 +755,7 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
endtime=None if self._last_team_time is None else (
|
endtime=None if self._last_team_time is None else (
|
||||||
self._timer.getstarttime() + self._last_team_time))
|
self._timer.getstarttime() + self._last_team_time))
|
||||||
|
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
|
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
if team.time is not None:
|
if team.time is not None:
|
||||||
|
|
@ -768,10 +769,10 @@ class SleepRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# odd to be announcing that now.
|
# odd to be announcing that now.
|
||||||
self.end(results=results,
|
self.end(results=results,
|
||||||
announce_winning_team=isinstance(self.session,
|
announce_winning_team=isinstance(self.session,
|
||||||
ba.DualTeamSession))
|
bs.DualTeamSession))
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
# Augment default behavior.
|
# Augment default behavior.
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# snake
|
# snake
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
"""Snake game by SEBASTIAN2059"""
|
"""Snake game by SEBASTIAN2059"""
|
||||||
|
|
||||||
# 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.playerspaz import PlayerSpaz
|
import bauiv1 as bui
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
import bascenev1 as bs
|
||||||
from bastd.actor import bomb as stdbomb
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
from bascenev1lib.actor import bomb as stdbomb
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional
|
from typing import Any, Type, List, Dict, Tuple, Union, Sequence, Optional
|
||||||
|
|
@ -29,7 +32,7 @@ class ScoreMessage:
|
||||||
return self.player
|
return self.player
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -38,14 +41,14 @@ class Player(ba.Player['Team']):
|
||||||
self.actived = None
|
self.actived = None
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.score = 0
|
self.score = 0
|
||||||
|
|
||||||
|
|
||||||
lang = ba.app.lang.language
|
lang = bs.app.lang.language
|
||||||
if lang == 'Spanish':
|
if lang == 'Spanish':
|
||||||
description = 'Sobrevive a un número determinado de minas para ganar.'
|
description = 'Sobrevive a un número determinado de minas para ganar.'
|
||||||
join_description = 'Corre y no te dejes matar.'
|
join_description = 'Corre y no te dejes matar.'
|
||||||
|
|
@ -65,15 +68,15 @@ class Custom_Mine(stdbomb.Bomb):
|
||||||
source_player=source_player)
|
source_player=source_player)
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.HitMessage):
|
if isinstance(msg, bs.HitMessage):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
class SnakeGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""A game type based on acquiring kills."""
|
"""A game type based on acquiring kills."""
|
||||||
|
|
||||||
name = 'Snake'
|
name = 'Snake'
|
||||||
|
|
@ -84,15 +87,15 @@ class SnakeGame(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(
|
||||||
'Score to Win',
|
'Score to Win',
|
||||||
min_value=40,
|
min_value=40,
|
||||||
default=80,
|
default=80,
|
||||||
increment=5,
|
increment=5,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -104,7 +107,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -115,27 +118,27 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=1.0,
|
default=1.0,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', 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)
|
||||||
or issubclass(sessiontype, ba.FreeForAllSession))
|
or issubclass(sessiontype, bs.FreeForAllSession))
|
||||||
|
|
||||||
@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._score_to_win: Optional[int] = None
|
self._score_to_win: Optional[int] = None
|
||||||
self._dingsound = ba.getsound('dingSmall')
|
self._dingsound = bs.getsound('dingSmall')
|
||||||
|
|
||||||
self._beep_1_sound = ba.getsound('raceBeep1')
|
self._beep_1_sound = bs.getsound('raceBeep1')
|
||||||
self._beep_2_sound = ba.getsound('raceBeep2')
|
self._beep_2_sound = bs.getsound('raceBeep2')
|
||||||
|
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
self._kills_to_win_per_player = int(
|
self._kills_to_win_per_player = int(
|
||||||
|
|
@ -146,8 +149,8 @@ class SnakeGame(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 if self._epic_mode else
|
self.default_music = (bs.MusicType.EPIC if self._epic_mode else
|
||||||
ba.MusicType.TO_THE_DEATH)
|
bs.MusicType.TO_THE_DEATH)
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
return join_description
|
return join_description
|
||||||
|
|
@ -178,30 +181,30 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
lstart = 7.1 * t_scale
|
lstart = 7.1 * t_scale
|
||||||
inc = 1.25 * t_scale
|
inc = 1.25 * t_scale
|
||||||
|
|
||||||
ba.timer(lstart, self._do_light_1)
|
bs.timer(lstart, self._do_light_1)
|
||||||
ba.timer(lstart + inc, self._do_light_2)
|
bs.timer(lstart + inc, self._do_light_2)
|
||||||
ba.timer(lstart + 2 * inc, self._do_light_3)
|
bs.timer(lstart + 2 * inc, self._do_light_3)
|
||||||
ba.timer(lstart + 3 * inc, self._start_race)
|
bs.timer(lstart + 3 * inc, self._start_race)
|
||||||
|
|
||||||
self._start_lights = []
|
self._start_lights = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
lnub = ba.newnode('image',
|
lnub = bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'texture': ba.gettexture('nub'),
|
'texture': bs.gettexture('nub'),
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
'absolute_scale': True,
|
'absolute_scale': True,
|
||||||
'position': (-75 + i * 50, light_y),
|
'position': (-75 + i * 50, light_y),
|
||||||
'scale': (50, 50),
|
'scale': (50, 50),
|
||||||
'attach': 'center'
|
'attach': 'center'
|
||||||
})
|
})
|
||||||
ba.animate(
|
bs.animate(
|
||||||
lnub, 'opacity', {
|
lnub, 'opacity', {
|
||||||
4.0 * t_scale: 0,
|
4.0 * t_scale: 0,
|
||||||
5.0 * t_scale: 1.0,
|
5.0 * t_scale: 1.0,
|
||||||
12.0 * t_scale: 1.0,
|
12.0 * t_scale: 1.0,
|
||||||
12.5 * t_scale: 0.0
|
12.5 * t_scale: 0.0
|
||||||
})
|
})
|
||||||
ba.timer(13.0 * t_scale, lnub.delete)
|
bs.timer(13.0 * t_scale, lnub.delete)
|
||||||
self._start_lights.append(lnub)
|
self._start_lights.append(lnub)
|
||||||
|
|
||||||
self._start_lights[0].color = (0.2, 0, 0)
|
self._start_lights[0].color = (0.2, 0, 0)
|
||||||
|
|
@ -212,22 +215,22 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _do_light_1(self) -> None:
|
def _do_light_1(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[0].color = (1.0, 0, 0)
|
self._start_lights[0].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_2(self) -> None:
|
def _do_light_2(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[1].color = (1.0, 0, 0)
|
self._start_lights[1].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_3(self) -> None:
|
def _do_light_3(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[2].color = (1.0, 0.3, 0)
|
self._start_lights[2].color = (1.0, 0.3, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _start_race(self) -> None:
|
def _start_race(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[3].color = (0.0, 1.0, 0)
|
self._start_lights[3].color = (0.0, 1.0, 0)
|
||||||
ba.playsound(self._beep_2_sound)
|
self._beep_2_sound.play()
|
||||||
|
|
||||||
self._started = True
|
self._started = True
|
||||||
|
|
||||||
|
|
@ -235,7 +238,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self.generate_mines(player)
|
self.generate_mines(player)
|
||||||
|
|
||||||
# overriding the default character spawning..
|
# overriding the default character spawning..
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
spaz = self.spawn_player_spaz(player)
|
spaz = self.spawn_player_spaz(player)
|
||||||
|
|
||||||
# Let's reconnect this player's controls to this
|
# Let's reconnect this player's controls to this
|
||||||
|
|
@ -252,7 +255,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
def generate_mines(self, player: Player):
|
def generate_mines(self, player: Player):
|
||||||
try:
|
try:
|
||||||
player.actived = ba.Timer(0.5, ba.Call(self.spawn_mine, player), repeat=True)
|
player.actived = bs.Timer(0.5, babase.Call(self.spawn_mine, player), repeat=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Exception -> ' + str(e))
|
print('Exception -> ' + str(e))
|
||||||
|
|
||||||
|
|
@ -271,7 +274,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
def arm():
|
def arm():
|
||||||
mine.arm()
|
mine.arm()
|
||||||
ba.timer(0.5, arm)
|
bs.timer(0.5, arm)
|
||||||
|
|
||||||
player.mines.append(mine)
|
player.mines.append(mine)
|
||||||
if len(player.mines) > 15:
|
if len(player.mines) > 15:
|
||||||
|
|
@ -286,7 +289,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self.handlemessage(ScoreMessage(player))
|
self.handlemessage(ScoreMessage(player))
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -304,7 +307,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
assert self._score_to_win is not None
|
assert self._score_to_win is not None
|
||||||
if any(team.score >= self._score_to_win for team in self.teams):
|
if any(team.score >= self._score_to_win for team in self.teams):
|
||||||
self.end_game() # ba.timer(0.5, self.end_game)
|
self.end_game() # bs.timer(0.5, self.end_game)
|
||||||
else:
|
else:
|
||||||
return super().handlemessage(msg)
|
return super().handlemessage(msg)
|
||||||
return None
|
return None
|
||||||
|
|
@ -315,7 +318,7 @@ class SnakeGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._score_to_win)
|
self._score_to_win)
|
||||||
|
|
||||||
def end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
results.set_team_score(team, team.score)
|
results.set_team_score(team, team.score)
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
# Released under the MIT License. See LICENSE for details.
|
# Released under the MIT License. See LICENSE for details.
|
||||||
#
|
#
|
||||||
"""Defines Race mini-game."""
|
"""Defines Race 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
|
||||||
|
|
@ -11,16 +12,18 @@ import random
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
from bastd.actor.bomb import Bomb, Blast, ExplodeHitMessage
|
import bauiv1 as bui
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
import bascenev1 as bs
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.bomb import Bomb, Blast, ExplodeHitMessage
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import (Any, Type, Tuple, List, Sequence, Optional, Dict,
|
from typing import (Any, Type, Tuple, List, Sequence, Optional, Dict,
|
||||||
Union)
|
Union)
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
|
|
||||||
|
|
||||||
class NewBlast(Blast):
|
class NewBlast(Blast):
|
||||||
|
|
@ -38,7 +41,7 @@ class RaceMine:
|
||||||
mine: Optional[Bomb]
|
mine: Optional[Bomb]
|
||||||
|
|
||||||
|
|
||||||
class RaceRegion(ba.Actor):
|
class RaceRegion(bs.Actor):
|
||||||
"""Region used to track progress during a race."""
|
"""Region used to track progress during a race."""
|
||||||
|
|
||||||
def __init__(self, pt: Sequence[float], index: int):
|
def __init__(self, pt: Sequence[float], index: int):
|
||||||
|
|
@ -47,7 +50,7 @@ class RaceRegion(ba.Actor):
|
||||||
assert isinstance(activity, RaceGame)
|
assert isinstance(activity, RaceGame)
|
||||||
self.pos = pt
|
self.pos = pt
|
||||||
self.index = index
|
self.index = index
|
||||||
self.node = ba.newnode(
|
self.node = bs.newnode(
|
||||||
'region',
|
'region',
|
||||||
delegate=self,
|
delegate=self,
|
||||||
attrs={
|
attrs={
|
||||||
|
|
@ -58,11 +61,11 @@ class RaceRegion(ba.Actor):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
self.distance_txt: Optional[ba.Node] = None
|
self.distance_txt: Optional[bs.Node] = None
|
||||||
self.last_region = 0
|
self.last_region = 0
|
||||||
self.lap = 0
|
self.lap = 0
|
||||||
self.distance = 0.0
|
self.distance = 0.0
|
||||||
|
|
@ -70,7 +73,7 @@ class Player(ba.Player['Team']):
|
||||||
self.rank: Optional[int] = None
|
self.rank: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -79,22 +82,22 @@ class Team(ba.Team[Player]):
|
||||||
self.finished = False
|
self.finished = False
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
class SquidRaceGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Game of racing around a track."""
|
"""Game of racing around a track."""
|
||||||
|
|
||||||
name = 'Squid Race'
|
name = 'Squid Race'
|
||||||
description = 'Run real fast!'
|
description = 'Run real fast!'
|
||||||
scoreconfig = ba.ScoreConfig(label='Time',
|
scoreconfig = bs.ScoreConfig(label='Time',
|
||||||
lower_is_better=True,
|
lower_is_better=True,
|
||||||
scoretype=ba.ScoreType.MILLISECONDS)
|
scoretype=bs.ScoreType.MILLISECONDS)
|
||||||
|
|
||||||
@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('Laps', min_value=1, default=3, increment=1),
|
bs.IntSetting('Laps', min_value=1, default=3, increment=1),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
default=0,
|
default=0,
|
||||||
choices=[
|
choices=[
|
||||||
|
|
@ -106,7 +109,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('20 Minutes', 1200),
|
('20 Minutes', 1200),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Mine Spawning',
|
'Mine Spawning',
|
||||||
default=4000,
|
default=4000,
|
||||||
choices=[
|
choices=[
|
||||||
|
|
@ -116,7 +119,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
('2 Seconds', 2000),
|
('2 Seconds', 2000),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Bomb Spawning',
|
'Bomb Spawning',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -127,49 +130,49 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=2000,
|
default=2000,
|
||||||
),
|
),
|
||||||
ba.BoolSetting('Epic Mode', default=False),
|
bs.BoolSetting('Epic Mode', default=False),
|
||||||
]
|
]
|
||||||
|
|
||||||
# We have some specific settings in teams mode.
|
# We have some specific settings in teams mode.
|
||||||
if issubclass(sessiontype, ba.DualTeamSession):
|
if issubclass(sessiontype, bs.DualTeamSession):
|
||||||
settings.append(
|
settings.append(
|
||||||
ba.BoolSetting('Entire Team Must Finish', default=False))
|
bs.BoolSetting('Entire Team Must Finish', 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.MultiTeamSession)
|
return issubclass(sessiontype, bs.MultiTeamSession)
|
||||||
|
|
||||||
@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('race')
|
return bs.app.classic.getmaps('race')
|
||||||
|
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
self._race_started = False
|
self._race_started = False
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._scoreboard = Scoreboard()
|
self._scoreboard = Scoreboard()
|
||||||
self._score_sound = ba.getsound('score')
|
self._score_sound = bs.getsound('score')
|
||||||
self._swipsound = ba.getsound('swip')
|
self._swipsound = bs.getsound('swip')
|
||||||
self._last_team_time: Optional[float] = None
|
self._last_team_time: Optional[float] = None
|
||||||
self._front_race_region: Optional[int] = None
|
self._front_race_region: Optional[int] = None
|
||||||
self._nub_tex = ba.gettexture('nub')
|
self._nub_tex = bs.gettexture('nub')
|
||||||
self._beep_1_sound = ba.getsound('raceBeep1')
|
self._beep_1_sound = bs.getsound('raceBeep1')
|
||||||
self._beep_2_sound = ba.getsound('raceBeep2')
|
self._beep_2_sound = bs.getsound('raceBeep2')
|
||||||
self.race_region_material: Optional[ba.Material] = None
|
self.race_region_material: Optional[bs.Material] = None
|
||||||
self._regions: List[RaceRegion] = []
|
self._regions: List[RaceRegion] = []
|
||||||
self._team_finish_pts: Optional[int] = None
|
self._team_finish_pts: Optional[int] = None
|
||||||
self._time_text: Optional[ba.Actor] = None
|
self._time_text: Optional[bs.Actor] = None
|
||||||
self._timer: Optional[OnScreenTimer] = None
|
self._timer: Optional[OnScreenTimer] = None
|
||||||
self._race_mines: Optional[List[RaceMine]] = None
|
self._race_mines: Optional[List[RaceMine]] = None
|
||||||
self._race_mine_timer: Optional[ba.Timer] = None
|
self._race_mine_timer: Optional[bs.Timer] = None
|
||||||
self._scoreboard_timer: Optional[ba.Timer] = None
|
self._scoreboard_timer: Optional[bs.Timer] = None
|
||||||
self._player_order_update_timer: Optional[ba.Timer] = None
|
self._player_order_update_timer: Optional[bs.Timer] = None
|
||||||
self._start_lights: Optional[List[ba.Node]] = None
|
self._start_lights: Optional[List[bs.Node]] = None
|
||||||
self._squid_lights: Optional[List[ba.Node]] = None
|
self._squid_lights: Optional[List[bs.Node]] = None
|
||||||
self._countdown_timer: int = 0
|
self._countdown_timer: int = 0
|
||||||
self._sq_mode: str = 'Easy'
|
self._sq_mode: str = 'Easy'
|
||||||
self._tick_timer: Optional[ba.Timer] = None
|
self._tick_timer: Optional[bs.Timer] = None
|
||||||
self._bomb_spawn_timer: Optional[ba.Timer] = None
|
self._bomb_spawn_timer: Optional[bs.Timer] = None
|
||||||
self._laps = int(settings['Laps'])
|
self._laps = int(settings['Laps'])
|
||||||
self._entire_team_must_finish = bool(
|
self._entire_team_must_finish = bool(
|
||||||
settings.get('Entire Team Must Finish', False))
|
settings.get('Entire Team Must Finish', False))
|
||||||
|
|
@ -179,25 +182,25 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._epic_mode = bool(settings['Epic Mode'])
|
self._epic_mode = bool(settings['Epic Mode'])
|
||||||
|
|
||||||
self._countdownsounds = {
|
self._countdownsounds = {
|
||||||
10: ba.getsound('announceTen'),
|
10: bs.getsound('announceTen'),
|
||||||
9: ba.getsound('announceNine'),
|
9: bs.getsound('announceNine'),
|
||||||
8: ba.getsound('announceEight'),
|
8: bs.getsound('announceEight'),
|
||||||
7: ba.getsound('announceSeven'),
|
7: bs.getsound('announceSeven'),
|
||||||
6: ba.getsound('announceSix'),
|
6: bs.getsound('announceSix'),
|
||||||
5: ba.getsound('announceFive'),
|
5: bs.getsound('announceFive'),
|
||||||
4: ba.getsound('announceFour'),
|
4: bs.getsound('announceFour'),
|
||||||
3: ba.getsound('announceThree'),
|
3: bs.getsound('announceThree'),
|
||||||
2: ba.getsound('announceTwo'),
|
2: bs.getsound('announceTwo'),
|
||||||
1: ba.getsound('announceOne')
|
1: bs.getsound('announceOne')
|
||||||
}
|
}
|
||||||
|
|
||||||
# Base class overrides.
|
# Base class overrides.
|
||||||
self.slow_motion = self._epic_mode
|
self.slow_motion = self._epic_mode
|
||||||
self.default_music = (ba.MusicType.EPIC_RACE
|
self.default_music = (bs.MusicType.EPIC_RACE
|
||||||
if self._epic_mode else ba.MusicType.RACE)
|
if self._epic_mode else bs.MusicType.RACE)
|
||||||
|
|
||||||
def get_instance_description(self) -> Union[str, Sequence]:
|
def get_instance_description(self) -> Union[str, Sequence]:
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
t_str = ' Your entire team has to finish.'
|
t_str = ' Your entire team has to finish.'
|
||||||
else:
|
else:
|
||||||
|
|
@ -216,7 +219,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
super().on_transition_in()
|
super().on_transition_in()
|
||||||
shared = SharedObjects.get()
|
shared = SharedObjects.get()
|
||||||
pts = self.map.get_def_points('race_point')
|
pts = self.map.get_def_points('race_point')
|
||||||
mat = self.race_region_material = ba.Material()
|
mat = self.race_region_material = bs.Material()
|
||||||
mat.add_actions(conditions=('they_have_material',
|
mat.add_actions(conditions=('they_have_material',
|
||||||
shared.player_material),
|
shared.player_material),
|
||||||
actions=(
|
actions=(
|
||||||
|
|
@ -232,28 +235,28 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
assert player.actor.node
|
assert player.actor.node
|
||||||
pos = player.actor.node.position
|
pos = player.actor.node.position
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': pos,
|
'position': pos,
|
||||||
'color': (1, 1, 0),
|
'color': (1, 1, 0),
|
||||||
'height_attenuated': False,
|
'height_attenuated': False,
|
||||||
'radius': 0.4
|
'radius': 0.4
|
||||||
})
|
})
|
||||||
ba.timer(0.5, light.delete)
|
bs.timer(0.5, light.delete)
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.1: 1.0 * scale, 0.5: 0})
|
bs.animate(light, 'intensity', {0: 0, 0.1: 1.0 * scale, 0.5: 0})
|
||||||
|
|
||||||
def _handle_race_point_collide(self) -> None:
|
def _handle_race_point_collide(self) -> None:
|
||||||
# FIXME: Tidy this up.
|
# FIXME: Tidy this up.
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-nested-blocks
|
# pylint: disable=too-many-nested-blocks
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
try:
|
try:
|
||||||
region = collision.sourcenode.getdelegate(RaceRegion, True)
|
region = collision.sourcenode.getdelegate(RaceRegion, True)
|
||||||
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
player = collision.opposingnode.getdelegate(PlayerSpaz,
|
||||||
True).getplayer(
|
True).getplayer(
|
||||||
Player, True)
|
Player, True)
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return
|
return
|
||||||
|
|
||||||
last_region = player.last_region
|
last_region = player.last_region
|
||||||
|
|
@ -267,8 +270,8 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if this_region > last_region + 2:
|
if this_region > last_region + 2:
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
assert player.actor
|
assert player.actor
|
||||||
player.actor.handlemessage(ba.DieMessage())
|
player.actor.handlemessage(bs.DieMessage())
|
||||||
ba.screenmessage(ba.Lstr(
|
bs.broadcastmessage(babase.Lstr(
|
||||||
translate=('statements', 'Killing ${NAME} for'
|
translate=('statements', 'Killing ${NAME} for'
|
||||||
' skipping part of the track!'),
|
' skipping part of the track!'),
|
||||||
subs=[('${NAME}', player.getname(full=True))]),
|
subs=[('${NAME}', player.getname(full=True))]),
|
||||||
|
|
@ -287,7 +290,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# In teams mode with all-must-finish on, the team lap
|
# In teams mode with all-must-finish on, the team lap
|
||||||
# value is the min of all team players.
|
# value is the min of all team players.
|
||||||
# Otherwise its the max.
|
# Otherwise its the max.
|
||||||
if isinstance(self.session, ba.DualTeamSession
|
if isinstance(self.session, bs.DualTeamSession
|
||||||
) and self._entire_team_must_finish:
|
) and self._entire_team_must_finish:
|
||||||
team.lap = min([p.lap for p in team.players])
|
team.lap = min([p.lap for p in team.players])
|
||||||
else:
|
else:
|
||||||
|
|
@ -298,7 +301,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# In teams mode, hand out points based on the order
|
# In teams mode, hand out points based on the order
|
||||||
# players come in.
|
# players come in.
|
||||||
if isinstance(self.session, ba.DualTeamSession):
|
if isinstance(self.session, bs.DualTeamSession):
|
||||||
assert self._team_finish_pts is not None
|
assert self._team_finish_pts is not None
|
||||||
if self._team_finish_pts > 0:
|
if self._team_finish_pts > 0:
|
||||||
self.stats.player_scored(player,
|
self.stats.player_scored(player,
|
||||||
|
|
@ -311,7 +314,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.finished = True
|
player.finished = True
|
||||||
assert player.actor
|
assert player.actor
|
||||||
player.actor.handlemessage(
|
player.actor.handlemessage(
|
||||||
ba.DieMessage(immediate=True))
|
bs.DieMessage(immediate=True))
|
||||||
|
|
||||||
# Makes sure noone behind them passes them in rank
|
# Makes sure noone behind them passes them in rank
|
||||||
# while finishing.
|
# while finishing.
|
||||||
|
|
@ -319,25 +322,25 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# If the whole team has finished the race.
|
# If the whole team has finished the race.
|
||||||
if team.lap == self._laps:
|
if team.lap == self._laps:
|
||||||
ba.playsound(self._score_sound)
|
self._score_sound.play()
|
||||||
player.team.finished = True
|
player.team.finished = True
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
elapsed = ba.time() - self._timer.getstarttime()
|
elapsed = bs.time() - self._timer.getstarttime()
|
||||||
self._last_team_time = player.team.time = elapsed
|
self._last_team_time = player.team.time = elapsed
|
||||||
|
|
||||||
# Team has yet to finish.
|
# Team has yet to finish.
|
||||||
else:
|
else:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
|
|
||||||
# They've just finished a lap but not the race.
|
# They've just finished a lap but not the race.
|
||||||
else:
|
else:
|
||||||
ba.playsound(self._swipsound)
|
self._swipsound.play()
|
||||||
self._flash_player(player, 0.3)
|
self._flash_player(player, 0.3)
|
||||||
|
|
||||||
# Print their lap number over their head.
|
# Print their lap number over their head.
|
||||||
try:
|
try:
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
mathnode = ba.newnode('math',
|
mathnode = bs.newnode('math',
|
||||||
owner=player.actor.node,
|
owner=player.actor.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': (0, 1.9, 0),
|
'input1': (0, 1.9, 0),
|
||||||
|
|
@ -345,12 +348,12 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
})
|
})
|
||||||
player.actor.node.connectattr(
|
player.actor.node.connectattr(
|
||||||
'torso_position', mathnode, 'input2')
|
'torso_position', mathnode, 'input2')
|
||||||
tstr = ba.Lstr(resource='lapNumberText',
|
tstr = babase.Lstr(resource='lapNumberText',
|
||||||
subs=[('${CURRENT}',
|
subs=[('${CURRENT}',
|
||||||
str(player.lap + 1)),
|
str(player.lap + 1)),
|
||||||
('${TOTAL}', str(self._laps))
|
('${TOTAL}', str(self._laps))
|
||||||
])
|
])
|
||||||
txtnode = ba.newnode('text',
|
txtnode = bs.newnode('text',
|
||||||
owner=mathnode,
|
owner=mathnode,
|
||||||
attrs={
|
attrs={
|
||||||
'text': tstr,
|
'text': tstr,
|
||||||
|
|
@ -360,15 +363,15 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'h_align': 'center'
|
'h_align': 'center'
|
||||||
})
|
})
|
||||||
mathnode.connectattr('output', txtnode, 'position')
|
mathnode.connectattr('output', txtnode, 'position')
|
||||||
ba.animate(txtnode, 'scale', {
|
bs.animate(txtnode, 'scale', {
|
||||||
0.0: 0,
|
0.0: 0,
|
||||||
0.2: 0.019,
|
0.2: 0.019,
|
||||||
2.0: 0.019,
|
2.0: 0.019,
|
||||||
2.2: 0
|
2.2: 0
|
||||||
})
|
})
|
||||||
ba.timer(2.3, mathnode.delete)
|
bs.timer(2.3, mathnode.delete)
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error printing lap.')
|
babase.print_exception('Error printing lap.')
|
||||||
|
|
||||||
def on_team_join(self, team: Team) -> None:
|
def on_team_join(self, team: Team) -> None:
|
||||||
self._update_scoreboard()
|
self._update_scoreboard()
|
||||||
|
|
@ -377,8 +380,8 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# Don't allow joining after we start
|
# Don't allow joining after we start
|
||||||
# (would enable leave/rejoin tomfoolery).
|
# (would enable leave/rejoin tomfoolery).
|
||||||
if self.has_begun():
|
if self.has_begun():
|
||||||
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),
|
||||||
)
|
)
|
||||||
|
|
@ -391,9 +394,9 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# A player leaving disqualifies the team if 'Entire Team Must Finish'
|
# A player leaving disqualifies the team if 'Entire Team Must Finish'
|
||||||
# is on (otherwise in teams mode everyone could just leave except the
|
# is on (otherwise in teams mode everyone could just leave except the
|
||||||
# leading player to win).
|
# leading player to win).
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
ba.screenmessage(ba.Lstr(
|
bs.broadcastmessage(babase.Lstr(
|
||||||
translate=('statements',
|
translate=('statements',
|
||||||
'${TEAM} is disqualified because ${PLAYER} left'),
|
'${TEAM} is disqualified because ${PLAYER} left'),
|
||||||
subs=[('${TEAM}', player.team.name),
|
subs=[('${TEAM}', player.team.name),
|
||||||
|
|
@ -402,18 +405,18 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.team.finished = True
|
player.team.finished = True
|
||||||
player.team.time = None
|
player.team.time = None
|
||||||
player.team.lap = 0
|
player.team.lap = 0
|
||||||
ba.playsound(ba.getsound('boo'))
|
bs.getsound('boo').play()
|
||||||
for otherplayer in player.team.players:
|
for otherplayer in player.team.players:
|
||||||
otherplayer.lap = 0
|
otherplayer.lap = 0
|
||||||
otherplayer.finished = True
|
otherplayer.finished = True
|
||||||
try:
|
try:
|
||||||
if otherplayer.actor is not None:
|
if otherplayer.actor is not None:
|
||||||
otherplayer.actor.handlemessage(ba.DieMessage())
|
otherplayer.actor.handlemessage(bs.DieMessage())
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error sending DieMessage.')
|
babase.print_exception('Error sending DieMessage.')
|
||||||
|
|
||||||
# Defer so team/player lists will be updated.
|
# Defer so team/player lists will be updated.
|
||||||
ba.pushcall(self._check_end_game)
|
babase.pushcall(self._check_end_game)
|
||||||
|
|
||||||
def _update_scoreboard(self) -> None:
|
def _update_scoreboard(self) -> None:
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
|
|
@ -421,7 +424,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if not distances:
|
if not distances:
|
||||||
teams_dist = 0.0
|
teams_dist = 0.0
|
||||||
else:
|
else:
|
||||||
if (isinstance(self.session, ba.DualTeamSession)
|
if (isinstance(self.session, bs.DualTeamSession)
|
||||||
and self._entire_team_must_finish):
|
and self._entire_team_must_finish):
|
||||||
teams_dist = min(distances)
|
teams_dist = min(distances)
|
||||||
else:
|
else:
|
||||||
|
|
@ -434,15 +437,15 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
show_value=False)
|
show_value=False)
|
||||||
|
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
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._team_finish_pts = 100
|
self._team_finish_pts = 100
|
||||||
|
|
||||||
# Throw a timer up on-screen.
|
# Throw a timer up on-screen.
|
||||||
self._time_text = ba.NodeActor(
|
self._time_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'v_attach': 'top',
|
'v_attach': 'top',
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -462,14 +465,14 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
for p in self.map.get_def_points('race_mine')
|
for p in self.map.get_def_points('race_mine')
|
||||||
]
|
]
|
||||||
if self._race_mines:
|
if self._race_mines:
|
||||||
self._race_mine_timer = ba.Timer(0.001 * self._mine_spawning,
|
self._race_mine_timer = bs.Timer(0.001 * self._mine_spawning,
|
||||||
self._update_race_mine,
|
self._update_race_mine,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
self._scoreboard_timer = ba.Timer(0.25,
|
self._scoreboard_timer = bs.Timer(0.25,
|
||||||
self._update_scoreboard,
|
self._update_scoreboard,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
self._player_order_update_timer = ba.Timer(0.25,
|
self._player_order_update_timer = bs.Timer(0.25,
|
||||||
self._update_player_order,
|
self._update_player_order,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
|
|
@ -482,30 +485,30 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
lstart = 7.1 * t_scale
|
lstart = 7.1 * t_scale
|
||||||
inc = 1.25 * t_scale
|
inc = 1.25 * t_scale
|
||||||
|
|
||||||
ba.timer(lstart, self._do_light_1)
|
bs.timer(lstart, self._do_light_1)
|
||||||
ba.timer(lstart + inc, self._do_light_2)
|
bs.timer(lstart + inc, self._do_light_2)
|
||||||
ba.timer(lstart + 2 * inc, self._do_light_3)
|
bs.timer(lstart + 2 * inc, self._do_light_3)
|
||||||
ba.timer(lstart + 3 * inc, self._start_race)
|
bs.timer(lstart + 3 * inc, self._start_race)
|
||||||
|
|
||||||
self._start_lights = []
|
self._start_lights = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
lnub = ba.newnode('image',
|
lnub = bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'texture': ba.gettexture('nub'),
|
'texture': bs.gettexture('nub'),
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
'absolute_scale': True,
|
'absolute_scale': True,
|
||||||
'position': (-75 + i * 50, light_y),
|
'position': (-75 + i * 50, light_y),
|
||||||
'scale': (50, 50),
|
'scale': (50, 50),
|
||||||
'attach': 'center'
|
'attach': 'center'
|
||||||
})
|
})
|
||||||
ba.animate(
|
bs.animate(
|
||||||
lnub, 'opacity', {
|
lnub, 'opacity', {
|
||||||
4.0 * t_scale: 0,
|
4.0 * t_scale: 0,
|
||||||
5.0 * t_scale: 1.0,
|
5.0 * t_scale: 1.0,
|
||||||
12.0 * t_scale: 1.0,
|
12.0 * t_scale: 1.0,
|
||||||
12.5 * t_scale: 0.0
|
12.5 * t_scale: 0.0
|
||||||
})
|
})
|
||||||
ba.timer(13.0 * t_scale, lnub.delete)
|
bs.timer(13.0 * t_scale, lnub.delete)
|
||||||
self._start_lights.append(lnub)
|
self._start_lights.append(lnub)
|
||||||
|
|
||||||
self._start_lights[0].color = (0.2, 0, 0)
|
self._start_lights[0].color = (0.2, 0, 0)
|
||||||
|
|
@ -515,16 +518,16 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
self._squid_lights = []
|
self._squid_lights = []
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
lnub = ba.newnode('image',
|
lnub = bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'texture': ba.gettexture('nub'),
|
'texture': bs.gettexture('nub'),
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
'absolute_scale': True,
|
'absolute_scale': True,
|
||||||
'position': (-33 + i * 65, 220),
|
'position': (-33 + i * 65, 220),
|
||||||
'scale': (60, 60),
|
'scale': (60, 60),
|
||||||
'attach': 'center'
|
'attach': 'center'
|
||||||
})
|
})
|
||||||
ba.animate(
|
bs.animate(
|
||||||
lnub, 'opacity', {
|
lnub, 'opacity', {
|
||||||
4.0 * t_scale: 0,
|
4.0 * t_scale: 0,
|
||||||
5.0 * t_scale: 1.0})
|
5.0 * t_scale: 1.0})
|
||||||
|
|
@ -532,12 +535,12 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._squid_lights[0].color = (0.2, 0, 0)
|
self._squid_lights[0].color = (0.2, 0, 0)
|
||||||
self._squid_lights[1].color = (0.0, 0.3, 0)
|
self._squid_lights[1].color = (0.0, 0.3, 0)
|
||||||
|
|
||||||
ba.timer(1.0, self._check_squid_end, repeat=True)
|
bs.timer(1.0, self._check_squid_end, repeat=True)
|
||||||
self._squidgame_countdown()
|
self._squidgame_countdown()
|
||||||
|
|
||||||
def _squidgame_countdown(self) -> None:
|
def _squidgame_countdown(self) -> None:
|
||||||
self._countdown_timer = 80 * self._laps # 80
|
self._countdown_timer = 80 * self._laps # 80
|
||||||
ba.newnode(
|
bs.newnode(
|
||||||
'image',
|
'image',
|
||||||
attrs={
|
attrs={
|
||||||
'opacity': 0.7,
|
'opacity': 0.7,
|
||||||
|
|
@ -545,8 +548,8 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'attach': 'topCenter',
|
'attach': 'topCenter',
|
||||||
'position': (-220, -40),
|
'position': (-220, -40),
|
||||||
'scale': (135, 45),
|
'scale': (135, 45),
|
||||||
'texture': ba.gettexture('bar')})
|
'texture': bs.gettexture('bar')})
|
||||||
ba.newnode(
|
bs.newnode(
|
||||||
'image',
|
'image',
|
||||||
attrs={
|
attrs={
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
|
|
@ -554,9 +557,9 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'attach': 'topCenter',
|
'attach': 'topCenter',
|
||||||
'position': (-220, -38),
|
'position': (-220, -38),
|
||||||
'scale': (155, 65),
|
'scale': (155, 65),
|
||||||
'texture': ba.gettexture('uiAtlas'),
|
'texture': bs.gettexture('uiAtlas'),
|
||||||
'model_transparent': ba.getmodel('meterTransparent')})
|
'mesh_transparent': bs.getmesh('meterTransparent')})
|
||||||
self._sgcountdown_text = ba.newnode(
|
self._sgcountdown_text = bs.newnode(
|
||||||
'text',
|
'text',
|
||||||
attrs={
|
attrs={
|
||||||
'v_attach': 'top',
|
'v_attach': 'top',
|
||||||
|
|
@ -576,14 +579,14 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._squid_game_all_die()
|
self._squid_game_all_die()
|
||||||
if self._countdown_timer == 20:
|
if self._countdown_timer == 20:
|
||||||
self._sq_mode = 'Hard'
|
self._sq_mode = 'Hard'
|
||||||
ba.playsound(ba.getsound('alarm'))
|
bs.getsound('alarm').play()
|
||||||
if self._countdown_timer == 40:
|
if self._countdown_timer == 40:
|
||||||
self._sq_mode = 'Normal'
|
self._sq_mode = 'Normal'
|
||||||
if self._countdown_timer <= 20:
|
if self._countdown_timer <= 20:
|
||||||
self._sgcountdown_text.color = (1.2, 0.0, 0.0)
|
self._sgcountdown_text.color = (1.2, 0.0, 0.0)
|
||||||
self._sgcountdown_text.scale = 1.2
|
self._sgcountdown_text.scale = 1.2
|
||||||
if self._countdown_timer in self._countdownsounds:
|
if self._countdown_timer in self._countdownsounds:
|
||||||
ba.playsound(self._countdownsounds[self._countdown_timer])
|
self._countdownsounds[self._countdown_timer].play()
|
||||||
else:
|
else:
|
||||||
self._sgcountdown_text.color = (1.0, 1.0, 1.0)
|
self._sgcountdown_text.color = (1.0, 1.0, 1.0)
|
||||||
self._sgcountdown_text.text = str(self._countdown_timer)+"s"
|
self._sgcountdown_text.text = str(self._countdown_timer)+"s"
|
||||||
|
|
@ -592,14 +595,14 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
player.actor._cursed = True
|
player.actor._cursed = True
|
||||||
player.actor.handlemessage(ba.DieMessage())
|
player.actor.handlemessage(bs.DieMessage())
|
||||||
NewBlast(
|
NewBlast(
|
||||||
position=player.actor.node.position,
|
position=player.actor.node.position,
|
||||||
velocity=player.actor.node.velocity,
|
velocity=player.actor.node.velocity,
|
||||||
blast_radius=3.0,
|
blast_radius=3.0,
|
||||||
blast_type='normal').autoretain()
|
blast_type='normal').autoretain()
|
||||||
player.actor.handlemessage(
|
player.actor.handlemessage(
|
||||||
ba.HitMessage(
|
bs.HitMessage(
|
||||||
pos=player.actor.node.position,
|
pos=player.actor.node.position,
|
||||||
velocity=player.actor.node.velocity,
|
velocity=player.actor.node.velocity,
|
||||||
magnitude=2000,
|
magnitude=2000,
|
||||||
|
|
@ -612,8 +615,8 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _do_ticks(self) -> None:
|
def _do_ticks(self) -> None:
|
||||||
def do_ticks():
|
def do_ticks():
|
||||||
if self._ticks:
|
if self._ticks:
|
||||||
ba.playsound(ba.getsound('tick'))
|
bs.getsound('tick').play()
|
||||||
self._tick_timer = ba.timer(1.0, do_ticks, repeat=True)
|
self._tick_timer = bs.timer(1.0, do_ticks, repeat=True)
|
||||||
|
|
||||||
def _start_squid_game(self) -> None:
|
def _start_squid_game(self) -> None:
|
||||||
easy = [4.5, 5, 5.5, 6]
|
easy = [4.5, 5, 5.5, 6]
|
||||||
|
|
@ -623,30 +626,30 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
hard if self._sq_mode == 'Hard' else
|
hard if self._sq_mode == 'Hard' else
|
||||||
normal if self._sq_mode == 'Normal' else easy)
|
normal if self._sq_mode == 'Normal' else easy)
|
||||||
# if random_number == 6:
|
# if random_number == 6:
|
||||||
# ba.playsound(ba.getsound('lrlg_06s'))
|
# bs.getsound('lrlg_06s').play()
|
||||||
# elif random_number == 5.5:
|
# elif random_number == 5.5:
|
||||||
# ba.playsound(ba.getsound('lrlg_055s'))
|
# bs.getsound('lrlg_055s').play()
|
||||||
# elif random_number == 5:
|
# elif random_number == 5:
|
||||||
# ba.playsound(ba.getsound('lrlg_05s'))
|
# bs.getsound('lrlg_05s').play()
|
||||||
# elif random_number == 4.5:
|
# elif random_number == 4.5:
|
||||||
# ba.playsound(ba.getsound('lrlg_045s'))
|
# bs.getsound('lrlg_045s').play()
|
||||||
# elif random_number == 4:
|
# elif random_number == 4:
|
||||||
# ba.playsound(ba.getsound('lrlg_04s'))
|
# bs.getsound('lrlg_04s').play()
|
||||||
# elif random_number == 3.5:
|
# elif random_number == 3.5:
|
||||||
# ba.playsound(ba.getsound('lrlg_035s'))
|
# bs.getsound('lrlg_035s').play()
|
||||||
# elif random_number == 3:
|
# elif random_number == 3:
|
||||||
# ba.playsound(ba.getsound('lrlg_03s'))
|
# bs.getsound('lrlg_03s').play()
|
||||||
self._squid_lights[0].color = (0.2, 0, 0)
|
self._squid_lights[0].color = (0.2, 0, 0)
|
||||||
self._squid_lights[1].color = (0.0, 1.0, 0)
|
self._squid_lights[1].color = (0.0, 1.0, 0)
|
||||||
self._do_delete = False
|
self._do_delete = False
|
||||||
self._ticks = True
|
self._ticks = True
|
||||||
ba.timer(random_number, self._stop_squid_game)
|
bs.timer(random_number, self._stop_squid_game)
|
||||||
|
|
||||||
def _stop_squid_game(self) -> None:
|
def _stop_squid_game(self) -> None:
|
||||||
self._ticks = False
|
self._ticks = False
|
||||||
self._squid_lights[0].color = (1.0, 0, 0)
|
self._squid_lights[0].color = (1.0, 0, 0)
|
||||||
self._squid_lights[1].color = (0.0, 0.3, 0)
|
self._squid_lights[1].color = (0.0, 0.3, 0)
|
||||||
ba.timer(0.2, self._check_delete)
|
bs.timer(0.2, self._check_delete)
|
||||||
|
|
||||||
def _check_delete(self) -> None:
|
def _check_delete(self) -> None:
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
|
|
@ -654,7 +657,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
player.customdata['position'] = None
|
player.customdata['position'] = None
|
||||||
player.customdata['position'] = player.actor.node.position
|
player.customdata['position'] = player.actor.node.position
|
||||||
self._do_delete = True
|
self._do_delete = True
|
||||||
ba.timer(3.0 if self._sq_mode == 'Hard' else 4.0,
|
bs.timer(3.0 if self._sq_mode == 'Hard' else 4.0,
|
||||||
self._start_squid_game)
|
self._start_squid_game)
|
||||||
|
|
||||||
def _start_delete(self) -> None:
|
def _start_delete(self) -> None:
|
||||||
|
|
@ -684,14 +687,14 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
current_posz in posz_list) or not (
|
current_posz in posz_list) or not (
|
||||||
current_posy in posy_list):
|
current_posy in posy_list):
|
||||||
player.actor._cursed = True
|
player.actor._cursed = True
|
||||||
player.actor.handlemessage(ba.DieMessage())
|
player.actor.handlemessage(bs.DieMessage())
|
||||||
NewBlast(
|
NewBlast(
|
||||||
position=player.actor.node.position,
|
position=player.actor.node.position,
|
||||||
velocity=player.actor.node.velocity,
|
velocity=player.actor.node.velocity,
|
||||||
blast_radius=3.0,
|
blast_radius=3.0,
|
||||||
blast_type='normal').autoretain()
|
blast_type='normal').autoretain()
|
||||||
player.actor.handlemessage(
|
player.actor.handlemessage(
|
||||||
ba.HitMessage(
|
bs.HitMessage(
|
||||||
pos=player.actor.node.position,
|
pos=player.actor.node.position,
|
||||||
velocity=player.actor.node.velocity,
|
velocity=player.actor.node.velocity,
|
||||||
magnitude=2000,
|
magnitude=2000,
|
||||||
|
|
@ -713,34 +716,34 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _do_light_1(self) -> None:
|
def _do_light_1(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[0].color = (1.0, 0, 0)
|
self._start_lights[0].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_2(self) -> None:
|
def _do_light_2(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[1].color = (1.0, 0, 0)
|
self._start_lights[1].color = (1.0, 0, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _do_light_3(self) -> None:
|
def _do_light_3(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[2].color = (1.0, 0.3, 0)
|
self._start_lights[2].color = (1.0, 0.3, 0)
|
||||||
ba.playsound(self._beep_1_sound)
|
self._beep_1_sound.play()
|
||||||
|
|
||||||
def _start_race(self) -> None:
|
def _start_race(self) -> None:
|
||||||
assert self._start_lights is not None
|
assert self._start_lights is not None
|
||||||
self._start_lights[3].color = (0.0, 1.0, 0)
|
self._start_lights[3].color = (0.0, 1.0, 0)
|
||||||
ba.playsound(self._beep_2_sound)
|
self._beep_2_sound.play()
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
if player.actor is not None:
|
if player.actor is not None:
|
||||||
try:
|
try:
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
player.actor.connect_controls_to_player()
|
player.actor.connect_controls_to_player()
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error in race player connects.')
|
babase.print_exception('Error in race player connects.')
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
self._timer.start()
|
self._timer.start()
|
||||||
|
|
||||||
if self._bomb_spawning != 0:
|
if self._bomb_spawning != 0:
|
||||||
self._bomb_spawn_timer = ba.Timer(0.001 * self._bomb_spawning,
|
self._bomb_spawn_timer = bs.Timer(0.001 * self._bomb_spawning,
|
||||||
self._spawn_bomb,
|
self._spawn_bomb,
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
|
|
@ -748,25 +751,25 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
self._squid_lights[1].color = (0.0, 1.0, 0)
|
self._squid_lights[1].color = (0.0, 1.0, 0)
|
||||||
self._start_squid_game()
|
self._start_squid_game()
|
||||||
self._do_ticks()
|
self._do_ticks()
|
||||||
ba.timer(0.2, self._start_delete, repeat=True)
|
bs.timer(0.2, self._start_delete, repeat=True)
|
||||||
ba.timer(1.0, self._update_sgcountdown, repeat=True)
|
bs.timer(1.0, self._update_sgcountdown, repeat=True)
|
||||||
|
|
||||||
def _update_player_order(self) -> None:
|
def _update_player_order(self) -> None:
|
||||||
|
|
||||||
# Calc all player distances.
|
# Calc all player distances.
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
pos: Optional[ba.Vec3]
|
pos: Optional[babase.Vec3]
|
||||||
try:
|
try:
|
||||||
pos = player.position
|
pos = player.position
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
pos = None
|
pos = None
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
r_index = player.last_region
|
r_index = player.last_region
|
||||||
rg1 = self._regions[r_index]
|
rg1 = self._regions[r_index]
|
||||||
r1pt = ba.Vec3(rg1.pos[:3])
|
r1pt = babase.Vec3(rg1.pos[:3])
|
||||||
rg2 = self._regions[0] if r_index == len(
|
rg2 = self._regions[0] if r_index == len(
|
||||||
self._regions) - 1 else self._regions[r_index + 1]
|
self._regions) - 1 else self._regions[r_index + 1]
|
||||||
r2pt = ba.Vec3(rg2.pos[:3])
|
r2pt = babase.Vec3(rg2.pos[:3])
|
||||||
r2dist = (pos - r2pt).length()
|
r2dist = (pos - r2pt).length()
|
||||||
amt = 1.0 - (r2dist / (r2pt - r1pt).length())
|
amt = 1.0 - (r2dist / (r2pt - r1pt).length())
|
||||||
amt = player.lap + (r_index + amt) * (1.0 / len(self._regions))
|
amt = player.lap + (r_index + amt) * (1.0 / len(self._regions))
|
||||||
|
|
@ -797,8 +800,8 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
(-region_scale * pos[5], region_scale * pos[5]))
|
(-region_scale * pos[5], region_scale * pos[5]))
|
||||||
pos = (pos[0] + random.uniform(*x_range), pos[1] + 1.0,
|
pos = (pos[0] + random.uniform(*x_range), pos[1] + 1.0,
|
||||||
pos[2] + random.uniform(*z_range))
|
pos[2] + random.uniform(*z_range))
|
||||||
ba.timer(random.uniform(0.0, 2.0),
|
bs.timer(random.uniform(0.0, 2.0),
|
||||||
ba.WeakCall(self._spawn_bomb_at_pos, pos))
|
bs.WeakCall(self._spawn_bomb_at_pos, pos))
|
||||||
|
|
||||||
def _spawn_bomb_at_pos(self, pos: Sequence[float]) -> None:
|
def _spawn_bomb_at_pos(self, pos: Sequence[float]) -> None:
|
||||||
if self.has_ended():
|
if self.has_ended():
|
||||||
|
|
@ -814,15 +817,15 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def _flash_mine(self, i: int) -> None:
|
def _flash_mine(self, i: int) -> None:
|
||||||
assert self._race_mines is not None
|
assert self._race_mines is not None
|
||||||
rmine = self._race_mines[i]
|
rmine = self._race_mines[i]
|
||||||
light = ba.newnode('light',
|
light = bs.newnode('light',
|
||||||
attrs={
|
attrs={
|
||||||
'position': rmine.point[:3],
|
'position': rmine.point[:3],
|
||||||
'color': (1, 0.2, 0.2),
|
'color': (1, 0.2, 0.2),
|
||||||
'radius': 0.1,
|
'radius': 0.1,
|
||||||
'height_attenuated': False
|
'height_attenuated': False
|
||||||
})
|
})
|
||||||
ba.animate(light, 'intensity', {0.0: 0, 0.1: 1.0, 0.2: 0}, loop=True)
|
bs.animate(light, 'intensity', {0.0: 0, 0.1: 1.0, 0.2: 0}, loop=True)
|
||||||
ba.timer(1.0, light.delete)
|
bs.timer(1.0, light.delete)
|
||||||
|
|
||||||
def _update_race_mine(self) -> None:
|
def _update_race_mine(self) -> None:
|
||||||
assert self._race_mines is not None
|
assert self._race_mines is not None
|
||||||
|
|
@ -836,9 +839,9 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
assert rmine is not None
|
assert rmine is not None
|
||||||
if not rmine.mine:
|
if not rmine.mine:
|
||||||
self._flash_mine(m_index)
|
self._flash_mine(m_index)
|
||||||
ba.timer(0.95, ba.Call(self._make_mine, m_index))
|
bs.timer(0.95, babase.Call(self._make_mine, m_index))
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
if player.team.finished:
|
if player.team.finished:
|
||||||
# FIXME: This is not type-safe!
|
# FIXME: This is not type-safe!
|
||||||
# This call is expected to always return an Actor!
|
# This call is expected to always return an Actor!
|
||||||
|
|
@ -863,7 +866,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
if not self._race_started:
|
if not self._race_started:
|
||||||
spaz.disconnect_controls_from_player()
|
spaz.disconnect_controls_from_player()
|
||||||
|
|
||||||
mathnode = ba.newnode('math',
|
mathnode = bs.newnode('math',
|
||||||
owner=spaz.node,
|
owner=spaz.node,
|
||||||
attrs={
|
attrs={
|
||||||
'input1': (0, 1.4, 0),
|
'input1': (0, 1.4, 0),
|
||||||
|
|
@ -871,7 +874,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
})
|
})
|
||||||
spaz.node.connectattr('torso_position', mathnode, 'input2')
|
spaz.node.connectattr('torso_position', mathnode, 'input2')
|
||||||
|
|
||||||
distance_txt = ba.newnode('text',
|
distance_txt = bs.newnode('text',
|
||||||
owner=spaz.node,
|
owner=spaz.node,
|
||||||
attrs={
|
attrs={
|
||||||
'text': '',
|
'text': '',
|
||||||
|
|
@ -902,14 +905,14 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# In teams mode its over as soon as any team finishes the race
|
# In teams mode its over as soon as any team finishes the race
|
||||||
|
|
||||||
# FIXME: The get_ffa_point_awards code looks dangerous.
|
# FIXME: The get_ffa_point_awards code looks dangerous.
|
||||||
if isinstance(session, ba.DualTeamSession):
|
if isinstance(session, bs.DualTeamSession):
|
||||||
self.end_game()
|
self.end_game()
|
||||||
else:
|
else:
|
||||||
# In ffa we keep the race going while there's still any points
|
# In ffa we keep the race going while there's still any points
|
||||||
# to be handed out. Find out how many points we have to award
|
# to be handed out. Find out how many points we have to award
|
||||||
# and how many teams have finished, and once that matches
|
# and how many teams have finished, and once that matches
|
||||||
# we're done.
|
# we're done.
|
||||||
assert isinstance(session, ba.FreeForAllSession)
|
assert isinstance(session, bs.FreeForAllSession)
|
||||||
points_to_award = len(session.get_ffa_point_awards())
|
points_to_award = len(session.get_ffa_point_awards())
|
||||||
if teams_completed >= points_to_award - teams_completed:
|
if teams_completed >= points_to_award - teams_completed:
|
||||||
self.end_game()
|
self.end_game()
|
||||||
|
|
@ -926,7 +929,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
endtime=None if self._last_team_time is None else (
|
endtime=None if self._last_team_time is None else (
|
||||||
self._timer.getstarttime() + self._last_team_time))
|
self._timer.getstarttime() + self._last_team_time))
|
||||||
|
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
|
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
if team.time is not None:
|
if team.time is not None:
|
||||||
|
|
@ -940,10 +943,10 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# odd to be announcing that now.
|
# odd to be announcing that now.
|
||||||
self.end(results=results,
|
self.end(results=results,
|
||||||
announce_winning_team=isinstance(self.session,
|
announce_winning_team=isinstance(self.session,
|
||||||
ba.DualTeamSession))
|
bs.DualTeamSession))
|
||||||
|
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
# Augment default behavior.
|
# Augment default behavior.
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
|
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
"""
|
"""
|
||||||
TheSpazGame - Mini game where all characters looks identical , identify enemies and kill them.
|
TheSpazGame - Mini game where all characters looks identical , identify enemies and kill them.
|
||||||
Author: Mr.Smoothy
|
Author: Mr.Smoothy
|
||||||
|
|
@ -12,9 +13,11 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
from bastd.game.elimination import EliminationGame, Player
|
import bauiv1 as bui
|
||||||
from bastd.actor.spazfactory import SpazFactory
|
import bascenev1 as bs
|
||||||
|
from bascenev1lib.game.elimination import EliminationGame, Player
|
||||||
|
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||||
import random
|
import random
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -23,14 +26,14 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
CHARACTER = 'Spaz'
|
CHARACTER = 'Spaz'
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
|
|
||||||
|
|
||||||
class TheSpazGame(EliminationGame):
|
class TheSpazGame(EliminationGame):
|
||||||
name = 'TheSpazGame'
|
name = 'TheSpazGame'
|
||||||
description = 'Enemy Spaz AmongUs. Kill them all'
|
description = 'Enemy Spaz AmongUs. Kill them all'
|
||||||
scoreconfig = ba.ScoreConfig(
|
scoreconfig = bs.ScoreConfig(
|
||||||
label='Survived', scoretype=ba.ScoreType.SECONDS, none_is_winner=True
|
label='Survived', scoretype=bs.ScoreType.SECONDS, none_is_winner=True
|
||||||
)
|
)
|
||||||
|
|
||||||
announce_player_deaths = False
|
announce_player_deaths = False
|
||||||
|
|
@ -39,17 +42,17 @@ class TheSpazGame(EliminationGame):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_settings(
|
def get_available_settings(
|
||||||
cls, sessiontype: type[ba.Session]
|
cls, sessiontype: type[bs.Session]
|
||||||
) -> list[ba.Setting]:
|
) -> 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.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -61,31 +64,31 @@ class TheSpazGame(EliminationGame):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.15)
|
('Shorter', 0.15)
|
||||||
],
|
],
|
||||||
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(ba.BoolSetting('Solo Mode', default=False))
|
settings.append(bs.BoolSetting('Solo Mode', default=False))
|
||||||
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) or issubclass(
|
return issubclass(sessiontype, bs.DualTeamSession) or issubclass(
|
||||||
sessiontype, ba.FreeForAllSession
|
sessiontype, bs.FreeForAllSession
|
||||||
)
|
)
|
||||||
|
|
||||||
@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 get_instance_description(self) -> str | Sequence:
|
def get_instance_description(self) -> str | Sequence:
|
||||||
return (
|
return (
|
||||||
|
|
@ -101,7 +104,7 @@ class TheSpazGame(EliminationGame):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._solo_mode = False
|
self._solo_mode = False
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
p = [-6, -4.3, -2.6, -0.9, 0.8, 2.5, 4.2, 5.9]
|
p = [-6, -4.3, -2.6, -0.9, 0.8, 2.5, 4.2, 5.9]
|
||||||
q = [-4, -2.3, -0.6, 1.1, 2.8, 4.5]
|
q = [-4, -2.3, -0.6, 1.1, 2.8, 4.5]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
"""UFO Boss Fight v1.0:
|
"""UFO Boss Fight v2.0:
|
||||||
Made by Cross Joy"""
|
Made by Cross Joy"""
|
||||||
|
|
||||||
# Anyone who wanna help me in giving suggestion/ fix bugs/ by creating PR,
|
# Anyone who wanna help me in giving suggestion/ fix bugs/ by creating PR,
|
||||||
|
|
@ -8,21 +8,28 @@ Made by Cross Joy"""
|
||||||
# My Discord Id: Cross Joy#0721
|
# My Discord Id: Cross Joy#0721
|
||||||
# My BS Discord Server: https://discford.gg/JyBY6haARJ
|
# My BS Discord Server: https://discford.gg/JyBY6haARJ
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Update v2.0
|
||||||
|
|
||||||
|
# updated to api 8
|
||||||
|
# ---------------------------------------
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import random
|
import random
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
import ba
|
|
||||||
import _ba
|
import babase
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
import bascenev1 as bs
|
||||||
from bastd.actor.spaz import Spaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.bomb import Blast, Bomb
|
from bascenev1lib.actor.spaz import Spaz
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.bomb import Blast, Bomb
|
||||||
from bastd.actor.spazbot import SpazBotSet, StickyBot
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
from bastd.gameutils import SharedObjects
|
from bascenev1lib.actor.spazbot import SpazBotSet, StickyBot
|
||||||
|
from bascenev1lib.gameutils import SharedObjects
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence, Union, Callable
|
from typing import Any, Sequence, Union, Callable
|
||||||
|
|
@ -32,17 +39,17 @@ class UFODiedMessage:
|
||||||
ufo: UFO
|
ufo: UFO
|
||||||
"""The UFO that was killed."""
|
"""The UFO that was killed."""
|
||||||
|
|
||||||
killerplayer: ba.Player | None
|
killerplayer: bs.Player | None
|
||||||
"""The ba.Player that killed it (or None)."""
|
"""The bs.Player that killed it (or None)."""
|
||||||
|
|
||||||
how: ba.DeathType
|
how: bs.DeathType
|
||||||
"""The particular type of death."""
|
"""The particular type of death."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
ufo: UFO,
|
ufo: UFO,
|
||||||
killerplayer: ba.Player | None,
|
killerplayer: bs.Player | None,
|
||||||
how: ba.DeathType,
|
how: bs.DeathType,
|
||||||
):
|
):
|
||||||
"""Instantiate with given values."""
|
"""Instantiate with given values."""
|
||||||
self.spazbot = ufo
|
self.spazbot = ufo
|
||||||
|
|
@ -57,7 +64,7 @@ class RoboBot(StickyBot):
|
||||||
highlight = (3, 3, 3)
|
highlight = (3, 3, 3)
|
||||||
|
|
||||||
|
|
||||||
class UFO(ba.Actor):
|
class UFO(bs.Actor):
|
||||||
"""
|
"""
|
||||||
New AI for Boss
|
New AI for Boss
|
||||||
"""
|
"""
|
||||||
|
|
@ -65,7 +72,7 @@ class UFO(ba.Actor):
|
||||||
# pylint: disable=too-many-public-methods
|
# pylint: disable=too-many-public-methods
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
|
|
||||||
node: ba.Node
|
node: bs.Node
|
||||||
|
|
||||||
def __init__(self, hitpoints: int = 5000):
|
def __init__(self, hitpoints: int = 5000):
|
||||||
|
|
||||||
|
|
@ -74,32 +81,29 @@ class UFO(ba.Actor):
|
||||||
|
|
||||||
self.update_callback: Callable[[UFO], Any] | None = None
|
self.update_callback: Callable[[UFO], Any] | None = None
|
||||||
activity = self.activity
|
activity = self.activity
|
||||||
assert isinstance(activity, ba.GameActivity)
|
assert isinstance(activity, bs.GameActivity)
|
||||||
|
|
||||||
self.platform_material = ba.Material()
|
self.platform_material = bs.Material()
|
||||||
self.platform_material.add_actions(
|
self.platform_material.add_actions(
|
||||||
conditions=('they_have_material', shared.footing_material),
|
conditions=('they_have_material', shared.footing_material),
|
||||||
actions=(
|
actions=(
|
||||||
'modify_part_collision', 'collide', True))
|
'modify_part_collision', 'collide', True))
|
||||||
self.ice_material = ba.Material()
|
self.ice_material = bs.Material()
|
||||||
self.ice_material.add_actions(
|
self.ice_material.add_actions(
|
||||||
actions=('modify_part_collision', 'friction', 0.0))
|
actions=('modify_part_collision', 'friction', 0.0))
|
||||||
|
|
||||||
self._player_pts: list[tuple[ba.Vec3, ba.Vec3]] | None = None
|
self._player_pts: list[tuple[bs.Vec3, bs.Vec3]] | None = None
|
||||||
self._ufo_update_timer: ba.Timer | None = None
|
self._ufo_update_timer: bs.Timer | None = None
|
||||||
self.last_player_attacked_by: ba.Player | None = None
|
self.last_player_attacked_by: bs.Player | None = None
|
||||||
self.last_attacked_time = 0.0
|
self.last_attacked_time = 0.0
|
||||||
self.last_attacked_type: tuple[str, str] | None = None
|
self.last_attacked_type: tuple[str, str] | None = None
|
||||||
|
|
||||||
self.to_target: ba.Vec3 = ba.Vec3(0, 0, 0)
|
self.to_target: bs.Vec3 = bs.Vec3(0, 0, 0)
|
||||||
self.dist = (0, 0, 0)
|
self.dist = (0, 0, 0)
|
||||||
|
|
||||||
self._bots = SpazBotSet()
|
self._bots = SpazBotSet()
|
||||||
self.frozen = False
|
self.frozen = False
|
||||||
self.y_pos = 3
|
|
||||||
self.xz_pos = 1
|
|
||||||
self.bot_count = 3
|
self.bot_count = 3
|
||||||
self.bot_dur_froze = False
|
|
||||||
|
|
||||||
self.hitpoints = hitpoints
|
self.hitpoints = hitpoints
|
||||||
self.hitpoints_max = hitpoints
|
self.hitpoints_max = hitpoints
|
||||||
|
|
@ -108,18 +112,18 @@ class UFO(ba.Actor):
|
||||||
self._height = 35
|
self._height = 35
|
||||||
self._bar_width = 240
|
self._bar_width = 240
|
||||||
self._bar_height = 35
|
self._bar_height = 35
|
||||||
self._bar_tex = self._backing_tex = ba.gettexture('bar')
|
self._bar_tex = self._backing_tex = bs.gettexture('bar')
|
||||||
self._cover_tex = ba.gettexture('uiAtlas')
|
self._cover_tex = bs.gettexture('uiAtlas')
|
||||||
self._model = ba.getmodel('meterTransparent')
|
self._mesh = bs.getmesh('meterTransparent')
|
||||||
self.bar_posx = -120
|
self.bar_posx = -120
|
||||||
|
|
||||||
self._last_hit_time: int | None = None
|
self._last_hit_time: int | None = None
|
||||||
self.impact_scale = 1.0
|
self.impact_scale = 1.0
|
||||||
self._num_times_hit = 0
|
self._num_times_hit = 0
|
||||||
|
|
||||||
self._sucker_mat = ba.Material()
|
self._sucker_mat = bs.Material()
|
||||||
|
|
||||||
self.ufo_material = ba.Material()
|
self.ufo_material = bs.Material()
|
||||||
self.ufo_material.add_actions(
|
self.ufo_material.add_actions(
|
||||||
conditions=('they_have_material',
|
conditions=('they_have_material',
|
||||||
shared.player_material),
|
shared.player_material),
|
||||||
|
|
@ -135,21 +139,20 @@ class UFO(ba.Actor):
|
||||||
self.ufo_material)),
|
self.ufo_material)),
|
||||||
actions=('modify_part_collision', 'physical', False))
|
actions=('modify_part_collision', 'physical', False))
|
||||||
|
|
||||||
activity = _ba.get_foreground_host_activity()
|
activity = bs.get_foreground_host_activity()
|
||||||
with ba.Context(activity):
|
|
||||||
point = activity.map.get_flag_position(None)
|
point = activity.map.get_flag_position(None)
|
||||||
boss_spawn_pos = (point[0], point[1] + 1, point[2])
|
boss_spawn_pos = (point[0], point[1] + 1, point[2])
|
||||||
|
|
||||||
self.node = ba.newnode('prop', delegate=self, attrs={
|
self.node = bs.newnode('prop', delegate=self, attrs={
|
||||||
'position': boss_spawn_pos,
|
'position': boss_spawn_pos,
|
||||||
'velocity': (2, 0, 0),
|
'velocity': (2, 0, 0),
|
||||||
'color_texture': ba.gettexture('achievementFootballShutout'),
|
'color_texture': bs.gettexture('achievementFootballShutout'),
|
||||||
'model': ba.getmodel('landMine'),
|
'mesh': bs.getmesh('landMine'),
|
||||||
# 'light_model': ba.getmodel('powerupSimple'),
|
# 'light_mesh': bs.getmesh('powerupSimple'),
|
||||||
'model_scale': 3.3,
|
'mesh_scale': 3.3,
|
||||||
'body': 'landMine',
|
'body': 'landMine',
|
||||||
'body_scale': 3.3,
|
'body_scale': 3.3,
|
||||||
'gravity_scale': 0.05,
|
'gravity_scale': 0.2,
|
||||||
'density': 1,
|
'density': 1,
|
||||||
'reflection': 'soft',
|
'reflection': 'soft',
|
||||||
'reflection_scale': [0.25],
|
'reflection_scale': [0.25],
|
||||||
|
|
@ -159,7 +162,7 @@ class UFO(ba.Actor):
|
||||||
True,
|
True,
|
||||||
'materials': [shared.footing_material, shared.object_material]})
|
'materials': [shared.footing_material, shared.object_material]})
|
||||||
|
|
||||||
self.holder = ba.newnode('region', attrs={
|
self.holder = bs.newnode('region', attrs={
|
||||||
'position': (
|
'position': (
|
||||||
boss_spawn_pos[0], boss_spawn_pos[1] - 0.25,
|
boss_spawn_pos[0], boss_spawn_pos[1] - 0.25,
|
||||||
boss_spawn_pos[2]),
|
boss_spawn_pos[2]),
|
||||||
|
|
@ -168,7 +171,7 @@ class UFO(ba.Actor):
|
||||||
'materials': (self.platform_material, self.ice_material,
|
'materials': (self.platform_material, self.ice_material,
|
||||||
shared.object_material)})
|
shared.object_material)})
|
||||||
|
|
||||||
self.suck_anim = ba.newnode('locator',
|
self.suck_anim = bs.newnode('locator',
|
||||||
owner=self.node,
|
owner=self.node,
|
||||||
attrs={'shape': 'circleOutline',
|
attrs={'shape': 'circleOutline',
|
||||||
'position': (
|
'position': (
|
||||||
|
|
@ -181,7 +184,7 @@ class UFO(ba.Actor):
|
||||||
'additive': True})
|
'additive': True})
|
||||||
|
|
||||||
def suck_anim():
|
def suck_anim():
|
||||||
ba.animate_array(self.suck_anim, 'position', 3,
|
bs.animate_array(self.suck_anim, 'position', 3,
|
||||||
{0: (
|
{0: (
|
||||||
self.node.position[0],
|
self.node.position[0],
|
||||||
self.node.position[1] - 5,
|
self.node.position[1] - 5,
|
||||||
|
|
@ -194,7 +197,7 @@ class UFO(ba.Actor):
|
||||||
self.node.position[
|
self.node.position[
|
||||||
2] + self.to_target.z / 2)})
|
2] + self.to_target.z / 2)})
|
||||||
|
|
||||||
self.suck_timer = ba.Timer(0.5, suck_anim, repeat=True)
|
self.suck_timer = bs.Timer(0.5, suck_anim, repeat=True)
|
||||||
|
|
||||||
self.blocks = []
|
self.blocks = []
|
||||||
|
|
||||||
|
|
@ -209,14 +212,14 @@ class UFO(ba.Actor):
|
||||||
|
|
||||||
))
|
))
|
||||||
|
|
||||||
# self.sucker = ba.newnode('region', attrs={
|
# self.sucker = bs.newnode('region', attrs={
|
||||||
# 'position': (
|
# 'position': (
|
||||||
# boss_spawn_pos[0], boss_spawn_pos[1] - 2, boss_spawn_pos[2]),
|
# boss_spawn_pos[0], boss_spawn_pos[1] - 2, boss_spawn_pos[2]),
|
||||||
# 'scale': [2, 10, 2],
|
# 'scale': [2, 10, 2],
|
||||||
# 'type': 'box',
|
# 'type': 'box',
|
||||||
# 'materials': self._sucker_mat, })
|
# 'materials': self._sucker_mat, })
|
||||||
|
|
||||||
self.suck = ba.newnode('region',
|
self.suck = bs.newnode('region',
|
||||||
attrs={'position': (
|
attrs={'position': (
|
||||||
boss_spawn_pos[0], boss_spawn_pos[1] - 2,
|
boss_spawn_pos[0], boss_spawn_pos[1] - 2,
|
||||||
boss_spawn_pos[2]),
|
boss_spawn_pos[2]),
|
||||||
|
|
@ -227,27 +230,26 @@ class UFO(ba.Actor):
|
||||||
self.node.connectattr('position', self.holder, 'position')
|
self.node.connectattr('position', self.holder, 'position')
|
||||||
self.node.connectattr('position', self.suck, 'position')
|
self.node.connectattr('position', self.suck, 'position')
|
||||||
|
|
||||||
ba.animate(self.node, 'model_scale', {
|
bs.animate(self.node, 'mesh_scale', {
|
||||||
0: 0,
|
0: 0,
|
||||||
0.2: self.node.model_scale * 1.1,
|
0.2: self.node.mesh_scale * 1.1,
|
||||||
0.26: self.node.model_scale})
|
0.26: self.node.mesh_scale})
|
||||||
|
|
||||||
self.shield_deco = ba.newnode('shield', owner=self.node,
|
self.shield_deco = bs.newnode('shield', owner=self.node,
|
||||||
attrs={'color': (4, 4, 4),
|
attrs={'color': (4, 4, 4),
|
||||||
'radius': 1.2})
|
'radius': 1.2})
|
||||||
self.node.connectattr('position', self.shield_deco, 'position')
|
self.node.connectattr('position', self.shield_deco, 'position')
|
||||||
self._scoreboard()
|
self._scoreboard()
|
||||||
self._update()
|
self._update()
|
||||||
self.drop_bomb_timer = ba.Timer(1.5, ba.Call(self._drop_bomb),
|
self.drop_bomb_timer = bs.Timer(1.5, bs.Call(self._drop_bomb),
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
self.drop_bots_timer = ba.Timer(15.0, ba.Call(self._drop_bots), repeat=True)
|
self.drop_bots_timer = bs.Timer(15.0, bs.Call(self._drop_bots), repeat=True)
|
||||||
|
|
||||||
def _drop_bots(self) -> None:
|
def _drop_bots(self) -> None:
|
||||||
p = self.node.position
|
p = self.node.position
|
||||||
if not self.frozen:
|
|
||||||
for i in range(self.bot_count):
|
for i in range(self.bot_count):
|
||||||
ba.timer(
|
bs.timer(
|
||||||
1.0 + i,
|
1.0 + i,
|
||||||
lambda: self._bots.spawn_bot(
|
lambda: self._bots.spawn_bot(
|
||||||
RoboBot, pos=(self.node.position[0],
|
RoboBot, pos=(self.node.position[0],
|
||||||
|
|
@ -255,13 +257,10 @@ class UFO(ba.Actor):
|
||||||
self.node.position[2]), spawn_time=0.0
|
self.node.position[2]), spawn_time=0.0
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
self.bot_dur_froze = True
|
|
||||||
|
|
||||||
def _drop_bomb(self) -> None:
|
def _drop_bomb(self) -> None:
|
||||||
t = self.to_target
|
t = self.to_target
|
||||||
p = self.node.position
|
p = self.node.position
|
||||||
if not self.frozen:
|
|
||||||
if abs(self.dist[0]) < 2 and abs(self.dist[2]) < 2:
|
if abs(self.dist[0]) < 2 and abs(self.dist[2]) < 2:
|
||||||
Bomb(position=(p[0], p[1] - 0.5, p[2]),
|
Bomb(position=(p[0], p[1] - 0.5, p[2]),
|
||||||
velocity=(t[0] * 5, 0, t[2] * 5),
|
velocity=(t[0] * 5, 0, t[2] * 5),
|
||||||
|
|
@ -285,11 +284,11 @@ class UFO(ba.Actor):
|
||||||
bomb_type='impact').autoretain()
|
bomb_type='impact').autoretain()
|
||||||
|
|
||||||
def _levitate(self):
|
def _levitate(self):
|
||||||
node = ba.getcollision().opposingnode
|
node = bs.getcollision().opposingnode
|
||||||
if node.exists():
|
if node.exists():
|
||||||
p = node.getdelegate(Spaz, True)
|
p = node.getdelegate(Spaz, True)
|
||||||
|
|
||||||
def raise_player(player: ba.Player):
|
def raise_player(player: bs.Player):
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
node = player.node
|
node = player.node
|
||||||
try:
|
try:
|
||||||
|
|
@ -298,12 +297,13 @@ class UFO(ba.Actor):
|
||||||
node.position[2], 0, 5, 0, 3, 10, 0,
|
node.position[2], 0, 5, 0, 3, 10, 0,
|
||||||
0, 0, 5, 0)
|
0, 0, 5, 0)
|
||||||
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not self.frozen:
|
if not self.frozen:
|
||||||
for i in range(7):
|
for i in range(7):
|
||||||
ba.timer(0.05 + i / 20, ba.Call(raise_player, p))
|
bs.timer(0.05 + i / 20, bs.Call(raise_player, p))
|
||||||
|
|
||||||
def on_punched(self, damage: int) -> None:
|
def on_punched(self, damage: int) -> None:
|
||||||
"""Called when this spaz gets punched."""
|
"""Called when this spaz gets punched."""
|
||||||
|
|
@ -315,24 +315,22 @@ class UFO(ba.Actor):
|
||||||
damage = abs(msg.magnitude)
|
damage = abs(msg.magnitude)
|
||||||
if msg.hit_type == 'explosion':
|
if msg.hit_type == 'explosion':
|
||||||
damage /= 20
|
damage /= 20
|
||||||
else:
|
|
||||||
damage /= 5
|
|
||||||
|
|
||||||
self.hitpoints -= int(damage)
|
self.hitpoints -= int(damage)
|
||||||
if self.hitpoints <= 0:
|
if self.hitpoints <= 0:
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
def _get_target_player_pt(self) -> tuple[
|
def _get_target_player_pt(self) -> tuple[
|
||||||
ba.Vec3 | None, ba.Vec3 | None]:
|
bs.Vec3 | None, bs.Vec3 | None]:
|
||||||
"""Returns the position and velocity of our target.
|
"""Returns the position and velocity of our target.
|
||||||
|
|
||||||
Both values will be None in the case of no target.
|
Both values will be None in the case of no target.
|
||||||
"""
|
"""
|
||||||
assert self.node
|
assert self.node
|
||||||
botpt = ba.Vec3(self.node.position)
|
botpt = bs.Vec3(self.node.position)
|
||||||
closest_dist: float | None = None
|
closest_dist: float | None = None
|
||||||
closest_vel: ba.Vec3 | None = None
|
closest_vel: bs.Vec3 | None = None
|
||||||
closest: ba.Vec3 | None = None
|
closest: bs.Vec3 | None = None
|
||||||
assert self._player_pts is not None
|
assert self._player_pts is not None
|
||||||
for plpt, plvel in self._player_pts:
|
for plpt, plvel in self._player_pts:
|
||||||
dist = (plpt - botpt).length()
|
dist = (plpt - botpt).length()
|
||||||
|
|
@ -349,12 +347,12 @@ class UFO(ba.Actor):
|
||||||
assert closest_vel is not None
|
assert closest_vel is not None
|
||||||
assert closest is not None
|
assert closest is not None
|
||||||
return (
|
return (
|
||||||
ba.Vec3(closest[0], closest[1], closest[2]),
|
bs.Vec3(closest[0], closest[1], closest[2]),
|
||||||
ba.Vec3(closest_vel[0], closest_vel[1], closest_vel[2]),
|
bs.Vec3(closest_vel[0], closest_vel[1], closest_vel[2]),
|
||||||
)
|
)
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
def set_player_points(self, pts: list[tuple[ba.Vec3, ba.Vec3]]) -> None:
|
def set_player_points(self, pts: list[tuple[bs.Vec3, bs.Vec3]]) -> None:
|
||||||
"""Provide the spaz-bot with the locations of its enemies."""
|
"""Provide the spaz-bot with the locations of its enemies."""
|
||||||
self._player_pts = pts
|
self._player_pts = pts
|
||||||
|
|
||||||
|
|
@ -368,13 +366,13 @@ class UFO(ba.Actor):
|
||||||
Category: Gameplay Functions
|
Category: Gameplay Functions
|
||||||
"""
|
"""
|
||||||
lifespan = 1.0
|
lifespan = 1.0
|
||||||
app = ba.app
|
app = bs.app
|
||||||
|
|
||||||
# FIXME: Should never vary game elements based on local config.
|
# FIXME: Should never vary game elements based on local config.
|
||||||
# (connected clients may have differing configs so they won't
|
# (connected clients may have differing configs so they won't
|
||||||
# get the intended results).
|
# get the intended results).
|
||||||
do_big = app.ui.uiscale is ba.UIScale.SMALL or app.vr_mode
|
do_big = app.ui.uiscale is bs.UIScale.SMALL or app.vr_mode
|
||||||
txtnode = ba.newnode('text',
|
txtnode = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'text': damage,
|
'text': damage,
|
||||||
'in_world': True,
|
'in_world': True,
|
||||||
|
|
@ -385,7 +383,7 @@ class UFO(ba.Actor):
|
||||||
'scale': 0.035 if do_big else 0.03
|
'scale': 0.035 if do_big else 0.03
|
||||||
})
|
})
|
||||||
# Translate upward.
|
# Translate upward.
|
||||||
tcombine = ba.newnode('combine', owner=txtnode, attrs={'size': 3})
|
tcombine = bs.newnode('combine', owner=txtnode, attrs={'size': 3})
|
||||||
tcombine.connectattr('output', txtnode, 'position')
|
tcombine.connectattr('output', txtnode, 'position')
|
||||||
v_vals = []
|
v_vals = []
|
||||||
pval = 0.0
|
pval = 0.0
|
||||||
|
|
@ -397,25 +395,25 @@ class UFO(ba.Actor):
|
||||||
vval *= 0.5
|
vval *= 0.5
|
||||||
p_start = position[0]
|
p_start = position[0]
|
||||||
p_dir = direction[0]
|
p_dir = direction[0]
|
||||||
ba.animate(tcombine, 'input0',
|
bs.animate(tcombine, 'input0',
|
||||||
{i[0] * lifespan: p_start + p_dir * i[1]
|
{i[0] * lifespan: p_start + p_dir * i[1]
|
||||||
for i in v_vals})
|
for i in v_vals})
|
||||||
p_start = position[1]
|
p_start = position[1]
|
||||||
p_dir = direction[1]
|
p_dir = direction[1]
|
||||||
ba.animate(tcombine, 'input1',
|
bs.animate(tcombine, 'input1',
|
||||||
{i[0] * lifespan: p_start + p_dir * i[1]
|
{i[0] * lifespan: p_start + p_dir * i[1]
|
||||||
for i in v_vals})
|
for i in v_vals})
|
||||||
p_start = position[2]
|
p_start = position[2]
|
||||||
p_dir = direction[2]
|
p_dir = direction[2]
|
||||||
ba.animate(tcombine, 'input2',
|
bs.animate(tcombine, 'input2',
|
||||||
{i[0] * lifespan: p_start + p_dir * i[1]
|
{i[0] * lifespan: p_start + p_dir * i[1]
|
||||||
for i in v_vals})
|
for i in v_vals})
|
||||||
ba.animate(txtnode, 'opacity', {0.7 * lifespan: 1.0, lifespan: 0.0})
|
bs.animate(txtnode, 'opacity', {0.7 * lifespan: 1.0, lifespan: 0.0})
|
||||||
ba.timer(lifespan, txtnode.delete)
|
bs.timer(lifespan, txtnode.delete)
|
||||||
|
|
||||||
def _scoreboard(self) -> None:
|
def _scoreboard(self) -> None:
|
||||||
self._backing = ba.NodeActor(
|
self._backing = bs.NodeActor(
|
||||||
ba.newnode('image',
|
bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (self.bar_posx + self._width / 2, -100),
|
'position': (self.bar_posx + self._width / 2, -100),
|
||||||
'scale': (self._width, self._height),
|
'scale': (self._width, self._height),
|
||||||
|
|
@ -427,15 +425,15 @@ class UFO(ba.Actor):
|
||||||
'attach': 'topCenter',
|
'attach': 'topCenter',
|
||||||
'texture': self._backing_tex
|
'texture': self._backing_tex
|
||||||
}))
|
}))
|
||||||
self._bar = ba.NodeActor(
|
self._bar = bs.NodeActor(
|
||||||
ba.newnode('image',
|
bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'opacity': 1.0,
|
'opacity': 1.0,
|
||||||
'color': (0.5, 0.5, 0.5),
|
'color': (0.5, 0.5, 0.5),
|
||||||
'attach': 'topCenter',
|
'attach': 'topCenter',
|
||||||
'texture': self._bar_tex
|
'texture': self._bar_tex
|
||||||
}))
|
}))
|
||||||
self._bar_scale = ba.newnode('combine',
|
self._bar_scale = bs.newnode('combine',
|
||||||
owner=self._bar.node,
|
owner=self._bar.node,
|
||||||
attrs={
|
attrs={
|
||||||
'size': 2,
|
'size': 2,
|
||||||
|
|
@ -443,7 +441,7 @@ class UFO(ba.Actor):
|
||||||
'input1': self._bar_height
|
'input1': self._bar_height
|
||||||
})
|
})
|
||||||
self._bar_scale.connectattr('output', self._bar.node, 'scale')
|
self._bar_scale.connectattr('output', self._bar.node, 'scale')
|
||||||
self._bar_position = ba.newnode(
|
self._bar_position = bs.newnode(
|
||||||
'combine',
|
'combine',
|
||||||
owner=self._bar.node,
|
owner=self._bar.node,
|
||||||
attrs={
|
attrs={
|
||||||
|
|
@ -452,8 +450,8 @@ class UFO(ba.Actor):
|
||||||
'input1': -100
|
'input1': -100
|
||||||
})
|
})
|
||||||
self._bar_position.connectattr('output', self._bar.node, 'position')
|
self._bar_position.connectattr('output', self._bar.node, 'position')
|
||||||
self._cover = ba.NodeActor(
|
self._cover = bs.NodeActor(
|
||||||
ba.newnode('image',
|
bs.newnode('image',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (self.bar_posx + 120, -100),
|
'position': (self.bar_posx + 120, -100),
|
||||||
'scale':
|
'scale':
|
||||||
|
|
@ -465,10 +463,10 @@ class UFO(ba.Actor):
|
||||||
'vr_depth': 2,
|
'vr_depth': 2,
|
||||||
'attach': 'topCenter',
|
'attach': 'topCenter',
|
||||||
'texture': self._cover_tex,
|
'texture': self._cover_tex,
|
||||||
'model_transparent': self._model
|
'mesh_transparent': self._mesh
|
||||||
}))
|
}))
|
||||||
self._score_text = ba.NodeActor(
|
self._score_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (self.bar_posx + 120, -100),
|
'position': (self.bar_posx + 120, -100),
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -487,35 +485,36 @@ class UFO(ba.Actor):
|
||||||
self._score_text.node.text = str(self.hitpoints)
|
self._score_text.node.text = str(self.hitpoints)
|
||||||
self._bar_width = self.hitpoints * self._width_max / self.hitpoints_max
|
self._bar_width = self.hitpoints * self._width_max / self.hitpoints_max
|
||||||
cur_width = self._bar_scale.input0
|
cur_width = self._bar_scale.input0
|
||||||
ba.animate(self._bar_scale, 'input0', {
|
bs.animate(self._bar_scale, 'input0', {
|
||||||
0.0: cur_width,
|
0.0: cur_width,
|
||||||
0.1: self._bar_width
|
0.1: self._bar_width
|
||||||
})
|
})
|
||||||
cur_x = self._bar_position.input0
|
cur_x = self._bar_position.input0
|
||||||
|
|
||||||
ba.animate(self._bar_position, 'input0', {
|
bs.animate(self._bar_position, 'input0', {
|
||||||
0.0: cur_x,
|
0.0: cur_x,
|
||||||
0.1: self.bar_posx + self._bar_width / 2
|
0.1: self.bar_posx + self._bar_width / 2
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.hitpoints > self.hitpoints_max * 3 / 4:
|
if self.hitpoints > self.hitpoints_max * 3 / 4:
|
||||||
ba.animate_array(self.shield_deco, 'color', 3,
|
bs.animate_array(self.shield_deco, 'color', 3,
|
||||||
{0: self.shield_deco.color, 0.2: (4, 4, 4)})
|
{0: self.shield_deco.color, 0.2: (4, 4, 4)})
|
||||||
elif self.hitpoints > self.hitpoints_max * 1 / 2:
|
elif self.hitpoints > self.hitpoints_max * 1 / 2:
|
||||||
ba.animate_array(self.shield_deco, 'color', 3,
|
bs.animate_array(self.shield_deco, 'color', 3,
|
||||||
{0: self.shield_deco.color, 0.2: (3, 3, 5)})
|
{0: self.shield_deco.color, 0.2: (3, 3, 5)})
|
||||||
self.bot_count = 4
|
self.bot_count = 4
|
||||||
|
|
||||||
elif self.hitpoints > self.hitpoints_max * 1 / 4:
|
elif self.hitpoints > self.hitpoints_max * 1 / 4:
|
||||||
ba.animate_array(self.shield_deco, 'color', 3,
|
bs.animate_array(self.shield_deco, 'color', 3,
|
||||||
{0: self.shield_deco.color, 0.2: (1, 5, 1)})
|
{0: self.shield_deco.color, 0.2: (1, 5, 1)})
|
||||||
self.bot_count = 5
|
self.bot_count = 5
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ba.animate_array(self.shield_deco, 'color', 3,
|
bs.animate_array(self.shield_deco, 'color', 3,
|
||||||
{0: self.shield_deco.color, 0.2: (5, 0.2, 0.2)})
|
{0: self.shield_deco.color, 0.2: (5, 0.2, 0.2)})
|
||||||
self.bot_count = 6
|
self.bot_count = 6
|
||||||
|
|
||||||
|
|
||||||
def update_ai(self) -> None:
|
def update_ai(self) -> None:
|
||||||
"""Should be called periodically to update the spaz' AI."""
|
"""Should be called periodically to update the spaz' AI."""
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|
@ -530,10 +529,10 @@ class UFO(ba.Actor):
|
||||||
return
|
return
|
||||||
|
|
||||||
pos = self.node.position
|
pos = self.node.position
|
||||||
our_pos = ba.Vec3(pos[0], pos[1] - self.y_pos, pos[2])
|
our_pos = bs.Vec3(pos[0], pos[1] - 3, pos[2])
|
||||||
|
|
||||||
target_pt_raw: ba.Vec3 | None
|
target_pt_raw: bs.Vec3 | None
|
||||||
target_vel: ba.Vec3 | None
|
target_vel: bs.Vec3 | None
|
||||||
|
|
||||||
target_pt_raw, target_vel = self._get_target_player_pt()
|
target_pt_raw, target_vel = self._get_target_player_pt()
|
||||||
|
|
||||||
|
|
@ -562,15 +561,12 @@ class UFO(ba.Actor):
|
||||||
setattr(self.node, 'extra_acceleration',
|
setattr(self.node, 'extra_acceleration',
|
||||||
(0, self.to_target.y * 80 + 70,
|
(0, self.to_target.y * 80 + 70,
|
||||||
0))
|
0))
|
||||||
else:
|
elif not self.frozen:
|
||||||
setattr(self.node, 'velocity',
|
setattr(self.node, 'velocity',
|
||||||
(self.to_target.x * self.xz_pos,
|
(self.to_target.x, self.to_target.y, self.to_target.z))
|
||||||
self.to_target.y,
|
|
||||||
self.to_target.z * self.xz_pos))
|
|
||||||
setattr(self.node, 'extra_acceleration',
|
setattr(self.node, 'extra_acceleration',
|
||||||
(self.to_target.x * self.xz_pos,
|
(self.to_target.x, self.to_target.y * 80 + 70,
|
||||||
self.to_target.y * 80 + 70,
|
self.to_target.z))
|
||||||
self.to_target.z * self.xz_pos))
|
|
||||||
|
|
||||||
def on_expire(self) -> None:
|
def on_expire(self) -> None:
|
||||||
super().on_expire()
|
super().on_expire()
|
||||||
|
|
@ -579,14 +575,14 @@ class UFO(ba.Actor):
|
||||||
# no chance of them keeping activities or other things alive.
|
# no chance of them keeping activities or other things alive.
|
||||||
self.update_callback = None
|
self.update_callback = None
|
||||||
|
|
||||||
def animate_model(self) -> None:
|
def animate_mesh(self) -> None:
|
||||||
if not self.node:
|
if not self.node:
|
||||||
return None
|
return None
|
||||||
# ba.animate(self.node, 'model_scale', {
|
# bs.animate(self.node, 'mesh_scale', {
|
||||||
# 0: self.node.model_scale,
|
# 0: self.node.mesh_scale,
|
||||||
# 0.08: self.node.model_scale * 0.9,
|
# 0.08: self.node.mesh_scale * 0.9,
|
||||||
# 0.15: self.node.model_scale})
|
# 0.15: self.node.mesh_scale})
|
||||||
ba.emitfx(position=self.node.position,
|
bs.emitfx(position=self.node.position,
|
||||||
velocity=self.node.velocity,
|
velocity=self.node.velocity,
|
||||||
count=int(6 + random.random() * 10),
|
count=int(6 + random.random() * 10),
|
||||||
scale=0.5,
|
scale=0.5,
|
||||||
|
|
@ -597,15 +593,15 @@ class UFO(ba.Actor):
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
assert not self.expired
|
assert not self.expired
|
||||||
|
|
||||||
if isinstance(msg, ba.HitMessage):
|
if isinstance(msg, bs.HitMessage):
|
||||||
# Don't die on punches (that's annoying).
|
# Don't die on punches (that's annoying).
|
||||||
self.animate_model()
|
self.animate_mesh()
|
||||||
if self.hitpoints != 0:
|
if self.hitpoints != 0:
|
||||||
self.do_damage(msg)
|
self.do_damage(msg)
|
||||||
# self.show_damage_msg(msg)
|
# self.show_damage_msg(msg)
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
elif isinstance(msg, ba.DieMessage):
|
elif isinstance(msg, bs.DieMessage):
|
||||||
if self.node:
|
if self.node:
|
||||||
self.hitpoints = 0
|
self.hitpoints = 0
|
||||||
self.frozen = True
|
self.frozen = True
|
||||||
|
|
@ -629,46 +625,52 @@ class UFO(ba.Actor):
|
||||||
position=(p_x, p[1], p_z),
|
position=(p_x, p[1], p_z),
|
||||||
blast_radius=2.0).autoretain()
|
blast_radius=2.0).autoretain()
|
||||||
|
|
||||||
ba.timer(0 + i, ba.Call(ded_explode, i))
|
bs.timer(0 + i, bs.Call(ded_explode, i))
|
||||||
|
|
||||||
ba.timer(5, self.node.delete)
|
bs.timer(5, self.node.delete)
|
||||||
ba.timer(0.1, self.suck.delete)
|
bs.timer(0.1, self.suck.delete)
|
||||||
ba.timer(0.1, self.suck_anim.delete)
|
bs.timer(0.1, self.suck_anim.delete)
|
||||||
|
|
||||||
elif isinstance(msg, ba.OutOfBoundsMessage):
|
elif isinstance(msg, bs.OutOfBoundsMessage):
|
||||||
activity = _ba.get_foreground_host_activity()
|
activity = bs.get_foreground_host_activity()
|
||||||
try:
|
try:
|
||||||
point = activity.map.get_flag_position(None)
|
point = activity.map.get_flag_position(None)
|
||||||
boss_spawn_pos = (point[0], point[1] + 1.5, point[2])
|
boss_spawn_pos = (point[0], point[1] + 1.5, point[2])
|
||||||
assert self.node
|
assert self.node
|
||||||
self.node.position = boss_spawn_pos
|
self.node.position = boss_spawn_pos
|
||||||
except:
|
except:
|
||||||
self.handlemessage(ba.DieMessage())
|
self.handlemessage(bs.DieMessage())
|
||||||
|
|
||||||
elif isinstance(msg, ba.FreezeMessage):
|
elif isinstance(msg, bs.FreezeMessage):
|
||||||
if not self.frozen:
|
if not self.frozen:
|
||||||
self.frozen = True
|
self.frozen = True
|
||||||
self.y_pos = -1.5
|
self.drop_bomb_timer = False
|
||||||
self.xz_pos = 0.01
|
self.drop_bots_timer = False
|
||||||
|
setattr(self.node, 'velocity',
|
||||||
|
(0, self.to_target.y, 0))
|
||||||
|
setattr(self.node, 'extra_acceleration',
|
||||||
|
(0, 0, 0))
|
||||||
self.node.reflection_scale = [2]
|
self.node.reflection_scale = [2]
|
||||||
|
|
||||||
def unfrozen():
|
def unfrozen():
|
||||||
self.frozen = False
|
self.frozen = False
|
||||||
if self.bot_dur_froze:
|
self.drop_bomb_timer = bs.Timer(1.5,
|
||||||
ba.timer(0.1, ba.Call(self._drop_bots))
|
bs.Call(self._drop_bomb),
|
||||||
self.bot_dur_froze = False
|
repeat=True)
|
||||||
self.y_pos = 3
|
|
||||||
self.xz_pos = 1
|
self.drop_bots_timer = bs.Timer(15.0,
|
||||||
|
bs.Call(self._drop_bots),
|
||||||
|
repeat=True)
|
||||||
self.node.reflection_scale = [0.25]
|
self.node.reflection_scale = [0.25]
|
||||||
|
|
||||||
ba.timer(5.0, unfrozen)
|
bs.timer(3.0, unfrozen)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
super().handlemessage(msg)
|
super().handlemessage(msg)
|
||||||
|
|
||||||
|
|
||||||
class UFOSet:
|
class UFOSet:
|
||||||
"""A container/controller for one or more ba.SpazBots.
|
"""A container/controller for one or more bs.SpazBots.
|
||||||
|
|
||||||
category: Bot Classes
|
category: Bot Classes
|
||||||
"""
|
"""
|
||||||
|
|
@ -684,9 +686,9 @@ class UFOSet:
|
||||||
self._ufo_bot_lists: list[list[UFO]] = [
|
self._ufo_bot_lists: list[list[UFO]] = [
|
||||||
[] for _ in range(self._ufo_bot_list_count)
|
[] for _ in range(self._ufo_bot_list_count)
|
||||||
]
|
]
|
||||||
self._ufo_spawn_sound = ba.getsound('spawn')
|
self._ufo_spawn_sound = bs.getsound('spawn')
|
||||||
self._ufo_spawning_count = 0
|
self._ufo_spawning_count = 0
|
||||||
self._ufo_bot_update_timer: ba.Timer | None = None
|
self._ufo_bot_update_timer: bs.Timer | None = None
|
||||||
self.start_moving()
|
self.start_moving()
|
||||||
|
|
||||||
def _update(self) -> None:
|
def _update(self) -> None:
|
||||||
|
|
@ -699,7 +701,7 @@ class UFOSet:
|
||||||
]
|
]
|
||||||
except Exception:
|
except Exception:
|
||||||
bot_list = []
|
bot_list = []
|
||||||
ba.print_exception(
|
bs.print_exception(
|
||||||
'Error updating bot list: '
|
'Error updating bot list: '
|
||||||
+ str(self._ufo_bot_lists[self._ufo_bot_update_list])
|
+ str(self._ufo_bot_lists[self._ufo_bot_update_list])
|
||||||
)
|
)
|
||||||
|
|
@ -709,8 +711,8 @@ class UFOSet:
|
||||||
|
|
||||||
# Update our list of player points for the bots to use.
|
# Update our list of player points for the bots to use.
|
||||||
player_pts = []
|
player_pts = []
|
||||||
for player in ba.getactivity().players:
|
for player in bs.getactivity().players:
|
||||||
assert isinstance(player, ba.Player)
|
assert isinstance(player, bs.Player)
|
||||||
try:
|
try:
|
||||||
# TODO: could use abstracted player.position here so we
|
# TODO: could use abstracted player.position here so we
|
||||||
# don't have to assume their actor type, but we have no
|
# don't have to assume their actor type, but we have no
|
||||||
|
|
@ -720,12 +722,12 @@ class UFOSet:
|
||||||
assert player.actor.node
|
assert player.actor.node
|
||||||
player_pts.append(
|
player_pts.append(
|
||||||
(
|
(
|
||||||
ba.Vec3(player.actor.node.position),
|
bs.Vec3(player.actor.node.position),
|
||||||
ba.Vec3(player.actor.node.velocity),
|
bs.Vec3(player.actor.node.velocity),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error on bot-set _update.')
|
bs.print_exception('Error on bot-set _update.')
|
||||||
|
|
||||||
for bot in bot_list:
|
for bot in bot_list:
|
||||||
bot.set_player_points(player_pts)
|
bot.set_player_points(player_pts)
|
||||||
|
|
@ -733,8 +735,8 @@ class UFOSet:
|
||||||
|
|
||||||
def start_moving(self) -> None:
|
def start_moving(self) -> None:
|
||||||
"""Start processing bot AI updates so they start doing their thing."""
|
"""Start processing bot AI updates so they start doing their thing."""
|
||||||
self._ufo_bot_update_timer = ba.Timer(
|
self._ufo_bot_update_timer = bs.Timer(
|
||||||
0.05, ba.WeakCall(self._update), repeat=True
|
0.05, bs.WeakCall(self._update), repeat=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def spawn_bot(
|
def spawn_bot(
|
||||||
|
|
@ -745,13 +747,13 @@ class UFOSet:
|
||||||
on_spawn_call: Callable[[UFO], Any] | None = None,
|
on_spawn_call: Callable[[UFO], Any] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Spawn a bot from this set."""
|
"""Spawn a bot from this set."""
|
||||||
from bastd.actor import spawner
|
from bascenev1lib.actor import spawner
|
||||||
|
|
||||||
spawner.Spawner(
|
spawner.Spawner(
|
||||||
pt=pos,
|
pt=pos,
|
||||||
spawn_time=spawn_time,
|
spawn_time=spawn_time,
|
||||||
send_spawn_message=False,
|
send_spawn_message=False,
|
||||||
spawn_callback=ba.Call(
|
spawn_callback=bs.Call(
|
||||||
self._spawn_bot, bot_type, pos, on_spawn_call
|
self._spawn_bot, bot_type, pos, on_spawn_call
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -764,18 +766,18 @@ class UFOSet:
|
||||||
on_spawn_call: Callable[[UFO], Any] | None,
|
on_spawn_call: Callable[[UFO], Any] | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
spaz = bot_type()
|
spaz = bot_type()
|
||||||
ba.playsound(self._ufo_spawn_sound, position=pos)
|
self._ufo_spawn_sound.play(position=pos)
|
||||||
assert spaz.node
|
assert spaz.node
|
||||||
spaz.node.handlemessage('flash')
|
spaz.node.handlemessage('flash')
|
||||||
spaz.node.is_area_of_interest = False
|
spaz.node.is_area_of_interest = False
|
||||||
spaz.handlemessage(ba.StandMessage(pos, random.uniform(0, 360)))
|
spaz.handlemessage(bs.StandMessage(pos, random.uniform(0, 360)))
|
||||||
self.add_bot(spaz)
|
self.add_bot(spaz)
|
||||||
self._ufo_spawning_count -= 1
|
self._ufo_spawning_count -= 1
|
||||||
if on_spawn_call is not None:
|
if on_spawn_call is not None:
|
||||||
on_spawn_call(spaz)
|
on_spawn_call(spaz)
|
||||||
|
|
||||||
def add_bot(self, bot: UFO) -> None:
|
def add_bot(self, bot: UFO) -> None:
|
||||||
"""Add a ba.SpazBot instance to the set."""
|
"""Add a bs.SpazBot instance to the set."""
|
||||||
self._ufo_bot_lists[self._ufo_bot_add_list].append(bot)
|
self._ufo_bot_lists[self._ufo_bot_add_list].append(bot)
|
||||||
self._ufo_bot_add_list = (
|
self._ufo_bot_add_list = (
|
||||||
self._ufo_bot_add_list + 1) % self._ufo_bot_list_count
|
self._ufo_bot_add_list + 1) % self._ufo_bot_list_count
|
||||||
|
|
@ -799,26 +801,26 @@ class UFOSet:
|
||||||
"""Immediately clear out any bots in the set."""
|
"""Immediately clear out any bots in the set."""
|
||||||
|
|
||||||
# Don't do this if the activity is shutting down or dead.
|
# Don't do this if the activity is shutting down or dead.
|
||||||
activity = ba.getactivity(doraise=False)
|
activity = bs.getactivity(doraise=False)
|
||||||
if activity is None or activity.expired:
|
if activity is None or activity.expired:
|
||||||
return
|
return
|
||||||
|
|
||||||
for i, bot_list in enumerate(self._ufo_bot_lists):
|
for i, bot_list in enumerate(self._ufo_bot_lists):
|
||||||
for bot in bot_list:
|
for bot in bot_list:
|
||||||
bot.handlemessage(ba.DieMessage(immediate=True))
|
bot.handlemessage(bs.DieMessage(immediate=True))
|
||||||
self._ufo_bot_lists[i] = []
|
self._ufo_bot_lists[i] = []
|
||||||
|
|
||||||
|
|
||||||
class Player(ba.Player['Team']):
|
class Player(bs.Player['Team']):
|
||||||
"""Our player type for this game."""
|
"""Our player type for this game."""
|
||||||
|
|
||||||
|
|
||||||
class Team(ba.Team[Player]):
|
class Team(bs.Team[Player]):
|
||||||
"""Our team type for this game."""
|
"""Our team type for this game."""
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
class UFOightGame(bs.TeamGameActivity[Player, Team]):
|
||||||
"""
|
"""
|
||||||
A co-op game where you try to defeat UFO Boss
|
A co-op game where you try to defeat UFO Boss
|
||||||
as fast as possible
|
as fast as possible
|
||||||
|
|
@ -826,33 +828,33 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
name = 'UFO Fight'
|
name = 'UFO Fight'
|
||||||
description = 'REal Boss Fight?'
|
description = 'REal Boss Fight?'
|
||||||
scoreconfig = ba.ScoreConfig(
|
scoreconfig = bs.ScoreConfig(
|
||||||
label='Time', scoretype=ba.ScoreType.MILLISECONDS, lower_is_better=True
|
label='Time', scoretype=bs.ScoreType.MILLISECONDS, lower_is_better=True
|
||||||
)
|
)
|
||||||
default_music = ba.MusicType.TO_THE_DEATH
|
default_music = bs.MusicType.TO_THE_DEATH
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_supported_maps(cls, sessiontype: type[ba.Session]) -> list[str]:
|
def get_supported_maps(cls, sessiontype: type[bs.Session]) -> list[str]:
|
||||||
# For now we're hard-coding spawn positions and whatnot
|
# For now we're hard-coding spawn positions and whatnot
|
||||||
# so we need to be sure to specify that we only support
|
# so we need to be sure to specify that we only support
|
||||||
# a specific map.
|
# a specific map.
|
||||||
return ['Football Stadium']
|
return ['Football Stadium']
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def supports_session_type(cls, sessiontype: type[ba.Session]) -> bool:
|
def supports_session_type(cls, sessiontype: type[bs.Session]) -> bool:
|
||||||
# We currently support Co-Op only.
|
# We currently support Co-Op only.
|
||||||
return issubclass(sessiontype, ba.CoopSession)
|
return issubclass(sessiontype, bs.CoopSession)
|
||||||
|
|
||||||
# In the constructor we should load any media we need/etc.
|
# In the constructor we should load any media we need/etc.
|
||||||
# ...but not actually create anything yet.
|
# ...but not actually create anything yet.
|
||||||
def __init__(self, settings: dict):
|
def __init__(self, settings: dict):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
self._winsound = ba.getsound('score')
|
self._winsound = bs.getsound('score')
|
||||||
self._won = False
|
self._won = False
|
||||||
self._timer: OnScreenTimer | None = None
|
self._timer: OnScreenTimer | None = None
|
||||||
self._bots = UFOSet()
|
self._bots = UFOSet()
|
||||||
self._preset = str(settings['preset'])
|
self._preset = str(settings['preset'])
|
||||||
self._credit = ba.newnode('text',
|
self._credit = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'v_attach': 'bottom',
|
'v_attach': 'bottom',
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
|
|
@ -864,9 +866,11 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
'text': 'By Cross Joy'
|
'text': 'By Cross Joy'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def on_transition_in(self) -> None:
|
def on_transition_in(self) -> None:
|
||||||
super().on_transition_in()
|
super().on_transition_in()
|
||||||
gnode = ba.getactivity().globalsnode
|
gnode = bs.getactivity().globalsnode
|
||||||
gnode.tint = (0.42, 0.55, 0.66)
|
gnode.tint = (0.42, 0.55, 0.66)
|
||||||
|
|
||||||
# Called when our game actually begins.
|
# Called when our game actually begins.
|
||||||
|
|
@ -874,24 +878,26 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
self.setup_standard_powerup_drops()
|
self.setup_standard_powerup_drops()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# In pro mode there's no powerups.
|
# In pro mode there's no powerups.
|
||||||
|
|
||||||
# Make our on-screen timer and start it roughly when our bots appear.
|
# Make our on-screen timer and start it roughly when our bots appear.
|
||||||
self._timer = OnScreenTimer()
|
self._timer = OnScreenTimer()
|
||||||
ba.timer(4.0, self._timer.start)
|
bs.timer(4.0, self._timer.start)
|
||||||
|
|
||||||
def checker():
|
def checker():
|
||||||
if not self._won:
|
if not self._won:
|
||||||
self.timer = ba.Timer(0.1, self._check_if_won, repeat=True)
|
self.timer = bs.Timer(0.1, self._check_if_won, repeat=True)
|
||||||
|
|
||||||
ba.timer(10, checker)
|
bs.timer(10, checker)
|
||||||
activity = _ba.get_foreground_host_activity()
|
activity = bs.get_foreground_host_activity()
|
||||||
|
|
||||||
point = activity.map.get_flag_position(None)
|
point = activity.map.get_flag_position(None)
|
||||||
boss_spawn_pos = (point[0], point[1] + 1.5, point[2])
|
boss_spawn_pos = (point[0], point[1] + 1.5, point[2])
|
||||||
|
|
||||||
# Spawn some baddies.
|
# Spawn some baddies.
|
||||||
ba.timer(
|
bs.timer(
|
||||||
1.0,
|
1.0,
|
||||||
lambda: self._bots.spawn_bot(
|
lambda: self._bots.spawn_bot(
|
||||||
UFO, pos=boss_spawn_pos, spawn_time=3.0
|
UFO, pos=boss_spawn_pos, spawn_time=3.0
|
||||||
|
|
@ -915,10 +921,10 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
def handlemessage(self, msg: Any) -> Any:
|
def handlemessage(self, msg: Any) -> Any:
|
||||||
|
|
||||||
# A player has died.
|
# A player has died.
|
||||||
if isinstance(msg, ba.PlayerDiedMessage):
|
if isinstance(msg, bs.PlayerDiedMessage):
|
||||||
player = msg.getplayer(Player)
|
player = msg.getplayer(Player)
|
||||||
self.stats.player_was_killed(player)
|
self.stats.player_was_killed(player)
|
||||||
ba.timer(0.1, self._checkroundover)
|
bs.timer(0.1, self._checkroundover)
|
||||||
|
|
||||||
# A spaz-bot has died.
|
# A spaz-bot has died.
|
||||||
elif isinstance(msg, UFODiedMessage):
|
elif isinstance(msg, UFODiedMessage):
|
||||||
|
|
@ -926,7 +932,7 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
# bots if we ask here (the currently-dying bot isn't officially
|
# bots if we ask here (the currently-dying bot isn't officially
|
||||||
# marked dead yet) ..so lets push a call into the event loop to
|
# marked dead yet) ..so lets push a call into the event loop to
|
||||||
# check once this guy has finished dying.
|
# check once this guy has finished dying.
|
||||||
ba.pushcall(self._check_if_won)
|
bs.pushcall(self._check_if_won)
|
||||||
|
|
||||||
# Let the base class handle anything we don't.
|
# Let the base class handle anything we don't.
|
||||||
else:
|
else:
|
||||||
|
|
@ -948,20 +954,20 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
assert self._timer is not None
|
assert self._timer is not None
|
||||||
self._timer.stop()
|
self._timer.stop()
|
||||||
|
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
|
|
||||||
# If we won, set our score to the elapsed time in milliseconds.
|
# If we won, set our score to the elapsed time in milliseconds.
|
||||||
# (there should just be 1 team here since this is co-op).
|
# (there should just be 1 team here since this is co-op).
|
||||||
# ..if we didn't win, leave scores as default (None) which means
|
# ..if we didn't win, leave scores as default (None) which means
|
||||||
# we lost.
|
# we lost.
|
||||||
if self._won:
|
if self._won:
|
||||||
elapsed_time_ms = int((ba.time() - self._timer.starttime) * 1000.0)
|
elapsed_time_ms = int((bs.time() - self._timer.starttime) * 1000.0)
|
||||||
ba.cameraflash()
|
bs.cameraflash()
|
||||||
ba.playsound(self._winsound)
|
self._winsound.play()
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
for player in team.players:
|
for player in team.players:
|
||||||
if player.actor:
|
if player.actor:
|
||||||
player.actor.handlemessage(ba.CelebrateMessage())
|
player.actor.handlemessage(bs.CelebrateMessage())
|
||||||
results.set_team_score(team, elapsed_time_ms)
|
results.set_team_score(team, elapsed_time_ms)
|
||||||
|
|
||||||
# Ends the activity.
|
# Ends the activity.
|
||||||
|
|
@ -969,11 +975,11 @@ class UFOightGame(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export plugin
|
# ba_meta export plugin
|
||||||
class MyUFOFightLevel(ba.Plugin):
|
class MyUFOFightLevel(babase.Plugin):
|
||||||
|
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs.Level(
|
||||||
name='The UFO Fight',
|
name='The UFO Fight',
|
||||||
displayname='${GAME}',
|
displayname='${GAME}',
|
||||||
gametype=UFOightGame,
|
gametype=UFOightGame,
|
||||||
|
|
@ -981,3 +987,4 @@ class MyUFOFightLevel(ba.Plugin):
|
||||||
preview_texture_name='footballStadiumPreview',
|
preview_texture_name='footballStadiumPreview',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
"""Ultimate Last Stand V2:
|
"""Ultimate Last Stand V2:
|
||||||
Made by Cross Joy"""
|
Made by Cross Joy"""
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ Made by Cross Joy"""
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
# ba_meta require api 7
|
# ba_meta require api 8
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
@ -33,13 +34,15 @@ import random
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import ba
|
import babase
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
import bauiv1 as bui
|
||||||
from bastd.actor.bomb import TNTSpawner
|
import bascenev1 as bs
|
||||||
from bastd.actor.onscreentimer import OnScreenTimer
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.bomb import TNTSpawner
|
||||||
from bastd.actor.spazfactory import SpazFactory
|
from bascenev1lib.actor.onscreentimer import OnScreenTimer
|
||||||
from bastd.actor.spazbot import (SpazBot, SpazBotSet, BomberBot,
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
|
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||||
|
from bascenev1lib.actor.spazbot import (SpazBot, SpazBotSet, BomberBot,
|
||||||
BomberBotPro, BomberBotProShielded,
|
BomberBotPro, BomberBotProShielded,
|
||||||
BrawlerBot, BrawlerBotPro,
|
BrawlerBot, BrawlerBotPro,
|
||||||
BrawlerBotProShielded, TriggerBot,
|
BrawlerBotProShielded, TriggerBot,
|
||||||
|
|
@ -48,7 +51,7 @@ from bastd.actor.spazbot import (SpazBot, SpazBotSet, BomberBot,
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, Sequence
|
from typing import Any, Sequence
|
||||||
from bastd.actor.spazbot import SpazBot
|
from bascenev1lib.actor.spazbot import SpazBot
|
||||||
|
|
||||||
|
|
||||||
class IceBot(SpazBot):
|
class IceBot(SpazBot):
|
||||||
|
|
@ -71,7 +74,7 @@ class IceBot(SpazBot):
|
||||||
points_mult = 3
|
points_mult = 3
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -90,10 +93,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'],
|
||||||
|
|
@ -106,12 +109,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,
|
||||||
|
|
@ -122,7 +125,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',
|
||||||
|
|
@ -178,7 +181,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,
|
||||||
|
|
@ -195,10 +198,10 @@ 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)
|
||||||
|
|
@ -212,7 +215,7 @@ class SpawnInfo:
|
||||||
dincrease: float
|
dincrease: float
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -222,7 +225,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:
|
||||||
|
|
@ -230,14 +233,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 UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
class UltimateLastStand(bs.TeamGameActivity[Player, Team]):
|
||||||
"""Minigame involving dodging falling bombs."""
|
"""Minigame involving dodging falling bombs."""
|
||||||
|
|
||||||
name = 'Ultimate Last Stand'
|
name = 'Ultimate Last Stand'
|
||||||
description = 'Only the strongest will stand at the end.'
|
description = 'Only the strongest will stand at the end.'
|
||||||
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)
|
||||||
|
|
||||||
# Print messages when players die (since its meaningful in this game).
|
# Print messages when players die (since its meaningful in this game).
|
||||||
|
|
@ -250,16 +253,16 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_settings(
|
def get_available_settings(
|
||||||
cls,
|
cls,
|
||||||
sessiontype: type[ba.Session]) -> list[ba.Setting]:
|
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.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -270,31 +273,31 @@ class UltimateLastStand(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
|
||||||
|
|
||||||
# We're currently hard-coded for one map.
|
# We're currently hard-coded for one map.
|
||||||
@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 ['Rampage']
|
return ['Rampage']
|
||||||
|
|
||||||
# We support teams, free-for-all, and co-op sessions.
|
# We support teams, free-for-all, and co-op sessions.
|
||||||
@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)
|
||||||
or issubclass(sessiontype, ba.FreeForAllSession))
|
or issubclass(sessiontype, bs.FreeForAllSession))
|
||||||
|
|
||||||
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: float | None = None
|
self._start_time: float | None = None
|
||||||
self._vs_text: ba.Actor | None = None
|
self._vs_text: bs.Actor | None = None
|
||||||
self._round_end_timer: ba.Timer | None = None
|
self._round_end_timer: bs.Timer | None = None
|
||||||
self._lives_per_player = int(settings['Lives Per Player'])
|
self._lives_per_player = int(settings['Lives Per Player'])
|
||||||
self._balance_total_lives = bool(
|
self._balance_total_lives = bool(
|
||||||
settings.get('Balance Total Lives', False))
|
settings.get('Balance Total Lives', False))
|
||||||
|
|
@ -302,17 +305,17 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
self._last_player_death_time: float | None = None
|
self._last_player_death_time: float | None = None
|
||||||
self._timer: OnScreenTimer | None = None
|
self._timer: OnScreenTimer | None = None
|
||||||
self._tntspawner: TNTSpawner | None = None
|
self._tntspawner: TNTSpawner | None = None
|
||||||
self._new_wave_sound = ba.getsound('scoreHit01')
|
self._new_wave_sound = bs.getsound('scoreHit01')
|
||||||
self._bots = SpazBotSet()
|
self._bots = SpazBotSet()
|
||||||
self._tntspawnpos = (0, 5.5, -6)
|
self._tntspawnpos = (0, 5.5, -6)
|
||||||
self.spazList = []
|
self.spazList = []
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
||||||
self.node = ba.newnode('text',
|
self.node = bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'v_attach': 'bottom',
|
'v_attach': 'bottom',
|
||||||
'h_align': 'center',
|
'h_align': 'center',
|
||||||
|
|
@ -342,24 +345,24 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
} # yapf: disable
|
} # yapf: disable
|
||||||
|
|
||||||
# Some base class overrides:
|
# Some base class overrides:
|
||||||
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)
|
||||||
if self._epic_mode:
|
if self._epic_mode:
|
||||||
self.slow_motion = True
|
self.slow_motion = True
|
||||||
|
|
||||||
def get_instance_description(self) -> str | Sequence:
|
def get_instance_description(self) -> str | Sequence:
|
||||||
return 'Only the strongest team will stand at the end.' if isinstance(
|
return 'Only the strongest team will stand at the end.' if isinstance(
|
||||||
self.session,
|
self.session,
|
||||||
ba.DualTeamSession) else 'Only the strongest will stand at the end.'
|
bs.DualTeamSession) else 'Only the strongest will stand at the end.'
|
||||||
|
|
||||||
def get_instance_description_short(self) -> str | Sequence:
|
def get_instance_description_short(self) -> str | Sequence:
|
||||||
return 'Only the strongest team will stand at the end.' if isinstance(
|
return 'Only the strongest team will stand at the end.' if isinstance(
|
||||||
self.session,
|
self.session,
|
||||||
ba.DualTeamSession) else 'Only the strongest will stand at the end.'
|
bs.DualTeamSession) else 'Only the strongest will stand at the end.'
|
||||||
|
|
||||||
def on_transition_in(self) -> None:
|
def on_transition_in(self) -> None:
|
||||||
super().on_transition_in()
|
super().on_transition_in()
|
||||||
ba.timer(1.3, ba.Call(ba.playsound, self._new_wave_sound))
|
bs.timer(1.3, babase.Call(babase.playsound, self._new_wave_sound))
|
||||||
|
|
||||||
def on_player_join(self, player: Player) -> None:
|
def on_player_join(self, player: Player) -> None:
|
||||||
player.lives = self._lives_per_player
|
player.lives = self._lives_per_player
|
||||||
|
|
@ -374,13 +377,13 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
def on_begin(self) -> None:
|
def on_begin(self) -> None:
|
||||||
super().on_begin()
|
super().on_begin()
|
||||||
ba.animate_array(node=self.node, attr='color', size=3, keys={
|
bs.animate_array(node=self.node, attr='color', size=3, keys={
|
||||||
0.0: (0.5, 0.5, 0.5),
|
0.0: (0.5, 0.5, 0.5),
|
||||||
0.8: (0.83, 0.69, 0.21),
|
0.8: (0.83, 0.69, 0.21),
|
||||||
1.6: (0.5, 0.5, 0.5)
|
1.6: (0.5, 0.5, 0.5)
|
||||||
}, loop=True)
|
}, loop=True)
|
||||||
|
|
||||||
ba.timer(0.001, ba.WeakCall(self._start_bot_updates))
|
bs.timer(0.001, bs.WeakCall(self._start_bot_updates))
|
||||||
self._tntspawner = TNTSpawner(position=self._tntspawnpos,
|
self._tntspawner = TNTSpawner(position=self._tntspawnpos,
|
||||||
respawn_time=10.0)
|
respawn_time=10.0)
|
||||||
|
|
||||||
|
|
@ -389,11 +392,11 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
self.setup_standard_powerup_drops()
|
self.setup_standard_powerup_drops()
|
||||||
|
|
||||||
# Check for immediate end (if we've only got 1 player, etc).
|
# Check for immediate end (if we've only got 1 player, etc).
|
||||||
self._start_time = ba.time()
|
self._start_time = bs.time()
|
||||||
|
|
||||||
# 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(
|
||||||
|
|
@ -409,7 +412,7 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
lesser_team.players[add_index].lives += 1
|
lesser_team.players[add_index].lives += 1
|
||||||
add_index = (add_index + 1) % len(lesser_team.players)
|
add_index = (add_index + 1) % len(lesser_team.players)
|
||||||
|
|
||||||
ba.timer(1.0, self._update, repeat=True)
|
bs.timer(1.0, self._update, repeat=True)
|
||||||
self._update_icons()
|
self._update_icons()
|
||||||
|
|
||||||
# We could check game-over conditions at explicit trigger points,
|
# We could check game-over conditions at explicit trigger points,
|
||||||
|
|
@ -419,7 +422,7 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|
||||||
# In free-for-all mode, everyone is just lined up along the bottom.
|
# In free-for-all mode, everyone is just lined up along the bottom.
|
||||||
if isinstance(self.session, ba.FreeForAllSession):
|
if isinstance(self.session, bs.FreeForAllSession):
|
||||||
count = len(self.teams)
|
count = len(self.teams)
|
||||||
x_offs = 85
|
x_offs = 85
|
||||||
xval = x_offs * (count - 1) * -0.5
|
xval = x_offs * (count - 1) * -0.5
|
||||||
|
|
@ -453,21 +456,21 @@ class UltimateLastStand(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)
|
||||||
|
|
||||||
# A departing player may trigger game-over.
|
# A departing player may trigger game-over.
|
||||||
|
|
||||||
# overriding the default character spawning..
|
# overriding the default character spawning..
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
actor = self.spawn_player_spaz(player)
|
actor = self.spawn_player_spaz(player)
|
||||||
ba.timer(0.3, ba.Call(self._print_lives, player))
|
bs.timer(0.3, babase.Call(self._print_lives, player))
|
||||||
|
|
||||||
# If we have any icons, update their state.
|
# If we have any icons, update their state.
|
||||||
for icon in player.icons:
|
for icon in player.icons:
|
||||||
|
|
@ -475,7 +478,7 @@ class UltimateLastStand(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:
|
||||||
|
|
@ -499,14 +502,14 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
self._update_bots()
|
self._update_bots()
|
||||||
if len(self.players) > 3:
|
if len(self.players) > 3:
|
||||||
self._update_bots()
|
self._update_bots()
|
||||||
self._bot_update_timer = ba.Timer(self._bot_update_interval,
|
self._bot_update_timer = bs.Timer(self._bot_update_interval,
|
||||||
ba.WeakCall(self._update_bots))
|
bs.WeakCall(self._update_bots))
|
||||||
|
|
||||||
def _update_bots(self) -> None:
|
def _update_bots(self) -> None:
|
||||||
assert self._bot_update_interval is not None
|
assert self._bot_update_interval is not None
|
||||||
self._bot_update_interval = max(0.5, self._bot_update_interval * 0.98)
|
self._bot_update_interval = max(0.5, self._bot_update_interval * 0.98)
|
||||||
self._bot_update_timer = ba.Timer(self._bot_update_interval,
|
self._bot_update_timer = bs.Timer(self._bot_update_interval,
|
||||||
ba.WeakCall(self._update_bots))
|
bs.WeakCall(self._update_bots))
|
||||||
botspawnpts: list[Sequence[float]] = [[-5.0, 5.5, -4.14],
|
botspawnpts: list[Sequence[float]] = [[-5.0, 5.5, -4.14],
|
||||||
[0.0, 5.5, -4.14],
|
[0.0, 5.5, -4.14],
|
||||||
[5.0, 5.5, -4.14]]
|
[5.0, 5.5, -4.14]]
|
||||||
|
|
@ -516,7 +519,7 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
assert isinstance(player.actor, PlayerSpaz)
|
assert isinstance(player.actor, PlayerSpaz)
|
||||||
assert player.actor.node
|
assert player.actor.node
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error updating bots.')
|
babase.print_exception('Error updating bots.')
|
||||||
|
|
||||||
spawnpt = random.choice(
|
spawnpt = random.choice(
|
||||||
[botspawnpts[0], botspawnpts[1], botspawnpts[2]])
|
[botspawnpts[0], botspawnpts[1], botspawnpts[2]])
|
||||||
|
|
@ -550,12 +553,12 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Various high-level game events come through this method.
|
# Various high-level game events come through this method.
|
||||||
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)
|
||||||
|
|
||||||
curtime = ba.time()
|
curtime = bs.time()
|
||||||
|
|
||||||
# Record the player's moment of death.
|
# Record the player's moment of death.
|
||||||
# assert isinstance(msg.spaz.player
|
# assert isinstance(msg.spaz.player
|
||||||
|
|
@ -574,14 +577,14 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
# Play big death sound on our last death
|
# Play big death sound on our last death
|
||||||
# or for every one in solo mode.
|
# or for every one in solo mode.
|
||||||
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)
|
||||||
else:
|
else:
|
||||||
# Otherwise, in regular mode, respawn.
|
# Otherwise, in regular mode, respawn.
|
||||||
|
|
@ -599,7 +602,7 @@ class UltimateLastStand(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 end_game(self) -> None:
|
def end_game(self) -> None:
|
||||||
# Stop updating our time text, and set the final time to match
|
# Stop updating our time text, and set the final time to match
|
||||||
|
|
@ -608,7 +611,7 @@ class UltimateLastStand(ba.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
# Ok now calc game results: set a score for each team and then tell
|
# Ok now calc game results: set a score for each team and then tell
|
||||||
# the game to end.
|
# the game to end.
|
||||||
results = ba.GameResults()
|
results = bs.GameResults()
|
||||||
|
|
||||||
# Remember that 'free-for-all' mode is simply a special form
|
# Remember that 'free-for-all' mode is simply a special form
|
||||||
# of 'teams' mode where each player gets their own team, so we can
|
# of 'teams' mode where each player gets their own team, so we can
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,26 @@
|
||||||
# ba_meta require api 7
|
# Porting to api 8 made easier by baport.(https://github.com/bombsquad-community/baport)
|
||||||
|
# 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
|
||||||
import _ba
|
import bauiv1 as bui
|
||||||
|
import bascenev1 as bs
|
||||||
|
import _babase
|
||||||
import copy
|
import copy
|
||||||
import random
|
import random
|
||||||
from ba import _math
|
from babase import _math
|
||||||
from ba._coopsession import CoopSession
|
from bascenev1._coopsession import CoopSession
|
||||||
from ba._messages import PlayerDiedMessage, StandMessage
|
from bascenev1._messages import PlayerDiedMessage, StandMessage
|
||||||
from bastd.actor.playerspaz import PlayerSpaz
|
from bascenev1lib.actor.playerspaz import PlayerSpaz
|
||||||
from bastd.actor.scoreboard import Scoreboard
|
from bascenev1lib.actor.scoreboard import Scoreboard
|
||||||
from bastd.game.elimination import Icon, Player
|
from bascenev1lib.game.elimination import Icon, Player
|
||||||
from bastd.actor.spaz import PickupMessage
|
from bascenev1lib.actor.spaz import PickupMessage
|
||||||
from bastd.actor.spazbot import SpazBotSet, BrawlerBot, SpazBotDiedMessage
|
from bascenev1lib.actor.spazbot import SpazBotSet, BrawlerBot, SpazBotDiedMessage
|
||||||
from bastd.actor.spazfactory import SpazFactory
|
from bascenev1lib.actor.spazfactory import SpazFactory
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -26,7 +29,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
class PlayerSpaz_Zom(PlayerSpaz):
|
class PlayerSpaz_Zom(PlayerSpaz):
|
||||||
def handlemessage(self, m: Any) -> Any:
|
def handlemessage(self, m: Any) -> Any:
|
||||||
if isinstance(m, ba.HitMessage):
|
if isinstance(m, bs.HitMessage):
|
||||||
if not self.node:
|
if not self.node:
|
||||||
return
|
return
|
||||||
if not m._source_player is None:
|
if not m._source_player is None:
|
||||||
|
|
@ -40,7 +43,7 @@ class PlayerSpaz_Zom(PlayerSpaz):
|
||||||
else:
|
else:
|
||||||
super().handlemessage(m)
|
super().handlemessage(m)
|
||||||
|
|
||||||
elif isinstance(m, ba.FreezeMessage):
|
elif isinstance(m, bs.FreezeMessage):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
elif isinstance(m, PickupMessage):
|
elif isinstance(m, PickupMessage):
|
||||||
|
|
@ -48,10 +51,10 @@ class PlayerSpaz_Zom(PlayerSpaz):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
collision = ba.getcollision()
|
collision = bs.getcollision()
|
||||||
opposingnode = collision.opposingnode
|
opposingnode = collision.opposingnode
|
||||||
opposingbody = collision.opposingbody
|
opposingbody = collision.opposingbody
|
||||||
except ba.NotFoundError:
|
except bs.NotFoundError:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -85,7 +88,7 @@ class PlayerSpaz_Zom(PlayerSpaz):
|
||||||
|
|
||||||
class PlayerZombie(PlayerSpaz):
|
class PlayerZombie(PlayerSpaz):
|
||||||
def handlemessage(self, m: Any) -> Any:
|
def handlemessage(self, m: Any) -> Any:
|
||||||
if isinstance(m, ba.HitMessage):
|
if isinstance(m, bs.HitMessage):
|
||||||
if not self.node:
|
if not self.node:
|
||||||
return None
|
return None
|
||||||
if not m._source_player is None:
|
if not m._source_player is None:
|
||||||
|
|
@ -106,8 +109,8 @@ class PlayerZombie(PlayerSpaz):
|
||||||
class zBotSet(SpazBotSet):
|
class zBotSet(SpazBotSet):
|
||||||
def start_moving(self) -> None:
|
def start_moving(self) -> None:
|
||||||
"""Start processing bot AI updates so they start doing their thing."""
|
"""Start processing bot AI updates so they start doing their thing."""
|
||||||
self._bot_update_timer = ba.Timer(0.05,
|
self._bot_update_timer = bs.Timer(0.05,
|
||||||
ba.WeakCall(self.zUpdate),
|
bs.WeakCall(self.zUpdate),
|
||||||
repeat=True)
|
repeat=True)
|
||||||
|
|
||||||
def zUpdate(self) -> None:
|
def zUpdate(self) -> None:
|
||||||
|
|
@ -118,31 +121,31 @@ class zBotSet(SpazBotSet):
|
||||||
])
|
])
|
||||||
except Exception:
|
except Exception:
|
||||||
bot_list = []
|
bot_list = []
|
||||||
ba.print_exception('Error updating bot list: ' +
|
babase.print_exception('Error updating bot list: ' +
|
||||||
str(self._bot_lists[self._bot_update_list]))
|
str(self._bot_lists[self._bot_update_list]))
|
||||||
self._bot_update_list = (self._bot_update_list +
|
self._bot_update_list = (self._bot_update_list +
|
||||||
1) % self._bot_list_count
|
1) % self._bot_list_count
|
||||||
|
|
||||||
player_pts = []
|
player_pts = []
|
||||||
for player in ba.getactivity().players:
|
for player in bs.getactivity().players:
|
||||||
assert isinstance(player, ba.Player)
|
assert isinstance(player, bs.Player)
|
||||||
try:
|
try:
|
||||||
if player.is_alive():
|
if player.is_alive():
|
||||||
assert isinstance(player.actor, Spaz)
|
assert isinstance(player.actor, Spaz)
|
||||||
assert player.actor.node
|
assert player.actor.node
|
||||||
if player.lives > 0:
|
if player.lives > 0:
|
||||||
player_pts.append(
|
player_pts.append(
|
||||||
(ba.Vec3(player.actor.node.position),
|
(babase.Vec3(player.actor.node.position),
|
||||||
ba.Vec3(player.actor.node.velocity)))
|
babase.Vec3(player.actor.node.velocity)))
|
||||||
except Exception:
|
except Exception:
|
||||||
ba.print_exception('Error on bot-set _update.')
|
babase.print_exception('Error on bot-set _update.')
|
||||||
|
|
||||||
for bot in bot_list:
|
for bot in bot_list:
|
||||||
bot.set_player_points(player_pts)
|
bot.set_player_points(player_pts)
|
||||||
bot.update_ai()
|
bot.update_ai()
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -150,13 +153,13 @@ 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 ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
class ZombieHorde(bs.TeamGameActivity[Player, Team]):
|
||||||
|
|
||||||
name = 'Zombie Horde'
|
name = 'Zombie Horde'
|
||||||
description = 'Kill walkers for points!'
|
description = 'Kill walkers for points!'
|
||||||
scoreconfig = ba.ScoreConfig(label='Score',
|
scoreconfig = bs.ScoreConfig(label='Score',
|
||||||
scoretype=ba.ScoreType.POINTS,
|
scoretype=bs.ScoreType.POINTS,
|
||||||
none_is_winner=False,
|
none_is_winner=False,
|
||||||
lower_is_better=False)
|
lower_is_better=False)
|
||||||
# Show messages when players die since it's meaningful here.
|
# Show messages when players die since it's meaningful here.
|
||||||
|
|
@ -164,23 +167,23 @@ class ZombieHorde(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(
|
||||||
'Max Zombies',
|
'Max Zombies',
|
||||||
default=10,
|
default=10,
|
||||||
min_value=5,
|
min_value=5,
|
||||||
max_value=50,
|
max_value=50,
|
||||||
increment=5,
|
increment=5,
|
||||||
),
|
),
|
||||||
ba.IntChoiceSetting(
|
bs.IntChoiceSetting(
|
||||||
'Time Limit',
|
'Time Limit',
|
||||||
choices=[
|
choices=[
|
||||||
('None', 0),
|
('None', 0),
|
||||||
|
|
@ -192,7 +195,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
],
|
],
|
||||||
default=0,
|
default=0,
|
||||||
),
|
),
|
||||||
ba.FloatChoiceSetting(
|
bs.FloatChoiceSetting(
|
||||||
'Respawn Times',
|
'Respawn Times',
|
||||||
choices=[
|
choices=[
|
||||||
('Shorter', 0.25),
|
('Shorter', 0.25),
|
||||||
|
|
@ -203,29 +206,29 @@ class ZombieHorde(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(ba.BoolSetting('Solo Mode', default=False))
|
settings.append(bs.BoolSetting('Solo Mode', default=False))
|
||||||
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)
|
||||||
or issubclass(sessiontype, ba.FreeForAllSession))
|
or issubclass(sessiontype, bs.FreeForAllSession))
|
||||||
|
|
||||||
@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: float | None = None
|
self._start_time: float | None = None
|
||||||
self._vs_text: ba.Actor | None = None
|
self._vs_text: bs.Actor | None = None
|
||||||
self._round_end_timer: ba.Timer | None = None
|
self._round_end_timer: bs.Timer | None = 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._max_zombies = int(settings['Max Zombies'])
|
self._max_zombies = int(settings['Max Zombies'])
|
||||||
|
|
@ -236,53 +239,53 @@ class ZombieHorde(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)
|
||||||
|
|
||||||
self.spazList = []
|
self.spazList = []
|
||||||
self.zombieQ = 0
|
self.zombieQ = 0
|
||||||
|
|
||||||
activity = ba.getactivity()
|
activity = bs.getactivity()
|
||||||
my_factory = SpazFactory.get()
|
my_factory = SpazFactory.get()
|
||||||
|
|
||||||
appears = ['Kronk', 'Zoe', 'Pixel', 'Agent Johnson',
|
appears = ['Kronk', 'Zoe', 'Pixel', 'Agent Johnson',
|
||||||
'Bones', 'Frosty', 'Kronk2']
|
'Bones', 'Frosty', 'Kronk2']
|
||||||
myAppear = copy.copy(ba.app.spaz_appearances['Kronk'])
|
myAppear = copy.copy(babase.app.classic.spaz_appearances['Kronk'])
|
||||||
myAppear.name = 'Kronk2'
|
myAppear.name = 'Kronk2'
|
||||||
ba.app.spaz_appearances['Kronk2'] = myAppear
|
babase.app.classic.spaz_appearances['Kronk2'] = myAppear
|
||||||
for appear in appears:
|
for appear in appears:
|
||||||
my_factory.get_media(appear)
|
my_factory.get_media(appear)
|
||||||
med = my_factory.spaz_media
|
med = my_factory.spaz_media
|
||||||
med['Kronk2']['head_model'] = med['Zoe']['head_model']
|
med['Kronk2']['head_mesh'] = med['Zoe']['head_mesh']
|
||||||
med['Kronk2']['color_texture'] = med['Agent Johnson']['color_texture']
|
med['Kronk2']['color_texture'] = med['Agent Johnson']['color_texture']
|
||||||
med['Kronk2']['color_mask_texture'] = med['Pixel']['color_mask_texture']
|
med['Kronk2']['color_mask_texture'] = med['Pixel']['color_mask_texture']
|
||||||
med['Kronk2']['torso_model'] = med['Bones']['torso_model']
|
med['Kronk2']['torso_mesh'] = med['Bones']['torso_mesh']
|
||||||
med['Kronk2']['pelvis_model'] = med['Pixel']['pelvis_model']
|
med['Kronk2']['pelvis_mesh'] = med['Pixel']['pelvis_mesh']
|
||||||
med['Kronk2']['upper_arm_model'] = med['Frosty']['upper_arm_model']
|
med['Kronk2']['upper_arm_mesh'] = med['Frosty']['upper_arm_mesh']
|
||||||
med['Kronk2']['forearm_model'] = med['Frosty']['forearm_model']
|
med['Kronk2']['forearm_mesh'] = med['Frosty']['forearm_mesh']
|
||||||
med['Kronk2']['hand_model'] = med['Bones']['hand_model']
|
med['Kronk2']['hand_mesh'] = med['Bones']['hand_mesh']
|
||||||
med['Kronk2']['upper_leg_model'] = med['Bones']['upper_leg_model']
|
med['Kronk2']['upper_leg_mesh'] = med['Bones']['upper_leg_mesh']
|
||||||
med['Kronk2']['lower_leg_model'] = med['Pixel']['lower_leg_model']
|
med['Kronk2']['lower_leg_mesh'] = med['Pixel']['lower_leg_mesh']
|
||||||
med['Kronk2']['toes_model'] = med['Bones']['toes_model']
|
med['Kronk2']['toes_mesh'] = med['Bones']['toes_mesh']
|
||||||
|
|
||||||
def get_instance_description(self) -> str | Sequence:
|
def get_instance_description(self) -> str | Sequence:
|
||||||
return ('Kill walkers for points! ',
|
return ('Kill walkers for points! ',
|
||||||
'Dead player walker: 2 points!') if isinstance(
|
'Dead player walker: 2 points!') if isinstance(
|
||||||
self.session, ba.DualTeamSession) else (
|
self.session, bs.DualTeamSession) else (
|
||||||
'Kill walkers for points! Dead player walker: 2 points!')
|
'Kill walkers for points! Dead player walker: 2 points!')
|
||||||
|
|
||||||
def get_instance_description_short(self) -> str | Sequence:
|
def get_instance_description_short(self) -> str | Sequence:
|
||||||
return ('Kill walkers for points! ',
|
return ('Kill walkers for points! ',
|
||||||
'Dead player walker: 2 points!') if isinstance(
|
'Dead player walker: 2 points!') if isinstance(
|
||||||
self.session, ba.DualTeamSession) else (
|
self.session, bs.DualTeamSession) else (
|
||||||
'Kill walkers for points! Dead player walker: 2 points!')
|
'Kill walkers for points! Dead player walker: 2 points!')
|
||||||
|
|
||||||
def on_player_join(self, player: Player) -> None:
|
def on_player_join(self, player: Player) -> None:
|
||||||
if self.has_begun():
|
if self.has_begun():
|
||||||
player.lives = 0
|
player.lives = 0
|
||||||
player.icons = []
|
player.icons = []
|
||||||
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),
|
||||||
)
|
)
|
||||||
|
|
@ -314,13 +317,13 @@ class ZombieHorde(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.zombieQ = 1
|
self.zombieQ = 1
|
||||||
if self._solo_mode:
|
if self._solo_mode:
|
||||||
self._vs_text = ba.NodeActor(
|
self._vs_text = bs.NodeActor(
|
||||||
ba.newnode('text',
|
bs.newnode('text',
|
||||||
attrs={
|
attrs={
|
||||||
'position': (0, 105),
|
'position': (0, 105),
|
||||||
'h_attach': 'center',
|
'h_attach': 'center',
|
||||||
|
|
@ -331,12 +334,12 @@ class ZombieHorde(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(
|
||||||
|
|
@ -365,13 +368,13 @@ class ZombieHorde(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_icons(self) -> None:
|
def _update_icons(self) -> None:
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|
||||||
# In free-for-all mode, everyone is just lined up along the bottom.
|
# In free-for-all mode, everyone is just lined up along the bottom.
|
||||||
if isinstance(self.session, ba.FreeForAllSession):
|
if isinstance(self.session, bs.FreeForAllSession):
|
||||||
count = len(self.teams)
|
count = len(self.teams)
|
||||||
x_offs = 85
|
x_offs = 85
|
||||||
xval = x_offs * (count - 1) * -0.5
|
xval = x_offs * (count - 1) * -0.5
|
||||||
|
|
@ -437,7 +440,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
icon.update_for_lives()
|
icon.update_for_lives()
|
||||||
xval += x_offs
|
xval += x_offs
|
||||||
|
|
||||||
def _get_spawn_point(self, player: Player) -> ba.Vec3 | None:
|
def _get_spawn_point(self, player: Player) -> babase.Vec3 | None:
|
||||||
del player # Unused.
|
del player # Unused.
|
||||||
|
|
||||||
# In solo-mode, if there's an existing live player on the map, spawn at
|
# In solo-mode, if there's an existing live player on the map, spawn at
|
||||||
|
|
@ -455,10 +458,10 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
break
|
break
|
||||||
if living_player:
|
if living_player:
|
||||||
assert living_player_pos is not None
|
assert living_player_pos is not None
|
||||||
player_pos = ba.Vec3(living_player_pos)
|
player_pos = babase.Vec3(living_player_pos)
|
||||||
points: list[tuple[float, ba.Vec3]] = []
|
points: list[tuple[float, babase.Vec3]] = []
|
||||||
for team in self.teams:
|
for team in self.teams:
|
||||||
start_pos = ba.Vec3(self.map.get_start_position(team.id))
|
start_pos = babase.Vec3(self.map.get_start_position(team.id))
|
||||||
points.append(
|
points.append(
|
||||||
((start_pos - player_pos).length(), start_pos))
|
((start_pos - player_pos).length(), start_pos))
|
||||||
# Hmm.. we need to sorting vectors too?
|
# Hmm.. we need to sorting vectors too?
|
||||||
|
|
@ -466,13 +469,13 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
return points[-1][1]
|
return points[-1][1]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def spawn_player(self, player: Player) -> ba.Actor:
|
def spawn_player(self, player: Player) -> bs.Actor:
|
||||||
position = self.map.get_ffa_start_position(self.players)
|
position = self.map.get_ffa_start_position(self.players)
|
||||||
angle = 20
|
angle = 20
|
||||||
name = player.getname()
|
name = player.getname()
|
||||||
|
|
||||||
light_color = _math.normalized_color(player.color)
|
light_color = _math.normalized_color(player.color)
|
||||||
display_color = _ba.safecolor(player.color, target_intensity=0.75)
|
display_color = _babase.safecolor(player.color, target_intensity=0.75)
|
||||||
spaz = PlayerSpaz_Zom(color=player.color,
|
spaz = PlayerSpaz_Zom(color=player.color,
|
||||||
highlight=player.highlight,
|
highlight=player.highlight,
|
||||||
character=player.character,
|
character=player.character,
|
||||||
|
|
@ -500,14 +503,14 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
StandMessage(
|
StandMessage(
|
||||||
position,
|
position,
|
||||||
angle if angle is not None else random.uniform(0, 360)))
|
angle if angle is not None else random.uniform(0, 360)))
|
||||||
_ba.playsound(self._spawn_sound, 1, position=spaz.node.position)
|
bs.Sound.play(self._spawn_sound, 1, position=spaz.node.position)
|
||||||
light = _ba.newnode('light', attrs={'color': light_color})
|
light = bs.newnode('light', attrs={'color': light_color})
|
||||||
spaz.node.connectattr('position', light, 'position')
|
spaz.node.connectattr('position', light, 'position')
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0})
|
bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0})
|
||||||
_ba.timer(0.5, light.delete)
|
bs.timer(0.5, light.delete)
|
||||||
|
|
||||||
if not self._solo_mode:
|
if not self._solo_mode:
|
||||||
ba.timer(0.3, ba.Call(self._print_lives, player))
|
bs.timer(0.3, babase.Call(self._print_lives, player))
|
||||||
|
|
||||||
for icon in player.icons:
|
for icon in player.icons:
|
||||||
icon.handle_player_spawned()
|
icon.handle_player_spawned()
|
||||||
|
|
@ -539,30 +542,30 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
respawn_time = round(max(1.0, respawn_time), 0)
|
respawn_time = round(max(1.0, respawn_time), 0)
|
||||||
|
|
||||||
if player.actor and not self.has_ended():
|
if player.actor and not self.has_ended():
|
||||||
from bastd.actor.respawnicon import RespawnIcon
|
from bascenev1lib.actor.respawnicon import RespawnIcon
|
||||||
player.customdata['respawn_timer'] = _ba.Timer(
|
player.customdata['respawn_timer'] = bs.Timer(
|
||||||
respawn_time, ba.WeakCall(
|
respawn_time, bs.WeakCall(
|
||||||
self.spawn_player_if_exists_as_zombie, player))
|
self.spawn_player_if_exists_as_zombie, player))
|
||||||
player.customdata['respawn_icon'] = RespawnIcon(
|
player.customdata['respawn_icon'] = RespawnIcon(
|
||||||
player, respawn_time)
|
player, respawn_time)
|
||||||
|
|
||||||
def spawn_player_if_exists_as_zombie(self, player: PlayerType) -> None:
|
def spawn_player_if_exists_as_zombie(self, player: PlayerT) -> None:
|
||||||
"""
|
"""
|
||||||
A utility method which calls self.spawn_player() *only* if the
|
A utility method which calls self.spawn_player() *only* if the
|
||||||
ba.Player provided still exists; handy for use in timers and whatnot.
|
bs.Player provided still exists; handy for use in timers and whatnot.
|
||||||
|
|
||||||
There is no need to override this; just override spawn_player().
|
There is no need to override this; just override spawn_player().
|
||||||
"""
|
"""
|
||||||
if player:
|
if player:
|
||||||
self.spawn_player_zombie(player)
|
self.spawn_player_zombie(player)
|
||||||
|
|
||||||
def spawn_player_zombie(self, player: PlayerType) -> ba.Actor:
|
def spawn_player_zombie(self, player: PlayerT) -> bs.Actor:
|
||||||
position = self.map.get_ffa_start_position(self.players)
|
position = self.map.get_ffa_start_position(self.players)
|
||||||
angle = 20
|
angle = 20
|
||||||
name = player.getname()
|
name = player.getname()
|
||||||
|
|
||||||
light_color = _math.normalized_color(player.color)
|
light_color = _math.normalized_color(player.color)
|
||||||
display_color = _ba.safecolor(player.color, target_intensity=0.75)
|
display_color = _babase.safecolor(player.color, target_intensity=0.75)
|
||||||
spaz = PlayerSpaz_Zom(color=player.color,
|
spaz = PlayerSpaz_Zom(color=player.color,
|
||||||
highlight=player.highlight,
|
highlight=player.highlight,
|
||||||
character='Kronk2',
|
character='Kronk2',
|
||||||
|
|
@ -591,21 +594,21 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
StandMessage(
|
StandMessage(
|
||||||
position,
|
position,
|
||||||
angle if angle is not None else random.uniform(0, 360)))
|
angle if angle is not None else random.uniform(0, 360)))
|
||||||
_ba.playsound(self._spawn_sound, 1, position=spaz.node.position)
|
bs.Sound.play(self._spawn_sound, 1, position=spaz.node.position)
|
||||||
light = _ba.newnode('light', attrs={'color': light_color})
|
light = bs.newnode('light', attrs={'color': light_color})
|
||||||
spaz.node.connectattr('position', light, 'position')
|
spaz.node.connectattr('position', light, 'position')
|
||||||
ba.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0})
|
bs.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0})
|
||||||
_ba.timer(0.5, light.delete)
|
bs.timer(0.5, light.delete)
|
||||||
|
|
||||||
if not self._solo_mode:
|
if not self._solo_mode:
|
||||||
ba.timer(0.3, ba.Call(self._print_lives, player))
|
bs.timer(0.3, babase.Call(self._print_lives, player))
|
||||||
|
|
||||||
for icon in player.icons:
|
for icon in player.icons:
|
||||||
icon.handle_player_spawned()
|
icon.handle_player_spawned()
|
||||||
return spaz
|
return spaz
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -642,13 +645,13 @@ class ZombieHorde(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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -665,7 +668,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
if msg._player in self.spazList:
|
if msg._player in self.spazList:
|
||||||
self.spazList.remove(msg._player)
|
self.spazList.remove(msg._player)
|
||||||
if player.lives < 0:
|
if player.lives < 0:
|
||||||
ba.print_error(
|
babase.print_error(
|
||||||
"Got lives < 0 in Elim; this shouldn't happen. solo:" +
|
"Got lives < 0 in Elim; this shouldn't happen. solo:" +
|
||||||
str(self._solo_mode))
|
str(self._solo_mode))
|
||||||
player.lives = 0
|
player.lives = 0
|
||||||
|
|
@ -677,7 +680,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
# Play big death sound on our last death
|
# Play big death sound on our last death
|
||||||
# or for every one in solo mode.
|
# or for every one in solo mode.
|
||||||
if self._solo_mode or player.lives == 0:
|
if self._solo_mode or 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:
|
||||||
|
|
@ -732,16 +735,16 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
theScores) and theScores.count(max(theScores)) > 1:
|
theScores) and theScores.count(max(theScores)) > 1:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self._round_end_timer = ba.Timer(0.5, self.end_game)
|
self._round_end_timer = bs.Timer(0.5, self.end_game)
|
||||||
else:
|
else:
|
||||||
self._round_end_timer = ba.Timer(0.5, self.end_game)
|
self._round_end_timer = bs.Timer(0.5, self.end_game)
|
||||||
|
|
||||||
def spawn_zombie(self) -> None:
|
def spawn_zombie(self) -> None:
|
||||||
# We need a Z height...
|
# We need a Z height...
|
||||||
thePt = list(self.get_random_point_in_play())
|
thePt = list(self.get_random_point_in_play())
|
||||||
thePt2 = self.map.get_ffa_start_position(self.players)
|
thePt2 = self.map.get_ffa_start_position(self.players)
|
||||||
thePt[1] = thePt2[1]
|
thePt[1] = thePt2[1]
|
||||||
ba.timer(0.1, ba.Call(
|
bs.timer(0.1, babase.Call(
|
||||||
self._bots.spawn_bot, BrawlerBot, pos=thePt, spawn_time=1.0))
|
self._bots.spawn_bot, BrawlerBot, pos=thePt, spawn_time=1.0))
|
||||||
|
|
||||||
def _onSpazBotDied(self, DeathMsg) -> None:
|
def _onSpazBotDied(self, DeathMsg) -> None:
|
||||||
|
|
@ -816,25 +819,25 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
|
||||||
setattr(BrawlerBot, 'color', (0.6, 0.6, 0.6))
|
setattr(BrawlerBot, 'color', (0.6, 0.6, 0.6))
|
||||||
setattr(BrawlerBot, 'highlight', (0.6, 0.6, 0.6))
|
setattr(BrawlerBot, 'highlight', (0.6, 0.6, 0.6))
|
||||||
setattr(BrawlerBot, 'character', 'Kronk')
|
setattr(BrawlerBot, 'character', 'Kronk')
|
||||||
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.score)
|
results.set_team_score(team, team.score)
|
||||||
self.end(results=results)
|
self.end(results=results)
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export game
|
# ba_meta export bascenev1.GameActivity
|
||||||
class ZombieHordeCoop(ZombieHorde):
|
class ZombieHordeCoop(ZombieHorde):
|
||||||
|
|
||||||
name = 'Zombie Horde'
|
name = 'Zombie Horde'
|
||||||
|
|
||||||
@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 ['Football Stadium']
|
return ['Football Stadium']
|
||||||
|
|
||||||
@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.CoopSession))
|
return (issubclass(sessiontype, bs.CoopSession))
|
||||||
|
|
||||||
def _update(self) -> None:
|
def _update(self) -> None:
|
||||||
if self.zombieQ > 0:
|
if self.zombieQ > 0:
|
||||||
|
|
@ -855,12 +858,12 @@ class ZombieHordeCoop(ZombieHorde):
|
||||||
break
|
break
|
||||||
|
|
||||||
if not any(player.is_alive() for player in self.teams[0].players):
|
if not any(player.is_alive() for player in self.teams[0].players):
|
||||||
self._round_end_timer = ba.Timer(0.5, self.end_game)
|
self._round_end_timer = bs.Timer(0.5, self.end_game)
|
||||||
|
|
||||||
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.
|
||||||
ba.TeamGameActivity.handlemessage(self, msg)
|
bs.TeamGameActivity.handlemessage(self, msg)
|
||||||
player: Player = msg.getplayer(Player)
|
player: Player = msg.getplayer(Player)
|
||||||
# If we have any icons, update their state.
|
# If we have any icons, update their state.
|
||||||
for icon in player.icons:
|
for icon in player.icons:
|
||||||
|
|
@ -870,10 +873,10 @@ class ZombieHordeCoop(ZombieHorde):
|
||||||
|
|
||||||
|
|
||||||
# ba_meta export plugin
|
# ba_meta export plugin
|
||||||
class ZombieHordeLevel(ba.Plugin):
|
class ZombieHordeLevel(babase.Plugin):
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
ba.app.add_coop_practice_level(
|
babase.app.classic.add_coop_practice_level(
|
||||||
ba.Level(
|
bs._level.Level(
|
||||||
'Zombie Horde',
|
'Zombie Horde',
|
||||||
gametype=ZombieHordeCoop,
|
gametype=ZombieHordeCoop,
|
||||||
settings={},
|
settings={},
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import _babase
|
||||||
import bascenev1 as bs
|
import bascenev1 as bs
|
||||||
import bascenev1lib
|
import bascenev1lib
|
||||||
import bauiv1 as bui
|
import bauiv1 as bui
|
||||||
from baenv import TARGET_BALLISTICA_BUILD
|
from baenv import TARGET_BALLISTICA_BUILD as build_number
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|
@ -37,8 +37,8 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
ANDROID = babase.app.classic.platform == "android"
|
ANDROID = babase.app.classic.platform == "android"
|
||||||
DIRPATH = Path(
|
DIRPATH = Path(
|
||||||
f"{_babase.app.python_directory_user if TARGET_BALLISTICA_BUILD < 21282 else _babase.app.env.python_directory_user}/image_id.json")
|
f"{_babase.app.python_directory_user if build_number < 21282 else _babase.app.env.python_directory_user}/image_id.json")
|
||||||
APP_VERSION = _babase.app.version if TARGET_BALLISTICA_BUILD < 21282 else _babase.app.env.version
|
APP_VERSION = _babase.app.version if build_number < 21282 else _babase.app.env.version
|
||||||
|
|
||||||
if ANDROID: # !can add ios in future
|
if ANDROID: # !can add ios in future
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class RagdollBGone(babase.Plugin):
|
||||||
# Pick a random death noise
|
# Pick a random death noise
|
||||||
sound = death_sounds[random.randrange(len(death_sounds))]
|
sound = death_sounds[random.randrange(len(death_sounds))]
|
||||||
# Play the sound where our Spaz is
|
# Play the sound where our Spaz is
|
||||||
sound.play(position=args[0].node.position)
|
bs.Sound.play(sound, position=args[0].node.position)
|
||||||
# Delete our Spaz node immediately.
|
# Delete our Spaz node immediately.
|
||||||
# Removing stuff is weird and prone to errors, so we're gonna delay it.
|
# Removing stuff is weird and prone to errors, so we're gonna delay it.
|
||||||
bs.timer(0.001, args[0].node.delete)
|
bs.timer(0.001, args[0].node.delete)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue