def _touch_return_update(self, team: ba.Team) -> None: # Count down only while its away from base and not being held. if (team.gamedata['home_flag_at_base'] or team.gamedata['flag'].held_count > 0): team.gamedata['touch_return_timer_ticking'] = None return # No need to return when its at home. if team.gamedata['touch_return_timer_ticking'] is None: team.gamedata['touch_return_timer_ticking'] = ba.NodeActor( ba.newnode('sound', attrs={ 'sound': self._ticking_sound, 'positional': False, 'loop': True })) flag = team.gamedata['flag'] flag.touch_return_time -= 0.1 if flag.counter: flag.counter.text = '%.1f' % flag.touch_return_time flag.counter.color = (1, 1, 0, 1) flag.counter.scale = 0.02 if flag.touch_return_time <= 0.0: self._award_players_touching_own_flag(team) flag.handlemessage(ba.DieMessage())
def _add_team(self, team: ba.Team) -> None: if team.get_id() in self._entries: raise Exception('Duplicate team add') self._entries[team.get_id()] = _Entry(self, team, do_cover=self._do_cover, scale=self._scale, label=self._label, flash_length=self._flash_length) self._update_teams()
def _handle_flag_entered_base(self, team: ba.Team) -> None: node = ba.get_collision_info('opposing_node') assert isinstance(node, (ba.Node, type(None))) flag = CTFFlag.from_node(node) if not flag: print('Unable to get flag in _handle_flag_entered_base') return if flag.team is team: team.gamedata['home_flag_at_base'] = True # If the enemy flag is already here, score! if team.gamedata['enemy_flag_at_base']: self._score(team) else: team.gamedata['enemy_flag_at_base'] = True if team.gamedata['home_flag_at_base']: # Award points to whoever was carrying the enemy flag. player = flag.last_player_to_hold if player and player.team is team: assert self.stats self.stats.player_scored(player, 50, big_message=True) # Update score and reset flags. self._score(team) # If the home-team flag isn't here, print a message to that effect. else: # Don't want slo-mo affecting this curtime = ba.time(ba.TimeType.BASE) if curtime - self._last_home_flag_notice_print_time > 5.0: self._last_home_flag_notice_print_time = curtime bpos = team.gamedata['base_pos'] tval = ba.Lstr(resource='ownFlagAtYourBaseWarning') tnode = ba.newnode('text', attrs={ 'text': tval, 'in_world': True, 'scale': 0.013, 'color': (1, 1, 0, 1), 'h_align': 'center', 'position': (bpos[0], bpos[1] + 3.2, bpos[2]) }) ba.timer(5.1, tnode.delete) ba.animate(tnode, 'scale', { 0.0: 0, 0.2: 0.013, 4.8: 0.013, 5.0: 0 })
def set_team_score(self, team: ba.Team, score: int) -> None: """Set the score for a given ba.Team. This can be a number or None. (see the none_is_winner arg in the constructor) """ self._scores[team.get_id()] = (weakref.ref(team), score)
def _handle_hit_own_flag(self, team: ba.Team, val: int) -> None: """ keep track of when each player is touching their own flag so we can award points when returned """ srcnode = ba.get_collision_info('source_node') assert isinstance(srcnode, (ba.Node, type(None))) player = self._player_from_node(srcnode) if player: player.gamedata['touching_own_flag'] += (1 if val else -1) # If return-time is zero, just kill it immediately.. otherwise keep # track of touches and count down. if float(self.settings_raw['Flag Touch Return Time']) <= 0.0: if (not team.gamedata['home_flag_at_base'] and team.gamedata['flag'].held_count == 0): # Use a node message to kill the flag instead of just killing # our team's. (avoids redundantly killing new flags if # multiple body parts generate callbacks in one step). node = ba.get_collision_info('opposing_node') if node: self._award_players_touching_own_flag(team) node.handlemessage(ba.DieMessage()) # Takes a non-zero amount of time to return. else: if val: team.gamedata['flag_return_touches'] += 1 if team.gamedata['flag_return_touches'] == 1: team.gamedata['touch_return_timer'] = ba.Timer( 0.1, call=ba.Call(self._touch_return_update, team), repeat=True) team.gamedata['touch_return_timer_ticking'] = None else: team.gamedata['flag_return_touches'] -= 1 if team.gamedata['flag_return_touches'] == 0: team.gamedata['touch_return_timer'] = None team.gamedata['touch_return_timer_ticking'] = None if team.gamedata['flag_return_touches'] < 0: ba.print_error( "CTF: flag_return_touches < 0; this shouldn't happen.")
def _handle_flag_left_base(self, team: ba.Team) -> None: cur_time = ba.time() op_node = ba.get_collision_info('opposing_node') assert isinstance(op_node, (ba.Node, type(None))) flag = CTFFlag.from_node(op_node) if not flag: return if flag.team is team: # Check times here to prevent too much flashing. if ('last_flag_leave_time' not in team.gamedata or cur_time - team.gamedata['last_flag_leave_time'] > 3.0): ba.playsound(self._alarmsound, position=team.gamedata['base_pos']) self._flash_base(team) team.gamedata['last_flag_leave_time'] = cur_time team.gamedata['home_flag_at_base'] = False else: team.gamedata['enemy_flag_at_base'] = False
def set_team_value(self, team: ba.Team, score: int, max_score: int = None, countdown: bool = False, flash: bool = True, show_value: bool = True) -> None: """Update the score-board display for the given ba.Team.""" if not team.get_id() in self._entries: self._add_team(team) # create a proxy in the team which will kill # our entry when it dies (for convenience) if '_scoreboard_entry' in team.gamedata: raise Exception("existing _EntryProxy found") team.gamedata['_scoreboard_entry'] = _EntryProxy(self, team) # now set the entry.. self._entries[team.get_id()].set_value(score=score, max_score=max_score, countdown=countdown, flash=flash, show_value=show_value)
def on_team_join(self, team: ba.Team) -> None: team.gamedata['score'] = 0 if self.has_begun(): self._update_scoreboard()
def on_team_join(self, team: ba.Team) -> None: team.gamedata['score'] = 0 self._update_scoreboard()
def on_team_join(self, team: ba.Team) -> None: team.gamedata['time_remaining'] = self.settings['Hold Time'] self._update_scoreboard()
def __init__(self, scoreboard: Scoreboard, team: ba.Team): self._scoreboard = weakref.ref(scoreboard) # have to store ID here instead of a weak-ref since the team will be # dead when we die and need to remove it self._team_id = team.get_id()
def on_team_join(self, team: ba.Team) -> None: team.gamedata['survival_seconds'] = None team.gamedata['spawn_order'] = []
def _spawn_flag_for_team(self, team: ba.Team) -> None: flag = team.gamedata['flag'] = CTFFlag(team) team.gamedata['flag_return_touches'] = 0 self._flash_base(team, length=1.0) assert flag.node ba.playsound(self._swipsound, position=flag.node.position)
def on_team_join(self, team: ba.Team) -> None: team.gamedata['score'] = 0 team.gamedata['flag_return_touches'] = 0 team.gamedata['home_flag_at_base'] = True team.gamedata['touch_return_timer'] = None team.gamedata['enemy_flag_at_base'] = False team.gamedata['base_pos'] = (self.map.get_flag_position(team.get_id())) self.project_flag_stand(team.gamedata['base_pos']) ba.newnode('light', attrs={ 'position': team.gamedata['base_pos'], 'intensity': 0.6, 'height_attenuated': False, 'volume_intensity_scale': 0.1, 'radius': 0.1, 'color': team.color }) base_region_mat = team.gamedata['base_region_material'] = ba.Material() pos = team.gamedata['base_pos'] team.gamedata['base_region'] = ba.newnode( 'region', attrs={ 'position': (pos[0], pos[1] + 0.75, pos[2]), 'scale': (0.5, 0.5, 0.5), 'type': 'sphere', 'materials': [base_region_mat, self._all_bases_material] }) # create some materials for this team spaz_mat_no_flag_physical = team.gamedata[ 'spaz_material_no_flag_physical'] = ba.Material() spaz_mat_no_flag_collide = team.gamedata[ 'spaz_material_no_flag_collide'] = ba.Material() flagmat = team.gamedata['flagmaterial'] = ba.Material() # Some parts of our spazzes don't collide physically with our # flags but generate callbacks. spaz_mat_no_flag_physical.add_actions( conditions=('they_have_material', flagmat), actions=(('modify_part_collision', 'physical', False), ('call', 'at_connect', lambda: self._handle_hit_own_flag(team, 1)), ('call', 'at_disconnect', lambda: self._handle_hit_own_flag(team, 0)))) # Other parts of our spazzes don't collide with our flags at all. spaz_mat_no_flag_collide.add_actions(conditions=('they_have_material', flagmat), actions=('modify_part_collision', 'collide', False)) # We wanna know when *any* flag enters/leaves our base. base_region_mat.add_actions( conditions=('they_have_material', stdflag.get_factory().flagmaterial), actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', lambda: self._handle_flag_entered_base(team)), ('call', 'at_disconnect', lambda: self._handle_flag_left_base(team)))) self._spawn_flag_for_team(team) self._update_scoreboard()
def on_team_join(self, team: ba.Team) -> None: if self.has_begun(): self._update_scores() team.gamedata['flags_held'] = 0
def on_team_join(self, team: ba.Team) -> None: team.gamedata['time'] = None team.gamedata['lap'] = 0 team.gamedata['finished'] = False self._update_scoreboard()
def on_team_join(self, team: ba.Team) -> None: team.gamedata['time_remaining'] = self.settings["Chosen One Time"] self._update_scoreboard()