bastd.gameutils

Various utilities useful for gameplay.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Various utilities useful for gameplay."""
  4
  5from __future__ import annotations
  6
  7from typing import TYPE_CHECKING
  8
  9import ba
 10
 11if TYPE_CHECKING:
 12    pass
 13
 14
 15class SharedObjects:
 16    """Various common components for use in games.
 17
 18    Category: Gameplay Classes
 19
 20    Objects contained here are created on-demand as accessed and shared
 21    by everything in the current activity. This includes things such as
 22    standard materials.
 23    """
 24
 25    _STORENAME = ba.storagename()
 26
 27    def __init__(self) -> None:
 28        activity = ba.getactivity()
 29        if self._STORENAME in activity.customdata:
 30            raise RuntimeError('Use SharedObjects.get() to fetch the'
 31                               ' shared instance for this activity.')
 32        self._object_material: ba.Material | None = None
 33        self._player_material: ba.Material | None = None
 34        self._pickup_material: ba.Material | None = None
 35        self._footing_material: ba.Material | None = None
 36        self._attack_material: ba.Material | None = None
 37        self._death_material: ba.Material | None = None
 38        self._region_material: ba.Material | None = None
 39        self._railing_material: ba.Material | None = None
 40
 41    @classmethod
 42    def get(cls) -> SharedObjects:
 43        """Fetch/create the instance of this class for the current activity."""
 44        activity = ba.getactivity()
 45        shobs = activity.customdata.get(cls._STORENAME)
 46        if shobs is None:
 47            shobs = SharedObjects()
 48            activity.customdata[cls._STORENAME] = shobs
 49        assert isinstance(shobs, SharedObjects)
 50        return shobs
 51
 52    @property
 53    def player_material(self) -> ba.Material:
 54        """a ba.Material to be applied to player parts. Generally,
 55        materials related to the process of scoring when reaching a goal, etc
 56        will look for the presence of this material on things that hit them.
 57        """
 58        if self._player_material is None:
 59            self._player_material = ba.Material()
 60        return self._player_material
 61
 62    @property
 63    def object_material(self) -> ba.Material:
 64        """A ba.Material that should be applied to any small,
 65        normal, physical objects such as bombs, boxes, players, etc. Other
 66        materials often check for the  presence of this material as a
 67        prerequisite for performing certain actions (such as disabling
 68        collisions between initially-overlapping objects)
 69        """
 70        if self._object_material is None:
 71            self._object_material = ba.Material()
 72        return self._object_material
 73
 74    @property
 75    def pickup_material(self) -> ba.Material:
 76        """A ba.Material; collision shapes used for picking things
 77        up will have this material applied. To prevent an object from being
 78        picked up, you can add a material that disables collisions against
 79        things containing this material.
 80        """
 81        if self._pickup_material is None:
 82            self._pickup_material = ba.Material()
 83        return self._pickup_material
 84
 85    @property
 86    def footing_material(self) -> ba.Material:
 87        """Anything that can be 'walked on' should have this
 88        ba.Material applied; generally just terrain and whatnot. A character
 89        will snap upright whenever touching something with this material so it
 90        should not be applied to props, etc.
 91        """
 92        if self._footing_material is None:
 93            self._footing_material = ba.Material()
 94        return self._footing_material
 95
 96    @property
 97    def attack_material(self) -> ba.Material:
 98        """A ba.Material applied to explosion shapes, punch
 99        shapes, etc.  An object not wanting to receive impulse/etc messages can
