示例#1
0
    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})
示例#2
0
        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
            })
示例#3
0
            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
                    })
示例#4
0
    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()
示例#5
0
 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))
示例#6
0
    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')
示例#7
0
    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)
示例#8
0
 def _hide_score_text(self) -> None:
     assert self._score_text is not None
     assert isinstance(self._score_text.scale, float)
     ba.animate(self._score_text, 'scale', {
         0: self._score_text.scale,
         0.2: 0
     })
示例#9
0
    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
        })
示例#10
0
    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)
示例#11
0
文件: railgun.py 项目: Dliwk/bs1new
    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))
示例#12
0
 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 _handle_flag_entered_base(self, team: Team) -> None:
        try:
            flag = ba.getcollision().opposingnode.getdelegate(
                StickyStormCTFFlag, True)
        except ba.NotFoundError:
            # Don't think this should logically ever happen.
            print(
                'Error getting StickyStormCTFFlag in entering-base callback.')
            return

        if flag.team is team:
            team.home_flag_at_base = True

            # If the enemy flag is already here, score!
            if team.enemy_flag_at_base:
                self._score(team)
        else:
            team.enemy_flag_at_base = True
            if team.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.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
                    })
示例#14
0
 def _flash_puck_spawn(self) -> None:
     light = ba.newnode('light',
                        attrs={
                            'position': self._puck_spawn_pos,
                            'height_attenuated': False,
                            'color': (1, 0, 0)
                        })
     ba.animate(light, 'intensity', {0.0: 0, 0.25: 1, 0.5: 0}, loop=True)
     ba.timer(1.0, light.delete)
示例#15
0
    def handlemessage(self, msg: Any) -> Any:
        """ handle high-level game messages """
        if isinstance(msg, playerspaz.PlayerSpazDeathMessage):
            from bastd.actor import respawnicon

            # Respawn dead players.
            player = msg.spaz.player
            self.stats.player_was_killed(player)
            assert self.initial_player_info is not None
            respawn_time = 2.0 + len(self.initial_player_info) * 1.0

            # Respawn them shortly.
            player.gamedata['respawn_timer'] = ba.Timer(
                respawn_time, ba.Call(self.spawn_player_if_exists, player))
            player.gamedata['respawn_icon'] = respawnicon.RespawnIcon(
                player, respawn_time)

            # Augment standard behavior.
            super().handlemessage(msg)

        elif isinstance(msg, spazbot.SpazBotDeathMessage):

            # Every time a bad guy dies, spawn a new one.
            ba.timer(3.0, ba.Call(self._spawn_bot, (type(msg.badguy))))

        elif isinstance(msg, spazbot.SpazBotPunchedMessage):
            if self._preset in ['rookie', 'rookie_easy']:
                if msg.damage >= 500:
                    self._award_achievement('Super Punch')
            elif self._preset in ['pro', 'pro_easy']:
                if msg.damage >= 1000:
                    self._award_achievement('Super Mega Punch')

        # Respawn dead flags.
        elif isinstance(msg, stdflag.FlagDeathMessage):
            assert isinstance(msg.flag, FootballFlag)
            msg.flag.respawn_timer = ba.Timer(3.0, self._spawn_flag)
            self._flag_respawn_light = ba.NodeActor(
                ba.newnode('light',
                           attrs={
                               'position': self._flag_spawn_pos,
                               'height_attenuated': False,
                               'radius': 0.15,
                               'color': (1.0, 1.0, 0.3)
                           }))
            assert self._flag_respawn_light.node
            ba.animate(self._flag_respawn_light.node,
                       'intensity', {
                           0: 0,
                           0.25: 0.15,
                           0.5: 0
                       },
                       loop=True)
            ba.timer(3.0, self._flag_respawn_light.node.delete)
        else:
            super().handlemessage(msg)
