bastd.maps

Standard maps.

   1# Released under the MIT License. See LICENSE for details.
   2#
   3"""Standard maps."""
   4# pylint: disable=too-many-lines
   5
   6from __future__ import annotations
   7
   8from typing import TYPE_CHECKING
   9
  10import ba
  11from bastd.gameutils import SharedObjects
  12
  13if TYPE_CHECKING:
  14    from typing import Any
  15
  16
  17class HockeyStadium(ba.Map):
  18    """Stadium map used for ice hockey games."""
  19
  20    from bastd.mapdata import hockey_stadium as defs
  21
  22    name = 'Hockey Stadium'
  23
  24    @classmethod
  25    def get_play_types(cls) -> list[str]:
  26        """Return valid play types for this map."""
  27        return ['melee', 'hockey', 'team_flag', 'keep_away']
  28
  29    @classmethod
  30    def get_preview_texture_name(cls) -> str:
  31        return 'hockeyStadiumPreview'
  32
  33    @classmethod
  34    def on_preload(cls) -> Any:
  35        data: dict[str, Any] = {
  36            'models': (
  37                ba.getmodel('hockeyStadiumOuter'),
  38                ba.getmodel('hockeyStadiumInner'),
  39                ba.getmodel('hockeyStadiumStands'),
  40            ),
  41            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
  42            'collide_model': ba.getcollidemodel('hockeyStadiumCollide'),
  43            'tex': ba.gettexture('hockeyStadium'),
  44            'stands_tex': ba.gettexture('footballStadium'),
  45        }
  46        mat = ba.Material()
  47        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
  48        data['ice_material'] = mat
  49        return data
  50
  51    def __init__(self) -> None:
  52        super().__init__()
  53        shared = SharedObjects.get()
  54        self.node = ba.newnode(
  55            'terrain',
  56            delegate=self,
  57            attrs={
  58                'model': self.preloaddata['models'][0],
  59                'collide_model': self.preloaddata['collide_model'],
  60                'color_texture': self.preloaddata['tex'],
  61                'materials': [
  62                    shared.footing_material,
  63                    self.preloaddata['ice_material'],
  64                ],
  65            },
  66        )
  67        ba.newnode(
  68            'terrain',
  69            attrs={
  70                'model': self.preloaddata['vr_fill_model'],
  71                'vr_only': True,
  72                'lighting': False,
  73                'background': True,
  74                'color_texture': self.preloaddata['stands_tex'],
  75            },
  76        )
  77        mats = [shared.footing_material, self.preloaddata['ice_material']]
  78        self.floor = ba.newnode(
  79            'terrain',
  80            attrs={
  81                'model': self.preloaddata['models'][1],
  82                'color_texture': self.preloaddata['tex'],
  83                'opacity': 0.92,
  84                'opacity_in_low_or_medium_quality': 1.0,
  85                'materials': mats,
  86            },
  87        )
  88        self.stands = ba.newnode(
  89            'terrain',
  90            attrs={
  91                'model': self.preloaddata['models'][2],
  92                'visible_in_reflections': False,
  93                'color_texture': self.preloaddata['stands_tex'],
  94            },
  95        )
  96        gnode = ba.getactivity().globalsnode
  97        gnode.floor_reflection = True
  98        gnode.debris_friction = 0.3
  99        gnode.debris_kill_height = -0.3
 100        gnode.tint = (1.2, 1.3, 1.33)
 101        gnode.ambient_color = (1.15, 1.25, 1.6)
 102        gnode.vignette_outer = (0.66, 0.67, 0.73)
 103        gnode.vignette_inner = (0.93, 0.93, 0.95)
 104        gnode.vr_camera_offset = (0, -0.8, -1.1)
 105        gnode.vr_near_clip = 0.5
 106        self.is_hockey = True
 107
 108
 109class FootballStadium(ba.Map):
 110    """Stadium map for football games."""
 111
 112    from bastd.mapdata import football_stadium as defs
 113
 114    name = 'Football Stadium'
 115
 116    @classmethod
 117    def get_play_types(cls) -> list[str]:
 118        """Return valid play types for this map."""
 119        return ['melee', 'football', 'team_flag', 'keep_away']
 120
 121    @classmethod
 122    def get_preview_texture_name(cls) -> str:
 123        return 'footballStadiumPreview'
 124
 125    @classmethod
 126    def on_preload(cls) -> Any:
 127        data: dict[str, Any] = {
 128            'model': ba.getmodel('footballStadium'),
 129            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
 130            'collide_model': ba.getcollidemodel('footballStadiumCollide'),
 131            'tex': ba.gettexture('footballStadium'),
 132        }
 133        return data
 134
 135    def __init__(self) -> None:
 136        super().__init__()
 137        shared = SharedObjects.get()
 138        self.node = ba.newnode(
 139            'terrain',
 140            delegate=self,
 141            attrs={
 142                'model': self.preloaddata['model'],
 143                'collide_model': self.preloaddata['collide_model'],
 144                'color_texture': self.preloaddata['tex'],
 145                'materials': [shared.footing_material],
 146            },
 147        )
 148        ba.newnode(
 149            'terrain',
 150            attrs={
 151                'model': self.preloaddata['vr_fill_model'],
 152                'lighting': False,
 153                'vr_only': True,
 154                'background': True,
 155                'color_texture': self.preloaddata['tex'],
 156            },
 157        )
 158        gnode = ba.getactivity().globalsnode
 159        gnode.tint = (1.3, 1.2, 1.0)
 160        gnode.ambient_color = (1.3, 1.2, 1.0)
 161        gnode.vignette_outer = (0.57, 0.57, 0.57)
 162        gnode.vignette_inner = (0.9, 0.9, 0.9)
 163        gnode.vr_camera_offset = (0, -0.8, -1.1)
 164        gnode.vr_near_clip = 0.5
 165
 166    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
 167        box_position = self.defs.boxes['edge_box'][0:3]
 168        box_scale = self.defs.boxes['edge_box'][6:9]
 169        xpos = (point.x - box_position[0]) / box_scale[0]
 170        zpos = (point.z - box_position[2]) / box_scale[2]
 171        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5
 172
 173
 174class Bridgit(ba.Map):
 175    """Map with a narrow bridge in the middle."""
 176
 177    from bastd.mapdata import bridgit as defs
 178
 179    name = 'Bridgit'
 180    dataname = 'bridgit'
 181
 182    @classmethod
 183    def get_play_types(cls) -> list[str]:
 184        """Return valid play types for this map."""
 185        # print('getting playtypes', cls._getdata()['play_types'])
 186        return ['melee', 'team_flag', 'keep_away']
 187
 188    @classmethod
 189    def get_preview_texture_name(cls) -> str:
 190        return 'bridgitPreview'
 191
 192    @classmethod
 193    def on_preload(cls) -> Any:
 194        data: dict[str, Any] = {
 195            'model_top': ba.getmodel('bridgitLevelTop'),
 196            'model_bottom': ba.getmodel('bridgitLevelBottom'),
 197            'model_bg': ba.getmodel('natureBackground'),
 198            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
 199            'collide_model': ba.getcollidemodel('bridgitLevelCollide'),
 200            'tex': ba.gettexture('bridgitLevelColor'),
 201            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
 202            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
 203            'railing_collide_model': (
 204                ba.getcollidemodel('bridgitLevelRailingCollide')
 205            ),
 206            'bg_material': ba.Material(),
 207        }
 208        data['bg_material'].add_actions(
 209            actions=('modify_part_collision', 'friction', 10.0)
 210        )
 211        return data
 212
 213    def __init__(self) -> None:
 214        super().__init__()
 215        shared = SharedObjects.get()
 216        self.node = ba.newnode(
 217            'terrain',
 218            delegate=self,
 219            attrs={
 220                'collide_model': self.preloaddata['collide_model'],
 221                'model': self.preloaddata['model_top'],
 222                'color_texture': self.preloaddata['tex'],
 223                'materials': [shared.footing_material],
 224            },
 225        )
 226        self.bottom = ba.newnode(
 227            'terrain',
 228            attrs={
 229                'model': self.preloaddata['model_bottom'],
 230                'lighting': False,
 231                'color_texture': self.preloaddata['tex'],
 232            },
 233        )
 234        self.background = ba.newnode(
 235            'terrain',
 236            attrs={
 237                'model': self.preloaddata['model_bg'],
 238                'lighting': False,
 239                'background': True,
 240                'color_texture': self.preloaddata['model_bg_tex'],
 241            },
 242        )
 243        ba.newnode(
 244            'terrain',
 245            attrs={
 246                'model': self.preloaddata['bg_vr_fill_model'],
 247                'lighting': False,
 248                'vr_only': True,
 249                'background': True,
 250                'color_texture': self.preloaddata['model_bg_tex'],
 251            },
 252        )
 253        self.railing = ba.newnode(
 254            'terrain',
 255            attrs={
 256                'collide_model': self.preloaddata['railing_collide_model'],
 257                'materials': [shared.railing_material],
 258                'bumper': True,
 259            },
 260        )
 261        self.bg_collide = ba.newnode(
 262            'terrain',
 263            attrs={
 264                'collide_model': self.preloaddata['collide_bg'],
 265                'materials': [
 266                    shared.footing_material,
 267                    self.preloaddata['bg_material'],
 268                    shared.death_material,
 269                ],
 270            },
 271        )
 272        gnode = ba.getactivity().globalsnode
 273        gnode.tint = (1.1, 1.2, 1.3)
 274        gnode.ambient_color = (1.1, 1.2, 1.3)
 275        gnode.vignette_outer = (0.65, 0.6, 0.55)
 276        gnode.vignette_inner = (0.9, 0.9, 0.93)
 277
 278
 279class BigG(ba.Map):
 280    """Large G shaped map for racing"""
 281
 282    from bastd.mapdata import big_g as defs
 283
 284    name = 'Big G'
 285
 286    @classmethod
 287    def get_play_types(cls) -> list[str]:
 288        """Return valid play types for this map."""
 289        return [
 290            'race',
 291            'melee',
 292            'keep_away',
 293            'team_flag',
 294            'king_of_the_hill',
 295            'conquest',
 296        ]
 297
 298    @classmethod
 299    def get_preview_texture_name(cls) -> str:
 300        return 'bigGPreview'
 301
 302    @classmethod
 303    def on_preload(cls) -> Any:
 304        data: dict[str, Any] = {
 305            'model_top': ba.getmodel('bigG'),
 306            'model_bottom': ba.getmodel('bigGBottom'),
 307            'model_bg': ba.getmodel('natureBackground'),
 308            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
 309            'collide_model': ba.getcollidemodel('bigGCollide'),
 310            'tex': ba.gettexture('bigG'),
 311            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
 312            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
 313            'bumper_collide_model': ba.getcollidemodel('bigGBumper'),
 314            'bg_material': ba.Material(),
 315        }
 316        data['bg_material'].add_actions(
 317            actions=('modify_part_collision', 'friction', 10.0)
 318        )
 319        return data
 320
 321    def __init__(self) -> None:
 322        super().__init__()
 323        shared = SharedObjects.get()
 324        self.node = ba.newnode(
 325            'terrain',
 326            delegate=self,
 327            attrs={
 328                'collide_model': self.preloaddata['collide_model'],
 329                'color': (0.7, 0.7, 0.7),
 330                'model': self.preloaddata['model_top'],
 331                'color_texture': self.preloaddata['tex'],
 332                'materials': [shared.footing_material],
 333            },
 334        )
 335        self.bottom = ba.newnode(
 336            'terrain',
 337            attrs={
 338                'model': self.preloaddata['model_bottom'],
 339                'color': (0.7, 0.7, 0.7),
 340                'lighting': False,
 341                'color_texture': self.preloaddata['tex'],
 342            },
 343        )
 344        self.background = ba.newnode(
 345            'terrain',
 346            attrs={
 347                'model': self.preloaddata['model_bg'],
 348                'lighting': False,
 349                'background': True,
 350                'color_texture': self.preloaddata['model_bg_tex'],
 351            },
 352        )
 353        ba.newnode(
 354            'terrain',
 355            attrs={
 356                'model': self.preloaddata['bg_vr_fill_model'],
 357                'lighting': False,
 358                'vr_only': True,
 359                'background': True,
 360                'color_texture': self.preloaddata['model_bg_tex'],
 361            },
 362        )
 363        self.railing = ba.newnode(
 364            'terrain',
 365            attrs={
 366                'collide_model': self.preloaddata['bumper_collide_model'],
 367                'materials': [shared.railing_material],
 368                'bumper': True,
 369            },
 370        )
 371        self.bg_collide = ba.newnode(
 372            'terrain',
 373            attrs={
 374                'collide_model': self.preloaddata['collide_bg'],
 375                'materials': [
 376                    shared.footing_material,
 377                    self.preloaddata['bg_material'],
 378                    shared.death_material,
 379                ],
 380            },
 381        )
 382        gnode = ba.getactivity().globalsnode
 383        gnode.tint = (1.1, 1.2, 1.3)
 384        gnode.ambient_color = (1.1, 1.2, 1.3)
 385        gnode.vignette_outer = (0.65, 0.6, 0.55)
 386        gnode.vignette_inner = (0.9, 0.9, 0.93)
 387
 388
 389class Roundabout(ba.Map):
 390    """CTF map featuring two platforms and a long way around between them"""
 391
 392    from bastd.mapdata import roundabout as defs
 393
 394    name = 'Roundabout'
 395
 396    @classmethod
 397    def get_play_types(cls) -> list[str]:
 398        """Return valid play types for this map."""
 399        return ['melee', 'keep_away', 'team_flag']
 400
 401    @classmethod
 402    def get_preview_texture_name(cls) -> str:
 403        return 'roundaboutPreview'
 404
 405    @classmethod
 406    def on_preload(cls) -> Any:
 407        data: dict[str, Any] = {
 408            'model': ba.getmodel('roundaboutLevel'),
 409            'model_bottom': ba.getmodel('roundaboutLevelBottom'),
 410            'model_bg': ba.getmodel('natureBackground'),
 411            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
 412            'collide_model': ba.getcollidemodel('roundaboutLevelCollide'),
 413            'tex': ba.gettexture('roundaboutLevelColor'),
 414            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
 415            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
 416            'railing_collide_model': (
 417                ba.getcollidemodel('roundaboutLevelBumper')
 418            ),
 419            'bg_material': ba.Material(),
 420        }
 421        data['bg_material'].add_actions(
 422            actions=('modify_part_collision', 'friction', 10.0)
 423        )
 424        return data
 425
 426    def __init__(self) -> None:
 427        super().__init__(vr_overlay_offset=(0, -1, 1))
 428        shared = SharedObjects.get()
 429        self.node = ba.newnode(
 430            'terrain',
 431            delegate=self,
 432            attrs={
 433                'collide_model': self.preloaddata['collide_model'],
 434                'model': self.preloaddata['model'],
 435                'color_texture': self.preloaddata['tex'],
 436                'materials': [shared.footing_material],
 437            },
 438        )
 439        self.bottom = ba.newnode(
 440            'terrain',
 441            attrs={
 442                'model': self.preloaddata['model_bottom'],
 443                'lighting': False,
 444                'color_texture': self.preloaddata['tex'],
 445            },
 446        )
 447        self.background = ba.newnode(
 448            'terrain',
 449            attrs={
 450                'model': self.preloaddata['model_bg'],
 451                'lighting': False,
 452                'background': True,
 453                'color_texture': self.preloaddata['model_bg_tex'],
 454            },
 455        )
 456        ba.newnode(
 457            'terrain',
 458            attrs={
 459                'model': self.preloaddata['bg_vr_fill_model'],
 460                'lighting': False,
 461                'vr_only': True,
 462                'background': True,
 463                'color_texture': self.preloaddata['model_bg_tex'],
 464            },
 465        )
 466        self.bg_collide = ba.newnode(
 467            'terrain',
 468            attrs={
 469                'collide_model': self.preloaddata['collide_bg'],
 470                'materials': [
 471                    shared.footing_material,
 472                    self.preloaddata['bg_material'],
 473                    shared.death_material,
 474                ],
 475            },
 476        )
 477        self.railing = ba.newnode(
 478            'terrain',
 479            attrs={
 480                'collide_model': self.preloaddata['railing_collide_model'],
 481                'materials': [shared.railing_material],
 482                'bumper': True,
 483            },
 484        )
 485        gnode = ba.getactivity().globalsnode
 486        gnode.tint = (1.0, 1.05, 1.1)
 487        gnode.ambient_color = (1.0, 1.05, 1.1)
 488        gnode.shadow_ortho = True
 489        gnode.vignette_outer = (0.63, 0.65, 0.7)
 490        gnode.vignette_inner = (0.97, 0.95, 0.93)
 491
 492
 493class MonkeyFace(ba.Map):
 494    """Map sorta shaped like a monkey face; teehee!"""
 495
 496    from bastd.mapdata import monkey_face as defs
 497
 498    name = 'Monkey Face'
 499
 500    @classmethod
 501    def get_play_types(cls) -> list[str]:
 502        """Return valid play types for this map."""
 503        return ['melee', 'keep_away', 'team_flag']
 504
 505    @classmethod
 506    def get_preview_texture_name(cls) -> str:
 507        return 'monkeyFacePreview'
 508
 509    @classmethod
 510    def on_preload(cls) -> Any:
 511        data: dict[str, Any] = {
 512            'model': ba.getmodel('monkeyFaceLevel'),
 513            'bottom_model': ba.getmodel('monkeyFaceLevelBottom'),
 514            'model_bg': ba.getmodel('natureBackground'),
 515            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
 516            'collide_model': ba.getcollidemodel('monkeyFaceLevelCollide'),
 517            'tex': ba.gettexture('monkeyFaceLevelColor'),
 518            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
 519            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
 520            'railing_collide_model': (
 521                ba.getcollidemodel('monkeyFaceLevelBumper')
 522            ),
 523            'bg_material': ba.Material(),
 524        }
 525        data['bg_material'].add_actions(
 526            actions=('modify_part_collision', 'friction', 10.0)
 527        )
 528        return data
 529
 530    def __init__(self) -> None:
 531        super().__init__()
 532        shared = SharedObjects.get()
 533        self.node = ba.newnode(
 534            'terrain',
 535            delegate=self,
 536            attrs={
 537                'collide_model': self.preloaddata['collide_model'],
 538                'model': self.preloaddata['model'],
 539                'color_texture': self.preloaddata['tex'],
 540                'materials': [shared.footing_material],
 541            },
 542        )
 543        self.bottom = ba.newnode(
 544            'terrain',
 545            attrs={
 546                'model': self.preloaddata['bottom_model'],
 547                'lighting': False,
 548                'color_texture': self.preloaddata['tex'],
 549            },
 550        )
 551        self.background = ba.newnode(
 552            'terrain',
 553            attrs={
 554                'model': self.preloaddata['model_bg'],
 555                'lighting': False,
 556                'background': True,
 557                'color_texture': self.preloaddata['model_bg_tex'],
 558            },
 559        )
 560        ba.newnode(
 561            'terrain',
 562            attrs={
 563                'model': self.preloaddata['bg_vr_fill_model'],
 564                'lighting': False,
 565                'vr_only': True,
 566                'background': True,
 567                'color_texture': self.preloaddata['model_bg_tex'],
 568            },
 569        )
 570        self.bg_collide = ba.newnode(
 571            'terrain',
 572            attrs={
 573                'collide_model': self.preloaddata['collide_bg'],
 574                'materials': [
 575                    shared.footing_material,
 576                    self.preloaddata['bg_material'],
 577                    shared.death_material,
 578                ],
 579            },
 580        )
 581        self.railing = ba.newnode(
 582            'terrain',
 583            attrs={
 584                'collide_model': self.preloaddata['railing_collide_model'],
 585                'materials': [shared.railing_material],
 586                'bumper': True,
 587            },
 588        )
 589        gnode = ba.getactivity().globalsnode
 590        gnode.tint = (1.1, 1.2, 1.2)
 591        gnode.ambient_color = (1.2, 1.3, 1.3)
 592        gnode.vignette_outer = (0.60, 0.62, 0.66)
 593        gnode.vignette_inner = (0.97, 0.95, 0.93)
 594        gnode.vr_camera_offset = (-1.4, 0, 0)
 595
 596
 597class ZigZag(ba.Map):
 598    """A very long zig-zaggy map"""
 599
 600    from bastd.mapdata import zig_zag as defs
 601
 602    name = 'Zigzag'
 603
 604    @classmethod
 605    def get_play_types(cls) -> list[str]:
 606        """Return valid play types for this map."""
 607        return [
 608            'melee',
 609            'keep_away',
 610            'team_flag',
 611            'conquest',
 612            'king_of_the_hill',
 613        ]
 614
 615    @classmethod
 616    def get_preview_texture_name(cls) -> str:
 617        return 'zigzagPreview'
 618
 619    @classmethod
 620    def on_preload(cls) -> Any:
 621        data: dict[str, Any] = {
 622            'model': ba.getmodel('zigZagLevel'),
 623            'model_bottom': ba.getmodel('zigZagLevelBottom'),
 624            'model_bg': ba.getmodel('natureBackground'),
 625            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
 626            'collide_model': ba.getcollidemodel('zigZagLevelCollide'),
 627            'tex': ba.gettexture('zigZagLevelColor'),
 628            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
 629            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
 630            'railing_collide_model': ba.getcollidemodel('zigZagLevelBumper'),
 631            'bg_material': ba.Material(),
 632        }
 633        data['bg_material'].add_actions(
 634            actions=('modify_part_collision', 'friction', 10.0)
 635        )
 636        return data
 637
 638    def __init__(self) -> None:
 639        super().__init__()
 640        shared = SharedObjects.get()
 641        self.node = ba.newnode(
 642            'terrain',
 643            delegate=self,
 644            attrs={
 645                'collide_model': self.preloaddata['collide_model'],
 646                'model': self.preloaddata['model'],
 647                'color_texture': self.preloaddata['tex'],
 648                'materials': [shared.footing_material],
 649            },
 650        )
 651        self.background = ba.newnode(
 652            'terrain',
 653            attrs={
 654                'model': self.preloaddata['model_bg'],
 655                'lighting': False,
 656                'color_texture': self.preloaddata['model_bg_tex'],
 657            },
 658        )
 659        self.bottom = ba.newnode(
 660            'terrain',
 661            attrs={
 662                'model': self.preloaddata['model_bottom'],
 663                'lighting': False,
 664                'color_texture': self.preloaddata['tex'],
 665            },
 666        )
 667        ba.newnode(
 668            'terrain',
 669            attrs={
 670                'model': self.preloaddata['bg_vr_fill_model'],
 671                'lighting': False,
 672                'vr_only': True,
 673                'background': True,
 674                'color_texture': self.preloaddata['model_bg_tex'],
 675            },
 676        )
 677        self.bg_collide = ba.newnode(
 678            'terrain',
 679            attrs={
 680                'collide_model': self.preloaddata['collide_bg'],
 681                'materials': [
 682                    shared.footing_material,
 683                    self.preloaddata['bg_material'],
 684                    shared.death_material,
 685                ],
 686            },
 687        )
 688        self.railing = ba.newnode(
 689            'terrain',
 690            attrs={
 691                'collide_model': self.preloaddata['railing_collide_model'],
 692                'materials': [shared.railing_material],
 693                'bumper': True,
 694            },
 695        )
 696        gnode = ba.getactivity().globalsnode
 697        gnode.tint = (1.0, 1.15, 1.15)
 698        gnode.ambient_color = (1.0, 1.15, 1.15)
 699        gnode.vignette_outer = (0.57, 0.59, 0.63)
 700        gnode.vignette_inner = (0.97, 0.95, 0.93)
 701        gnode.vr_camera_offset = (-1.5, 0, 0)
 702
 703
 704class ThePad(ba.Map):
 705    """A simple square shaped map with a raised edge."""
 706
 707    from bastd.mapdata import the_pad as defs
 708
 709    name = 'The Pad'
 710
 711    @classmethod
 712    def get_play_types(cls) -> list[str]:
 713        """Return valid play types for this map."""
 714        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
 715
 716    @classmethod
 717    def get_preview_texture_name(cls) -> str:
 718        return 'thePadPreview'
 719
 720    @classmethod
 721    def on_preload(cls) -> Any:
 722        data: dict[str, Any] = {
 723            'model': ba.getmodel('thePadLevel'),
 724            'bottom_model': ba.getmodel('thePadLevelBottom'),
 725            'collide_model': ba.getcollidemodel('thePadLevelCollide'),
 726            'tex': ba.gettexture('thePadLevelColor'),
 727            'bgtex': ba.gettexture('menuBG'),
 728            'bgmodel': ba.getmodel('thePadBG'),
 729            'railing_collide_model': ba.getcollidemodel('thePadLevelBumper'),
 730            'vr_fill_mound_model': ba.getmodel('thePadVRFillMound'),
 731            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
 732        }
 733        # fixme should chop this into vr/non-vr sections for efficiency
 734        return data
 735
 736    def __init__(self) -> None:
 737        super().__init__()
 738        shared = SharedObjects.get()
 739        self.node = ba.newnode(
 740            'terrain',
 741            delegate=self,
 742            attrs={
 743                'collide_model': self.preloaddata['collide_model'],
 744                'model': self.preloaddata['model'],
 745                'color_texture': self.preloaddata['tex'],
 746                'materials': [shared.footing_material],
 747            },
 748        )
 749        self.bottom = ba.newnode(
 750            'terrain',
 751            attrs={
 752                'model': self.preloaddata['bottom_model'],
 753                'lighting': False,
 754                'color_texture': self.preloaddata['tex'],
 755            },
 756        )
 757        self.background = ba.newnode(
 758            'terrain',
 759            attrs={
 760                'model': self.preloaddata['bgmodel'],
 761                'lighting': False,
 762                'background': True,
 763                'color_texture': self.preloaddata['bgtex'],
 764            },
 765        )
 766        self.railing = ba.newnode(
 767            'terrain',
 768            attrs={
 769                'collide_model': self.preloaddata['railing_collide_model'],
 770                'materials': [shared.railing_material],
 771                'bumper': True,
 772            },
 773        )
 774        ba.newnode(
 775            'terrain',
 776            attrs={
 777                'model': self.preloaddata['vr_fill_mound_model'],
 778                'lighting': False,
 779                'vr_only': True,
 780                'color': (0.56, 0.55, 0.47),
 781                'background': True,
 782                'color_texture': self.preloaddata['vr_fill_mound_tex'],
 783            },
 784        )
 785        gnode = ba.getactivity().globalsnode
 786        gnode.tint = (1.1, 1.1, 1.0)
 787        gnode.ambient_color = (1.1, 1.1, 1.0)
 788        gnode.vignette_outer = (0.7, 0.65, 0.75)
 789        gnode.vignette_inner = (0.95, 0.95, 0.93)
 790
 791
 792class DoomShroom(ba.Map):
 793    """A giant mushroom. Of doom!"""
 794
 795    from bastd.mapdata import doom_shroom as defs
 796
 797    name = 'Doom Shroom'
 798
 799    @classmethod
 800    def get_play_types(cls) -> list[str]:
 801        """Return valid play types for this map."""
 802        return ['melee', 'keep_away', 'team_flag']
 803
 804    @classmethod
 805    def get_preview_texture_name(cls) -> str:
 806        return 'doomShroomPreview'
 807
 808    @classmethod
 809    def on_preload(cls) -> Any:
 810        data: dict[str, Any] = {
 811            'model': ba.getmodel('doomShroomLevel'),
 812            'collide_model': ba.getcollidemodel('doomShroomLevelCollide'),
 813            'tex': ba.gettexture('doomShroomLevelColor'),
 814            'bgtex': ba.gettexture('doomShroomBGColor'),
 815            'bgmodel': ba.getmodel('doomShroomBG'),
 816            'vr_fill_model': ba.getmodel('doomShroomVRFill'),
 817            'stem_model': ba.getmodel('doomShroomStem'),
 818            'collide_bg': ba.getcollidemodel('doomShroomStemCollide'),
 819        }
 820        return data
 821
 822    def __init__(self) -> None:
 823        super().__init__()
 824        shared = SharedObjects.get()
 825        self.node = ba.newnode(
 826            'terrain',
 827            delegate=self,
 828            attrs={
 829                'collide_model': self.preloaddata['collide_model'],
 830                'model': self.preloaddata['model'],
 831                'color_texture': self.preloaddata['tex'],
 832                'materials': [shared.footing_material],
 833            },
 834        )
 835        self.background = ba.newnode(
 836            'terrain',
 837            attrs={
 838                'model': self.preloaddata['bgmodel'],
 839                'lighting': False,
 840                'background': True,
 841                'color_texture': self.preloaddata['bgtex'],
 842            },
 843        )
 844        ba.newnode(
 845            'terrain',
 846            attrs={
 847                'model': self.preloaddata['vr_fill_model'],
 848                'lighting': False,
 849                'vr_only': True,
 850                'background': True,
 851                'color_texture': self.preloaddata['bgtex'],
 852            },
 853        )
 854        self.stem = ba.newnode(
 855            'terrain',
 856            attrs={
 857                'model': self.preloaddata['stem_model'],
 858                'lighting': False,
 859                'color_texture': self.preloaddata['tex'],
 860            },
 861        )
 862        self.bg_collide = ba.newnode(
 863            'terrain',
 864            attrs={
 865                'collide_model': self.preloaddata['collide_bg'],
 866                'materials': [shared.footing_material, shared.death_material],
 867            },
 868        )
 869        gnode = ba.getactivity().globalsnode
 870        gnode.tint = (0.82, 1.10, 1.15)
 871        gnode.ambient_color = (0.9, 1.3, 1.1)
 872        gnode.shadow_ortho = False
 873        gnode.vignette_outer = (0.76, 0.76, 0.76)
 874        gnode.vignette_inner = (0.95, 0.95, 0.99)
 875
 876    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
 877        xpos = point.x
 878        zpos = point.z
 879        x_adj = xpos * 0.125
 880        z_adj = (zpos + 3.7) * 0.2
 881        if running:
 882            x_adj *= 1.4
 883            z_adj *= 1.4
 884        return x_adj * x_adj + z_adj * z_adj > 1.0
 885
 886
 887class LakeFrigid(ba.Map):
 888    """An icy lake fit for racing."""
 889
 890    from bastd.mapdata import lake_frigid as defs
 891
 892    name = 'Lake Frigid'
 893
 894    @classmethod
 895    def get_play_types(cls) -> list[str]:
 896        """Return valid play types for this map."""
 897        return ['melee', 'keep_away', 'team_flag', 'race']
 898
 899    @classmethod
 900    def get_preview_texture_name(cls) -> str:
 901        return 'lakeFrigidPreview'
 902
 903    @classmethod
 904    def on_preload(cls) -> Any:
 905        data: dict[str, Any] = {
 906            'model': ba.getmodel('lakeFrigid'),
 907            'model_top': ba.getmodel('lakeFrigidTop'),
 908            'model_reflections': ba.getmodel('lakeFrigidReflections'),
 909            'collide_model': ba.getcollidemodel('lakeFrigidCollide'),
 910            'tex': ba.gettexture('lakeFrigid'),
 911            'tex_reflections': ba.gettexture('lakeFrigidReflections'),
 912            'vr_fill_model': ba.getmodel('lakeFrigidVRFill'),
 913        }
 914        mat = ba.Material()
 915        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
 916        data['ice_material'] = mat
 917        return data
 918
 919    def __init__(self) -> None:
 920        super().__init__()
 921        shared = SharedObjects.get()
 922        self.node = ba.newnode(
 923            'terrain',
 924            delegate=self,
 925            attrs={
 926                'collide_model': self.preloaddata['collide_model'],
 927                'model': self.preloaddata['model'],
 928                'color_texture': self.preloaddata['tex'],
 929                'materials': [
 930                    shared.footing_material,
 931                    self.preloaddata['ice_material'],
 932                ],
 933            },
 934        )
 935        ba.newnode(
 936            'terrain',
 937            attrs={
 938                'model': self.preloaddata['model_top'],
 939                'lighting': False,
 940                'color_texture': self.preloaddata['tex'],
 941            },
 942        )
 943        ba.newnode(
 944            'terrain',
 945            attrs={
 946                'model': self.preloaddata['model_reflections'],
 947                'lighting': False,
 948                'overlay': True,
 949                'opacity': 0.15,
 950                'color_texture': self.preloaddata['tex_reflections'],
 951            },
 952        )
 953        ba.newnode(
 954            'terrain',
 955            attrs={
 956                'model': self.preloaddata['vr_fill_model'],
 957                'lighting': False,
 958                'vr_only': True,
 959                'background': True,
 960                'color_texture': self.preloaddata['tex'],
 961            },
 962        )
 963        gnode = ba.getactivity().globalsnode
 964        gnode.tint = (1, 1, 1)
 965        gnode.ambient_color = (1, 1, 1)
 966        gnode.shadow_ortho = True
 967        gnode.vignette_outer = (0.86, 0.86, 0.86)
 968        gnode.vignette_inner = (0.95, 0.95, 0.99)
 969        gnode.vr_near_clip = 0.5
 970        self.is_hockey = True
 971
 972
 973class TipTop(ba.Map):
 974    """A pointy map good for king-of-the-hill-ish games."""
 975
 976    from bastd.mapdata import tip_top as defs
 977
 978    name = 'Tip Top'
 979
 980    @classmethod
 981    def get_play_types(cls) -> list[str]:
 982        """Return valid play types for this map."""
 983        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
 984
 985    @classmethod
 986    def get_preview_texture_name(cls) -> str:
 987        return 'tipTopPreview'
 988
 989    @classmethod
 990    def on_preload(cls) -> Any:
 991        data: dict[str, Any] = {
 992            'model': ba.getmodel('tipTopLevel'),
 993            'bottom_model': ba.getmodel('tipTopLevelBottom'),
 994            'collide_model': ba.getcollidemodel('tipTopLevelCollide'),
 995            'tex': ba.gettexture('tipTopLevelColor'),
 996            'bgtex': ba.gettexture('tipTopBGColor'),
 997            'bgmodel': ba.getmodel('tipTopBG'),
 998            'railing_collide_model': ba.getcollidemodel('tipTopLevelBumper'),
 999        }
