[ci] auto-format

This commit is contained in:
Loup-Garou911XD 2022-11-03 17:29:43 +00:00 committed by github-actions[bot]
parent d513809ad3
commit c052a1d7c1
6 changed files with 883 additions and 824 deletions

View file

@ -6,7 +6,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import ba, _ba import ba
import _ba
from bastd.actor.playerspaz import PlayerSpaz from bastd.actor.playerspaz import PlayerSpaz
from bastd.actor.scoreboard import Scoreboard from bastd.actor.scoreboard import Scoreboard
from bastd.actor.powerupbox import PowerupBoxFactory from bastd.actor.powerupbox import PowerupBoxFactory
@ -19,42 +20,46 @@ if TYPE_CHECKING:
bsuSpaz = None bsuSpaz = None
def getlanguage(text, sub: str = ''): def getlanguage(text, sub: str = ''):
lang = _ba.app.lang.language lang = _ba.app.lang.language
translate = { translate = {
"Name": "Name":
{"Spanish": "Baloncesto", {"Spanish": "Baloncesto",
"English": "Basketbomb", "English": "Basketbomb",
"Portuguese": "Basketbomb"}, "Portuguese": "Basketbomb"},
"Info": "Info":
{"Spanish": "Anota todas las canastas y sé el MVP.", {"Spanish": "Anota todas las canastas y sé el MVP.",
"English": "Score all the baskets and be the MVP.", "English": "Score all the baskets and be the MVP.",
"Portuguese": "Marque cada cesta e seja o MVP."}, "Portuguese": "Marque cada cesta e seja o MVP."},
"Info-Short": "Info-Short":
{"Spanish": f"Anota {sub} canasta(s) para ganar", {"Spanish": f"Anota {sub} canasta(s) para ganar",
"English": f"Score {sub} baskets to win", "English": f"Score {sub} baskets to win",
"Portuguese": f"Cestas de {sub} pontos para ganhar"}, "Portuguese": f"Cestas de {sub} pontos para ganhar"},
"S: Powerups": "S: Powerups":
{"Spanish": "Aparecer Potenciadores", {"Spanish": "Aparecer Potenciadores",
"English": "Powerups Spawn", "English": "Powerups Spawn",
"Portuguese": "Habilitar Potenciadores"}, "Portuguese": "Habilitar Potenciadores"},
"S: Velocity": "S: Velocity":
{"Spanish": "Activar velocidad", {"Spanish": "Activar velocidad",
"English": "Enable speed", "English": "Enable speed",
"Portuguese": "Ativar velocidade"}, "Portuguese": "Ativar velocidade"},
} }
languages = ['Spanish','Portuguese','English'] languages = ['Spanish', 'Portuguese', 'English']
if lang not in languages: lang = 'English' if lang not in languages:
lang = 'English'
if text not in translate: if text not in translate:
return text return text
return translate[text][lang] return translate[text][lang]
class BallDiedMessage: class BallDiedMessage:
def __init__(self, ball: Ball): def __init__(self, ball: Ball):
self.ball = ball self.ball = ball
class Ball(ba.Actor): class Ball(ba.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__()
@ -62,14 +67,14 @@ class Ball(ba.Actor):
activity = self.getactivity() activity = self.getactivity()
velocty = (0.0, 8.0, 0.0) velocty = (0.0, 8.0, 0.0)
_scale = 1.2 _scale = 1.2
self._spawn_pos = (position[0], position[1] + 0.5, position[2]) self._spawn_pos = (position[0], position[1] + 0.5, position[2])
self.last_players_to_touch: Dict[int, Player] = {} self.last_players_to_touch: Dict[int, Player] = {}
self.scored = False self.scored = False
assert activity is not None assert activity is not None
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 = ba.newnode('prop',
delegate=self, delegate=self,
@ -132,14 +137,18 @@ class Team(ba.Team[Player]):
def __init__(self) -> None: def __init__(self) -> None:
self.score = 0 self.score = 0
class Points: class Points:
postes = dict() postes = dict()
postes['pal_0'] = (10.64702320098877, 0.0000000000000000, 0.0000000000000000) #10.736066818237305, 0.3002409040927887, 0.5281256437301636 # 10.736066818237305, 0.3002409040927887, 0.5281256437301636
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 game
class BasketGame(ba.TeamGameActivity[Player, Team]): class BasketGame(ba.TeamGameActivity[Player, Team]):
name = getlanguage('Name') name = getlanguage('Name')
description = getlanguage('Info') description = getlanguage('Info')
available_settings = [ available_settings = [
@ -202,7 +211,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
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 = ba.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)))
@ -251,10 +260,10 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
super().on_begin() super().on_begin()
self.setup_standard_time_limit(self._time_limit) self.setup_standard_time_limit(self._time_limit)
if self._powerups: if self._powerups:
self.setup_standard_powerup_drops() self.setup_standard_powerup_drops()
self._ball_spawn_pos = self.map.get_flag_position(None) self._ball_spawn_pos = self.map.get_flag_position(None)
self._spawn_ball() self._spawn_ball()
@ -336,7 +345,7 @@ 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) # ba.playsound(self._foghorn_sound)
ba.playsound(self._cheer_sound) ba.playsound(self._cheer_sound)
self._ball.scored = True self._ball.scored = True
@ -366,8 +375,8 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
winscore = self._score_to_win winscore = self._score_to_win
for id, team in enumerate(self.teams): for id, team in enumerate(self.teams):
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) -> ba.Actor:
if bsuSpaz is None: if bsuSpaz is None:
spaz = self.spawn_player_spaz(player) spaz = self.spawn_player_spaz(player)
@ -375,7 +384,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
ps.PlayerSpaz = bsuSpaz.BskSpaz ps.PlayerSpaz = bsuSpaz.BskSpaz
spaz = self.spawn_player_spaz(player) spaz = self.spawn_player_spaz(player)
ps.PlayerSpaz = bsuSpaz.OldPlayerSpaz ps.PlayerSpaz = bsuSpaz.OldPlayerSpaz
if self._speed: if self._speed:
spaz.node.hockey = True spaz.node.hockey = True
return spaz return spaz
@ -393,9 +402,9 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
def postes(self, team_id: int): def postes(self, team_id: int):
if not hasattr(self._map, 'poste_'+str(team_id)): if not hasattr(self._map, 'poste_'+str(team_id)):
setattr(self._map, 'poste_'+str(team_id), setattr(self._map, 'poste_'+str(team_id),
Palos(team=team_id, Palos(team=team_id,
position=Points.postes['pal_' + position=Points.postes['pal_' +
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 = ba.newnode('light',
@ -414,6 +423,7 @@ class BasketGame(ba.TeamGameActivity[Player, Team]):
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(ba.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)):
@ -422,7 +432,7 @@ class Aro(ba.Actor):
shared = SharedObjects.get() shared = SharedObjects.get()
setattr(self, 'team', team) setattr(self, 'team', team)
setattr(self, 'locs', []) setattr(self, 'locs', [])
# Material Para; Traspasar Objetos # Material Para; Traspasar Objetos
self.no_collision = ba.Material() self.no_collision = ba.Material()
self.no_collision.add_actions( self.no_collision.add_actions(
@ -443,10 +453,10 @@ class Aro(ba.Actor):
self._spawn_pos = (position[0], position[1], position[2]) self._spawn_pos = (position[0], position[1], position[2])
self._materials_region0 = [self.collision, self._materials_region0 = [self.collision,
shared.footing_material] shared.footing_material]
model = None model = None
tex = ba.gettexture('null') tex = ba.gettexture('null')
pmats = [self.no_collision] pmats = [self.no_collision]
self.node = ba.newnode('prop', self.node = ba.newnode('prop',
delegate=self, delegate=self,
@ -459,55 +469,56 @@ class Aro(ba.Actor):
'shadow_size': 0.1, 'shadow_size': 0.1,
'position': self._spawn_pos, 'position': self._spawn_pos,
'materials': pmats}) 'materials': pmats})
self.scale = scale = 1.4 self.scale = scale = 1.4
ba.animate(self.node, 'model_scale', {0: 0}) ba.animate(self.node, 'model_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[ba.Node] = [
ba.newnode('region', ba.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', ba.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',
'materials': [self._score_region_material]}) 'materials': [self._score_region_material]})
] ]
self.regions[0].connectattr('position', self.node, 'position') self.regions[0].connectattr('position', self.node, 'position')
#self.regions[0].connectattr('position', self.regions[1], 'position') #self.regions[0].connectattr('position', self.regions[1], 'position')
locs_count = 9 locs_count = 9
pos = list(position) pos = list(position)
try: try:
id = 0 if team == 1 else 1 id = 0 if team == 1 else 1
color = act.teams[id].color color = act.teams[id].color
except: color = (1,1,1) except:
color = (1, 1, 1)
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(ba.newnode('locator',
owner=self.node, owner=self.node,
attrs={'shape': 'circleOutline', attrs={'shape': 'circleOutline',
'position': pos, 'position': pos,
'color': color, 'color': color,
'opacity': 1.0, 'opacity': 1.0,
'size': [scale], 'size': [scale],
'draw_beauty': True, 'draw_beauty': True,
'additive': False})) 'additive': False}))
pos[1] -= 0.1 pos[1] -= 0.1
locs_count -= 1 locs_count -= 1
def _annotation(self): def _annotation(self):
assert len(self.regions) >= 2 assert len(self.regions) >= 2
ball = self.getactivity()._ball ball = self.getactivity()._ball
if ball: if ball:
p = self.regions[0].position p = self.regions[0].position
ball.node.position = p ball.node.position = p
@ -523,6 +534,7 @@ class Aro(ba.Actor):
else: else:
super().handlemessage(msg) super().handlemessage(msg)
class Cuadro(ba.Actor): class Cuadro(ba.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)):
@ -536,13 +548,13 @@ class Cuadro(ba.Actor):
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: ba.Node = ba.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 = ba.newnode('shield', attrs={'radius': 1.0, 'color': (0,10,0)})
#self.region.connectattr('position', self.shield, 'position') #self.region.connectattr('position', self.shield, 'position')
@ -550,38 +562,38 @@ class Cuadro(ba.Actor):
pos = list(position) pos = list(position)
oldpos = list(position) oldpos = list(position)
old_count = 14 old_count = 14
count = old_count count = old_count
count_y = 9 count_y = 9
try: try:
id = 0 if team == 1 else 1 id = 0 if team == 1 else 1
color = act.teams[id].color color = act.teams[id].color
except: color = (1,1,1) except:
color = (1, 1, 1)
while(count_y != 1): while (count_y != 1):
while(count != 1): while (count != 1):
pos[2] += 0.19 pos[2] += 0.19
self.locs.append( self.locs.append(
ba.newnode('locator', ba.newnode('locator',
owner=self.region, owner=self.region,
attrs={'shape': 'circle', attrs={'shape': 'circle',
'position': pos, 'position': pos,
'size': [0.5], 'size': [0.5],
'color': color, 'color': color,
'opacity': 1.0, 'opacity': 1.0,
'draw_beauty': True, 'draw_beauty': True,
'additive': False})) 'additive': False}))
count -= 1 count -= 1
count = old_count count = old_count
pos[1] += 0.2 pos[1] += 0.2
pos[2] = oldpos[2] pos[2] = oldpos[2]
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, ba.DieMessage):
if self.node.exists(): if self.node.exists():
@ -589,6 +601,7 @@ class Cuadro(ba.Actor):
else: else:
super().handlemessage(msg) super().handlemessage(msg)
class Palos(ba.Actor): class Palos(ba.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)):
@ -604,17 +617,17 @@ class Palos(ba.Actor):
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 = ba.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') model = ba.getmodel('flagPole')
tex = ba.gettexture('flagPoleColor') tex = ba.gettexture('flagPoleColor')
pmats = [self.no_collision] pmats = [self.no_collision]
self.node = ba.newnode('prop', self.node = ba.newnode('prop',
delegate=self, delegate=self,
@ -633,34 +646,35 @@ class Palos(ba.Actor):
ba.animate(self.node, 'model_scale', {0: scale}) ba.animate(self.node, 'model_scale', {0: scale})
self.loc = ba.newnode('locator', self.loc = ba.newnode('locator',
owner=self.node, owner=self.node,
attrs={'shape': 'circle', attrs={'shape': 'circle',
'position': position, 'position': position,
'color': (1,1,0), 'color': (1, 1, 0),
'opacity': 1.0, 'opacity': 1.0,
'draw_beauty': False, 'draw_beauty': False,
'additive': True}) 'additive': True})
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 = ba.newnode('region',
attrs={ attrs={
'position': _pos, 'position': _pos,
'scale': (0.4, 8, 0.4), 'scale': (0.4, 8, 0.4),
'type': 'box', 'type': 'box',
'materials': [self.collision]}) 'materials': [self.collision]})
self.region.connectattr('position', self.node, 'position') self.region.connectattr('position', self.node, 'position')
_y = self._y _y = self._y
position = self._pos position = self._pos
if team == 0: if team == 0:
pos = (position[0]-0.8, position[1] + 2.0 + _y, position[2]) pos = (position[0]-0.8, position[1] + 2.0 + _y, position[2])
else: pos = (position[0]+0.8, position[1] + 2.0 + _y, position[2]) else:
pos = (position[0]+0.8, position[1] + 2.0 + _y, position[2])
if self.aro is None: if self.aro is None:
self.aro = Aro(team, pos).autoretain() self.aro = Aro(team, pos).autoretain()
if self.cua is None: if self.cua is None:
pos = (position[0], position[1] + 1.8 + _y, position[2]-1.4) pos = (position[0], position[1] + 1.8 + _y, position[2]-1.4)
self.cua = Cuadro(team, pos).autoretain() self.cua = Cuadro(team, pos).autoretain()
@ -670,7 +684,8 @@ class Palos(ba.Actor):
if self.node.exists(): if self.node.exists():
self.node.delete() self.node.delete()
else: else:
super().handlemessage(msg) super().handlemessage(msg)
class BasketMap(maps.FootballStadium): class BasketMap(maps.FootballStadium):
name = 'BasketBall Stadium' name = 'BasketBall Stadium'
@ -682,7 +697,7 @@ class BasketMap(maps.FootballStadium):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
gnode = ba.getactivity().globalsnode gnode = ba.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)
@ -691,13 +706,14 @@ class BasketMap(maps.FootballStadium):
gnode.vr_camera_offset = (0, -0.8, -1.1) gnode.vr_camera_offset = (0, -0.8, -1.1)
gnode.vr_near_clip = 0.5 gnode.vr_near_clip = 0.5
class BasketMapV2(maps.HockeyStadium): class BasketMapV2(maps.HockeyStadium):
name = 'BasketBall Stadium V2' name = 'BasketBall Stadium V2'
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
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.collide_model = ba.getcollidemodel('footballStadiumCollide')
self.node.model = None self.node.model = None
@ -705,13 +721,13 @@ class BasketMapV2(maps.HockeyStadium):
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 = ba.newnode('terrain',
attrs={'model': ba.getmodel('thePadBG'), attrs={'model': ba.getmodel('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': ba.gettexture('menuBG')})
gnode = ba.getactivity().globalsnode gnode = ba.getactivity().globalsnode
gnode.floor_reflection = True gnode.floor_reflection = True
@ -729,26 +745,27 @@ class BasketMapV2(maps.HockeyStadium):
self.collision = ba.Material() self.collision = ba.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[ba.Node] = [
ba.newnode('region', ba.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', ba.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', ba.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',
'materials': [self.collision]}), 'materials': [self.collision]}),
] ]
ba._map.register_map(BasketMap) ba._map.register_map(BasketMap)
ba._map.register_map(BasketMapV2) ba._map.register_map(BasketMapV2)