示例#16
0
    def _handle_reached_end(self) -> None:
        spaz = ba.getcollision().opposingnode.getdelegate(SpazBot, True)
        if not spaz.is_alive():
            return  # Ignore bodies flying in.

        self._flawless = False
        pos = spaz.node.position
        ba.playsound(self._bad_guy_score_sound, position=pos)
        light = ba.newnode('light',
                           attrs={
                               'position': pos,
                               'radius': 0.5,
                               'color': (1, 0, 0)
                           })
        ba.animate(light, 'intensity', {0.0: 0, 0.1: 1, 0.5: 0}, loop=False)
        ba.timer(1.0, light.delete)
        spaz.handlemessage(
            ba.DieMessage(immediate=True, how=ba.DeathType.REACHED_GOAL))

        if self._lives > 0:
            self._lives -= 1
            if self._lives == 0:
                self._bots.stop_moving()
                self.continue_or_end_game()
            assert self._lives_text is not None
            assert self._lives_text.node
            self._lives_text.node.text = str(self._lives)
            delay = 0.0

            def _safesetattr(node: ba.Node, attr: str, value: Any) -> None:
                if node:
                    setattr(node, attr, value)

            for _i in range(4):
                ba.timer(
                    delay,
                    ba.Call(_safesetattr, self._lives_text.node, 'color',
                            (1, 0, 0, 1.0)))
                assert self._lives_bg is not None
                assert self._lives_bg.node
                ba.timer(
                    delay,
                    ba.Call(_safesetattr, self._lives_bg.node, 'opacity', 0.5))
                delay += 0.125
                ba.timer(
                    delay,
                    ba.Call(_safesetattr, self._lives_text.node, 'color',
                            (1.0, 1.0, 0.0, 1.0)))
                ba.timer(
                    delay,
                    ba.Call(_safesetattr, self._lives_bg.node, 'opacity', 1.0))
                delay += 0.125
            ba.timer(
                delay,
                ba.Call(_safesetattr, self._lives_text.node, 'color',
                        (0.8, 0.8, 0.8, 1.0)))
 def _flash_flag_spawn(self) -> None:
     light = ba.newnode('light',
                        attrs={
                            'position': self._flag_spawn_pos,
                            'color': (1, 1, 1),
                            'radius': 0.3,
                            'height_attenuated': False
                        })
     ba.animate(light, 'intensity', {0: 0, 0.25: 0.5, 0.5: 0}, loop=True)
     ba.timer(1.0, light.delete)
示例#18
0
 def _flash_base(self, team: Team, length: float = 2.0) -> None:
     light = ba.newnode('light',
                        attrs={
                            'position': team.base_pos,
                            'height_attenuated': False,
                            'radius': 0.3,
                            'color': team.color
                        })
     ba.animate(light, 'intensity', {0: 0, 0.25: 2.0, 0.5: 0}, loop=True)
     ba.timer(length, light.delete)
示例#19
0
    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
                    })
示例#20
0
 def _flash_flag(self, flag: ConquestFlag, length: float = 1.0) -> None:
     assert flag.node
     assert flag.light
     light = ba.newnode('light',
                        attrs={
                            'position': flag.node.position,
                            'height_attenuated': False,
                            'color': flag.light.color
                        })
     ba.animate(light, 'intensity', {0: 0, 0.25: 1, 0.5: 0}, loop=True)
     ba.timer(length, light.delete)
示例#21
0
 def _flash_mine(self, i: int) -> None:
     assert self._race_mines is not None
     rmine = self._race_mines[i]
     light = ba.newnode('light',
                        attrs={
                            'position': rmine.point[:3],
                            'color': (1, 0.2, 0.2),
                            'radius': 0.1,
                            'height_attenuated': False
                        })
     ba.animate(light, 'intensity', {0.0: 0, 0.1: 1.0, 0.2: 0}, loop=True)
     ba.timer(1.0, light.delete)
示例#22
0
    def _fade_in(self) -> None:
        for node in self._nodes:
            ba.animate(node, 'opacity', {0: 0.0, 2.0: 1.0})

        # If we were given a lifespan, transition out after it.
        if self._lifespan is not None:
            ba.timer(self._lifespan,
                     ba.WeakCall(self.handlemessage, ba.DieMessage()))
        self._update()
        self._update_timer = ba.Timer(1.0,
                                      ba.WeakCall(self._update),
                                      repeat=True)
示例#23
0
 def handlemessage(self, msg: Any) -> Any:
     assert not self.expired
     if isinstance(msg, ba.DieMessage):
         if msg.immediate:
             self._die()
         else:
             # If they don't need immediate,
             # fade out our nodes and die later.
             for node in self._nodes:
                 ba.animate(node, 'opacity', {0: node.opacity, 3.0: 0.0})
             ba.timer(3.1, ba.WeakCall(self._die))
         return None
     return super().handlemessage(msg)