1000        return data
1001
1002    def __init__(self) -> None:
1003        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1004        shared = SharedObjects.get()
1005        self.node = ba.newnode(
1006            'terrain',
1007            delegate=self,
1008            attrs={
1009                'collide_model': self.preloaddata['collide_model'],
1010                'model': self.preloaddata['model'],
1011                'color_texture': self.preloaddata['tex'],
1012                'color': (0.7, 0.7, 0.7),
1013                'materials': [shared.footing_material],
1014            },
1015        )
1016        self.bottom = ba.newnode(
1017            'terrain',
1018            attrs={
1019                'model': self.preloaddata['bottom_model'],
1020                'lighting': False,
1021                'color': (0.7, 0.7, 0.7),
1022                'color_texture': self.preloaddata['tex'],
1023            },
1024        )
1025        self.background = ba.newnode(
1026            'terrain',
1027            attrs={
1028                'model': self.preloaddata['bgmodel'],
1029                'lighting': False,
1030                'color': (0.4, 0.4, 0.4),
1031                'background': True,
1032                'color_texture': self.preloaddata['bgtex'],
1033            },
1034        )
1035        self.railing = ba.newnode(
1036            'terrain',
1037            attrs={
1038                'collide_model': self.preloaddata['railing_collide_model'],
1039                'materials': [shared.railing_material],
1040                'bumper': True,
1041            },
1042        )
1043        gnode = ba.getactivity().globalsnode
1044        gnode.tint = (0.8, 0.9, 1.3)
1045        gnode.ambient_color = (0.8, 0.9, 1.3)
1046        gnode.vignette_outer = (0.79, 0.79, 0.69)
1047        gnode.vignette_inner = (0.97, 0.97, 0.99)
1048
1049
1050class CragCastle(ba.Map):
1051    """A lovely castle map."""
1052
1053    from bastd.mapdata import crag_castle as defs
1054
1055    name = 'Crag Castle'
1056
1057    @classmethod
1058    def get_play_types(cls) -> list[str]:
1059        """Return valid play types for this map."""
1060        return ['melee', 'keep_away', 'team_flag', 'conquest']
1061
1062    @classmethod
1063    def get_preview_texture_name(cls) -> str:
1064        return 'cragCastlePreview'
1065
1066    @classmethod
1067    def on_preload(cls) -> Any:
1068        data: dict[str, Any] = {
1069            'model': ba.getmodel('cragCastleLevel'),
1070            'bottom_model': ba.getmodel('cragCastleLevelBottom'),
1071            'collide_model': ba.getcollidemodel('cragCastleLevelCollide'),
1072            'tex': ba.gettexture('cragCastleLevelColor'),
1073            'bgtex': ba.gettexture('menuBG'),
1074            'bgmodel': ba.getmodel('thePadBG'),
1075            'railing_collide_model': (
1076                ba.getcollidemodel('cragCastleLevelBumper')
1077            ),
1078            'vr_fill_mound_model': ba.getmodel('cragCastleVRFillMound'),
1079            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1080        }
1081        # fixme should chop this into vr/non-vr sections
1082        return data
1083
1084    def __init__(self) -> None:
1085        super().__init__()
1086        shared = SharedObjects.get()
1087        self.node = ba.newnode(
1088            'terrain',
1089            delegate=self,
1090            attrs={
1091                'collide_model': self.preloaddata['collide_model'],
1092                'model': self.preloaddata['model'],
1093                'color_texture': self.preloaddata['tex'],
1094                'materials': [shared.footing_material],
1095            },
1096        )
1097        self.bottom = ba.newnode(
1098            'terrain',
1099            attrs={
1100                'model': self.preloaddata['bottom_model'],
1101                'lighting': False,
1102                'color_texture': self.preloaddata['tex'],
1103            },
1104        )
1105        self.background = ba.newnode(
1106            'terrain',
1107            attrs={
1108                'model': self.preloaddata['bgmodel'],
1109                'lighting': False,
1110                'background': True,
1111                'color_texture': self.preloaddata['bgtex'],
1112            },
1113        )
1114        self.railing = ba.newnode(
1115            'terrain',
1116            attrs={
1117                'collide_model': self.preloaddata['railing_collide_model'],
1118                'materials': [shared.railing_material],
1119                'bumper': True,
1120            },
1121        )
1122        ba.newnode(
1123            'terrain',
1124            attrs={
1125                'model': self.preloaddata['vr_fill_mound_model'],
1126                'lighting': False,
1127                'vr_only': True,
1128                'color': (0.2, 0.25, 0.2),
1129                'background': True,
1130                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1131            },
1132        )
1133        gnode = ba.getactivity().globalsnode
1134        gnode.shadow_ortho = True
1135        gnode.shadow_offset = (0, 0, -5.0)
1136        gnode.tint = (1.15, 1.05, 0.75)
1137        gnode.ambient_color = (1.15, 1.05, 0.75)
1138        gnode.vignette_outer = (0.6, 0.65, 0.6)
1139        gnode.vignette_inner = (0.95, 0.95, 0.95)
1140        gnode.vr_near_clip = 1.0
1141
1142
1143class TowerD(ba.Map):
1144    """Map used for runaround mini-game."""
1145
1146    from bastd.mapdata import tower_d as defs
1147
1148    name = 'Tower D'
1149
1150    @classmethod
1151    def get_play_types(cls) -> list[str]:
1152        """Return valid play types for this map."""
1153        return []
1154
1155    @classmethod
1156    def get_preview_texture_name(cls) -> str:
1157        return 'towerDPreview'
1158
1159    @classmethod
1160    def on_preload(cls) -> Any:
1161        data: dict[str, Any] = {
1162            'model': ba.getmodel('towerDLevel'),
1163            'model_bottom': ba.getmodel('towerDLevelBottom'),
1164            'collide_model': ba.getcollidemodel('towerDLevelCollide'),
1165            'tex': ba.gettexture('towerDLevelColor'),
1166            'bgtex': ba.gettexture('menuBG'),
1167            'bgmodel': ba.getmodel('thePadBG'),
1168            'player_wall_collide_model': ba.getcollidemodel('towerDPlayerWall'),
1169            'player_wall_material': ba.Material(),
1170        }
1171        # fixme should chop this into vr/non-vr sections
1172        data['player_wall_material'].add_actions(
1173            actions=('modify_part_collision', 'friction', 0.0)
1174        )
1175        # anything that needs to hit the wall can apply this material
1176        data['collide_with_wall_material'] = ba.Material()
1177        data['player_wall_material'].add_actions(
1178            conditions=(
1179                'they_dont_have_material',
1180                data['collide_with_wall_material'],
1181            ),
1182            actions=('modify_part_collision', 'collide', False),
1183        )
1184        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1185        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1186        return data
1187
1188    def __init__(self) -> None:
1189        super().__init__(vr_overlay_offset=(0, 1, 1))
1190        shared = SharedObjects.get()
1191        self.node = ba.newnode(
1192            'terrain',
1193            delegate=self,
1194            attrs={
1195                'collide_model': self.preloaddata['collide_model'],
1196                'model': self.preloaddata['model'],
1197                'color_texture': self.preloaddata['tex'],
1198                'materials': [shared.footing_material],
1199            },
1200        )
1201        self.node_bottom = ba.newnode(
1202            'terrain',
1203            delegate=self,
1204            attrs={
1205                'model': self.preloaddata['model_bottom'],
1206                'lighting': False,
1207                'color_texture': self.preloaddata['tex'],
1208            },
1209        )
1210        ba.newnode(
1211            'terrain',
1212            attrs={
1213                'model': self.preloaddata['vr_fill_mound_model'],
1214                'lighting': False,
1215                'vr_only': True,
1216                'color': (0.53, 0.57, 0.5),
1217                'background': True,
1218                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1219            },
1220        )
1221        self.background = ba.newnode(
1222            'terrain',
1223            attrs={
1224                'model': self.preloaddata['bgmodel'],
1225                'lighting': False,
1226                'background': True,
1227                'color_texture': self.preloaddata['bgtex'],
1228            },
1229        )
1230        self.player_wall = ba.newnode(
1231            'terrain',
1232            attrs={
1233                'collide_model': self.preloaddata['player_wall_collide_model'],
1234                'affect_bg_dynamics': False,
1235                'materials': [self.preloaddata['player_wall_material']],
1236            },
1237        )
1238        gnode = ba.getactivity().globalsnode
1239        gnode.tint = (1.15, 1.11, 1.03)
1240        gnode.ambient_color = (1.2, 1.1, 1.0)
1241        gnode.vignette_outer = (0.7, 0.73, 0.7)
1242        gnode.vignette_inner = (0.95, 0.95, 0.95)
1243
1244    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1245        # see if we're within edge_box
1246        boxes = self.defs.boxes
1247        box_position = boxes['edge_box'][0:3]
1248        box_scale = boxes['edge_box'][6:9]
1249        box_position2 = boxes['edge_box2'][0:3]
1250        box_scale2 = boxes['edge_box2'][6:9]
1251        xpos = (point.x - box_position[0]) / box_scale[0]
1252        zpos = (point.z - box_position[2]) / box_scale[2]
1253        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1254        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1255        # if we're outside of *both* boxes we're near the edge
1256        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1257            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1258        )
1259
1260
1261class HappyThoughts(ba.Map):
1262    """Flying map."""
1263
1264    from bastd.mapdata import happy_thoughts as defs
1265
1266    name = 'Happy Thoughts'
1267
1268    @classmethod
1269    def get_play_types(cls) -> list[str]:
1270        """Return valid play types for this map."""
1271        return [
1272            'melee',
1273            'keep_away',
1274            'team_flag',
1275            'conquest',
1276            'king_of_the_hill',
1277        ]
1278
1279    @classmethod
1280    def get_preview_texture_name(cls) -> str:
1281        return 'alwaysLandPreview'
1282
1283    @classmethod
1284    def on_preload(cls) -> Any:
1285        data: dict[str, Any] = {
1286            'model': ba.getmodel('alwaysLandLevel'),
1287            'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
1288            'bgmodel': ba.getmodel('alwaysLandBG'),
1289            'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
1290            'tex': ba.gettexture('alwaysLandLevelColor'),
1291            'bgtex': ba.gettexture('alwaysLandBGColor'),
1292            'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
1293            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1294        }
1295        return data
1296
1297    @classmethod
1298    def get_music_type(cls) -> ba.MusicType:
1299        return ba.MusicType.FLYING
1300
1301    def __init__(self) -> None:
1302        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1303        shared = SharedObjects.get()
1304        self.node = ba.newnode(
1305            'terrain',
1306            delegate=self,
1307            attrs={
1308                'collide_model': self.preloaddata['collide_model'],
1309                'model': self.preloaddata['model'],
1310                'color_texture': self.preloaddata['tex'],
1311                'materials': [shared.footing_material],
1312            },
1313        )
1314        self.bottom = ba.newnode(
1315            'terrain',
1316            attrs={
1317                'model': self.preloaddata['bottom_model'],
1318                'lighting': False,
1319                'color_texture': self.preloaddata['tex'],
1320            },
1321        )
1322        self.background = ba.newnode(
1323            'terrain',
1324            attrs={
1325                'model': self.preloaddata['bgmodel'],
1326                'lighting': False,
1327                'background': True,
1328                'color_texture': self.preloaddata['bgtex'],
1329            },
1330        )
1331        ba.newnode(
1332            'terrain',
1333            attrs={
1334                'model': self.preloaddata['vr_fill_mound_model'],
1335                'lighting': False,
1336                'vr_only': True,
1337                'color': (0.2, 0.25, 0.2),
1338                'background': True,
1339                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1340            },
1341        )
1342        gnode = ba.getactivity().globalsnode
1343        gnode.happy_thoughts_mode = True
1344        gnode.shadow_offset = (0.0, 8.0, 5.0)
1345        gnode.tint = (1.3, 1.23, 1.0)
1346        gnode.ambient_color = (1.3, 1.23, 1.0)
1347        gnode.vignette_outer = (0.64, 0.59, 0.69)
1348        gnode.vignette_inner = (0.95, 0.95, 0.93)
1349        gnode.vr_near_clip = 1.0
1350        self.is_flying = True
1351
1352        # throw out some tips on flying
1353        txt = ba.newnode(
1354            'text',
1355            attrs={
1356                'text': ba.Lstr(resource='pressJumpToFlyText'),
1357                'scale': 1.2,
1358                'maxwidth': 800,
1359                'position': (0, 200),
1360                'shadow': 0.5,
1361                'flatness': 0.5,
1362                'h_align': 'center',
1363                'v_attach': 'bottom',
1364            },
1365        )
1366        cmb = ba.newnode(
1367            'combine',
1368            owner=txt,
1369            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1370        )
1371        ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1372        cmb.connectattr('output', txt, 'color')
1373        ba.timer(10.0, txt.delete)
1374
1375
1376class StepRightUp(ba.Map):
1377    """Wide stepped map good for CTF or Assault."""
1378
1379    from bastd.mapdata import step_right_up as defs
1380
1381    name = 'Step Right Up'
1382
1383    @classmethod
1384    def get_play_types(cls) -> list[str]:
1385        """Return valid play types for this map."""
1386        return ['melee', 'keep_away', 'team_flag', 'conquest']
1387
1388    @classmethod
1389    def get_preview_texture_name(cls) -> str:
1390        return 'stepRightUpPreview'
1391
1392    @classmethod
1393    def on_preload(cls) -> Any:
1394        data: dict[str, Any] = {
1395            'model': ba.getmodel('stepRightUpLevel'),
1396            'model_bottom': ba.getmodel('stepRightUpLevelBottom'),
1397            'collide_model': ba.getcollidemodel('stepRightUpLevelCollide'),
1398            'tex': ba.gettexture('stepRightUpLevelColor'),
1399            'bgtex': ba.gettexture('menuBG'),
1400            'bgmodel': ba.getmodel('thePadBG'),
1401            'vr_fill_mound_model': ba.getmodel('stepRightUpVRFillMound'),
1402            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1403        }
1404        # fixme should chop this into vr/non-vr chunks
1405        return data
1406
1407    def __init__(self) -> None:
1408        super().__init__(vr_overlay_offset=(0, -1, 2))
1409        shared = SharedObjects.get()
1410        self.node = ba.newnode(
1411            'terrain',
1412            delegate=self,
1413            attrs={
1414                'collide_model': self.preloaddata['collide_model'],
1415                'model': self.preloaddata['model'],
1416                'color_texture': self.preloaddata['tex'],
1417                'materials': [shared.footing_material],
1418            },
1419        )
1420        self.node_bottom = ba.newnode(
1421            'terrain',
1422            delegate=self,
1423            attrs={
1424                'model': self.preloaddata['model_bottom'],
1425                'lighting': False,
1426                'color_texture': self.preloaddata['tex'],
1427            },
1428        )
1429        ba.newnode(
1430            'terrain',
1431            attrs={
1432                'model': self.preloaddata['vr_fill_mound_model'],
1433                'lighting': False,
1434                'vr_only': True,
1435                'color': (0.53, 0.57, 0.5),
1436                'background': True,
1437                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1438            },
1439        )
1440        self.background = ba.newnode(
1441            'terrain',
1442            attrs={
1443                'model': self.preloaddata['bgmodel'],
1444                'lighting': False,
1445                'background': True,
1446                'color_texture': self.preloaddata['bgtex'],
1447            },
1448        )
1449        gnode = ba.getactivity().globalsnode
1450        gnode.tint = (1.2, 1.1, 1.0)
1451        gnode.ambient_color = (1.2, 1.1, 1.0)
1452        gnode.vignette_outer = (0.7, 0.65, 0.75)
1453        gnode.vignette_inner = (0.95, 0.95, 0.93)
1454
1455
1456class Courtyard(ba.Map):
1457    """A courtyard-ish looking map for co-op levels."""
1458
1459    from bastd.mapdata import courtyard as defs
1460
1461    name = 'Courtyard'
1462
1463    @classmethod
1464    def get_play_types(cls) -> list[str]:
1465        """Return valid play types for this map."""
1466        return ['melee', 'keep_away', 'team_flag']
1467
1468    @classmethod
1469    def get_preview_texture_name(cls) -> str:
1470        return 'courtyardPreview'
1471
1472    @classmethod
1473    def on_preload(cls) -> Any:
1474        data: dict[str, Any] = {
1475            'model': ba.getmodel('courtyardLevel'),
1476            'model_bottom': ba.getmodel('courtyardLevelBottom'),
1477            'collide_model': ba.getcollidemodel('courtyardLevelCollide'),
1478            'tex': ba.gettexture('courtyardLevelColor'),
1479            'bgtex': ba.gettexture('menuBG'),
1480            'bgmodel': ba.getmodel('thePadBG'),
1481            'player_wall_collide_model': (
1482                ba.getcollidemodel('courtyardPlayerWall')
1483            ),
1484            'player_wall_material': ba.Material(),
1485        }
1486        # FIXME: Chop this into vr and non-vr chunks.
1487        data['player_wall_material'].add_actions(
1488            actions=('modify_part_collision', 'friction', 0.0)
1489        )
1490        # anything that needs to hit the wall should apply this.
1491        data['collide_with_wall_material'] = ba.Material()
1492        data['player_wall_material'].add_actions(
1493            conditions=(
1494                'they_dont_have_material',
1495                data['collide_with_wall_material'],
1496            ),
1497            actions=('modify_part_collision', 'collide', False),
1498        )
1499        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1500        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1501        return data
1502
1503    def __init__(self) -> None:
1504        super().__init__()
1505        shared = SharedObjects.get()
1506        self.node = ba.newnode(
1507            'terrain',
1508            delegate=self,
1509            attrs={
1510                'collide_model': self.preloaddata['collide_model'],
1511                'model': self.preloaddata['model'],
1512                'color_texture': self.preloaddata['tex'],
1513                'materials': [shared.footing_material],
1514            },
1515        )
1516        self.background = ba.newnode(
1517            'terrain',
1518            attrs={
1519                'model': self.preloaddata['bgmodel'],
1520                'lighting': False,
1521                'background': True,
1522                'color_texture': self.preloaddata['bgtex'],
1523            },
1524        )
1525        self.bottom = ba.newnode(
1526            'terrain',
1527            attrs={
1528                'model': self.preloaddata['model_bottom'],
1529                'lighting': False,
1530                'color_texture': self.preloaddata['tex'],
1531            },
1532        )
1533        ba.newnode(
1534            'terrain',
1535            attrs={
1536                'model': self.preloaddata['vr_fill_mound_model'],
1537                'lighting': False,
1538                'vr_only': True,
1539                'color': (0.53, 0.57, 0.5),
1540                'background': True,
1541                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1542            },
1543        )
1544        # in co-op mode games, put up a wall to prevent players
1545        # from getting in the turrets (that would foil our brilliant AI)
1546        if isinstance(ba.getsession(), ba.CoopSession):
1547            cmodel = self.preloaddata['player_wall_collide_model']
1548            self.player_wall = ba.newnode(
1549                'terrain',
1550                attrs={
1551                    'collide_model': cmodel,
1552                    'affect_bg_dynamics': False,
1553                    'materials': [self.preloaddata['player_wall_material']],
1554                },
1555            )
1556        gnode = ba.getactivity().globalsnode
1557        gnode.tint = (1.2, 1.17, 1.1)
1558        gnode.ambient_color = (1.2, 1.17, 1.1)
1559        gnode.vignette_outer = (0.6, 0.6, 0.64)
1560        gnode.vignette_inner = (0.95, 0.95, 0.93)
1561
1562    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1563        # count anything off our ground level as safe (for our platforms)
1564        # see if we're within edge_box
1565        box_position = self.defs.boxes['edge_box'][0:3]
1566        box_scale = self.defs.boxes['edge_box'][6:9]
1567        xpos = (point.x - box_position[0]) / box_scale[0]
1568        zpos = (point.z - box_position[2]) / box_scale[2]
1569        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5
1570
1571
1572class Rampage(ba.Map):
1573    """Wee little map with ramps on the sides."""
1574
1575    from bastd.mapdata import rampage as defs
1576
1577    name = 'Rampage'
1578
1579    @classmethod
1580    def get_play_types(cls) -> list[str]:
1581        """Return valid play types for this map."""
1582        return ['melee', 'keep_away', 'team_flag']
1583
1584    @classmethod
1585    def get_preview_texture_name(cls) -> str:
1586        return 'rampagePreview'
1587
1588    @classmethod
1589    def on_preload(cls) -> Any:
1590        data: dict[str, Any] = {
1591            'model': ba.getmodel('rampageLevel'),
1592            'bottom_model': ba.getmodel('rampageLevelBottom'),
1593            'collide_model': ba.getcollidemodel('rampageLevelCollide'),
1594            'tex': ba.gettexture('rampageLevelColor'),
1595            'bgtex': ba.gettexture('rampageBGColor'),
1596            'bgtex2': ba.gettexture('rampageBGColor2'),
1597            'bgmodel': ba.getmodel('rampageBG'),
1598            'bgmodel2': ba.getmodel('rampageBG2'),
1599            'vr_fill_model': ba.getmodel('rampageVRFill'),
1600            'railing_collide_model': ba.getcollidemodel('rampageBumper'),
1601        }
1602        return data
1603
1604    def __init__(self) -> None:
1605        super().__init__(vr_overlay_offset=(0, 0, 2))
1606        shared = SharedObjects.get()
1607        self.node = ba.newnode(
1608            'terrain',
1609            delegate=self,
1610            attrs={
1611                'collide_model': self.preloaddata['collide_model'],
1612                'model': self.preloaddata['model'],
1613                'color_texture': self.preloaddata['tex'],
1614                'materials': [shared.footing_material],
1615            },
1616        )
1617        self.background = ba.newnode(
1618            'terrain',
1619            attrs={
1620                'model': self.preloaddata['bgmodel'],
1621                'lighting': False,
1622                'background': True,
1623                'color_texture': self.preloaddata['bgtex'],
1624            },
1625        )
1626        self.bottom = ba.newnode(
1627            'terrain',
1628            attrs={
1629                'model': self.preloaddata['bottom_model'],
1630                'lighting': False,
1631                'color_texture': self.preloaddata['tex'],
1632            },
1633        )
1634        self.bg2 = ba.newnode(
1635            'terrain',
1636            attrs={
1637                'model': self.preloaddata['bgmodel2'],
1638                'lighting': False,
1639                'background': True,
1640                'color_texture': self.preloaddata['bgtex2'],
1641            },
1642        )
1643        ba.newnode(
1644            'terrain',
1645            attrs={
1646                'model': self.preloaddata['vr_fill_model'],
1647                'lighting': False,
1648                'vr_only': True,
1649                'background': True,
1650                'color_texture': self.preloaddata['bgtex2'],
1651            },
1652        )
1653        self.railing = ba.newnode(
1654            'terrain',
1655            attrs={
1656                'collide_model': self.preloaddata['railing_collide_model'],
1657                'materials': [shared.railing_material],
1658                'bumper': True,
1659            },
1660        )
1661        gnode = ba.getactivity().globalsnode
1662        gnode.tint = (1.2, 1.1, 0.97)
1663        gnode.ambient_color = (1.3, 1.2, 1.03)
1664        gnode.vignette_outer = (0.62, 0.64, 0.69)
1665        gnode.vignette_inner = (0.97, 0.95, 0.93)
1666
1667    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1668        box_position = self.defs.boxes['edge_box'][0:3]
1669        box_scale = self.defs.boxes['edge_box'][6:9]
1670        xpos = (point.x - box_position[0]) / box_scale[0]
1671        zpos = (point.z - box_position[2]) / box_scale[2]
1672        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5
class HockeyStadium(ba._map.Map):
 18class HockeyStadium(ba.Map):
 19    """Stadium map used for ice hockey games."""
 20
 21    from bastd.mapdata import hockey_stadium as defs
 22
 23    name = 'Hockey Stadium'
 24
 25    @classmethod
 26    def get_play_types(cls) -> list[str]:
 27        """Return valid play types for this map."""
 28        return ['melee', 'hockey', 'team_flag', 'keep_away']
 29
 30    @classmethod
 31    def get_preview_texture_name(cls) -> str:
 32        return 'hockeyStadiumPreview'
 33
 34    @classmethod
 35    def on_preload(cls) -> Any:
 36        data: dict[str, Any] = {
 37            'models': (
 38                ba.getmodel('hockeyStadiumOuter'),
 39                ba.getmodel('hockeyStadiumInner'),
 40                ba.getmodel('hockeyStadiumStands'),
 41            ),
 42            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
 43            'collide_model': ba.getcollidemodel('hockeyStadiumCollide'),
 44            'tex': ba.gettexture('hockeyStadium'),
 45            'stands_tex': ba.gettexture('footballStadium'),
 46        }
 47        mat = ba.Material()
 48        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
 49        data['ice_material'] = mat
 50        return data
 51
 52    def __init__(self) -> None:
 53        super().__init__()
 54        shared = SharedObjects.get()
 55        self.node = ba.newnode(
 56            'terrain',
 57            delegate=self,
 58            attrs={
 59                'model': self.preloaddata['models'][0],
 60                'collide_model': self.preloaddata['collide_model'],
 61                'color_texture': self.preloaddata['tex'],
 62                'materials': [
 63                    shared.footing_material,
 64                    self.preloaddata['ice_material'],
 65                ],
 66            },
 67        )
 68        ba.newnode(
 69            'terrain',
 70            attrs={
 71                'model': self.preloaddata['vr_fill_model'],
 72                'vr_only': True,
 73                'lighting': False,
 74                'background': True,
 75                'color_texture': self.preloaddata['stands_tex'],
 76            },
 77        )
 78        mats = [shared.footing_material, self.preloaddata['ice_material']]
 79        self.floor = ba.newnode(
 80            'terrain',
 81            attrs={
 82                'model': self.preloaddata['models'][1],
 83                'color_texture': self.preloaddata['tex'],
 84                'opacity': 0.92,
 85                'opacity_in_low_or_medium_quality': 1.0,
 86                'materials': mats,
 87            },
 88        )
 89        self.stands = ba.newnode(
 90            'terrain',
 91            attrs={
 92                'model': self.preloaddata['models'][2],
 93                'visible_in_reflections': False,
 94                'color_texture': self.preloaddata['stands_tex'],
 95            },
 96        )
 97        gnode = ba.getactivity().globalsnode
 98        gnode.floor_reflection = True
 99        gnode.debris_friction = 0.3
