Пример #1
0
        def _apply(name2: Lstr, score2: int, showpoints2: bool,
                   color2: Tuple[float, float, float, float], scale2: float,
                   sound2: Optional[ba.Sound]) -> None:
            from bastd.actor.popuptext import PopupText

            # Only award this if they're still alive and we can get
            # their pos.
            if self._player is not None and self._player.node:
                our_pos = self._player.node.position
            else:
                return

            # Jitter position a bit since these often come in clusters.
            our_pos = (our_pos[0] + (random.random() - 0.5) * 2.0,
                       our_pos[1] + (random.random() - 0.5) * 2.0,
                       our_pos[2] + (random.random() - 0.5) * 2.0)
            activity = self.getactivity()
            if activity is not None:
                PopupText(Lstr(
                    value=(('+' + str(score2) + ' ') if showpoints2 else '') +
                    '${N}',
                    subs=[('${N}', name2)]),
                          color=color2,
                          scale=scale2,
                          position=our_pos).autoretain()
            if sound2:
                _ba.playsound(sound2)

            self.score += score2
            self.accumscore += score2

            # Inform a running game of the score.
            if score2 != 0 and activity is not None:
                activity.handlemessage(PlayerScoredMessage(score=score2))
Пример #2
0
    def _award_time_bonus(self, bonus: int) -> None:
        ba.playsound(self._cashregistersound)
        PopupText(ba.Lstr(value='+${A} ${B}',
                          subs=[('${A}', str(bonus)),
                                ('${B}', ba.Lstr(resource='timeBonusText'))]),
                  color=(1, 1, 0.5, 1),
                  scale=1.0,
                  position=(0, 3, -1)).autoretain()

        self._score += self._time_bonus
        self._update_scores()
Пример #3
0
 def _award_lives_bonus(self) -> None:
     bonus = self._lives * 30
     ba.playsound(self._cashregistersound)
     PopupText(ba.Lstr(value='+${A} ${B}',
                       subs=[('${A}', str(bonus)),
                             ('${B}', ba.Lstr(resource='livesBonusText'))]),
               color=(0.7, 1.0, 0.3, 1),
               scale=1.3,
               position=(0, 1, -1)).autoretain()
     self._score += bonus
     self._update_scores()
Пример #4
0
    def _award_flawless_bonus(self) -> None:
        ba.playsound(self._cashregistersound)
        PopupText(ba.Lstr(value='+${A} ${B}',
                          subs=[('${A}', str(self._flawless_bonus)),
                                ('${B}', ba.Lstr(resource='perfectWaveText'))
                                ]),
                  color=(1, 1, 0.2, 1),
                  scale=1.2,
                  position=(0, 2, -1)).autoretain()

        assert self._flawless_bonus is not None
        self._score += self._flawless_bonus
        self._update_scores()