示例#24
0
 def _flash_player(self, player: ba.Player, scale: float) -> None:
     assert isinstance(player.actor, PlayerSpaz)
     assert player.actor.node
     pos = player.actor.node.position
     light = ba.newnode('light',
                        attrs={
                            'position': pos,
                            'color': (1, 1, 0),
                            'height_attenuated': False,
                            'radius': 0.4
                        })
     ba.timer(0.5, light.delete)
     ba.animate(light, 'intensity', {0: 0, 0.1: 1.0 * scale, 0.5: 0})
    def set_value(self,
                  score: float,
                  max_score: float = None,
                  countdown: bool = False,
                  flash: bool = True,
                  show_value: bool = True) -> None:
        """Set the value for the scoreboard entry."""

        # If we have no score yet, just set it.. otherwise compare
        # and see if we should flash.
        if self._score is None:
            self._score = score
        else:
            if score > self._score or (countdown and score < self._score):
                extra_flash = (max_score is not None and score >= max_score
                               and not countdown) or (countdown and score == 0)
                if flash:
                    self.flash(countdown, extra_flash)
            self._score = score

        if max_score is None:
            self._bar_width = 0.0
        else:
            if countdown:
                self._bar_width = max(
                    2.0 * self._scale,
                    self._width * (1.0 - (float(score) / max_score)))
            else:
                self._bar_width = max(
                    2.0 * self._scale,
                    self._width * (min(1.0,
                                       float(score) / max_score)))

        cur_width = self._bar_scale.input0
        ba.animate(self._bar_scale, 'input0', {
            0.0: cur_width,
            0.25: self._bar_width
        })
        self._bar_scale.input1 = self._bar_height
        cur_x = self._bar_position.input0
        assert self._pos is not None
        ba.animate(self._bar_position, 'input0', {
            0.0: cur_x,
            0.25: self._pos[0] + self._bar_width / 2
        })
        self._bar_position.input1 = self._pos[1] - self._bar_height / 2
        assert self._score_text.node
        if show_value:
            self._score_text.node.text = str(score)
        else:
            self._score_text.node.text = ''
示例#26
0
    def handlemessage(self, msg: Any) -> Any:
        """ handle high-level game messages """
        if isinstance(msg, ba.PlayerDiedMessage):
            # Augment standard behavior.
            super().handlemessage(msg)

            # Respawn them shortly.
            player = msg.getplayer(Player)
            assert self.initialplayerinfos is not None
            respawn_time = 2.0 + len(self.initialplayerinfos) * 1.0
            player.respawn_timer = ba.Timer(
                respawn_time, ba.Call(self.spawn_player_if_exists, player))
            player.respawn_icon = RespawnIcon(player, respawn_time)

        elif isinstance(msg, SpazBotDiedMessage):

            # Every time a bad guy dies, spawn a new one.
            ba.timer(3.0, ba.Call(self._spawn_bot, (type(msg.spazbot))))

        elif isinstance(msg, SpazBotPunchedMessage):
            if self._preset in ['rookie', 'rookie_easy']:
                if msg.damage >= 500:
                    self._award_achievement('Super Punch')
            elif self._preset in ['pro', 'pro_easy']:
                if msg.damage >= 1000:
                    self._award_achievement('Super Mega Punch')

        # Respawn dead flags.
        elif isinstance(msg, FlagDiedMessage):
            assert isinstance(msg.flag, FootballFlag)
            msg.flag.respawn_timer = ba.Timer(3.0, self._spawn_flag)
            self._flag_respawn_light = ba.NodeActor(
                ba.newnode('light',
                           attrs={
                               'position': self._flag_spawn_pos,
                               'height_attenuated': False,
                               'radius': 0.15,
                               'color': (1.0, 1.0, 0.3)
                           }))
            assert self._flag_respawn_light.node
            ba.animate(self._flag_respawn_light.node,
                       'intensity', {
                           0: 0,
                           0.25: 0.15,
                           0.5: 0
                       },
                       loop=True)
            ba.timer(3.0, self._flag_respawn_light.node.delete)
        else:
            return super().handlemessage(msg)
        return None
示例#27
0
    def _handle_score(self) -> None:
        """A point has been scored."""

        # Our flag might stick around for a second or two
        # make sure it doesn't score again.
        assert self._flag is not None
        if self._flag.scored:
            return
        region = ba.getcollision().sourcenode
        i = None
        for i in range(len(self._score_regions)):
            if region == self._score_regions[i].node:
                break
        for team in self.teams:
            if team.id == i:
                team.score += 7

                # Tell all players to celebrate.
                for player in team.players:
                    if player.actor:
                        player.actor.handlemessage(ba.CelebrateMessage(2.0))

                # If someone on this team was last to touch it,
                # give them points.
                assert self._flag is not None
                if (self._flag.last_holding_player
                        and team == self._flag.last_holding_player.team):
                    self.stats.player_scored(self._flag.last_holding_player,
                                             50,
                                             big_message=True)
                # End the game if we won.
                if team.score >= self._score_to_win:
                    self.end_game()
        ba.playsound(self._score_sound)
        ba.playsound(self._cheer_sound)
        assert self._flag
        self._flag.scored = True

        # Kill the flag (it'll respawn shortly).
        ba.timer(1.0, self._kill_flag)
        light = ba.newnode('light',
                           attrs={
                               'position': ba.getcollision().position,
                               'height_attenuated': False,
                               'color': (1, 0, 0)
                           })
        ba.animate(light, 'intensity', {0.0: 0, 0.5: 1, 1.0: 0}, loop=True)
        ba.timer(1.0, light.delete)
        ba.cameraflash(duration=10.0)
        self._update_scoreboard()