100        gnode.debris_kill_height = -0.3
101        gnode.tint = (1.2, 1.3, 1.33)
102        gnode.ambient_color = (1.15, 1.25, 1.6)
103        gnode.vignette_outer = (0.66, 0.67, 0.73)
104        gnode.vignette_inner = (0.93, 0.93, 0.95)
105        gnode.vr_camera_offset = (0, -0.8, -1.1)
106        gnode.vr_near_clip = 0.5
107        self.is_hockey = True

Stadium map used for ice hockey games.

HockeyStadium()
 52    def __init__(self) -> None:
 53        super().__init__()
 54        shared = SharedObjects.get()
 55        self.node = ba.newnode(
 56            'terrain',
 57            delegate=self,
 58            attrs={
 59                'model': self.preloaddata['models'][0],
 60                'collide_model': self.preloaddata['collide_model'],
 61                'color_texture': self.preloaddata['tex'],
 62                'materials': [
 63                    shared.footing_material,
 64                    self.preloaddata['ice_material'],
 65                ],
 66            },
 67        )
 68        ba.newnode(
 69            'terrain',
 70            attrs={
 71                'model': self.preloaddata['vr_fill_model'],
 72                'vr_only': True,
 73                'lighting': False,
 74                'background': True,
 75                'color_texture': self.preloaddata['stands_tex'],
 76            },
 77        )
 78        mats = [shared.footing_material, self.preloaddata['ice_material']]
 79        self.floor = ba.newnode(
 80            'terrain',
 81            attrs={
 82                'model': self.preloaddata['models'][1],
 83                'color_texture': self.preloaddata['tex'],
 84                'opacity': 0.92,
 85                'opacity_in_low_or_medium_quality': 1.0,
 86                'materials': mats,
 87            },
 88        )
 89        self.stands = ba.newnode(
 90            'terrain',
 91            attrs={
 92                'model': self.preloaddata['models'][2],
 93                'visible_in_reflections': False,
 94                'color_texture': self.preloaddata['stands_tex'],
 95            },
 96        )
 97        gnode = ba.getactivity().globalsnode
 98        gnode.floor_reflection = True
 99        gnode.debris_friction = 0.3
