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

Stadium map used for ice hockey games.

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

Instantiate a map.

name = 'Hockey Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
27    @override
28    @classmethod
29    def get_play_types(cls) -> list[str]:
30        """Return valid play types for this map."""
31        return ['melee', 'hockey', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
33    @override
34    @classmethod
35    def get_preview_texture_name(cls) -> str:
36        return 'hockeyStadiumPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
38    @override
39    @classmethod
40    def on_preload(cls) -> Any:
41        data: dict[str, Any] = {
42            'meshes': (
43                bs.getmesh('hockeyStadiumOuter'),
44                bs.getmesh('hockeyStadiumInner'),
45                bs.getmesh('hockeyStadiumStands'),
46            ),
47            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
48            'collision_mesh': bs.getcollisionmesh('hockeyStadiumCollide'),
49            'tex': bs.gettexture('hockeyStadium'),
50            'stands_tex': bs.gettexture('footballStadium'),
51        }
52        mat = bs.Material()
53        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
54        data['ice_material'] = mat
55        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
floor
stands
is_hockey
class FootballStadium(bascenev1._map.Map):
115class FootballStadium(bs.Map):
116    """Stadium map for football games."""
117
118    from bascenev1lib.mapdata import football_stadium as defs
119
120    name = 'Football Stadium'
121
122    @override
123    @classmethod
124    def get_play_types(cls) -> list[str]:
125        """Return valid play types for this map."""
126        return ['melee', 'football', 'team_flag', 'keep_away']
127
128    @override
129    @classmethod
130    def get_preview_texture_name(cls) -> str:
131        return 'footballStadiumPreview'
132
133    @override
134    @classmethod
135    def on_preload(cls) -> Any:
136        data: dict[str, Any] = {
137            'mesh': bs.getmesh('footballStadium'),
138            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
139            'collision_mesh': bs.getcollisionmesh('footballStadiumCollide'),
140            'tex': bs.gettexture('footballStadium'),
141        }
142        return data
143
144    def __init__(self) -> None:
145        super().__init__()
146        shared = SharedObjects.get()
147        self.node = bs.newnode(
148            'terrain',
149            delegate=self,
150            attrs={
151                'mesh': self.preloaddata['mesh'],
152                'collision_mesh': self.preloaddata['collision_mesh'],
153                'color_texture': self.preloaddata['tex'],
154                'materials': [shared.footing_material],
155            },
156        )
157        bs.newnode(
158            'terrain',
159            attrs={
160                'mesh': self.preloaddata['vr_fill_mesh'],
161                'lighting': False,
162                'vr_only': True,
163                'background': True,
164                'color_texture': self.preloaddata['tex'],
165            },
166        )
167        gnode = bs.getactivity().globalsnode
168        gnode.tint = (1.3, 1.2, 1.0)
169        gnode.ambient_color = (1.3, 1.2, 1.0)
170        gnode.vignette_outer = (0.57, 0.57, 0.57)
171        gnode.vignette_inner = (0.9, 0.9, 0.9)
172        gnode.vr_camera_offset = (0, -0.8, -1.1)
173        gnode.vr_near_clip = 0.5
174
175    @override
176    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
177        box_position = self.defs.boxes['edge_box'][0:3]
178        box_scale = self.defs.boxes['edge_box'][6:9]
179        xpos = (point.x - box_position[0]) / box_scale[0]
180        zpos = (point.z - box_position[2]) / box_scale[2]
181        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Stadium map for football games.

FootballStadium()
144    def __init__(self) -> None:
145        super().__init__()
146        shared = SharedObjects.get()
147        self.node = bs.newnode(
148            'terrain',
149            delegate=self,
150            attrs={
151                'mesh': self.preloaddata['mesh'],
152                'collision_mesh': self.preloaddata['collision_mesh'],
153                'color_texture': self.preloaddata['tex'],
154                'materials': [shared.footing_material],
155            },
156        )
157        bs.newnode(
158            'terrain',
159            attrs={
160                'mesh': self.preloaddata['vr_fill_mesh'],
161                'lighting': False,
162                'vr_only': True,
163                'background': True,
164                'color_texture': self.preloaddata['tex'],
165            },
166        )
167        gnode = bs.getactivity().globalsnode
168        gnode.tint = (1.3, 1.2, 1.0)
169        gnode.ambient_color = (1.3, 1.2, 1.0)
170        gnode.vignette_outer = (0.57, 0.57, 0.57)
171        gnode.vignette_inner = (0.9, 0.9, 0.9)
172        gnode.vr_camera_offset = (0, -0.8, -1.1)
173        gnode.vr_near_clip = 0.5

Instantiate a map.

name = 'Football Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
122    @override
123    @classmethod
124    def get_play_types(cls) -> list[str]:
125        """Return valid play types for this map."""
126        return ['melee', 'football', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
128    @override
129    @classmethod
130    def get_preview_texture_name(cls) -> str:
131        return 'footballStadiumPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
133    @override
134    @classmethod
135    def on_preload(cls) -> Any:
136        data: dict[str, Any] = {
137            'mesh': bs.getmesh('footballStadium'),
138            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
139            'collision_mesh': bs.getcollisionmesh('footballStadiumCollide'),
140            'tex': bs.gettexture('footballStadium'),
141        }
142        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
@override
def is_point_near_edge(self, point: _babase.Vec3, running: bool = False) -> bool:
175    @override
176    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
177        box_position = self.defs.boxes['edge_box'][0:3]
178        box_scale = self.defs.boxes['edge_box'][6:9]
179        xpos = (point.x - box_position[0]) / box_scale[0]
180        zpos = (point.z - box_position[2]) / box_scale[2]
181        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.

class Bridgit(bascenev1._map.Map):
184class Bridgit(bs.Map):
185    """Map with a narrow bridge in the middle."""
186
187    # noinspection PyUnresolvedReferences
188    from bascenev1lib.mapdata import bridgit as defs
189
190    name = 'Bridgit'
191    dataname = 'bridgit'
192
193    @override
194    @classmethod
195    def get_play_types(cls) -> list[str]:
196        """Return valid play types for this map."""
197        # print('getting playtypes', cls._getdata()['play_types'])
198        return ['melee', 'team_flag', 'keep_away']
199
200    @override
201    @classmethod
202    def get_preview_texture_name(cls) -> str:
203        return 'bridgitPreview'
204
205    @override
206    @classmethod
207    def on_preload(cls) -> Any:
208        data: dict[str, Any] = {
209            'mesh_top': bs.getmesh('bridgitLevelTop'),
210            'mesh_bottom': bs.getmesh('bridgitLevelBottom'),
211            'mesh_bg': bs.getmesh('natureBackground'),
212            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
213            'collision_mesh': bs.getcollisionmesh('bridgitLevelCollide'),
214            'tex': bs.gettexture('bridgitLevelColor'),
215            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
216            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
217            'railing_collision_mesh': (
218                bs.getcollisionmesh('bridgitLevelRailingCollide')
219            ),
220            'bg_material': bs.Material(),
221        }
222        data['bg_material'].add_actions(
223            actions=('modify_part_collision', 'friction', 10.0)
224        )
225        return data
226
227    def __init__(self) -> None:
228        super().__init__()
229        shared = SharedObjects.get()
230        self.node = bs.newnode(
231            'terrain',
232            delegate=self,
233            attrs={
234                'collision_mesh': self.preloaddata['collision_mesh'],
235                'mesh': self.preloaddata['mesh_top'],
236                'color_texture': self.preloaddata['tex'],
237                'materials': [shared.footing_material],
238            },
239        )
240        self.bottom = bs.newnode(
241            'terrain',
242            attrs={
243                'mesh': self.preloaddata['mesh_bottom'],
244                'lighting': False,
245                'color_texture': self.preloaddata['tex'],
246            },
247        )
248        self.background = bs.newnode(
249            'terrain',
250            attrs={
251                'mesh': self.preloaddata['mesh_bg'],
252                'lighting': False,
253                'background': True,
254                'color_texture': self.preloaddata['mesh_bg_tex'],
255            },
256        )
257        bs.newnode(
258            'terrain',
259            attrs={
260                'mesh': self.preloaddata['bg_vr_fill_mesh'],
261                'lighting': False,
262                'vr_only': True,
263                'background': True,
264                'color_texture': self.preloaddata['mesh_bg_tex'],
265            },
266        )
267        self.railing = bs.newnode(
268            'terrain',
269            attrs={
270                'collision_mesh': self.preloaddata['railing_collision_mesh'],
271                'materials': [shared.railing_material],
272                'bumper': True,
273            },
274        )
275        self.bg_collide = bs.newnode(
276            'terrain',
277            attrs={
278                'collision_mesh': self.preloaddata['collide_bg'],
279                'materials': [
280                    shared.footing_material,
281                    self.preloaddata['bg_material'],
282                    shared.death_material,
283                ],
284            },
285        )
286        gnode = bs.getactivity().globalsnode
287        gnode.tint = (1.1, 1.2, 1.3)
288        gnode.ambient_color = (1.1, 1.2, 1.3)
289        gnode.vignette_outer = (0.65, 0.6, 0.55)
290        gnode.vignette_inner = (0.9, 0.9, 0.93)

Map with a narrow bridge in the middle.

Bridgit()
227    def __init__(self) -> None:
228        super().__init__()
229        shared = SharedObjects.get()
230        self.node = bs.newnode(
231            'terrain',
232            delegate=self,
233            attrs={
234                'collision_mesh': self.preloaddata['collision_mesh'],
235                'mesh': self.preloaddata['mesh_top'],
236                'color_texture': self.preloaddata['tex'],
237                'materials': [shared.footing_material],
238            },
239        )
240        self.bottom = bs.newnode(
241            'terrain',
242            attrs={
243                'mesh': self.preloaddata['mesh_bottom'],
244                'lighting': False,
245                'color_texture': self.preloaddata['tex'],
246            },
247        )
248        self.background = bs.newnode(
249            'terrain',
250            attrs={
251                'mesh': self.preloaddata['mesh_bg'],
252                'lighting': False,
253                'background': True,
254                'color_texture': self.preloaddata['mesh_bg_tex'],
255            },
256        )
257        bs.newnode(
258            'terrain',
259            attrs={
260                'mesh': self.preloaddata['bg_vr_fill_mesh'],
261                'lighting': False,
262                'vr_only': True,
263                'background': True,
264                'color_texture': self.preloaddata['mesh_bg_tex'],
265            },
266        )
267        self.railing = bs.newnode(
268            'terrain',
269            attrs={
270                'collision_mesh': self.preloaddata['railing_collision_mesh'],
271                'materials': [shared.railing_material],
272                'bumper': True,
273            },
274        )
275        self.bg_collide = bs.newnode(
276            'terrain',
277            attrs={
278                'collision_mesh': self.preloaddata['collide_bg'],
279                'materials': [
280                    shared.footing_material,
281                    self.preloaddata['bg_material'],
282                    shared.death_material,
283                ],
284            },
285        )
286        gnode = bs.getactivity().globalsnode
287        gnode.tint = (1.1, 1.2, 1.3)
288        gnode.ambient_color = (1.1, 1.2, 1.3)
289        gnode.vignette_outer = (0.65, 0.6, 0.55)
290        gnode.vignette_inner = (0.9, 0.9, 0.93)

Instantiate a map.

name = 'Bridgit'
dataname = 'bridgit'
@override
@classmethod
def get_play_types(cls) -> list[str]:
193    @override
194    @classmethod
195    def get_play_types(cls) -> list[str]:
196        """Return valid play types for this map."""
197        # print('getting playtypes', cls._getdata()['play_types'])
198        return ['melee', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
200    @override
201    @classmethod
202    def get_preview_texture_name(cls) -> str:
203        return 'bridgitPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
205    @override
206    @classmethod
207    def on_preload(cls) -> Any:
208        data: dict[str, Any] = {
209            'mesh_top': bs.getmesh('bridgitLevelTop'),
210            'mesh_bottom': bs.getmesh('bridgitLevelBottom'),
211            'mesh_bg': bs.getmesh('natureBackground'),
212            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
213            'collision_mesh': bs.getcollisionmesh('bridgitLevelCollide'),
214            'tex': bs.gettexture('bridgitLevelColor'),
215            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
216            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
217            'railing_collision_mesh': (
218                bs.getcollisionmesh('bridgitLevelRailingCollide')
219            ),
220            'bg_material': bs.Material(),
221        }
222        data['bg_material'].add_actions(
223            actions=('modify_part_collision', 'friction', 10.0)
224        )
225        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
railing
bg_collide
class BigG(bascenev1._map.Map):
293class BigG(bs.Map):
294    """Large G shaped map for racing"""
295
296    # noinspection PyUnresolvedReferences
297    from bascenev1lib.mapdata import big_g as defs
298
299    name = 'Big G'
300
301    @override
302    @classmethod
303    def get_play_types(cls) -> list[str]:
304        """Return valid play types for this map."""
305        return [
306            'race',
307            'melee',
308            'keep_away',
309            'team_flag',
310            'king_of_the_hill',
311            'conquest',
312        ]
313
314    @override
315    @classmethod
316    def get_preview_texture_name(cls) -> str:
317        return 'bigGPreview'
318
319    @override
320    @classmethod
321    def on_preload(cls) -> Any:
322        data: dict[str, Any] = {
323            'mesh_top': bs.getmesh('bigG'),
324            'mesh_bottom': bs.getmesh('bigGBottom'),
325            'mesh_bg': bs.getmesh('natureBackground'),
326            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
327            'collision_mesh': bs.getcollisionmesh('bigGCollide'),
328            'tex': bs.gettexture('bigG'),
329            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
330            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
331            'bumper_collision_mesh': bs.getcollisionmesh('bigGBumper'),
332            'bg_material': bs.Material(),
333        }
334        data['bg_material'].add_actions(
335            actions=('modify_part_collision', 'friction', 10.0)
336        )
337        return data
338
339    def __init__(self) -> None:
340        super().__init__()
341        shared = SharedObjects.get()
342        self.node = bs.newnode(
343            'terrain',
344            delegate=self,
345            attrs={
346                'collision_mesh': self.preloaddata['collision_mesh'],
347                'color': (0.7, 0.7, 0.7),
348                'mesh': self.preloaddata['mesh_top'],
349                'color_texture': self.preloaddata['tex'],
350                'materials': [shared.footing_material],
351            },
352        )
353        self.bottom = bs.newnode(
354            'terrain',
355            attrs={
356                'mesh': self.preloaddata['mesh_bottom'],
357                'color': (0.7, 0.7, 0.7),
358                'lighting': False,
359                'color_texture': self.preloaddata['tex'],
360            },
361        )
362        self.background = bs.newnode(
363            'terrain',
364            attrs={
365                'mesh': self.preloaddata['mesh_bg'],
366                'lighting': False,
367                'background': True,
368                'color_texture': self.preloaddata['mesh_bg_tex'],
369            },
370        )
371        bs.newnode(
372            'terrain',
373            attrs={
374                'mesh': self.preloaddata['bg_vr_fill_mesh'],
375                'lighting': False,
376                'vr_only': True,
377                'background': True,
378                'color_texture': self.preloaddata['mesh_bg_tex'],
379            },
380        )
381        self.railing = bs.newnode(
382            'terrain',
383            attrs={
384                'collision_mesh': self.preloaddata['bumper_collision_mesh'],
385                'materials': [shared.railing_material],
386                'bumper': True,
387            },
388        )
389        self.bg_collide = bs.newnode(
390            'terrain',
391            attrs={
392                'collision_mesh': self.preloaddata['collide_bg'],
393                'materials': [
394                    shared.footing_material,
395                    self.preloaddata['bg_material'],
396                    shared.death_material,
397                ],
398            },
399        )
400        gnode = bs.getactivity().globalsnode
401        gnode.tint = (1.1, 1.2, 1.3)
402        gnode.ambient_color = (1.1, 1.2, 1.3)
403        gnode.vignette_outer = (0.65, 0.6, 0.55)
404        gnode.vignette_inner = (0.9, 0.9, 0.93)

Large G shaped map for racing

BigG()
339    def __init__(self) -> None:
340        super().__init__()
341        shared = SharedObjects.get()
342        self.node = bs.newnode(
343            'terrain',
344            delegate=self,
345            attrs={
346                'collision_mesh': self.preloaddata['collision_mesh'],
347                'color': (0.7, 0.7, 0.7),
348                'mesh': self.preloaddata['mesh_top'],
349                'color_texture': self.preloaddata['tex'],
350                'materials': [shared.footing_material],
351            },
352        )
353        self.bottom = bs.newnode(
354            'terrain',
355            attrs={
356                'mesh': self.preloaddata['mesh_bottom'],
357                'color': (0.7, 0.7, 0.7),
358                'lighting': False,
359                'color_texture': self.preloaddata['tex'],
360            },
361        )
362        self.background = bs.newnode(
363            'terrain',
364            attrs={
365                'mesh': self.preloaddata['mesh_bg'],
366                'lighting': False,
367                'background': True,
368                'color_texture': self.preloaddata['mesh_bg_tex'],
369            },
370        )
371        bs.newnode(
372            'terrain',
373            attrs={
374                'mesh': self.preloaddata['bg_vr_fill_mesh'],
375                'lighting': False,
376                'vr_only': True,
377                'background': True,
378                'color_texture': self.preloaddata['mesh_bg_tex'],
379            },
380        )
381        self.railing = bs.newnode(
382            'terrain',
383            attrs={
384                'collision_mesh': self.preloaddata['bumper_collision_mesh'],
385                'materials': [shared.railing_material],
386                'bumper': True,
387            },
388        )
389        self.bg_collide = bs.newnode(
390            'terrain',
391            attrs={
392                'collision_mesh': self.preloaddata['collide_bg'],
393                'materials': [
394                    shared.footing_material,
395                    self.preloaddata['bg_material'],
396                    shared.death_material,
397                ],
398            },
399        )
400        gnode = bs.getactivity().globalsnode
401        gnode.tint = (1.1, 1.2, 1.3)
402        gnode.ambient_color = (1.1, 1.2, 1.3)
403        gnode.vignette_outer = (0.65, 0.6, 0.55)
404        gnode.vignette_inner = (0.9, 0.9, 0.93)

Instantiate a map.

name = 'Big G'
@override
@classmethod
def get_play_types(cls) -> list[str]:
301    @override
302    @classmethod
303    def get_play_types(cls) -> list[str]:
304        """Return valid play types for this map."""
305        return [
306            'race',
307            'melee',
308            'keep_away',
309            'team_flag',
310            'king_of_the_hill',
311            'conquest',
312        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
314    @override
315    @classmethod
316    def get_preview_texture_name(cls) -> str:
317        return 'bigGPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
319    @override
320    @classmethod
321    def on_preload(cls) -> Any:
322        data: dict[str, Any] = {
323            'mesh_top': bs.getmesh('bigG'),
324            'mesh_bottom': bs.getmesh('bigGBottom'),
325            'mesh_bg': bs.getmesh('natureBackground'),
326            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
327            'collision_mesh': bs.getcollisionmesh('bigGCollide'),
328            'tex': bs.gettexture('bigG'),
329            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
330            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
331            'bumper_collision_mesh': bs.getcollisionmesh('bigGBumper'),
332            'bg_material': bs.Material(),
333        }
334        data['bg_material'].add_actions(
335            actions=('modify_part_collision', 'friction', 10.0)
336        )
337        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
railing
bg_collide
class Roundabout(bascenev1._map.Map):
407class Roundabout(bs.Map):
408    """CTF map featuring two platforms and a long way around between them"""
409
410    # noinspection PyUnresolvedReferences
411    from bascenev1lib.mapdata import roundabout as defs
412
413    name = 'Roundabout'
414
415    @override
416    @classmethod
417    def get_play_types(cls) -> list[str]:
418        """Return valid play types for this map."""
419        return ['melee', 'keep_away', 'team_flag']
420
421    @override
422    @classmethod
423    def get_preview_texture_name(cls) -> str:
424        return 'roundaboutPreview'
425
426    @override
427    @classmethod
428    def on_preload(cls) -> Any:
429        data: dict[str, Any] = {
430            'mesh': bs.getmesh('roundaboutLevel'),
431            'mesh_bottom': bs.getmesh('roundaboutLevelBottom'),
432            'mesh_bg': bs.getmesh('natureBackground'),
433            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
434            'collision_mesh': bs.getcollisionmesh('roundaboutLevelCollide'),
435            'tex': bs.gettexture('roundaboutLevelColor'),
436            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
437            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
438            'railing_collision_mesh': (
439                bs.getcollisionmesh('roundaboutLevelBumper')
440            ),
441            'bg_material': bs.Material(),
442        }
443        data['bg_material'].add_actions(
444            actions=('modify_part_collision', 'friction', 10.0)
445        )
446        return data
447
448    def __init__(self) -> None:
449        super().__init__(vr_overlay_offset=(0, -1, 1))
450        shared = SharedObjects.get()
451        self.node = bs.newnode(
452            'terrain',
453            delegate=self,
454            attrs={
455                'collision_mesh': self.preloaddata['collision_mesh'],
456                'mesh': self.preloaddata['mesh'],
457                'color_texture': self.preloaddata['tex'],
458                'materials': [shared.footing_material],
459            },
460        )
461        self.bottom = bs.newnode(
462            'terrain',
463            attrs={
464                'mesh': self.preloaddata['mesh_bottom'],
465                'lighting': False,
466                'color_texture': self.preloaddata['tex'],
467            },
468        )
469        self.background = bs.newnode(
470            'terrain',
471            attrs={
472                'mesh': self.preloaddata['mesh_bg'],
473                'lighting': False,
474                'background': True,
475                'color_texture': self.preloaddata['mesh_bg_tex'],
476            },
477        )
478        bs.newnode(
479            'terrain',
480            attrs={
481                'mesh': self.preloaddata['bg_vr_fill_mesh'],
482                'lighting': False,
483                'vr_only': True,
484                'background': True,
485                'color_texture': self.preloaddata['mesh_bg_tex'],
486            },
487        )
488        self.bg_collide = bs.newnode(
489            'terrain',
490            attrs={
491                'collision_mesh': self.preloaddata['collide_bg'],
492                'materials': [
493                    shared.footing_material,
494                    self.preloaddata['bg_material'],
495                    shared.death_material,
496                ],
497            },
498        )
499        self.railing = bs.newnode(
500            'terrain',
501            attrs={
502                'collision_mesh': self.preloaddata['railing_collision_mesh'],
503                'materials': [shared.railing_material],
504                'bumper': True,
505            },
506        )
507        gnode = bs.getactivity().globalsnode
508        gnode.tint = (1.0, 1.05, 1.1)
509        gnode.ambient_color = (1.0, 1.05, 1.1)
510        gnode.shadow_ortho = True
511        gnode.vignette_outer = (0.63, 0.65, 0.7)
512        gnode.vignette_inner = (0.97, 0.95, 0.93)

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

Roundabout()
448    def __init__(self) -> None:
449        super().__init__(vr_overlay_offset=(0, -1, 1))
450        shared = SharedObjects.get()
451        self.node = bs.newnode(
452            'terrain',
453            delegate=self,
454            attrs={
455                'collision_mesh': self.preloaddata['collision_mesh'],
456                'mesh': self.preloaddata['mesh'],
457                'color_texture': self.preloaddata['tex'],
458                'materials': [shared.footing_material],
459            },
460        )
461        self.bottom = bs.newnode(
462            'terrain',
463            attrs={
464                'mesh': self.preloaddata['mesh_bottom'],
465                'lighting': False,
466                'color_texture': self.preloaddata['tex'],
467            },
468        )
469        self.background = bs.newnode(
470            'terrain',
471            attrs={
472                'mesh': self.preloaddata['mesh_bg'],
473                'lighting': False,
474                'background': True,
475                'color_texture': self.preloaddata['mesh_bg_tex'],
476            },
477        )
478        bs.newnode(
479            'terrain',
480            attrs={
481                'mesh': self.preloaddata['bg_vr_fill_mesh'],
482                'lighting': False,
483                'vr_only': True,
484                'background': True,
485                'color_texture': self.preloaddata['mesh_bg_tex'],
486            },
487        )
488        self.bg_collide = bs.newnode(
489            'terrain',
490            attrs={
491                'collision_mesh': self.preloaddata['collide_bg'],
492                'materials': [
493                    shared.footing_material,
494                    self.preloaddata['bg_material'],
495                    shared.death_material,
496                ],
497            },
498        )
499        self.railing = bs.newnode(
500            'terrain',
501            attrs={
502                'collision_mesh': self.preloaddata['railing_collision_mesh'],
503                'materials': [shared.railing_material],
504                'bumper': True,
505            },
506        )
507        gnode = bs.getactivity().globalsnode
508        gnode.tint = (1.0, 1.05, 1.1)
509        gnode.ambient_color = (1.0, 1.05, 1.1)
510        gnode.shadow_ortho = True
511        gnode.vignette_outer = (0.63, 0.65, 0.7)
512        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

name = 'Roundabout'
@override
@classmethod
def get_play_types(cls) -> list[str]:
415    @override
416    @classmethod
417    def get_play_types(cls) -> list[str]:
418        """Return valid play types for this map."""
419        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
421    @override
422    @classmethod
423    def get_preview_texture_name(cls) -> str:
424        return 'roundaboutPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
426    @override
427    @classmethod
428    def on_preload(cls) -> Any:
429        data: dict[str, Any] = {
430            'mesh': bs.getmesh('roundaboutLevel'),
431            'mesh_bottom': bs.getmesh('roundaboutLevelBottom'),
432            'mesh_bg': bs.getmesh('natureBackground'),
433            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
434            'collision_mesh': bs.getcollisionmesh('roundaboutLevelCollide'),
435            'tex': bs.gettexture('roundaboutLevelColor'),
436            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
437            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
438            'railing_collision_mesh': (
439                bs.getcollisionmesh('roundaboutLevelBumper')
440            ),
441            'bg_material': bs.Material(),
442        }
443        data['bg_material'].add_actions(
444            actions=('modify_part_collision', 'friction', 10.0)
445        )
446        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
bg_collide
railing
class MonkeyFace(bascenev1._map.Map):
515class MonkeyFace(bs.Map):
516    """Map sorta shaped like a monkey face; teehee!"""
517
518    # noinspection PyUnresolvedReferences
519    from bascenev1lib.mapdata import monkey_face as defs
520
521    name = 'Monkey Face'
522
523    @override
524    @classmethod
525    def get_play_types(cls) -> list[str]:
526        """Return valid play types for this map."""
527        return ['melee', 'keep_away', 'team_flag']
528
529    @override
530    @classmethod
531    def get_preview_texture_name(cls) -> str:
532        return 'monkeyFacePreview'
533
534    @override
535    @classmethod
536    def on_preload(cls) -> Any:
537        data: dict[str, Any] = {
538            'mesh': bs.getmesh('monkeyFaceLevel'),
539            'bottom_mesh': bs.getmesh('monkeyFaceLevelBottom'),
540            'mesh_bg': bs.getmesh('natureBackground'),
541            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
542            'collision_mesh': bs.getcollisionmesh('monkeyFaceLevelCollide'),
543            'tex': bs.gettexture('monkeyFaceLevelColor'),
544            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
545            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
546            'railing_collision_mesh': (
547                bs.getcollisionmesh('monkeyFaceLevelBumper')
548            ),
549            'bg_material': bs.Material(),
550        }
551        data['bg_material'].add_actions(
552            actions=('modify_part_collision', 'friction', 10.0)
553        )
554        return data
555
556    def __init__(self) -> None:
557        super().__init__()
558        shared = SharedObjects.get()
559        self.node = bs.newnode(
560            'terrain',
561            delegate=self,
562            attrs={
563                'collision_mesh': self.preloaddata['collision_mesh'],
564                'mesh': self.preloaddata['mesh'],
565                'color_texture': self.preloaddata['tex'],
566                'materials': [shared.footing_material],
567            },
568        )
569        self.bottom = bs.newnode(
570            'terrain',
571            attrs={
572                'mesh': self.preloaddata['bottom_mesh'],
573                'lighting': False,
574                'color_texture': self.preloaddata['tex'],
575            },
576        )
577        self.background = bs.newnode(
578            'terrain',
579            attrs={
580                'mesh': self.preloaddata['mesh_bg'],
581                'lighting': False,
582                'background': True,
583                'color_texture': self.preloaddata['mesh_bg_tex'],
584            },
585        )
586        bs.newnode(
587            'terrain',
588            attrs={
589                'mesh': self.preloaddata['bg_vr_fill_mesh'],
590                'lighting': False,
591                'vr_only': True,
592                'background': True,
593                'color_texture': self.preloaddata['mesh_bg_tex'],
594            },
595        )
596        self.bg_collide = bs.newnode(
597            'terrain',
598            attrs={
599                'collision_mesh': self.preloaddata['collide_bg'],
600                'materials': [
601                    shared.footing_material,
602                    self.preloaddata['bg_material'],
603                    shared.death_material,
604                ],
605            },
606        )
607        self.railing = bs.newnode(
608            'terrain',
609            attrs={
610                'collision_mesh': self.preloaddata['railing_collision_mesh'],
611                'materials': [shared.railing_material],
612                'bumper': True,
613            },
614        )
615        gnode = bs.getactivity().globalsnode
616        gnode.tint = (1.1, 1.2, 1.2)
617        gnode.ambient_color = (1.2, 1.3, 1.3)
618        gnode.vignette_outer = (0.60, 0.62, 0.66)
619        gnode.vignette_inner = (0.97, 0.95, 0.93)
620        gnode.vr_camera_offset = (-1.4, 0, 0)

Map sorta shaped like a monkey face; teehee!

MonkeyFace()
556    def __init__(self) -> None:
557        super().__init__()
558        shared = SharedObjects.get()
559        self.node = bs.newnode(
560            'terrain',
561            delegate=self,
562            attrs={
563                'collision_mesh': self.preloaddata['collision_mesh'],
564                'mesh': self.preloaddata['mesh'],
565                'color_texture': self.preloaddata['tex'],
566                'materials': [shared.footing_material],
567            },
568        )
569        self.bottom = bs.newnode(
570            'terrain',
571            attrs={
572                'mesh': self.preloaddata['bottom_mesh'],
573                'lighting': False,
574                'color_texture': self.preloaddata['tex'],
575            },
576        )
577        self.background = bs.newnode(
578            'terrain',
579            attrs={
580                'mesh': self.preloaddata['mesh_bg'],
581                'lighting': False,
582                'background': True,
583                'color_texture': self.preloaddata['mesh_bg_tex'],
584            },
585        )
586        bs.newnode(
587            'terrain',
588            attrs={
589                'mesh': self.preloaddata['bg_vr_fill_mesh'],
590                'lighting': False,
591                'vr_only': True,
592                'background': True,
593                'color_texture': self.preloaddata['mesh_bg_tex'],
594            },
595        )
596        self.bg_collide = bs.newnode(
597            'terrain',
598            attrs={
599                'collision_mesh': self.preloaddata['collide_bg'],
600                'materials': [
601                    shared.footing_material,
602                    self.preloaddata['bg_material'],
603                    shared.death_material,
604                ],
605            },
606        )
607        self.railing = bs.newnode(
608            'terrain',
609            attrs={
610                'collision_mesh': self.preloaddata['railing_collision_mesh'],
611                'materials': [shared.railing_material],
612                'bumper': True,
613            },
614        )
615        gnode = bs.getactivity().globalsnode
616        gnode.tint = (1.1, 1.2, 1.2)
617        gnode.ambient_color = (1.2, 1.3, 1.3)
618        gnode.vignette_outer = (0.60, 0.62, 0.66)
619        gnode.vignette_inner = (0.97, 0.95, 0.93)
620        gnode.vr_camera_offset = (-1.4, 0, 0)

Instantiate a map.

name = 'Monkey Face'
@override
@classmethod
def get_play_types(cls) -> list[str]:
523    @override
524    @classmethod
525    def get_play_types(cls) -> list[str]:
526        """Return valid play types for this map."""
527        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
529    @override
530    @classmethod
531    def get_preview_texture_name(cls) -> str:
532        return 'monkeyFacePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
534    @override
535    @classmethod
536    def on_preload(cls) -> Any:
537        data: dict[str, Any] = {
538            'mesh': bs.getmesh('monkeyFaceLevel'),
539            'bottom_mesh': bs.getmesh('monkeyFaceLevelBottom'),
540            'mesh_bg': bs.getmesh('natureBackground'),
541            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
542            'collision_mesh': bs.getcollisionmesh('monkeyFaceLevelCollide'),
543            'tex': bs.gettexture('monkeyFaceLevelColor'),
544            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
545            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
546            'railing_collision_mesh': (
547                bs.getcollisionmesh('monkeyFaceLevelBumper')
548            ),
549            'bg_material': bs.Material(),
550        }
551        data['bg_material'].add_actions(
552            actions=('modify_part_collision', 'friction', 10.0)
553        )
554        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
bg_collide
railing
class ZigZag(bascenev1._map.Map):
623class ZigZag(bs.Map):
624    """A very long zig-zaggy map"""
625
626    # noinspection PyUnresolvedReferences
627    from bascenev1lib.mapdata import zig_zag as defs
628
629    name = 'Zigzag'
630
631    @override
632    @classmethod
633    def get_play_types(cls) -> list[str]:
634        """Return valid play types for this map."""
635        return [
636            'melee',
637            'keep_away',
638            'team_flag',
639            'conquest',
640            'king_of_the_hill',
641        ]
642
643    @override
644    @classmethod
645    def get_preview_texture_name(cls) -> str:
646        return 'zigzagPreview'
647
648    @override
649    @classmethod
650    def on_preload(cls) -> Any:
651        data: dict[str, Any] = {
652            'mesh': bs.getmesh('zigZagLevel'),
653            'mesh_bottom': bs.getmesh('zigZagLevelBottom'),
654            'mesh_bg': bs.getmesh('natureBackground'),
655            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
656            'collision_mesh': bs.getcollisionmesh('zigZagLevelCollide'),
657            'tex': bs.gettexture('zigZagLevelColor'),
658            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
659            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
660            'railing_collision_mesh': bs.getcollisionmesh('zigZagLevelBumper'),
661            'bg_material': bs.Material(),
662        }
663        data['bg_material'].add_actions(
664            actions=('modify_part_collision', 'friction', 10.0)
665        )
666        return data
667
668    def __init__(self) -> None:
669        super().__init__()
670        shared = SharedObjects.get()
671        self.node = bs.newnode(
672            'terrain',
673            delegate=self,
674            attrs={
675                'collision_mesh': self.preloaddata['collision_mesh'],
676                'mesh': self.preloaddata['mesh'],
677                'color_texture': self.preloaddata['tex'],
678                'materials': [shared.footing_material],
679            },
680        )
681        self.background = bs.newnode(
682            'terrain',
683            attrs={
684                'mesh': self.preloaddata['mesh_bg'],
685                'lighting': False,
686                'color_texture': self.preloaddata['mesh_bg_tex'],
687            },
688        )
689        self.bottom = bs.newnode(
690            'terrain',
691            attrs={
692                'mesh': self.preloaddata['mesh_bottom'],
693                'lighting': False,
694                'color_texture': self.preloaddata['tex'],
695            },
696        )
697        bs.newnode(
698            'terrain',
699            attrs={
700                'mesh': self.preloaddata['bg_vr_fill_mesh'],
701                'lighting': False,
702                'vr_only': True,
703                'background': True,
704                'color_texture': self.preloaddata['mesh_bg_tex'],
705            },
706        )
707        self.bg_collide = bs.newnode(
708            'terrain',
709            attrs={
710                'collision_mesh': self.preloaddata['collide_bg'],
711                'materials': [
712                    shared.footing_material,
713                    self.preloaddata['bg_material'],
714                    shared.death_material,
715                ],
716            },
717        )
718        self.railing = bs.newnode(
719            'terrain',
720            attrs={
721                'collision_mesh': self.preloaddata['railing_collision_mesh'],
722                'materials': [shared.railing_material],
723                'bumper': True,
724            },
725        )
726        gnode = bs.getactivity().globalsnode
727        gnode.tint = (1.0, 1.15, 1.15)
728        gnode.ambient_color = (1.0, 1.15, 1.15)
729        gnode.vignette_outer = (0.57, 0.59, 0.63)
730        gnode.vignette_inner = (0.97, 0.95, 0.93)
731        gnode.vr_camera_offset = (-1.5, 0, 0)

A very long zig-zaggy map

ZigZag()
668    def __init__(self) -> None:
669        super().__init__()
670        shared = SharedObjects.get()
671        self.node = bs.newnode(
672            'terrain',
673            delegate=self,
674            attrs={
675                'collision_mesh': self.preloaddata['collision_mesh'],
676                'mesh': self.preloaddata['mesh'],
677                'color_texture': self.preloaddata['tex'],
678                'materials': [shared.footing_material],
679            },
680        )
681        self.background = bs.newnode(
682            'terrain',
683            attrs={
684                'mesh': self.preloaddata['mesh_bg'],
685                'lighting': False,
686                'color_texture': self.preloaddata['mesh_bg_tex'],
687            },
688        )
689        self.bottom = bs.newnode(
690            'terrain',
691            attrs={
692                'mesh': self.preloaddata['mesh_bottom'],
693                'lighting': False,
694                'color_texture': self.preloaddata['tex'],
695            },
696        )
697        bs.newnode(
698            'terrain',
699            attrs={
700                'mesh': self.preloaddata['bg_vr_fill_mesh'],
701                'lighting': False,
702                'vr_only': True,
703                'background': True,
704                'color_texture': self.preloaddata['mesh_bg_tex'],
705            },
706        )
707        self.bg_collide = bs.newnode(
708            'terrain',
709            attrs={
710                'collision_mesh': self.preloaddata['collide_bg'],
711                'materials': [
712                    shared.footing_material,
713                    self.preloaddata['bg_material'],
714                    shared.death_material,
715                ],
716            },
717        )
718        self.railing = bs.newnode(
719            'terrain',
720            attrs={
721                'collision_mesh': self.preloaddata['railing_collision_mesh'],
722                'materials': [shared.railing_material],
723                'bumper': True,
724            },
725        )
726        gnode = bs.getactivity().globalsnode
727        gnode.tint = (1.0, 1.15, 1.15)
728        gnode.ambient_color = (1.0, 1.15, 1.15)
729        gnode.vignette_outer = (0.57, 0.59, 0.63)
730        gnode.vignette_inner = (0.97, 0.95, 0.93)
731        gnode.vr_camera_offset = (-1.5, 0, 0)

Instantiate a map.

name = 'Zigzag'
@override
@classmethod
def get_play_types(cls) -> list[str]:
631    @override
632    @classmethod
633    def get_play_types(cls) -> list[str]:
634        """Return valid play types for this map."""
635        return [
636            'melee',
637            'keep_away',
638            'team_flag',
639            'conquest',
640            'king_of_the_hill',
641        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
643    @override
644    @classmethod
645    def get_preview_texture_name(cls) -> str:
646        return 'zigzagPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
648    @override
649    @classmethod
650    def on_preload(cls) -> Any:
651        data: dict[str, Any] = {
652            'mesh': bs.getmesh('zigZagLevel'),
653            'mesh_bottom': bs.getmesh('zigZagLevelBottom'),
654            'mesh_bg': bs.getmesh('natureBackground'),
655            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
656            'collision_mesh': bs.getcollisionmesh('zigZagLevelCollide'),
657            'tex': bs.gettexture('zigZagLevelColor'),
658            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
659            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
660            'railing_collision_mesh': bs.getcollisionmesh('zigZagLevelBumper'),
661            'bg_material': bs.Material(),
662        }
663        data['bg_material'].add_actions(
664            actions=('modify_part_collision', 'friction', 10.0)
665        )
666        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
background
bottom
bg_collide
railing
class ThePad(bascenev1._map.Map):
734class ThePad(bs.Map):
735    """A simple square shaped map with a raised edge."""
736
737    # noinspection PyUnresolvedReferences
738    from bascenev1lib.mapdata import the_pad as defs
739
740    name = 'The Pad'
741
742    @override
743    @classmethod
744    def get_play_types(cls) -> list[str]:
745        """Return valid play types for this map."""
746        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
747
748    @override
749    @classmethod
750    def get_preview_texture_name(cls) -> str:
751        return 'thePadPreview'
752
753    @override
754    @classmethod
755    def on_preload(cls) -> Any:
756        data: dict[str, Any] = {
757            'mesh': bs.getmesh('thePadLevel'),
758            'bottom_mesh': bs.getmesh('thePadLevelBottom'),
759            'collision_mesh': bs.getcollisionmesh('thePadLevelCollide'),
760            'tex': bs.gettexture('thePadLevelColor'),
761            'bgtex': bs.gettexture('menuBG'),
762            'bgmesh': bs.getmesh('thePadBG'),
763            'railing_collision_mesh': bs.getcollisionmesh('thePadLevelBumper'),
764            'vr_fill_mound_mesh': bs.getmesh('thePadVRFillMound'),
765            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
766        }
767        # fixme should chop this into vr/non-vr sections for efficiency
768        return data
769
770    def __init__(self) -> None:
771        super().__init__()
772        shared = SharedObjects.get()
773        self.node = bs.newnode(
774            'terrain',
775            delegate=self,
776            attrs={
777                'collision_mesh': self.preloaddata['collision_mesh'],
778                'mesh': self.preloaddata['mesh'],
779                'color_texture': self.preloaddata['tex'],
780                'materials': [shared.footing_material],
781            },
782        )
783        self.bottom = bs.newnode(
784            'terrain',
785            attrs={
786                'mesh': self.preloaddata['bottom_mesh'],
787                'lighting': False,
788                'color_texture': self.preloaddata['tex'],
789            },
790        )
791        self.background = bs.newnode(
792            'terrain',
793            attrs={
794                'mesh': self.preloaddata['bgmesh'],
795                'lighting': False,
796                'background': True,
797                'color_texture': self.preloaddata['bgtex'],
798            },
799        )
800        self.railing = bs.newnode(
801            'terrain',
802            attrs={
803                'collision_mesh': self.preloaddata['railing_collision_mesh'],
804                'materials': [shared.railing_material],
805                'bumper': True,
806            },
807        )
808        bs.newnode(
809            'terrain',
810            attrs={
811                'mesh': self.preloaddata['vr_fill_mound_mesh'],
812                'lighting': False,
813                'vr_only': True,
814                'color': (0.56, 0.55, 0.47),
815                'background': True,
816                'color_texture': self.preloaddata['vr_fill_mound_tex'],
817            },
818        )
819        gnode = bs.getactivity().globalsnode
820        gnode.tint = (1.1, 1.1, 1.0)
821        gnode.ambient_color = (1.1, 1.1, 1.0)
822        gnode.vignette_outer = (0.7, 0.65, 0.75)
823        gnode.vignette_inner = (0.95, 0.95, 0.93)

A simple square shaped map with a raised edge.

ThePad()
770    def __init__(self) -> None:
771        super().__init__()
772        shared = SharedObjects.get()
773        self.node = bs.newnode(
774            'terrain',
775            delegate=self,
776            attrs={
777                'collision_mesh': self.preloaddata['collision_mesh'],
778                'mesh': self.preloaddata['mesh'],
779                'color_texture': self.preloaddata['tex'],
780                'materials': [shared.footing_material],
781            },
782        )
783        self.bottom = bs.newnode(
784            'terrain',
785            attrs={
786                'mesh': self.preloaddata['bottom_mesh'],
787                'lighting': False,
788                'color_texture': self.preloaddata['tex'],
789            },
790        )
791        self.background = bs.newnode(
792            'terrain',
793            attrs={
794                'mesh': self.preloaddata['bgmesh'],
795                'lighting': False,
796                'background': True,
797                'color_texture': self.preloaddata['bgtex'],
798            },
799        )
800        self.railing = bs.newnode(
801            'terrain',
802            attrs={
803                'collision_mesh': self.preloaddata['railing_collision_mesh'],
804                'materials': [shared.railing_material],
805                'bumper': True,
806            },
807        )
808        bs.newnode(
809            'terrain',
810            attrs={
811                'mesh': self.preloaddata['vr_fill_mound_mesh'],
812                'lighting': False,
813                'vr_only': True,
814                'color': (0.56, 0.55, 0.47),
815                'background': True,
816                'color_texture': self.preloaddata['vr_fill_mound_tex'],
817            },
818        )
819        gnode = bs.getactivity().globalsnode
820        gnode.tint = (1.1, 1.1, 1.0)
821        gnode.ambient_color = (1.1, 1.1, 1.0)
822        gnode.vignette_outer = (0.7, 0.65, 0.75)
823        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

name = 'The Pad'
@override
@classmethod
def get_play_types(cls) -> list[str]:
742    @override
743    @classmethod
744    def get_play_types(cls) -> list[str]:
745        """Return valid play types for this map."""
746        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
748    @override
749    @classmethod
750    def get_preview_texture_name(cls) -> str:
751        return 'thePadPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
753    @override
754    @classmethod
755    def on_preload(cls) -> Any:
756        data: dict[str, Any] = {
757            'mesh': bs.getmesh('thePadLevel'),
758            'bottom_mesh': bs.getmesh('thePadLevelBottom'),
759            'collision_mesh': bs.getcollisionmesh('thePadLevelCollide'),
760            'tex': bs.gettexture('thePadLevelColor'),
761            'bgtex': bs.gettexture('menuBG'),
762            'bgmesh': bs.getmesh('thePadBG'),
763            'railing_collision_mesh': bs.getcollisionmesh('thePadLevelBumper'),
764            'vr_fill_mound_mesh': bs.getmesh('thePadVRFillMound'),
765            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
766        }
767        # fixme should chop this into vr/non-vr sections for efficiency
768        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
railing
class DoomShroom(bascenev1._map.Map):
826class DoomShroom(bs.Map):
827    """A giant mushroom. Of doom!"""
828
829    # noinspection PyUnresolvedReferences
830    from bascenev1lib.mapdata import doom_shroom as defs
831
832    name = 'Doom Shroom'
833
834    @override
835    @classmethod
836    def get_play_types(cls) -> list[str]:
837        """Return valid play types for this map."""
838        return ['melee', 'keep_away', 'team_flag']
839
840    @override
841    @classmethod
842    def get_preview_texture_name(cls) -> str:
843        return 'doomShroomPreview'
844
845    @override
846    @classmethod
847    def on_preload(cls) -> Any:
848        data: dict[str, Any] = {
849            'mesh': bs.getmesh('doomShroomLevel'),
850            'collision_mesh': bs.getcollisionmesh('doomShroomLevelCollide'),
851            'tex': bs.gettexture('doomShroomLevelColor'),
852            'bgtex': bs.gettexture('doomShroomBGColor'),
853            'bgmesh': bs.getmesh('doomShroomBG'),
854            'vr_fill_mesh': bs.getmesh('doomShroomVRFill'),
855            'stem_mesh': bs.getmesh('doomShroomStem'),
856            'collide_bg': bs.getcollisionmesh('doomShroomStemCollide'),
857        }
858        return data
859
860    def __init__(self) -> None:
861        super().__init__()
862        shared = SharedObjects.get()
863        self.node = bs.newnode(
864            'terrain',
865            delegate=self,
866            attrs={
867                'collision_mesh': self.preloaddata['collision_mesh'],
868                'mesh': self.preloaddata['mesh'],
869                'color_texture': self.preloaddata['tex'],
870                'materials': [shared.footing_material],
871            },
872        )
873        self.background = bs.newnode(
874            'terrain',
875            attrs={
876                'mesh': self.preloaddata['bgmesh'],
877                'lighting': False,
878                'background': True,
879                'color_texture': self.preloaddata['bgtex'],
880            },
881        )
882        bs.newnode(
883            'terrain',
884            attrs={
885                'mesh': self.preloaddata['vr_fill_mesh'],
886                'lighting': False,
887                'vr_only': True,
888                'background': True,
889                'color_texture': self.preloaddata['bgtex'],
890            },
891        )
892        self.stem = bs.newnode(
893            'terrain',
894            attrs={
895                'mesh': self.preloaddata['stem_mesh'],
896                'lighting': False,
897                'color_texture': self.preloaddata['tex'],
898            },
899        )
900        self.bg_collide = bs.newnode(
901            'terrain',
902            attrs={
903                'collision_mesh': self.preloaddata['collide_bg'],
904                'materials': [shared.footing_material, shared.death_material],
905            },
906        )
907        gnode = bs.getactivity().globalsnode
908        gnode.tint = (0.82, 1.10, 1.15)
909        gnode.ambient_color = (0.9, 1.3, 1.1)
910        gnode.shadow_ortho = False
911        gnode.vignette_outer = (0.76, 0.76, 0.76)
912        gnode.vignette_inner = (0.95, 0.95, 0.99)
913
914    @override
915    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
916        xpos = point.x
917        zpos = point.z
918        x_adj = xpos * 0.125
919        z_adj = (zpos + 3.7) * 0.2
920        if running:
921            x_adj *= 1.4
922            z_adj *= 1.4
923        return x_adj * x_adj + z_adj * z_adj > 1.0

A giant mushroom. Of doom!

DoomShroom()
860    def __init__(self) -> None:
861        super().__init__()
862        shared = SharedObjects.get()
863        self.node = bs.newnode(
864            'terrain',
865            delegate=self,
866            attrs={
867                'collision_mesh': self.preloaddata['collision_mesh'],
868                'mesh': self.preloaddata['mesh'],
869                'color_texture': self.preloaddata['tex'],
870                'materials': [shared.footing_material],
871            },
872        )
873        self.background = bs.newnode(
874            'terrain',
875            attrs={
876                'mesh': self.preloaddata['bgmesh'],
877                'lighting': False,
878                'background': True,
879                'color_texture': self.preloaddata['bgtex'],
880            },
881        )
882        bs.newnode(
883            'terrain',
884            attrs={
885                'mesh': self.preloaddata['vr_fill_mesh'],
886                'lighting': False,
887                'vr_only': True,
888                'background': True,
889                'color_texture': self.preloaddata['bgtex'],
890            },
891        )
892        self.stem = bs.newnode(
893            'terrain',
894            attrs={
895                'mesh': self.preloaddata['stem_mesh'],
896                'lighting': False,
897                'color_texture': self.preloaddata['tex'],
898            },
899        )
900        self.bg_collide = bs.newnode(
901            'terrain',
902            attrs={
903                'collision_mesh': self.preloaddata['collide_bg'],
904                'materials': [shared.footing_material, shared.death_material],
905            },
906        )
907        gnode = bs.getactivity().globalsnode
908        gnode.tint = (0.82, 1.10, 1.15)
909        gnode.ambient_color = (0.9, 1.3, 1.1)
910        gnode.shadow_ortho = False
911        gnode.vignette_outer = (0.76, 0.76, 0.76)
912        gnode.vignette_inner = (0.95, 0.95, 0.99)

Instantiate a map.

name = 'Doom Shroom'
@override
@classmethod
def get_play_types(cls) -> list[str]:
834    @override
835    @classmethod
836    def get_play_types(cls) -> list[str]:
837        """Return valid play types for this map."""
838        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
840    @override
841    @classmethod
842    def get_preview_texture_name(cls) -> str:
843        return 'doomShroomPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
845    @override
846    @classmethod
847    def on_preload(cls) -> Any:
848        data: dict[str, Any] = {
849            'mesh': bs.getmesh('doomShroomLevel'),
850            'collision_mesh': bs.getcollisionmesh('doomShroomLevelCollide'),
851            'tex': bs.gettexture('doomShroomLevelColor'),
852            'bgtex': bs.gettexture('doomShroomBGColor'),
853            'bgmesh': bs.getmesh('doomShroomBG'),
854            'vr_fill_mesh': bs.getmesh('doomShroomVRFill'),
855            'stem_mesh': bs.getmesh('doomShroomStem'),
856            'collide_bg': bs.getcollisionmesh('doomShroomStemCollide'),
857        }
858        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
background
stem
bg_collide
@override
def is_point_near_edge(self, point: _babase.Vec3, running: bool = False) -> bool:
914    @override
915    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
916        xpos = point.x
917        zpos = point.z
918        x_adj = xpos * 0.125
919        z_adj = (zpos + 3.7) * 0.2
920        if running:
921            x_adj *= 1.4
922            z_adj *= 1.4
923        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.

class LakeFrigid(bascenev1._map.Map):
 926class LakeFrigid(bs.Map):
 927    """An icy lake fit for racing."""
 928
 929    # noinspection PyUnresolvedReferences
 930    from bascenev1lib.mapdata import lake_frigid as defs
 931
 932    name = 'Lake Frigid'
 933
 934    @override
 935    @classmethod
 936    def get_play_types(cls) -> list[str]:
 937        """Return valid play types for this map."""
 938        return ['melee', 'keep_away', 'team_flag', 'race']
 939
 940    @override
 941    @classmethod
 942    def get_preview_texture_name(cls) -> str:
 943        return 'lakeFrigidPreview'
 944
 945    @override
 946    @classmethod
 947    def on_preload(cls) -> Any:
 948        data: dict[str, Any] = {
 949            'mesh': bs.getmesh('lakeFrigid'),
 950            'mesh_top': bs.getmesh('lakeFrigidTop'),
 951            'mesh_reflections': bs.getmesh('lakeFrigidReflections'),
 952            'collision_mesh': bs.getcollisionmesh('lakeFrigidCollide'),
 953            'tex': bs.gettexture('lakeFrigid'),
 954            'tex_reflections': bs.gettexture('lakeFrigidReflections'),
 955            'vr_fill_mesh': bs.getmesh('lakeFrigidVRFill'),
 956        }
 957        mat = bs.Material()
 958        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
 959        data['ice_material'] = mat
 960        return data
 961
 962    def __init__(self) -> None:
 963        super().__init__()
 964        shared = SharedObjects.get()
 965        self.node = bs.newnode(
 966            'terrain',
 967            delegate=self,
 968            attrs={
 969                'collision_mesh': self.preloaddata['collision_mesh'],
 970                'mesh': self.preloaddata['mesh'],
 971                'color_texture': self.preloaddata['tex'],
 972                'materials': [
 973                    shared.footing_material,
 974                    self.preloaddata['ice_material'],
 975                ],
 976            },
 977        )
 978        bs.newnode(
 979            'terrain',
 980            attrs={
 981                'mesh': self.preloaddata['mesh_top'],
 982                'lighting': False,
 983                'color_texture': self.preloaddata['tex'],
 984            },
 985        )
 986        bs.newnode(
 987            'terrain',
 988            attrs={
 989                'mesh': self.preloaddata['mesh_reflections'],
 990                'lighting': False,
 991                'overlay': True,
 992                'opacity': 0.15,
 993                'color_texture': self.preloaddata['tex_reflections'],
 994            },
 995        )
 996        bs.newnode(
 997            'terrain',
 998            attrs={
 999                'mesh': self.preloaddata['vr_fill_mesh'],
1000                'lighting': False,
1001                'vr_only': True,
1002                'background': True,
1003                'color_texture': self.preloaddata['tex'],
1004            },
1005        )
1006        gnode = bs.getactivity().globalsnode
1007        gnode.tint = (1, 1, 1)
1008        gnode.ambient_color = (1, 1, 1)
1009        gnode.shadow_ortho = True
1010        gnode.vignette_outer = (0.86, 0.86, 0.86)
1011        gnode.vignette_inner = (0.95, 0.95, 0.99)
1012        gnode.vr_near_clip = 0.5
1013        self.is_hockey = True

An icy lake fit for racing.

LakeFrigid()
 962    def __init__(self) -> None:
 963        super().__init__()
 964        shared = SharedObjects.get()
 965        self.node = bs.newnode(
 966            'terrain',
 967            delegate=self,
 968            attrs={
 969                'collision_mesh': self.preloaddata['collision_mesh'],
 970                'mesh': self.preloaddata['mesh'],
 971                'color_texture': self.preloaddata['tex'],
 972                'materials': [
 973                    shared.footing_material,
 974                    self.preloaddata['ice_material'],
 975                ],
 976            },
 977        )
 978        bs.newnode(
 979            'terrain',
 980            attrs={
 981                'mesh': self.preloaddata['mesh_top'],
 982                'lighting': False,
 983                'color_texture': self.preloaddata['tex'],
 984            },
 985        )
 986        bs.newnode(
 987            'terrain',
 988            attrs={
 989                'mesh': self.preloaddata['mesh_reflections'],
 990                'lighting': False,
 991                'overlay': True,
 992                'opacity': 0.15,
 993                'color_texture': self.preloaddata['tex_reflections'],
 994            },
 995        )
 996        bs.newnode(
 997            'terrain',
 998            attrs={
 999                'mesh': self.preloaddata['vr_fill_mesh'],
1000                'lighting': False,
1001                'vr_only': True,
1002                'background': True,
1003                'color_texture': self.preloaddata['tex'],
1004            },
1005        )
1006        gnode = bs.getactivity().globalsnode
1007        gnode.tint = (1, 1, 1)
1008        gnode.ambient_color = (1, 1, 1)
1009        gnode.shadow_ortho = True
1010        gnode.vignette_outer = (0.86, 0.86, 0.86)
1011        gnode.vignette_inner = (0.95, 0.95, 0.99)
1012        gnode.vr_near_clip = 0.5
1013        self.is_hockey = True

Instantiate a map.

name = 'Lake Frigid'
@override
@classmethod
def get_play_types(cls) -> list[str]:
934    @override
935    @classmethod
936    def get_play_types(cls) -> list[str]:
937        """Return valid play types for this map."""
938        return ['melee', 'keep_away', 'team_flag', 'race']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
940    @override
941    @classmethod
942    def get_preview_texture_name(cls) -> str:
943        return 'lakeFrigidPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
945    @override
946    @classmethod
947    def on_preload(cls) -> Any:
948        data: dict[str, Any] = {
949            'mesh': bs.getmesh('lakeFrigid'),
950            'mesh_top': bs.getmesh('lakeFrigidTop'),
951            'mesh_reflections': bs.getmesh('lakeFrigidReflections'),
952            'collision_mesh': bs.getcollisionmesh('lakeFrigidCollide'),
953            'tex': bs.gettexture('lakeFrigid'),
954            'tex_reflections': bs.gettexture('lakeFrigidReflections'),
955            'vr_fill_mesh': bs.getmesh('lakeFrigidVRFill'),
956        }
957        mat = bs.Material()
958        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
959        data['ice_material'] = mat
960        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
is_hockey
class TipTop(bascenev1._map.Map):
1016class TipTop(bs.Map):
1017    """A pointy map good for king-of-the-hill-ish games."""
1018
1019    # noinspection PyUnresolvedReferences
1020    from bascenev1lib.mapdata import tip_top as defs
1021
1022    name = 'Tip Top'
1023
1024    @override
1025    @classmethod
1026    def get_play_types(cls) -> list[str]:
1027        """Return valid play types for this map."""
1028        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
1029
1030    @override
1031    @classmethod
1032    def get_preview_texture_name(cls) -> str:
1033        return 'tipTopPreview'
1034
1035    @override
1036    @classmethod
1037    def on_preload(cls) -> Any:
1038        data: dict[str, Any] = {
1039            'mesh': bs.getmesh('tipTopLevel'),
1040            'bottom_mesh': bs.getmesh('tipTopLevelBottom'),
1041            'collision_mesh': bs.getcollisionmesh('tipTopLevelCollide'),
1042            'tex': bs.gettexture('tipTopLevelColor'),
1043            'bgtex': bs.gettexture('tipTopBGColor'),
1044            'bgmesh': bs.getmesh('tipTopBG'),
1045            'railing_collision_mesh': bs.getcollisionmesh('tipTopLevelBumper'),
1046        }
1047        return data
1048
1049    def __init__(self) -> None:
1050        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1051        shared = SharedObjects.get()
1052        self.node = bs.newnode(
1053            'terrain',
1054            delegate=self,
1055            attrs={
1056                'collision_mesh': self.preloaddata['collision_mesh'],
1057                'mesh': self.preloaddata['mesh'],
1058                'color_texture': self.preloaddata['tex'],
1059                'color': (0.7, 0.7, 0.7),
1060                'materials': [shared.footing_material],
1061            },
1062        )
1063        self.bottom = bs.newnode(
1064            'terrain',
1065            attrs={
1066                'mesh': self.preloaddata['bottom_mesh'],
1067                'lighting': False,
1068                'color': (0.7, 0.7, 0.7),
1069                'color_texture': self.preloaddata['tex'],
1070            },
1071        )
1072        self.background = bs.newnode(
1073            'terrain',
1074            attrs={
1075                'mesh': self.preloaddata['bgmesh'],
1076                'lighting': False,
1077                'color': (0.4, 0.4, 0.4),
1078                'background': True,
1079                'color_texture': self.preloaddata['bgtex'],
1080            },
1081        )
1082        self.railing = bs.newnode(
1083            'terrain',
1084            attrs={
1085                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1086                'materials': [shared.railing_material],
1087                'bumper': True,
1088            },
1089        )
1090        gnode = bs.getactivity().globalsnode
1091        gnode.tint = (0.8, 0.9, 1.3)
1092        gnode.ambient_color = (0.8, 0.9, 1.3)
1093        gnode.vignette_outer = (0.79, 0.79, 0.69)
1094        gnode.vignette_inner = (0.97, 0.97, 0.99)

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

TipTop()
1049    def __init__(self) -> None:
1050        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1051        shared = SharedObjects.get()
1052        self.node = bs.newnode(
1053            'terrain',
1054            delegate=self,
1055            attrs={
1056                'collision_mesh': self.preloaddata['collision_mesh'],
1057                'mesh': self.preloaddata['mesh'],
1058                'color_texture': self.preloaddata['tex'],
1059                'color': (0.7, 0.7, 0.7),
1060                'materials': [shared.footing_material],
1061            },
1062        )
1063        self.bottom = bs.newnode(
1064            'terrain',
1065            attrs={
1066                'mesh': self.preloaddata['bottom_mesh'],
1067                'lighting': False,
1068                'color': (0.7, 0.7, 0.7),
1069                'color_texture': self.preloaddata['tex'],
1070            },
1071        )
1072        self.background = bs.newnode(
1073            'terrain',
1074            attrs={
1075                'mesh': self.preloaddata['bgmesh'],
1076                'lighting': False,
1077                'color': (0.4, 0.4, 0.4),
1078                'background': True,
1079                'color_texture': self.preloaddata['bgtex'],
1080            },
1081        )
1082        self.railing = bs.newnode(
1083            'terrain',
1084            attrs={
1085                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1086                'materials': [shared.railing_material],
1087                'bumper': True,
1088            },
1089        )
1090        gnode = bs.getactivity().globalsnode
1091        gnode.tint = (0.8, 0.9, 1.3)
1092        gnode.ambient_color = (0.8, 0.9, 1.3)
1093        gnode.vignette_outer = (0.79, 0.79, 0.69)
1094        gnode.vignette_inner = (0.97, 0.97, 0.99)

Instantiate a map.

name = 'Tip Top'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1024    @override
1025    @classmethod
1026    def get_play_types(cls) -> list[str]:
1027        """Return valid play types for this map."""
1028        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1030    @override
1031    @classmethod
1032    def get_preview_texture_name(cls) -> str:
1033        return 'tipTopPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1035    @override
1036    @classmethod
1037    def on_preload(cls) -> Any:
1038        data: dict[str, Any] = {
1039            'mesh': bs.getmesh('tipTopLevel'),
1040            'bottom_mesh': bs.getmesh('tipTopLevelBottom'),
1041            'collision_mesh': bs.getcollisionmesh('tipTopLevelCollide'),
1042            'tex': bs.gettexture('tipTopLevelColor'),
1043            'bgtex': bs.gettexture('tipTopBGColor'),
1044            'bgmesh': bs.getmesh('tipTopBG'),
1045            'railing_collision_mesh': bs.getcollisionmesh('tipTopLevelBumper'),
1046        }
1047        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
railing
class CragCastle(bascenev1._map.Map):
1097class CragCastle(bs.Map):
1098    """A lovely castle map."""
1099
1100    # noinspection PyUnresolvedReferences
1101    from bascenev1lib.mapdata import crag_castle as defs
1102
1103    name = 'Crag Castle'
1104
1105    @override
1106    @classmethod
1107    def get_play_types(cls) -> list[str]:
1108        """Return valid play types for this map."""
1109        return ['melee', 'keep_away', 'team_flag', 'conquest']
1110
1111    @override
1112    @classmethod
1113    def get_preview_texture_name(cls) -> str:
1114        return 'cragCastlePreview'
1115
1116    @override
1117    @classmethod
1118    def on_preload(cls) -> Any:
1119        data: dict[str, Any] = {
1120            'mesh': bs.getmesh('cragCastleLevel'),
1121            'bottom_mesh': bs.getmesh('cragCastleLevelBottom'),
1122            'collision_mesh': bs.getcollisionmesh('cragCastleLevelCollide'),
1123            'tex': bs.gettexture('cragCastleLevelColor'),
1124            'bgtex': bs.gettexture('menuBG'),
1125            'bgmesh': bs.getmesh('thePadBG'),
1126            'railing_collision_mesh': (
1127                bs.getcollisionmesh('cragCastleLevelBumper')
1128            ),
1129            'vr_fill_mound_mesh': bs.getmesh('cragCastleVRFillMound'),
1130            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1131        }
1132        # fixme should chop this into vr/non-vr sections
1133        return data
1134
1135    def __init__(self) -> None:
1136        super().__init__()
1137        shared = SharedObjects.get()
1138        self.node = bs.newnode(
1139            'terrain',
1140            delegate=self,
1141            attrs={
1142                'collision_mesh': self.preloaddata['collision_mesh'],
1143                'mesh': self.preloaddata['mesh'],
1144                'color_texture': self.preloaddata['tex'],
1145                'materials': [shared.footing_material],
1146            },
1147        )
1148        self.bottom = bs.newnode(
1149            'terrain',
1150            attrs={
1151                'mesh': self.preloaddata['bottom_mesh'],
1152                'lighting': False,
1153                'color_texture': self.preloaddata['tex'],
1154            },
1155        )
1156        self.background = bs.newnode(
1157            'terrain',
1158            attrs={
1159                'mesh': self.preloaddata['bgmesh'],
1160                'lighting': False,
1161                'background': True,
1162                'color_texture': self.preloaddata['bgtex'],
1163            },
1164        )
1165        self.railing = bs.newnode(
1166            'terrain',
1167            attrs={
1168                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1169                'materials': [shared.railing_material],
1170                'bumper': True,
1171            },
1172        )
1173        bs.newnode(
1174            'terrain',
1175            attrs={
1176                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1177                'lighting': False,
1178                'vr_only': True,
1179                'color': (0.2, 0.25, 0.2),
1180                'background': True,
1181                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1182            },
1183        )
1184        gnode = bs.getactivity().globalsnode
1185        gnode.shadow_ortho = True
1186        gnode.shadow_offset = (0, 0, -5.0)
1187        gnode.tint = (1.15, 1.05, 0.75)
1188        gnode.ambient_color = (1.15, 1.05, 0.75)
1189        gnode.vignette_outer = (0.6, 0.65, 0.6)
1190        gnode.vignette_inner = (0.95, 0.95, 0.95)
1191        gnode.vr_near_clip = 1.0

A lovely castle map.

CragCastle()
1135    def __init__(self) -> None:
1136        super().__init__()
1137        shared = SharedObjects.get()
1138        self.node = bs.newnode(
1139            'terrain',
1140            delegate=self,
1141            attrs={
1142                'collision_mesh': self.preloaddata['collision_mesh'],
1143                'mesh': self.preloaddata['mesh'],
1144                'color_texture': self.preloaddata['tex'],
1145                'materials': [shared.footing_material],
1146            },
1147        )
1148        self.bottom = bs.newnode(
1149            'terrain',
1150            attrs={
1151                'mesh': self.preloaddata['bottom_mesh'],
1152                'lighting': False,
1153                'color_texture': self.preloaddata['tex'],
1154            },
1155        )
1156        self.background = bs.newnode(
1157            'terrain',
1158            attrs={
1159                'mesh': self.preloaddata['bgmesh'],
1160                'lighting': False,
1161                'background': True,
1162                'color_texture': self.preloaddata['bgtex'],
1163            },
1164        )
1165        self.railing = bs.newnode(
1166            'terrain',
1167            attrs={
1168                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1169                'materials': [shared.railing_material],
1170                'bumper': True,
1171            },
1172        )
1173        bs.newnode(
1174            'terrain',
1175            attrs={
1176                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1177                'lighting': False,
1178                'vr_only': True,
1179                'color': (0.2, 0.25, 0.2),
1180                'background': True,
1181                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1182            },
1183        )
1184        gnode = bs.getactivity().globalsnode
1185        gnode.shadow_ortho = True
1186        gnode.shadow_offset = (0, 0, -5.0)
1187        gnode.tint = (1.15, 1.05, 0.75)
1188        gnode.ambient_color = (1.15, 1.05, 0.75)
1189        gnode.vignette_outer = (0.6, 0.65, 0.6)
1190        gnode.vignette_inner = (0.95, 0.95, 0.95)
1191        gnode.vr_near_clip = 1.0

Instantiate a map.

name = 'Crag Castle'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1105    @override
1106    @classmethod
1107    def get_play_types(cls) -> list[str]:
1108        """Return valid play types for this map."""
1109        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1111    @override
1112    @classmethod
1113    def get_preview_texture_name(cls) -> str:
1114        return 'cragCastlePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1116    @override
1117    @classmethod
1118    def on_preload(cls) -> Any:
1119        data: dict[str, Any] = {
1120            'mesh': bs.getmesh('cragCastleLevel'),
1121            'bottom_mesh': bs.getmesh('cragCastleLevelBottom'),
1122            'collision_mesh': bs.getcollisionmesh('cragCastleLevelCollide'),
1123            'tex': bs.gettexture('cragCastleLevelColor'),
1124            'bgtex': bs.gettexture('menuBG'),
1125            'bgmesh': bs.getmesh('thePadBG'),
1126            'railing_collision_mesh': (
1127                bs.getcollisionmesh('cragCastleLevelBumper')
1128            ),
1129            'vr_fill_mound_mesh': bs.getmesh('cragCastleVRFillMound'),
1130            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1131        }
1132        # fixme should chop this into vr/non-vr sections
1133        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
bottom
background
railing
class TowerD(bascenev1._map.Map):
1194class TowerD(bs.Map):
1195    """Map used for runaround mini-game."""
1196
1197    from bascenev1lib.mapdata import tower_d as defs
1198
1199    name = 'Tower D'
1200
1201    @override
1202    @classmethod
1203    def get_play_types(cls) -> list[str]:
1204        """Return valid play types for this map."""
1205        return []
1206
1207    @override
1208    @classmethod
1209    def get_preview_texture_name(cls) -> str:
1210        return 'towerDPreview'
1211
1212    @override
1213    @classmethod
1214    def on_preload(cls) -> Any:
1215        data: dict[str, Any] = {
1216            'mesh': bs.getmesh('towerDLevel'),
1217            'mesh_bottom': bs.getmesh('towerDLevelBottom'),
1218            'collision_mesh': bs.getcollisionmesh('towerDLevelCollide'),
1219            'tex': bs.gettexture('towerDLevelColor'),
1220            'bgtex': bs.gettexture('menuBG'),
1221            'bgmesh': bs.getmesh('thePadBG'),
1222            'player_wall_collision_mesh': bs.getcollisionmesh(
1223                'towerDPlayerWall'
1224            ),
1225            'player_wall_material': bs.Material(),
1226        }
1227        # fixme should chop this into vr/non-vr sections
1228        data['player_wall_material'].add_actions(
1229            actions=('modify_part_collision', 'friction', 0.0)
1230        )
1231        # anything that needs to hit the wall can apply this material
1232        data['collide_with_wall_material'] = bs.Material()
1233        data['player_wall_material'].add_actions(
1234            conditions=(
1235                'they_dont_have_material',
1236                data['collide_with_wall_material'],
1237            ),
1238            actions=('modify_part_collision', 'collide', False),
1239        )
1240        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1241        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1242        return data
1243
1244    def __init__(self) -> None:
1245        super().__init__(vr_overlay_offset=(0, 1, 1))
1246        shared = SharedObjects.get()
1247        self.node = bs.newnode(
1248            'terrain',
1249            delegate=self,
1250            attrs={
1251                'collision_mesh': self.preloaddata['collision_mesh'],
1252                'mesh': self.preloaddata['mesh'],
1253                'color_texture': self.preloaddata['tex'],
1254                'materials': [shared.footing_material],
1255            },
1256        )
1257        self.node_bottom = bs.newnode(
1258            'terrain',
1259            delegate=self,
1260            attrs={
1261                'mesh': self.preloaddata['mesh_bottom'],
1262                'lighting': False,
1263                'color_texture': self.preloaddata['tex'],
1264            },
1265        )
1266        bs.newnode(
1267            'terrain',
1268            attrs={
1269                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1270                'lighting': False,
1271                'vr_only': True,
1272                'color': (0.53, 0.57, 0.5),
1273                'background': True,
1274                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1275            },
1276        )
1277        self.background = bs.newnode(
1278            'terrain',
1279            attrs={
1280                'mesh': self.preloaddata['bgmesh'],
1281                'lighting': False,
1282                'background': True,
1283                'color_texture': self.preloaddata['bgtex'],
1284            },
1285        )
1286        self.player_wall = bs.newnode(
1287            'terrain',
1288            attrs={
1289                'collision_mesh': self.preloaddata[
1290                    'player_wall_collision_mesh'
1291                ],
1292                'affect_bg_dynamics': False,
1293                'materials': [self.preloaddata['player_wall_material']],
1294            },
1295        )
1296        gnode = bs.getactivity().globalsnode
1297        gnode.tint = (1.15, 1.11, 1.03)
1298        gnode.ambient_color = (1.2, 1.1, 1.0)
1299        gnode.vignette_outer = (0.7, 0.73, 0.7)
1300        gnode.vignette_inner = (0.95, 0.95, 0.95)
1301
1302    @override
1303    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1304        # see if we're within edge_box
1305        boxes = self.defs.boxes
1306        box_position = boxes['edge_box'][0:3]
1307        box_scale = boxes['edge_box'][6:9]
1308        box_position2 = boxes['edge_box2'][0:3]
1309        box_scale2 = boxes['edge_box2'][6:9]
1310        xpos = (point.x - box_position[0]) / box_scale[0]
1311        zpos = (point.z - box_position[2]) / box_scale[2]
1312        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1313        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1314        # if we're outside of *both* boxes we're near the edge
1315        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1316            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1317        )

Map used for runaround mini-game.

TowerD()
1244    def __init__(self) -> None:
1245        super().__init__(vr_overlay_offset=(0, 1, 1))
1246        shared = SharedObjects.get()
1247        self.node = bs.newnode(
1248            'terrain',
1249            delegate=self,
1250            attrs={
1251                'collision_mesh': self.preloaddata['collision_mesh'],
1252                'mesh': self.preloaddata['mesh'],
1253                'color_texture': self.preloaddata['tex'],
1254                'materials': [shared.footing_material],
1255            },
1256        )
1257        self.node_bottom = bs.newnode(
1258            'terrain',
1259            delegate=self,
1260            attrs={
1261                'mesh': self.preloaddata['mesh_bottom'],
1262                'lighting': False,
1263                'color_texture': self.preloaddata['tex'],
1264            },
1265        )
1266        bs.newnode(
1267            'terrain',
1268            attrs={
1269                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1270                'lighting': False,
1271                'vr_only': True,
1272                'color': (0.53, 0.57, 0.5),
1273                'background': True,
1274                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1275            },
1276        )
1277        self.background = bs.newnode(
1278            'terrain',
1279            attrs={
1280                'mesh': self.preloaddata['bgmesh'],
1281                'lighting': False,
1282                'background': True,
1283                'color_texture': self.preloaddata['bgtex'],
1284            },
1285        )
1286        self.player_wall = bs.newnode(
1287            'terrain',
1288            attrs={
1289                'collision_mesh': self.preloaddata[
1290                    'player_wall_collision_mesh'
1291                ],
1292                'affect_bg_dynamics': False,
1293                'materials': [self.preloaddata['player_wall_material']],
1294            },
1295        )
1296        gnode = bs.getactivity().globalsnode
1297        gnode.tint = (1.15, 1.11, 1.03)
1298        gnode.ambient_color = (1.2, 1.1, 1.0)
1299        gnode.vignette_outer = (0.7, 0.73, 0.7)
1300        gnode.vignette_inner = (0.95, 0.95, 0.95)

Instantiate a map.

name = 'Tower D'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1201    @override
1202    @classmethod
1203    def get_play_types(cls) -> list[str]:
1204        """Return valid play types for this map."""
1205        return []

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1207    @override
1208    @classmethod
1209    def get_preview_texture_name(cls) -> str:
1210        return 'towerDPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1212    @override
1213    @classmethod
1214    def on_preload(cls) -> Any:
1215        data: dict[str, Any] = {
1216            'mesh': bs.getmesh('towerDLevel'),
1217            'mesh_bottom': bs.getmesh('towerDLevelBottom'),
1218            'collision_mesh': bs.getcollisionmesh('towerDLevelCollide'),
1219            'tex': bs.gettexture('towerDLevelColor'),
1220            'bgtex': bs.gettexture('menuBG'),
1221            'bgmesh': bs.getmesh('thePadBG'),
1222            'player_wall_collision_mesh': bs.getcollisionmesh(
1223                'towerDPlayerWall'
1224            ),
1225            'player_wall_material': bs.Material(),
1226        }
1227        # fixme should chop this into vr/non-vr sections
1228        data['player_wall_material'].add_actions(
1229            actions=('modify_part_collision', 'friction', 0.0)
1230        )
1231        # anything that needs to hit the wall can apply this material
1232        data['collide_with_wall_material'] = bs.Material()
1233        data['player_wall_material'].add_actions(
1234            conditions=(
1235                'they_dont_have_material',
1236                data['collide_with_wall_material'],
1237            ),
1238            actions=('modify_part_collision', 'collide', False),
1239        )
1240        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1241        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1242        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
node_bottom
background
player_wall
@override
def is_point_near_edge(self, point: _babase.Vec3, running: bool = False) -> bool:
1302    @override
1303    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1304        # see if we're within edge_box
1305        boxes = self.defs.boxes
1306        box_position = boxes['edge_box'][0:3]
1307        box_scale = boxes['edge_box'][6:9]
1308        box_position2 = boxes['edge_box2'][0:3]
1309        box_scale2 = boxes['edge_box2'][6:9]
1310        xpos = (point.x - box_position[0]) / box_scale[0]
1311        zpos = (point.z - box_position[2]) / box_scale[2]
1312        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1313        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1314        # if we're outside of *both* boxes we're near the edge
1315        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1316            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1317        )

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.

class HappyThoughts(bascenev1._map.Map):
1320class HappyThoughts(bs.Map):
1321    """Flying map."""
1322
1323    # noinspection PyUnresolvedReferences
1324    from bascenev1lib.mapdata import happy_thoughts as defs
1325
1326    name = 'Happy Thoughts'
1327
1328    @override
1329    @classmethod
1330    def get_play_types(cls) -> list[str]:
1331        """Return valid play types for this map."""
1332        return [
1333            'melee',
1334            'keep_away',
1335            'team_flag',
1336            'conquest',
1337            'king_of_the_hill',
1338        ]
1339
1340    @override
1341    @classmethod
1342    def get_preview_texture_name(cls) -> str:
1343        return 'alwaysLandPreview'
1344
1345    @override
1346    @classmethod
1347    def on_preload(cls) -> Any:
1348        data: dict[str, Any] = {
1349            'mesh': bs.getmesh('alwaysLandLevel'),
1350            'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
1351            'bgmesh': bs.getmesh('alwaysLandBG'),
1352            'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
1353            'tex': bs.gettexture('alwaysLandLevelColor'),
1354            'bgtex': bs.gettexture('alwaysLandBGColor'),
1355            'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
1356            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1357        }
1358        return data
1359
1360    @override
1361    @classmethod
1362    def get_music_type(cls) -> bs.MusicType:
1363        return bs.MusicType.FLYING
1364
1365    def __init__(self) -> None:
1366        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1367        shared = SharedObjects.get()
1368        self.node = bs.newnode(
1369            'terrain',
1370            delegate=self,
1371            attrs={
1372                'collision_mesh': self.preloaddata['collision_mesh'],
1373                'mesh': self.preloaddata['mesh'],
1374                'color_texture': self.preloaddata['tex'],
1375                'materials': [shared.footing_material],
1376            },
1377        )
1378        self.bottom = bs.newnode(
1379            'terrain',
1380            attrs={
1381                'mesh': self.preloaddata['bottom_mesh'],
1382                'lighting': False,
1383                'color_texture': self.preloaddata['tex'],
1384            },
1385        )
1386        self.background = bs.newnode(
1387            'terrain',
1388            attrs={
1389                'mesh': self.preloaddata['bgmesh'],
1390                'lighting': False,
1391                'background': True,
1392                'color_texture': self.preloaddata['bgtex'],
1393            },
1394        )
1395        bs.newnode(
1396            'terrain',
1397            attrs={
1398                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1399                'lighting': False,
1400                'vr_only': True,
1401                'color': (0.2, 0.25, 0.2),
1402                'background': True,
1403                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1404            },
1405        )
1406        gnode = bs.getactivity().globalsnode
1407        gnode.happy_thoughts_mode = True
1408        gnode.shadow_offset = (0.0, 8.0, 5.0)
1409        gnode.tint = (1.3, 1.23, 1.0)
1410        gnode.ambient_color = (1.3, 1.23, 1.0)
1411        gnode.vignette_outer = (0.64, 0.59, 0.69)
1412        gnode.vignette_inner = (0.95, 0.95, 0.93)
1413        gnode.vr_near_clip = 1.0
1414        self.is_flying = True
1415
1416        # throw out some tips on flying
1417        txt = bs.newnode(
1418            'text',
1419            attrs={
1420                'text': bs.Lstr(resource='pressJumpToFlyText'),
1421                'scale': 1.2,
1422                'maxwidth': 800,
1423                'position': (0, 200),
1424                'shadow': 0.5,
1425                'flatness': 0.5,
1426                'h_align': 'center',
1427                'v_attach': 'bottom',
1428            },
1429        )
1430        cmb = bs.newnode(
1431            'combine',
1432            owner=txt,
1433            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1434        )
1435        bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1436        cmb.connectattr('output', txt, 'color')
1437        bs.timer(10.0, txt.delete)

Flying map.

HappyThoughts()
1365    def __init__(self) -> None:
1366        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1367        shared = SharedObjects.get()
1368        self.node = bs.newnode(
1369            'terrain',
1370            delegate=self,
1371            attrs={
1372                'collision_mesh': self.preloaddata['collision_mesh'],
1373                'mesh': self.preloaddata['mesh'],
1374                'color_texture': self.preloaddata['tex'],
1375                'materials': [shared.footing_material],
1376            },
1377        )
1378        self.bottom = bs.newnode(
1379            'terrain',
1380            attrs={
1381                'mesh': self.preloaddata['bottom_mesh'],
1382                'lighting': False,
1383                'color_texture': self.preloaddata['tex'],
1384            },
1385        )
1386        self.background = bs.newnode(
1387            'terrain',
1388            attrs={
1389                'mesh': self.preloaddata['bgmesh'],
1390                'lighting': False,
1391                'background': True,
1392                'color_texture': self.preloaddata['bgtex'],
1393            },
1394        )
1395        bs.newnode(
1396            'terrain',
1397            attrs={
1398                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1399                'lighting': False,
1400                'vr_only': True,
1401                'color': (0.2, 0.25, 0.2),
1402                'background': True,
1403                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1404            },
1405        )
1406        gnode = bs.getactivity().globalsnode
1407        gnode.happy_thoughts_mode = True
1408        gnode.shadow_offset = (0.0, 8.0, 5.0)
1409        gnode.tint = (1.3, 1.23, 1.0)
1410        gnode.ambient_color = (1.3, 1.23, 1.0)
1411        gnode.vignette_outer = (0.64, 0.59, 0.69)
1412        gnode.vignette_inner = (0.95, 0.95, 0.93)
1413        gnode.vr_near_clip = 1.0
1414        self.is_flying = True
1415
1416        # throw out some tips on flying
1417        txt = bs.newnode(
1418            'text',
1419            attrs={
1420                'text': bs.Lstr(resource='pressJumpToFlyText'),
1421                'scale': 1.2,
1422                'maxwidth': 800,
1423                'position': (0, 200),
1424                'shadow': 0.5,
1425                'flatness': 0.5,
1426                'h_align': 'center',
1427                'v_attach': 'bottom',
1428            },
1429        )
1430        cmb = bs.newnode(
1431            'combine',
1432            owner=txt,
1433            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1434        )
1435        bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1436        cmb.connectattr('output', txt, 'color')
1437        bs.timer(10.0, txt.delete)

Instantiate a map.

name = 'Happy Thoughts'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1328    @override
1329    @classmethod
1330    def get_play_types(cls) -> list[str]:
1331        """Return valid play types for this map."""
1332        return [
1333            'melee',
1334            'keep_away',
1335            'team_flag',
1336            'conquest',
1337            'king_of_the_hill',
1338        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1340    @override
1341    @classmethod
1342    def get_preview_texture_name(cls) -> str:
1343        return 'alwaysLandPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1345    @override
1346    @classmethod
1347    def on_preload(cls) -> Any:
1348        data: dict[str, Any] = {
1349            'mesh': bs.getmesh('alwaysLandLevel'),
1350            'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
1351            'bgmesh': bs.getmesh('alwaysLandBG'),
1352            'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
1353            'tex': bs.gettexture('alwaysLandLevelColor'),
1354            'bgtex': bs.gettexture('alwaysLandBGColor'),
1355            'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
1356            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1357        }
1358        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

@override
@classmethod
def get_music_type(cls) -> bascenev1.MusicType:
1360    @override
1361    @classmethod
1362    def get_music_type(cls) -> bs.MusicType:
1363        return bs.MusicType.FLYING

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

If None is returned, default music will be used.

node
bottom
background
is_flying
class StepRightUp(bascenev1._map.Map):
1440class StepRightUp(bs.Map):
1441    """Wide stepped map good for CTF or Assault."""
1442
1443    # noinspection PyUnresolvedReferences
1444    from bascenev1lib.mapdata import step_right_up as defs
1445
1446    name = 'Step Right Up'
1447
1448    @override
1449    @classmethod
1450    def get_play_types(cls) -> list[str]:
1451        """Return valid play types for this map."""
1452        return ['melee', 'keep_away', 'team_flag', 'conquest']
1453
1454    @override
1455    @classmethod
1456    def get_preview_texture_name(cls) -> str:
1457        return 'stepRightUpPreview'
1458
1459    @override
1460    @classmethod
1461    def on_preload(cls) -> Any:
1462        data: dict[str, Any] = {
1463            'mesh': bs.getmesh('stepRightUpLevel'),
1464            'mesh_bottom': bs.getmesh('stepRightUpLevelBottom'),
1465            'collision_mesh': bs.getcollisionmesh('stepRightUpLevelCollide'),
1466            'tex': bs.gettexture('stepRightUpLevelColor'),
1467            'bgtex': bs.gettexture('menuBG'),
1468            'bgmesh': bs.getmesh('thePadBG'),
1469            'vr_fill_mound_mesh': bs.getmesh('stepRightUpVRFillMound'),
1470            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1471        }
1472        # fixme should chop this into vr/non-vr chunks
1473        return data
1474
1475    def __init__(self) -> None:
1476        super().__init__(vr_overlay_offset=(0, -1, 2))
1477        shared = SharedObjects.get()
1478        self.node = bs.newnode(
1479            'terrain',
1480            delegate=self,
1481            attrs={
1482                'collision_mesh': self.preloaddata['collision_mesh'],
1483                'mesh': self.preloaddata['mesh'],
1484                'color_texture': self.preloaddata['tex'],
1485                'materials': [shared.footing_material],
1486            },
1487        )
1488        self.node_bottom = bs.newnode(
1489            'terrain',
1490            delegate=self,
1491            attrs={
1492                'mesh': self.preloaddata['mesh_bottom'],
1493                'lighting': False,
1494                'color_texture': self.preloaddata['tex'],
1495            },
1496        )
1497        bs.newnode(
1498            'terrain',
1499            attrs={
1500                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1501                'lighting': False,
1502                'vr_only': True,
1503                'color': (0.53, 0.57, 0.5),
1504                'background': True,
1505                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1506            },
1507        )
1508        self.background = bs.newnode(
1509            'terrain',
1510            attrs={
1511                'mesh': self.preloaddata['bgmesh'],
1512                'lighting': False,
1513                'background': True,
1514                'color_texture': self.preloaddata['bgtex'],
1515            },
1516        )
1517        gnode = bs.getactivity().globalsnode
1518        gnode.tint = (1.2, 1.1, 1.0)
1519        gnode.ambient_color = (1.2, 1.1, 1.0)
1520        gnode.vignette_outer = (0.7, 0.65, 0.75)
1521        gnode.vignette_inner = (0.95, 0.95, 0.93)

Wide stepped map good for CTF or Assault.

StepRightUp()
1475    def __init__(self) -> None:
1476        super().__init__(vr_overlay_offset=(0, -1, 2))
1477        shared = SharedObjects.get()
1478        self.node = bs.newnode(
1479            'terrain',
1480            delegate=self,
1481            attrs={
1482                'collision_mesh': self.preloaddata['collision_mesh'],
1483                'mesh': self.preloaddata['mesh'],
1484                'color_texture': self.preloaddata['tex'],
1485                'materials': [shared.footing_material],
1486            },
1487        )
1488        self.node_bottom = bs.newnode(
1489            'terrain',
1490            delegate=self,
1491            attrs={
1492                'mesh': self.preloaddata['mesh_bottom'],
1493                'lighting': False,
1494                'color_texture': self.preloaddata['tex'],
1495            },
1496        )
1497        bs.newnode(
1498            'terrain',
1499            attrs={
1500                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1501                'lighting': False,
1502                'vr_only': True,
1503                'color': (0.53, 0.57, 0.5),
1504                'background': True,
1505                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1506            },
1507        )
1508        self.background = bs.newnode(
1509            'terrain',
1510            attrs={
1511                'mesh': self.preloaddata['bgmesh'],
1512                'lighting': False,
1513                'background': True,
1514                'color_texture': self.preloaddata['bgtex'],
1515            },
1516        )
1517        gnode = bs.getactivity().globalsnode
1518        gnode.tint = (1.2, 1.1, 1.0)
1519        gnode.ambient_color = (1.2, 1.1, 1.0)
1520        gnode.vignette_outer = (0.7, 0.65, 0.75)
1521        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

name = 'Step Right Up'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1448    @override
1449    @classmethod
1450    def get_play_types(cls) -> list[str]:
1451        """Return valid play types for this map."""
1452        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1454    @override
1455    @classmethod
1456    def get_preview_texture_name(cls) -> str:
1457        return 'stepRightUpPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1459    @override
1460    @classmethod
1461    def on_preload(cls) -> Any:
1462        data: dict[str, Any] = {
1463            'mesh': bs.getmesh('stepRightUpLevel'),
1464            'mesh_bottom': bs.getmesh('stepRightUpLevelBottom'),
1465            'collision_mesh': bs.getcollisionmesh('stepRightUpLevelCollide'),
1466            'tex': bs.gettexture('stepRightUpLevelColor'),
1467            'bgtex': bs.gettexture('menuBG'),
1468            'bgmesh': bs.getmesh('thePadBG'),
1469            'vr_fill_mound_mesh': bs.getmesh('stepRightUpVRFillMound'),
1470            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1471        }
1472        # fixme should chop this into vr/non-vr chunks
1473        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
node_bottom
background
class Courtyard(bascenev1._map.Map):
1524class Courtyard(bs.Map):
1525    """A courtyard-ish looking map for co-op levels."""
1526
1527    from bascenev1lib.mapdata import courtyard as defs
1528
1529    name = 'Courtyard'
1530
1531    @override
1532    @classmethod
1533    def get_play_types(cls) -> list[str]:
1534        """Return valid play types for this map."""
1535        return ['melee', 'keep_away', 'team_flag']
1536
1537    @override
1538    @classmethod
1539    def get_preview_texture_name(cls) -> str:
1540        return 'courtyardPreview'
1541
1542    @override
1543    @classmethod
1544    def on_preload(cls) -> Any:
1545        data: dict[str, Any] = {
1546            'mesh': bs.getmesh('courtyardLevel'),
1547            'mesh_bottom': bs.getmesh('courtyardLevelBottom'),
1548            'collision_mesh': bs.getcollisionmesh('courtyardLevelCollide'),
1549            'tex': bs.gettexture('courtyardLevelColor'),
1550            'bgtex': bs.gettexture('menuBG'),
1551            'bgmesh': bs.getmesh('thePadBG'),
1552            'player_wall_collision_mesh': (
1553                bs.getcollisionmesh('courtyardPlayerWall')
1554            ),
1555            'player_wall_material': bs.Material(),
1556        }
1557        # FIXME: Chop this into vr and non-vr chunks.
1558        data['player_wall_material'].add_actions(
1559            actions=('modify_part_collision', 'friction', 0.0)
1560        )
1561        # anything that needs to hit the wall should apply this.
1562        data['collide_with_wall_material'] = bs.Material()
1563        data['player_wall_material'].add_actions(
1564            conditions=(
1565                'they_dont_have_material',
1566                data['collide_with_wall_material'],
1567            ),
1568            actions=('modify_part_collision', 'collide', False),
1569        )
1570        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1571        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1572        return data
1573
1574    def __init__(self) -> None:
1575        super().__init__()
1576        shared = SharedObjects.get()
1577        self.node = bs.newnode(
1578            'terrain',
1579            delegate=self,
1580            attrs={
1581                'collision_mesh': self.preloaddata['collision_mesh'],
1582                'mesh': self.preloaddata['mesh'],
1583                'color_texture': self.preloaddata['tex'],
1584                'materials': [shared.footing_material],
1585            },
1586        )
1587        self.background = bs.newnode(
1588            'terrain',
1589            attrs={
1590                'mesh': self.preloaddata['bgmesh'],
1591                'lighting': False,
1592                'background': True,
1593                'color_texture': self.preloaddata['bgtex'],
1594            },
1595        )
1596        self.bottom = bs.newnode(
1597            'terrain',
1598            attrs={
1599                'mesh': self.preloaddata['mesh_bottom'],
1600                'lighting': False,
1601                'color_texture': self.preloaddata['tex'],
1602            },
1603        )
1604        bs.newnode(
1605            'terrain',
1606            attrs={
1607                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1608                'lighting': False,
1609                'vr_only': True,
1610                'color': (0.53, 0.57, 0.5),
1611                'background': True,
1612                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1613            },
1614        )
1615        # in co-op mode games, put up a wall to prevent players
1616        # from getting in the turrets (that would foil our brilliant AI)
1617        if isinstance(bs.getsession(), bs.CoopSession):
1618            cmesh = self.preloaddata['player_wall_collision_mesh']
1619            self.player_wall = bs.newnode(
1620                'terrain',
1621                attrs={
1622                    'collision_mesh': cmesh,
1623                    'affect_bg_dynamics': False,
1624                    'materials': [self.preloaddata['player_wall_material']],
1625                },
1626            )
1627        gnode = bs.getactivity().globalsnode
1628        gnode.tint = (1.2, 1.17, 1.1)
1629        gnode.ambient_color = (1.2, 1.17, 1.1)
1630        gnode.vignette_outer = (0.6, 0.6, 0.64)
1631        gnode.vignette_inner = (0.95, 0.95, 0.93)
1632
1633    @override
1634    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1635        # count anything off our ground level as safe (for our platforms)
1636        # see if we're within edge_box
1637        box_position = self.defs.boxes['edge_box'][0:3]
1638        box_scale = self.defs.boxes['edge_box'][6:9]
1639        xpos = (point.x - box_position[0]) / box_scale[0]
1640        zpos = (point.z - box_position[2]) / box_scale[2]
1641        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()
1574    def __init__(self) -> None:
1575        super().__init__()
1576        shared = SharedObjects.get()
1577        self.node = bs.newnode(
1578            'terrain',
1579            delegate=self,
1580            attrs={
1581                'collision_mesh': self.preloaddata['collision_mesh'],
1582                'mesh': self.preloaddata['mesh'],
1583                'color_texture': self.preloaddata['tex'],
1584                'materials': [shared.footing_material],
1585            },
1586        )
1587        self.background = bs.newnode(
1588            'terrain',
1589            attrs={
1590                'mesh': self.preloaddata['bgmesh'],
1591                'lighting': False,
1592                'background': True,
1593                'color_texture': self.preloaddata['bgtex'],
1594            },
1595        )
1596        self.bottom = bs.newnode(
1597            'terrain',
1598            attrs={
1599                'mesh': self.preloaddata['mesh_bottom'],
1600                'lighting': False,
1601                'color_texture': self.preloaddata['tex'],
1602            },
1603        )
1604        bs.newnode(
1605            'terrain',
1606            attrs={
1607                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1608                'lighting': False,
1609                'vr_only': True,
1610                'color': (0.53, 0.57, 0.5),
1611                'background': True,
1612                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1613            },
1614        )
1615        # in co-op mode games, put up a wall to prevent players
1616        # from getting in the turrets (that would foil our brilliant AI)
1617        if isinstance(bs.getsession(), bs.CoopSession):
1618            cmesh = self.preloaddata['player_wall_collision_mesh']
1619            self.player_wall = bs.newnode(
1620                'terrain',
1621                attrs={
1622                    'collision_mesh': cmesh,
1623                    'affect_bg_dynamics': False,
1624                    'materials': [self.preloaddata['player_wall_material']],
1625                },
1626            )
1627        gnode = bs.getactivity().globalsnode
1628        gnode.tint = (1.2, 1.17, 1.1)
1629        gnode.ambient_color = (1.2, 1.17, 1.1)
1630        gnode.vignette_outer = (0.6, 0.6, 0.64)
1631        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

name = 'Courtyard'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1531    @override
1532    @classmethod
1533    def get_play_types(cls) -> list[str]:
1534        """Return valid play types for this map."""
1535        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1537    @override
1538    @classmethod
1539    def get_preview_texture_name(cls) -> str:
1540        return 'courtyardPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1542    @override
1543    @classmethod
1544    def on_preload(cls) -> Any:
1545        data: dict[str, Any] = {
1546            'mesh': bs.getmesh('courtyardLevel'),
1547            'mesh_bottom': bs.getmesh('courtyardLevelBottom'),
1548            'collision_mesh': bs.getcollisionmesh('courtyardLevelCollide'),
1549            'tex': bs.gettexture('courtyardLevelColor'),
1550            'bgtex': bs.gettexture('menuBG'),
1551            'bgmesh': bs.getmesh('thePadBG'),
1552            'player_wall_collision_mesh': (
1553                bs.getcollisionmesh('courtyardPlayerWall')
1554            ),
1555            'player_wall_material': bs.Material(),
1556        }
1557        # FIXME: Chop this into vr and non-vr chunks.
1558        data['player_wall_material'].add_actions(
1559            actions=('modify_part_collision', 'friction', 0.0)
1560        )
1561        # anything that needs to hit the wall should apply this.
1562        data['collide_with_wall_material'] = bs.Material()
1563        data['player_wall_material'].add_actions(
1564            conditions=(
1565                'they_dont_have_material',
1566                data['collide_with_wall_material'],
1567            ),
1568            actions=('modify_part_collision', 'collide', False),
1569        )
1570        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1571        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1572        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
background
bottom
@override
def is_point_near_edge(self, point: _babase.Vec3, running: bool = False) -> bool:
1633    @override
1634    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1635        # count anything off our ground level as safe (for our platforms)
1636        # see if we're within edge_box
1637        box_position = self.defs.boxes['edge_box'][0:3]
1638        box_scale = self.defs.boxes['edge_box'][6:9]
1639        xpos = (point.x - box_position[0]) / box_scale[0]
1640        zpos = (point.z - box_position[2]) / box_scale[2]
1641        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.

class Rampage(bascenev1._map.Map):
1644class Rampage(bs.Map):
1645    """Wee little map with ramps on the sides."""
1646
1647    from bascenev1lib.mapdata import rampage as defs
1648
1649    name = 'Rampage'
1650
1651    @override
1652    @classmethod
1653    def get_play_types(cls) -> list[str]:
1654        """Return valid play types for this map."""
1655        return ['melee', 'keep_away', 'team_flag']
1656
1657    @override
1658    @classmethod
1659    def get_preview_texture_name(cls) -> str:
1660        return 'rampagePreview'
1661
1662    @override
1663    @classmethod
1664    def on_preload(cls) -> Any:
1665        data: dict[str, Any] = {
1666            'mesh': bs.getmesh('rampageLevel'),
1667            'bottom_mesh': bs.getmesh('rampageLevelBottom'),
1668            'collision_mesh': bs.getcollisionmesh('rampageLevelCollide'),
1669            'tex': bs.gettexture('rampageLevelColor'),
1670            'bgtex': bs.gettexture('rampageBGColor'),
1671            'bgtex2': bs.gettexture('rampageBGColor2'),
1672            'bgmesh': bs.getmesh('rampageBG'),
1673            'bgmesh2': bs.getmesh('rampageBG2'),
1674            'vr_fill_mesh': bs.getmesh('rampageVRFill'),
1675            'railing_collision_mesh': bs.getcollisionmesh('rampageBumper'),
1676        }
1677        return data
1678
1679    def __init__(self) -> None:
1680        super().__init__(vr_overlay_offset=(0, 0, 2))
1681        shared = SharedObjects.get()
1682        self.node = bs.newnode(
1683            'terrain',
1684            delegate=self,
1685            attrs={
1686                'collision_mesh': self.preloaddata['collision_mesh'],
1687                'mesh': self.preloaddata['mesh'],
1688                'color_texture': self.preloaddata['tex'],
1689                'materials': [shared.footing_material],
1690            },
1691        )
1692        self.background = bs.newnode(
1693            'terrain',
1694            attrs={
1695                'mesh': self.preloaddata['bgmesh'],
1696                'lighting': False,
1697                'background': True,
1698                'color_texture': self.preloaddata['bgtex'],
1699            },
1700        )
1701        self.bottom = bs.newnode(
1702            'terrain',
1703            attrs={
1704                'mesh': self.preloaddata['bottom_mesh'],
1705                'lighting': False,
1706                'color_texture': self.preloaddata['tex'],
1707            },
1708        )
1709        self.bg2 = bs.newnode(
1710            'terrain',
1711            attrs={
1712                'mesh': self.preloaddata['bgmesh2'],
1713                'lighting': False,
1714                'background': True,
1715                'color_texture': self.preloaddata['bgtex2'],
1716            },
1717        )
1718        bs.newnode(
1719            'terrain',
1720            attrs={
1721                'mesh': self.preloaddata['vr_fill_mesh'],
1722                'lighting': False,
1723                'vr_only': True,
1724                'background': True,
1725                'color_texture': self.preloaddata['bgtex2'],
1726            },
1727        )
1728        self.railing = bs.newnode(
1729            'terrain',
1730            attrs={
1731                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1732                'materials': [shared.railing_material],
1733                'bumper': True,
1734            },
1735        )
1736        gnode = bs.getactivity().globalsnode
1737        gnode.tint = (1.2, 1.1, 0.97)
1738        gnode.ambient_color = (1.3, 1.2, 1.03)
1739        gnode.vignette_outer = (0.62, 0.64, 0.69)
1740        gnode.vignette_inner = (0.97, 0.95, 0.93)
1741
1742    @override
1743    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1744        box_position = self.defs.boxes['edge_box'][0:3]
1745        box_scale = self.defs.boxes['edge_box'][6:9]
1746        xpos = (point.x - box_position[0]) / box_scale[0]
1747        zpos = (point.z - box_position[2]) / box_scale[2]
1748        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()
1679    def __init__(self) -> None:
1680        super().__init__(vr_overlay_offset=(0, 0, 2))
1681        shared = SharedObjects.get()
1682        self.node = bs.newnode(
1683            'terrain',
1684            delegate=self,
1685            attrs={
1686                'collision_mesh': self.preloaddata['collision_mesh'],
1687                'mesh': self.preloaddata['mesh'],
1688                'color_texture': self.preloaddata['tex'],
1689                'materials': [shared.footing_material],
1690            },
1691        )
1692        self.background = bs.newnode(
1693            'terrain',
1694            attrs={
1695                'mesh': self.preloaddata['bgmesh'],
1696                'lighting': False,
1697                'background': True,
1698                'color_texture': self.preloaddata['bgtex'],
1699            },
1700        )
1701        self.bottom = bs.newnode(
1702            'terrain',
1703            attrs={
1704                'mesh': self.preloaddata['bottom_mesh'],
1705                'lighting': False,
1706                'color_texture': self.preloaddata['tex'],
1707            },
1708        )
1709        self.bg2 = bs.newnode(
1710            'terrain',
1711            attrs={
1712                'mesh': self.preloaddata['bgmesh2'],
1713                'lighting': False,
1714                'background': True,
1715                'color_texture': self.preloaddata['bgtex2'],
1716            },
1717        )
1718        bs.newnode(
1719            'terrain',
1720            attrs={
1721                'mesh': self.preloaddata['vr_fill_mesh'],
1722                'lighting': False,
1723                'vr_only': True,
1724                'background': True,
1725                'color_texture': self.preloaddata['bgtex2'],
1726            },
1727        )
1728        self.railing = bs.newnode(
1729            'terrain',
1730            attrs={
1731                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1732                'materials': [shared.railing_material],
1733                'bumper': True,
1734            },
1735        )
1736        gnode = bs.getactivity().globalsnode
1737        gnode.tint = (1.2, 1.1, 0.97)
1738        gnode.ambient_color = (1.3, 1.2, 1.03)
1739        gnode.vignette_outer = (0.62, 0.64, 0.69)
1740        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

name = 'Rampage'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1651    @override
1652    @classmethod
1653    def get_play_types(cls) -> list[str]:
1654        """Return valid play types for this map."""
1655        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1657    @override
1658    @classmethod
1659    def get_preview_texture_name(cls) -> str:
1660        return 'rampagePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1662    @override
1663    @classmethod
1664    def on_preload(cls) -> Any:
1665        data: dict[str, Any] = {
1666            'mesh': bs.getmesh('rampageLevel'),
1667            'bottom_mesh': bs.getmesh('rampageLevelBottom'),
1668            'collision_mesh': bs.getcollisionmesh('rampageLevelCollide'),
1669            'tex': bs.gettexture('rampageLevelColor'),
1670            'bgtex': bs.gettexture('rampageBGColor'),
1671            'bgtex2': bs.gettexture('rampageBGColor2'),
1672            'bgmesh': bs.getmesh('rampageBG'),
1673            'bgmesh2': bs.getmesh('rampageBG2'),
1674            'vr_fill_mesh': bs.getmesh('rampageVRFill'),
1675            'railing_collision_mesh': bs.getcollisionmesh('rampageBumper'),
1676        }
1677        return data

Called when the map is being preloaded.

It should return any media/data it requires to operate

node
background
bottom
bg2
railing
@override
def is_point_near_edge(self, point: _babase.Vec3, running: bool = False) -> bool:
1742    @override
1743    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1744        box_position = self.defs.boxes['edge_box'][0:3]
1745        box_scale = self.defs.boxes['edge_box'][6:9]
1746        xpos = (point.x - box_position[0]) / box_scale[0]
1747        zpos = (point.z - box_position[2]) / box_scale[2]
1748        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.