def on_begin(self) -> None: super().on_begin() self.setup_standard_time_limit(self._time_limit) self.setup_standard_powerup_drops() self._puck_spawn_pos = self.map.get_flag_position(None) self._spawn_puck() # Set up the two score regions. defs = self.map.defs self._score_regions = [] self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': [self._score_region_material] }))) self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], 'type': 'box', 'materials': [self._score_region_material] }))) self._update_scoreboard() ba.playsound(self._chant_sound)
def on_begin(self) -> None: super().on_begin() shared = SharedObjects.get() self.setup_standard_time_limit(self._time_limit) self.setup_standard_powerup_drops() self._flag_pos = self.map.get_flag_position(None) ba.timer(1.0, self._tick, repeat=True) self._flag_state = FlagState.NEW Flag.project_stand(self._flag_pos) self._flag = Flag(position=self._flag_pos, touchable=False, color=(1, 1, 1)) self._flag_light = ba.newnode('light', attrs={ 'position': self._flag_pos, 'intensity': 0.2, 'height_attenuated': False, 'radius': 0.4, 'color': (0.2, 0.2, 0.2) }) # Flag region. flagmats = [self._flag_region_material, shared.region_material] ba.newnode('region', attrs={ 'position': self._flag_pos, 'scale': (1.8, 1.8, 1.8), 'type': 'sphere', 'materials': flagmats }) self._update_flag_state()
def on_begin(self) -> None: super().on_begin() self.setup_standard_time_limit(self.settings['Time Limit']) self.setup_standard_powerup_drops() self._flag_spawn_pos = (self.map.get_flag_position(None)) self._spawn_flag() defs = self.map.defs self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': (self.score_region_material, ) }))) self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], 'type': 'box', 'materials': (self.score_region_material, ) }))) self._update_scoreboard() ba.playsound(self._chant_sound)
def on_transition_in(self) -> None: super().on_transition_in() self._scoreboard = Scoreboard() self._flag_spawn_pos = self.map.get_flag_position(None) self._spawn_flag() # Set up the two score regions. defs = self.map.defs self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal1'][0:3], 'scale': defs.boxes['goal1'][6:9], 'type': 'box', 'materials': [self._score_region_material] }))) self._score_regions.append( ba.NodeActor( ba.newnode('region', attrs={ 'position': defs.boxes['goal2'][0:3], 'scale': defs.boxes['goal2'][6:9], 'type': 'box', 'materials': [self._score_region_material] }))) ba.playsound(self._chant_sound)
def spawn_holding_node(self) -> Optional[ba.Node]: if not self.node: return None self.delete_holding_node() t = self.node.position t = (t[0], t[1] + 1, t[2]) self.holding_node = ba.newnode('prop', owner=self.node, delegate=self, attrs={ 'position': t, 'body': 'box', 'body_scale': 0.000001, 'model': None, 'model_scale': 0.000001, 'color_texture': None, 'max_speed': 0, 'owner': self.node, 'materials': [] }) self._combine = ba.newnode('combine', owner=self.holding_node, attrs={'size': 3}) self._offset = [0, 0, 0] self._combine.input0, self._combine.input1, self._combine.input2 = t self._combine.connectattr('output', self.holding_node, 'position') self.move_holding_node('xyz') self.fly_timer = ba.Timer(0.1, ba.WeakCall(self.move_holding_node, 'xyz'), repeat=True) return self.holding_node
def __init__(self, m, random_col): super().__init__() shared = SharedObjects.get() if random_col: col = (random.uniform(0, 1.2), random.uniform(0, 1.2), random.uniform(0, 1.2)) else: col = (0.9, 0.7, 0.0) self.mat = ba.Material() self.mat.add_actions(actions=( ('modify_part_collision', 'collide', False), ('modify_part_collision', 'physical', False), )) self.node = ba.newnode('prop', delegate=self, attrs={ 'model': ba.getmodel('bomb'), 'position': (2, 4, 2), 'body': 'capsule', 'shadow_size': 0.0, 'color_texture': ba.gettexture('coin'), 'reflection': 'soft', 'reflection_scale': [1.5], 'materials': [shared.object_material, self.mat] }) ba.animate(self.node, 'model_scale', { 0: 0, 1: 0.19, 5: 0.10, 10: 0.0 }, loop=True) ba.animate_array(self.node, 'position', 3, self.generateKeys(m), loop=True) self.light = ba.newnode('light', owner=self.node, attrs={ 'intensity': 0.6, 'height_attenuated': True, 'radius': 0.2, 'color': col }) ba.animate(self.light, 'radius', { 0: 0.0, 20: 0.4, 70: 0.1, 100: 0.3, 150: 0 }, loop=True) self.node.connectattr('position', self.light, 'position')
def set_score_text(self, text: str) -> None: """Show a message over the flag; handy for scores.""" if not self.node: return if not self._score_text: start_scale = 0.0 math = ba.newnode('math', owner=self.node, attrs={ 'input1': (0, 1.4, 0), 'operation': 'add' }) self.node.connectattr('position', math, 'input2') self._score_text = ba.newnode('text', owner=self.node, attrs={ 'text': text, 'in_world': True, 'scale': 0.02, 'shadow': 0.5, 'flatness': 1.0, 'h_align': 'center' }) math.connectattr('output', self._score_text, 'position') else: assert isinstance(self._score_text.scale, float) start_scale = self._score_text.scale self._score_text.text = text self._score_text.color = ba.safecolor(self.node.color) ba.animate(self._score_text, 'scale', {0: start_scale, 0.2: 0.02}) self._score_text_hide_timer = ba.Timer( 1.0, ba.WeakCall(self._hide_score_text))
def init(self, actor: stdbomb.Bomb, position, velocity, materials): factory = stdbomb.BombFactory.get() actor.node = ba.newnode('prop', delegate=actor, attrs={ 'position': position, 'velocity': velocity, 'body': 'sphere', 'materials': materials }) actor.first_shield = ba.newnode( 'shield', owner=actor.node, attrs={ 'color': (1, 1, 1), 'radius': 0.6}) actor.node.connectattr( 'position', actor.first_shield, 'position') actor.second_shield = ba.newnode( 'shield', owner=actor.node, attrs={ 'color': (20, 0, 0), 'radius': 0.4}) actor.node.connectattr( 'position', actor.second_shield, 'position') ba.animate(actor.second_shield, 'radius', {0: 0.1, 0.05: 0.4, 0.2: 0.1, 0.25: 0.5, 0.4: 0.3, 0.7: 0.1}, True)
def __init__(self, position=(0, 5, 0), direction=(0, 2, 0), source_player=None, owner=None, color=(1, 1, 1)) -> None: super().__init__() self._color = color self.node = ba.newnode('light', delegate=self, attrs={ 'position': position, 'color': self._color }) ba.animate(self.node, 'radius', {0: 0, 0.1: 0.5, 0.5: 0}) self.source_player = source_player self.owner = owner self._life_timer = ba.Timer( 0.5, ba.WeakCall(self.handlemessage, ba.DieMessage())) pos = position vel = tuple(i / 5 for i in ba.Vec3(direction).normalized()) for _ in range(500): # Optimization :( ba.newnode('explosion', owner=self.node, attrs={ 'position': pos, 'radius': 0.2, 'color': self._color }) pos = (pos[0] + vel[0], pos[1] + vel[1], pos[2] + vel[2]) for node in _ba.getnodes(): if node and node.getnodetype() == 'spaz': # pylint: disable=invalid-name m3 = ba.Vec3(position) a = ba.Vec3(direction[2], direction[1], direction[0]) m1 = ba.Vec3(node.position) # pylint: enable=invalid-name # distance between node and line dist = (a * (m1 - m3)).length() / a.length() if dist < 0.3: if node and node != self.owner and node.getdelegate( PlayerSpaz, True).getplayer( ba.Player, True).team != self.owner.team: node.handlemessage(ba.FreezeMessage()) pos = self.node.position hit_dir = (0, 10, 0) node.handlemessage( ba.HitMessage(pos=pos, magnitude=50, velocity_magnitude=50, radius=0, srcnode=self.node, source_player=self.source_player, force_direction=hit_dir))
def init(self, actor: stdbomb.Bomb, position: Sequence[Union[int, float]], velocity: Sequence[Union[int, float]], materials: Sequence[ba.Material]): factory = stdbomb.BombFactory.get() actor.node = ba.newnode('prop', delegate=actor, attrs={ 'body': 'landMine', 'model': factory.land_mine_model, 'light_model': factory.land_mine_model, 'color_texture': ba.gettexture('achievementCrossHair'), 'position': position, 'velocity': velocity, 'shadow_size': 0.44, 'reflection': 'powerup', 'reflection_scale': [1], 'materials': materials })
def equip_shields(self, decay: bool = False) -> None: """ Give this spaz a nice energy shield. """ if not self.node: ba.print_error('Can\'t equip shields; no node.') return factory = SpazFactory.get() if self.shield is None: self.shield = ba.newnode('shield', owner=self.node, attrs={ 'color': ((0 + random.random() * 6.5), (0 + random.random() * 6.5), (0 + random.random() * 6.5)), 'radius': 1.3 }) self.node.connectattr('position_center', self.shield, 'position') #ba.animate_array(self.shield, 'color', 3,{0:(1,0,0),0.2:(1,0.5,0),0.4:(1,1,0),0.6:(0,1,0),0.8:(0,1,1),1.0:(0,0,1),1.2:(1,0,0)},True) self.shield_hitpoints = self.shield_hitpoints_max = 650 self.shield_decay_rate = factory.shield_decay_rate if decay else 0 self.shield.hurt = 0 ba.playsound(factory.shield_up_sound, 1.0, position=self.node.position) if self.shield_decay_rate > 0: self.shield_decay_timer = ba.Timer(0.5, ba.WeakCall(self.shield_decay), repeat=True) # So user can see the decay. self.shield.always_show_health_bar = True
def upNextNodeFunc(self): if self.upNextNode: self.upNextNode.delete() playerPlayingRightNow1 = self.myPlayers[self.count - 2] playerPlayingRightNow2 = self.myPlayers[self.count - 1] upNextP1 = 'TBD' upNextP2 = 'TBD' n = len(self.myPlayers) if self.count >= n - 1: upNextP1 = self.myPlayers[0] upNextP2 = self.myPlayers[1] else: upNextP1 = self.myPlayers[self.count] upNextP2 = self.myPlayers[self.count + 1] if upNextP1 in [playerPlayingRightNow1, playerPlayingRightNow2]: upNextP1 = "TBD" if upNextP2 in [playerPlayingRightNow1, playerPlayingRightNow2]: upNextP2 = "TBD" upNextNodeText = "Up Next:\n" + upNextP1 + " vs " + upNextP2 + "\n" z = self.roundNameFunc(n - 1) if z < 4: upNextNodeText += self.roundNames[z] self.upNextNode = ba.newnode('text', attrs={ 'v_attach': 'top', 'h_attach': 'right', 'h_align': 'right', 'color': (1, 1, 1, 0.5), 'flatness': 0.5, 'shadow': 0.5, 'position': (-17, -60), 'scale': 0.7, 'maxwidth': 480, 'text': upNextNodeText })
def spawn_wrapper(): if self.node.exists(): self.phrase_text_node = ba.newnode('text', owner=self.node, attrs={ 'text': random.choice( self.phrases), 'scale': 0.0, 'in_world': True, 'h_align': 'center' }) math.connectattr('output', self.phrase_text_node, 'position') ba.animate(self.phrase_text_node, 'scale', { 0: 0.0, 0.5: 0.01, 5: 0.01, 5.5: 0.0 })
def _touch_return_update(self, team: Team) -> None: # Count down only while its away from base and not being held. assert team.flag is not None if team.home_flag_at_base or team.flag.held_count > 0: team.touch_return_timer_ticking = None return # No need to return when its at home. if team.touch_return_timer_ticking is None: team.touch_return_timer_ticking = ba.NodeActor( ba.newnode('sound', attrs={ 'sound': self._ticking_sound, 'positional': False, 'loop': True })) flag = team.flag if flag.touch_return_time is not None: flag.touch_return_time -= 0.1 if flag.counter: flag.counter.text = f'{flag.touch_return_time:.1f}' 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 _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 lightning_bolt(self, position=(0, 10, 0), radius=10): tint = self.activity.globalsnode.tint sounds = ('impactHard', 'impactHard2', 'impactHard3') ba.playsound(ba.getsound(random.choice(sounds)), volume=2) light = ba.newnode('light', attrs={ 'position': position, 'color': (0.2, 0.2, 0.4), 'volume_intensity_scale': 1.0, 'radius': radius }) intensity = { 0: 1, 0.05: radius, 0.15: radius / 2, 0.25: 0, 0.26: radius, 0.41: radius / 2, 0.51: 0 } ba.animate(light, 'intensity', intensity) ba.animate_array(self.activity.globalsnode, 'tint', 3, { 0: tint, 0.2: (0.2, 0.2, 0.2), 0.51: tint })
def __init__(self, item: ba.Node, owner: ba.Node): self.item = item self.owner = owner self.node: ba.Node self.target: Optional[ba.Node] = None self.aim_zone: ba.Material = ba.Material() shared = SharedObjects.get() self.aim_zone.add_actions( conditions=(('they_have_material', shared.player_material)), actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', self._touch_handler))) # raise the item a little self.item.extra_acceleration = (0, 20, 0) # if the item exists, then take its position, # else "turn the bench" if self.item.exists(): position = self.item.position else: return self.node = ba.newnode('region', attrs={ 'type': 'sphere', 'position': position, 'materials': [self.aim_zone]}) # aiming effect ba.animate_array(self.node, 'scale', 3, {0: (0.1, 0.1, 0.1), 1: (60, 60, 60)})
def __init__(self, position: Sequence[float] = (0, 3, 0), velocity: Sequence[float] = (0, -5, 0), amount: int = 15, bomb_type: str = 'impact', highlight: bool = True, source_player: ba.Player = None): ba.Actor.__init__(self) self.position = position self.velocity = velocity self.amount = amount self.bomb_type = bomb_type self._source_player = source_player self.drop_count = 0 # highlight the bombing zone if highlight: self.area_highlight = ba.newnode('light', attrs={ 'color': (1, 0, 0), 'position': position, 'volume_intensity_scale': 1.0 }) ba.animate(self.area_highlight, 'intensity', { 0: 0, 0.5: 1.0, 1: 0 }) def wrapper(): self.drop_timer = ba.Timer(0.25, self._drop_bomb, repeat=True) ba.timer(1, wrapper)
def on_begin(self) -> None: super().on_begin() shared = SharedObjects.get() self.setup_standard_time_limit(self._time_limit) self.setup_standard_powerup_drops() self._flag_spawn_pos = self.map.get_flag_position(None) Flag.project_stand(self._flag_spawn_pos) self._set_chosen_one_player(None) pos = self._flag_spawn_pos ba.timer(1.0, call=self._tick, repeat=True) mat = self._reset_region_material = ba.Material() mat.add_actions( conditions=( 'they_have_material', shared.player_material, ), actions=( ('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', ba.WeakCall(self._handle_reset_collide)), ), ) self._reset_region = ba.newnode('region', attrs={ 'position': (pos[0], pos[1] + 0.75, pos[2]), 'scale': (0.5, 0.5, 0.5), 'type': 'sphere', 'materials': [mat] })
def lightning_bolt(position, radius=1): ba.camerashake(4) vignette_outer = self.activity.globalsnode.vignette_outer # if ba.getactivity().tint is None: # ba.getactivity().std_tint = ba.sharedobj('globals').vignette_outer # vignette_outer = ba.sharedobj('globals').vignette_outer # else: # vignette_outer = ba.getactivity().tint light = ba.newnode('light', attrs={ 'position': position, 'color': (0.4, 0.4, 0.8), 'volume_intensity_scale': 1.0, 'radius': radius }) ba.animate(light, 'intensity', { 0: 1, 50: radius, 150: radius / 2, 250: 0, 260: radius, 410: radius / 2, 510: 0 }, timeformat=ba.TimeFormat.MILLISECONDS, suppress_format_warning=True) ba.animate_array(self.activity.globalsnode, 'vignette_outer', 3, { 0: vignette_outer, 0.2: (0.2, 0.2, 0.2), 0.51: vignette_outer })
def __init__(self, position: Sequence[float] = (0.0, 1.0, 0.0)): super().__init__() shared = SharedObjects.get() activity = self.getactivity() # Spawn just above the provided point. self._spawn_pos = (position[0], position[1] + 1.0, position[2]) self.last_players_to_touch: Dict[int, Player] = {} self.scored = False assert activity is not None assert isinstance(activity, HockeyGame) pmats = [shared.object_material, activity.puck_material] self.node = ba.newnode('prop', delegate=self, attrs={ 'model': activity.puck_model, 'color_texture': activity.puck_tex, 'body': 'puck', 'reflection': 'soft', 'reflection_scale': [0.2], 'shadow_size': 1.0, 'is_area_of_interest': True, 'position': self._spawn_pos, 'materials': pmats }) ba.animate(self.node, 'model_scale', {0: 0, 0.2: 1.3, 0.26: 1})
def _update(self, forcevalue: int = None) -> None: if forcevalue is not None: tval = forcevalue else: self._timeremaining = max(0, self._timeremaining - 1) tval = self._timeremaining # if there's a countdown sound for this time that we # haven't played yet, play it if tval == 10: assert self.node assert isinstance(self.node.scale, float) self.node.scale *= 1.2 cmb = ba.newnode('combine', owner=self.node, attrs={'size': 4}) cmb.connectattr('output', self.node, 'color') ba.animate(cmb, "input0", {0: 1.0, 0.15: 1.0}, loop=True) ba.animate(cmb, "input1", {0: 1.0, 0.15: 0.5}, loop=True) ba.animate(cmb, "input2", {0: 0.1, 0.15: 0.0}, loop=True) cmb.input3 = 1.0 if tval <= 10 and not self._ended: ba.playsound(ba.getsound('tick')) if tval in self._countdownsounds: ba.playsound(self._countdownsounds[tval]) if tval <= 0 and not self._ended: self._ended = True if self._endcall is not None: self._endcall()
def __init__(self, position: Tuple[float, float, float] = (0.0, 1.0, 0.0)): super().__init__() activity = self.activity assert isinstance(activity, EasterEggHuntGame) # Spawn just above the provided point. self._spawn_pos = (position[0], position[1] + 1.0, position[2]) ctex = (activity.egg_tex_1, activity.egg_tex_2, activity.egg_tex_3)[random.randrange(3)] mats = [ba.sharedobj('object_material'), activity.egg_material] self.node = ba.newnode("prop", delegate=self, attrs={ 'model': activity.egg_model, 'color_texture': ctex, 'body': 'capsule', 'reflection': 'soft', 'model_scale': 0.5, 'bodyScale': 0.6, 'density': 4.0, 'reflection_scale': [0.15], 'shadow_size': 0.6, 'position': self._spawn_pos, 'materials': mats })
def _handle_score(self) -> None: """A point has been scored.""" assert self._puck is not None assert self._score_regions is not None # Our puck might stick around for a second or two # we don't want it to be able to score again. if self._puck.scored: return region = ba.get_collision_info("source_node") index = 0 for index in range(len(self._score_regions)): if region == self._score_regions[index].node: break for team in self.teams: if team.get_id() == index: scoring_team = team team.gamedata['score'] += 1 # Tell all players to celebrate. for player in team.players: if player.actor: player.actor.handlemessage(ba.CelebrateMessage(2.0)) # If we've got the player from the scoring team that last # touched us, give them points. if (scoring_team.get_id() in self._puck.last_players_to_touch and self._puck.last_players_to_touch[ scoring_team.get_id()]): self.stats.player_scored(self._puck.last_players_to_touch[ scoring_team.get_id()], 100, big_message=True) # End game if we won. if team.gamedata['score'] >= self.settings['Score to Win']: self.end_game() ba.playsound(self._foghorn_sound) ba.playsound(self._cheer_sound) self._puck.scored = True # Kill the puck (it'll respawn itself shortly). ba.timer(1.0, self._kill_puck) light = ba.newnode('light', attrs={ 'position': ba.get_collision_info('position'), 'height_attenuated': False, 'color': (1, 0, 0) }) ba.animate(light, 'intensity', {0: 0, 0.5: 1, 1.0: 0}, loop=True) ba.timer(1.0, light.delete) ba.cameraflash(duration=10.0) self._update_scoreboard()
def _new_hp(): if not self.node: return hp = ba.newnode('math', owner=self.node, attrs={ 'input1': (0, 0.65, 0), 'operation': 'add' }) self.node.connectattr('torso_position', hp, 'input2') self.hp = ba.newnode('text', owner=self.node, attrs={ 'text': '', 'in_world': True, 'shadow': 1.0, 'flatness': 1.0, 'scale': 0.008, 'h_align': 'center', }) hp.connectattr('output', self.hp, 'position') #ba.animate(self.hp, 'scale', {0:0, 0.2:0, 0.6:0.018, 0.8:0.012}) activity = get_foreground_host_activity() if don.tint: activity.globalsnode.tint = (tintColor) def _update(): if not self.hp: return if self.shield: hptext = int( (self.shield_hitpoints / self.shield_hitpoints_max) * 100) else: hptext = int(self.hitpoints * 0.1) if hptext >= 75: color = (1, 1, 1) elif hptext >= 50: color = (1, 1, 1) elif hptext >= 25: color = (1, 1, 1) else: color = (1, 1, 1) self.hp.text = 'HP:' + str(hptext) self.hp.color = (0.2, 1.0, 0.8) if self.shield else color ba.timer(0.05, _update, repeat=True)
def on_begin(self) -> None: from bastd.actor.flag import Flag super().on_begin() self.setup_standard_time_limit(self.settings_raw['Time Limit']) self.setup_standard_powerup_drops() for team in self.teams: mat = self._base_region_materials[team.get_id()] = ba.Material() mat.add_actions(conditions=('they_have_material', ba.sharedobj('player_material')), actions=(('modify_part_collision', 'collide', True), ('modify_part_collision', 'physical', False), ('call', 'at_connect', ba.Call(self._handle_base_collide, team)))) # Create a score region and flag for each team. for team in self.teams: team.gamedata['base_pos'] = self.map.get_flag_position( team.get_id()) 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 }) self.project_flag_stand(team.gamedata['base_pos']) team.gamedata['flag'] = Flag(touchable=False, position=team.gamedata['base_pos'], color=team.color) basepos = team.gamedata['base_pos'] ba.newnode('region', owner=team.gamedata['flag'].node, attrs={ 'position': (basepos[0], basepos[1] + 0.75, basepos[2]), 'scale': (0.5, 0.5, 0.5), 'type': 'sphere', 'materials': [self._base_region_materials[team.get_id()]] })
def __init__(self, position: Sequence[float]): self._r1 = 0.45 self._r2 = 1.1 self._r3 = 2.0 self._rfudge = 0.15 super().__init__() self._position = ba.Vec3(position) self._hit = False # It can be handy to test with this on to make sure the projection # isn't too far off from the actual object. show_in_space = False loc1 = ba.newnode('locator', attrs={ 'shape': 'circle', 'position': position, 'color': (0, 1, 0), 'opacity': 0.5, 'draw_beauty': show_in_space, 'additive': True }) loc2 = ba.newnode('locator', attrs={ 'shape': 'circleOutline', 'position': position, 'color': (0, 1, 0), 'opacity': 0.3, 'draw_beauty': False, 'additive': True }) loc3 = ba.newnode('locator', attrs={ 'shape': 'circleOutline', 'position': position, 'color': (0, 1, 0), 'opacity': 0.1, 'draw_beauty': False, 'additive': True }) self._nodes = [loc1, loc2, loc3] ba.animate_array(loc1, 'size', 1, {0: [0.0], 0.2: [self._r1 * 2.0]}) ba.animate_array(loc2, 'size', 1, { 0.05: [0.0], 0.25: [self._r2 * 2.0] }) ba.animate_array(loc3, 'size', 1, {0.1: [0.0], 0.3: [self._r3 * 2.0]}) ba.playsound(ba.getsound('laserReverse'))
def _shift(self, position1: Tuple[float, float], position2: Tuple[float, float]) -> None: if not self.node: return cmb = ba.newnode('combine', owner=self.node, attrs={'size': 2}) ba.animate(cmb, 'input0', {0.0: position1[0], 0.25: position2[0]}) ba.animate(cmb, 'input1', {0.0: position1[1], 0.25: position2[1]}) cmb.connectattr('output', self.node, 'position')
def blast(x: int, y: int, z: int) -> None: # add sound ba.NodeActor(node=ba.newnode('scorch', attrs={ 'position': (x, z, y), 'size': 0.2, 'big': False, })).autoretain()
def spawn_player(self, player: ba.Player) -> ba.Actor: if player.team.gamedata['finished']: # FIXME: This is not type-safe # (this call is expected to return an Actor). # noinspection PyTypeChecker return None # type: ignore pos = self._regions[player.gamedata['last_region']].pos # Don't use the full region so we're less likely to spawn off a cliff. region_scale = 0.8 x_range = ((-0.5, 0.5) if pos[3] == 0 else (-region_scale * pos[3], region_scale * pos[3])) z_range = ((-0.5, 0.5) if pos[5] == 0 else (-region_scale * pos[5], region_scale * pos[5])) pos = (pos[0] + random.uniform(*x_range), pos[1], pos[2] + random.uniform(*z_range)) spaz = self.spawn_player_spaz( player, position=pos, angle=90 if not self._race_started else None) assert spaz.node # Prevent controlling of characters before the start of the race. if not self._race_started: spaz.disconnect_controls_from_player() mathnode = ba.newnode('math', owner=spaz.node, attrs={ 'input1': (0, 1.4, 0), 'operation': 'add' }) spaz.node.connectattr('torso_position', mathnode, 'input2') distance_txt = ba.newnode('text', owner=spaz.node, attrs={ 'text': '', 'in_world': True, 'color': (1, 1, 0.4), 'scale': 0.02, 'h_align': 'center' }) # FIXME store this in a type-safe way # noinspection PyTypeHints spaz.distance_txt = distance_txt # type: ignore mathnode.connectattr('output', distance_txt, 'position') return spaz