示例#28
0
def move_holding_node(self, move: str = '') -> None:
    if self._combine:
        t = []
        if 'x' in move: t.append(0)
        if 'y' in move: t.append(1)
        if 'z' in move: t.append(2)

        for i in t:
            val = getattr(self._combine, 'input{}'.format(i), None)
            if val is not None:
                ba.animate(self._combine, 'input{}'.format(i), {
                    0: val,
                    0.5: val + self._offset[i]
                })
示例#29
0
    def _show_winner(self, team: ba.SessionTeam) -> None:
        from bastd.actor.image import Image
        from bastd.actor.zoomtext import ZoomText
        if not self._is_ffa:
            offs_v = 0.0
            ZoomText(team.name,
                     position=(0, 97),
                     color=team.color,
                     scale=1.15,
                     jitter=1.0,
                     maxwidth=250).autoretain()
        else:
            offs_v = -80.0
            if len(team.players) == 1:
                i = Image(team.players[0].get_icon(),
                          position=(0, 143),
                          scale=(100, 100)).autoretain()
                assert i.node
                ba.animate(i.node, 'opacity', {0.0: 0.0, 0.25: 1.0})
                ZoomText(ba.Lstr(
                    value=team.players[0].getname(full=True, icon=False)),
                         position=(0, 97 + offs_v),
                         color=team.color,
                         scale=1.15,
                         jitter=1.0,
                         maxwidth=250).autoretain()

        s_extra = 1.0 if self._is_ffa else 1.0

        # Some languages say "FOO WINS" differently for teams vs players.
        if isinstance(self.session, ba.FreeForAllSession):
            wins_resource = 'seriesWinLine1PlayerText'
        else:
            wins_resource = 'seriesWinLine1TeamText'
        wins_text = ba.Lstr(resource=wins_resource)

        # Temp - if these come up as the english default, fall-back to the
        # unified old form which is more likely to be translated.
        ZoomText(wins_text,
                 position=(0, -10 + offs_v),
                 color=team.color,
                 scale=0.65 * s_extra,
                 jitter=1.0,
                 maxwidth=250).autoretain()
        ZoomText(ba.Lstr(resource='seriesWinLine2Text'),
                 position=(0, -110 + offs_v),
                 scale=1.0 * s_extra,
                 color=team.color,
                 jitter=1.0,
                 maxwidth=250).autoretain()
示例#30
0
    def __init__(
            self,
            data: Any = None,
            pt: Sequence[float] = (0, 0, 0),  # pylint: disable=invalid-name
            spawn_time: float = 1.0,
            send_spawn_message: bool = True,
            spawn_callback: Callable[[], Any] = None):
        """Instantiate a Spawner.

        Requires some custom data, a position,
        and a spawn-time in seconds.
        """
        self._spawn_callback = spawn_callback
        self._send_spawn_message = send_spawn_message
        self._spawner_sound = ba.getsound('swip2')
        self._data = data
        self._pt = pt
        # create a light where the spawn will happen
        self._light = ba.newnode('light',
                                 attrs={
                                     'position': tuple(pt),
                                     'radius': 0.1,
                                     'color': (1.0, 0.1, 0.1),
                                     'lights_volumes': False
                                 })
        scl = float(spawn_time) / 3.75
        min_val = 0.4
        max_val = 0.7
        ba.playsound(self._spawner_sound, position=self._light.position)
        ba.animate(
            self._light, 'intensity', {
                0.0: 0.0,
                0.25 * scl: max_val,
                0.500 * scl: min_val,
                0.750 * scl: max_val,
                1.000 * scl: min_val,
                1.250 * scl: 1.1 * max_val,
                1.500 * scl: min_val,
                1.750 * scl: 1.2 * max_val,
                2.000 * scl: min_val,
                2.250 * scl: 1.3 * max_val,
                2.500 * scl: min_val,
                2.750 * scl: 1.4 * max_val,
                3.000 * scl: min_val,
                3.250 * scl: 1.5 * max_val,
                3.500 * scl: min_val,
                3.750 * scl: 2.0,
                4.000 * scl: 0.0
            })
        ba.timer(spawn_time, self._spawn)