100        gnode.debris_kill_height = -0.3
101        gnode.tint = (1.2, 1.3, 1.33)
102        gnode.ambient_color = (1.15, 1.25, 1.6)
103        gnode.vignette_outer = (0.66, 0.67, 0.73)
104        gnode.vignette_inner = (0.93, 0.93, 0.95)
105        gnode.vr_camera_offset = (0, -0.8, -1.1)
106        gnode.vr_near_clip = 0.5
107        self.is_hockey = True

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
25    @classmethod
26    def get_play_types(cls) -> list[str]:
27        """Return valid play types for this map."""
28        return ['melee', 'hockey', 'team_flag', 'keep_away']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
30    @classmethod
31    def get_preview_texture_name(cls) -> str:
32        return 'hockeyStadiumPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
34    @classmethod
35    def on_preload(cls) -> Any:
36        data: dict[str, Any] = {
37            'models': (
38                ba.getmodel('hockeyStadiumOuter'),
39                ba.getmodel('hockeyStadiumInner'),
40                ba.getmodel('hockeyStadiumStands'),
41            ),
42            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
43            'collide_model': ba.getcollidemodel('hockeyStadiumCollide'),
44            'tex': ba.gettexture('hockeyStadium'),
45            'stands_tex': ba.gettexture('footballStadium'),
46        }
47        mat = ba.Material()
48        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
49        data['ice_material'] = mat
50        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class FootballStadium(ba._map.Map):
110class FootballStadium(ba.Map):
111    """Stadium map for football games."""
112
113    from bastd.mapdata import football_stadium as defs
114
115    name = 'Football Stadium'
116
117    @classmethod
118    def get_play_types(cls) -> list[str]:
119        """Return valid play types for this map."""
120        return ['melee', 'football', 'team_flag', 'keep_away']
121
122    @classmethod
123    def get_preview_texture_name(cls) -> str:
124        return 'footballStadiumPreview'
125
126    @classmethod
127    def on_preload(cls) -> Any:
128        data: dict[str, Any] = {
129            'model': ba.getmodel('footballStadium'),
130            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
131            'collide_model': ba.getcollidemodel('footballStadiumCollide'),
132            'tex': ba.gettexture('footballStadium'),
133        }
134        return data
135
136    def __init__(self) -> None:
137        super().__init__()
138        shared = SharedObjects.get()
139        self.node = ba.newnode(
140            'terrain',
141            delegate=self,
142            attrs={
143                'model': self.preloaddata['model'],
144                'collide_model': self.preloaddata['collide_model'],
145                'color_texture': self.preloaddata['tex'],
146                'materials': [shared.footing_material],
147            },
148        )
149        ba.newnode(
150            'terrain',
151            attrs={
152                'model': self.preloaddata['vr_fill_model'],
153                'lighting': False,
154                'vr_only': True,
155                'background': True,
156                'color_texture': self.preloaddata['tex'],
157            },
158        )
159        gnode = ba.getactivity().globalsnode
160        gnode.tint = (1.3, 1.2, 1.0)
161        gnode.ambient_color = (1.3, 1.2, 1.0)
162        gnode.vignette_outer = (0.57, 0.57, 0.57)
163        gnode.vignette_inner = (0.9, 0.9, 0.9)
164        gnode.vr_camera_offset = (0, -0.8, -1.1)
165        gnode.vr_near_clip = 0.5
166
167    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
168        box_position = self.defs.boxes['edge_box'][0:3]
169        box_scale = self.defs.boxes['edge_box'][6:9]
170        xpos = (point.x - box_position[0]) / box_scale[0]
171        zpos = (point.z - box_position[2]) / box_scale[2]
172        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Stadium map for football games.

FootballStadium()
136    def __init__(self) -> None:
137        super().__init__()
138        shared = SharedObjects.get()
139        self.node = ba.newnode(
140            'terrain',
141            delegate=self,
142            attrs={
143                'model': self.preloaddata['model'],
144                'collide_model': self.preloaddata['collide_model'],
145                'color_texture': self.preloaddata['tex'],
146                'materials': [shared.footing_material],
147            },
148        )
149        ba.newnode(
150            'terrain',
151            attrs={
152                'model': self.preloaddata['vr_fill_model'],
153                'lighting': False,
154                'vr_only': True,
155                'background': True,
156                'color_texture': self.preloaddata['tex'],
157            },
158        )
159        gnode = ba.getactivity().globalsnode
160        gnode.tint = (1.3, 1.2, 1.0)
161        gnode.ambient_color = (1.3, 1.2, 1.0)
162        gnode.vignette_outer = (0.57, 0.57, 0.57)
163        gnode.vignette_inner = (0.9, 0.9, 0.9)
164        gnode.vr_camera_offset = (0, -0.8, -1.1)
165        gnode.vr_near_clip = 0.5

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
117    @classmethod
118    def get_play_types(cls) -> list[str]:
119        """Return valid play types for this map."""
120        return ['melee', 'football', 'team_flag', 'keep_away']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
122    @classmethod
123    def get_preview_texture_name(cls) -> str:
124        return 'footballStadiumPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
126    @classmethod
127    def on_preload(cls) -> Any:
128        data: dict[str, Any] = {
129            'model': ba.getmodel('footballStadium'),
130            'vr_fill_model': ba.getmodel('footballStadiumVRFill'),
131            'collide_model': ba.getcollidemodel('footballStadiumCollide'),
132            'tex': ba.gettexture('footballStadium'),
133        }
134        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

def is_point_near_edge(self, point: _ba.Vec3, running: bool = False) -> bool:
167    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
168        box_position = self.defs.boxes['edge_box'][0:3]
169        box_scale = self.defs.boxes['edge_box'][6:9]
170        xpos = (point.x - box_position[0]) / box_scale[0]
171        zpos = (point.z - box_position[2]) / box_scale[2]
172        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Return whether the provided point is near an edge of the map.

Simple bot logic uses this call to determine if they are approaching a cliff or wall. If this returns True they will generally not walk/run any farther away from the origin. If 'running' is True, the buffer should be a bit larger.

Inherited Members
ba._map.Map
preload
getname
get_music_type
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class Bridgit(ba._map.Map):
175class Bridgit(ba.Map):
176    """Map with a narrow bridge in the middle."""
177
178    from bastd.mapdata import bridgit as defs
179
180    name = 'Bridgit'
181    dataname = 'bridgit'
182
183    @classmethod
184    def get_play_types(cls) -> list[str]:
185        """Return valid play types for this map."""
186        # print('getting playtypes', cls._getdata()['play_types'])
187        return ['melee', 'team_flag', 'keep_away']
188
189    @classmethod
190    def get_preview_texture_name(cls) -> str:
191        return 'bridgitPreview'
192
193    @classmethod
194    def on_preload(cls) -> Any:
195        data: dict[str, Any] = {
196            'model_top': ba.getmodel('bridgitLevelTop'),
197            'model_bottom': ba.getmodel('bridgitLevelBottom'),
198            'model_bg': ba.getmodel('natureBackground'),
199            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
200            'collide_model': ba.getcollidemodel('bridgitLevelCollide'),
201            'tex': ba.gettexture('bridgitLevelColor'),
202            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
203            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
204            'railing_collide_model': (
205                ba.getcollidemodel('bridgitLevelRailingCollide')
206            ),
207            'bg_material': ba.Material(),
208        }
209        data['bg_material'].add_actions(
210            actions=('modify_part_collision', 'friction', 10.0)
211        )
212        return data
213
214    def __init__(self) -> None:
215        super().__init__()
216        shared = SharedObjects.get()
217        self.node = ba.newnode(
218            'terrain',
219            delegate=self,
220            attrs={
221                'collide_model': self.preloaddata['collide_model'],
222                'model': self.preloaddata['model_top'],
223                'color_texture': self.preloaddata['tex'],
224                'materials': [shared.footing_material],
225            },
226        )
227        self.bottom = ba.newnode(
228            'terrain',
229            attrs={
230                'model': self.preloaddata['model_bottom'],
231                'lighting': False,
232                'color_texture': self.preloaddata['tex'],
233            },
234        )
235        self.background = ba.newnode(
236            'terrain',
237            attrs={
238                'model': self.preloaddata['model_bg'],
239                'lighting': False,
240                'background': True,
241                'color_texture': self.preloaddata['model_bg_tex'],
242            },
243        )
244        ba.newnode(
245            'terrain',
246            attrs={
247                'model': self.preloaddata['bg_vr_fill_model'],
248                'lighting': False,
249                'vr_only': True,
250                'background': True,
251                'color_texture': self.preloaddata['model_bg_tex'],
252            },
253        )
254        self.railing = ba.newnode(
255            'terrain',
256            attrs={
257                'collide_model': self.preloaddata['railing_collide_model'],
258                'materials': [shared.railing_material],
259                'bumper': True,
260            },
261        )
262        self.bg_collide = ba.newnode(
263            'terrain',
264            attrs={
265                'collide_model': self.preloaddata['collide_bg'],
266                'materials': [
267                    shared.footing_material,
268                    self.preloaddata['bg_material'],
269                    shared.death_material,
270                ],
271            },
272        )
273        gnode = ba.getactivity().globalsnode
274        gnode.tint = (1.1, 1.2, 1.3)
275        gnode.ambient_color = (1.1, 1.2, 1.3)
276        gnode.vignette_outer = (0.65, 0.6, 0.55)
277        gnode.vignette_inner = (0.9, 0.9, 0.93)

Map with a narrow bridge in the middle.

