bastd.actor.spazfactory
Provides a factory object from creating Spazzes.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a factory object from creating Spazzes.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import ba 10from bastd.gameutils import SharedObjects 11import _ba 12 13if TYPE_CHECKING: 14 from typing import Any, Sequence 15 16 17class SpazFactory: 18 """Wraps up media and other resources used by ba.Spaz instances. 19 20 Category: **Gameplay Classes** 21 22 Generally one of these is created per ba.Activity and shared 23 between all spaz instances. Use ba.Spaz.get_factory() to return 24 the shared factory for the current activity. 25 """ 26 27 impact_sounds_medium: Sequence[ba.Sound] 28 """A tuple of ba.Sound-s for when a ba.Spaz hits something kinda hard.""" 29 30 impact_sounds_hard: Sequence[ba.Sound] 31 """A tuple of ba.Sound-s for when a ba.Spaz hits something really hard.""" 32 33 impact_sounds_harder: Sequence[ba.Sound] 34 """A tuple of ba.Sound-s for when a ba.Spaz hits something really 35 really hard.""" 36 37 single_player_death_sound: ba.Sound 38 """The sound that plays for an 'important' spaz death such as in 39 co-op games.""" 40 41 punch_sound: ba.Sound 42 """A standard punch ba.Sound.""" 43 44 punch_sound_strong: Sequence[ba.Sound] 45 """A tuple of stronger sounding punch ba.Sounds.""" 46 47 punch_sound_stronger: ba.Sound 48 """A really really strong sounding punch ba.Sound.""" 49 50 swish_sound: ba.Sound 51 """A punch swish ba.Sound.""" 52 53 block_sound: ba.Sound 54 """A ba.Sound for when an attack is blocked by invincibility.""" 55 56 shatter_sound: ba.Sound 57 """A ba.Sound for when a frozen ba.Spaz shatters.""" 58 59 splatter_sound: ba.Sound 60 """A ba.Sound for when a ba.Spaz blows up via curse.""" 61 62 spaz_material: ba.Material 63 """A ba.Material applied to all of parts of a ba.Spaz.""" 64 65 roller_material: ba.Material 66 """A ba.Material applied to the invisible roller ball body that 67 a ba.Spaz uses for locomotion.""" 68 69 punch_material: ba.Material 70 """A ba.Material applied to the 'fist' of a ba.Spaz.""" 71 72 pickup_material: ba.Material 73 """A ba.Material applied to the 'grabber' body of a ba.Spaz.""" 74 75 curse_material: ba.Material 76 """A ba.Material applied to a cursed ba.Spaz that triggers an explosion.""" 77 78 _STORENAME = ba.storagename() 79 80 def _preload(self, character: str) -> None: 81 """Preload media needed for a given character.""" 82 self.get_media(character) 83 84 def __init__(self) -> None: 85 """Instantiate a factory object.""" 86 # pylint: disable=cyclic-import 87 # FIXME: should probably put these somewhere common so we don't 88 # have to import them from a module that imports us. 89 from bastd.actor.spaz import (PickupMessage, PunchHitMessage, 90 CurseExplodeMessage) 91 92 shared = SharedObjects.get() 93 self.impact_sounds_medium = (ba.getsound('impactMedium'), 94 ba.getsound('impactMedium2')) 95 self.impact_sounds_hard = (ba.getsound('impactHard'), 96 ba.getsound('impactHard2'), 97 ba.getsound('impactHard3')) 98 self.impact_sounds_harder = (ba.getsound('bigImpact'), 99 ba.getsound('bigImpact2')) 100 self.single_player_death_sound = ba.getsound('playerDeath') 101 self.punch_sound = ba.getsound('punch01') 102 self.punch_sound_strong = (ba.getsound('punchStrong01'), 103 ba.getsound('punchStrong02')) 104 self.punch_sound_stronger = ba.getsound('superPunch') 105 self.swish_sound = ba.getsound('punchSwish') 106 self.block_sound = ba.getsound('block') 107 self.shatter_sound = ba.getsound('shatter') 108 self.splatter_sound = ba.getsound('splatter') 109 self.spaz_material = ba.Material() 110 self.roller_material = ba.Material() 111 self.punch_material = ba.Material() 112 self.pickup_material = ba.Material() 113 self.curse_material = ba.Material() 114 115 footing_material = shared.footing_material 116 object_material = shared.object_material 117 player_material = shared.player_material 118 region_material = shared.region_material 119 120 # Send footing messages to spazzes so they know when they're on 121 # solid ground. 122 # Eww; this probably should just be built into the spaz node. 123 self.roller_material.add_actions( 124 conditions=('they_have_material', footing_material), 125 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 126 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 127 128 self.spaz_material.add_actions( 129 conditions=('they_have_material', footing_material), 130 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 131 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 132 133 # Punches. 134 self.punch_material.add_actions( 135 conditions=('they_are_different_node_than_us', ), 136 actions=( 137 ('modify_part_collision', 'collide', True), 138 ('modify_part_collision', 'physical', False), 139 ('message', 'our_node', 'at_connect', PunchHitMessage()), 140 )) 141 142 # Pickups. 143 self.pickup_material.add_actions( 144 conditions=(('they_are_different_node_than_us', ), 'and', 145 ('they_have_material', object_material)), 146 actions=( 147 ('modify_part_collision', 'collide', True), 148 ('modify_part_collision', 'physical', False), 149 ('message', 'our_node', 'at_connect', PickupMessage()), 150 )) 151 152 # Curse. 153 self.curse_material.add_actions( 154 conditions=( 155 ('they_are_different_node_than_us', ), 156 'and', 157 ('they_have_material', player_material), 158 ), 159 actions=('message', 'our_node', 'at_connect', 160 CurseExplodeMessage()), 161 ) 162 163 self.foot_impact_sounds = (ba.getsound('footImpact01'), 164 ba.getsound('footImpact02'), 165 ba.getsound('footImpact03')) 166 167 self.foot_skid_sound = ba.getsound('skid01') 168 self.foot_roll_sound = ba.getsound('scamper01') 169 170 self.roller_material.add_actions( 171 conditions=('they_have_material', footing_material), 172 actions=( 173 ('impact_sound', self.foot_impact_sounds, 1, 0.2), 174 ('skid_sound', self.foot_skid_sound, 20, 0.3), 175 ('roll_sound', self.foot_roll_sound, 20, 3.0), 176 )) 177 178 self.skid_sound = ba.getsound('gravelSkid') 179 180 self.spaz_material.add_actions( 181 conditions=('they_have_material', footing_material), 182 actions=( 183 ('impact_sound', self.foot_impact_sounds, 20, 6), 184 ('skid_sound', self.skid_sound, 2.0, 1), 185 ('roll_sound', self.skid_sound, 2.0, 1), 186 )) 187 188 self.shield_up_sound = ba.getsound('shieldUp') 189 self.shield_down_sound = ba.getsound('shieldDown') 190 self.shield_hit_sound = ba.getsound('shieldHit') 191 192 # We don't want to collide with stuff we're initially overlapping 193 # (unless its marked with a special region material). 194 self.spaz_material.add_actions( 195 conditions=( 196 ( 197 ('we_are_younger_than', 51), 198 'and', 199 ('they_are_different_node_than_us', ), 200 ), 201 'and', 202 ('they_dont_have_material', region_material), 203 ), 204 actions=('modify_node_collision', 'collide', False), 205 ) 206 207 self.spaz_media: dict[str, Any] = {} 208 209 # Lets load some basic rules. 210 # (allows them to be tweaked from the master server) 211 self.shield_decay_rate = _ba.get_v1_account_misc_read_val('rsdr', 10.0) 212 self.punch_cooldown = _ba.get_v1_account_misc_read_val('rpc', 400) 213 self.punch_cooldown_gloves = (_ba.get_v1_account_misc_read_val( 214 'rpcg', 300)) 215 self.punch_power_scale = _ba.get_v1_account_misc_read_val('rpp', 1.2) 216 self.punch_power_scale_gloves = (_ba.get_v1_account_misc_read_val( 217 'rppg', 1.4)) 218 self.max_shield_spillover_damage = (_ba.get_v1_account_misc_read_val( 219 'rsms', 500)) 220 221 def get_style(self, character: str) -> str: 222 """Return the named style for this character. 223 224 (this influences subtle aspects of their appearance, etc) 225 """ 226 return ba.app.spaz_appearances[character].style 227 228 def get_media(self, character: str) -> dict[str, Any]: 229 """Return the set of media used by this variant of spaz.""" 230 char = ba.app.spaz_appearances[character] 231 if character not in self.spaz_media: 232 media = self.spaz_media[character] = { 233 'jump_sounds': [ba.getsound(s) for s in char.jump_sounds], 234 'attack_sounds': [ba.getsound(s) for s in char.attack_sounds], 235 'impact_sounds': [ba.getsound(s) for s in char.impact_sounds], 236 'death_sounds': [ba.getsound(s) for s in char.death_sounds], 237 'pickup_sounds': [ba.getsound(s) for s in char.pickup_sounds], 238 'fall_sounds': [ba.getsound(s) for s in char.fall_sounds], 239 'color_texture': ba.gettexture(char.color_texture), 240 'color_mask_texture': ba.gettexture(char.color_mask_texture), 241 'head_model': ba.getmodel(char.head_model), 242 'torso_model': ba.getmodel(char.torso_model), 243 'pelvis_model': ba.getmodel(char.pelvis_model), 244 'upper_arm_model': ba.getmodel(char.upper_arm_model), 245 'forearm_model': ba.getmodel(char.forearm_model), 246 'hand_model': ba.getmodel(char.hand_model), 247 'upper_leg_model': ba.getmodel(char.upper_leg_model), 248 'lower_leg_model': ba.getmodel(char.lower_leg_model), 249 'toes_model': ba.getmodel(char.toes_model) 250 } 251 else: 252 media = self.spaz_media[character] 253 return media 254 255 @classmethod 256 def get(cls) -> SpazFactory: 257 """Return the shared ba.SpazFactory, creating it if necessary.""" 258 # pylint: disable=cyclic-import 259 activity = ba.getactivity() 260 factory = activity.customdata.get(cls._STORENAME) 261 if factory is None: 262 factory = activity.customdata[cls._STORENAME] = SpazFactory() 263 assert isinstance(factory, SpazFactory) 264 return factory
18class SpazFactory: 19 """Wraps up media and other resources used by ba.Spaz instances. 20 21 Category: **Gameplay Classes** 22 23 Generally one of these is created per ba.Activity and shared 24 between all spaz instances. Use ba.Spaz.get_factory() to return 25 the shared factory for the current activity. 26 """ 27 28 impact_sounds_medium: Sequence[ba.Sound] 29 """A tuple of ba.Sound-s for when a ba.Spaz hits something kinda hard.""" 30 31 impact_sounds_hard: Sequence[ba.Sound] 32 """A tuple of ba.Sound-s for when a ba.Spaz hits something really hard.""" 33 34 impact_sounds_harder: Sequence[ba.Sound] 35 """A tuple of ba.Sound-s for when a ba.Spaz hits something really 36 really hard.""" 37 38 single_player_death_sound: ba.Sound 39 """The sound that plays for an 'important' spaz death such as in 40 co-op games.""" 41 42 punch_sound: ba.Sound 43 """A standard punch ba.Sound.""" 44 45 punch_sound_strong: Sequence[ba.Sound] 46 """A tuple of stronger sounding punch ba.Sounds.""" 47 48 punch_sound_stronger: ba.Sound 49 """A really really strong sounding punch ba.Sound.""" 50 51 swish_sound: ba.Sound 52 """A punch swish ba.Sound.""" 53 54 block_sound: ba.Sound 55 """A ba.Sound for when an attack is blocked by invincibility.""" 56 57 shatter_sound: ba.Sound 58 """A ba.Sound for when a frozen ba.Spaz shatters.""" 59 60 splatter_sound: ba.Sound 61 """A ba.Sound for when a ba.Spaz blows up via curse.""" 62 63 spaz_material: ba.Material 64 """A ba.Material applied to all of parts of a ba.Spaz.""" 65 66 roller_material: ba.Material 67 """A ba.Material applied to the invisible roller ball body that 68 a ba.Spaz uses for locomotion.""" 69 70 punch_material: ba.Material 71 """A ba.Material applied to the 'fist' of a ba.Spaz.""" 72 73 pickup_material: ba.Material 74 """A ba.Material applied to the 'grabber' body of a ba.Spaz.""" 75 76 curse_material: ba.Material 77 """A ba.Material applied to a cursed ba.Spaz that triggers an explosion.""" 78 79 _STORENAME = ba.storagename() 80 81 def _preload(self, character: str) -> None: 82 """Preload media needed for a given character.""" 83 self.get_media(character) 84 85 def __init__(self) -> None: 86 """Instantiate a factory object.""" 87 # pylint: disable=cyclic-import 88 # FIXME: should probably put these somewhere common so we don't 89 # have to import them from a module that imports us. 90 from bastd.actor.spaz import (PickupMessage, PunchHitMessage, 91 CurseExplodeMessage) 92 93 shared = SharedObjects.get() 94 self.impact_sounds_medium = (ba.getsound('impactMedium'), 95 ba.getsound('impactMedium2')) 96 self.impact_sounds_hard = (ba.getsound('impactHard'), 97 ba.getsound('impactHard2'), 98 ba.getsound('impactHard3')) 99 self.impact_sounds_harder = (ba.getsound('bigImpact'), 100 ba.getsound('bigImpact2')) 101 self.single_player_death_sound = ba.getsound('playerDeath') 102 self.punch_sound = ba.getsound('punch01') 103 self.punch_sound_strong = (ba.getsound('punchStrong01'), 104 ba.getsound('punchStrong02')) 105 self.punch_sound_stronger = ba.getsound('superPunch') 106 self.swish_sound = ba.getsound('punchSwish') 107 self.block_sound = ba.getsound('block') 108 self.shatter_sound = ba.getsound('shatter') 109 self.splatter_sound = ba.getsound('splatter') 110 self.spaz_material = ba.Material() 111 self.roller_material = ba.Material() 112 self.punch_material = ba.Material() 113 self.pickup_material = ba.Material() 114 self.curse_material = ba.Material() 115 116 footing_material = shared.footing_material 117 object_material = shared.object_material 118 player_material = shared.player_material 119 region_material = shared.region_material 120 121 # Send footing messages to spazzes so they know when they're on 122 # solid ground. 123 # Eww; this probably should just be built into the spaz node. 124 self.roller_material.add_actions( 125 conditions=('they_have_material', footing_material), 126 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 127 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 128 129 self.spaz_material.add_actions( 130 conditions=('they_have_material', footing_material), 131 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 132 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 133 134 # Punches. 135 self.punch_material.add_actions( 136 conditions=('they_are_different_node_than_us', ), 137 actions=( 138 ('modify_part_collision', 'collide', True), 139 ('modify_part_collision', 'physical', False), 140 ('message', 'our_node', 'at_connect', PunchHitMessage()), 141 )) 142 143 # Pickups. 144 self.pickup_material.add_actions( 145 conditions=(('they_are_different_node_than_us', ), 'and', 146 ('they_have_material', object_material)), 147 actions=( 148 ('modify_part_collision', 'collide', True), 149 ('modify_part_collision', 'physical', False), 150 ('message', 'our_node', 'at_connect', PickupMessage()), 151 )) 152 153 # Curse. 154 self.curse_material.add_actions( 155 conditions=( 156 ('they_are_different_node_than_us', ), 157 'and', 158 ('they_have_material', player_material), 159 ), 160 actions=('message', 'our_node', 'at_connect', 161 CurseExplodeMessage()), 162 ) 163 164 self.foot_impact_sounds = (ba.getsound('footImpact01'), 165 ba.getsound('footImpact02'), 166 ba.getsound('footImpact03')) 167 168 self.foot_skid_sound = ba.getsound('skid01') 169 self.foot_roll_sound = ba.getsound('scamper01') 170 171 self.roller_material.add_actions( 172 conditions=('they_have_material', footing_material), 173 actions=( 174 ('impact_sound', self.foot_impact_sounds, 1, 0.2), 175 ('skid_sound', self.foot_skid_sound, 20, 0.3), 176 ('roll_sound', self.foot_roll_sound, 20, 3.0), 177 )) 178 179 self.skid_sound = ba.getsound('gravelSkid') 180 181 self.spaz_material.add_actions( 182 conditions=('they_have_material', footing_material), 183 actions=( 184 ('impact_sound', self.foot_impact_sounds, 20, 6), 185 ('skid_sound', self.skid_sound, 2.0, 1), 186 ('roll_sound', self.skid_sound, 2.0, 1), 187 )) 188 189 self.shield_up_sound = ba.getsound('shieldUp') 190 self.shield_down_sound = ba.getsound('shieldDown') 191 self.shield_hit_sound = ba.getsound('shieldHit') 192 193 # We don't want to collide with stuff we're initially overlapping 194 # (unless its marked with a special region material). 195 self.spaz_material.add_actions( 196 conditions=( 197 ( 198 ('we_are_younger_than', 51), 199 'and', 200 ('they_are_different_node_than_us', ), 201 ), 202 'and', 203 ('they_dont_have_material', region_material), 204 ), 205 actions=('modify_node_collision', 'collide', False), 206 ) 207 208 self.spaz_media: dict[str, Any] = {} 209 210 # Lets load some basic rules. 211 # (allows them to be tweaked from the master server) 212 self.shield_decay_rate = _ba.get_v1_account_misc_read_val('rsdr', 10.0) 213 self.punch_cooldown = _ba.get_v1_account_misc_read_val('rpc', 400) 214 self.punch_cooldown_gloves = (_ba.get_v1_account_misc_read_val( 215 'rpcg', 300)) 216 self.punch_power_scale = _ba.get_v1_account_misc_read_val('rpp', 1.2) 217 self.punch_power_scale_gloves = (_ba.get_v1_account_misc_read_val( 218 'rppg', 1.4)) 219 self.max_shield_spillover_damage = (_ba.get_v1_account_misc_read_val( 220 'rsms', 500)) 221 222 def get_style(self, character: str) -> str: 223 """Return the named style for this character. 224 225 (this influences subtle aspects of their appearance, etc) 226 """ 227 return ba.app.spaz_appearances[character].style 228 229 def get_media(self, character: str) -> dict[str, Any]: 230 """Return the set of media used by this variant of spaz.""" 231 char = ba.app.spaz_appearances[character] 232 if character not in self.spaz_media: 233 media = self.spaz_media[character] = { 234 'jump_sounds': [ba.getsound(s) for s in char.jump_sounds], 235 'attack_sounds': [ba.getsound(s) for s in char.attack_sounds], 236 'impact_sounds': [ba.getsound(s) for s in char.impact_sounds], 237 'death_sounds': [ba.getsound(s) for s in char.death_sounds], 238 'pickup_sounds': [ba.getsound(s) for s in char.pickup_sounds], 239 'fall_sounds': [ba.getsound(s) for s in char.fall_sounds], 240 'color_texture': ba.gettexture(char.color_texture), 241 'color_mask_texture': ba.gettexture(char.color_mask_texture), 242 'head_model': ba.getmodel(char.head_model), 243 'torso_model': ba.getmodel(char.torso_model), 244 'pelvis_model': ba.getmodel(char.pelvis_model), 245 'upper_arm_model': ba.getmodel(char.upper_arm_model), 246 'forearm_model': ba.getmodel(char.forearm_model), 247 'hand_model': ba.getmodel(char.hand_model), 248 'upper_leg_model': ba.getmodel(char.upper_leg_model), 249 'lower_leg_model': ba.getmodel(char.lower_leg_model), 250 'toes_model': ba.getmodel(char.toes_model) 251 } 252 else: 253 media = self.spaz_media[character] 254 return media 255 256 @classmethod 257 def get(cls) -> SpazFactory: 258 """Return the shared ba.SpazFactory, creating it if necessary.""" 259 # pylint: disable=cyclic-import 260 activity = ba.getactivity() 261 factory = activity.customdata.get(cls._STORENAME) 262 if factory is None: 263 factory = activity.customdata[cls._STORENAME] = SpazFactory() 264 assert isinstance(factory, SpazFactory) 265 return factory
Wraps up media and other resources used by ba.Spaz instances.
Category: Gameplay Classes
Generally one of these is created per ba.Activity and shared between all spaz instances. Use ba.Spaz.get_factory() to return the shared factory for the current activity.
85 def __init__(self) -> None: 86 """Instantiate a factory object.""" 87 # pylint: disable=cyclic-import 88 # FIXME: should probably put these somewhere common so we don't 89 # have to import them from a module that imports us. 90 from bastd.actor.spaz import (PickupMessage, PunchHitMessage, 91 CurseExplodeMessage) 92 93 shared = SharedObjects.get() 94 self.impact_sounds_medium = (ba.getsound('impactMedium'), 95 ba.getsound('impactMedium2')) 96 self.impact_sounds_hard = (ba.getsound('impactHard'), 97 ba.getsound('impactHard2'), 98 ba.getsound('impactHard3')) 99 self.impact_sounds_harder = (ba.getsound('bigImpact'), 100 ba.getsound('bigImpact2')) 101 self.single_player_death_sound = ba.getsound('playerDeath') 102 self.punch_sound = ba.getsound('punch01') 103 self.punch_sound_strong = (ba.getsound('punchStrong01'), 104 ba.getsound('punchStrong02')) 105 self.punch_sound_stronger = ba.getsound('superPunch') 106 self.swish_sound = ba.getsound('punchSwish') 107 self.block_sound = ba.getsound('block') 108 self.shatter_sound = ba.getsound('shatter') 109 self.splatter_sound = ba.getsound('splatter') 110 self.spaz_material = ba.Material() 111 self.roller_material = ba.Material() 112 self.punch_material = ba.Material() 113 self.pickup_material = ba.Material() 114 self.curse_material = ba.Material() 115 116 footing_material = shared.footing_material 117 object_material = shared.object_material 118 player_material = shared.player_material 119 region_material = shared.region_material 120 121 # Send footing messages to spazzes so they know when they're on 122 # solid ground. 123 # Eww; this probably should just be built into the spaz node. 124 self.roller_material.add_actions( 125 conditions=('they_have_material', footing_material), 126 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 127 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 128 129 self.spaz_material.add_actions( 130 conditions=('they_have_material', footing_material), 131 actions=(('message', 'our_node', 'at_connect', 'footing', 1), 132 ('message', 'our_node', 'at_disconnect', 'footing', -1))) 133 134 # Punches. 135 self.punch_material.add_actions( 136 conditions=('they_are_different_node_than_us', ), 137 actions=( 138 ('modify_part_collision', 'collide', True), 139 ('modify_part_collision', 'physical', False), 140 ('message', 'our_node', 'at_connect', PunchHitMessage()), 141 )) 142 143 # Pickups. 144 self.pickup_material.add_actions( 145 conditions=(('they_are_different_node_than_us', ), 'and', 146 ('they_have_material', object_material)), 147 actions=( 148 ('modify_part_collision', 'collide', True), 149 ('modify_part_collision', 'physical', False), 150 ('message', 'our_node', 'at_connect', PickupMessage()), 151 )) 152 153 # Curse. 154 self.curse_material.add_actions( 155 conditions=( 156 ('they_are_different_node_than_us', ), 157 'and', 158 ('they_have_material', player_material), 159 ), 160 actions=('message', 'our_node', 'at_connect', 161 CurseExplodeMessage()), 162 ) 163 164 self.foot_impact_sounds = (ba.getsound('footImpact01'), 165 ba.getsound('footImpact02'), 166 ba.getsound('footImpact03')) 167 168 self.foot_skid_sound = ba.getsound('skid01') 169 self.foot_roll_sound = ba.getsound('scamper01') 170 171 self.roller_material.add_actions( 172 conditions=('they_have_material', footing_material), 173 actions=( 174 ('impact_sound', self.foot_impact_sounds, 1, 0.2), 175 ('skid_sound', self.foot_skid_sound, 20, 0.3), 176 ('roll_sound', self.foot_roll_sound, 20, 3.0), 177 )) 178 179 self.skid_sound = ba.getsound('gravelSkid') 180 181 self.spaz_material.add_actions( 182 conditions=('they_have_material', footing_material), 183 actions=( 184 ('impact_sound', self.foot_impact_sounds, 20, 6), 185 ('skid_sound', self.skid_sound, 2.0, 1), 186 ('roll_sound', self.skid_sound, 2.0, 1), 187 )) 188 189 self.shield_up_sound = ba.getsound('shieldUp') 190 self.shield_down_sound = ba.getsound('shieldDown') 191 self.shield_hit_sound = ba.getsound('shieldHit') 192 193 # We don't want to collide with stuff we're initially overlapping 194 # (unless its marked with a special region material). 195 self.spaz_material.add_actions( 196 conditions=( 197 ( 198 ('we_are_younger_than', 51), 199 'and', 200 ('they_are_different_node_than_us', ), 201 ), 202 'and', 203 ('they_dont_have_material', region_material), 204 ), 205 actions=('modify_node_collision', 'collide', False), 206 ) 207 208 self.spaz_media: dict[str, Any] = {} 209 210 # Lets load some basic rules. 211 # (allows them to be tweaked from the master server) 212 self.shield_decay_rate = _ba.get_v1_account_misc_read_val('rsdr', 10.0) 213 self.punch_cooldown = _ba.get_v1_account_misc_read_val('rpc', 400) 214 self.punch_cooldown_gloves = (_ba.get_v1_account_misc_read_val( 215 'rpcg', 300)) 216 self.punch_power_scale = _ba.get_v1_account_misc_read_val('rpp', 1.2) 217 self.punch_power_scale_gloves = (_ba.get_v1_account_misc_read_val( 218 'rppg', 1.4)) 219 self.max_shield_spillover_damage = (_ba.get_v1_account_misc_read_val( 220 'rsms', 500))
Instantiate a factory object.
A tuple of ba.Sound-s for when a ba.Spaz hits something kinda hard.
A tuple of ba.Sound-s for when a ba.Spaz hits something really hard.
A tuple of ba.Sound-s for when a ba.Spaz hits something really really hard.
The sound that plays for an 'important' spaz death such as in co-op games.
A ba.Material applied to the invisible roller ball body that a ba.Spaz uses for locomotion.
222 def get_style(self, character: str) -> str: 223 """Return the named style for this character. 224 225 (this influences subtle aspects of their appearance, etc) 226 """ 227 return ba.app.spaz_appearances[character].style
Return the named style for this character.
(this influences subtle aspects of their appearance, etc)
229 def get_media(self, character: str) -> dict[str, Any]: 230 """Return the set of media used by this variant of spaz.""" 231 char = ba.app.spaz_appearances[character] 232 if character not in self.spaz_media: 233 media = self.spaz_media[character] = { 234 'jump_sounds': [ba.getsound(s) for s in char.jump_sounds], 235 'attack_sounds': [ba.getsound(s) for s in char.attack_sounds], 236 'impact_sounds': [ba.getsound(s) for s in char.impact_sounds], 237 'death_sounds': [ba.getsound(s) for s in char.death_sounds], 238 'pickup_sounds': [ba.getsound(s) for s in char.pickup_sounds], 239 'fall_sounds': [ba.getsound(s) for s in char.fall_sounds], 240 'color_texture': ba.gettexture(char.color_texture), 241 'color_mask_texture': ba.gettexture(char.color_mask_texture), 242 'head_model': ba.getmodel(char.head_model), 243 'torso_model': ba.getmodel(char.torso_model), 244 'pelvis_model': ba.getmodel(char.pelvis_model), 245 'upper_arm_model': ba.getmodel(char.upper_arm_model), 246 'forearm_model': ba.getmodel(char.forearm_model), 247 'hand_model': ba.getmodel(char.hand_model), 248 'upper_leg_model': ba.getmodel(char.upper_leg_model), 249 'lower_leg_model': ba.getmodel(char.lower_leg_model), 250 'toes_model': ba.getmodel(char.toes_model) 251 } 252 else: 253 media = self.spaz_media[character] 254 return media
Return the set of media used by this variant of spaz.
256 @classmethod 257 def get(cls) -> SpazFactory: 258 """Return the shared ba.SpazFactory, creating it if necessary.""" 259 # pylint: disable=cyclic-import 260 activity = ba.getactivity() 261 factory = activity.customdata.get(cls._STORENAME) 262 if factory is None: 263 factory = activity.customdata[cls._STORENAME] = SpazFactory() 264 assert isinstance(factory, SpazFactory) 265 return factory
Return the shared ba.SpazFactory, creating it if necessary.