def spawn_player_spaz(self, player: PlayerType, position: Sequence[float] = (0, 0, 0), angle: float = None) -> MyPlayerSpaz: """Create and wire up a ba.PlayerSpaz for the provided ba.Player.""" # pylint: disable=too-many-locals # pylint: disable=cyclic-import name = player.getname() color = player.color highlight = player.highlight light_color = _math.normalized_color(color) display_color = _ba.safecolor(color, target_intensity=0.75) spaz = MyPlayerSpaz(color=color, highlight=highlight, character=player.character, player=player) player.actor = spaz assert spaz.node if position is None: # In teams-mode get our team-start-location. if isinstance(self.session, DualTeamSession): position = (self.map.get_start_position(player.team.id)) else: # Otherwise do free-for-all spawn locations. position = self.map.get_ffa_start_position(self.players) # If this is co-op and we're on Courtyard or Runaround, add the # material that allows us to collide with the player-walls. # FIXME: Need to generalize this. if isinstance(self.session, CoopSession) and self.map.getname() in [ 'Courtyard', 'Tower D' ]: mat = self.map.preloaddata['collide_with_wall_material'] assert isinstance(spaz.node.materials, tuple) assert isinstance(spaz.node.roller_materials, tuple) spaz.node.materials += (mat, ) spaz.node.roller_materials += (mat, ) spaz.node.name = name spaz.node.name_color = display_color spaz.connect_controls_to_player() # Move to the stand position and add a flash of light. spaz.handlemessage( StandMessage( position, angle if angle is not None else random.uniform(0, 360))) _ba.playsound(self._spawn_sound, 1, position=spaz.node.position) light = _ba.newnode('light', attrs={'color': light_color}) spaz.node.connectattr('position', light, 'position') animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}) _ba.timer(0.5, light.delete) return spaz
def announce_game_results(self, activity: ba.GameActivity, results: ba.GameResults, delay: float, announce_winning_team: bool = True) -> None: """Show basic game result at the end of a game. (before transitioning to a score screen). This will include a zoom-text of 'BLUE WINS' or whatnot, along with a possible audio announcement of the same. """ # pylint: disable=cyclic-import # pylint: disable=too-many-locals from ba._math import normalized_color from ba._general import Call from ba._gameutils import cameraflash from ba._language import Lstr from ba._freeforallsession import FreeForAllSession from ba._messages import CelebrateMessage _ba.timer(delay, Call(_ba.playsound, _ba.getsound('boxingBell'))) if announce_winning_team: winning_sessionteam = results.winning_sessionteam if winning_sessionteam is not None: # Have all players celebrate. celebrate_msg = CelebrateMessage(duration=10.0) assert winning_sessionteam.activityteam is not None for player in winning_sessionteam.activityteam.players: if player.actor: player.actor.handlemessage(celebrate_msg) cameraflash() # Some languages say "FOO WINS" different for teams vs players. if isinstance(self, FreeForAllSession): wins_resource = 'winsPlayerText' else: wins_resource = 'winsTeamText' wins_text = Lstr(resource=wins_resource, subs=[('${NAME}', winning_sessionteam.name)]) activity.show_zoom_message( wins_text, scale=0.85, color=normalized_color(winning_sessionteam.color), )
def player_scored(self, player: ba.Player, base_points: int = 1, target: Sequence[float] = None, kill: bool = False, victim_player: ba.Player = None, scale: float = 1.0, color: Sequence[float] = None, title: Union[str, ba.Lstr] = None, screenmessage: bool = True, display: bool = True, importance: int = 1, showpoints: bool = True, big_message: bool = False) -> int: """Register a score for the player. Return value is actual score with multipliers and such factored in. """ # FIXME: Tidy this up. # pylint: disable=cyclic-import # pylint: disable=too-many-branches # pylint: disable=too-many-locals # pylint: disable=too-many-statements from bastd.actor.popuptext import PopupText from ba import _math from ba._gameactivity import GameActivity from ba._lang import Lstr del victim_player # Currently unused. name = player.getname() s_player = self._player_records[name] if kill: s_player.submit_kill(showpoints=showpoints) display_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) if color is not None: display_color = color elif importance != 1: display_color = (1.0, 1.0, 0.4, 1.0) points = base_points # If they want a big announcement, throw a zoom-text up there. if display and big_message: try: assert self._activity is not None activity = self._activity() if isinstance(activity, GameActivity): name_full = player.getname(full=True, icon=False) activity.show_zoom_message( Lstr(resource='nameScoresText', subs=[('${NAME}', name_full)]), color=_math.normalized_color(player.team.color)) except Exception: print_exception('error showing big_message') # If we currently have a actor, pop up a score over it. if display and showpoints: our_pos = player.node.position if player.node else None if our_pos is not None: if target is None: target = our_pos # If display-pos is *way* lower than us, raise it up # (so we can still see scores from dudes that fell off cliffs). display_pos = (target[0], max(target[1], our_pos[1] - 2.0), min(target[2], our_pos[2] + 2.0)) activity = self.getactivity() if activity is not None: if title is not None: sval = Lstr(value='+${A} ${B}', subs=[('${A}', str(points)), ('${B}', title)]) else: sval = Lstr(value='+${A}', subs=[('${A}', str(points))]) PopupText(sval, color=display_color, scale=1.2 * scale, position=display_pos).autoretain() # Tally kills. if kill: s_player.accum_kill_count += 1 s_player.kill_count += 1 # Report non-kill scorings. try: if screenmessage and not kill: _ba.screenmessage(Lstr(resource='nameScoresText', subs=[('${NAME}', name)]), top=True, color=player.color, image=player.get_icon()) except Exception: print_exception('error announcing score') s_player.score += points s_player.accumscore += points # Inform a running game of the score. if points != 0: activity = self._activity() if self._activity is not None else None if activity is not None: activity.handlemessage(PlayerScoredMessage(score=points)) return points