View file

@ -11,230 +11,230 @@ from bastd.actor.scoreboard import Scoreboard
from bastd.game.deathmatch import DeathMatchGame from bastd.game.deathmatch import DeathMatchGame
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any, Sequence
lang = ba.app.lang.language lang = ba.app.lang.language
if lang == 'Spanish': if lang == 'Spanish':
name = 'Super Boxeo' name = 'Super Boxeo'
description = ('¡Sin bombas!\n' description = ('¡Sin bombas!\n'
'¡Noquea a los enemigos con tus propias manos!\n') '¡Noquea a los enemigos con tus propias manos!\n')
super_jump_text = 'Super Salto' super_jump_text = 'Super Salto'
enable_powerups = 'Habilitar Potenciadores' enable_powerups = 'Habilitar Potenciadores'
else: else:
name = 'Super Boxing' name = 'Super Boxing'
description = ('No bombs!\n' description = ('No bombs!\n'
'Knock out your enemies using your bare hands!\n') 'Knock out your enemies using your bare hands!\n')
super_jump_text = 'Super Jump' super_jump_text = 'Super Jump'
enable_powerups = 'Enable Powerups' enable_powerups = 'Enable Powerups'
class NewPlayerSpaz(PlayerSpaz): class NewPlayerSpaz(PlayerSpaz):
def __init__(self, def __init__(self,
player: ba.Player, player: ba.Player,
color: Sequence[float] = (1.0, 1.0, 1.0), color: Sequence[float] = (1.0, 1.0, 1.0),
highlight: Sequence[float] = (0.5, 0.5, 0.5), highlight: Sequence[float] = (0.5, 0.5, 0.5),
character: str = 'Spaz', character: str = 'Spaz',
powerups_expire: bool = True, powerups_expire: bool = True,
super_jump: bool = False): super_jump: bool = False):
super().__init__(player=player, super().__init__(player=player,
color=color, color=color,
highlight=highlight, highlight=highlight,
character=character, character=character,
powerups_expire=powerups_expire) powerups_expire=powerups_expire)
from bastd.gameutils import SharedObjects from bastd.gameutils import SharedObjects
shared = SharedObjects.get() shared = SharedObjects.get()
self._super_jump = super_jump self._super_jump = super_jump
self.jump_mode = False self.jump_mode = False
self.super_jump_material = ba.Material() self.super_jump_material = ba.Material()
self.super_jump_material.add_actions( self.super_jump_material.add_actions(
conditions=('they_have_material', shared.footing_material), conditions=('they_have_material', shared.footing_material),
actions=( actions=(
('call', 'at_connect', ba.Call(self.jump_state, True)), ('call', 'at_connect', ba.Call(self.jump_state, True)),
('call', 'at_disconnect', ba.Call(self.jump_state, False)) ('call', 'at_disconnect', ba.Call(self.jump_state, False))
), ),
) )
self.node.roller_materials += (self.super_jump_material, ) self.node.roller_materials += (self.super_jump_material, )
def jump_state(self, mode: bool) -> None: def jump_state(self, mode: bool) -> None:
self.jump_mode = mode self.jump_mode = mode
def on_jump_press(self) -> None: def on_jump_press(self) -> None:
""" """
Called to 'press jump' on this spaz; Called to 'press jump' on this spaz;
used by player or AI connections. used by player or AI connections.
""" """
if not self.node: if not self.node:
return return
t_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS) t_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
assert isinstance(t_ms, int) assert isinstance(t_ms, int)
if t_ms - self.last_jump_time_ms >= self._jump_cooldown: if t_ms - self.last_jump_time_ms >= self._jump_cooldown:
self.node.jump_pressed = True self.node.jump_pressed = True
self.last_jump_time_ms = t_ms self.last_jump_time_ms = t_ms
if self._player.is_alive() and self.jump_mode and ( if self._player.is_alive() and self.jump_mode and (
self._super_jump): self._super_jump):
def do_jump(): def do_jump():
self.node.handlemessage( self.node.handlemessage(
'impulse', 'impulse',
self.node.position[0], self.node.position[0],
self.node.position[1], self.node.position[1],
self.node.position[2], self.node.position[2],
0, 0, 0, 150, 150, 0, 0, 0, 1, 0 0, 0, 0, 150, 150, 0, 0, 0, 1, 0
) )
ba.timer(0.0, do_jump) ba.timer(0.0, do_jump)
ba.timer(0.1, do_jump) ba.timer(0.1, do_jump)
ba.timer(0.2, do_jump) ba.timer(0.2, do_jump)
self._turbo_filter_add_press('jump') self._turbo_filter_add_press('jump')
# ba_meta export game # ba_meta export game
class BoxingGame(DeathMatchGame): class BoxingGame(DeathMatchGame):
name = name name = name
description = description description = description
@classmethod @classmethod
def get_available_settings( def get_available_settings(
cls, sessiontype: type[ba.Session] cls, sessiontype: type[ba.Session]
) -> list[ba.Setting]: ) -> list[ba.Setting]:
settings = [ settings = [
ba.IntSetting( ba.IntSetting(
'Kills to Win Per Player', 'Kills to Win Per Player',
min_value=1, min_value=1,
default=5, default=5,
increment=1, increment=1,
), ),
ba.IntChoiceSetting( ba.IntChoiceSetting(
'Time Limit', 'Time Limit',
choices=[ choices=[
('None', 0), ('None', 0),
('1 Minute', 60), ('1 Minute', 60),
('2 Minutes', 120), ('2 Minutes', 120),
('5 Minutes', 300), ('5 Minutes', 300),
('10 Minutes', 600), ('10 Minutes', 600),
('20 Minutes', 1200), ('20 Minutes', 1200),
], ],
default=0, default=0,
), ),
ba.FloatChoiceSetting( ba.FloatChoiceSetting(
'Respawn Times', 'Respawn Times',
choices=[ choices=[
('Shorter', 0.25), ('Shorter', 0.25),
('Short', 0.5), ('Short', 0.5),
('Normal', 1.0), ('Normal', 1.0),
('Long', 2.0), ('Long', 2.0),
('Longer', 4.0), ('Longer', 4.0),
], ],
default=1.0, default=1.0,
), ),
ba.BoolSetting(super_jump_text, default=False), ba.BoolSetting(super_jump_text, default=False),
ba.BoolSetting(enable_powerups, default=False), ba.BoolSetting(enable_powerups, default=False),
ba.BoolSetting('Epic Mode', default=False), ba.BoolSetting('Epic Mode', default=False),
] ]
# In teams mode, a suicide gives a point to the other team, but in # In teams mode, a suicide gives a point to the other team, but in
# free-for-all it subtracts from your own score. By default we clamp # free-for-all it subtracts from your own score. By default we clamp
# this at zero to benefit new players, but pro players might like to # this at zero to benefit new players, but pro players might like to
# be able to go negative. (to avoid a strategy of just # be able to go negative. (to avoid a strategy of just
# suiciding until you get a good drop) # suiciding until you get a good drop)
if issubclass(sessiontype, ba.FreeForAllSession): if issubclass(sessiontype, ba.FreeForAllSession):
settings.append( settings.append(
ba.BoolSetting('Allow Negative Scores', default=False) ba.BoolSetting('Allow Negative Scores', default=False)
) )
return settings return settings
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: int | None = None self._score_to_win: int | None = None
self._dingsound = ba.getsound('dingSmall') self._dingsound = ba.getsound('dingSmall')
self._epic_mode = bool(settings['Epic Mode']) self._epic_mode = bool(settings['Epic Mode'])
self._kills_to_win_per_player = int(settings['Kills to Win Per Player']) self._kills_to_win_per_player = int(settings['Kills to Win Per Player'])
self._time_limit = float(settings['Time Limit']) self._time_limit = float(settings['Time Limit'])
self._allow_negative_scores = bool( self._allow_negative_scores = bool(
settings.get('Allow Negative Scores', False) settings.get('Allow Negative Scores', False)
) )
self._super_jump = bool(settings[super_jump_text]) self._super_jump = bool(settings[super_jump_text])
self._enable_powerups = bool(settings[enable_powerups]) self._enable_powerups = bool(settings[enable_powerups])
# Base class overrides. # Base class overrides.
self.slow_motion = self._epic_mode self.slow_motion = self._epic_mode
self.default_music = ( self.default_music = (
ba.MusicType.EPIC if self._epic_mode else ba.MusicType.TO_THE_DEATH ba.MusicType.EPIC if self._epic_mode else ba.MusicType.TO_THE_DEATH
) )
def on_begin(self) -> None: def on_begin(self) -> None:
ba.TeamGameActivity.on_begin(self) ba.TeamGameActivity.on_begin(self)
self.setup_standard_time_limit(self._time_limit) self.setup_standard_time_limit(self._time_limit)
if self._enable_powerups: if self._enable_powerups:
self.setup_standard_powerup_drops() self.setup_standard_powerup_drops()
# Base kills needed to win on the size of the largest team. # Base kills needed to win on the size of the largest team.
self._score_to_win = self._kills_to_win_per_player * max( self._score_to_win = self._kills_to_win_per_player * max(
1, max(len(t.players) for t in self.teams) 1, max(len(t.players) for t in self.teams)
) )
self._update_scoreboard() self._update_scoreboard()
def _standard_drop_powerup(self, index: int, expire: bool = True) -> None: def _standard_drop_powerup(self, index: int, expire: bool = True) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bastd.actor.powerupbox import PowerupBox, PowerupBoxFactory from bastd.actor.powerupbox import PowerupBox, PowerupBoxFactory
PowerupBox( PowerupBox(
position=self.map.powerup_spawn_points[index], position=self.map.powerup_spawn_points[index],
poweruptype=PowerupBoxFactory.get().get_random_powerup_type( poweruptype=PowerupBoxFactory.get().get_random_powerup_type(
excludetypes=['triple_bombs','ice_bombs','impact_bombs', excludetypes=['triple_bombs', 'ice_bombs', 'impact_bombs',
'land_mines','sticky_bombs','punch'] 'land_mines', 'sticky_bombs', 'punch']
), ),
expire=expire, expire=expire,
).autoretain() ).autoretain()
def spawn_player(self, player: Player) -> ba.Actor: def spawn_player(self, player: Player) -> ba.Actor:
import random import random
from ba import _math from ba import _math
from ba._gameutils import animate from ba._gameutils import animate
from ba._coopsession import CoopSession from ba._coopsession import CoopSession
if isinstance(self.session, ba.DualTeamSession): if isinstance(self.session, ba.DualTeamSession):
position = self.map.get_start_position(player.team.id) position = self.map.get_start_position(player.team.id)
else: else:
# otherwise do free-for-all spawn locations # otherwise do free-for-all spawn locations
position = self.map.get_ffa_start_position(self.players) position = self.map.get_ffa_start_position(self.players)
angle = None angle = None
name = player.getname() name = player.getname()
color = player.color color = player.color
highlight = player.highlight highlight = player.highlight
light_color = _math.normalized_color(color) light_color = _math.normalized_color(color)
display_color = ba.safecolor(color, target_intensity=0.75) display_color = ba.safecolor(color, target_intensity=0.75)
spaz = NewPlayerSpaz(color=color, spaz = NewPlayerSpaz(color=color,
highlight=highlight, highlight=highlight,
character=player.character, character=player.character,
player=player, player=player,
super_jump=self._super_jump) super_jump=self._super_jump)
player.actor = spaz player.actor = spaz
assert spaz.node assert spaz.node
spaz.node.name = name spaz.node.name = name
spaz.node.name_color = display_color spaz.node.name_color = display_color
# Move to the stand position and add a flash of light. # Move to the stand position and add a flash of light.
spaz.handlemessage( spaz.handlemessage(
ba.StandMessage( ba.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) ba.playsound(self._spawn_sound, 1, position=spaz.node.position)
light = ba.newnode('light', attrs={'color': light_color}) light = ba.newnode('light', attrs={'color': light_color})
spaz.node.connectattr('position', light, 'position') spaz.node.connectattr('position', light, 'position')
animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0})
ba.timer(0.5, light.delete) ba.timer(0.5, light.delete)
# custom # custom
spaz.connect_controls_to_player(enable_bomb=False) spaz.connect_controls_to_player(enable_bomb=False)
spaz.equip_boxing_gloves() spaz.equip_boxing_gloves()
return spaz return spaz