Bridgit()
214    def __init__(self) -> None:
215        super().__init__()
216        shared = SharedObjects.get()
217        self.node = ba.newnode(
218            'terrain',
219            delegate=self,
220            attrs={
221                'collide_model': self.preloaddata['collide_model'],
222                'model': self.preloaddata['model_top'],
223                'color_texture': self.preloaddata['tex'],
224                'materials': [shared.footing_material],
225            },
226        )
227        self.bottom = ba.newnode(
228            'terrain',
229            attrs={
230                'model': self.preloaddata['model_bottom'],
231                'lighting': False,
232                'color_texture': self.preloaddata['tex'],
233            },
234        )
235        self.background = ba.newnode(
236            'terrain',
237            attrs={
238                'model': self.preloaddata['model_bg'],
239                'lighting': False,
240                'background': True,
241                'color_texture': self.preloaddata['model_bg_tex'],
242            },
243        )
244        ba.newnode(
245            'terrain',
246            attrs={
247                'model': self.preloaddata['bg_vr_fill_model'],
248                'lighting': False,
249                'vr_only': True,
250                'background': True,
251                'color_texture': self.preloaddata['model_bg_tex'],
252            },
253        )
254        self.railing = ba.newnode(
255            'terrain',
256            attrs={
257                'collide_model': self.preloaddata['railing_collide_model'],
258                'materials': [shared.railing_material],
259                'bumper': True,
260            },
261        )
262        self.bg_collide = ba.newnode(
263            'terrain',
264            attrs={
265                'collide_model': self.preloaddata['collide_bg'],
266                'materials': [
267                    shared.footing_material,
268                    self.preloaddata['bg_material'],
269                    shared.death_material,
270                ],
271            },
272        )
273        gnode = ba.getactivity().globalsnode
274        gnode.tint = (1.1, 1.2, 1.3)
275        gnode.ambient_color = (1.1, 1.2, 1.3)
276        gnode.vignette_outer = (0.65, 0.6, 0.55)
277        gnode.vignette_inner = (0.9, 0.9, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
183    @classmethod
184    def get_play_types(cls) -> list[str]:
185        """Return valid play types for this map."""
186        # print('getting playtypes', cls._getdata()['play_types'])
187        return ['melee', 'team_flag', 'keep_away']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
189    @classmethod
190    def get_preview_texture_name(cls) -> str:
191        return 'bridgitPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
193    @classmethod
194    def on_preload(cls) -> Any:
195        data: dict[str, Any] = {
196            'model_top': ba.getmodel('bridgitLevelTop'),
197            'model_bottom': ba.getmodel('bridgitLevelBottom'),
198            'model_bg': ba.getmodel('natureBackground'),
199            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
200            'collide_model': ba.getcollidemodel('bridgitLevelCollide'),
201            'tex': ba.gettexture('bridgitLevelColor'),
202            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
203            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
204            'railing_collide_model': (
205                ba.getcollidemodel('bridgitLevelRailingCollide')
206            ),
207            'bg_material': ba.Material(),
208        }
209        data['bg_material'].add_actions(
210            actions=('modify_part_collision', 'friction', 10.0)
211        )
212        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class BigG(ba._map.Map):
280class BigG(ba.Map):
281    """Large G shaped map for racing"""
282
283    from bastd.mapdata import big_g as defs
284
285    name = 'Big G'
286
287    @classmethod
288    def get_play_types(cls) -> list[str]:
289        """Return valid play types for this map."""
290        return [
291            'race',
292            'melee',
293            'keep_away',
294            'team_flag',
295            'king_of_the_hill',
296            'conquest',
297        ]
298
299    @classmethod
300    def get_preview_texture_name(cls) -> str:
301        return 'bigGPreview'
302
303    @classmethod
304    def on_preload(cls) -> Any:
305        data: dict[str, Any] = {
306            'model_top': ba.getmodel('bigG'),
307            'model_bottom': ba.getmodel('bigGBottom'),
308            'model_bg': ba.getmodel('natureBackground'),
309            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
310            'collide_model': ba.getcollidemodel('bigGCollide'),
311            'tex': ba.gettexture('bigG'),
312            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
313            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
314            'bumper_collide_model': ba.getcollidemodel('bigGBumper'),
315            'bg_material': ba.Material(),
316        }
317        data['bg_material'].add_actions(
318            actions=('modify_part_collision', 'friction', 10.0)
319        )
320        return data
321
322    def __init__(self) -> None:
323        super().__init__()
324        shared = SharedObjects.get()
325        self.node = ba.newnode(
326            'terrain',
327            delegate=self,
328            attrs={
329                'collide_model': self.preloaddata['collide_model'],
330                'color': (0.7, 0.7, 0.7),
331                'model': self.preloaddata['model_top'],
332                'color_texture': self.preloaddata['tex'],
333                'materials': [shared.footing_material],
334            },
335        )
336        self.bottom = ba.newnode(
337            'terrain',
338            attrs={
339                'model': self.preloaddata['model_bottom'],
340                'color': (0.7, 0.7, 0.7),
341                'lighting': False,
342                'color_texture': self.preloaddata['tex'],
343            },
344        )
345        self.background = ba.newnode(
346            'terrain',
347            attrs={
348                'model': self.preloaddata['model_bg'],
349                'lighting': False,
350                'background': True,
351                'color_texture': self.preloaddata['model_bg_tex'],
352            },
353        )
354        ba.newnode(
355            'terrain',
356            attrs={
357                'model': self.preloaddata['bg_vr_fill_model'],
358                'lighting': False,
359                'vr_only': True,
360                'background': True,
361                'color_texture': self.preloaddata['model_bg_tex'],
362            },
363        )
364        self.railing = ba.newnode(
365            'terrain',
366            attrs={
367                'collide_model': self.preloaddata['bumper_collide_model'],
368                'materials': [shared.railing_material],
369                'bumper': True,
370            },
371        )
372        self.bg_collide = ba.newnode(
373            'terrain',
374            attrs={
375                'collide_model': self.preloaddata['collide_bg'],
376                'materials': [
377                    shared.footing_material,
378                    self.preloaddata['bg_material'],
379                    shared.death_material,
380                ],
381            },
382        )
383        gnode = ba.getactivity().globalsnode
384        gnode.tint = (1.1, 1.2, 1.3)
385        gnode.ambient_color = (1.1, 1.2, 1.3)
386        gnode.vignette_outer = (0.65, 0.6, 0.55)
387        gnode.vignette_inner = (0.9, 0.9, 0.93)

Large G shaped map for racing

BigG()
322    def __init__(self) -> None:
323        super().__init__()
324        shared = SharedObjects.get()
325        self.node = ba.newnode(
326            'terrain',
327            delegate=self,
328            attrs={
329                'collide_model': self.preloaddata['collide_model'],
330                'color': (0.7, 0.7, 0.7),
331                'model': self.preloaddata['model_top'],
332                'color_texture': self.preloaddata['tex'],
333                'materials': [shared.footing_material],
334            },
335        )
336        self.bottom = ba.newnode(
337            'terrain',
338            attrs={
339                'model': self.preloaddata['model_bottom'],
340                'color': (0.7, 0.7, 0.7),
341                'lighting': False,
342                'color_texture': self.preloaddata['tex'],
343            },
344        )
345        self.background = ba.newnode(
346            'terrain',
347            attrs={
348                'model': self.preloaddata['model_bg'],
349                'lighting': False,
350                'background': True,
351                'color_texture': self.preloaddata['model_bg_tex'],
352            },
353        )
354        ba.newnode(
355            'terrain',
356            attrs={
357                'model': self.preloaddata['bg_vr_fill_model'],
358                'lighting': False,
359                'vr_only': True,
360                'background': True,
361                'color_texture': self.preloaddata['model_bg_tex'],
362            },
363        )
364        self.railing = ba.newnode(
365            'terrain',
366            attrs={
367                'collide_model': self.preloaddata['bumper_collide_model'],
368                'materials': [shared.railing_material],
369                'bumper': True,
370            },
371        )
372        self.bg_collide = ba.newnode(
373            'terrain',
374            attrs={
375                'collide_model': self.preloaddata['collide_bg'],
376                'materials': [
377                    shared.footing_material,
378                    self.preloaddata['bg_material'],
379                    shared.death_material,
380                ],
381            },
382        )
383        gnode = ba.getactivity().globalsnode
384        gnode.tint = (1.1, 1.2, 1.3)
385        gnode.ambient_color = (1.1, 1.2, 1.3)
386        gnode.vignette_outer = (0.65, 0.6, 0.55)
387        gnode.vignette_inner = (0.9, 0.9, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
287    @classmethod
288    def get_play_types(cls) -> list[str]:
289        """Return valid play types for this map."""
290        return [
291            'race',
292            'melee',
293            'keep_away',
294            'team_flag',
295            'king_of_the_hill',
296            'conquest',
297        ]

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
299    @classmethod
300    def get_preview_texture_name(cls) -> str:
301        return 'bigGPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
303    @classmethod
304    def on_preload(cls) -> Any:
305        data: dict[str, Any] = {
306            'model_top': ba.getmodel('bigG'),
307            'model_bottom': ba.getmodel('bigGBottom'),
308            'model_bg': ba.getmodel('natureBackground'),
309            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
310            'collide_model': ba.getcollidemodel('bigGCollide'),
311            'tex': ba.gettexture('bigG'),
312            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
313            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
314            'bumper_collide_model': ba.getcollidemodel('bigGBumper'),
315            'bg_material': ba.Material(),
316        }
317        data['bg_material'].add_actions(
318            actions=('modify_part_collision', 'friction', 10.0)
319        )
320        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class Roundabout(ba._map.Map):
390class Roundabout(ba.Map):
391    """CTF map featuring two platforms and a long way around between them"""
392
393    from bastd.mapdata import roundabout as defs
394
395    name = 'Roundabout'
396
397    @classmethod
398    def get_play_types(cls) -> list[str]:
399        """Return valid play types for this map."""
400        return ['melee', 'keep_away', 'team_flag']
401
402    @classmethod
403    def get_preview_texture_name(cls) -> str:
404        return 'roundaboutPreview'
405
406    @classmethod
407    def on_preload(cls) -> Any:
408        data: dict[str, Any] = {
409            'model': ba.getmodel('roundaboutLevel'),
410            'model_bottom': ba.getmodel('roundaboutLevelBottom'),
411            'model_bg': ba.getmodel('natureBackground'),
412            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
413            'collide_model': ba.getcollidemodel('roundaboutLevelCollide'),
414            'tex': ba.gettexture('roundaboutLevelColor'),
415            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
416            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
417            'railing_collide_model': (
418                ba.getcollidemodel('roundaboutLevelBumper')
419            ),
420            'bg_material': ba.Material(),
421        }
422        data['bg_material'].add_actions(
423            actions=('modify_part_collision', 'friction', 10.0)
424        )
425        return data
426
427    def __init__(self) -> None:
428        super().__init__(vr_overlay_offset=(0, -1, 1))
429        shared = SharedObjects.get()
430        self.node = ba.newnode(
431            'terrain',
432            delegate=self,
433            attrs={
434                'collide_model': self.preloaddata['collide_model'],
435                'model': self.preloaddata['model'],
436                'color_texture': self.preloaddata['tex'],
437                'materials': [shared.footing_material],
438            },
439        )
440        self.bottom = ba.newnode(
441            'terrain',
442            attrs={
443                'model': self.preloaddata['model_bottom'],
444                'lighting': False,
445                'color_texture': self.preloaddata['tex'],
446            },
447        )
448        self.background = ba.newnode(
449            'terrain',
450            attrs={
451                'model': self.preloaddata['model_bg'],
452                'lighting': False,
453                'background': True,
454                'color_texture': self.preloaddata['model_bg_tex'],
455            },
456        )
457        ba.newnode(
458            'terrain',
459            attrs={
460                'model': self.preloaddata['bg_vr_fill_model'],
461                'lighting': False,
462                'vr_only': True,
463                'background': True,
464                'color_texture': self.preloaddata['model_bg_tex'],
465            },
466        )
467        self.bg_collide = ba.newnode(
468            'terrain',
469            attrs={
470                'collide_model': self.preloaddata['collide_bg'],
471                'materials': [
472                    shared.footing_material,
473                    self.preloaddata['bg_material'],
474                    shared.death_material,
475                ],
476            },
477        )
478        self.railing = ba.newnode(
479            'terrain',
480            attrs={
481                'collide_model': self.preloaddata['railing_collide_model'],
482                'materials': [shared.railing_material],
483                'bumper': True,
484            },
485        )
486        gnode = ba.getactivity().globalsnode
487        gnode.tint = (1.0, 1.05, 1.1)
488        gnode.ambient_color = (1.0, 1.05, 1.1)
489        gnode.shadow_ortho = True
490        gnode.vignette_outer = (0.63, 0.65, 0.7)
491        gnode.vignette_inner = (0.97, 0.95, 0.93)

CTF map featuring two platforms and a long way around between them

Roundabout()
427    def __init__(self) -> None:
428        super().__init__(vr_overlay_offset=(0, -1, 1))
429        shared = SharedObjects.get()
430        self.node = ba.newnode(
431            'terrain',
432            delegate=self,
433            attrs={
434                'collide_model': self.preloaddata['collide_model'],
435                'model': self.preloaddata['model'],
436                'color_texture': self.preloaddata['tex'],
437                'materials': [shared.footing_material],
438            },
439        )
440        self.bottom = ba.newnode(
441            'terrain',
442            attrs={
443                'model': self.preloaddata['model_bottom'],
444                'lighting': False,
445                'color_texture': self.preloaddata['tex'],
446            },
447        )
448        self.background = ba.newnode(
449            'terrain',
450            attrs={
451                'model': self.preloaddata['model_bg'],
452                'lighting': False,
453                'background': True,
454                'color_texture': self.preloaddata['model_bg_tex'],
455            },
456        )
457        ba.newnode(
458            'terrain',
459            attrs={
460                'model': self.preloaddata['bg_vr_fill_model'],
461                'lighting': False,
462                'vr_only': True,
463                'background': True,
464                'color_texture': self.preloaddata['model_bg_tex'],
465            },
466        )
467        self.bg_collide = ba.newnode(
468            'terrain',
469            attrs={
470                'collide_model': self.preloaddata['collide_bg'],
471                'materials': [
472                    shared.footing_material,
473                    self.preloaddata['bg_material'],
474                    shared.death_material,
475                ],
476            },
477        )
478        self.railing = ba.newnode(
479            'terrain',
480            attrs={
481                'collide_model': self.preloaddata['railing_collide_model'],
482                'materials': [shared.railing_material],
483                'bumper': True,
484            },
485        )
486        gnode = ba.getactivity().globalsnode
487        gnode.tint = (1.0, 1.05, 1.1)
488        gnode.ambient_color = (1.0, 1.05, 1.1)
489        gnode.shadow_ortho = True
490        gnode.vignette_outer = (0.63, 0.65, 0.7)
491        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
397    @classmethod
398    def get_play_types(cls) -> list[str]:
399        """Return valid play types for this map."""
400        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
402    @classmethod
403    def get_preview_texture_name(cls) -> str:
404        return 'roundaboutPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
406    @classmethod
407    def on_preload(cls) -> Any:
408        data: dict[str, Any] = {
409            'model': ba.getmodel('roundaboutLevel'),
410            'model_bottom': ba.getmodel('roundaboutLevelBottom'),
411            'model_bg': ba.getmodel('natureBackground'),
412            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
413            'collide_model': ba.getcollidemodel('roundaboutLevelCollide'),
414            'tex': ba.gettexture('roundaboutLevelColor'),
415            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
416            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
417            'railing_collide_model': (
418                ba.getcollidemodel('roundaboutLevelBumper')
419            ),
420            'bg_material': ba.Material(),
421        }
422        data['bg_material'].add_actions(
423            actions=('modify_part_collision', 'friction', 10.0)
424        )
425        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class MonkeyFace(ba._map.Map):
494class MonkeyFace(ba.Map):
495    """Map sorta shaped like a monkey face; teehee!"""
496
497    from bastd.mapdata import monkey_face as defs
498
499    name = 'Monkey Face'
500
501    @classmethod
502    def get_play_types(cls) -> list[str]:
503        """Return valid play types for this map."""
504        return ['melee', 'keep_away', 'team_flag']
505
506    @classmethod
507    def get_preview_texture_name(cls) -> str:
508        return 'monkeyFacePreview'
509
510    @classmethod
511    def on_preload(cls) -> Any:
512        data: dict[str, Any] = {
513            'model': ba.getmodel('monkeyFaceLevel'),
514            'bottom_model': ba.getmodel('monkeyFaceLevelBottom'),
515            'model_bg': ba.getmodel('natureBackground'),
516            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
517            'collide_model': ba.getcollidemodel('monkeyFaceLevelCollide'),
518            'tex': ba.gettexture('monkeyFaceLevelColor'),
519            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
520            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
521            'railing_collide_model': (
522                ba.getcollidemodel('monkeyFaceLevelBumper')
523            ),
524            'bg_material': ba.Material(),
525        }
526        data['bg_material'].add_actions(
527            actions=('modify_part_collision', 'friction', 10.0)
528        )
529        return data
530
531    def __init__(self) -> None:
532        super().__init__()
533        shared = SharedObjects.get()
534        self.node = ba.newnode(
535            'terrain',
536            delegate=self,
537            attrs={
538                'collide_model': self.preloaddata['collide_model'],
539                'model': self.preloaddata['model'],
540                'color_texture': self.preloaddata['tex'],
541                'materials': [shared.footing_material],
542            },
543        )
544        self.bottom = ba.newnode(
545            'terrain',
546            attrs={
547                'model': self.preloaddata['bottom_model'],
548                'lighting': False,
549                'color_texture': self.preloaddata['tex'],
550            },
551        )
552        self.background = ba.newnode(
553            'terrain',
554            attrs={
555                'model': self.preloaddata['model_bg'],
556                'lighting': False,
557                'background': True,
558                'color_texture': self.preloaddata['model_bg_tex'],
559            },
560        )
561        ba.newnode(
562            'terrain',
563            attrs={
564                'model': self.preloaddata['bg_vr_fill_model'],
565                'lighting': False,
566                'vr_only': True,
567                'background': True,
568                'color_texture': self.preloaddata['model_bg_tex'],
569            },
570        )
571        self.bg_collide = ba.newnode(
572            'terrain',
573            attrs={
574                'collide_model': self.preloaddata['collide_bg'],
575                'materials': [
576                    shared.footing_material,
577                    self.preloaddata['bg_material'],
578                    shared.death_material,
579                ],
580            },
581        )
582        self.railing = ba.newnode(
583            'terrain',
584            attrs={
585                'collide_model': self.preloaddata['railing_collide_model'],
586                'materials': [shared.railing_material],
587                'bumper': True,
588            },
589        )
590        gnode = ba.getactivity().globalsnode
591        gnode.tint = (1.1, 1.2, 1.2)
592        gnode.ambient_color = (1.2, 1.3, 1.3)
593        gnode.vignette_outer = (0.60, 0.62, 0.66)
594        gnode.vignette_inner = (0.97, 0.95, 0.93)
595        gnode.vr_camera_offset = (-1.4, 0, 0)

Map sorta shaped like a monkey face; teehee!

MonkeyFace()
531    def __init__(self) -> None:
532        super().__init__()
533        shared = SharedObjects.get()
534        self.node = ba.newnode(
535            'terrain',
536            delegate=self,
537            attrs={
538                'collide_model': self.preloaddata['collide_model'],
539                'model': self.preloaddata['model'],
540                'color_texture': self.preloaddata['tex'],
541                'materials': [shared.footing_material],
542            },
543        )
544        self.bottom = ba.newnode(
545            'terrain',
546            attrs={
547                'model': self.preloaddata['bottom_model'],
548                'lighting': False,
549                'color_texture': self.preloaddata['tex'],
550            },
551        )
552        self.background = ba.newnode(
553            'terrain',
554            attrs={
555                'model': self.preloaddata['model_bg'],
556                'lighting': False,
557                'background': True,
558                'color_texture': self.preloaddata['model_bg_tex'],
559            },
560        )
561        ba.newnode(
562            'terrain',
563            attrs={
564                'model': self.preloaddata['bg_vr_fill_model'],
565                'lighting': False,
566                'vr_only': True,
567                'background': True,
568                'color_texture': self.preloaddata['model_bg_tex'],
569            },
570        )
571        self.bg_collide = ba.newnode(
572            'terrain',
573            attrs={
574                'collide_model': self.preloaddata['collide_bg'],
575                'materials': [
576                    shared.footing_material,
577                    self.preloaddata['bg_material'],
578                    shared.death_material,
579                ],
580            },
581        )
582        self.railing = ba.newnode(
583            'terrain',
584            attrs={
585                'collide_model': self.preloaddata['railing_collide_model'],
586                'materials': [shared.railing_material],
587                'bumper': True,
588            },
589        )
590        gnode = ba.getactivity().globalsnode
591        gnode.tint = (1.1, 1.2, 1.2)
592        gnode.ambient_color = (1.2, 1.3, 1.3)
593        gnode.vignette_outer = (0.60, 0.62, 0.66)
594        gnode.vignette_inner = (0.97, 0.95, 0.93)
595        gnode.vr_camera_offset = (-1.4, 0, 0)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
501    @classmethod
502    def get_play_types(cls) -> list[str]:
503        """Return valid play types for this map."""
504        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
506    @classmethod
507    def get_preview_texture_name(cls) -> str:
508        return 'monkeyFacePreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
510    @classmethod
511    def on_preload(cls) -> Any:
512        data: dict[str, Any] = {
513            'model': ba.getmodel('monkeyFaceLevel'),
514            'bottom_model': ba.getmodel('monkeyFaceLevelBottom'),
515            'model_bg': ba.getmodel('natureBackground'),
516            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
517            'collide_model': ba.getcollidemodel('monkeyFaceLevelCollide'),
518            'tex': ba.gettexture('monkeyFaceLevelColor'),
519            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
520            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
521            'railing_collide_model': (
522                ba.getcollidemodel('monkeyFaceLevelBumper')
523            ),
524            'bg_material': ba.Material(),
525        }
526        data['bg_material'].add_actions(
527            actions=('modify_part_collision', 'friction', 10.0)
528        )
529        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class ZigZag(ba._map.Map):
598class ZigZag(ba.Map):
599    """A very long zig-zaggy map"""
600
601    from bastd.mapdata import zig_zag as defs
602
603    name = 'Zigzag'
604
605    @classmethod
606    def get_play_types(cls) -> list[str]:
607        """Return valid play types for this map."""
608        return [
609            'melee',
610            'keep_away',
611            'team_flag',
612            'conquest',
613            'king_of_the_hill',
614        ]
615
616    @classmethod
617    def get_preview_texture_name(cls) -> str:
618        return 'zigzagPreview'
619
620    @classmethod
621    def on_preload(cls) -> Any:
622        data: dict[str, Any] = {
623            'model': ba.getmodel('zigZagLevel'),
624            'model_bottom': ba.getmodel('zigZagLevelBottom'),
625            'model_bg': ba.getmodel('natureBackground'),
626            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
627            'collide_model': ba.getcollidemodel('zigZagLevelCollide'),
628            'tex': ba.gettexture('zigZagLevelColor'),
629            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
630            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
631            'railing_collide_model': ba.getcollidemodel('zigZagLevelBumper'),
632            'bg_material': ba.Material(),
633        }
634        data['bg_material'].add_actions(
635            actions=('modify_part_collision', 'friction', 10.0)
636        )
637        return data
638
639    def __init__(self) -> None:
640        super().__init__()
641        shared = SharedObjects.get()
642        self.node = ba.newnode(
643            'terrain',
644            delegate=self,
645            attrs={
646                'collide_model': self.preloaddata['collide_model'],
647                'model': self.preloaddata['model'],
648                'color_texture': self.preloaddata['tex'],
649                'materials': [shared.footing_material],
650            },
651        )
652        self.background = ba.newnode(
653            'terrain',
654            attrs={
655                'model': self.preloaddata['model_bg'],
656                'lighting': False,
657                'color_texture': self.preloaddata['model_bg_tex'],
658            },
659        )
660        self.bottom = ba.newnode(
661            'terrain',
662            attrs={
663                'model': self.preloaddata['model_bottom'],
664                'lighting': False,
665                'color_texture': self.preloaddata['tex'],
666            },
667        )
668        ba.newnode(
669            'terrain',
670            attrs={
671                'model': self.preloaddata['bg_vr_fill_model'],
672                'lighting': False,
673                'vr_only': True,
674                'background': True,
675                'color_texture': self.preloaddata['model_bg_tex'],
676            },
677        )
678        self.bg_collide = ba.newnode(
679            'terrain',
680            attrs={
681                'collide_model': self.preloaddata['collide_bg'],
682                'materials': [
683                    shared.footing_material,
684                    self.preloaddata['bg_material'],
685                    shared.death_material,
686                ],
687            },
688        )
689        self.railing = ba.newnode(
690            'terrain',
691            attrs={
692                'collide_model': self.preloaddata['railing_collide_model'],
693                'materials': [shared.railing_material],
694                'bumper': True,
695            },
696        )
697        gnode = ba.getactivity().globalsnode
698        gnode.tint = (1.0, 1.15, 1.15)
699        gnode.ambient_color = (1.0, 1.15, 1.15)
700        gnode.vignette_outer = (0.57, 0.59, 0.63)
701        gnode.vignette_inner = (0.97, 0.95, 0.93)
702        gnode.vr_camera_offset = (-1.5, 0, 0)

A very long zig-zaggy map

ZigZag()
639    def __init__(self) -> None:
640        super().__init__()
641        shared = SharedObjects.get()
642        self.node = ba.newnode(
643            'terrain',
644            delegate=self,
645            attrs={
646                'collide_model': self.preloaddata['collide_model'],
647                'model': self.preloaddata['model'],
648                'color_texture': self.preloaddata['tex'],
649                'materials': [shared.footing_material],
650            },
651        )
652        self.background = ba.newnode(
653            'terrain',
654            attrs={
655                'model': self.preloaddata['model_bg'],
656                'lighting': False,
657                'color_texture': self.preloaddata['model_bg_tex'],
658            },
659        )
660        self.bottom = ba.newnode(
661            'terrain',
662            attrs={
663                'model': self.preloaddata['model_bottom'],
664                'lighting': False,
665                'color_texture': self.preloaddata['tex'],
666            },
667        )
668        ba.newnode(
669            'terrain',
670            attrs={
671                'model': self.preloaddata['bg_vr_fill_model'],
672                'lighting': False,
673                'vr_only': True,
674                'background': True,
675                'color_texture': self.preloaddata['model_bg_tex'],
676            },
677        )
678        self.bg_collide = ba.newnode(
679            'terrain',
680            attrs={
681                'collide_model': self.preloaddata['collide_bg'],
682                'materials': [
683                    shared.footing_material,
684                    self.preloaddata['bg_material'],
685                    shared.death_material,
686                ],
687            },
688        )
689        self.railing = ba.newnode(
690            'terrain',
691            attrs={
692                'collide_model': self.preloaddata['railing_collide_model'],
693                'materials': [shared.railing_material],
694                'bumper': True,
695            },
696        )
697        gnode = ba.getactivity().globalsnode
698        gnode.tint = (1.0, 1.15, 1.15)
699        gnode.ambient_color = (1.0, 1.15, 1.15)
700        gnode.vignette_outer = (0.57, 0.59, 0.63)
701        gnode.vignette_inner = (0.97, 0.95, 0.93)
702        gnode.vr_camera_offset = (-1.5, 0, 0)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
605    @classmethod
606    def get_play_types(cls) -> list[str]:
607        """Return valid play types for this map."""
608        return [
609            'melee',
610            'keep_away',
611            'team_flag',
612            'conquest',
613            'king_of_the_hill',
614        ]

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
616    @classmethod
617    def get_preview_texture_name(cls) -> str:
618        return 'zigzagPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
620    @classmethod
621    def on_preload(cls) -> Any:
622        data: dict[str, Any] = {
623            'model': ba.getmodel('zigZagLevel'),
624            'model_bottom': ba.getmodel('zigZagLevelBottom'),
625            'model_bg': ba.getmodel('natureBackground'),
626            'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
627            'collide_model': ba.getcollidemodel('zigZagLevelCollide'),
628            'tex': ba.gettexture('zigZagLevelColor'),
629            'model_bg_tex': ba.gettexture('natureBackgroundColor'),
630            'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
631            'railing_collide_model': ba.getcollidemodel('zigZagLevelBumper'),
632            'bg_material': ba.Material(),
633        }
634        data['bg_material'].add_actions(
635            actions=('modify_part_collision', 'friction', 10.0)
636        )
637        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class ThePad(ba._map.Map):
705class ThePad(ba.Map):
706    """A simple square shaped map with a raised edge."""
707
708    from bastd.mapdata import the_pad as defs
709
710    name = 'The Pad'
711
712    @classmethod
713    def get_play_types(cls) -> list[str]:
714        """Return valid play types for this map."""
715        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
716
717    @classmethod
718    def get_preview_texture_name(cls) -> str:
719        return 'thePadPreview'
720
721    @classmethod
722    def on_preload(cls) -> Any:
723        data: dict[str, Any] = {
724            'model': ba.getmodel('thePadLevel'),
725            'bottom_model': ba.getmodel('thePadLevelBottom'),
726            'collide_model': ba.getcollidemodel('thePadLevelCollide'),
727            'tex': ba.gettexture('thePadLevelColor'),
728            'bgtex': ba.gettexture('menuBG'),
729            'bgmodel': ba.getmodel('thePadBG'),
730            'railing_collide_model': ba.getcollidemodel('thePadLevelBumper'),
731            'vr_fill_mound_model': ba.getmodel('thePadVRFillMound'),
732            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
733        }
734        # fixme should chop this into vr/non-vr sections for efficiency
735        return data
736
737    def __init__(self) -> None:
738        super().__init__()
739        shared = SharedObjects.get()
740        self.node = ba.newnode(
741            'terrain',
742            delegate=self,
743            attrs={
744                'collide_model': self.preloaddata['collide_model'],
745                'model': self.preloaddata['model'],
746                'color_texture': self.preloaddata['tex'],
747                'materials': [shared.footing_material],
748            },
749        )
750        self.bottom = ba.newnode(
751            'terrain',
752            attrs={
753                'model': self.preloaddata['bottom_model'],
754                'lighting': False,
755                'color_texture': self.preloaddata['tex'],
756            },
757        )
758        self.background = ba.newnode(
759            'terrain',
760            attrs={
761                'model': self.preloaddata['bgmodel'],
762                'lighting': False,
763                'background': True,
764                'color_texture': self.preloaddata['bgtex'],
765            },
766        )
767        self.railing = ba.newnode(
768            'terrain',
769            attrs={
770                'collide_model': self.preloaddata['railing_collide_model'],
771                'materials': [shared.railing_material],
772                'bumper': True,
773            },
774        )
775        ba.newnode(
776            'terrain',
777            attrs={
778                'model': self.preloaddata['vr_fill_mound_model'],
779                'lighting': False,
780                'vr_only': True,
781                'color': (0.56, 0.55, 0.47),
782                'background': True,
783                'color_texture': self.preloaddata['vr_fill_mound_tex'],
784            },
785        )
786        gnode = ba.getactivity().globalsnode
787        gnode.tint = (1.1, 1.1, 1.0)
788        gnode.ambient_color = (1.1, 1.1, 1.0)
789        gnode.vignette_outer = (0.7, 0.65, 0.75)
790        gnode.vignette_inner = (0.95, 0.95, 0.93)

A simple square shaped map with a raised edge.

ThePad()
737    def __init__(self) -> None:
738        super().__init__()
739        shared = SharedObjects.get()
740        self.node = ba.newnode(
741            'terrain',
742            delegate=self,
743            attrs={
744                'collide_model': self.preloaddata['collide_model'],
745                'model': self.preloaddata['model'],
746                'color_texture': self.preloaddata['tex'],
747                'materials': [shared.footing_material],
748            },
749        )
750        self.bottom = ba.newnode(
751            'terrain',
752            attrs={
753                'model': self.preloaddata['bottom_model'],
754                'lighting': False,
755                'color_texture': self.preloaddata['tex'],
756            },
757        )
758        self.background = ba.newnode(
759            'terrain',
760            attrs={
761                'model': self.preloaddata['bgmodel'],
762                'lighting': False,
763                'background': True,
764                'color_texture': self.preloaddata['bgtex'],
765            },
766        )
767        self.railing = ba.newnode(
768            'terrain',
769            attrs={
770                'collide_model': self.preloaddata['railing_collide_model'],
771                'materials': [shared.railing_material],
772                'bumper': True,
773            },
774        )
775        ba.newnode(
776            'terrain',
777            attrs={
778                'model': self.preloaddata['vr_fill_mound_model'],
779                'lighting': False,
780                'vr_only': True,
781                'color': (0.56, 0.55, 0.47),
782                'background': True,
783                'color_texture': self.preloaddata['vr_fill_mound_tex'],
784            },
785        )
786        gnode = ba.getactivity().globalsnode
787        gnode.tint = (1.1, 1.1, 1.0)
788        gnode.ambient_color = (1.1, 1.1, 1.0)
789        gnode.vignette_outer = (0.7, 0.65, 0.75)
790        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
712    @classmethod
713    def get_play_types(cls) -> list[str]:
714        """Return valid play types for this map."""
715        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
717    @classmethod
718    def get_preview_texture_name(cls) -> str:
719        return 'thePadPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
721    @classmethod
722    def on_preload(cls) -> Any:
723        data: dict[str, Any] = {
724            'model': ba.getmodel('thePadLevel'),
725            'bottom_model': ba.getmodel('thePadLevelBottom'),
726            'collide_model': ba.getcollidemodel('thePadLevelCollide'),
727            'tex': ba.gettexture('thePadLevelColor'),
728            'bgtex': ba.gettexture('menuBG'),
729            'bgmodel': ba.getmodel('thePadBG'),
730            'railing_collide_model': ba.getcollidemodel('thePadLevelBumper'),
731            'vr_fill_mound_model': ba.getmodel('thePadVRFillMound'),
732            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
733        }
734        # fixme should chop this into vr/non-vr sections for efficiency
735        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class DoomShroom(ba._map.Map):
793class DoomShroom(ba.Map):
794    """A giant mushroom. Of doom!"""
795
796    from bastd.mapdata import doom_shroom as defs
797
798    name = 'Doom Shroom'
799
800    @classmethod
801    def get_play_types(cls) -> list[str]:
802        """Return valid play types for this map."""
803        return ['melee', 'keep_away', 'team_flag']
804
805    @classmethod
806    def get_preview_texture_name(cls) -> str:
807        return 'doomShroomPreview'
808
809    @classmethod
810    def on_preload(cls) -> Any:
811        data: dict[str, Any] = {
812            'model': ba.getmodel('doomShroomLevel'),
813            'collide_model': ba.getcollidemodel('doomShroomLevelCollide'),
814            'tex': ba.gettexture('doomShroomLevelColor'),
815            'bgtex': ba.gettexture('doomShroomBGColor'),
816            'bgmodel': ba.getmodel('doomShroomBG'),
817            'vr_fill_model': ba.getmodel('doomShroomVRFill'),
818            'stem_model': ba.getmodel('doomShroomStem'),
819            'collide_bg': ba.getcollidemodel('doomShroomStemCollide'),
820        }
821        return data
822
823    def __init__(self) -> None:
824        super().__init__()
825        shared = SharedObjects.get()
826        self.node = ba.newnode(
827            'terrain',
828            delegate=self,
829            attrs={
830                'collide_model': self.preloaddata['collide_model'],
831                'model': self.preloaddata['model'],
832                'color_texture': self.preloaddata['tex'],
833                'materials': [shared.footing_material],
834            },
835        )
836        self.background = ba.newnode(
837            'terrain',
838            attrs={
839                'model': self.preloaddata['bgmodel'],
840                'lighting': False,
841                'background': True,
842                'color_texture': self.preloaddata['bgtex'],
843            },
844        )
845        ba.newnode(
846            'terrain',
847            attrs={
848                'model': self.preloaddata['vr_fill_model'],
849                'lighting': False,
850                'vr_only': True,
851                'background': True,
852                'color_texture': self.preloaddata['bgtex'],
853            },
854        )
855        self.stem = ba.newnode(
856            'terrain',
857            attrs={
858                'model': self.preloaddata['stem_model'],
859                'lighting': False,
860                'color_texture': self.preloaddata['tex'],
861            },
862        )
863        self.bg_collide = ba.newnode(
864            'terrain',
865            attrs={
866                'collide_model': self.preloaddata['collide_bg'],
867                'materials': [shared.footing_material, shared.death_material],
868            },
869        )
870        gnode = ba.getactivity().globalsnode
871        gnode.tint = (0.82, 1.10, 1.15)
872        gnode.ambient_color = (0.9, 1.3, 1.1)
873        gnode.shadow_ortho = False
874        gnode.vignette_outer = (0.76, 0.76, 0.76)
875        gnode.vignette_inner = (0.95, 0.95, 0.99)
876
877    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
878        xpos = point.x
879        zpos = point.z
880        x_adj = xpos * 0.125
881        z_adj = (zpos + 3.7) * 0.2
882        if running:
883            x_adj *= 1.4
884            z_adj *= 1.4
885        return x_adj * x_adj + z_adj * z_adj > 1.0

A giant mushroom. Of doom!

DoomShroom()
823    def __init__(self) -> None:
824        super().__init__()
825        shared = SharedObjects.get()
826        self.node = ba.newnode(
827            'terrain',
828            delegate=self,
829            attrs={
830                'collide_model': self.preloaddata['collide_model'],
831                'model': self.preloaddata['model'],
832                'color_texture': self.preloaddata['tex'],
833                'materials': [shared.footing_material],
834            },
835        )
836        self.background = ba.newnode(
837            'terrain',
838            attrs={
839                'model': self.preloaddata['bgmodel'],
840                'lighting': False,
841                'background': True,
842                'color_texture': self.preloaddata['bgtex'],
843            },
844        )
845        ba.newnode(
846            'terrain',
847            attrs={
848                'model': self.preloaddata['vr_fill_model'],
849                'lighting': False,
850                'vr_only': True,
851                'background': True,
852                'color_texture': self.preloaddata['bgtex'],
853            },
854        )
855        self.stem = ba.newnode(
856            'terrain',
857            attrs={
858                'model': self.preloaddata['stem_model'],
859                'lighting': False,
860                'color_texture': self.preloaddata['tex'],
861            },
862        )
863        self.bg_collide = ba.newnode(
864            'terrain',
865            attrs={
866                'collide_model': self.preloaddata['collide_bg'],
867                'materials': [shared.footing_material, shared.death_material],
868            },
869        )
870        gnode = ba.getactivity().globalsnode
871        gnode.tint = (0.82, 1.10, 1.15)
872        gnode.ambient_color = (0.9, 1.3, 1.1)
873        gnode.shadow_ortho = False
874        gnode.vignette_outer = (0.76, 0.76, 0.76)
875        gnode.vignette_inner = (0.95, 0.95, 0.99)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
800    @classmethod
801    def get_play_types(cls) -> list[str]:
802        """Return valid play types for this map."""
803        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
805    @classmethod
806    def get_preview_texture_name(cls) -> str:
807        return 'doomShroomPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
809    @classmethod
810    def on_preload(cls) -> Any:
811        data: dict[str, Any] = {
812            'model': ba.getmodel('doomShroomLevel'),
813            'collide_model': ba.getcollidemodel('doomShroomLevelCollide'),
814            'tex': ba.gettexture('doomShroomLevelColor'),
815            'bgtex': ba.gettexture('doomShroomBGColor'),
816            'bgmodel': ba.getmodel('doomShroomBG'),
817            'vr_fill_model': ba.getmodel('doomShroomVRFill'),
818            'stem_model': ba.getmodel('doomShroomStem'),
819            'collide_bg': ba.getcollidemodel('doomShroomStemCollide'),
820        }
821        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

def is_point_near_edge(self, point: _ba.Vec3, running: bool = False) -> bool:
877    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
878        xpos = point.x
879        zpos = point.z
880        x_adj = xpos * 0.125
881        z_adj = (zpos + 3.7) * 0.2
882        if running:
883            x_adj *= 1.4
884            z_adj *= 1.4
885        return x_adj * x_adj + z_adj * z_adj > 1.0

Return whether the provided point is near an edge of the map.

Simple bot logic uses this call to determine if they are approaching a cliff or wall. If this returns True they will generally not walk/run any farther away from the origin. If 'running' is True, the buffer should be a bit larger.

Inherited Members
ba._map.Map
preload
getname
get_music_type
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class LakeFrigid(ba._map.Map):
888class LakeFrigid(ba.Map):
889    """An icy lake fit for racing."""
890
891    from bastd.mapdata import lake_frigid as defs
892
893    name = 'Lake Frigid'
894
895    @classmethod
896    def get_play_types(cls) -> list[str]:
897        """Return valid play types for this map."""
898        return ['melee', 'keep_away', 'team_flag', 'race']
899
900    @classmethod
901    def get_preview_texture_name(cls) -> str:
902        return 'lakeFrigidPreview'
903
904    @classmethod
905    def on_preload(cls) -> Any:
906        data: dict[str, Any] = {
907            'model': ba.getmodel('lakeFrigid'),
908            'model_top': ba.getmodel('lakeFrigidTop'),
909            'model_reflections': ba.getmodel('lakeFrigidReflections'),
910            'collide_model': ba.getcollidemodel('lakeFrigidCollide'),
911            'tex': ba.gettexture('lakeFrigid'),
912            'tex_reflections': ba.gettexture('lakeFrigidReflections'),
913            'vr_fill_model': ba.getmodel('lakeFrigidVRFill'),
914        }
915        mat = ba.Material()
916        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
917        data['ice_material'] = mat
918        return data
919
920    def __init__(self) -> None:
921        super().__init__()
922        shared = SharedObjects.get()
923        self.node = ba.newnode(
924            'terrain',
925            delegate=self,
926            attrs={
927                'collide_model': self.preloaddata['collide_model'],
928                'model': self.preloaddata['model'],
929                'color_texture': self.preloaddata['tex'],
930                'materials': [
931                    shared.footing_material,
932                    self.preloaddata['ice_material'],
933                ],
934            },
935        )
936        ba.newnode(
937            'terrain',
938            attrs={
939                'model': self.preloaddata['model_top'],
940                'lighting': False,
941                'color_texture': self.preloaddata['tex'],
942            },
943        )
944        ba.newnode(
945            'terrain',
946            attrs={
947                'model': self.preloaddata['model_reflections'],
948                'lighting': False,
949                'overlay': True,
950                'opacity': 0.15,
951                'color_texture': self.preloaddata['tex_reflections'],
952            },
953        )
954        ba.newnode(
955            'terrain',
956            attrs={
957                'model': self.preloaddata['vr_fill_model'],
958                'lighting': False,
959                'vr_only': True,
960                'background': True,
961                'color_texture': self.preloaddata['tex'],
962            },
963        )
964        gnode = ba.getactivity().globalsnode
965        gnode.tint = (1, 1, 1)
966        gnode.ambient_color = (1, 1, 1)
967        gnode.shadow_ortho = True
968        gnode.vignette_outer = (0.86, 0.86, 0.86)
969        gnode.vignette_inner = (0.95, 0.95, 0.99)
970        gnode.vr_near_clip = 0.5
971        self.is_hockey = True

An icy lake fit for racing.

LakeFrigid()
920    def __init__(self) -> None:
921        super().__init__()
922        shared = SharedObjects.get()
923        self.node = ba.newnode(
924            'terrain',
925            delegate=self,
926            attrs={
927                'collide_model': self.preloaddata['collide_model'],
928                'model': self.preloaddata['model'],
929                'color_texture': self.preloaddata['tex'],
930                'materials': [
931                    shared.footing_material,
932                    self.preloaddata['ice_material'],
933                ],
934            },
935        )
936        ba.newnode(
937            'terrain',
938            attrs={
939                'model': self.preloaddata['model_top'],
940                'lighting': False,
941                'color_texture': self.preloaddata['tex'],
942            },
943        )
944        ba.newnode(
945            'terrain',
946            attrs={
947                'model': self.preloaddata['model_reflections'],
948                'lighting': False,
949                'overlay': True,
950                'opacity': 0.15,
951                'color_texture': self.preloaddata['tex_reflections'],
952            },
953        )
954        ba.newnode(
955            'terrain',
956            attrs={
957                'model': self.preloaddata['vr_fill_model'],
958                'lighting': False,
959                'vr_only': True,
960                'background': True,
961                'color_texture': self.preloaddata['tex'],
962            },
963        )
964        gnode = ba.getactivity().globalsnode
965        gnode.tint = (1, 1, 1)
966        gnode.ambient_color = (1, 1, 1)
967        gnode.shadow_ortho = True
968        gnode.vignette_outer = (0.86, 0.86, 0.86)
969        gnode.vignette_inner = (0.95, 0.95, 0.99)
970        gnode.vr_near_clip = 0.5
971        self.is_hockey = True

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
895    @classmethod
896    def get_play_types(cls) -> list[str]:
897        """Return valid play types for this map."""
898        return ['melee', 'keep_away', 'team_flag', 'race']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
900    @classmethod
901    def get_preview_texture_name(cls) -> str:
902        return 'lakeFrigidPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
904    @classmethod
905    def on_preload(cls) -> Any:
906        data: dict[str, Any] = {
907            'model': ba.getmodel('lakeFrigid'),
908            'model_top': ba.getmodel('lakeFrigidTop'),
909            'model_reflections': ba.getmodel('lakeFrigidReflections'),
910            'collide_model': ba.getcollidemodel('lakeFrigidCollide'),
911            'tex': ba.gettexture('lakeFrigid'),
912            'tex_reflections': ba.gettexture('lakeFrigidReflections'),
913            'vr_fill_model': ba.getmodel('lakeFrigidVRFill'),
914        }
915        mat = ba.Material()
916        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
917        data['ice_material'] = mat
918        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class TipTop(ba._map.Map):
 974class TipTop(ba.Map):
 975    """A pointy map good for king-of-the-hill-ish games."""
 976
 977    from bastd.mapdata import tip_top as defs
 978
 979    name = 'Tip Top'
 980
 981    @classmethod
 982    def get_play_types(cls) -> list[str]:
 983        """Return valid play types for this map."""
 984        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
 985
 986    @classmethod
 987    def get_preview_texture_name(cls) -> str:
 988        return 'tipTopPreview'
 989
 990    @classmethod
 991    def on_preload(cls) -> Any:
 992        data: dict[str, Any] = {
 993            'model': ba.getmodel('tipTopLevel'),
 994            'bottom_model': ba.getmodel('tipTopLevelBottom'),
 995            'collide_model': ba.getcollidemodel('tipTopLevelCollide'),
 996            'tex': ba.gettexture('tipTopLevelColor'),
 997            'bgtex': ba.gettexture('tipTopBGColor'),
 998            'bgmodel': ba.getmodel('tipTopBG'),
 999            'railing_collide_model': ba.getcollidemodel('tipTopLevelBumper'),
1000        }
1001        return data
1002
1003    def __init__(self) -> None:
1004        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1005        shared = SharedObjects.get()
1006        self.node = ba.newnode(
1007            'terrain',
1008            delegate=self,
1009            attrs={
1010                'collide_model': self.preloaddata['collide_model'],
1011                'model': self.preloaddata['model'],
1012                'color_texture': self.preloaddata['tex'],
1013                'color': (0.7, 0.7, 0.7),
1014                'materials': [shared.footing_material],
1015            },
1016        )
1017        self.bottom = ba.newnode(
1018            'terrain',
1019            attrs={
1020                'model': self.preloaddata['bottom_model'],
1021                'lighting': False,
1022                'color': (0.7, 0.7, 0.7),
1023                'color_texture': self.preloaddata['tex'],
1024            },
1025        )
1026        self.background = ba.newnode(
1027            'terrain',
1028            attrs={
1029                'model': self.preloaddata['bgmodel'],
1030                'lighting': False,
1031                'color': (0.4, 0.4, 0.4),
1032                'background': True,
1033                'color_texture': self.preloaddata['bgtex'],
1034            },
1035        )
1036        self.railing = ba.newnode(
1037            'terrain',
1038            attrs={
1039                'collide_model': self.preloaddata['railing_collide_model'],
1040                'materials': [shared.railing_material],
1041                'bumper': True,
1042            },
1043        )
1044        gnode = ba.getactivity().globalsnode
1045        gnode.tint = (0.8, 0.9, 1.3)
1046        gnode.ambient_color = (0.8, 0.9, 1.3)
1047        gnode.vignette_outer = (0.79, 0.79, 0.69)
1048        gnode.vignette_inner = (0.97, 0.97, 0.99)

A pointy map good for king-of-the-hill-ish games.

TipTop()
1003    def __init__(self) -> None:
1004        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1005        shared = SharedObjects.get()
1006        self.node = ba.newnode(
1007            'terrain',
1008            delegate=self,
1009            attrs={
1010                'collide_model': self.preloaddata['collide_model'],
1011                'model': self.preloaddata['model'],
1012                'color_texture': self.preloaddata['tex'],
1013                'color': (0.7, 0.7, 0.7),
1014                'materials': [shared.footing_material],
1015            },
1016        )
1017        self.bottom = ba.newnode(
1018            'terrain',
1019            attrs={
1020                'model': self.preloaddata['bottom_model'],
1021                'lighting': False,
1022                'color': (0.7, 0.7, 0.7),
1023                'color_texture': self.preloaddata['tex'],
1024            },
1025        )
1026        self.background = ba.newnode(
1027            'terrain',
1028            attrs={
1029                'model': self.preloaddata['bgmodel'],
1030                'lighting': False,
1031                'color': (0.4, 0.4, 0.4),
1032                'background': True,
1033                'color_texture': self.preloaddata['bgtex'],
1034            },
1035        )
1036        self.railing = ba.newnode(
1037            'terrain',
1038            attrs={
1039                'collide_model': self.preloaddata['railing_collide_model'],
1040                'materials': [shared.railing_material],
1041                'bumper': True,
1042            },
1043        )
1044        gnode = ba.getactivity().globalsnode
1045        gnode.tint = (0.8, 0.9, 1.3)
1046        gnode.ambient_color = (0.8, 0.9, 1.3)
1047        gnode.vignette_outer = (0.79, 0.79, 0.69)
1048        gnode.vignette_inner = (0.97, 0.97, 0.99)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
981    @classmethod
982    def get_play_types(cls) -> list[str]:
983        """Return valid play types for this map."""
984        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
986    @classmethod
987    def get_preview_texture_name(cls) -> str:
988        return 'tipTopPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
 990    @classmethod
 991    def on_preload(cls) -> Any:
 992        data: dict[str, Any] = {
 993            'model': ba.getmodel('tipTopLevel'),
 994            'bottom_model': ba.getmodel('tipTopLevelBottom'),
 995            'collide_model': ba.getcollidemodel('tipTopLevelCollide'),
 996            'tex': ba.gettexture('tipTopLevelColor'),
 997            'bgtex': ba.gettexture('tipTopBGColor'),
 998            'bgmodel': ba.getmodel('tipTopBG'),
 999            'railing_collide_model': ba.getcollidemodel('tipTopLevelBumper'),
1000        }
1001        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class CragCastle(ba._map.Map):
1051class CragCastle(ba.Map):
1052    """A lovely castle map."""
1053
1054    from bastd.mapdata import crag_castle as defs
1055
1056    name = 'Crag Castle'
1057
1058    @classmethod
1059    def get_play_types(cls) -> list[str]:
1060        """Return valid play types for this map."""
1061        return ['melee', 'keep_away', 'team_flag', 'conquest']
1062
1063    @classmethod
1064    def get_preview_texture_name(cls) -> str:
1065        return 'cragCastlePreview'
1066
1067    @classmethod
1068    def on_preload(cls) -> Any:
1069        data: dict[str, Any] = {
1070            'model': ba.getmodel('cragCastleLevel'),
1071            'bottom_model': ba.getmodel('cragCastleLevelBottom'),
1072            'collide_model': ba.getcollidemodel('cragCastleLevelCollide'),
1073            'tex': ba.gettexture('cragCastleLevelColor'),
1074            'bgtex': ba.gettexture('menuBG'),
1075            'bgmodel': ba.getmodel('thePadBG'),
1076            'railing_collide_model': (
1077                ba.getcollidemodel('cragCastleLevelBumper')
1078            ),
1079            'vr_fill_mound_model': ba.getmodel('cragCastleVRFillMound'),
1080            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1081        }
1082        # fixme should chop this into vr/non-vr sections
1083        return data
1084
1085    def __init__(self) -> None:
1086        super().__init__()
1087        shared = SharedObjects.get()
1088        self.node = ba.newnode(
1089            'terrain',
1090            delegate=self,
1091            attrs={
1092                'collide_model': self.preloaddata['collide_model'],
1093                'model': self.preloaddata['model'],
1094                'color_texture': self.preloaddata['tex'],
1095                'materials': [shared.footing_material],
1096            },
1097        )
1098        self.bottom = ba.newnode(
1099            'terrain',
1100            attrs={
1101                'model': self.preloaddata['bottom_model'],
1102                'lighting': False,
1103                'color_texture': self.preloaddata['tex'],
1104            },
1105        )
1106        self.background = ba.newnode(
1107            'terrain',
1108            attrs={
1109                'model': self.preloaddata['bgmodel'],
1110                'lighting': False,
1111                'background': True,
1112                'color_texture': self.preloaddata['bgtex'],
1113            },
1114        )
1115        self.railing = ba.newnode(
1116            'terrain',
1117            attrs={
1118                'collide_model': self.preloaddata['railing_collide_model'],
1119                'materials': [shared.railing_material],
1120                'bumper': True,
1121            },
1122        )
1123        ba.newnode(
1124            'terrain',
1125            attrs={
1126                'model': self.preloaddata['vr_fill_mound_model'],
1127                'lighting': False,
1128                'vr_only': True,
1129                'color': (0.2, 0.25, 0.2),
1130                'background': True,
1131                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1132            },
1133        )
1134        gnode = ba.getactivity().globalsnode
1135        gnode.shadow_ortho = True
1136        gnode.shadow_offset = (0, 0, -5.0)
1137        gnode.tint = (1.15, 1.05, 0.75)
1138        gnode.ambient_color = (1.15, 1.05, 0.75)
1139        gnode.vignette_outer = (0.6, 0.65, 0.6)
1140        gnode.vignette_inner = (0.95, 0.95, 0.95)
1141        gnode.vr_near_clip = 1.0

A lovely castle map.

CragCastle()
1085    def __init__(self) -> None:
1086        super().__init__()
1087        shared = SharedObjects.get()
1088        self.node = ba.newnode(
1089            'terrain',
1090            delegate=self,
1091            attrs={
1092                'collide_model': self.preloaddata['collide_model'],
1093                'model': self.preloaddata['model'],
1094                'color_texture': self.preloaddata['tex'],
1095                'materials': [shared.footing_material],
1096            },
1097        )
1098        self.bottom = ba.newnode(
1099            'terrain',
1100            attrs={
1101                'model': self.preloaddata['bottom_model'],
1102                'lighting': False,
1103                'color_texture': self.preloaddata['tex'],
1104            },
1105        )
1106        self.background = ba.newnode(
1107            'terrain',
1108            attrs={
1109                'model': self.preloaddata['bgmodel'],
1110                'lighting': False,
1111                'background': True,
1112                'color_texture': self.preloaddata['bgtex'],
1113            },
1114        )
1115        self.railing = ba.newnode(
1116            'terrain',
1117            attrs={
1118                'collide_model': self.preloaddata['railing_collide_model'],
1119                'materials': [shared.railing_material],
1120                'bumper': True,
1121            },
1122        )
1123        ba.newnode(
1124            'terrain',
1125            attrs={
1126                'model': self.preloaddata['vr_fill_mound_model'],
1127                'lighting': False,
1128                'vr_only': True,
1129                'color': (0.2, 0.25, 0.2),
1130                'background': True,
1131                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1132            },
1133        )
1134        gnode = ba.getactivity().globalsnode
1135        gnode.shadow_ortho = True
1136        gnode.shadow_offset = (0, 0, -5.0)
1137        gnode.tint = (1.15, 1.05, 0.75)
1138        gnode.ambient_color = (1.15, 1.05, 0.75)
1139        gnode.vignette_outer = (0.6, 0.65, 0.6)
1140        gnode.vignette_inner = (0.95, 0.95, 0.95)
1141        gnode.vr_near_clip = 1.0

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1058    @classmethod
1059    def get_play_types(cls) -> list[str]:
1060        """Return valid play types for this map."""
1061        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1063    @classmethod
1064    def get_preview_texture_name(cls) -> str:
1065        return 'cragCastlePreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1067    @classmethod
1068    def on_preload(cls) -> Any:
1069        data: dict[str, Any] = {
1070            'model': ba.getmodel('cragCastleLevel'),
1071            'bottom_model': ba.getmodel('cragCastleLevelBottom'),
1072            'collide_model': ba.getcollidemodel('cragCastleLevelCollide'),
1073            'tex': ba.gettexture('cragCastleLevelColor'),
1074            'bgtex': ba.gettexture('menuBG'),
1075            'bgmodel': ba.getmodel('thePadBG'),
1076            'railing_collide_model': (
1077                ba.getcollidemodel('cragCastleLevelBumper')
1078            ),
1079            'vr_fill_mound_model': ba.getmodel('cragCastleVRFillMound'),
1080            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1081        }
1082        # fixme should chop this into vr/non-vr sections
1083        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class TowerD(ba._map.Map):
1144class TowerD(ba.Map):
1145    """Map used for runaround mini-game."""
1146
1147    from bastd.mapdata import tower_d as defs
1148
1149    name = 'Tower D'
1150
1151    @classmethod
1152    def get_play_types(cls) -> list[str]:
1153        """Return valid play types for this map."""
1154        return []
1155
1156    @classmethod
1157    def get_preview_texture_name(cls) -> str:
1158        return 'towerDPreview'
1159
1160    @classmethod
1161    def on_preload(cls) -> Any:
1162        data: dict[str, Any] = {
1163            'model': ba.getmodel('towerDLevel'),
1164            'model_bottom': ba.getmodel('towerDLevelBottom'),
1165            'collide_model': ba.getcollidemodel('towerDLevelCollide'),
1166            'tex': ba.gettexture('towerDLevelColor'),
1167            'bgtex': ba.gettexture('menuBG'),
1168            'bgmodel': ba.getmodel('thePadBG'),
1169            'player_wall_collide_model': ba.getcollidemodel('towerDPlayerWall'),
1170            'player_wall_material': ba.Material(),
1171        }
1172        # fixme should chop this into vr/non-vr sections
1173        data['player_wall_material'].add_actions(
1174            actions=('modify_part_collision', 'friction', 0.0)
1175        )
1176        # anything that needs to hit the wall can apply this material
1177        data['collide_with_wall_material'] = ba.Material()
1178        data['player_wall_material'].add_actions(
1179            conditions=(
1180                'they_dont_have_material',
1181                data['collide_with_wall_material'],
1182            ),
1183            actions=('modify_part_collision', 'collide', False),
1184        )
1185        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1186        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1187        return data
1188
1189    def __init__(self) -> None:
1190        super().__init__(vr_overlay_offset=(0, 1, 1))
1191        shared = SharedObjects.get()
1192        self.node = ba.newnode(
1193            'terrain',
1194            delegate=self,
1195            attrs={
1196                'collide_model': self.preloaddata['collide_model'],
1197                'model': self.preloaddata['model'],
1198                'color_texture': self.preloaddata['tex'],
1199                'materials': [shared.footing_material],
1200            },
1201        )
1202        self.node_bottom = ba.newnode(
1203            'terrain',
1204            delegate=self,
1205            attrs={
1206                'model': self.preloaddata['model_bottom'],
1207                'lighting': False,
1208                'color_texture': self.preloaddata['tex'],
1209            },
1210        )
1211        ba.newnode(
1212            'terrain',
1213            attrs={
1214                'model': self.preloaddata['vr_fill_mound_model'],
1215                'lighting': False,
1216                'vr_only': True,
1217                'color': (0.53, 0.57, 0.5),
1218                'background': True,
1219                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1220            },
1221        )
1222        self.background = ba.newnode(
1223            'terrain',
1224            attrs={
1225                'model': self.preloaddata['bgmodel'],
1226                'lighting': False,
1227                'background': True,
1228                'color_texture': self.preloaddata['bgtex'],
1229            },
1230        )
1231        self.player_wall = ba.newnode(
1232            'terrain',
1233            attrs={
1234                'collide_model': self.preloaddata['player_wall_collide_model'],
1235                'affect_bg_dynamics': False,
1236                'materials': [self.preloaddata['player_wall_material']],
1237            },
1238        )
1239        gnode = ba.getactivity().globalsnode
1240        gnode.tint = (1.15, 1.11, 1.03)
1241        gnode.ambient_color = (1.2, 1.1, 1.0)
1242        gnode.vignette_outer = (0.7, 0.73, 0.7)
1243        gnode.vignette_inner = (0.95, 0.95, 0.95)
1244
1245    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1246        # see if we're within edge_box
1247        boxes = self.defs.boxes
1248        box_position = boxes['edge_box'][0:3]
1249        box_scale = boxes['edge_box'][6:9]
1250        box_position2 = boxes['edge_box2'][0:3]
1251        box_scale2 = boxes['edge_box2'][6:9]
1252        xpos = (point.x - box_position[0]) / box_scale[0]
1253        zpos = (point.z - box_position[2]) / box_scale[2]
1254        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1255        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1256        # if we're outside of *both* boxes we're near the edge
1257        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1258            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1259        )

Map used for runaround mini-game.

TowerD()
1189    def __init__(self) -> None:
1190        super().__init__(vr_overlay_offset=(0, 1, 1))
1191        shared = SharedObjects.get()
1192        self.node = ba.newnode(
1193            'terrain',
1194            delegate=self,
1195            attrs={
1196                'collide_model': self.preloaddata['collide_model'],
1197                'model': self.preloaddata['model'],
1198                'color_texture': self.preloaddata['tex'],
1199                'materials': [shared.footing_material],
1200            },
1201        )
1202        self.node_bottom = ba.newnode(
1203            'terrain',
1204            delegate=self,
1205            attrs={
1206                'model': self.preloaddata['model_bottom'],
1207                'lighting': False,
1208                'color_texture': self.preloaddata['tex'],
1209            },
1210        )
1211        ba.newnode(
1212            'terrain',
1213            attrs={
1214                'model': self.preloaddata['vr_fill_mound_model'],
1215                'lighting': False,
1216                'vr_only': True,
1217                'color': (0.53, 0.57, 0.5),
1218                'background': True,
1219                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1220            },
1221        )
1222        self.background = ba.newnode(
1223            'terrain',
1224            attrs={
1225                'model': self.preloaddata['bgmodel'],
1226                'lighting': False,
1227                'background': True,
1228                'color_texture': self.preloaddata['bgtex'],
1229            },
1230        )
1231        self.player_wall = ba.newnode(
1232            'terrain',
1233            attrs={
1234                'collide_model': self.preloaddata['player_wall_collide_model'],
1235                'affect_bg_dynamics': False,
1236                'materials': [self.preloaddata['player_wall_material']],
1237            },
1238        )
1239        gnode = ba.getactivity().globalsnode
1240        gnode.tint = (1.15, 1.11, 1.03)
1241        gnode.ambient_color = (1.2, 1.1, 1.0)
1242        gnode.vignette_outer = (0.7, 0.73, 0.7)
1243        gnode.vignette_inner = (0.95, 0.95, 0.95)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1151    @classmethod
1152    def get_play_types(cls) -> list[str]:
1153        """Return valid play types for this map."""
1154        return []

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1156    @classmethod
1157    def get_preview_texture_name(cls) -> str:
1158        return 'towerDPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1160    @classmethod
1161    def on_preload(cls) -> Any:
1162        data: dict[str, Any] = {
1163            'model': ba.getmodel('towerDLevel'),
1164            'model_bottom': ba.getmodel('towerDLevelBottom'),
1165            'collide_model': ba.getcollidemodel('towerDLevelCollide'),
1166            'tex': ba.gettexture('towerDLevelColor'),
1167            'bgtex': ba.gettexture('menuBG'),
1168            'bgmodel': ba.getmodel('thePadBG'),
1169            'player_wall_collide_model': ba.getcollidemodel('towerDPlayerWall'),
1170            'player_wall_material': ba.Material(),
1171        }
1172        # fixme should chop this into vr/non-vr sections
1173        data['player_wall_material'].add_actions(
1174            actions=('modify_part_collision', 'friction', 0.0)
1175        )
1176        # anything that needs to hit the wall can apply this material
1177        data['collide_with_wall_material'] = ba.Material()
1178        data['player_wall_material'].add_actions(
1179            conditions=(
1180                'they_dont_have_material',
1181                data['collide_with_wall_material'],
1182            ),
1183            actions=('modify_part_collision', 'collide', False),
1184        )
1185        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1186        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1187        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

def is_point_near_edge(self, point: _ba.Vec3, running: bool = False) -> bool:
1245    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1246        # see if we're within edge_box
1247        boxes = self.defs.boxes
1248        box_position = boxes['edge_box'][0:3]
1249        box_scale = boxes['edge_box'][6:9]
1250        box_position2 = boxes['edge_box2'][0:3]
1251        box_scale2 = boxes['edge_box2'][6:9]
1252        xpos = (point.x - box_position[0]) / box_scale[0]
1253        zpos = (point.z - box_position[2]) / box_scale[2]
1254        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1255        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1256        # if we're outside of *both* boxes we're near the edge
1257        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1258            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1259        )

Return whether the provided point is near an edge of the map.

Simple bot logic uses this call to determine if they are approaching a cliff or wall. If this returns True they will generally not walk/run any farther away from the origin. If 'running' is True, the buffer should be a bit larger.

Inherited Members
ba._map.Map
preload
getname
get_music_type
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class HappyThoughts(ba._map.Map):
1262class HappyThoughts(ba.Map):
1263    """Flying map."""
1264
1265    from bastd.mapdata import happy_thoughts as defs
1266
1267    name = 'Happy Thoughts'
1268
1269    @classmethod
1270    def get_play_types(cls) -> list[str]:
1271        """Return valid play types for this map."""
1272        return [
1273            'melee',
1274            'keep_away',
1275            'team_flag',
1276            'conquest',
1277            'king_of_the_hill',
1278        ]
1279
1280    @classmethod
1281    def get_preview_texture_name(cls) -> str:
1282        return 'alwaysLandPreview'
1283
1284    @classmethod
1285    def on_preload(cls) -> Any:
1286        data: dict[str, Any] = {
1287            'model': ba.getmodel('alwaysLandLevel'),
1288            'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
1289            'bgmodel': ba.getmodel('alwaysLandBG'),
1290            'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
1291            'tex': ba.gettexture('alwaysLandLevelColor'),
1292            'bgtex': ba.gettexture('alwaysLandBGColor'),
1293            'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
1294            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1295        }
1296        return data
1297
1298    @classmethod
1299    def get_music_type(cls) -> ba.MusicType:
1300        return ba.MusicType.FLYING
1301
1302    def __init__(self) -> None:
1303        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1304        shared = SharedObjects.get()
1305        self.node = ba.newnode(
1306            'terrain',
1307            delegate=self,
1308            attrs={
1309                'collide_model': self.preloaddata['collide_model'],
1310                'model': self.preloaddata['model'],
1311                'color_texture': self.preloaddata['tex'],
1312                'materials': [shared.footing_material],
1313            },
1314        )
1315        self.bottom = ba.newnode(
1316            'terrain',
1317            attrs={
1318                'model': self.preloaddata['bottom_model'],
1319                'lighting': False,
1320                'color_texture': self.preloaddata['tex'],
1321            },
1322        )
1323        self.background = ba.newnode(
1324            'terrain',
1325            attrs={
1326                'model': self.preloaddata['bgmodel'],
1327                'lighting': False,
1328                'background': True,
1329                'color_texture': self.preloaddata['bgtex'],
1330            },
1331        )
1332        ba.newnode(
1333            'terrain',
1334            attrs={
1335                'model': self.preloaddata['vr_fill_mound_model'],
1336                'lighting': False,
1337                'vr_only': True,
1338                'color': (0.2, 0.25, 0.2),
1339                'background': True,
1340                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1341            },
1342        )
1343        gnode = ba.getactivity().globalsnode
1344        gnode.happy_thoughts_mode = True
1345        gnode.shadow_offset = (0.0, 8.0, 5.0)
1346        gnode.tint = (1.3, 1.23, 1.0)
1347        gnode.ambient_color = (1.3, 1.23, 1.0)
1348        gnode.vignette_outer = (0.64, 0.59, 0.69)
1349        gnode.vignette_inner = (0.95, 0.95, 0.93)
1350        gnode.vr_near_clip = 1.0
1351        self.is_flying = True
1352
1353        # throw out some tips on flying
1354        txt = ba.newnode(
1355            'text',
1356            attrs={
1357                'text': ba.Lstr(resource='pressJumpToFlyText'),
1358                'scale': 1.2,
1359                'maxwidth': 800,
1360                'position': (0, 200),
1361                'shadow': 0.5,
1362                'flatness': 0.5,
1363                'h_align': 'center',
1364                'v_attach': 'bottom',
1365            },
1366        )
1367        cmb = ba.newnode(
1368            'combine',
1369            owner=txt,
1370            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1371        )
1372        ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1373        cmb.connectattr('output', txt, 'color')
1374        ba.timer(10.0, txt.delete)