Пример #5
0
def handle_hit(msg, hp, dmg, hit_by, msg_pos):
    #Check
    if not msg.hit_type: return

    #Record Out Data
    dmg = dmg / 10
    if hit_by is not None:
        hit_by_id = None
        hit_by_id = hit_by.node.playerID
        if hit_by_id is not None:
            hit_by_account_id = None
            for c in _ba.get_foreground_host_session().sessionplayers:
                if (c.activityplayer) and (c.activityplayer.node.playerID
                                           == hit_by_id):
                    hit_by_account_id = c.get_account_id()
                    if hit_by_account_id in damage_data:
                        damage_data[hit_by_account_id] += float(dmg)
                    else:
                        damage_data[hit_by_account_id] = float(dmg)
    #Send Screen Texts in enabled
    if our_settings['enableHitTexts']:
        try:
            if hp <= 0:
                PopupText("Rest In Peace !",
                          color=(1, 0.2, 0.2),
                          scale=1.6,
                          position=msg_pos).autoretain()
            else:
                if dmg >= 800:
                    PopupText("#PRO !",
                              color=(1, 0.2, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 600 and dmg < 800:
                    PopupText("GOOD ONE!",
                              color=(1, 0.3, 0.1),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 400 and dmg < 600:
                    PopupText("OH! YEAH",
                              color=(1, 0.5, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg >= 200 and dmg < 400:
                    PopupText("WTF!",
                              color=(0.7, 0.4, 0.2),
                              scale=1.6,
                              position=msg_pos).autoretain()
                elif dmg > 0 and dmg < 200:
                    PopupText("!!!",
                              color=(1, 1, 1),
                              scale=1.6,
                              position=msg_pos).autoretain()
        except:
            pass
    return
Пример #6
0
    def handlemessage(self, msg: Any, returned: Any = None) -> Any:
        super(stdspaz.Spaz, self).handlemessage(msg)
        if isinstance(msg, ba.PowerupMessage):
            if not self.is_alive():
                return
            for poweruptype, texture, callback in _callbacks:
                if msg.poweruptype == poweruptype:
                    if ba.app.config.get('Powerup Popups', True):
                        powerup_text = get_locale(
                            'powerup_names')[poweruptype]

                        PopupText(
                            ba.Lstr(translate=('gameDescriptions',
                                               powerup_text)),
                            color=(1, 1, 1),
                            scale=1,
                            position=self.node.position).autoretain()
                    callback(self, msg)
Пример #7
0
    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
Пример #8
0
    def do_hit_at_position(self, pos: Sequence[float], player: Player) -> bool:
        """Handle a bomb hit at the given position."""
        # pylint: disable=too-many-statements
        activity = self.activity

        # Ignore hits if the game is over or if we've already been hit
        if activity.has_ended() or self._hit or not self._nodes:
            return False

        diff = (ba.Vec3(pos) - self._position)

        # Disregard Y difference. Our target point probably isn't exactly
        # on the ground anyway.
        diff[1] = 0.0
        dist = diff.length()

        bullseye = False
        if dist <= self._r3 + self._rfudge:
            # Inform our activity that we were hit
            self._hit = True
            activity.handlemessage(self.TargetHitMessage())
            keys: Dict[float, Sequence[float]] = {
                0.0: (1.0, 0.0, 0.0),
                0.049: (1.0, 0.0, 0.0),
                0.05: (1.0, 1.0, 1.0),
                0.1: (0.0, 1.0, 0.0)
            }
            cdull = (0.3, 0.3, 0.3)
            popupcolor: Sequence[float]
            if dist <= self._r1 + self._rfudge:
                bullseye = True
                self._nodes[1].color = cdull
                self._nodes[2].color = cdull
                ba.animate_array(self._nodes[0], 'color', 3, keys, loop=True)
                popupscale = 1.8
                popupcolor = (1, 1, 0, 1)
                streak = player.streak
                points = 10 + min(20, streak * 2)
                ba.playsound(ba.getsound('bellHigh'))
                if streak > 0:
                    ba.playsound(
                        ba.getsound(
                            'orchestraHit4' if streak > 3 else
                            'orchestraHit3' if streak > 2 else
                            'orchestraHit2' if streak > 1 else 'orchestraHit'))
            elif dist <= self._r2 + self._rfudge:
                self._nodes[0].color = cdull
                self._nodes[2].color = cdull
                ba.animate_array(self._nodes[1], 'color', 3, keys, loop=True)
                popupscale = 1.25
                popupcolor = (1, 0.5, 0.2, 1)
                points = 4
                ba.playsound(ba.getsound('bellMed'))
            else:
                self._nodes[0].color = cdull
                self._nodes[1].color = cdull
                ba.animate_array(self._nodes[2], 'color', 3, keys, loop=True)
                popupscale = 1.0
                popupcolor = (0.8, 0.3, 0.3, 1)
                points = 2
                ba.playsound(ba.getsound('bellLow'))

            # Award points/etc.. (technically should probably leave this up
            # to the activity).
            popupstr = '+' + str(points)

            # If there's more than 1 player in the game, include their
            # names and colors so they know who got the hit.
            if len(activity.players) > 1:
                popupcolor = ba.safecolor(player.color, target_intensity=0.75)
                popupstr += ' ' + player.getname()
            PopupText(popupstr,
                      position=self._position,
                      color=popupcolor,
                      scale=popupscale).autoretain()

            # Give this player's team points and update the score-board.
            player.team.score += points
            assert isinstance(activity, TargetPracticeGame)
            activity.update_scoreboard()

            # Also give this individual player points
            # (only applies in teams mode).
            assert activity.stats is not None
            activity.stats.player_scored(player,
                                         points,
                                         showpoints=False,
                                         screenmessage=False)

            ba.animate_array(self._nodes[0], 'size', 1, {
                0.8: self._nodes[0].size,
                1.0: [0.0]
            })
            ba.animate_array(self._nodes[1], 'size', 1, {
                0.85: self._nodes[1].size,
                1.05: [0.0]
            })
            ba.animate_array(self._nodes[2], 'size', 1, {
                0.9: self._nodes[2].size,
                1.1: [0.0]
            })
            ba.timer(1.1, ba.Call(self.handlemessage, ba.DieMessage()))

        return bullseye
Пример #9
0
    def handlemessage(self, msg, returned):
        from bastd.actor.popuptext import PopupText
        if isinstance(msg, ba.HitMessage):
            if msg.hit_type == 'punch':
                if not self.node:
                    return None
                if self.node.invincible:
                    return True
                mag = msg.magnitude * self.impact_scale
                velocity_mag = msg.velocity_magnitude * self.impact_scale
                damage_scale = 0.22

                # If they've got a shield, deliver it to that instead.
                if self.shield:
                    if msg.flat_damage:
                        damage = msg.flat_damage * self.impact_scale
                    else:
                        damage = damage_scale * self.node.damage

                    # Its a cleaner event if a hit just kills the shield
                    # without damaging the player.
                    # However, massive damage events should still be able to
                    # damage the player. This hopefully gives us a happy medium.
                    max_spillover = stdspaz.get_factory(
                    ).max_shield_spillover_damage

                    # If they passed our spillover threshold,
                    # pass damage along to spaz.
                    if self.shield_hitpoints <= -max_spillover:
                        leftover_damage = -max_spillover - self.shield_hitpoints
                        shield_leftover_ratio = leftover_damage / damage

                        # Scale down the magnitudes applied to spaz accordingly.
                        mag *= shield_leftover_ratio
                        velocity_mag *= shield_leftover_ratio
                    else:
                        return True  # Good job shield!
                else:
                    shield_leftover_ratio = 1.0

                if msg.flat_damage:
                    damage = int(msg.flat_damage * self.impact_scale *
                                 shield_leftover_ratio)
                else:
                    damage = int(damage_scale * self.node.damage)

                if damage > 999:
                    PopupText(get_locale('fatality_text'),
                              color=(0.905, 0.298, 0.235),
                              scale=2.0,
                              position=self.node.position).autoretain()

                    ba.emitfx(position=msg.pos,
                              chunk_type='spark',
                              velocity=(msg.force_direction[0] * 1.3,
                                        msg.force_direction[1] * 1.3 + 5.0,
                                        msg.force_direction[2] * 1.3),
                              count=45,
                              scale=1.0,
                              spread=1.0)

                    self.lightning_bolt(position=self.node.position, radius=3)

                    gnode = self.activity.globalsnode

                    if not gnode.slow_motion:
                        gnode.slow_motion = True

                        def off_sm():
                            if gnode:
                                gnode.slow_motion = False

                        ba.timer(0.5, off_sm)

                elif 800 < damage < 999:
                    PopupText(get_locale('crazy_text'),
                              color=(0.180, 0.800, 0.443),
                              scale=1.5,
                              position=self.node.position).autoretain()

                    ba.emitfx(position=msg.pos,
                              chunk_type='spark',
                              velocity=(msg.force_direction[0] * 1.3,
                                        msg.force_direction[1] * 1.3 + 5.0,
                                        msg.force_direction[2] * 1.3),
                              count=45,
                              scale=1.0,
                              spread=1.0)
                elif 750 < damage < 800:
                    PopupText(get_locale('aggressive_text'),
                              color=(0.231, 0.596, 0.858),
                              scale=1.5,
                              position=self.node.position).autoretain()
        return returned