100        disable collisions against this material.
101        """
102        if self._attack_material is None:
103            self._attack_material = ba.Material()
104        return self._attack_material
105
106    @property
107    def death_material(self) -> ba.Material:
108        """A ba.Material that sends a ba.DieMessage() to anything
109        that touches it; handy for terrain below a cliff, etc.
110        """
111        if self._death_material is None:
112            mat = self._death_material = ba.Material()
113            mat.add_actions(
114                ('message', 'their_node', 'at_connect', ba.DieMessage()))
115        return self._death_material
116
117    @property
118    def region_material(self) -> ba.Material:
119        """A ba.Material used for non-physical collision shapes
120        (regions); collisions can generally be allowed with this material even
121        when initially overlapping since it is not physical.
122        """
123        if self._region_material is None:
124            self._region_material = ba.Material()
125        return self._region_material
126
127    @property
128    def railing_material(self) -> ba.Material:
129        """A ba.Material with a very low friction/stiffness/etc
130        that can be applied to invisible 'railings' useful for gently keeping
131        characters from falling off of cliffs.
132        """
133        if self._railing_material is None:
134            mat = self._railing_material = ba.Material()
135            mat.add_actions(('modify_part_collision', 'collide', False))
136            mat.add_actions(('modify_part_collision', 'stiffness', 0.003))
137            mat.add_actions(('modify_part_collision', 'damping', 0.00001))
138            mat.add_actions(
139                conditions=('they_have_material', self.player_material),
140                actions=(
141                    ('modify_part_collision', 'collide', True),
142                    ('modify_part_collision', 'friction', 0.0),
143                ),
144            )
145        return self._railing_material
class SharedObjects:
 16class SharedObjects:
 17    """Various common components for use in games.
 18
 19    Category: Gameplay Classes
 20
 21    Objects contained here are created on-demand as accessed and shared
 22    by everything in the current activity. This includes things such as
 23    standard materials.
 24    """
 25
 26    _STORENAME = ba.storagename()
 27
 28    def __init__(self) -> None:
 29        activity = ba.getactivity()
 30        if self._STORENAME in activity.customdata:
 31            raise RuntimeError('Use SharedObjects.get() to fetch the'
 32                               ' shared instance for this activity.')
 33        self._object_material: ba.Material | None = None
 34        self._player_material: ba.Material | None = None
 35        self._pickup_material: ba.Material | None = None
 36        self._footing_material: ba.Material | None = None
 37        self._attack_material: ba.Material | None = None
 38        self._death_material: ba.Material | None = None
 39        self._region_material: ba.Material | None = None
 40        self._railing_material: ba.Material | None = None
 41
 42    @classmethod
 43    def get(cls) -> SharedObjects:
 44        """Fetch/create the instance of this class for the current activity."""
 45        activity = ba.getactivity()
 46        shobs = activity.customdata.get(cls._STORENAME)
 47        if shobs is None:
 48            shobs = SharedObjects()
 49            activity.customdata[cls._STORENAME] = shobs
 50        assert isinstance(shobs, SharedObjects)
 51        return shobs
 52
 53    @property
 54    def player_material(self) -> ba.Material:
 55        """a ba.Material to be applied to player parts. Generally,
 56        materials related to the process of scoring when reaching a goal, etc
 57        will look for the presence of this material on things that hit them.
 58        """
 59        if self._player_material is None:
 60            self._player_material = ba.Material()
 61        return self._player_material
 62
 63    @property
 64    def object_material(self) -> ba.Material:
 65        """A ba.Material that should be applied to any small,
 66        normal, physical objects such as bombs, boxes, players, etc. Other
 67        materials often check for the  presence of this material as a
 68        prerequisite for performing certain actions (such as disabling
 69        collisions between initially-overlapping objects)
 70        """
 71        if self._object_material is None:
 72            self._object_material = ba.Material()
 73        return self._object_material
 74
 75    @property
 76    def pickup_material(self) -> ba.Material:
 77        """A ba.Material; collision shapes used for picking things
 78        up will have this material applied. To prevent an object from being
 79        picked up, you can add a material that disables collisions against
 80        things containing this material.
 81        """
 82        if self._pickup_material is None:
 83            self._pickup_material = ba.Material()
 84        return self._pickup_material
 85
 86    @property
 87    def footing_material(self) -> ba.Material:
 88        """Anything that can be 'walked on' should have this
 89        ba.Material applied; generally just terrain and whatnot. A character
 90        will snap upright whenever touching something with this material so it
 91        should not be applied to props, etc.
 92        """
 93        if self._footing_material is None:
 94            self._footing_material = ba.Material()
 95        return self._footing_material
 96
 97    @property
 98    def attack_material(self) -> ba.Material:
 99        """A ba.Material applied to explosion shapes, punch