Flying map.

HappyThoughts()
1302    def __init__(self) -> None:
1303        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1304        shared = SharedObjects.get()
1305        self.node = ba.newnode(
1306            'terrain',
1307            delegate=self,
1308            attrs={
1309                'collide_model': self.preloaddata['collide_model'],
1310                'model': self.preloaddata['model'],
1311                'color_texture': self.preloaddata['tex'],
1312                'materials': [shared.footing_material],
1313            },
1314        )
1315        self.bottom = ba.newnode(
1316            'terrain',
1317            attrs={
1318                'model': self.preloaddata['bottom_model'],
1319                'lighting': False,
1320                'color_texture': self.preloaddata['tex'],
1321            },
1322        )
1323        self.background = ba.newnode(
1324            'terrain',
1325            attrs={
1326                'model': self.preloaddata['bgmodel'],
1327                'lighting': False,
1328                'background': True,
1329                'color_texture': self.preloaddata['bgtex'],
1330            },
1331        )
1332        ba.newnode(
1333            'terrain',
1334            attrs={
1335                'model': self.preloaddata['vr_fill_mound_model'],
1336                'lighting': False,
1337                'vr_only': True,
1338                'color': (0.2, 0.25, 0.2),
1339                'background': True,
1340                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1341            },
1342        )
1343        gnode = ba.getactivity().globalsnode
1344        gnode.happy_thoughts_mode = True
1345        gnode.shadow_offset = (0.0, 8.0, 5.0)
1346        gnode.tint = (1.3, 1.23, 1.0)
1347        gnode.ambient_color = (1.3, 1.23, 1.0)
1348        gnode.vignette_outer = (0.64, 0.59, 0.69)
1349        gnode.vignette_inner = (0.95, 0.95, 0.93)
1350        gnode.vr_near_clip = 1.0
1351        self.is_flying = True
1352
1353        # throw out some tips on flying
1354        txt = ba.newnode(
1355            'text',
1356            attrs={
1357                'text': ba.Lstr(resource='pressJumpToFlyText'),
1358                'scale': 1.2,
1359                'maxwidth': 800,
1360                'position': (0, 200),
1361                'shadow': 0.5,
1362                'flatness': 0.5,
1363                'h_align': 'center',
1364                'v_attach': 'bottom',
1365            },
1366        )
1367        cmb = ba.newnode(
1368            'combine',
1369            owner=txt,
1370            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1371        )
1372        ba.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1373        cmb.connectattr('output', txt, 'color')
1374        ba.timer(10.0, txt.delete)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1269    @classmethod
1270    def get_play_types(cls) -> list[str]:
1271        """Return valid play types for this map."""
1272        return [
1273            'melee',
1274            'keep_away',
1275            'team_flag',
1276            'conquest',
1277            'king_of_the_hill',
1278        ]

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1280    @classmethod
1281    def get_preview_texture_name(cls) -> str:
1282        return 'alwaysLandPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1284    @classmethod
1285    def on_preload(cls) -> Any:
1286        data: dict[str, Any] = {
1287            'model': ba.getmodel('alwaysLandLevel'),
1288            'bottom_model': ba.getmodel('alwaysLandLevelBottom'),
1289            'bgmodel': ba.getmodel('alwaysLandBG'),
1290            'collide_model': ba.getcollidemodel('alwaysLandLevelCollide'),
1291            'tex': ba.gettexture('alwaysLandLevelColor'),
1292            'bgtex': ba.gettexture('alwaysLandBGColor'),
1293            'vr_fill_mound_model': ba.getmodel('alwaysLandVRFillMound'),
1294            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1295        }
1296        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

@classmethod
def get_music_type(cls) -> ba._music.MusicType:
1298    @classmethod
1299    def get_music_type(cls) -> ba.MusicType:
1300        return ba.MusicType.FLYING

Return a music-type string that should be played on this map.

If None is returned, default music will be used.

