bascenev1lib.actor.popuptext

Defines Actor(s).

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Defines Actor(s)."""
  4
  5from __future__ import annotations
  6
  7import random
  8from typing import TYPE_CHECKING, override
  9
 10import bascenev1 as bs
 11
 12if TYPE_CHECKING:
 13    from typing import Any, Sequence
 14
 15
 16class PopupText(bs.Actor):
 17    """Text that pops up above a position to denote something special.
 18
 19    category: Gameplay Classes
 20    """
 21
 22    def __init__(
 23        self,
 24        text: str | bs.Lstr,
 25        *,
 26        position: Sequence[float] = (0.0, 0.0, 0.0),
 27        color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
 28        random_offset: float = 0.5,
 29        offset: Sequence[float] = (0.0, 0.0, 0.0),
 30        scale: float = 1.0,
 31    ):
 32        """Instantiate with given values.
 33
 34        random_offset is the amount of random offset from the provided position
 35        that will be applied. This can help multiple achievements from
 36        overlapping too much.
 37        """
 38        super().__init__()
 39        if len(color) == 3:
 40            color = (color[0], color[1], color[2], 1.0)
 41        pos = (
 42            position[0] + offset[0] + random_offset * (0.5 - random.random()),
 43            position[1] + offset[1] + random_offset * (0.5 - random.random()),
 44            position[2] + offset[2] + random_offset * (0.5 - random.random()),
 45        )
 46
 47        self.node = bs.newnode(
 48            'text',
 49            attrs={
 50                'text': text,
 51                'in_world': True,
 52                'shadow': 1.0,
 53                'flatness': 1.0,
 54                'h_align': 'center',
 55            },
 56            delegate=self,
 57        )
 58
 59        lifespan = 1.5
 60
 61        # scale up
 62        bs.animate(
 63            self.node,
 64            'scale',
 65            {
 66                0: 0.0,
 67                lifespan * 0.11: 0.020 * 0.7 * scale,
 68                lifespan * 0.16: 0.013 * 0.7 * scale,
 69                lifespan * 0.25: 0.014 * 0.7 * scale,
 70            },
 71        )
 72
 73        # translate upward
 74        self._tcombine = bs.newnode(
 75            'combine',
 76            owner=self.node,
 77            attrs={'input0': pos[0], 'input2': pos[2], 'size': 3},
 78        )
 79        bs.animate(
 80            self._tcombine, 'input1', {0: pos[1] + 1.5, lifespan: pos[1] + 2.0}
 81        )
 82        self._tcombine.connectattr('output', self.node, 'position')
 83
 84        # fade our opacity in/out
 85        self._combine = bs.newnode(
 86            'combine',
 87            owner=self.node,
 88            attrs={
 89                'input0': color[0],
 90                'input1': color[1],
 91                'input2': color[2],
 92                'size': 4,
 93            },
 94        )
 95        for i in range(4):
 96            bs.animate(
 97                self._combine,
 98                'input' + str(i),
 99                {
100                    0.13 * lifespan: color[i],
101                    0.18 * lifespan: 4.0 * color[i],
102                    0.22 * lifespan: color[i],
103                },
104            )
105        bs.animate(
106            self._combine,
107            'input3',
108            {
109                0: 0,
110                0.1 * lifespan: color[3],
111                0.7 * lifespan: color[3],
112                lifespan: 0,
113            },
114        )
115        self._combine.connectattr('output', self.node, 'color')
116
117        # kill ourself
118        self._die_timer = bs.Timer(
119            lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage())
120        )
121
122    @override
123    def handlemessage(self, msg: Any) -> Any:
124        assert not self.expired
125        if isinstance(msg, bs.DieMessage):
126            if self.node:
127                self.node.delete()
128        else:
129            super().handlemessage(msg)
class PopupText(bascenev1._actor.Actor):
 17class PopupText(bs.Actor):
 18    """Text that pops up above a position to denote something special.
 19
 20    category: Gameplay Classes
 21    """
 22
 23    def __init__(
 24        self,
 25        text: str | bs.Lstr,
 26        *,
 27        position: Sequence[float] = (0.0, 0.0, 0.0),
 28        color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
 29        random_offset: float = 0.5,
 30        offset: Sequence[float] = (0.0, 0.0, 0.0),
 31        scale: float = 1.0,
 32    ):
 33        """Instantiate with given values.
 34
 35        random_offset is the amount of random offset from the provided position
 36        that will be applied. This can help multiple achievements from
 37        overlapping too much.
 38        """
 39        super().__init__()
 40        if len(color) == 3:
 41            color = (color[0], color[1], color[2], 1.0)
 42        pos = (
 43            position[0] + offset[0] + random_offset * (0.5 - random.random()),
 44            position[1] + offset[1] + random_offset * (0.5 - random.random()),
 45            position[2] + offset[2] + random_offset * (0.5 - random.random()),
 46        )
 47
 48        self.node = bs.newnode(
 49            'text',
 50            attrs={
 51                'text': text,
 52                'in_world': True,
 53                'shadow': 1.0,
 54                'flatness': 1.0,
 55                'h_align': 'center',
 56            },
 57            delegate=self,
 58        )
 59
 60        lifespan = 1.5
 61
 62        # scale up
 63        bs.animate(
 64            self.node,
 65            'scale',
 66            {
 67                0: 0.0,
 68                lifespan * 0.11: 0.020 * 0.7 * scale,
 69                lifespan * 0.16: 0.013 * 0.7 * scale,
 70                lifespan * 0.25: 0.014 * 0.7 * scale,
 71            },
 72        )
 73
 74        # translate upward
 75        self._tcombine = bs.newnode(
 76            'combine',
 77            owner=self.node,
 78            attrs={'input0': pos[0], 'input2': pos[2], 'size': 3},
 79        )
 80        bs.animate(
 81            self._tcombine, 'input1', {0: pos[1] + 1.5, lifespan: pos[1] + 2.0}
 82        )
 83        self._tcombine.connectattr('output', self.node, 'position')
 84
 85        # fade our opacity in/out
 86        self._combine = bs.newnode(
 87            'combine',
 88            owner=self.node,
 89            attrs={
 90                'input0': color[0],
 91                'input1': color[1],
 92                'input2': color[2],
 93                'size': 4,
 94            },
 95        )
 96        for i in range(4):
 97            bs.animate(
 98                self._combine,
 99                'input' + str(i),
100                {
101                    0.13 * lifespan: color[i],
102                    0.18 * lifespan: 4.0 * color[i],
103                    0.22 * lifespan: color[i],
104                },
105            )
106        bs.animate(
107            self._combine,
108            'input3',
109            {
110                0: 0,
111                0.1 * lifespan: color[3],
112                0.7 * lifespan: color[3],
113                lifespan: 0,
114            },
115        )
116        self._combine.connectattr('output', self.node, 'color')
117
118        # kill ourself
119        self._die_timer = bs.Timer(
120            lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage())
121        )
122
123    @override
124    def handlemessage(self, msg: Any) -> Any:
125        assert not self.expired
126        if isinstance(msg, bs.DieMessage):
127            if self.node:
128                self.node.delete()
129        else:
130            super().handlemessage(msg)

Text that pops up above a position to denote something special.

category: Gameplay Classes

PopupText( text: str | babase.Lstr, *, position: Sequence[float] = (0.0, 0.0, 0.0), color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), random_offset: float = 0.5, offset: Sequence[float] = (0.0, 0.0, 0.0), scale: float = 1.0)
 23    def __init__(
 24        self,
 25        text: str | bs.Lstr,
 26        *,
 27        position: Sequence[float] = (0.0, 0.0, 0.0),
 28        color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
 29        random_offset: float = 0.5,
 30        offset: Sequence[float] = (0.0, 0.0, 0.0),
 31        scale: float = 1.0,
 32    ):
 33        """Instantiate with given values.
 34
 35        random_offset is the amount of random offset from the provided position
 36        that will be applied. This can help multiple achievements from
 37        overlapping too much.
 38        """
 39        super().__init__()
 40        if len(color) == 3:
 41            color = (color[0], color[1], color[2], 1.0)
 42        pos = (
 43            position[0] + offset[0] + random_offset * (0.5 - random.random()),
 44            position[1] + offset[1] + random_offset * (0.5 - random.random()),
 45            position[2] + offset[2] + random_offset * (0.5 - random.random()),
 46        )
 47
 48        self.node = bs.newnode(
 49            'text',
 50            attrs={
 51                'text': text,
 52                'in_world': True,
 53                'shadow': 1.0,
 54                'flatness': 1.0,
 55                'h_align': 'center',
 56            },
 57            delegate=self,
 58        )
 59
 60        lifespan = 1.5
 61
 62        # scale up
 63        bs.animate(
 64            self.node,
 65            'scale',
 66            {
 67                0: 0.0,
 68                lifespan * 0.11: 0.020 * 0.7 * scale,
 69                lifespan * 0.16: 0.013 * 0.7 * scale,
 70                lifespan * 0.25: 0.014 * 0.7 * scale,
 71            },
 72        )
 73
 74        # translate upward
 75        self._tcombine = bs.newnode(
 76            'combine',
 77            owner=self.node,
 78            attrs={'input0': pos[0], 'input2': pos[2], 'size': 3},
 79        )
 80        bs.animate(
 81            self._tcombine, 'input1', {0: pos[1] + 1.5, lifespan: pos[1] + 2.0}
 82        )
 83        self._tcombine.connectattr('output', self.node, 'position')
 84
 85        # fade our opacity in/out
 86        self._combine = bs.newnode(
 87            'combine',
 88            owner=self.node,
 89            attrs={
 90                'input0': color[0],
 91                'input1': color[1],
 92                'input2': color[2],
 93                'size': 4,
 94            },
 95        )
 96        for i in range(4):
 97            bs.animate(
 98                self._combine,
 99                'input' + str(i),
100                {
101                    0.13 * lifespan: color[i],
102                    0.18 * lifespan: 4.0 * color[i],
103                    0.22 * lifespan: color[i],
104                },
105            )
106        bs.animate(
107            self._combine,
108            'input3',
109            {
110                0: 0,
111                0.1 * lifespan: color[3],
112                0.7 * lifespan: color[3],
113                lifespan: 0,
114            },
115        )
116        self._combine.connectattr('output', self.node, 'color')
117
118        # kill ourself
119        self._die_timer = bs.Timer(
120            lifespan, bs.WeakCall(self.handlemessage, bs.DieMessage())
121        )

Instantiate with given values.

random_offset is the amount of random offset from the provided position that will be applied. This can help multiple achievements from overlapping too much.

node
@override
def handlemessage(self, msg: Any) -> Any:
123    @override
124    def handlemessage(self, msg: Any) -> Any:
125        assert not self.expired
126        if isinstance(msg, bs.DieMessage):
127            if self.node:
128                self.node.delete()
129        else:
130            super().handlemessage(msg)

General message handling; can be passed any message object.