100        shapes, etc.  An object not wanting to receive impulse/etc messages can
101        disable collisions against this material.
102        """
103        if self._attack_material is None:
104            self._attack_material = ba.Material()
105        return self._attack_material
106
107    @property
108    def death_material(self) -> ba.Material:
109        """A ba.Material that sends a ba.DieMessage() to anything
110        that touches it; handy for terrain below a cliff, etc.
111        """
112        if self._death_material is None:
113            mat = self._death_material = ba.Material()
114            mat.add_actions(
115                ('message', 'their_node', 'at_connect', ba.DieMessage()))
116        return self._death_material
117
118    @property
119    def region_material(self) -> ba.Material:
120        """A ba.Material used for non-physical collision shapes
121        (regions); collisions can generally be allowed with this material even
122        when initially overlapping since it is not physical.
123        """
124        if self._region_material is None:
125            self._region_material = ba.Material()
126        return self._region_material
127
128    @property
129    def railing_material(self) -> ba.Material:
130        """A ba.Material with a very low friction/stiffness/etc
131        that can be applied to invisible 'railings' useful for gently keeping
132        characters from falling off of cliffs.
133        """
134        if self._railing_material is None:
135            mat = self._railing_material = ba.Material()
136            mat.add_actions(('modify_part_collision', 'collide', False))
137            mat.add_actions(('modify_part_collision', 'stiffness', 0.003))
138            mat.add_actions(('modify_part_collision', 'damping', 0.00001))
139            mat.add_actions(
140                conditions=('they_have_material', self.player_material),
141                actions=(
142                    ('modify_part_collision', 'collide', True),
143                    ('modify_part_collision', 'friction', 0.0),
144                ),
145            )
146        return self._railing_material

Various common components for use in games.

Category: Gameplay Classes

Objects contained here are created on-demand as accessed and shared by everything in the current activity. This includes things such as standard materials.

SharedObjects()
28    def __init__(self) -> None:
29        activity = ba.getactivity()
30        if self._STORENAME in activity.customdata:
31            raise RuntimeError('Use SharedObjects.get() to fetch the'
32                               ' shared instance for this activity.')
33        self._object_material: ba.Material | None = None
34        self._player_material: ba.Material | None = None
35        self._pickup_material: ba.Material | None = None
36        self._footing_material: ba.Material | None = None
37        self._attack_material: ba.Material | None = None
38        self._death_material: ba.Material | None = None
39        self._region_material: ba.Material | None = None
40        self._railing_material: ba.Material | None = None
@classmethod
def get(cls) -> bastd.gameutils.SharedObjects:
42    @classmethod
43    def get(cls) -> SharedObjects:
44        """Fetch/create the instance of this class for the current activity."""
45        activity = ba.getactivity()
46        shobs = activity.customdata.get(cls._STORENAME)
47        if shobs is None:
48            shobs = SharedObjects()
49            activity.customdata[cls._STORENAME] = shobs
50        assert isinstance(shobs, SharedObjects)
51        return shobs

Fetch/create the instance of this class for the current activity.

player_material: _ba.Material

a ba.Material to be applied to player parts. Generally, materials related to the process of scoring when reaching a goal, etc will look for the presence of this material on things that hit them.

object_material: _ba.Material

A ba.Material that should be applied to any small, normal, physical objects such as bombs, boxes, players, etc. Other materials often check for the presence of this material as a prerequisite for performing certain actions (such as disabling collisions between initially-overlapping objects)

pickup_material: _ba.Material

A ba.Material; collision shapes used for picking things up will have this material applied. To prevent an object from being picked up, you can add a material that disables collisions against things containing this material.

footing_material: _ba.Material

Anything that can be 'walked on' should have this ba.Material applied; generally just terrain and whatnot. A character will snap upright whenever touching something with this material so it should not be applied to props, etc.

attack_material: _ba.Material

A ba.Material applied to explosion shapes, punch shapes, etc. An object not wanting to receive impulse/etc messages can disable collisions against this material.

death_material: _ba.Material

A ba.Material that sends a ba.DieMessage() to anything that touches it; handy for terrain below a cliff, etc.

region_material: _ba.Material

A ba.Material used for non-physical collision shapes (regions); collisions can generally be allowed with this material even when initially overlapping since it is not physical.

railing_material: _ba.Material

A ba.Material with a very low friction/stiffness/etc that can be applied to invisible 'railings' useful for gently keeping characters from falling off of cliffs.