Inherited Members
ba._map.Map
preload
getname
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class StepRightUp(ba._map.Map):
1377class StepRightUp(ba.Map):
1378    """Wide stepped map good for CTF or Assault."""
1379
1380    from bastd.mapdata import step_right_up as defs
1381
1382    name = 'Step Right Up'
1383
1384    @classmethod
1385    def get_play_types(cls) -> list[str]:
1386        """Return valid play types for this map."""
1387        return ['melee', 'keep_away', 'team_flag', 'conquest']
1388
1389    @classmethod
1390    def get_preview_texture_name(cls) -> str:
1391        return 'stepRightUpPreview'
1392
1393    @classmethod
1394    def on_preload(cls) -> Any:
1395        data: dict[str, Any] = {
1396            'model': ba.getmodel('stepRightUpLevel'),
1397            'model_bottom': ba.getmodel('stepRightUpLevelBottom'),
1398            'collide_model': ba.getcollidemodel('stepRightUpLevelCollide'),
1399            'tex': ba.gettexture('stepRightUpLevelColor'),
1400            'bgtex': ba.gettexture('menuBG'),
1401            'bgmodel': ba.getmodel('thePadBG'),
1402            'vr_fill_mound_model': ba.getmodel('stepRightUpVRFillMound'),
1403            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1404        }
1405        # fixme should chop this into vr/non-vr chunks
1406        return data
1407
1408    def __init__(self) -> None:
1409        super().__init__(vr_overlay_offset=(0, -1, 2))
1410        shared = SharedObjects.get()
1411        self.node = ba.newnode(
1412            'terrain',
1413            delegate=self,
1414            attrs={
1415                'collide_model': self.preloaddata['collide_model'],
1416                'model': self.preloaddata['model'],
1417                'color_texture': self.preloaddata['tex'],
1418                'materials': [shared.footing_material],
1419            },
1420        )
1421        self.node_bottom = ba.newnode(
1422            'terrain',
1423            delegate=self,
1424            attrs={
1425                'model': self.preloaddata['model_bottom'],
1426                'lighting': False,
1427                'color_texture': self.preloaddata['tex'],
1428            },
1429        )
1430        ba.newnode(
1431            'terrain',
1432            attrs={
1433                'model': self.preloaddata['vr_fill_mound_model'],
1434                'lighting': False,
1435                'vr_only': True,
1436                'color': (0.53, 0.57, 0.5),
1437                'background': True,
1438                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1439            },
1440        )
1441        self.background = ba.newnode(
1442            'terrain',
1443            attrs={
1444                'model': self.preloaddata['bgmodel'],
1445                'lighting': False,
1446                'background': True,
1447                'color_texture': self.preloaddata['bgtex'],
1448            },
1449        )
1450        gnode = ba.getactivity().globalsnode
1451        gnode.tint = (1.2, 1.1, 1.0)
1452        gnode.ambient_color = (1.2, 1.1, 1.0)
1453        gnode.vignette_outer = (0.7, 0.65, 0.75)
1454        gnode.vignette_inner = (0.95, 0.95, 0.93)

Wide stepped map good for CTF or Assault.

StepRightUp()
1408    def __init__(self) -> None:
1409        super().__init__(vr_overlay_offset=(0, -1, 2))
1410        shared = SharedObjects.get()
1411        self.node = ba.newnode(
1412            'terrain',
1413            delegate=self,
1414            attrs={
1415                'collide_model': self.preloaddata['collide_model'],
1416                'model': self.preloaddata['model'],
1417                'color_texture': self.preloaddata['tex'],
1418                'materials': [shared.footing_material],
1419            },
1420        )
1421        self.node_bottom = ba.newnode(
1422            'terrain',
1423            delegate=self,
1424            attrs={
1425                'model': self.preloaddata['model_bottom'],
1426                'lighting': False,
1427                'color_texture': self.preloaddata['tex'],
1428            },
1429        )
1430        ba.newnode(
1431            'terrain',
1432            attrs={
1433                'model': self.preloaddata['vr_fill_mound_model'],
1434                'lighting': False,
1435                'vr_only': True,
1436                'color': (0.53, 0.57, 0.5),
1437                'background': True,
1438                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1439            },
1440        )
1441        self.background = ba.newnode(
1442            'terrain',
1443            attrs={
1444                'model': self.preloaddata['bgmodel'],
1445                'lighting': False,
1446                'background': True,
1447                'color_texture': self.preloaddata['bgtex'],
1448            },
1449        )
1450        gnode = ba.getactivity().globalsnode
1451        gnode.tint = (1.2, 1.1, 1.0)
1452        gnode.ambient_color = (1.2, 1.1, 1.0)
1453        gnode.vignette_outer = (0.7, 0.65, 0.75)
1454        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1384    @classmethod
1385    def get_play_types(cls) -> list[str]:
1386        """Return valid play types for this map."""
1387        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1389    @classmethod
1390    def get_preview_texture_name(cls) -> str:
1391        return 'stepRightUpPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1393    @classmethod
1394    def on_preload(cls) -> Any:
1395        data: dict[str, Any] = {
1396            'model': ba.getmodel('stepRightUpLevel'),
1397            'model_bottom': ba.getmodel('stepRightUpLevelBottom'),
1398            'collide_model': ba.getcollidemodel('stepRightUpLevelCollide'),
1399            'tex': ba.gettexture('stepRightUpLevelColor'),
1400            'bgtex': ba.gettexture('menuBG'),
1401            'bgmodel': ba.getmodel('thePadBG'),
1402            'vr_fill_mound_model': ba.getmodel('stepRightUpVRFillMound'),
1403            'vr_fill_mound_tex': ba.gettexture('vrFillMound'),
1404        }
1405        # fixme should chop this into vr/non-vr chunks
1406        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

Inherited Members
ba._map.Map
preload
getname
get_music_type
is_point_near_edge
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class Courtyard(ba._map.Map):
1457class Courtyard(ba.Map):
1458    """A courtyard-ish looking map for co-op levels."""
1459
1460    from bastd.mapdata import courtyard as defs
1461
1462    name = 'Courtyard'
1463
1464    @classmethod
1465    def get_play_types(cls) -> list[str]:
1466        """Return valid play types for this map."""
1467        return ['melee', 'keep_away', 'team_flag']
1468
1469    @classmethod
1470    def get_preview_texture_name(cls) -> str:
1471        return 'courtyardPreview'
1472
1473    @classmethod
1474    def on_preload(cls) -> Any:
1475        data: dict[str, Any] = {
1476            'model': ba.getmodel('courtyardLevel'),
1477            'model_bottom': ba.getmodel('courtyardLevelBottom'),
1478            'collide_model': ba.getcollidemodel('courtyardLevelCollide'),
1479            'tex': ba.gettexture('courtyardLevelColor'),
1480            'bgtex': ba.gettexture('menuBG'),
1481            'bgmodel': ba.getmodel('thePadBG'),
1482            'player_wall_collide_model': (
1483                ba.getcollidemodel('courtyardPlayerWall')
1484            ),
1485            'player_wall_material': ba.Material(),
1486        }
1487        # FIXME: Chop this into vr and non-vr chunks.
1488        data['player_wall_material'].add_actions(
1489            actions=('modify_part_collision', 'friction', 0.0)
1490        )
1491        # anything that needs to hit the wall should apply this.
1492        data['collide_with_wall_material'] = ba.Material()
1493        data['player_wall_material'].add_actions(
1494            conditions=(
1495                'they_dont_have_material',
1496                data['collide_with_wall_material'],
1497            ),
1498            actions=('modify_part_collision', 'collide', False),
1499        )
1500        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1501        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1502        return data
1503
1504    def __init__(self) -> None:
1505        super().__init__()
1506        shared = SharedObjects.get()
1507        self.node = ba.newnode(
1508            'terrain',
1509            delegate=self,
1510            attrs={
1511                'collide_model': self.preloaddata['collide_model'],
1512                'model': self.preloaddata['model'],
1513                'color_texture': self.preloaddata['tex'],
1514                'materials': [shared.footing_material],
1515            },
1516        )
1517        self.background = ba.newnode(
1518            'terrain',
1519            attrs={
1520                'model': self.preloaddata['bgmodel'],
1521                'lighting': False,
1522                'background': True,
1523                'color_texture': self.preloaddata['bgtex'],
1524            },
1525        )
1526        self.bottom = ba.newnode(
1527            'terrain',
1528            attrs={
1529                'model': self.preloaddata['model_bottom'],
1530                'lighting': False,
1531                'color_texture': self.preloaddata['tex'],
1532            },
1533        )
1534        ba.newnode(
1535            'terrain',
1536            attrs={
1537                'model': self.preloaddata['vr_fill_mound_model'],
1538                'lighting': False,
1539                'vr_only': True,
1540                'color': (0.53, 0.57, 0.5),
1541                'background': True,
1542                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1543            },
1544        )
1545        # in co-op mode games, put up a wall to prevent players
1546        # from getting in the turrets (that would foil our brilliant AI)
1547        if isinstance(ba.getsession(), ba.CoopSession):
1548            cmodel = self.preloaddata['player_wall_collide_model']
1549            self.player_wall = ba.newnode(
1550                'terrain',
1551                attrs={
1552                    'collide_model': cmodel,
1553                    'affect_bg_dynamics': False,
1554                    'materials': [self.preloaddata['player_wall_material']],
1555                },
1556            )
1557        gnode = ba.getactivity().globalsnode
1558        gnode.tint = (1.2, 1.17, 1.1)
1559        gnode.ambient_color = (1.2, 1.17, 1.1)
1560        gnode.vignette_outer = (0.6, 0.6, 0.64)
1561        gnode.vignette_inner = (0.95, 0.95, 0.93)
1562
1563    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1564        # count anything off our ground level as safe (for our platforms)
1565        # see if we're within edge_box
1566        box_position = self.defs.boxes['edge_box'][0:3]
1567        box_scale = self.defs.boxes['edge_box'][6:9]
1568        xpos = (point.x - box_position[0]) / box_scale[0]
1569        zpos = (point.z - box_position[2]) / box_scale[2]
1570        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

A courtyard-ish looking map for co-op levels.

Courtyard()
1504    def __init__(self) -> None:
1505        super().__init__()
1506        shared = SharedObjects.get()
1507        self.node = ba.newnode(
1508            'terrain',
1509            delegate=self,
1510            attrs={
1511                'collide_model': self.preloaddata['collide_model'],
1512                'model': self.preloaddata['model'],
1513                'color_texture': self.preloaddata['tex'],
1514                'materials': [shared.footing_material],
1515            },
1516        )
1517        self.background = ba.newnode(
1518            'terrain',
1519            attrs={
1520                'model': self.preloaddata['bgmodel'],
1521                'lighting': False,
1522                'background': True,
1523                'color_texture': self.preloaddata['bgtex'],
1524            },
1525        )
1526        self.bottom = ba.newnode(
1527            'terrain',
1528            attrs={
1529                'model': self.preloaddata['model_bottom'],
1530                'lighting': False,
1531                'color_texture': self.preloaddata['tex'],
1532            },
1533        )
1534        ba.newnode(
1535            'terrain',
1536            attrs={
1537                'model': self.preloaddata['vr_fill_mound_model'],
1538                'lighting': False,
1539                'vr_only': True,
1540                'color': (0.53, 0.57, 0.5),
1541                'background': True,
1542                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1543            },
1544        )
1545        # in co-op mode games, put up a wall to prevent players
1546        # from getting in the turrets (that would foil our brilliant AI)
1547        if isinstance(ba.getsession(), ba.CoopSession):
1548            cmodel = self.preloaddata['player_wall_collide_model']
1549            self.player_wall = ba.newnode(
1550                'terrain',
1551                attrs={
1552                    'collide_model': cmodel,
1553                    'affect_bg_dynamics': False,
1554                    'materials': [self.preloaddata['player_wall_material']],
1555                },
1556            )
1557        gnode = ba.getactivity().globalsnode
1558        gnode.tint = (1.2, 1.17, 1.1)
1559        gnode.ambient_color = (1.2, 1.17, 1.1)
1560        gnode.vignette_outer = (0.6, 0.6, 0.64)
1561        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1464    @classmethod
1465    def get_play_types(cls) -> list[str]:
1466        """Return valid play types for this map."""
1467        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1469    @classmethod
1470    def get_preview_texture_name(cls) -> str:
1471        return 'courtyardPreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1473    @classmethod
1474    def on_preload(cls) -> Any:
1475        data: dict[str, Any] = {
1476            'model': ba.getmodel('courtyardLevel'),
1477            'model_bottom': ba.getmodel('courtyardLevelBottom'),
1478            'collide_model': ba.getcollidemodel('courtyardLevelCollide'),
1479            'tex': ba.gettexture('courtyardLevelColor'),
1480            'bgtex': ba.gettexture('menuBG'),
1481            'bgmodel': ba.getmodel('thePadBG'),
1482            'player_wall_collide_model': (
1483                ba.getcollidemodel('courtyardPlayerWall')
1484            ),
1485            'player_wall_material': ba.Material(),
1486        }
1487        # FIXME: Chop this into vr and non-vr chunks.
1488        data['player_wall_material'].add_actions(
1489            actions=('modify_part_collision', 'friction', 0.0)
1490        )
1491        # anything that needs to hit the wall should apply this.
1492        data['collide_with_wall_material'] = ba.Material()
1493        data['player_wall_material'].add_actions(
1494            conditions=(
1495                'they_dont_have_material',
1496                data['collide_with_wall_material'],
1497            ),
1498            actions=('modify_part_collision', 'collide', False),
1499        )
1500        data['vr_fill_mound_model'] = ba.getmodel('stepRightUpVRFillMound')
1501        data['vr_fill_mound_tex'] = ba.gettexture('vrFillMound')
1502        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

def is_point_near_edge(self, point: _ba.Vec3, running: bool = False) -> bool:
1563    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1564        # count anything off our ground level as safe (for our platforms)
1565        # see if we're within edge_box
1566        box_position = self.defs.boxes['edge_box'][0:3]
1567        box_scale = self.defs.boxes['edge_box'][6:9]
1568        xpos = (point.x - box_position[0]) / box_scale[0]
1569        zpos = (point.z - box_position[2]) / box_scale[2]
1570        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Return whether the provided point is near an edge of the map.

Simple bot logic uses this call to determine if they are approaching a cliff or wall. If this returns True they will generally not walk/run any farther away from the origin. If 'running' is True, the buffer should be a bit larger.

Inherited Members
ba._map.Map
preload
getname
get_music_type
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity
class Rampage(ba._map.Map):
1573class Rampage(ba.Map):
1574    """Wee little map with ramps on the sides."""
1575
1576    from bastd.mapdata import rampage as defs
1577
1578    name = 'Rampage'
1579
1580    @classmethod
1581    def get_play_types(cls) -> list[str]:
1582        """Return valid play types for this map."""
1583        return ['melee', 'keep_away', 'team_flag']
1584
1585    @classmethod
1586    def get_preview_texture_name(cls) -> str:
1587        return 'rampagePreview'
1588
1589    @classmethod
1590    def on_preload(cls) -> Any:
1591        data: dict[str, Any] = {
1592            'model': ba.getmodel('rampageLevel'),
1593            'bottom_model': ba.getmodel('rampageLevelBottom'),
1594            'collide_model': ba.getcollidemodel('rampageLevelCollide'),
1595            'tex': ba.gettexture('rampageLevelColor'),
1596            'bgtex': ba.gettexture('rampageBGColor'),
1597            'bgtex2': ba.gettexture('rampageBGColor2'),
1598            'bgmodel': ba.getmodel('rampageBG'),
1599            'bgmodel2': ba.getmodel('rampageBG2'),
1600            'vr_fill_model': ba.getmodel('rampageVRFill'),
1601            'railing_collide_model': ba.getcollidemodel('rampageBumper'),
1602        }
1603        return data
1604
1605    def __init__(self) -> None:
1606        super().__init__(vr_overlay_offset=(0, 0, 2))
1607        shared = SharedObjects.get()
1608        self.node = ba.newnode(
1609            'terrain',
1610            delegate=self,
1611            attrs={
1612                'collide_model': self.preloaddata['collide_model'],
1613                'model': self.preloaddata['model'],
1614                'color_texture': self.preloaddata['tex'],
1615                'materials': [shared.footing_material],
1616            },
1617        )
1618        self.background = ba.newnode(
1619            'terrain',
1620            attrs={
1621                'model': self.preloaddata['bgmodel'],
1622                'lighting': False,
1623                'background': True,
1624                'color_texture': self.preloaddata['bgtex'],
1625            },
1626        )
1627        self.bottom = ba.newnode(
1628            'terrain',
1629            attrs={
1630                'model': self.preloaddata['bottom_model'],
1631                'lighting': False,
1632                'color_texture': self.preloaddata['tex'],
1633            },
1634        )
1635        self.bg2 = ba.newnode(
1636            'terrain',
1637            attrs={
1638                'model': self.preloaddata['bgmodel2'],
1639                'lighting': False,
1640                'background': True,
1641                'color_texture': self.preloaddata['bgtex2'],
1642            },
1643        )
1644        ba.newnode(
1645            'terrain',
1646            attrs={
1647                'model': self.preloaddata['vr_fill_model'],
1648                'lighting': False,
1649                'vr_only': True,
1650                'background': True,
1651                'color_texture': self.preloaddata['bgtex2'],
1652            },
1653        )
1654        self.railing = ba.newnode(
1655            'terrain',
1656            attrs={
1657                'collide_model': self.preloaddata['railing_collide_model'],
1658                'materials': [shared.railing_material],
1659                'bumper': True,
1660            },
1661        )
1662        gnode = ba.getactivity().globalsnode
1663        gnode.tint = (1.2, 1.1, 0.97)
1664        gnode.ambient_color = (1.3, 1.2, 1.03)
1665        gnode.vignette_outer = (0.62, 0.64, 0.69)
1666        gnode.vignette_inner = (0.97, 0.95, 0.93)
1667
1668    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1669        box_position = self.defs.boxes['edge_box'][0:3]
1670        box_scale = self.defs.boxes['edge_box'][6:9]
1671        xpos = (point.x - box_position[0]) / box_scale[0]
1672        zpos = (point.z - box_position[2]) / box_scale[2]
1673        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Wee little map with ramps on the sides.

Rampage()
1605    def __init__(self) -> None:
1606        super().__init__(vr_overlay_offset=(0, 0, 2))
1607        shared = SharedObjects.get()
1608        self.node = ba.newnode(
1609            'terrain',
1610            delegate=self,
1611            attrs={
1612                'collide_model': self.preloaddata['collide_model'],
1613                'model': self.preloaddata['model'],
1614                'color_texture': self.preloaddata['tex'],
1615                'materials': [shared.footing_material],
1616            },
1617        )
1618        self.background = ba.newnode(
1619            'terrain',
1620            attrs={
1621                'model': self.preloaddata['bgmodel'],
1622                'lighting': False,
1623                'background': True,
1624                'color_texture': self.preloaddata['bgtex'],
1625            },
1626        )
1627        self.bottom = ba.newnode(
1628            'terrain',
1629            attrs={
1630                'model': self.preloaddata['bottom_model'],
1631                'lighting': False,
1632                'color_texture': self.preloaddata['tex'],
1633            },
1634        )
1635        self.bg2 = ba.newnode(
1636            'terrain',
1637            attrs={
1638                'model': self.preloaddata['bgmodel2'],
1639                'lighting': False,
1640                'background': True,
1641                'color_texture': self.preloaddata['bgtex2'],
1642            },
1643        )
1644        ba.newnode(
1645            'terrain',
1646            attrs={
1647                'model': self.preloaddata['vr_fill_model'],
1648                'lighting': False,
1649                'vr_only': True,
1650                'background': True,
1651                'color_texture': self.preloaddata['bgtex2'],
1652            },
1653        )
1654        self.railing = ba.newnode(
1655            'terrain',
1656            attrs={
1657                'collide_model': self.preloaddata['railing_collide_model'],
1658                'materials': [shared.railing_material],
1659                'bumper': True,
1660            },
1661        )
1662        gnode = ba.getactivity().globalsnode
1663        gnode.tint = (1.2, 1.1, 0.97)
1664        gnode.ambient_color = (1.3, 1.2, 1.03)
1665        gnode.vignette_outer = (0.62, 0.64, 0.69)
1666        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

@classmethod
def get_play_types(cls) -> list[str]:
1580    @classmethod
1581    def get_play_types(cls) -> list[str]:
1582        """Return valid play types for this map."""
1583        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@classmethod
def get_preview_texture_name(cls) -> str:
1585    @classmethod
1586    def get_preview_texture_name(cls) -> str:
1587        return 'rampagePreview'

Return the name of the preview texture for this map.

@classmethod
def on_preload(cls) -> Any:
1589    @classmethod
1590    def on_preload(cls) -> Any:
1591        data: dict[str, Any] = {
1592            'model': ba.getmodel('rampageLevel'),
1593            'bottom_model': ba.getmodel('rampageLevelBottom'),
1594            'collide_model': ba.getcollidemodel('rampageLevelCollide'),
1595            'tex': ba.gettexture('rampageLevelColor'),
1596            'bgtex': ba.gettexture('rampageBGColor'),
1597            'bgtex2': ba.gettexture('rampageBGColor2'),
1598            'bgmodel': ba.getmodel('rampageBG'),
1599            'bgmodel2': ba.getmodel('rampageBG2'),
1600            'vr_fill_model': ba.getmodel('rampageVRFill'),
1601            'railing_collide_model': ba.getcollidemodel('rampageBumper'),
1602        }
1603        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

def is_point_near_edge(self, point: _ba.Vec3, running: bool = False) -> bool:
1668    def is_point_near_edge(self, point: ba.Vec3, running: bool = False) -> bool:
1669        box_position = self.defs.boxes['edge_box'][0:3]
1670        box_scale = self.defs.boxes['edge_box'][6:9]
1671        xpos = (point.x - box_position[0]) / box_scale[0]
1672        zpos = (point.z - box_position[2]) / box_scale[2]
1673        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Return whether the provided point is near an edge of the map.

Simple bot logic uses this call to determine if they are approaching a cliff or wall. If this returns True they will generally not walk/run any farther away from the origin. If 'running' is True, the buffer should be a bit larger.

Inherited Members
ba._map.Map
preload
getname
get_music_type
get_def_bound_box
get_def_point
get_def_points
get_start_position
get_ffa_start_position
get_flag_position
exists
handlemessage
ba._actor.Actor
autoretain
on_expire
expired
is_alive
activity
getactivity