View file

@ -11,396 +11,396 @@ from bastd.actor.bomb import Bomb
from bastd.actor.onscreentimer import OnScreenTimer from bastd.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 = ba.app.lang.language
if lang == 'Spanish': if lang == 'Spanish':
name = 'Lluvia de Meteoritos v2' name = 'Lluvia de Meteoritos v2'
bomb_type = 'Tipo de Bomba' bomb_type = 'Tipo de Bomba'
ice = 'hielo' ice = 'hielo'
sticky = 'pegajosa' sticky = 'pegajosa'
impact = 'insta-bomba' impact = 'insta-bomba'
land_mine = 'mina terrestre' land_mine = 'mina terrestre'
random_bomb = 'aleatoria' random_bomb = 'aleatoria'
normal_rain = 'Lluvia Normal' normal_rain = 'Lluvia Normal'
frozen_rain = 'Lluvia Congelada' frozen_rain = 'Lluvia Congelada'
sticky_rain = 'Lluvia Pegajosa' sticky_rain = 'Lluvia Pegajosa'
impact_rain = 'Lluvia de Impacto' impact_rain = 'Lluvia de Impacto'
mine_rain = 'Lluvia de Minas' mine_rain = 'Lluvia de Minas'
tnt_rain = 'Lluvia de TNT' tnt_rain = 'Lluvia de TNT'
random_rain = 'Lluvia Aleatoria' random_rain = 'Lluvia Aleatoria'
else: else:
name = 'Meteor Shower v2' name = 'Meteor Shower v2'
bomb_type = 'Bomb Type' bomb_type = 'Bomb Type'
ice = 'ice' ice = 'ice'
sticky = 'sticky' sticky = 'sticky'
impact = 'impact' impact = 'impact'
land_mine = 'land mine' land_mine = 'land mine'
random_bomb = 'random' random_bomb = 'random'
normal_rain = 'Normal Rain' normal_rain = 'Normal Rain'
frozen_rain = 'Frozen Rain' frozen_rain = 'Frozen Rain'
sticky_rain = 'Sticky Rain' sticky_rain = 'Sticky Rain'
impact_rain = 'Impact Rain' impact_rain = 'Impact Rain'
mine_rain = 'Mine Rain' mine_rain = 'Mine Rain'
tnt_rain = 'TNT Rain' tnt_rain = 'TNT Rain'
random_rain = 'Random Rain' random_rain = 'Random Rain'
class Player(ba.Player['Team']): class Player(ba.Player['Team']):
"""Our player type for this game.""" """Our player type for this game."""
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self.death_time: float | None = None self.death_time: float | None = None
class Team(ba.Team[Player]): class Team(ba.Team[Player]):
"""Our team type for this game.""" """Our team type for this game."""
# ba_meta export game # ba_meta export game
class MeteorShowerv2Game(ba.TeamGameActivity[Player, Team]): class MeteorShowerv2Game(ba.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 = ba.ScoreConfig(
label='Survived', scoretype=ba.ScoreType.MILLISECONDS, version='B' label='Survived', scoretype=ba.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).
announce_player_deaths = True announce_player_deaths = True
# Don't allow joining after we start # Don't allow joining after we start
# (would enable leave/rejoin tomfoolery). # (would enable leave/rejoin tomfoolery).
allow_mid_activity_joins = False allow_mid_activity_joins = False
@classmethod @classmethod
def get_available_settings( def get_available_settings(
cls, sessiontype: type[ba.Session] cls, sessiontype: type[ba.Session]
) -> list[ba.Setting]: ) -> list[ba.Setting]:
settings = [ settings = [
ba.IntChoiceSetting( ba.IntChoiceSetting(
bomb_type, bomb_type,
choices=[ choices=[
('normal', 0), ('normal', 0),
(ice, 1), (ice, 1),
(sticky, 2), (sticky, 2),
(impact, 3), (impact, 3),
(land_mine, 4), (land_mine, 4),
('tnt', 5), ('tnt', 5),
(random_bomb, 6) (random_bomb, 6)
], ],
default=0, default=0,
), ),
ba.BoolSetting('Epic Mode', default=False), ba.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[ba.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[ba.Session]) -> bool:
return ( return (
issubclass(sessiontype, ba.DualTeamSession) issubclass(sessiontype, ba.DualTeamSession)
or issubclass(sessiontype, ba.FreeForAllSession) or issubclass(sessiontype, ba.FreeForAllSession)
or issubclass(sessiontype, ba.CoopSession) or issubclass(sessiontype, ba.CoopSession)
) )
def __init__(self, settings: dict): def __init__(self, settings: dict):
super().__init__(settings) super().__init__(settings)
btype = int(settings[bomb_type]) btype = int(settings[bomb_type])
if btype == 0: if btype == 0:
newbtype = 'normal' newbtype = 'normal'
elif btype == 1: elif btype == 1:
newbtype = 'ice' newbtype = 'ice'
elif btype == 2: elif btype == 2:
newbtype = 'sticky' newbtype = 'sticky'
elif btype == 3: elif btype == 3:
newbtype = 'impact' newbtype = 'impact'
elif btype == 4: elif btype == 4:
newbtype = 'land_mine' newbtype = 'land_mine'
elif btype == 5: elif btype == 5:
newbtype = 'tnt' newbtype = 'tnt'
else: else:
newbtype = 'random' newbtype = 'random'
self._bomb_type = newbtype self._bomb_type = newbtype
self._epic_mode = settings.get('Epic Mode', False) self._epic_mode = settings.get('Epic Mode', False)
self._last_player_death_time: float | None = None self._last_player_death_time: float | None = None
self._meteor_time = 2.0 self._meteor_time = 2.0
self._timer: OnScreenTimer | None = None self._timer: OnScreenTimer | None = None
# 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 ba.MusicType.EPIC if self._epic_mode else ba.MusicType.SURVIVAL
) )
if self._epic_mode: if self._epic_mode:
self.slow_motion = True self.slow_motion = True
def on_begin(self) -> None: def on_begin(self) -> None:
super().on_begin() super().on_begin()
# Drop a wave every few seconds.. and every so often drop the time # Drop a wave every few seconds.. and every so often drop the time
# between waves ..lets have things increase faster if we have fewer # between waves ..lets have things increase faster if we have fewer
# players. # players.
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) ba.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) ba.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) ba.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.
super().on_player_leave(player) super().on_player_leave(player)
# A departing player may trigger game-over. # A departing player may trigger game-over.
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) -> ba.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
# spaz but *without* the ability to attack or pick stuff up. # spaz but *without* the ability to attack or pick stuff up.
spaz.connect_controls_to_player( spaz.connect_controls_to_player(
enable_punch=False, enable_bomb=False, enable_pickup=False enable_punch=False, enable_bomb=False, enable_pickup=False
) )
# Also lets have them make some noise when they die. # Also lets have them make some noise when they die.
spaz.play_big_death_sound = True spaz.play_big_death_sound = True
return spaz return spaz
# 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, ba.PlayerDiedMessage):
# Augment standard behavior. # Augment standard behavior.
super().handlemessage(msg) super().handlemessage(msg)
curtime = ba.time() curtime = ba.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
msg.getplayer(Player).death_time = curtime msg.getplayer(Player).death_time = curtime
# In co-op mode, end the game the instant everyone dies # In co-op mode, end the game the instant everyone dies
# (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, ba.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) ba.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) ba.timer(1.0, self._check_end_game)
else: else:
# Default handler: # Default handler:
return super().handlemessage(msg) return super().handlemessage(msg)
return None return None
def _check_end_game(self) -> None: def _check_end_game(self) -> None:
living_team_count = 0 living_team_count = 0
for team in self.teams: for team in self.teams:
for player in team.players: for player in team.players:
if player.is_alive(): if player.is_alive():
living_team_count += 1 living_team_count += 1
break break
# 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, ba.CoopSession):
if living_team_count <= 0: if living_team_count <= 0:
self.end_game() self.end_game()
else: else:
if living_team_count <= 1: if living_team_count <= 1:
self.end_game() self.end_game()
def _set_meteor_timer(self) -> None: def _set_meteor_timer(self) -> None:
ba.timer( ba.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,
) )
def _drop_bomb_cluster(self) -> None: def _drop_bomb_cluster(self) -> None:
# Random note: code like this is a handy way to plot out extents # Random note: code like this is a handy way to plot out extents
# 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)}) ba.newnode('locator', attrs={'position': (8, 6, -5.5)})
ba.newnode('locator', attrs={'position': (8, 6, -2.3)}) ba.newnode('locator', attrs={'position': (8, 6, -2.3)})
ba.newnode('locator', attrs={'position': (-7.3, 6, -5.5)}) ba.newnode('locator', attrs={'position': (-7.3, 6, -5.5)})
ba.newnode('locator', attrs={'position': (-7.3, 6, -2.3)}) ba.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
for _i in range(random.randrange(1, 3)): for _i in range(random.randrange(1, 3)):
# Drop them somewhere within our bounds with velocity pointing # Drop them somewhere within our bounds with velocity pointing
# toward the opposite side. # toward the opposite side.
pos = ( pos = (
-7.3 + 15.3 * random.random(), -7.3 + 15.3 * random.random(),
11, 11,
-5.57 + 2.1 * random.random(), -5.57 + 2.1 * random.random(),
) )
dropdir = -1.0 if pos[0] > 0 else 1.0 dropdir = -1.0 if pos[0] > 0 else 1.0
vel = ( vel = (
(-5.0 + random.random() * 30.0) * dropdir, (-5.0 + random.random() * 30.0) * dropdir,
random.uniform(-3.066, -4.12), random.uniform(-3.066, -4.12),
0, 0,
) )
ba.timer(delay, ba.Call(self._drop_bomb, pos, vel)) ba.timer(delay, ba.Call(self._drop_bomb, pos, vel))
delay += 0.1 delay += 0.1
self._set_meteor_timer() self._set_meteor_timer()
def _drop_bomb( def _drop_bomb(
self, position: Sequence[float], velocity: Sequence[float] self, position: Sequence[float], velocity: Sequence[float]
) -> None: ) -> None:
if self._bomb_type == 'tnt': if self._bomb_type == 'tnt':
bomb_type = random.choice(['tnt','tnt','tnt','tnt','impact']) bomb_type = random.choice(['tnt', 'tnt', 'tnt', 'tnt', 'impact'])
elif self._bomb_type == 'land_mine': elif self._bomb_type == 'land_mine':
bomb_type = random.choice([ bomb_type = random.choice([
'land_mine','land_mine','land_mine','land_mine','impact']) 'land_mine', 'land_mine', 'land_mine', 'land_mine', 'impact'])
elif self._bomb_type == 'random': elif self._bomb_type == 'random':
bomb_type = random.choice([ bomb_type = random.choice([
'normal','ice','sticky','impact','land_mine','tnt']) 'normal', 'ice', 'sticky', 'impact', 'land_mine', 'tnt'])
else: else:
bomb_type = self._bomb_type bomb_type = self._bomb_type
Bomb(position=position, Bomb(position=position,
velocity=velocity, velocity=velocity,
bomb_type=bomb_type).autoretain() bomb_type=bomb_type).autoretain()
def _decrement_meteor_time(self) -> None: def _decrement_meteor_time(self) -> None:
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 = ba.time()
assert self._timer is not None assert self._timer is not None
start_time = self._timer.getstarttime() start_time = self._timer.getstarttime()
# Mark death-time as now for any still-living players # Mark death-time as now for any still-living players
# and award players points for how long they lasted. # and award players points for how long they lasted.
# (these per-player scores are only meaningful in team-games) # (these per-player scores are only meaningful in team-games)
for team in self.teams: for team in self.teams:
for player in team.players: for player in team.players:
survived = False survived = False
# Throw an extra fudge factor in so teams that # Throw an extra fudge factor in so teams that
# didn't die come out ahead of teams that did. # didn't die come out ahead of teams that did.
if player.death_time is None: if player.death_time is None:
survived = True survived = True
player.death_time = cur_time + 1 player.death_time = cur_time + 1
# Award a per-player score depending on how many seconds # Award a per-player score depending on how many seconds
# they lasted (per-player scores only affect teams mode; # they lasted (per-player scores only affect teams mode;
# everywhere else just looks at the per-team score). # everywhere else just looks at the per-team score).
score = int(player.death_time - self._timer.getstarttime()) score = int(player.death_time - self._timer.getstarttime())
if survived: if survived:
score += 50 # A bit extra for survivors. score += 50 # A bit extra for survivors.
self.stats.player_scored(player, score, screenmessage=False) self.stats.player_scored(player, score, screenmessage=False)
# Stop updating our time text, and set the final time to match # Stop updating our time text, and set the final time to match
# exactly when our last guy died. # exactly when our last guy died.
self._timer.stop(endtime=self._last_player_death_time) self._timer.stop(endtime=self._last_player_death_time)
# 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 = ba.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
# just always deal in teams and have all cases covered. # just always deal in teams and have all cases covered.
for team in self.teams: for team in self.teams:
# Set the team score to the max time survived by any player on # Set the team score to the max time survived by any player on
# that team. # that team.
longest_life = 0.0 longest_life = 0.0
for player in team.players: for player in team.players:
assert player.death_time is not None assert player.death_time is not None
longest_life = max(longest_life, player.death_time - start_time) longest_life = max(longest_life, player.death_time - start_time)
# Submit the score value in milliseconds. # Submit the score value in milliseconds.
results.set_team_score(team, int(1000.0 * longest_life)) results.set_team_score(team, int(1000.0 * longest_life))
self.end(results=results) self.end(results=results)
# ba_meta export plugin # ba_meta export plugin
class MeteorShowerv2Coop(ba.Plugin): class MeteorShowerv2Coop(ba.Plugin):
def on_app_running(self) -> None: def on_app_running(self) -> None:
ba.app.add_coop_practice_level( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.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( ba.app.add_coop_practice_level(
ba.Level( ba.Level(
random_rain, random_rain,
gametype=MeteorShowerv2Game, gametype=MeteorShowerv2Game,
settings={bomb_type: 6}, settings={bomb_type: 6},
preview_texture_name='rampagePreview', preview_texture_name='rampagePreview',
) )
) )

View file

@ -1,4 +1,4 @@
#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 7
from __future__ import annotations from __future__ import annotations
@ -12,6 +12,7 @@ from ba import _gameutils
import ba import ba
import random import random
class CustomText(ba.Actor): class CustomText(ba.Actor):
"""Text that pops up above a position to denote something special. """Text that pops up above a position to denote something special.
@ -39,7 +40,7 @@ class CustomText(ba.Actor):
'in_world': True, 'in_world': True,
'shadow': 1.0, 'shadow': 1.0,
'flatness': 1.0, 'flatness': 1.0,
'h_align': 'center'},delegate=self) 'h_align': 'center'}, delegate=self)
lifespan = duration lifespan = duration
ba.animate( ba.animate(
self.node, 'scale', { self.node, 'scale', {
@ -83,6 +84,7 @@ class CustomText(ba.Actor):
self._combine.connectattr('output', self.node, 'color') self._combine.connectattr('output', self.node, 'color')
self._die_timer = ba.Timer( self._die_timer = ba.Timer(
lifespan, ba.WeakCall(self.handlemessage, ba.DieMessage())) lifespan, ba.WeakCall(self.handlemessage, ba.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, ba.DieMessage):
@ -91,11 +93,14 @@ class CustomText(ba.Actor):
else: else:
super().handlemessage(msg) super().handlemessage(msg)
class Player(ba.Player['Team']): class Player(ba.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(ba.Team[Player]):
"""Our team type for this game.""" """Our team type for this game."""
@ -103,30 +108,33 @@ class Team(ba.Team[Player]):
self.score = 0 self.score = 0
# ba_meta export game # ba_meta export game
class SimonSays(ba.TeamGameActivity[Player, Team]): class SimonSays(ba.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[ba.Session]) -> List[ba.Setting]:
settings = [ settings = [
ba.BoolSetting("Epic Mode", default=False), ba.BoolSetting("Epic Mode", default=False),
ba.BoolSetting("Enable Jumping", default=False), ba.BoolSetting("Enable Jumping", default=False),
ba.BoolSetting("Enable Punching", default=False), ba.BoolSetting("Enable Punching", default=False),
ba.BoolSetting("Enable Picking Up", default=False), ba.BoolSetting("Enable Picking Up", default=False),
ba.IntChoiceSetting("Timer Speed", ba.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", ba.FloatChoiceSetting("Text Duration",
choices=[("Slow", 2.5), choices=[("Slow", 2.5),
("Normal", 1.5), ("Normal", 1.5),
("Mediocre", 1.0), ("Mediocre", 1.0),
("Quick", 0.75)], default=1.5)] ("Quick", 0.75)], default=1.5)]
return settings return settings
@classmethod @classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]: def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:
return ["Courtyard"] return ["Courtyard"]
@ -149,53 +157,54 @@ 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 = ba.newnode('text', attrs={
'in_world': True, 'in_world': True,
'text':'......', 'text': '......',
'shadow': 1.0, 'shadow': 1.0,
'color': (1.0,1.0,1.0), 'color': (1.0, 1.0, 1.0),
'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 = ba.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 = ba.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 = ba.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 = ba.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 = ba.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 = ba.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 = ba.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 = ba.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 = ba.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", "white", "top", "bottom", "middle row", "left", "right", "center column", "outside"] self.options = ["red", "green", "blue", "yellow", "teal", "purple", "gray", "orange",
"white", "top", "bottom", "middle row", "left", "right", "center column", "outside"]
self.default_music = ba.MusicType.FLAG_CATCHER self.default_music = ba.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( ba.screenmessage(
ba.Lstr(resource = 'playerDelayedJoinText', ba.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
else: else:
self.spawn_player(player) self.spawn_player(player)
@ -203,119 +212,147 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
def on_begin(self) -> None: def on_begin(self) -> None:
super().on_begin() super().on_begin()
s = self.settings s = self.settings
_gameutils.animate_array(self.n1,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n1, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n2,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n2, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n3,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n3, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n4,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n4, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n5,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n5, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n6,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n6, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n7,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n7, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n8,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n8, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
_gameutils.animate_array(self.n9,'size',1,{0:[0.0],0.2:[self._r1*2.0]}) _gameutils.animate_array(self.n9, 'size', 1, {0: [0.0], 0.2: [self._r1*2.0]})
for team in self.teams: for team in self.teams:
team.score = 0 team.score = 0
for player in self.players: for player in self.players:
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) ba.timer(4000, lambda: self.check_end(), timeformat=ba.TimeFormat.MILLISECONDS)
else: else:
ba.timer(6000, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS) ba.timer(6000, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS)
def spawn_player(self, player: PlayerType) -> ba.Actor: def spawn_player(self, player: PlayerType) -> ba.Actor:
assert player assert player
spaz = self.spawn_player_spaz(player, position=(0 + random.uniform(-3.6, 3.6), 2.9, -2 + random.uniform(-3.6, 3.6))) spaz = self.spawn_player_spaz(player, position=(
0 + random.uniform(-3.6, 3.6), 2.9, -2 + random.uniform(-3.6, 3.6)))
assert spaz.node assert spaz.node
spaz.connect_controls_to_player( spaz.connect_controls_to_player(
enable_bomb=False, enable_bomb=False,
enable_run = True, enable_run=True,
enable_punch = self.settings["Enable Punching"], enable_punch=self.settings["Enable Punching"],
enable_pickup = self.settings["Enable Picking Up"], enable_pickup=self.settings["Enable Picking Up"],
enable_jump = self.settings["Enable Jumping"]) enable_jump=self.settings["Enable Jumping"])
def call_round(self) -> None: def call_round(self) -> None:
if self.ended: return if self.ended:
return
self.round_num += 1 self.round_num += 1
self.num = random.randint(0, 15) self.num = random.randint(0, 15)
self.numa = self.num self.numa = self.num
self.simon = random.choice([True, False]) self.simon = random.choice([True, False])
false_prefix = random.choices(['Simon say r', 'Simon said r', 'Simon r', 'Simons says r', 'Simons r', 'R'], weights=[35,45,45,39,49,100])[0] false_prefix = random.choices(['Simon say r', 'Simon said r', 'Simon r',
'Simons says r', 'Simons r', 'R'], weights=[35, 45, 45, 39, 49, 100])[0]
if self.numa < 9: if self.numa < 9:
if not self.simon: line = false_prefix + "un to the " + self.options[self.numa] + " circle!" if not self.simon:
else: line = "Run to the " + self.options[self.numa] + " circle!" line = false_prefix + "un to the " + self.options[self.numa] + " circle!"
else:
line = "Run to the " + self.options[self.numa] + " circle!"
elif self.numa < 15: elif self.numa < 15:
if not self.simon: line = false_prefix + "un to the " + self.options[self.numa] + "!" if not self.simon:
else: line = "Run to the " + self.options[self.numa] + "!" line = false_prefix + "un to the " + self.options[self.numa] + "!"
else:
line = "Run to the " + self.options[self.numa] + "!"
else: else:
if not self.simon: line = false_prefix + "un outside of the circles!" if not self.simon:
else: line = "Run outside of the circles!" line = false_prefix + "un outside of the circles!"
else:
line = "Run outside of the circles!"
if self.simon: if self.simon:
line = "Simon says " + line[0].lower() + line[1:] line = "Simon says " + line[0].lower() + line[1:]
self.text = CustomText(line, self.text = CustomText(line,
position=(0, 5, -4), position=(0, 5, -4),
color=(0.68, 0.95, 1.12), color=(0.68, 0.95, 1.12),
random_offset=0.5, random_offset=0.5,
offset=(0, 0, 0), offset=(0, 0, 0),
duration=self.lifespan, duration=self.lifespan,
scale=2.0).autoretain() scale=2.0).autoretain()
self.now = 6 self.now = 6
def dummy_check(): def dummy_check():
self.string = "...." self.string = "...."
self.check_round() self.check_round()
def set_counter(): def set_counter():
self.now = self.now - 1 self.now = self.now - 1
if self.now == 0: if self.now == 0:
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) ba.timer(1, dummy_check, timeformat=ba.TimeFormat.MILLISECONDS)
else: else:
self.ct_text.text = str(self.now) self.ct_text.text = str(self.now)
ba.playsound(ba.getsound('tick')) ba.playsound(ba.getsound('tick'))
self.counter_loop = ba.Timer(self.speed, set_counter ,timeformat=ba.TimeFormat.MILLISECONDS,repeat=True) self.counter_loop = ba.Timer(self.speed, set_counter,
timeformat=ba.TimeFormat.MILLISECONDS, repeat=True)
def check_round(self) -> None: def check_round(self) -> None:
if self.ended: return if self.ended:
return
for player in self.players: for player in self.players:
if player.is_alive(): if player.is_alive():
safe = True if self.options[self.numa] in self.in_circle(player.actor.node.position_center) else False safe = True if self.options[self.numa] in self.in_circle(
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(ba.DieMessage())
ba.timer(1633, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS) ba.timer(1633, self.call_round, timeformat=ba.TimeFormat.MILLISECONDS)
def in_circle(self, pos) -> None: def in_circle(self, pos) -> None:
circles = [] circles = []
x = pos[0] x = pos[0]
z = pos[2] z = pos[2]
if (x + 4) ** 2 + (z + 6) ** 2 < 4: circles.append("red") if (x + 4) ** 2 + (z + 6) ** 2 < 4:
elif (x) ** 2 + (z + 6) ** 2 < 4: circles.append("green") circles.append("red")
elif (x - 4) ** 2 + (z + 6) ** 2 < 4: circles.append("blue") elif (x) ** 2 + (z + 6) ** 2 < 4:
elif (x + 4) ** 2 + (z + 2) ** 2 < 4: circles.append("yellow") circles.append("green")
elif (x) ** 2 + (z + 2) ** 2 < 4: circles.append("teal") elif (x - 4) ** 2 + (z + 6) ** 2 < 4:
elif (x - 4) ** 2 + (z + 2) ** 2 < 4: circles.append("purple") circles.append("blue")
elif (x + 4) ** 2 + (z - 2) ** 2 < 4: circles.append("gray") elif (x + 4) ** 2 + (z + 2) ** 2 < 4:
elif (x) ** 2 + (z - 2) ** 2 < 4: circles.append("orange") circles.append("yellow")
elif (x - 4) ** 2 + (z - 2) ** 2 < 4: circles.append("white") elif (x) ** 2 + (z + 2) ** 2 < 4:
else: circles.append("outside") circles.append("teal")
if x < -2: circles.append("left") elif (x - 4) ** 2 + (z + 2) ** 2 < 4:
if x > 2: circles.append("right") circles.append("purple")
if x > -2 and x < 2: circles.append("center column") elif (x + 4) ** 2 + (z - 2) ** 2 < 4:
if z > 0: circles.append("bottom") circles.append("gray")
if z < -4: circles.append("top") elif (x) ** 2 + (z - 2) ** 2 < 4:
if z < 0 and z > -4: circles.append("middle row") circles.append("orange")
elif (x - 4) ** 2 + (z - 2) ** 2 < 4:
circles.append("white")
else:
circles.append("outside")
if x < -2:
circles.append("left")
if x > 2:
circles.append("right")
if x > -2 and x < 2:
circles.append("center column")
if z > 0:
circles.append("bottom")
if z < -4:
circles.append("top")
if z < 0 and z > -4:
circles.append("middle row")
return circles return circles
def handlemessage(self, msg) -> None: def handlemessage(self, msg) -> None:
if isinstance(msg, ba.PlayerDiedMessage): if isinstance(msg, ba.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
@ -327,7 +364,7 @@ class SimonSays(ba.TeamGameActivity[Player, Team]):
def check_end(self) -> None: def check_end(self) -> None:
i = 0 i = 0
for player in self.players: for player in self.players:
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()) ba.timer(0.6, lambda: self.end_game())

View file

@ -30,6 +30,7 @@ class NewBlast(Blast):
else: else:
return super().handlemessage(msg) return super().handlemessage(msg)
@dataclass @dataclass
class RaceMine: class RaceMine:
"""Holds info about a mine on the track.""" """Holds info about a mine on the track."""
@ -223,7 +224,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
('modify_part_collision', 'physical', False), ('modify_part_collision', 'physical', False),
('call', 'at_connect', ('call', 'at_connect',
self._handle_race_point_collide), self._handle_race_point_collide),
)) ))
for rpt in pts: for rpt in pts:
self._regions.append(RaceRegion(rpt, len(self._regions))) self._regions.append(RaceRegion(rpt, len(self._regions)))
@ -271,7 +272,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
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))]),
color=(1, 0, 0)) color=(1, 0, 0))
else: else:
# If this player is in first, note that this is the # If this player is in first, note that this is the
# front-most race-point. # front-most race-point.
@ -397,7 +398,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
'${TEAM} is disqualified because ${PLAYER} left'), '${TEAM} is disqualified because ${PLAYER} left'),
subs=[('${TEAM}', player.team.name), subs=[('${TEAM}', player.team.name),
('${PLAYER}', player.getname(full=True))]), ('${PLAYER}', player.getname(full=True))]),
color=(1, 1, 0)) color=(1, 1, 0))
player.team.finished = True player.team.finished = True
player.team.time = None player.team.time = None
player.team.lap = 0 player.team.lap = 0
@ -535,7 +536,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
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( ba.newnode(
'image', 'image',
attrs={ attrs={
@ -552,7 +553,7 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
'color': (1.0, 0.0, 0.0), 'color': (1.0, 0.0, 0.0),
'attach': 'topCenter', 'attach': 'topCenter',
'position': (-220, -38), 'position': (-220, -38),
'scale':(155, 65), 'scale': (155, 65),
'texture': ba.gettexture('uiAtlas'), 'texture': ba.gettexture('uiAtlas'),
'model_transparent': ba.getmodel('meterTransparent')}) 'model_transparent': ba.getmodel('meterTransparent')})
self._sgcountdown_text = ba.newnode( self._sgcountdown_text = ba.newnode(
@ -615,9 +616,9 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
self._tick_timer = ba.timer(1.0, do_ticks, repeat=True) self._tick_timer = ba.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]
normal = [4,4.5,5] normal = [4, 4.5, 5]
hard = [3,3.5,4] hard = [3, 3.5, 4]
random_number = random.choice( random_number = random.choice(
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)
@ -665,18 +666,18 @@ class SquidRaceGame(ba.TeamGameActivity[Player, Team]):
posy = float("%.1f" % player.customdata['position'][2]) posy = float("%.1f" % player.customdata['position'][2])
posx_list = [ posx_list = [
round(posx,1),round(posx+0.1,1),round(posx+0.2,1), round(posx, 1), round(posx+0.1, 1), round(posx+0.2, 1),
round(posx-0.1,1),round(posx-0.2,1)] round(posx-0.1, 1), round(posx-0.2, 1)]
current_posx = float("%.1f" % player.actor.node.position[0]) current_posx = float("%.1f" % player.actor.node.position[0])
posz_list = [ posz_list = [
round(posz,1),round(posz+0.1,1),round(posz+0.2,1), round(posz, 1), round(posz+0.1, 1), round(posz+0.2, 1),
round(posz-0.1,1),round(posz-0.2,1)] round(posz-0.1, 1), round(posz-0.2, 1)]
current_posz = float("%.1f" % player.actor.node.position[1]) current_posz = float("%.1f" % player.actor.node.position[1])
posy_list = [ posy_list = [
round(posy,1),round(posy+0.1,1),round(posy+0.2,1), round(posy, 1), round(posy+0.1, 1), round(posy+0.2, 1),
round(posy-0.1,1),round(posy-0.2,1)] round(posy-0.1, 1), round(posy-0.2, 1)]
current_posy = float("%.1f" % player.actor.node.position[2]) current_posy = float("%.1f" % player.actor.node.position[2])
if not (current_posx in posx_list) or not ( if not (current_posx in posx_list) or not (

View file

@ -65,7 +65,7 @@ class PlayerSpaz_Zom(PlayerSpaz):
if not playa is None: if not playa is None:
if opposingnode._source_player.lives > 0: if opposingnode._source_player.lives > 0:
return True return True
except Exception: except Exception:
pass pass
if (opposingnode.getnodetype() == 'spaz' if (opposingnode.getnodetype() == 'spaz'
@ -82,6 +82,7 @@ class PlayerSpaz_Zom(PlayerSpaz):
return super().handlemessage(m) return super().handlemessage(m)
return None return None
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, ba.HitMessage):
@ -101,6 +102,7 @@ class PlayerZombie(PlayerSpaz):
else: else:
super().handlemessage(m) super().handlemessage(m)
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."""
@ -139,6 +141,7 @@ class zBotSet(SpazBotSet):
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(ba.Team[Player]):
"""Our team type for this game.""" """Our team type for this game."""
@ -242,8 +245,8 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
activity = ba.getactivity() activity = ba.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(ba.app.spaz_appearances['Kronk'])
myAppear.name = 'Kronk2' myAppear.name = 'Kronk2'
ba.app.spaz_appearances['Kronk2'] = myAppear ba.app.spaz_appearances['Kronk2'] = myAppear
@ -252,7 +255,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
med = my_factory.spaz_media med = my_factory.spaz_media
med['Kronk2']['head_model'] = med['Zoe']['head_model'] med['Kronk2']['head_model'] = med['Zoe']['head_model']
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_model'] = med['Bones']['torso_model']
med['Kronk2']['pelvis_model'] = med['Pixel']['pelvis_model'] med['Kronk2']['pelvis_model'] = med['Pixel']['pelvis_model']
med['Kronk2']['upper_arm_model'] = med['Frosty']['upper_arm_model'] med['Kronk2']['upper_arm_model'] = med['Frosty']['upper_arm_model']
@ -351,9 +354,9 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
self._bots = zBotSet() self._bots = zBotSet()
#Set colors and character for ToughGuyBot to be zombie # Set colors and character for ToughGuyBot to be zombie
setattr(BrawlerBot, 'color', (0.4,0.1,0.05)) setattr(BrawlerBot, 'color', (0.4, 0.1, 0.05))
setattr(BrawlerBot, 'highlight', (0.2,0.4,0.3)) setattr(BrawlerBot, 'highlight', (0.2, 0.4, 0.3))
setattr(BrawlerBot, 'character', 'Kronk2') setattr(BrawlerBot, 'character', 'Kronk2')
# start some timers to spawn bots # start some timers to spawn bots
thePt = self.map.get_ffa_start_position(self.players) thePt = self.map.get_ffa_start_position(self.players)
@ -434,7 +437,6 @@ 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) -> ba.Vec3 | None:
del player # Unused. del player # Unused.
@ -612,7 +614,7 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
try: try:
pos = player.actor.node.position pos = player.actor.node.position
except Exception as e: except Exception as e:
print('EXC getting player pos in bsElim',e) print('EXC getting player pos in bsElim', e)
return return
if player.lives > 0: if player.lives > 0:
popuptext.PopupText('x' + str(player.lives - 1), popuptext.PopupText('x' + str(player.lives - 1),
@ -692,7 +694,8 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
elif isinstance(msg, SpazBotDiedMessage): elif isinstance(msg, SpazBotDiedMessage):
self._onSpazBotDied(msg) self._onSpazBotDied(msg)
super().handlemessage(msg)#bs.PopupText("died",position=self._position,color=popupColor,scale=popupScale).autoRetain() # bs.PopupText("died",position=self._position,color=popupColor,scale=popupScale).autoRetain()
super().handlemessage(msg)
else: else:
super().handlemessage(msg) super().handlemessage(msg)
@ -734,15 +737,15 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
self._round_end_timer = ba.Timer(0.5, self.end_game) self._round_end_timer = ba.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( ba.timer(0.1, ba.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:
#Just in case we are over max... # Just in case we are over max...
if len(self._bots.get_living_bots()) < self._max_zombies: if len(self._bots.get_living_bots()) < self._max_zombies:
self.zombieQ += 1 self.zombieQ += 1
@ -762,37 +765,38 @@ class ZombieHorde(ba.TeamGameActivity[Player, Team]):
myMap = self.map.getname() myMap = self.map.getname()
if myMap == 'Doom Shroom': if myMap == 'Doom Shroom':
while True: while True:
x = random.uniform(-1.0,1.0) x = random.uniform(-1.0, 1.0)
y = random.uniform(-1.0,1.0) y = random.uniform(-1.0, 1.0)
if x*x+y*y < 1.0: break if x*x+y*y < 1.0:
return ((8.0*x,8.0,-3.5+5.0*y)) break
return ((8.0*x, 8.0, -3.5+5.0*y))
elif myMap == 'Rampage': elif myMap == 'Rampage':
x = random.uniform(-6.0,7.0) x = random.uniform(-6.0, 7.0)
y = random.uniform(-6.0,-2.5) y = random.uniform(-6.0, -2.5)
return ((x, 8.0, y)) return ((x, 8.0, y))
elif myMap == 'Hockey Stadium': elif myMap == 'Hockey Stadium':
x = random.uniform(-11.5,11.5) x = random.uniform(-11.5, 11.5)
y = random.uniform(-4.5,4.5) y = random.uniform(-4.5, 4.5)
return ((x, 5.0, y)) return ((x, 5.0, y))
elif myMap == 'Courtyard': elif myMap == 'Courtyard':
x = random.uniform(-4.3,4.3) x = random.uniform(-4.3, 4.3)
y = random.uniform(-4.4,0.3) y = random.uniform(-4.4, 0.3)
return ((x, 8.0, y)) return ((x, 8.0, y))
elif myMap == 'Crag Castle': elif myMap == 'Crag Castle':
x = random.uniform(-6.7,8.0) x = random.uniform(-6.7, 8.0)
y = random.uniform(-6.0,0.0) y = random.uniform(-6.0, 0.0)
return ((x, 12.0, y)) return ((x, 12.0, y))
elif myMap == 'Big G': elif myMap == 'Big G':
x = random.uniform(-8.7,8.0) x = random.uniform(-8.7, 8.0)
y = random.uniform(-7.5,6.5) y = random.uniform(-7.5, 6.5)
return ((x, 8.0, y)) return ((x, 8.0, y))
elif myMap == 'Football Stadium': elif myMap == 'Football Stadium':
x = random.uniform(-12.5,12.5) x = random.uniform(-12.5, 12.5)
y = random.uniform(-5.0,5.5) y = random.uniform(-5.0, 5.5)
return ((x, 8.0, y)) return ((x, 8.0, y))
else: else:
x = random.uniform(-5.0,5.0) x = random.uniform(-5.0, 5.0)
y = random.uniform(-6.0,0.0) y = random.uniform(-6.0, 0.0)
return ((x, 8.0, y)) return ((x, 8.0, y))
def _update_scoreboard(self) -> None: def _update_scoreboard(self) -> None: