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

Registering all maps.

class HockeyStadium(bascenev1._map.Map):
 43class HockeyStadium(bs.Map):
 44    """Stadium map used for ice hockey games."""
 45
 46    # noinspection PyUnresolvedReferences
 47    from bascenev1lib.mapdata import hockey_stadium as defs
 48
 49    name = 'Hockey Stadium'
 50
 51    @override
 52    @classmethod
 53    def get_play_types(cls) -> list[str]:
 54        """Return valid play types for this map."""
 55        return ['melee', 'hockey', 'team_flag', 'keep_away']
 56
 57    @override
 58    @classmethod
 59    def get_preview_texture_name(cls) -> str:
 60        return 'hockeyStadiumPreview'
 61
 62    @override
 63    @classmethod
 64    def on_preload(cls) -> Any:
 65        data: dict[str, Any] = {
 66            'meshes': (
 67                bs.getmesh('hockeyStadiumOuter'),
 68                bs.getmesh('hockeyStadiumInner'),
 69                bs.getmesh('hockeyStadiumStands'),
 70            ),
 71            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
 72            'collision_mesh': bs.getcollisionmesh('hockeyStadiumCollide'),
 73            'tex': bs.gettexture('hockeyStadium'),
 74            'stands_tex': bs.gettexture('footballStadium'),
 75        }
 76        mat = bs.Material()
 77        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
 78        data['ice_material'] = mat
 79        return data
 80
 81    def __init__(self) -> None:
 82        super().__init__()
 83        shared = SharedObjects.get()
 84        self.node = bs.newnode(
 85            'terrain',
 86            delegate=self,
 87            attrs={
 88                'mesh': self.preloaddata['meshes'][0],
 89                'collision_mesh': self.preloaddata['collision_mesh'],
 90                'color_texture': self.preloaddata['tex'],
 91                'materials': [
 92                    shared.footing_material,
 93                    self.preloaddata['ice_material'],
 94                ],
 95            },
 96        )
 97        bs.newnode(
 98            'terrain',
 99            attrs={
100                'mesh': self.preloaddata['vr_fill_mesh'],
101                'vr_only': True,
102                'lighting': False,
103                'background': True,
104                'color_texture': self.preloaddata['stands_tex'],
105            },
106        )
107        mats = [shared.footing_material, self.preloaddata['ice_material']]
108        self.floor = bs.newnode(
109            'terrain',
110            attrs={
111                'mesh': self.preloaddata['meshes'][1],
112                'color_texture': self.preloaddata['tex'],
113                'opacity': 0.92,
114                'opacity_in_low_or_medium_quality': 1.0,
115                'materials': mats,
116            },
117        )
118        self.stands = bs.newnode(
119            'terrain',
120            attrs={
121                'mesh': self.preloaddata['meshes'][2],
122                'visible_in_reflections': False,
123                'color_texture': self.preloaddata['stands_tex'],
124            },
125        )
126        gnode = bs.getactivity().globalsnode
127        gnode.floor_reflection = True
128        gnode.debris_friction = 0.3
129        gnode.debris_kill_height = -0.3
130        gnode.tint = (1.2, 1.3, 1.33)
131        gnode.ambient_color = (1.15, 1.25, 1.6)
132        gnode.vignette_outer = (0.66, 0.67, 0.73)
133        gnode.vignette_inner = (0.93, 0.93, 0.95)
134        gnode.vr_camera_offset = (0, -0.8, -1.1)
135        gnode.vr_near_clip = 0.5
136        self.is_hockey = True

Stadium map used for ice hockey games.

HockeyStadium()
 81    def __init__(self) -> None:
 82        super().__init__()
 83        shared = SharedObjects.get()
 84        self.node = bs.newnode(
 85            'terrain',
 86            delegate=self,
 87            attrs={
 88                'mesh': self.preloaddata['meshes'][0],
 89                'collision_mesh': self.preloaddata['collision_mesh'],
 90                'color_texture': self.preloaddata['tex'],
 91                'materials': [
 92                    shared.footing_material,
 93                    self.preloaddata['ice_material'],
 94                ],
 95            },
 96        )
 97        bs.newnode(
 98            'terrain',
 99            attrs={
100                'mesh': self.preloaddata['vr_fill_mesh'],
101                'vr_only': True,
102                'lighting': False,
103                'background': True,
104                'color_texture': self.preloaddata['stands_tex'],
105            },
106        )
107        mats = [shared.footing_material, self.preloaddata['ice_material']]
108        self.floor = bs.newnode(
109            'terrain',
110            attrs={
111                'mesh': self.preloaddata['meshes'][1],
112                'color_texture': self.preloaddata['tex'],
113                'opacity': 0.92,
114                'opacity_in_low_or_medium_quality': 1.0,
115                'materials': mats,
116            },
117        )
118        self.stands = bs.newnode(
119            'terrain',
120            attrs={
121                'mesh': self.preloaddata['meshes'][2],
122                'visible_in_reflections': False,
123                'color_texture': self.preloaddata['stands_tex'],
124            },
125        )
126        gnode = bs.getactivity().globalsnode
127        gnode.floor_reflection = True
128        gnode.debris_friction = 0.3
129        gnode.debris_kill_height = -0.3
130        gnode.tint = (1.2, 1.3, 1.33)
131        gnode.ambient_color = (1.15, 1.25, 1.6)
132        gnode.vignette_outer = (0.66, 0.67, 0.73)
133        gnode.vignette_inner = (0.93, 0.93, 0.95)
134        gnode.vr_camera_offset = (0, -0.8, -1.1)
135        gnode.vr_near_clip = 0.5
136        self.is_hockey = True

Instantiate a map.

name = 'Hockey Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
51    @override
52    @classmethod
53    def get_play_types(cls) -> list[str]:
54        """Return valid play types for this map."""
55        return ['melee', 'hockey', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
57    @override
58    @classmethod
59    def get_preview_texture_name(cls) -> str:
60        return 'hockeyStadiumPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
62    @override
63    @classmethod
64    def on_preload(cls) -> Any:
65        data: dict[str, Any] = {
66            'meshes': (
67                bs.getmesh('hockeyStadiumOuter'),
68                bs.getmesh('hockeyStadiumInner'),
69                bs.getmesh('hockeyStadiumStands'),
70            ),
71            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
72            'collision_mesh': bs.getcollisionmesh('hockeyStadiumCollide'),
73            'tex': bs.gettexture('hockeyStadium'),
74            'stands_tex': bs.gettexture('footballStadium'),
75        }
76        mat = bs.Material()
77        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
78        data['ice_material'] = mat
79        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):
139class FootballStadium(bs.Map):
140    """Stadium map for football games."""
141
142    from bascenev1lib.mapdata import football_stadium as defs
143
144    name = 'Football Stadium'
145
146    @override
147    @classmethod
148    def get_play_types(cls) -> list[str]:
149        """Return valid play types for this map."""
150        return ['melee', 'football', 'team_flag', 'keep_away']
151
152    @override
153    @classmethod
154    def get_preview_texture_name(cls) -> str:
155        return 'footballStadiumPreview'
156
157    @override
158    @classmethod
159    def on_preload(cls) -> Any:
160        data: dict[str, Any] = {
161            'mesh': bs.getmesh('footballStadium'),
162            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
163            'collision_mesh': bs.getcollisionmesh('footballStadiumCollide'),
164            'tex': bs.gettexture('footballStadium'),
165        }
166        return data
167
168    def __init__(self) -> None:
169        super().__init__()
170        shared = SharedObjects.get()
171        self.node = bs.newnode(
172            'terrain',
173            delegate=self,
174            attrs={
175                'mesh': self.preloaddata['mesh'],
176                'collision_mesh': self.preloaddata['collision_mesh'],
177                'color_texture': self.preloaddata['tex'],
178                'materials': [shared.footing_material],
179            },
180        )
181        bs.newnode(
182            'terrain',
183            attrs={
184                'mesh': self.preloaddata['vr_fill_mesh'],
185                'lighting': False,
186                'vr_only': True,
187                'background': True,
188                'color_texture': self.preloaddata['tex'],
189            },
190        )
191        gnode = bs.getactivity().globalsnode
192        gnode.tint = (1.3, 1.2, 1.0)
193        gnode.ambient_color = (1.3, 1.2, 1.0)
194        gnode.vignette_outer = (0.57, 0.57, 0.57)
195        gnode.vignette_inner = (0.9, 0.9, 0.9)
196        gnode.vr_camera_offset = (0, -0.8, -1.1)
197        gnode.vr_near_clip = 0.5
198
199    @override
200    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
201        box_position = self.defs.boxes['edge_box'][0:3]
202        box_scale = self.defs.boxes['edge_box'][6:9]
203        xpos = (point.x - box_position[0]) / box_scale[0]
204        zpos = (point.z - box_position[2]) / box_scale[2]
205        return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5

Stadium map for football games.

FootballStadium()
168    def __init__(self) -> None:
169        super().__init__()
170        shared = SharedObjects.get()
171        self.node = bs.newnode(
172            'terrain',
173            delegate=self,
174            attrs={
175                'mesh': self.preloaddata['mesh'],
176                'collision_mesh': self.preloaddata['collision_mesh'],
177                'color_texture': self.preloaddata['tex'],
178                'materials': [shared.footing_material],
179            },
180        )
181        bs.newnode(
182            'terrain',
183            attrs={
184                'mesh': self.preloaddata['vr_fill_mesh'],
185                'lighting': False,
186                'vr_only': True,
187                'background': True,
188                'color_texture': self.preloaddata['tex'],
189            },
190        )
191        gnode = bs.getactivity().globalsnode
192        gnode.tint = (1.3, 1.2, 1.0)
193        gnode.ambient_color = (1.3, 1.2, 1.0)
194        gnode.vignette_outer = (0.57, 0.57, 0.57)
195        gnode.vignette_inner = (0.9, 0.9, 0.9)
196        gnode.vr_camera_offset = (0, -0.8, -1.1)
197        gnode.vr_near_clip = 0.5

Instantiate a map.

name = 'Football Stadium'
@override
@classmethod
def get_play_types(cls) -> list[str]:
146    @override
147    @classmethod
148    def get_play_types(cls) -> list[str]:
149        """Return valid play types for this map."""
150        return ['melee', 'football', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
152    @override
153    @classmethod
154    def get_preview_texture_name(cls) -> str:
155        return 'footballStadiumPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
157    @override
158    @classmethod
159    def on_preload(cls) -> Any:
160        data: dict[str, Any] = {
161            'mesh': bs.getmesh('footballStadium'),
162            'vr_fill_mesh': bs.getmesh('footballStadiumVRFill'),
163            'collision_mesh': bs.getcollisionmesh('footballStadiumCollide'),
164            'tex': bs.gettexture('footballStadium'),
165        }
166        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:
199    @override
200    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
201        box_position = self.defs.boxes['edge_box'][0:3]
202        box_scale = self.defs.boxes['edge_box'][6:9]
203        xpos = (point.x - box_position[0]) / box_scale[0]
204        zpos = (point.z - box_position[2]) / box_scale[2]
205        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):
208class Bridgit(bs.Map):
209    """Map with a narrow bridge in the middle."""
210
211    # noinspection PyUnresolvedReferences
212    from bascenev1lib.mapdata import bridgit as defs
213
214    name = 'Bridgit'
215    dataname = 'bridgit'
216
217    @override
218    @classmethod
219    def get_play_types(cls) -> list[str]:
220        """Return valid play types for this map."""
221        # print('getting playtypes', cls._getdata()['play_types'])
222        return ['melee', 'team_flag', 'keep_away']
223
224    @override
225    @classmethod
226    def get_preview_texture_name(cls) -> str:
227        return 'bridgitPreview'
228
229    @override
230    @classmethod
231    def on_preload(cls) -> Any:
232        data: dict[str, Any] = {
233            'mesh_top': bs.getmesh('bridgitLevelTop'),
234            'mesh_bottom': bs.getmesh('bridgitLevelBottom'),
235            'mesh_bg': bs.getmesh('natureBackground'),
236            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
237            'collision_mesh': bs.getcollisionmesh('bridgitLevelCollide'),
238            'tex': bs.gettexture('bridgitLevelColor'),
239            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
240            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
241            'railing_collision_mesh': (
242                bs.getcollisionmesh('bridgitLevelRailingCollide')
243            ),
244            'bg_material': bs.Material(),
245        }
246        data['bg_material'].add_actions(
247            actions=('modify_part_collision', 'friction', 10.0)
248        )
249        return data
250
251    def __init__(self) -> None:
252        super().__init__()
253        shared = SharedObjects.get()
254        self.node = bs.newnode(
255            'terrain',
256            delegate=self,
257            attrs={
258                'collision_mesh': self.preloaddata['collision_mesh'],
259                'mesh': self.preloaddata['mesh_top'],
260                'color_texture': self.preloaddata['tex'],
261                'materials': [shared.footing_material],
262            },
263        )
264        self.bottom = bs.newnode(
265            'terrain',
266            attrs={
267                'mesh': self.preloaddata['mesh_bottom'],
268                'lighting': False,
269                'color_texture': self.preloaddata['tex'],
270            },
271        )
272        self.background = bs.newnode(
273            'terrain',
274            attrs={
275                'mesh': self.preloaddata['mesh_bg'],
276                'lighting': False,
277                'background': True,
278                'color_texture': self.preloaddata['mesh_bg_tex'],
279            },
280        )
281        bs.newnode(
282            'terrain',
283            attrs={
284                'mesh': self.preloaddata['bg_vr_fill_mesh'],
285                'lighting': False,
286                'vr_only': True,
287                'background': True,
288                'color_texture': self.preloaddata['mesh_bg_tex'],
289            },
290        )
291        self.railing = bs.newnode(
292            'terrain',
293            attrs={
294                'collision_mesh': self.preloaddata['railing_collision_mesh'],
295                'materials': [shared.railing_material],
296                'bumper': True,
297            },
298        )
299        self.bg_collide = bs.newnode(
300            'terrain',
301            attrs={
302                'collision_mesh': self.preloaddata['collide_bg'],
303                'materials': [
304                    shared.footing_material,
305                    self.preloaddata['bg_material'],
306                    shared.death_material,
307                ],
308            },
309        )
310        gnode = bs.getactivity().globalsnode
311        gnode.tint = (1.1, 1.2, 1.3)
312        gnode.ambient_color = (1.1, 1.2, 1.3)
313        gnode.vignette_outer = (0.65, 0.6, 0.55)
314        gnode.vignette_inner = (0.9, 0.9, 0.93)

Map with a narrow bridge in the middle.

Bridgit()
251    def __init__(self) -> None:
252        super().__init__()
253        shared = SharedObjects.get()
254        self.node = bs.newnode(
255            'terrain',
256            delegate=self,
257            attrs={
258                'collision_mesh': self.preloaddata['collision_mesh'],
259                'mesh': self.preloaddata['mesh_top'],
260                'color_texture': self.preloaddata['tex'],
261                'materials': [shared.footing_material],
262            },
263        )
264        self.bottom = bs.newnode(
265            'terrain',
266            attrs={
267                'mesh': self.preloaddata['mesh_bottom'],
268                'lighting': False,
269                'color_texture': self.preloaddata['tex'],
270            },
271        )
272        self.background = bs.newnode(
273            'terrain',
274            attrs={
275                'mesh': self.preloaddata['mesh_bg'],
276                'lighting': False,
277                'background': True,
278                'color_texture': self.preloaddata['mesh_bg_tex'],
279            },
280        )
281        bs.newnode(
282            'terrain',
283            attrs={
284                'mesh': self.preloaddata['bg_vr_fill_mesh'],
285                'lighting': False,
286                'vr_only': True,
287                'background': True,
288                'color_texture': self.preloaddata['mesh_bg_tex'],
289            },
290        )
291        self.railing = bs.newnode(
292            'terrain',
293            attrs={
294                'collision_mesh': self.preloaddata['railing_collision_mesh'],
295                'materials': [shared.railing_material],
296                'bumper': True,
297            },
298        )
299        self.bg_collide = bs.newnode(
300            'terrain',
301            attrs={
302                'collision_mesh': self.preloaddata['collide_bg'],
303                'materials': [
304                    shared.footing_material,
305                    self.preloaddata['bg_material'],
306                    shared.death_material,
307                ],
308            },
309        )
310        gnode = bs.getactivity().globalsnode
311        gnode.tint = (1.1, 1.2, 1.3)
312        gnode.ambient_color = (1.1, 1.2, 1.3)
313        gnode.vignette_outer = (0.65, 0.6, 0.55)
314        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]:
217    @override
218    @classmethod
219    def get_play_types(cls) -> list[str]:
220        """Return valid play types for this map."""
221        # print('getting playtypes', cls._getdata()['play_types'])
222        return ['melee', 'team_flag', 'keep_away']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
224    @override
225    @classmethod
226    def get_preview_texture_name(cls) -> str:
227        return 'bridgitPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
229    @override
230    @classmethod
231    def on_preload(cls) -> Any:
232        data: dict[str, Any] = {
233            'mesh_top': bs.getmesh('bridgitLevelTop'),
234            'mesh_bottom': bs.getmesh('bridgitLevelBottom'),
235            'mesh_bg': bs.getmesh('natureBackground'),
236            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
237            'collision_mesh': bs.getcollisionmesh('bridgitLevelCollide'),
238            'tex': bs.gettexture('bridgitLevelColor'),
239            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
240            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
241            'railing_collision_mesh': (
242                bs.getcollisionmesh('bridgitLevelRailingCollide')
243            ),
244            'bg_material': bs.Material(),
245        }
246        data['bg_material'].add_actions(
247            actions=('modify_part_collision', 'friction', 10.0)
248        )
249        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):
317class BigG(bs.Map):
318    """Large G shaped map for racing"""
319
320    # noinspection PyUnresolvedReferences
321    from bascenev1lib.mapdata import big_g as defs
322
323    name = 'Big G'
324
325    @override
326    @classmethod
327    def get_play_types(cls) -> list[str]:
328        """Return valid play types for this map."""
329        return [
330            'race',
331            'melee',
332            'keep_away',
333            'team_flag',
334            'king_of_the_hill',
335            'conquest',
336        ]
337
338    @override
339    @classmethod
340    def get_preview_texture_name(cls) -> str:
341        return 'bigGPreview'
342
343    @override
344    @classmethod
345    def on_preload(cls) -> Any:
346        data: dict[str, Any] = {
347            'mesh_top': bs.getmesh('bigG'),
348            'mesh_bottom': bs.getmesh('bigGBottom'),
349            'mesh_bg': bs.getmesh('natureBackground'),
350            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
351            'collision_mesh': bs.getcollisionmesh('bigGCollide'),
352            'tex': bs.gettexture('bigG'),
353            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
354            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
355            'bumper_collision_mesh': bs.getcollisionmesh('bigGBumper'),
356            'bg_material': bs.Material(),
357        }
358        data['bg_material'].add_actions(
359            actions=('modify_part_collision', 'friction', 10.0)
360        )
361        return data
362
363    def __init__(self) -> None:
364        super().__init__()
365        shared = SharedObjects.get()
366        self.node = bs.newnode(
367            'terrain',
368            delegate=self,
369            attrs={
370                'collision_mesh': self.preloaddata['collision_mesh'],
371                'color': (0.7, 0.7, 0.7),
372                'mesh': self.preloaddata['mesh_top'],
373                'color_texture': self.preloaddata['tex'],
374                'materials': [shared.footing_material],
375            },
376        )
377        self.bottom = bs.newnode(
378            'terrain',
379            attrs={
380                'mesh': self.preloaddata['mesh_bottom'],
381                'color': (0.7, 0.7, 0.7),
382                'lighting': False,
383                'color_texture': self.preloaddata['tex'],
384            },
385        )
386        self.background = bs.newnode(
387            'terrain',
388            attrs={
389                'mesh': self.preloaddata['mesh_bg'],
390                'lighting': False,
391                'background': True,
392                'color_texture': self.preloaddata['mesh_bg_tex'],
393            },
394        )
395        bs.newnode(
396            'terrain',
397            attrs={
398                'mesh': self.preloaddata['bg_vr_fill_mesh'],
399                'lighting': False,
400                'vr_only': True,
401                'background': True,
402                'color_texture': self.preloaddata['mesh_bg_tex'],
403            },
404        )
405        self.railing = bs.newnode(
406            'terrain',
407            attrs={
408                'collision_mesh': self.preloaddata['bumper_collision_mesh'],
409                'materials': [shared.railing_material],
410                'bumper': True,
411            },
412        )
413        self.bg_collide = bs.newnode(
414            'terrain',
415            attrs={
416                'collision_mesh': self.preloaddata['collide_bg'],
417                'materials': [
418                    shared.footing_material,
419                    self.preloaddata['bg_material'],
420                    shared.death_material,
421                ],
422            },
423        )
424        gnode = bs.getactivity().globalsnode
425        gnode.tint = (1.1, 1.2, 1.3)
426        gnode.ambient_color = (1.1, 1.2, 1.3)
427        gnode.vignette_outer = (0.65, 0.6, 0.55)
428        gnode.vignette_inner = (0.9, 0.9, 0.93)

Large G shaped map for racing

BigG()
363    def __init__(self) -> None:
364        super().__init__()
365        shared = SharedObjects.get()
366        self.node = bs.newnode(
367            'terrain',
368            delegate=self,
369            attrs={
370                'collision_mesh': self.preloaddata['collision_mesh'],
371                'color': (0.7, 0.7, 0.7),
372                'mesh': self.preloaddata['mesh_top'],
373                'color_texture': self.preloaddata['tex'],
374                'materials': [shared.footing_material],
375            },
376        )
377        self.bottom = bs.newnode(
378            'terrain',
379            attrs={
380                'mesh': self.preloaddata['mesh_bottom'],
381                'color': (0.7, 0.7, 0.7),
382                'lighting': False,
383                'color_texture': self.preloaddata['tex'],
384            },
385        )
386        self.background = bs.newnode(
387            'terrain',
388            attrs={
389                'mesh': self.preloaddata['mesh_bg'],
390                'lighting': False,
391                'background': True,
392                'color_texture': self.preloaddata['mesh_bg_tex'],
393            },
394        )
395        bs.newnode(
396            'terrain',
397            attrs={
398                'mesh': self.preloaddata['bg_vr_fill_mesh'],
399                'lighting': False,
400                'vr_only': True,
401                'background': True,
402                'color_texture': self.preloaddata['mesh_bg_tex'],
403            },
404        )
405        self.railing = bs.newnode(
406            'terrain',
407            attrs={
408                'collision_mesh': self.preloaddata['bumper_collision_mesh'],
409                'materials': [shared.railing_material],
410                'bumper': True,
411            },
412        )
413        self.bg_collide = bs.newnode(
414            'terrain',
415            attrs={
416                'collision_mesh': self.preloaddata['collide_bg'],
417                'materials': [
418                    shared.footing_material,
419                    self.preloaddata['bg_material'],
420                    shared.death_material,
421                ],
422            },
423        )
424        gnode = bs.getactivity().globalsnode
425        gnode.tint = (1.1, 1.2, 1.3)
426        gnode.ambient_color = (1.1, 1.2, 1.3)
427        gnode.vignette_outer = (0.65, 0.6, 0.55)
428        gnode.vignette_inner = (0.9, 0.9, 0.93)

Instantiate a map.

name = 'Big G'
@override
@classmethod
def get_play_types(cls) -> list[str]:
325    @override
326    @classmethod
327    def get_play_types(cls) -> list[str]:
328        """Return valid play types for this map."""
329        return [
330            'race',
331            'melee',
332            'keep_away',
333            'team_flag',
334            'king_of_the_hill',
335            'conquest',
336        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
338    @override
339    @classmethod
340    def get_preview_texture_name(cls) -> str:
341        return 'bigGPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
343    @override
344    @classmethod
345    def on_preload(cls) -> Any:
346        data: dict[str, Any] = {
347            'mesh_top': bs.getmesh('bigG'),
348            'mesh_bottom': bs.getmesh('bigGBottom'),
349            'mesh_bg': bs.getmesh('natureBackground'),
350            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
351            'collision_mesh': bs.getcollisionmesh('bigGCollide'),
352            'tex': bs.gettexture('bigG'),
353            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
354            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
355            'bumper_collision_mesh': bs.getcollisionmesh('bigGBumper'),
356            'bg_material': bs.Material(),
357        }
358        data['bg_material'].add_actions(
359            actions=('modify_part_collision', 'friction', 10.0)
360        )
361        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):
431class Roundabout(bs.Map):
432    """CTF map featuring two platforms and a long way around between them"""
433
434    # noinspection PyUnresolvedReferences
435    from bascenev1lib.mapdata import roundabout as defs
436
437    name = 'Roundabout'
438
439    @override
440    @classmethod
441    def get_play_types(cls) -> list[str]:
442        """Return valid play types for this map."""
443        return ['melee', 'keep_away', 'team_flag']
444
445    @override
446    @classmethod
447    def get_preview_texture_name(cls) -> str:
448        return 'roundaboutPreview'
449
450    @override
451    @classmethod
452    def on_preload(cls) -> Any:
453        data: dict[str, Any] = {
454            'mesh': bs.getmesh('roundaboutLevel'),
455            'mesh_bottom': bs.getmesh('roundaboutLevelBottom'),
456            'mesh_bg': bs.getmesh('natureBackground'),
457            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
458            'collision_mesh': bs.getcollisionmesh('roundaboutLevelCollide'),
459            'tex': bs.gettexture('roundaboutLevelColor'),
460            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
461            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
462            'railing_collision_mesh': (
463                bs.getcollisionmesh('roundaboutLevelBumper')
464            ),
465            'bg_material': bs.Material(),
466        }
467        data['bg_material'].add_actions(
468            actions=('modify_part_collision', 'friction', 10.0)
469        )
470        return data
471
472    def __init__(self) -> None:
473        super().__init__(vr_overlay_offset=(0, -1, 1))
474        shared = SharedObjects.get()
475        self.node = bs.newnode(
476            'terrain',
477            delegate=self,
478            attrs={
479                'collision_mesh': self.preloaddata['collision_mesh'],
480                'mesh': self.preloaddata['mesh'],
481                'color_texture': self.preloaddata['tex'],
482                'materials': [shared.footing_material],
483            },
484        )
485        self.bottom = bs.newnode(
486            'terrain',
487            attrs={
488                'mesh': self.preloaddata['mesh_bottom'],
489                'lighting': False,
490                'color_texture': self.preloaddata['tex'],
491            },
492        )
493        self.background = bs.newnode(
494            'terrain',
495            attrs={
496                'mesh': self.preloaddata['mesh_bg'],
497                'lighting': False,
498                'background': True,
499                'color_texture': self.preloaddata['mesh_bg_tex'],
500            },
501        )
502        bs.newnode(
503            'terrain',
504            attrs={
505                'mesh': self.preloaddata['bg_vr_fill_mesh'],
506                'lighting': False,
507                'vr_only': True,
508                'background': True,
509                'color_texture': self.preloaddata['mesh_bg_tex'],
510            },
511        )
512        self.bg_collide = bs.newnode(
513            'terrain',
514            attrs={
515                'collision_mesh': self.preloaddata['collide_bg'],
516                'materials': [
517                    shared.footing_material,
518                    self.preloaddata['bg_material'],
519                    shared.death_material,
520                ],
521            },
522        )
523        self.railing = bs.newnode(
524            'terrain',
525            attrs={
526                'collision_mesh': self.preloaddata['railing_collision_mesh'],
527                'materials': [shared.railing_material],
528                'bumper': True,
529            },
530        )
531        gnode = bs.getactivity().globalsnode
532        gnode.tint = (1.0, 1.05, 1.1)
533        gnode.ambient_color = (1.0, 1.05, 1.1)
534        gnode.shadow_ortho = True
535        gnode.vignette_outer = (0.63, 0.65, 0.7)
536        gnode.vignette_inner = (0.97, 0.95, 0.93)

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

Roundabout()
472    def __init__(self) -> None:
473        super().__init__(vr_overlay_offset=(0, -1, 1))
474        shared = SharedObjects.get()
475        self.node = bs.newnode(
476            'terrain',
477            delegate=self,
478            attrs={
479                'collision_mesh': self.preloaddata['collision_mesh'],
480                'mesh': self.preloaddata['mesh'],
481                'color_texture': self.preloaddata['tex'],
482                'materials': [shared.footing_material],
483            },
484        )
485        self.bottom = bs.newnode(
486            'terrain',
487            attrs={
488                'mesh': self.preloaddata['mesh_bottom'],
489                'lighting': False,
490                'color_texture': self.preloaddata['tex'],
491            },
492        )
493        self.background = bs.newnode(
494            'terrain',
495            attrs={
496                'mesh': self.preloaddata['mesh_bg'],
497                'lighting': False,
498                'background': True,
499                'color_texture': self.preloaddata['mesh_bg_tex'],
500            },
501        )
502        bs.newnode(
503            'terrain',
504            attrs={
505                'mesh': self.preloaddata['bg_vr_fill_mesh'],
506                'lighting': False,
507                'vr_only': True,
508                'background': True,
509                'color_texture': self.preloaddata['mesh_bg_tex'],
510            },
511        )
512        self.bg_collide = bs.newnode(
513            'terrain',
514            attrs={
515                'collision_mesh': self.preloaddata['collide_bg'],
516                'materials': [
517                    shared.footing_material,
518                    self.preloaddata['bg_material'],
519                    shared.death_material,
520                ],
521            },
522        )
523        self.railing = bs.newnode(
524            'terrain',
525            attrs={
526                'collision_mesh': self.preloaddata['railing_collision_mesh'],
527                'materials': [shared.railing_material],
528                'bumper': True,
529            },
530        )
531        gnode = bs.getactivity().globalsnode
532        gnode.tint = (1.0, 1.05, 1.1)
533        gnode.ambient_color = (1.0, 1.05, 1.1)
534        gnode.shadow_ortho = True
535        gnode.vignette_outer = (0.63, 0.65, 0.7)
536        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

name = 'Roundabout'
@override
@classmethod
def get_play_types(cls) -> list[str]:
439    @override
440    @classmethod
441    def get_play_types(cls) -> list[str]:
442        """Return valid play types for this map."""
443        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
445    @override
446    @classmethod
447    def get_preview_texture_name(cls) -> str:
448        return 'roundaboutPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
450    @override
451    @classmethod
452    def on_preload(cls) -> Any:
453        data: dict[str, Any] = {
454            'mesh': bs.getmesh('roundaboutLevel'),
455            'mesh_bottom': bs.getmesh('roundaboutLevelBottom'),
456            'mesh_bg': bs.getmesh('natureBackground'),
457            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
458            'collision_mesh': bs.getcollisionmesh('roundaboutLevelCollide'),
459            'tex': bs.gettexture('roundaboutLevelColor'),
460            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
461            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
462            'railing_collision_mesh': (
463                bs.getcollisionmesh('roundaboutLevelBumper')
464            ),
465            'bg_material': bs.Material(),
466        }
467        data['bg_material'].add_actions(
468            actions=('modify_part_collision', 'friction', 10.0)
469        )
470        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):
539class MonkeyFace(bs.Map):
540    """Map sorta shaped like a monkey face; teehee!"""
541
542    # noinspection PyUnresolvedReferences
543    from bascenev1lib.mapdata import monkey_face as defs
544
545    name = 'Monkey Face'
546
547    @override
548    @classmethod
549    def get_play_types(cls) -> list[str]:
550        """Return valid play types for this map."""
551        return ['melee', 'keep_away', 'team_flag']
552
553    @override
554    @classmethod
555    def get_preview_texture_name(cls) -> str:
556        return 'monkeyFacePreview'
557
558    @override
559    @classmethod
560    def on_preload(cls) -> Any:
561        data: dict[str, Any] = {
562            'mesh': bs.getmesh('monkeyFaceLevel'),
563            'bottom_mesh': bs.getmesh('monkeyFaceLevelBottom'),
564            'mesh_bg': bs.getmesh('natureBackground'),
565            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
566            'collision_mesh': bs.getcollisionmesh('monkeyFaceLevelCollide'),
567            'tex': bs.gettexture('monkeyFaceLevelColor'),
568            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
569            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
570            'railing_collision_mesh': (
571                bs.getcollisionmesh('monkeyFaceLevelBumper')
572            ),
573            'bg_material': bs.Material(),
574        }
575        data['bg_material'].add_actions(
576            actions=('modify_part_collision', 'friction', 10.0)
577        )
578        return data
579
580    def __init__(self) -> None:
581        super().__init__()
582        shared = SharedObjects.get()
583        self.node = bs.newnode(
584            'terrain',
585            delegate=self,
586            attrs={
587                'collision_mesh': self.preloaddata['collision_mesh'],
588                'mesh': self.preloaddata['mesh'],
589                'color_texture': self.preloaddata['tex'],
590                'materials': [shared.footing_material],
591            },
592        )
593        self.bottom = bs.newnode(
594            'terrain',
595            attrs={
596                'mesh': self.preloaddata['bottom_mesh'],
597                'lighting': False,
598                'color_texture': self.preloaddata['tex'],
599            },
600        )
601        self.background = bs.newnode(
602            'terrain',
603            attrs={
604                'mesh': self.preloaddata['mesh_bg'],
605                'lighting': False,
606                'background': True,
607                'color_texture': self.preloaddata['mesh_bg_tex'],
608            },
609        )
610        bs.newnode(
611            'terrain',
612            attrs={
613                'mesh': self.preloaddata['bg_vr_fill_mesh'],
614                'lighting': False,
615                'vr_only': True,
616                'background': True,
617                'color_texture': self.preloaddata['mesh_bg_tex'],
618            },
619        )
620        self.bg_collide = bs.newnode(
621            'terrain',
622            attrs={
623                'collision_mesh': self.preloaddata['collide_bg'],
624                'materials': [
625                    shared.footing_material,
626                    self.preloaddata['bg_material'],
627                    shared.death_material,
628                ],
629            },
630        )
631        self.railing = bs.newnode(
632            'terrain',
633            attrs={
634                'collision_mesh': self.preloaddata['railing_collision_mesh'],
635                'materials': [shared.railing_material],
636                'bumper': True,
637            },
638        )
639        gnode = bs.getactivity().globalsnode
640        gnode.tint = (1.1, 1.2, 1.2)
641        gnode.ambient_color = (1.2, 1.3, 1.3)
642        gnode.vignette_outer = (0.60, 0.62, 0.66)
643        gnode.vignette_inner = (0.97, 0.95, 0.93)
644        gnode.vr_camera_offset = (-1.4, 0, 0)

Map sorta shaped like a monkey face; teehee!

MonkeyFace()
580    def __init__(self) -> None:
581        super().__init__()
582        shared = SharedObjects.get()
583        self.node = bs.newnode(
584            'terrain',
585            delegate=self,
586            attrs={
587                'collision_mesh': self.preloaddata['collision_mesh'],
588                'mesh': self.preloaddata['mesh'],
589                'color_texture': self.preloaddata['tex'],
590                'materials': [shared.footing_material],
591            },
592        )
593        self.bottom = bs.newnode(
594            'terrain',
595            attrs={
596                'mesh': self.preloaddata['bottom_mesh'],
597                'lighting': False,
598                'color_texture': self.preloaddata['tex'],
599            },
600        )
601        self.background = bs.newnode(
602            'terrain',
603            attrs={
604                'mesh': self.preloaddata['mesh_bg'],
605                'lighting': False,
606                'background': True,
607                'color_texture': self.preloaddata['mesh_bg_tex'],
608            },
609        )
610        bs.newnode(
611            'terrain',
612            attrs={
613                'mesh': self.preloaddata['bg_vr_fill_mesh'],
614                'lighting': False,
615                'vr_only': True,
616                'background': True,
617                'color_texture': self.preloaddata['mesh_bg_tex'],
618            },
619        )
620        self.bg_collide = bs.newnode(
621            'terrain',
622            attrs={
623                'collision_mesh': self.preloaddata['collide_bg'],
624                'materials': [
625                    shared.footing_material,
626                    self.preloaddata['bg_material'],
627                    shared.death_material,
628                ],
629            },
630        )
631        self.railing = bs.newnode(
632            'terrain',
633            attrs={
634                'collision_mesh': self.preloaddata['railing_collision_mesh'],
635                'materials': [shared.railing_material],
636                'bumper': True,
637            },
638        )
639        gnode = bs.getactivity().globalsnode
640        gnode.tint = (1.1, 1.2, 1.2)
641        gnode.ambient_color = (1.2, 1.3, 1.3)
642        gnode.vignette_outer = (0.60, 0.62, 0.66)
643        gnode.vignette_inner = (0.97, 0.95, 0.93)
644        gnode.vr_camera_offset = (-1.4, 0, 0)

Instantiate a map.

name = 'Monkey Face'
@override
@classmethod
def get_play_types(cls) -> list[str]:
547    @override
548    @classmethod
549    def get_play_types(cls) -> list[str]:
550        """Return valid play types for this map."""
551        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
553    @override
554    @classmethod
555    def get_preview_texture_name(cls) -> str:
556        return 'monkeyFacePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
558    @override
559    @classmethod
560    def on_preload(cls) -> Any:
561        data: dict[str, Any] = {
562            'mesh': bs.getmesh('monkeyFaceLevel'),
563            'bottom_mesh': bs.getmesh('monkeyFaceLevelBottom'),
564            'mesh_bg': bs.getmesh('natureBackground'),
565            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
566            'collision_mesh': bs.getcollisionmesh('monkeyFaceLevelCollide'),
567            'tex': bs.gettexture('monkeyFaceLevelColor'),
568            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
569            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
570            'railing_collision_mesh': (
571                bs.getcollisionmesh('monkeyFaceLevelBumper')
572            ),
573            'bg_material': bs.Material(),
574        }
575        data['bg_material'].add_actions(
576            actions=('modify_part_collision', 'friction', 10.0)
577        )
578        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):
647class ZigZag(bs.Map):
648    """A very long zig-zaggy map"""
649
650    # noinspection PyUnresolvedReferences
651    from bascenev1lib.mapdata import zig_zag as defs
652
653    name = 'Zigzag'
654
655    @override
656    @classmethod
657    def get_play_types(cls) -> list[str]:
658        """Return valid play types for this map."""
659        return [
660            'melee',
661            'keep_away',
662            'team_flag',
663            'conquest',
664            'king_of_the_hill',
665        ]
666
667    @override
668    @classmethod
669    def get_preview_texture_name(cls) -> str:
670        return 'zigzagPreview'
671
672    @override
673    @classmethod
674    def on_preload(cls) -> Any:
675        data: dict[str, Any] = {
676            'mesh': bs.getmesh('zigZagLevel'),
677            'mesh_bottom': bs.getmesh('zigZagLevelBottom'),
678            'mesh_bg': bs.getmesh('natureBackground'),
679            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
680            'collision_mesh': bs.getcollisionmesh('zigZagLevelCollide'),
681            'tex': bs.gettexture('zigZagLevelColor'),
682            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
683            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
684            'railing_collision_mesh': bs.getcollisionmesh('zigZagLevelBumper'),
685            'bg_material': bs.Material(),
686        }
687        data['bg_material'].add_actions(
688            actions=('modify_part_collision', 'friction', 10.0)
689        )
690        return data
691
692    def __init__(self) -> None:
693        super().__init__()
694        shared = SharedObjects.get()
695        self.node = bs.newnode(
696            'terrain',
697            delegate=self,
698            attrs={
699                'collision_mesh': self.preloaddata['collision_mesh'],
700                'mesh': self.preloaddata['mesh'],
701                'color_texture': self.preloaddata['tex'],
702                'materials': [shared.footing_material],
703            },
704        )
705        self.background = bs.newnode(
706            'terrain',
707            attrs={
708                'mesh': self.preloaddata['mesh_bg'],
709                'lighting': False,
710                'color_texture': self.preloaddata['mesh_bg_tex'],
711            },
712        )
713        self.bottom = bs.newnode(
714            'terrain',
715            attrs={
716                'mesh': self.preloaddata['mesh_bottom'],
717                'lighting': False,
718                'color_texture': self.preloaddata['tex'],
719            },
720        )
721        bs.newnode(
722            'terrain',
723            attrs={
724                'mesh': self.preloaddata['bg_vr_fill_mesh'],
725                'lighting': False,
726                'vr_only': True,
727                'background': True,
728                'color_texture': self.preloaddata['mesh_bg_tex'],
729            },
730        )
731        self.bg_collide = bs.newnode(
732            'terrain',
733            attrs={
734                'collision_mesh': self.preloaddata['collide_bg'],
735                'materials': [
736                    shared.footing_material,
737                    self.preloaddata['bg_material'],
738                    shared.death_material,
739                ],
740            },
741        )
742        self.railing = bs.newnode(
743            'terrain',
744            attrs={
745                'collision_mesh': self.preloaddata['railing_collision_mesh'],
746                'materials': [shared.railing_material],
747                'bumper': True,
748            },
749        )
750        gnode = bs.getactivity().globalsnode
751        gnode.tint = (1.0, 1.15, 1.15)
752        gnode.ambient_color = (1.0, 1.15, 1.15)
753        gnode.vignette_outer = (0.57, 0.59, 0.63)
754        gnode.vignette_inner = (0.97, 0.95, 0.93)
755        gnode.vr_camera_offset = (-1.5, 0, 0)

A very long zig-zaggy map

ZigZag()
692    def __init__(self) -> None:
693        super().__init__()
694        shared = SharedObjects.get()
695        self.node = bs.newnode(
696            'terrain',
697            delegate=self,
698            attrs={
699                'collision_mesh': self.preloaddata['collision_mesh'],
700                'mesh': self.preloaddata['mesh'],
701                'color_texture': self.preloaddata['tex'],
702                'materials': [shared.footing_material],
703            },
704        )
705        self.background = bs.newnode(
706            'terrain',
707            attrs={
708                'mesh': self.preloaddata['mesh_bg'],
709                'lighting': False,
710                'color_texture': self.preloaddata['mesh_bg_tex'],
711            },
712        )
713        self.bottom = bs.newnode(
714            'terrain',
715            attrs={
716                'mesh': self.preloaddata['mesh_bottom'],
717                'lighting': False,
718                'color_texture': self.preloaddata['tex'],
719            },
720        )
721        bs.newnode(
722            'terrain',
723            attrs={
724                'mesh': self.preloaddata['bg_vr_fill_mesh'],
725                'lighting': False,
726                'vr_only': True,
727                'background': True,
728                'color_texture': self.preloaddata['mesh_bg_tex'],
729            },
730        )
731        self.bg_collide = bs.newnode(
732            'terrain',
733            attrs={
734                'collision_mesh': self.preloaddata['collide_bg'],
735                'materials': [
736                    shared.footing_material,
737                    self.preloaddata['bg_material'],
738                    shared.death_material,
739                ],
740            },
741        )
742        self.railing = bs.newnode(
743            'terrain',
744            attrs={
745                'collision_mesh': self.preloaddata['railing_collision_mesh'],
746                'materials': [shared.railing_material],
747                'bumper': True,
748            },
749        )
750        gnode = bs.getactivity().globalsnode
751        gnode.tint = (1.0, 1.15, 1.15)
752        gnode.ambient_color = (1.0, 1.15, 1.15)
753        gnode.vignette_outer = (0.57, 0.59, 0.63)
754        gnode.vignette_inner = (0.97, 0.95, 0.93)
755        gnode.vr_camera_offset = (-1.5, 0, 0)

Instantiate a map.

name = 'Zigzag'
@override
@classmethod
def get_play_types(cls) -> list[str]:
655    @override
656    @classmethod
657    def get_play_types(cls) -> list[str]:
658        """Return valid play types for this map."""
659        return [
660            'melee',
661            'keep_away',
662            'team_flag',
663            'conquest',
664            'king_of_the_hill',
665        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
667    @override
668    @classmethod
669    def get_preview_texture_name(cls) -> str:
670        return 'zigzagPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
672    @override
673    @classmethod
674    def on_preload(cls) -> Any:
675        data: dict[str, Any] = {
676            'mesh': bs.getmesh('zigZagLevel'),
677            'mesh_bottom': bs.getmesh('zigZagLevelBottom'),
678            'mesh_bg': bs.getmesh('natureBackground'),
679            'bg_vr_fill_mesh': bs.getmesh('natureBackgroundVRFill'),
680            'collision_mesh': bs.getcollisionmesh('zigZagLevelCollide'),
681            'tex': bs.gettexture('zigZagLevelColor'),
682            'mesh_bg_tex': bs.gettexture('natureBackgroundColor'),
683            'collide_bg': bs.getcollisionmesh('natureBackgroundCollide'),
684            'railing_collision_mesh': bs.getcollisionmesh('zigZagLevelBumper'),
685            'bg_material': bs.Material(),
686        }
687        data['bg_material'].add_actions(
688            actions=('modify_part_collision', 'friction', 10.0)
689        )
690        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):
758class ThePad(bs.Map):
759    """A simple square shaped map with a raised edge."""
760
761    # noinspection PyUnresolvedReferences
762    from bascenev1lib.mapdata import the_pad as defs
763
764    name = 'The Pad'
765
766    @override
767    @classmethod
768    def get_play_types(cls) -> list[str]:
769        """Return valid play types for this map."""
770        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
771
772    @override
773    @classmethod
774    def get_preview_texture_name(cls) -> str:
775        return 'thePadPreview'
776
777    @override
778    @classmethod
779    def on_preload(cls) -> Any:
780        data: dict[str, Any] = {
781            'mesh': bs.getmesh('thePadLevel'),
782            'bottom_mesh': bs.getmesh('thePadLevelBottom'),
783            'collision_mesh': bs.getcollisionmesh('thePadLevelCollide'),
784            'tex': bs.gettexture('thePadLevelColor'),
785            'bgtex': bs.gettexture('menuBG'),
786            'bgmesh': bs.getmesh('thePadBG'),
787            'railing_collision_mesh': bs.getcollisionmesh('thePadLevelBumper'),
788            'vr_fill_mound_mesh': bs.getmesh('thePadVRFillMound'),
789            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
790        }
791        # fixme should chop this into vr/non-vr sections for efficiency
792        return data
793
794    def __init__(self) -> None:
795        super().__init__()
796        shared = SharedObjects.get()
797        self.node = bs.newnode(
798            'terrain',
799            delegate=self,
800            attrs={
801                'collision_mesh': self.preloaddata['collision_mesh'],
802                'mesh': self.preloaddata['mesh'],
803                'color_texture': self.preloaddata['tex'],
804                'materials': [shared.footing_material],
805            },
806        )
807        self.bottom = bs.newnode(
808            'terrain',
809            attrs={
810                'mesh': self.preloaddata['bottom_mesh'],
811                'lighting': False,
812                'color_texture': self.preloaddata['tex'],
813            },
814        )
815        self.background = bs.newnode(
816            'terrain',
817            attrs={
818                'mesh': self.preloaddata['bgmesh'],
819                'lighting': False,
820                'background': True,
821                'color_texture': self.preloaddata['bgtex'],
822            },
823        )
824        self.railing = bs.newnode(
825            'terrain',
826            attrs={
827                'collision_mesh': self.preloaddata['railing_collision_mesh'],
828                'materials': [shared.railing_material],
829                'bumper': True,
830            },
831        )
832        bs.newnode(
833            'terrain',
834            attrs={
835                'mesh': self.preloaddata['vr_fill_mound_mesh'],
836                'lighting': False,
837                'vr_only': True,
838                'color': (0.56, 0.55, 0.47),
839                'background': True,
840                'color_texture': self.preloaddata['vr_fill_mound_tex'],
841            },
842        )
843        gnode = bs.getactivity().globalsnode
844        gnode.tint = (1.1, 1.1, 1.0)
845        gnode.ambient_color = (1.1, 1.1, 1.0)
846        gnode.vignette_outer = (0.7, 0.65, 0.75)
847        gnode.vignette_inner = (0.95, 0.95, 0.93)

A simple square shaped map with a raised edge.

ThePad()
794    def __init__(self) -> None:
795        super().__init__()
796        shared = SharedObjects.get()
797        self.node = bs.newnode(
798            'terrain',
799            delegate=self,
800            attrs={
801                'collision_mesh': self.preloaddata['collision_mesh'],
802                'mesh': self.preloaddata['mesh'],
803                'color_texture': self.preloaddata['tex'],
804                'materials': [shared.footing_material],
805            },
806        )
807        self.bottom = bs.newnode(
808            'terrain',
809            attrs={
810                'mesh': self.preloaddata['bottom_mesh'],
811                'lighting': False,
812                'color_texture': self.preloaddata['tex'],
813            },
814        )
815        self.background = bs.newnode(
816            'terrain',
817            attrs={
818                'mesh': self.preloaddata['bgmesh'],
819                'lighting': False,
820                'background': True,
821                'color_texture': self.preloaddata['bgtex'],
822            },
823        )
824        self.railing = bs.newnode(
825            'terrain',
826            attrs={
827                'collision_mesh': self.preloaddata['railing_collision_mesh'],
828                'materials': [shared.railing_material],
829                'bumper': True,
830            },
831        )
832        bs.newnode(
833            'terrain',
834            attrs={
835                'mesh': self.preloaddata['vr_fill_mound_mesh'],
836                'lighting': False,
837                'vr_only': True,
838                'color': (0.56, 0.55, 0.47),
839                'background': True,
840                'color_texture': self.preloaddata['vr_fill_mound_tex'],
841            },
842        )
843        gnode = bs.getactivity().globalsnode
844        gnode.tint = (1.1, 1.1, 1.0)
845        gnode.ambient_color = (1.1, 1.1, 1.0)
846        gnode.vignette_outer = (0.7, 0.65, 0.75)
847        gnode.vignette_inner = (0.95, 0.95, 0.93)

Instantiate a map.

name = 'The Pad'
@override
@classmethod
def get_play_types(cls) -> list[str]:
766    @override
767    @classmethod
768    def get_play_types(cls) -> list[str]:
769        """Return valid play types for this map."""
770        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:
772    @override
773    @classmethod
774    def get_preview_texture_name(cls) -> str:
775        return 'thePadPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
777    @override
778    @classmethod
779    def on_preload(cls) -> Any:
780        data: dict[str, Any] = {
781            'mesh': bs.getmesh('thePadLevel'),
782            'bottom_mesh': bs.getmesh('thePadLevelBottom'),
783            'collision_mesh': bs.getcollisionmesh('thePadLevelCollide'),
784            'tex': bs.gettexture('thePadLevelColor'),
785            'bgtex': bs.gettexture('menuBG'),
786            'bgmesh': bs.getmesh('thePadBG'),
787            'railing_collision_mesh': bs.getcollisionmesh('thePadLevelBumper'),
788            'vr_fill_mound_mesh': bs.getmesh('thePadVRFillMound'),
789            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
790        }
791        # fixme should chop this into vr/non-vr sections for efficiency
792        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):
850class DoomShroom(bs.Map):
851    """A giant mushroom. Of doom!"""
852
853    # noinspection PyUnresolvedReferences
854    from bascenev1lib.mapdata import doom_shroom as defs
855
856    name = 'Doom Shroom'
857
858    @override
859    @classmethod
860    def get_play_types(cls) -> list[str]:
861        """Return valid play types for this map."""
862        return ['melee', 'keep_away', 'team_flag']
863
864    @override
865    @classmethod
866    def get_preview_texture_name(cls) -> str:
867        return 'doomShroomPreview'
868
869    @override
870    @classmethod
871    def on_preload(cls) -> Any:
872        data: dict[str, Any] = {
873            'mesh': bs.getmesh('doomShroomLevel'),
874            'collision_mesh': bs.getcollisionmesh('doomShroomLevelCollide'),
875            'tex': bs.gettexture('doomShroomLevelColor'),
876            'bgtex': bs.gettexture('doomShroomBGColor'),
877            'bgmesh': bs.getmesh('doomShroomBG'),
878            'vr_fill_mesh': bs.getmesh('doomShroomVRFill'),
879            'stem_mesh': bs.getmesh('doomShroomStem'),
880            'collide_bg': bs.getcollisionmesh('doomShroomStemCollide'),
881        }
882        return data
883
884    def __init__(self) -> None:
885        super().__init__()
886        shared = SharedObjects.get()
887        self.node = bs.newnode(
888            'terrain',
889            delegate=self,
890            attrs={
891                'collision_mesh': self.preloaddata['collision_mesh'],
892                'mesh': self.preloaddata['mesh'],
893                'color_texture': self.preloaddata['tex'],
894                'materials': [shared.footing_material],
895            },
896        )
897        self.background = bs.newnode(
898            'terrain',
899            attrs={
900                'mesh': self.preloaddata['bgmesh'],
901                'lighting': False,
902                'background': True,
903                'color_texture': self.preloaddata['bgtex'],
904            },
905        )
906        bs.newnode(
907            'terrain',
908            attrs={
909                'mesh': self.preloaddata['vr_fill_mesh'],
910                'lighting': False,
911                'vr_only': True,
912                'background': True,
913                'color_texture': self.preloaddata['bgtex'],
914            },
915        )
916        self.stem = bs.newnode(
917            'terrain',
918            attrs={
919                'mesh': self.preloaddata['stem_mesh'],
920                'lighting': False,
921                'color_texture': self.preloaddata['tex'],
922            },
923        )
924        self.bg_collide = bs.newnode(
925            'terrain',
926            attrs={
927                'collision_mesh': self.preloaddata['collide_bg'],
928                'materials': [shared.footing_material, shared.death_material],
929            },
930        )
931        gnode = bs.getactivity().globalsnode
932        gnode.tint = (0.82, 1.10, 1.15)
933        gnode.ambient_color = (0.9, 1.3, 1.1)
934        gnode.shadow_ortho = False
935        gnode.vignette_outer = (0.76, 0.76, 0.76)
936        gnode.vignette_inner = (0.95, 0.95, 0.99)
937
938    @override
939    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
940        xpos = point.x
941        zpos = point.z
942        x_adj = xpos * 0.125
943        z_adj = (zpos + 3.7) * 0.2
944        if running:
945            x_adj *= 1.4
946            z_adj *= 1.4
947        return x_adj * x_adj + z_adj * z_adj > 1.0

A giant mushroom. Of doom!

DoomShroom()
884    def __init__(self) -> None:
885        super().__init__()
886        shared = SharedObjects.get()
887        self.node = bs.newnode(
888            'terrain',
889            delegate=self,
890            attrs={
891                'collision_mesh': self.preloaddata['collision_mesh'],
892                'mesh': self.preloaddata['mesh'],
893                'color_texture': self.preloaddata['tex'],
894                'materials': [shared.footing_material],
895            },
896        )
897        self.background = bs.newnode(
898            'terrain',
899            attrs={
900                'mesh': self.preloaddata['bgmesh'],
901                'lighting': False,
902                'background': True,
903                'color_texture': self.preloaddata['bgtex'],
904            },
905        )
906        bs.newnode(
907            'terrain',
908            attrs={
909                'mesh': self.preloaddata['vr_fill_mesh'],
910                'lighting': False,
911                'vr_only': True,
912                'background': True,
913                'color_texture': self.preloaddata['bgtex'],
914            },
915        )
916        self.stem = bs.newnode(
917            'terrain',
918            attrs={
919                'mesh': self.preloaddata['stem_mesh'],
920                'lighting': False,
921                'color_texture': self.preloaddata['tex'],
922            },
923        )
924        self.bg_collide = bs.newnode(
925            'terrain',
926            attrs={
927                'collision_mesh': self.preloaddata['collide_bg'],
928                'materials': [shared.footing_material, shared.death_material],
929            },
930        )
931        gnode = bs.getactivity().globalsnode
932        gnode.tint = (0.82, 1.10, 1.15)
933        gnode.ambient_color = (0.9, 1.3, 1.1)
934        gnode.shadow_ortho = False
935        gnode.vignette_outer = (0.76, 0.76, 0.76)
936        gnode.vignette_inner = (0.95, 0.95, 0.99)

Instantiate a map.

name = 'Doom Shroom'
@override
@classmethod
def get_play_types(cls) -> list[str]:
858    @override
859    @classmethod
860    def get_play_types(cls) -> list[str]:
861        """Return valid play types for this map."""
862        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
864    @override
865    @classmethod
866    def get_preview_texture_name(cls) -> str:
867        return 'doomShroomPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
869    @override
870    @classmethod
871    def on_preload(cls) -> Any:
872        data: dict[str, Any] = {
873            'mesh': bs.getmesh('doomShroomLevel'),
874            'collision_mesh': bs.getcollisionmesh('doomShroomLevelCollide'),
875            'tex': bs.gettexture('doomShroomLevelColor'),
876            'bgtex': bs.gettexture('doomShroomBGColor'),
877            'bgmesh': bs.getmesh('doomShroomBG'),
878            'vr_fill_mesh': bs.getmesh('doomShroomVRFill'),
879            'stem_mesh': bs.getmesh('doomShroomStem'),
880            'collide_bg': bs.getcollisionmesh('doomShroomStemCollide'),
881        }
882        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:
938    @override
939    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
940        xpos = point.x
941        zpos = point.z
942        x_adj = xpos * 0.125
943        z_adj = (zpos + 3.7) * 0.2
944        if running:
945            x_adj *= 1.4
946            z_adj *= 1.4
947        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):
 950class LakeFrigid(bs.Map):
 951    """An icy lake fit for racing."""
 952
 953    # noinspection PyUnresolvedReferences
 954    from bascenev1lib.mapdata import lake_frigid as defs
 955
 956    name = 'Lake Frigid'
 957
 958    @override
 959    @classmethod
 960    def get_play_types(cls) -> list[str]:
 961        """Return valid play types for this map."""
 962        return ['melee', 'keep_away', 'team_flag', 'race']
 963
 964    @override
 965    @classmethod
 966    def get_preview_texture_name(cls) -> str:
 967        return 'lakeFrigidPreview'
 968
 969    @override
 970    @classmethod
 971    def on_preload(cls) -> Any:
 972        data: dict[str, Any] = {
 973            'mesh': bs.getmesh('lakeFrigid'),
 974            'mesh_top': bs.getmesh('lakeFrigidTop'),
 975            'mesh_reflections': bs.getmesh('lakeFrigidReflections'),
 976            'collision_mesh': bs.getcollisionmesh('lakeFrigidCollide'),
 977            'tex': bs.gettexture('lakeFrigid'),
 978            'tex_reflections': bs.gettexture('lakeFrigidReflections'),
 979            'vr_fill_mesh': bs.getmesh('lakeFrigidVRFill'),
 980        }
 981        mat = bs.Material()
 982        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
 983        data['ice_material'] = mat
 984        return data
 985
 986    def __init__(self) -> None:
 987        super().__init__()
 988        shared = SharedObjects.get()
 989        self.node = bs.newnode(
 990            'terrain',
 991            delegate=self,
 992            attrs={
 993                'collision_mesh': self.preloaddata['collision_mesh'],
 994                'mesh': self.preloaddata['mesh'],
 995                'color_texture': self.preloaddata['tex'],
 996                'materials': [
 997                    shared.footing_material,
 998                    self.preloaddata['ice_material'],
 999                ],
1000            },
1001        )
1002        bs.newnode(
1003            'terrain',
1004            attrs={
1005                'mesh': self.preloaddata['mesh_top'],
1006                'lighting': False,
1007                'color_texture': self.preloaddata['tex'],
1008            },
1009        )
1010        bs.newnode(
1011            'terrain',
1012            attrs={
1013                'mesh': self.preloaddata['mesh_reflections'],
1014                'lighting': False,
1015                'overlay': True,
1016                'opacity': 0.15,
1017                'color_texture': self.preloaddata['tex_reflections'],
1018            },
1019        )
1020        bs.newnode(
1021            'terrain',
1022            attrs={
1023                'mesh': self.preloaddata['vr_fill_mesh'],
1024                'lighting': False,
1025                'vr_only': True,
1026                'background': True,
1027                'color_texture': self.preloaddata['tex'],
1028            },
1029        )
1030        gnode = bs.getactivity().globalsnode
1031        gnode.tint = (1, 1, 1)
1032        gnode.ambient_color = (1, 1, 1)
1033        gnode.shadow_ortho = True
1034        gnode.vignette_outer = (0.86, 0.86, 0.86)
1035        gnode.vignette_inner = (0.95, 0.95, 0.99)
1036        gnode.vr_near_clip = 0.5
1037        self.is_hockey = True

An icy lake fit for racing.

LakeFrigid()
 986    def __init__(self) -> None:
 987        super().__init__()
 988        shared = SharedObjects.get()
 989        self.node = bs.newnode(
 990            'terrain',
 991            delegate=self,
 992            attrs={
 993                'collision_mesh': self.preloaddata['collision_mesh'],
 994                'mesh': self.preloaddata['mesh'],
 995                'color_texture': self.preloaddata['tex'],
 996                'materials': [
 997                    shared.footing_material,
 998                    self.preloaddata['ice_material'],
 999                ],
1000            },
1001        )
1002        bs.newnode(
1003            'terrain',
1004            attrs={
1005                'mesh': self.preloaddata['mesh_top'],
1006                'lighting': False,
1007                'color_texture': self.preloaddata['tex'],
1008            },
1009        )
1010        bs.newnode(
1011            'terrain',
1012            attrs={
1013                'mesh': self.preloaddata['mesh_reflections'],
1014                'lighting': False,
1015                'overlay': True,
1016                'opacity': 0.15,
1017                'color_texture': self.preloaddata['tex_reflections'],
1018            },
1019        )
1020        bs.newnode(
1021            'terrain',
1022            attrs={
1023                'mesh': self.preloaddata['vr_fill_mesh'],
1024                'lighting': False,
1025                'vr_only': True,
1026                'background': True,
1027                'color_texture': self.preloaddata['tex'],
1028            },
1029        )
1030        gnode = bs.getactivity().globalsnode
1031        gnode.tint = (1, 1, 1)
1032        gnode.ambient_color = (1, 1, 1)
1033        gnode.shadow_ortho = True
1034        gnode.vignette_outer = (0.86, 0.86, 0.86)
1035        gnode.vignette_inner = (0.95, 0.95, 0.99)
1036        gnode.vr_near_clip = 0.5
1037        self.is_hockey = True

Instantiate a map.

name = 'Lake Frigid'
@override
@classmethod
def get_play_types(cls) -> list[str]:
958    @override
959    @classmethod
960    def get_play_types(cls) -> list[str]:
961        """Return valid play types for this map."""
962        return ['melee', 'keep_away', 'team_flag', 'race']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
964    @override
965    @classmethod
966    def get_preview_texture_name(cls) -> str:
967        return 'lakeFrigidPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
969    @override
970    @classmethod
971    def on_preload(cls) -> Any:
972        data: dict[str, Any] = {
973            'mesh': bs.getmesh('lakeFrigid'),
974            'mesh_top': bs.getmesh('lakeFrigidTop'),
975            'mesh_reflections': bs.getmesh('lakeFrigidReflections'),
976            'collision_mesh': bs.getcollisionmesh('lakeFrigidCollide'),
977            'tex': bs.gettexture('lakeFrigid'),
978            'tex_reflections': bs.gettexture('lakeFrigidReflections'),
979            'vr_fill_mesh': bs.getmesh('lakeFrigidVRFill'),
980        }
981        mat = bs.Material()
982        mat.add_actions(actions=('modify_part_collision', 'friction', 0.01))
983        data['ice_material'] = mat
984        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):
1040class TipTop(bs.Map):
1041    """A pointy map good for king-of-the-hill-ish games."""
1042
1043    # noinspection PyUnresolvedReferences
1044    from bascenev1lib.mapdata import tip_top as defs
1045
1046    name = 'Tip Top'
1047
1048    @override
1049    @classmethod
1050    def get_play_types(cls) -> list[str]:
1051        """Return valid play types for this map."""
1052        return ['melee', 'keep_away', 'team_flag', 'king_of_the_hill']
1053
1054    @override
1055    @classmethod
1056    def get_preview_texture_name(cls) -> str:
1057        return 'tipTopPreview'
1058
1059    @override
1060    @classmethod
1061    def on_preload(cls) -> Any:
1062        data: dict[str, Any] = {
1063            'mesh': bs.getmesh('tipTopLevel'),
1064            'bottom_mesh': bs.getmesh('tipTopLevelBottom'),
1065            'collision_mesh': bs.getcollisionmesh('tipTopLevelCollide'),
1066            'tex': bs.gettexture('tipTopLevelColor'),
1067            'bgtex': bs.gettexture('tipTopBGColor'),
1068            'bgmesh': bs.getmesh('tipTopBG'),
1069            'railing_collision_mesh': bs.getcollisionmesh('tipTopLevelBumper'),
1070        }
1071        return data
1072
1073    def __init__(self) -> None:
1074        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1075        shared = SharedObjects.get()
1076        self.node = bs.newnode(
1077            'terrain',
1078            delegate=self,
1079            attrs={
1080                'collision_mesh': self.preloaddata['collision_mesh'],
1081                'mesh': self.preloaddata['mesh'],
1082                'color_texture': self.preloaddata['tex'],
1083                'color': (0.7, 0.7, 0.7),
1084                'materials': [shared.footing_material],
1085            },
1086        )
1087        self.bottom = bs.newnode(
1088            'terrain',
1089            attrs={
1090                'mesh': self.preloaddata['bottom_mesh'],
1091                'lighting': False,
1092                'color': (0.7, 0.7, 0.7),
1093                'color_texture': self.preloaddata['tex'],
1094            },
1095        )
1096        self.background = bs.newnode(
1097            'terrain',
1098            attrs={
1099                'mesh': self.preloaddata['bgmesh'],
1100                'lighting': False,
1101                'color': (0.4, 0.4, 0.4),
1102                'background': True,
1103                'color_texture': self.preloaddata['bgtex'],
1104            },
1105        )
1106        self.railing = bs.newnode(
1107            'terrain',
1108            attrs={
1109                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1110                'materials': [shared.railing_material],
1111                'bumper': True,
1112            },
1113        )
1114        gnode = bs.getactivity().globalsnode
1115        gnode.tint = (0.8, 0.9, 1.3)
1116        gnode.ambient_color = (0.8, 0.9, 1.3)
1117        gnode.vignette_outer = (0.79, 0.79, 0.69)
1118        gnode.vignette_inner = (0.97, 0.97, 0.99)

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

TipTop()
1073    def __init__(self) -> None:
1074        super().__init__(vr_overlay_offset=(0, -0.2, 2.5))
1075        shared = SharedObjects.get()
1076        self.node = bs.newnode(
1077            'terrain',
1078            delegate=self,
1079            attrs={
1080                'collision_mesh': self.preloaddata['collision_mesh'],
1081                'mesh': self.preloaddata['mesh'],
1082                'color_texture': self.preloaddata['tex'],
1083                'color': (0.7, 0.7, 0.7),
1084                'materials': [shared.footing_material],
1085            },
1086        )
1087        self.bottom = bs.newnode(
1088            'terrain',
1089            attrs={
1090                'mesh': self.preloaddata['bottom_mesh'],
1091                'lighting': False,
1092                'color': (0.7, 0.7, 0.7),
1093                'color_texture': self.preloaddata['tex'],
1094            },
1095        )
1096        self.background = bs.newnode(
1097            'terrain',
1098            attrs={
1099                'mesh': self.preloaddata['bgmesh'],
1100                'lighting': False,
1101                'color': (0.4, 0.4, 0.4),
1102                'background': True,
1103                'color_texture': self.preloaddata['bgtex'],
1104            },
1105        )
1106        self.railing = bs.newnode(
1107            'terrain',
1108            attrs={
1109                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1110                'materials': [shared.railing_material],
1111                'bumper': True,
1112            },
1113        )
1114        gnode = bs.getactivity().globalsnode
1115        gnode.tint = (0.8, 0.9, 1.3)
1116        gnode.ambient_color = (0.8, 0.9, 1.3)
1117        gnode.vignette_outer = (0.79, 0.79, 0.69)
1118        gnode.vignette_inner = (0.97, 0.97, 0.99)

Instantiate a map.

name = 'Tip Top'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1048    @override
1049    @classmethod
1050    def get_play_types(cls) -> list[str]:
1051        """Return valid play types for this map."""
1052        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:
1054    @override
1055    @classmethod
1056    def get_preview_texture_name(cls) -> str:
1057        return 'tipTopPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1059    @override
1060    @classmethod
1061    def on_preload(cls) -> Any:
1062        data: dict[str, Any] = {
1063            'mesh': bs.getmesh('tipTopLevel'),
1064            'bottom_mesh': bs.getmesh('tipTopLevelBottom'),
1065            'collision_mesh': bs.getcollisionmesh('tipTopLevelCollide'),
1066            'tex': bs.gettexture('tipTopLevelColor'),
1067            'bgtex': bs.gettexture('tipTopBGColor'),
1068            'bgmesh': bs.getmesh('tipTopBG'),
1069            'railing_collision_mesh': bs.getcollisionmesh('tipTopLevelBumper'),
1070        }
1071        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):
1121class CragCastle(bs.Map):
1122    """A lovely castle map."""
1123
1124    # noinspection PyUnresolvedReferences
1125    from bascenev1lib.mapdata import crag_castle as defs
1126
1127    name = 'Crag Castle'
1128
1129    @override
1130    @classmethod
1131    def get_play_types(cls) -> list[str]:
1132        """Return valid play types for this map."""
1133        return ['melee', 'keep_away', 'team_flag', 'conquest']
1134
1135    @override
1136    @classmethod
1137    def get_preview_texture_name(cls) -> str:
1138        return 'cragCastlePreview'
1139
1140    @override
1141    @classmethod
1142    def on_preload(cls) -> Any:
1143        data: dict[str, Any] = {
1144            'mesh': bs.getmesh('cragCastleLevel'),
1145            'bottom_mesh': bs.getmesh('cragCastleLevelBottom'),
1146            'collision_mesh': bs.getcollisionmesh('cragCastleLevelCollide'),
1147            'tex': bs.gettexture('cragCastleLevelColor'),
1148            'bgtex': bs.gettexture('menuBG'),
1149            'bgmesh': bs.getmesh('thePadBG'),
1150            'railing_collision_mesh': (
1151                bs.getcollisionmesh('cragCastleLevelBumper')
1152            ),
1153            'vr_fill_mound_mesh': bs.getmesh('cragCastleVRFillMound'),
1154            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1155        }
1156        # fixme should chop this into vr/non-vr sections
1157        return data
1158
1159    def __init__(self) -> None:
1160        super().__init__()
1161        shared = SharedObjects.get()
1162        self.node = bs.newnode(
1163            'terrain',
1164            delegate=self,
1165            attrs={
1166                'collision_mesh': self.preloaddata['collision_mesh'],
1167                'mesh': self.preloaddata['mesh'],
1168                'color_texture': self.preloaddata['tex'],
1169                'materials': [shared.footing_material],
1170            },
1171        )
1172        self.bottom = bs.newnode(
1173            'terrain',
1174            attrs={
1175                'mesh': self.preloaddata['bottom_mesh'],
1176                'lighting': False,
1177                'color_texture': self.preloaddata['tex'],
1178            },
1179        )
1180        self.background = bs.newnode(
1181            'terrain',
1182            attrs={
1183                'mesh': self.preloaddata['bgmesh'],
1184                'lighting': False,
1185                'background': True,
1186                'color_texture': self.preloaddata['bgtex'],
1187            },
1188        )
1189        self.railing = bs.newnode(
1190            'terrain',
1191            attrs={
1192                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1193                'materials': [shared.railing_material],
1194                'bumper': True,
1195            },
1196        )
1197        bs.newnode(
1198            'terrain',
1199            attrs={
1200                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1201                'lighting': False,
1202                'vr_only': True,
1203                'color': (0.2, 0.25, 0.2),
1204                'background': True,
1205                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1206            },
1207        )
1208        gnode = bs.getactivity().globalsnode
1209        gnode.shadow_ortho = True
1210        gnode.shadow_offset = (0, 0, -5.0)
1211        gnode.tint = (1.15, 1.05, 0.75)
1212        gnode.ambient_color = (1.15, 1.05, 0.75)
1213        gnode.vignette_outer = (0.6, 0.65, 0.6)
1214        gnode.vignette_inner = (0.95, 0.95, 0.95)
1215        gnode.vr_near_clip = 1.0

A lovely castle map.

CragCastle()
1159    def __init__(self) -> None:
1160        super().__init__()
1161        shared = SharedObjects.get()
1162        self.node = bs.newnode(
1163            'terrain',
1164            delegate=self,
1165            attrs={
1166                'collision_mesh': self.preloaddata['collision_mesh'],
1167                'mesh': self.preloaddata['mesh'],
1168                'color_texture': self.preloaddata['tex'],
1169                'materials': [shared.footing_material],
1170            },
1171        )
1172        self.bottom = bs.newnode(
1173            'terrain',
1174            attrs={
1175                'mesh': self.preloaddata['bottom_mesh'],
1176                'lighting': False,
1177                'color_texture': self.preloaddata['tex'],
1178            },
1179        )
1180        self.background = bs.newnode(
1181            'terrain',
1182            attrs={
1183                'mesh': self.preloaddata['bgmesh'],
1184                'lighting': False,
1185                'background': True,
1186                'color_texture': self.preloaddata['bgtex'],
1187            },
1188        )
1189        self.railing = bs.newnode(
1190            'terrain',
1191            attrs={
1192                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1193                'materials': [shared.railing_material],
1194                'bumper': True,
1195            },
1196        )
1197        bs.newnode(
1198            'terrain',
1199            attrs={
1200                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1201                'lighting': False,
1202                'vr_only': True,
1203                'color': (0.2, 0.25, 0.2),
1204                'background': True,
1205                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1206            },
1207        )
1208        gnode = bs.getactivity().globalsnode
1209        gnode.shadow_ortho = True
1210        gnode.shadow_offset = (0, 0, -5.0)
1211        gnode.tint = (1.15, 1.05, 0.75)
1212        gnode.ambient_color = (1.15, 1.05, 0.75)
1213        gnode.vignette_outer = (0.6, 0.65, 0.6)
1214        gnode.vignette_inner = (0.95, 0.95, 0.95)
1215        gnode.vr_near_clip = 1.0

Instantiate a map.

name = 'Crag Castle'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1129    @override
1130    @classmethod
1131    def get_play_types(cls) -> list[str]:
1132        """Return valid play types for this map."""
1133        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1135    @override
1136    @classmethod
1137    def get_preview_texture_name(cls) -> str:
1138        return 'cragCastlePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1140    @override
1141    @classmethod
1142    def on_preload(cls) -> Any:
1143        data: dict[str, Any] = {
1144            'mesh': bs.getmesh('cragCastleLevel'),
1145            'bottom_mesh': bs.getmesh('cragCastleLevelBottom'),
1146            'collision_mesh': bs.getcollisionmesh('cragCastleLevelCollide'),
1147            'tex': bs.gettexture('cragCastleLevelColor'),
1148            'bgtex': bs.gettexture('menuBG'),
1149            'bgmesh': bs.getmesh('thePadBG'),
1150            'railing_collision_mesh': (
1151                bs.getcollisionmesh('cragCastleLevelBumper')
1152            ),
1153            'vr_fill_mound_mesh': bs.getmesh('cragCastleVRFillMound'),
1154            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1155        }
1156        # fixme should chop this into vr/non-vr sections
1157        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):
1218class TowerD(bs.Map):
1219    """Map used for runaround mini-game."""
1220
1221    from bascenev1lib.mapdata import tower_d as defs
1222
1223    name = 'Tower D'
1224
1225    @override
1226    @classmethod
1227    def get_play_types(cls) -> list[str]:
1228        """Return valid play types for this map."""
1229        return []
1230
1231    @override
1232    @classmethod
1233    def get_preview_texture_name(cls) -> str:
1234        return 'towerDPreview'
1235
1236    @override
1237    @classmethod
1238    def on_preload(cls) -> Any:
1239        data: dict[str, Any] = {
1240            'mesh': bs.getmesh('towerDLevel'),
1241            'mesh_bottom': bs.getmesh('towerDLevelBottom'),
1242            'collision_mesh': bs.getcollisionmesh('towerDLevelCollide'),
1243            'tex': bs.gettexture('towerDLevelColor'),
1244            'bgtex': bs.gettexture('menuBG'),
1245            'bgmesh': bs.getmesh('thePadBG'),
1246            'player_wall_collision_mesh': bs.getcollisionmesh(
1247                'towerDPlayerWall'
1248            ),
1249            'player_wall_material': bs.Material(),
1250        }
1251        # fixme should chop this into vr/non-vr sections
1252        data['player_wall_material'].add_actions(
1253            actions=('modify_part_collision', 'friction', 0.0)
1254        )
1255        # anything that needs to hit the wall can apply this material
1256        data['collide_with_wall_material'] = bs.Material()
1257        data['player_wall_material'].add_actions(
1258            conditions=(
1259                'they_dont_have_material',
1260                data['collide_with_wall_material'],
1261            ),
1262            actions=('modify_part_collision', 'collide', False),
1263        )
1264        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1265        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1266        return data
1267
1268    def __init__(self) -> None:
1269        super().__init__(vr_overlay_offset=(0, 1, 1))
1270        shared = SharedObjects.get()
1271        self.node = bs.newnode(
1272            'terrain',
1273            delegate=self,
1274            attrs={
1275                'collision_mesh': self.preloaddata['collision_mesh'],
1276                'mesh': self.preloaddata['mesh'],
1277                'color_texture': self.preloaddata['tex'],
1278                'materials': [shared.footing_material],
1279            },
1280        )
1281        self.node_bottom = bs.newnode(
1282            'terrain',
1283            delegate=self,
1284            attrs={
1285                'mesh': self.preloaddata['mesh_bottom'],
1286                'lighting': False,
1287                'color_texture': self.preloaddata['tex'],
1288            },
1289        )
1290        bs.newnode(
1291            'terrain',
1292            attrs={
1293                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1294                'lighting': False,
1295                'vr_only': True,
1296                'color': (0.53, 0.57, 0.5),
1297                'background': True,
1298                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1299            },
1300        )
1301        self.background = bs.newnode(
1302            'terrain',
1303            attrs={
1304                'mesh': self.preloaddata['bgmesh'],
1305                'lighting': False,
1306                'background': True,
1307                'color_texture': self.preloaddata['bgtex'],
1308            },
1309        )
1310        self.player_wall = bs.newnode(
1311            'terrain',
1312            attrs={
1313                'collision_mesh': self.preloaddata[
1314                    'player_wall_collision_mesh'
1315                ],
1316                'affect_bg_dynamics': False,
1317                'materials': [self.preloaddata['player_wall_material']],
1318            },
1319        )
1320        gnode = bs.getactivity().globalsnode
1321        gnode.tint = (1.15, 1.11, 1.03)
1322        gnode.ambient_color = (1.2, 1.1, 1.0)
1323        gnode.vignette_outer = (0.7, 0.73, 0.7)
1324        gnode.vignette_inner = (0.95, 0.95, 0.95)
1325
1326    @override
1327    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1328        # see if we're within edge_box
1329        boxes = self.defs.boxes
1330        box_position = boxes['edge_box'][0:3]
1331        box_scale = boxes['edge_box'][6:9]
1332        box_position2 = boxes['edge_box2'][0:3]
1333        box_scale2 = boxes['edge_box2'][6:9]
1334        xpos = (point.x - box_position[0]) / box_scale[0]
1335        zpos = (point.z - box_position[2]) / box_scale[2]
1336        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1337        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1338        # if we're outside of *both* boxes we're near the edge
1339        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1340            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1341        )

Map used for runaround mini-game.

TowerD()
1268    def __init__(self) -> None:
1269        super().__init__(vr_overlay_offset=(0, 1, 1))
1270        shared = SharedObjects.get()
1271        self.node = bs.newnode(
1272            'terrain',
1273            delegate=self,
1274            attrs={
1275                'collision_mesh': self.preloaddata['collision_mesh'],
1276                'mesh': self.preloaddata['mesh'],
1277                'color_texture': self.preloaddata['tex'],
1278                'materials': [shared.footing_material],
1279            },
1280        )
1281        self.node_bottom = bs.newnode(
1282            'terrain',
1283            delegate=self,
1284            attrs={
1285                'mesh': self.preloaddata['mesh_bottom'],
1286                'lighting': False,
1287                'color_texture': self.preloaddata['tex'],
1288            },
1289        )
1290        bs.newnode(
1291            'terrain',
1292            attrs={
1293                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1294                'lighting': False,
1295                'vr_only': True,
1296                'color': (0.53, 0.57, 0.5),
1297                'background': True,
1298                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1299            },
1300        )
1301        self.background = bs.newnode(
1302            'terrain',
1303            attrs={
1304                'mesh': self.preloaddata['bgmesh'],
1305                'lighting': False,
1306                'background': True,
1307                'color_texture': self.preloaddata['bgtex'],
1308            },
1309        )
1310        self.player_wall = bs.newnode(
1311            'terrain',
1312            attrs={
1313                'collision_mesh': self.preloaddata[
1314                    'player_wall_collision_mesh'
1315                ],
1316                'affect_bg_dynamics': False,
1317                'materials': [self.preloaddata['player_wall_material']],
1318            },
1319        )
1320        gnode = bs.getactivity().globalsnode
1321        gnode.tint = (1.15, 1.11, 1.03)
1322        gnode.ambient_color = (1.2, 1.1, 1.0)
1323        gnode.vignette_outer = (0.7, 0.73, 0.7)
1324        gnode.vignette_inner = (0.95, 0.95, 0.95)

Instantiate a map.

name = 'Tower D'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1225    @override
1226    @classmethod
1227    def get_play_types(cls) -> list[str]:
1228        """Return valid play types for this map."""
1229        return []

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1231    @override
1232    @classmethod
1233    def get_preview_texture_name(cls) -> str:
1234        return 'towerDPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1236    @override
1237    @classmethod
1238    def on_preload(cls) -> Any:
1239        data: dict[str, Any] = {
1240            'mesh': bs.getmesh('towerDLevel'),
1241            'mesh_bottom': bs.getmesh('towerDLevelBottom'),
1242            'collision_mesh': bs.getcollisionmesh('towerDLevelCollide'),
1243            'tex': bs.gettexture('towerDLevelColor'),
1244            'bgtex': bs.gettexture('menuBG'),
1245            'bgmesh': bs.getmesh('thePadBG'),
1246            'player_wall_collision_mesh': bs.getcollisionmesh(
1247                'towerDPlayerWall'
1248            ),
1249            'player_wall_material': bs.Material(),
1250        }
1251        # fixme should chop this into vr/non-vr sections
1252        data['player_wall_material'].add_actions(
1253            actions=('modify_part_collision', 'friction', 0.0)
1254        )
1255        # anything that needs to hit the wall can apply this material
1256        data['collide_with_wall_material'] = bs.Material()
1257        data['player_wall_material'].add_actions(
1258            conditions=(
1259                'they_dont_have_material',
1260                data['collide_with_wall_material'],
1261            ),
1262            actions=('modify_part_collision', 'collide', False),
1263        )
1264        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1265        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1266        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:
1326    @override
1327    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1328        # see if we're within edge_box
1329        boxes = self.defs.boxes
1330        box_position = boxes['edge_box'][0:3]
1331        box_scale = boxes['edge_box'][6:9]
1332        box_position2 = boxes['edge_box2'][0:3]
1333        box_scale2 = boxes['edge_box2'][6:9]
1334        xpos = (point.x - box_position[0]) / box_scale[0]
1335        zpos = (point.z - box_position[2]) / box_scale[2]
1336        xpos2 = (point.x - box_position2[0]) / box_scale2[0]
1337        zpos2 = (point.z - box_position2[2]) / box_scale2[2]
1338        # if we're outside of *both* boxes we're near the edge
1339        return (xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5) and (
1340            xpos2 < -0.5 or xpos2 > 0.5 or zpos2 < -0.5 or zpos2 > 0.5
1341        )

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

Flying map.

HappyThoughts()
1389    def __init__(self) -> None:
1390        super().__init__(vr_overlay_offset=(0, -3.7, 2.5))
1391        shared = SharedObjects.get()
1392        self.node = bs.newnode(
1393            'terrain',
1394            delegate=self,
1395            attrs={
1396                'collision_mesh': self.preloaddata['collision_mesh'],
1397                'mesh': self.preloaddata['mesh'],
1398                'color_texture': self.preloaddata['tex'],
1399                'materials': [shared.footing_material],
1400            },
1401        )
1402        self.bottom = bs.newnode(
1403            'terrain',
1404            attrs={
1405                'mesh': self.preloaddata['bottom_mesh'],
1406                'lighting': False,
1407                'color_texture': self.preloaddata['tex'],
1408            },
1409        )
1410        self.background = bs.newnode(
1411            'terrain',
1412            attrs={
1413                'mesh': self.preloaddata['bgmesh'],
1414                'lighting': False,
1415                'background': True,
1416                'color_texture': self.preloaddata['bgtex'],
1417            },
1418        )
1419        bs.newnode(
1420            'terrain',
1421            attrs={
1422                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1423                'lighting': False,
1424                'vr_only': True,
1425                'color': (0.2, 0.25, 0.2),
1426                'background': True,
1427                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1428            },
1429        )
1430        gnode = bs.getactivity().globalsnode
1431        gnode.happy_thoughts_mode = True
1432        gnode.shadow_offset = (0.0, 8.0, 5.0)
1433        gnode.tint = (1.3, 1.23, 1.0)
1434        gnode.ambient_color = (1.3, 1.23, 1.0)
1435        gnode.vignette_outer = (0.64, 0.59, 0.69)
1436        gnode.vignette_inner = (0.95, 0.95, 0.93)
1437        gnode.vr_near_clip = 1.0
1438        self.is_flying = True
1439
1440        # throw out some tips on flying
1441        txt = bs.newnode(
1442            'text',
1443            attrs={
1444                'text': bs.Lstr(resource='pressJumpToFlyText'),
1445                'scale': 1.2,
1446                'maxwidth': 800,
1447                'position': (0, 200),
1448                'shadow': 0.5,
1449                'flatness': 0.5,
1450                'h_align': 'center',
1451                'v_attach': 'bottom',
1452            },
1453        )
1454        cmb = bs.newnode(
1455            'combine',
1456            owner=txt,
1457            attrs={'size': 4, 'input0': 0.3, 'input1': 0.9, 'input2': 0.0},
1458        )
1459        bs.animate(cmb, 'input3', {3.0: 0, 4.0: 1, 9.0: 1, 10.0: 0})
1460        cmb.connectattr('output', txt, 'color')
1461        bs.timer(10.0, txt.delete)

Instantiate a map.

name = 'Happy Thoughts'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1352    @override
1353    @classmethod
1354    def get_play_types(cls) -> list[str]:
1355        """Return valid play types for this map."""
1356        return [
1357            'melee',
1358            'keep_away',
1359            'team_flag',
1360            'conquest',
1361            'king_of_the_hill',
1362        ]

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1364    @override
1365    @classmethod
1366    def get_preview_texture_name(cls) -> str:
1367        return 'alwaysLandPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1369    @override
1370    @classmethod
1371    def on_preload(cls) -> Any:
1372        data: dict[str, Any] = {
1373            'mesh': bs.getmesh('alwaysLandLevel'),
1374            'bottom_mesh': bs.getmesh('alwaysLandLevelBottom'),
1375            'bgmesh': bs.getmesh('alwaysLandBG'),
1376            'collision_mesh': bs.getcollisionmesh('alwaysLandLevelCollide'),
1377            'tex': bs.gettexture('alwaysLandLevelColor'),
1378            'bgtex': bs.gettexture('alwaysLandBGColor'),
1379            'vr_fill_mound_mesh': bs.getmesh('alwaysLandVRFillMound'),
1380            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1381        }
1382        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:
1384    @override
1385    @classmethod
1386    def get_music_type(cls) -> bs.MusicType:
1387        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):
1464class StepRightUp(bs.Map):
1465    """Wide stepped map good for CTF or Assault."""
1466
1467    # noinspection PyUnresolvedReferences
1468    from bascenev1lib.mapdata import step_right_up as defs
1469
1470    name = 'Step Right Up'
1471
1472    @override
1473    @classmethod
1474    def get_play_types(cls) -> list[str]:
1475        """Return valid play types for this map."""
1476        return ['melee', 'keep_away', 'team_flag', 'conquest']
1477
1478    @override
1479    @classmethod
1480    def get_preview_texture_name(cls) -> str:
1481        return 'stepRightUpPreview'
1482
1483    @override
1484    @classmethod
1485    def on_preload(cls) -> Any:
1486        data: dict[str, Any] = {
1487            'mesh': bs.getmesh('stepRightUpLevel'),
1488            'mesh_bottom': bs.getmesh('stepRightUpLevelBottom'),
1489            'collision_mesh': bs.getcollisionmesh('stepRightUpLevelCollide'),
1490            'tex': bs.gettexture('stepRightUpLevelColor'),
1491            'bgtex': bs.gettexture('menuBG'),
1492            'bgmesh': bs.getmesh('thePadBG'),
1493            'vr_fill_mound_mesh': bs.getmesh('stepRightUpVRFillMound'),
1494            'vr_fill_mound_tex': bs.gettexture('vrFillMound'),
1495        }
1496        # fixme should chop this into vr/non-vr chunks
1497        return data
1498
1499    def __init__(self) -> None:
1500        super().__init__(vr_overlay_offset=(0, -1, 2))
1501        shared = SharedObjects.get()
1502        self.node = bs.newnode(
1503            'terrain',
1504            delegate=self,
1505            attrs={
1506                'collision_mesh': self.preloaddata['collision_mesh'],
1507                'mesh': self.preloaddata['mesh'],
1508                'color_texture': self.preloaddata['tex'],
1509                'materials': [shared.footing_material],
1510            },
1511        )
1512        self.node_bottom = bs.newnode(
1513            'terrain',
1514            delegate=self,
1515            attrs={
1516                'mesh': self.preloaddata['mesh_bottom'],
1517                'lighting': False,
1518                'color_texture': self.preloaddata['tex'],
1519            },
1520        )
1521        bs.newnode(
1522            'terrain',
1523            attrs={
1524                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1525                'lighting': False,
1526                'vr_only': True,
1527                'color': (0.53, 0.57, 0.5),
1528                'background': True,
1529                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1530            },
1531        )
1532        self.background = bs.newnode(
1533            'terrain',
1534            attrs={
1535                'mesh': self.preloaddata['bgmesh'],
1536                'lighting': False,
1537                'background': True,
1538                'color_texture': self.preloaddata['bgtex'],
1539            },
1540        )
1541        gnode = bs.getactivity().globalsnode
1542        gnode.tint = (1.2, 1.1, 1.0)
1543        gnode.ambient_color = (1.2, 1.1, 1.0)
1544        gnode.vignette_outer = (0.7, 0.65, 0.75)
1545        gnode.vignette_inner = (0.95, 0.95, 0.93)

Wide stepped map good for CTF or Assault.

StepRightUp()
1499    def __init__(self) -> None:
1500        super().__init__(vr_overlay_offset=(0, -1, 2))
1501        shared = SharedObjects.get()
1502        self.node = bs.newnode(
1503            'terrain',
1504            delegate=self,
1505            attrs={
1506                'collision_mesh': self.preloaddata['collision_mesh'],
1507                'mesh': self.preloaddata['mesh'],
1508                'color_texture': self.preloaddata['tex'],
1509                'materials': [shared.footing_material],
1510            },
1511        )
1512        self.node_bottom = bs.newnode(
1513            'terrain',
1514            delegate=self,
1515            attrs={
1516                'mesh': self.preloaddata['mesh_bottom'],
1517                'lighting': False,
1518                'color_texture': self.preloaddata['tex'],
1519            },
1520        )
1521        bs.newnode(
1522            'terrain',
1523            attrs={
1524                'mesh': self.preloaddata['vr_fill_mound_mesh'],
1525                'lighting': False,
1526                'vr_only': True,
1527                'color': (0.53, 0.57, 0.5),
1528                'background': True,
1529                'color_texture': self.preloaddata['vr_fill_mound_tex'],
1530            },
1531        )
1532        self.background = bs.newnode(
1533            'terrain',
1534            attrs={
1535                'mesh': self.preloaddata['bgmesh'],
1536                'lighting': False,
1537                'background': True,
1538                'color_texture': self.preloaddata['bgtex'],
1539            },
1540        )
1541        gnode = bs.getactivity().globalsnode
1542        gnode.tint = (1.2, 1.1, 1.0)
1543        gnode.ambient_color = (1.2, 1.1, 1.0)
1544        gnode.vignette_outer = (0.7, 0.65, 0.75)
1545        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]:
1472    @override
1473    @classmethod
1474    def get_play_types(cls) -> list[str]:
1475        """Return valid play types for this map."""
1476        return ['melee', 'keep_away', 'team_flag', 'conquest']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1478    @override
1479    @classmethod
1480    def get_preview_texture_name(cls) -> str:
1481        return 'stepRightUpPreview'

Return the name of the preview texture for this map.

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

Instantiate a map.

name = 'Courtyard'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1555    @override
1556    @classmethod
1557    def get_play_types(cls) -> list[str]:
1558        """Return valid play types for this map."""
1559        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1561    @override
1562    @classmethod
1563    def get_preview_texture_name(cls) -> str:
1564        return 'courtyardPreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1566    @override
1567    @classmethod
1568    def on_preload(cls) -> Any:
1569        data: dict[str, Any] = {
1570            'mesh': bs.getmesh('courtyardLevel'),
1571            'mesh_bottom': bs.getmesh('courtyardLevelBottom'),
1572            'collision_mesh': bs.getcollisionmesh('courtyardLevelCollide'),
1573            'tex': bs.gettexture('courtyardLevelColor'),
1574            'bgtex': bs.gettexture('menuBG'),
1575            'bgmesh': bs.getmesh('thePadBG'),
1576            'player_wall_collision_mesh': (
1577                bs.getcollisionmesh('courtyardPlayerWall')
1578            ),
1579            'player_wall_material': bs.Material(),
1580        }
1581        # FIXME: Chop this into vr and non-vr chunks.
1582        data['player_wall_material'].add_actions(
1583            actions=('modify_part_collision', 'friction', 0.0)
1584        )
1585        # anything that needs to hit the wall should apply this.
1586        data['collide_with_wall_material'] = bs.Material()
1587        data['player_wall_material'].add_actions(
1588            conditions=(
1589                'they_dont_have_material',
1590                data['collide_with_wall_material'],
1591            ),
1592            actions=('modify_part_collision', 'collide', False),
1593        )
1594        data['vr_fill_mound_mesh'] = bs.getmesh('stepRightUpVRFillMound')
1595        data['vr_fill_mound_tex'] = bs.gettexture('vrFillMound')
1596        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:
1657    @override
1658    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1659        # count anything off our ground level as safe (for our platforms)
1660        # see if we're within edge_box
1661        box_position = self.defs.boxes['edge_box'][0:3]
1662        box_scale = self.defs.boxes['edge_box'][6:9]
1663        xpos = (point.x - box_position[0]) / box_scale[0]
1664        zpos = (point.z - box_position[2]) / box_scale[2]
1665        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):
1668class Rampage(bs.Map):
1669    """Wee little map with ramps on the sides."""
1670
1671    from bascenev1lib.mapdata import rampage as defs
1672
1673    name = 'Rampage'
1674
1675    @override
1676    @classmethod
1677    def get_play_types(cls) -> list[str]:
1678        """Return valid play types for this map."""
1679        return ['melee', 'keep_away', 'team_flag']
1680
1681    @override
1682    @classmethod
1683    def get_preview_texture_name(cls) -> str:
1684        return 'rampagePreview'
1685
1686    @override
1687    @classmethod
1688    def on_preload(cls) -> Any:
1689        data: dict[str, Any] = {
1690            'mesh': bs.getmesh('rampageLevel'),
1691            'bottom_mesh': bs.getmesh('rampageLevelBottom'),
1692            'collision_mesh': bs.getcollisionmesh('rampageLevelCollide'),
1693            'tex': bs.gettexture('rampageLevelColor'),
1694            'bgtex': bs.gettexture('rampageBGColor'),
1695            'bgtex2': bs.gettexture('rampageBGColor2'),
1696            'bgmesh': bs.getmesh('rampageBG'),
1697            'bgmesh2': bs.getmesh('rampageBG2'),
1698            'vr_fill_mesh': bs.getmesh('rampageVRFill'),
1699            'railing_collision_mesh': bs.getcollisionmesh('rampageBumper'),
1700        }
1701        return data
1702
1703    def __init__(self) -> None:
1704        super().__init__(vr_overlay_offset=(0, 0, 2))
1705        shared = SharedObjects.get()
1706        self.node = bs.newnode(
1707            'terrain',
1708            delegate=self,
1709            attrs={
1710                'collision_mesh': self.preloaddata['collision_mesh'],
1711                'mesh': self.preloaddata['mesh'],
1712                'color_texture': self.preloaddata['tex'],
1713                'materials': [shared.footing_material],
1714            },
1715        )
1716        self.background = bs.newnode(
1717            'terrain',
1718            attrs={
1719                'mesh': self.preloaddata['bgmesh'],
1720                'lighting': False,
1721                'background': True,
1722                'color_texture': self.preloaddata['bgtex'],
1723            },
1724        )
1725        self.bottom = bs.newnode(
1726            'terrain',
1727            attrs={
1728                'mesh': self.preloaddata['bottom_mesh'],
1729                'lighting': False,
1730                'color_texture': self.preloaddata['tex'],
1731            },
1732        )
1733        self.bg2 = bs.newnode(
1734            'terrain',
1735            attrs={
1736                'mesh': self.preloaddata['bgmesh2'],
1737                'lighting': False,
1738                'background': True,
1739                'color_texture': self.preloaddata['bgtex2'],
1740            },
1741        )
1742        bs.newnode(
1743            'terrain',
1744            attrs={
1745                'mesh': self.preloaddata['vr_fill_mesh'],
1746                'lighting': False,
1747                'vr_only': True,
1748                'background': True,
1749                'color_texture': self.preloaddata['bgtex2'],
1750            },
1751        )
1752        self.railing = bs.newnode(
1753            'terrain',
1754            attrs={
1755                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1756                'materials': [shared.railing_material],
1757                'bumper': True,
1758            },
1759        )
1760        gnode = bs.getactivity().globalsnode
1761        gnode.tint = (1.2, 1.1, 0.97)
1762        gnode.ambient_color = (1.3, 1.2, 1.03)
1763        gnode.vignette_outer = (0.62, 0.64, 0.69)
1764        gnode.vignette_inner = (0.97, 0.95, 0.93)
1765
1766    @override
1767    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1768        box_position = self.defs.boxes['edge_box'][0:3]
1769        box_scale = self.defs.boxes['edge_box'][6:9]
1770        xpos = (point.x - box_position[0]) / box_scale[0]
1771        zpos = (point.z - box_position[2]) / box_scale[2]
1772        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()
1703    def __init__(self) -> None:
1704        super().__init__(vr_overlay_offset=(0, 0, 2))
1705        shared = SharedObjects.get()
1706        self.node = bs.newnode(
1707            'terrain',
1708            delegate=self,
1709            attrs={
1710                'collision_mesh': self.preloaddata['collision_mesh'],
1711                'mesh': self.preloaddata['mesh'],
1712                'color_texture': self.preloaddata['tex'],
1713                'materials': [shared.footing_material],
1714            },
1715        )
1716        self.background = bs.newnode(
1717            'terrain',
1718            attrs={
1719                'mesh': self.preloaddata['bgmesh'],
1720                'lighting': False,
1721                'background': True,
1722                'color_texture': self.preloaddata['bgtex'],
1723            },
1724        )
1725        self.bottom = bs.newnode(
1726            'terrain',
1727            attrs={
1728                'mesh': self.preloaddata['bottom_mesh'],
1729                'lighting': False,
1730                'color_texture': self.preloaddata['tex'],
1731            },
1732        )
1733        self.bg2 = bs.newnode(
1734            'terrain',
1735            attrs={
1736                'mesh': self.preloaddata['bgmesh2'],
1737                'lighting': False,
1738                'background': True,
1739                'color_texture': self.preloaddata['bgtex2'],
1740            },
1741        )
1742        bs.newnode(
1743            'terrain',
1744            attrs={
1745                'mesh': self.preloaddata['vr_fill_mesh'],
1746                'lighting': False,
1747                'vr_only': True,
1748                'background': True,
1749                'color_texture': self.preloaddata['bgtex2'],
1750            },
1751        )
1752        self.railing = bs.newnode(
1753            'terrain',
1754            attrs={
1755                'collision_mesh': self.preloaddata['railing_collision_mesh'],
1756                'materials': [shared.railing_material],
1757                'bumper': True,
1758            },
1759        )
1760        gnode = bs.getactivity().globalsnode
1761        gnode.tint = (1.2, 1.1, 0.97)
1762        gnode.ambient_color = (1.3, 1.2, 1.03)
1763        gnode.vignette_outer = (0.62, 0.64, 0.69)
1764        gnode.vignette_inner = (0.97, 0.95, 0.93)

Instantiate a map.

name = 'Rampage'
@override
@classmethod
def get_play_types(cls) -> list[str]:
1675    @override
1676    @classmethod
1677    def get_play_types(cls) -> list[str]:
1678        """Return valid play types for this map."""
1679        return ['melee', 'keep_away', 'team_flag']

Return valid play types for this map.

@override
@classmethod
def get_preview_texture_name(cls) -> str:
1681    @override
1682    @classmethod
1683    def get_preview_texture_name(cls) -> str:
1684        return 'rampagePreview'

Return the name of the preview texture for this map.

@override
@classmethod
def on_preload(cls) -> Any:
1686    @override
1687    @classmethod
1688    def on_preload(cls) -> Any:
1689        data: dict[str, Any] = {
1690            'mesh': bs.getmesh('rampageLevel'),
1691            'bottom_mesh': bs.getmesh('rampageLevelBottom'),
1692            'collision_mesh': bs.getcollisionmesh('rampageLevelCollide'),
1693            'tex': bs.gettexture('rampageLevelColor'),
1694            'bgtex': bs.gettexture('rampageBGColor'),
1695            'bgtex2': bs.gettexture('rampageBGColor2'),
1696            'bgmesh': bs.getmesh('rampageBG'),
1697            'bgmesh2': bs.getmesh('rampageBG2'),
1698            'vr_fill_mesh': bs.getmesh('rampageVRFill'),
1699            'railing_collision_mesh': bs.getcollisionmesh('rampageBumper'),
1700        }
1701        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:
1766    @override
1767    def is_point_near_edge(self, point: bs.Vec3, running: bool = False) -> bool:
1768        box_position = self.defs.boxes['edge_box'][0:3]
1769        box_scale = self.defs.boxes['edge_box'][6:9]
1770        xpos = (point.x - box_position[0]) / box_scale[0]
1771        zpos = (point.z - box_position[2]) / box_scale[2]
1772        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.