bastd.tutorial
Wrangles the game tutorial sequence.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Wrangles the game tutorial sequence.""" 4 5# Not too concerned with keeping this old module pretty; 6# don't expect to be revisiting it. 7# pylint: disable=too-many-branches 8# pylint: disable=too-many-statements 9# pylint: disable=too-many-lines 10# pylint: disable=missing-function-docstring, missing-class-docstring 11# pylint: disable=invalid-name 12# pylint: disable=too-many-locals 13# pylint: disable=unused-argument 14# pylint: disable=unused-variable 15 16from __future__ import annotations 17 18import math 19from collections import deque 20from typing import TYPE_CHECKING 21 22import ba 23import ba.internal 24from bastd.actor import spaz as basespaz 25 26if TYPE_CHECKING: 27 from typing import Any, Callable, Sequence 28 29 30def _safesetattr(node: ba.Node | None, attr: str, value: Any) -> None: 31 if node: 32 setattr(node, attr, value) 33 34 35class ButtonPress: 36 def __init__( 37 self, 38 button: str, 39 delay: int = 0, 40 release: bool = True, 41 release_delay: int = 0, 42 ): 43 self._button = button 44 self._delay = delay 45 self._release = release 46 self._release_delay = release_delay 47 48 def run(self, a: TutorialActivity) -> None: 49 s = a.current_spaz 50 assert s is not None 51 img: ba.Node | None 52 release_call: Callable[[], None] | None 53 color: Sequence[float] | None 54 if self._button == 'punch': 55 call = s.on_punch_press 56 release_call = s.on_punch_release 57 img = a.punch_image 58 color = a.punch_image_color 59 elif self._button == 'jump': 60 call = s.on_jump_press 61 release_call = s.on_jump_release 62 img = a.jump_image 63 color = a.jump_image_color 64 elif self._button == 'bomb': 65 call = s.on_bomb_press 66 release_call = s.on_bomb_release 67 img = a.bomb_image 68 color = a.bomb_image_color 69 elif self._button == 'pickUp': 70 call = s.on_pickup_press 71 release_call = s.on_pickup_release 72 img = a.pickup_image 73 color = a.pickup_image_color 74 elif self._button == 'run': 75 call = ba.Call(s.on_run, 1.0) 76 release_call = ba.Call(s.on_run, 0.0) 77 img = None 78 color = None 79 else: 80 raise Exception(f'invalid button: {self._button}') 81 82 brightness = 4.0 83 if color is not None: 84 c_bright = list(color) 85 c_bright[0] *= brightness 86 c_bright[1] *= brightness 87 c_bright[2] *= brightness 88 else: 89 c_bright = [1.0, 1.0, 1.0] 90 91 if self._delay == 0: 92 call() 93 if img is not None: 94 img.color = c_bright 95 img.vr_depth = -40 96 else: 97 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 98 if img is not None: 99 ba.timer( 100 self._delay, 101 ba.Call(_safesetattr, img, 'color', c_bright), 102 timeformat=ba.TimeFormat.MILLISECONDS, 103 ) 104 ba.timer( 105 self._delay, 106 ba.Call(_safesetattr, img, 'vr_depth', -30), 107 timeformat=ba.TimeFormat.MILLISECONDS, 108 ) 109 if self._release: 110 if self._delay == 0 and self._release_delay == 0: 111 release_call() 112 else: 113 ba.timer( 114 0.001 * (self._delay + self._release_delay), release_call 115 ) 116 if img is not None: 117 ba.timer( 118 self._delay + self._release_delay + 100, 119 ba.Call(_safesetattr, img, 'color', color), 120 timeformat=ba.TimeFormat.MILLISECONDS, 121 ) 122 ba.timer( 123 self._delay + self._release_delay + 100, 124 ba.Call(_safesetattr, img, 'vr_depth', -20), 125 timeformat=ba.TimeFormat.MILLISECONDS, 126 ) 127 128 129class ButtonRelease: 130 def __init__(self, button: str, delay: int = 0): 131 self._button = button 132 self._delay = delay 133 134 def run(self, a: TutorialActivity) -> None: 135 s = a.current_spaz 136 assert s is not None 137 call: Callable[[], None] | None 138 img: ba.Node | None 139 color: Sequence[float] | None 140 if self._button == 'punch': 141 call = s.on_punch_release 142 img = a.punch_image 143 color = a.punch_image_color 144 elif self._button == 'jump': 145 call = s.on_jump_release 146 img = a.jump_image 147 color = a.jump_image_color 148 elif self._button == 'bomb': 149 call = s.on_bomb_release 150 img = a.bomb_image 151 color = a.bomb_image_color 152 elif self._button == 'pickUp': 153 call = s.on_pickup_press 154 img = a.pickup_image 155 color = a.pickup_image_color 156 elif self._button == 'run': 157 call = ba.Call(s.on_run, 0.0) 158 img = None 159 color = None 160 else: 161 raise Exception('invalid button: ' + self._button) 162 if self._delay == 0: 163 call() 164 else: 165 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 166 if img is not None: 167 ba.timer( 168 self._delay + 100, 169 ba.Call(_safesetattr, img, 'color', color), 170 timeformat=ba.TimeFormat.MILLISECONDS, 171 ) 172 ba.timer( 173 self._delay + 100, 174 ba.Call(_safesetattr, img, 'vr_depth', -20), 175 timeformat=ba.TimeFormat.MILLISECONDS, 176 ) 177 178 179class Player(ba.Player['Team']): 180 """Our player type for this game.""" 181 182 def __init__(self) -> None: 183 self.pressed = False 184 185 186class Team(ba.Team[Player]): 187 """Our team type for this game.""" 188 189 def __init__(self) -> None: 190 pass 191 192 193class TutorialActivity(ba.Activity[Player, Team]): 194 def __init__(self, settings: dict | None = None): 195 from bastd.maps import Rampage 196 197 if settings is None: 198 settings = {} 199 super().__init__(settings) 200 self.current_spaz: basespaz.Spaz | None = None 201 self._benchmark_type = getattr(ba.getsession(), 'benchmark_type', None) 202 self.last_start_time: int | None = None 203 self.cycle_times: list[int] = [] 204 self.allow_pausing = True 205 self.allow_kick_idle_players = False 206 self._issued_warning = False 207 self._map_type = Rampage 208 self._map_type.preload() 209 self._jump_button_tex = ba.gettexture('buttonJump') 210 self._pick_up_button_tex = ba.gettexture('buttonPickUp') 211 self._bomb_button_tex = ba.gettexture('buttonBomb') 212 self._punch_button_tex = ba.gettexture('buttonPunch') 213 self._r = 'tutorial' 214 self._have_skipped = False 215 self.stick_image_position_x = self.stick_image_position_y = 0.0 216 self.spawn_sound = ba.getsound('spawn') 217 self.map: ba.Map | None = None 218 self.text: ba.Node | None = None 219 self._skip_text: ba.Node | None = None 220 self._skip_count_text: ba.Node | None = None 221 self._scale: float | None = None 222 self._stick_base_position: tuple[float, float] = (0.0, 0.0) 223 self._stick_nub_position: tuple[float, float] = (0.0, 0.0) 224 self._stick_base_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 225 self._stick_nub_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 226 self._time: int = -1 227 self.punch_image_color = (1.0, 1.0, 1.0) 228 self.punch_image: ba.Node | None = None 229 self.bomb_image: ba.Node | None = None 230 self.jump_image: ba.Node | None = None 231 self.pickup_image: ba.Node | None = None 232 self._stick_base_image: ba.Node | None = None 233 self._stick_nub_image: ba.Node | None = None 234 self.bomb_image_color = (1.0, 1.0, 1.0) 235 self.pickup_image_color = (1.0, 1.0, 1.0) 236 self.control_ui_nodes: list[ba.Node] = [] 237 self.spazzes: dict[int, basespaz.Spaz] = {} 238 self.jump_image_color = (1.0, 1.0, 1.0) 239 self._entries: deque[Any] = deque() 240 self._read_entries_timer: ba.Timer | None = None 241 self._entry_timer: ba.Timer | None = None 242 243 def on_transition_in(self) -> None: 244 super().on_transition_in() 245 ba.setmusic(ba.MusicType.CHAR_SELECT, continuous=True) 246 self.map = self._map_type() 247 248 def on_begin(self) -> None: 249 super().on_begin() 250 251 ba.set_analytics_screen('Tutorial Start') 252 ba.internal.increment_analytics_count('Tutorial start') 253 254 if bool(False): 255 # Buttons on top. 256 text_y = 140 257 buttons_y = 250 258 else: 259 # Buttons on bottom. 260 text_y = 260 261 buttons_y = 160 262 263 # Need different versions of this: taps/buttons/keys. 264 self.text = ba.newnode( 265 'text', 266 attrs={ 267 'text': '', 268 'scale': 1.9, 269 'position': (0, text_y), 270 'maxwidth': 500, 271 'flatness': 0.0, 272 'shadow': 0.5, 273 'h_align': 'center', 274 'v_align': 'center', 275 'v_attach': 'center', 276 }, 277 ) 278 279 # Need different versions of this: taps/buttons/keys. 280 txt = ( 281 ba.Lstr(resource=self._r + '.cpuBenchmarkText') 282 if self._benchmark_type == 'cpu' 283 else ba.Lstr(resource=self._r + '.toSkipPressAnythingText') 284 ) 285 t = self._skip_text = ba.newnode( 286 'text', 287 attrs={ 288 'text': txt, 289 'maxwidth': 900, 290 'scale': 1.1, 291 'vr_depth': 100, 292 'position': (0, 30), 293 'h_align': 'center', 294 'v_align': 'center', 295 'v_attach': 'bottom', 296 }, 297 ) 298 ba.animate(t, 'opacity', {1.0: 0.0, 2.0: 0.7}) 299 self._skip_count_text = ba.newnode( 300 'text', 301 attrs={ 302 'text': '', 303 'scale': 1.4, 304 'vr_depth': 90, 305 'position': (0, 70), 306 'h_align': 'center', 307 'v_align': 'center', 308 'v_attach': 'bottom', 309 }, 310 ) 311 312 ouya = False 313 314 self._scale = scale = 0.6 315 center_offs = 130.0 * scale 316 offs = 65.0 * scale 317 position = (0, buttons_y) 318 image_size = 90.0 * scale 319 image_size_2 = 220.0 * scale 320 nub_size = 110.0 * scale 321 p = (position[0] + center_offs, position[1] - offs) 322 323 def _sc(r: float, g: float, b: float) -> tuple[float, float, float]: 324 return 0.6 * r, 0.6 * g, 0.6 * b 325 326 self.jump_image_color = c = _sc(0.4, 1, 0.4) 327 self.jump_image = ba.newnode( 328 'image', 329 attrs={ 330 'texture': self._jump_button_tex, 331 'absolute_scale': True, 332 'vr_depth': -20, 333 'position': p, 334 'scale': (image_size, image_size), 335 'color': c, 336 }, 337 ) 338 p = (position[0] + center_offs - offs, position[1]) 339 self.punch_image_color = c = ( 340 _sc(0.2, 0.6, 1) if ouya else _sc(1, 0.7, 0.3) 341 ) 342 self.punch_image = ba.newnode( 343 'image', 344 attrs={ 345 'texture': ba.gettexture('buttonPunch'), 346 'absolute_scale': True, 347 'vr_depth': -20, 348 'position': p, 349 'scale': (image_size, image_size), 350 'color': c, 351 }, 352 ) 353 p = (position[0] + center_offs + offs, position[1]) 354 self.bomb_image_color = c = _sc(1, 0.3, 0.3) 355 self.bomb_image = ba.newnode( 356 'image', 357 attrs={ 358 'texture': ba.gettexture('buttonBomb'), 359 'absolute_scale': True, 360 'vr_depth': -20, 361 'position': p, 362 'scale': (image_size, image_size), 363 'color': c, 364 }, 365 ) 366 p = (position[0] + center_offs, position[1] + offs) 367 self.pickup_image_color = c = ( 368 _sc(1, 0.8, 0.3) if ouya else _sc(0.5, 0.5, 1) 369 ) 370 self.pickup_image = ba.newnode( 371 'image', 372 attrs={ 373 'texture': ba.gettexture('buttonPickUp'), 374 'absolute_scale': True, 375 'vr_depth': -20, 376 'position': p, 377 'scale': (image_size, image_size), 378 'color': c, 379 }, 380 ) 381 382 self._stick_base_position = p = (position[0] - center_offs, position[1]) 383 self._stick_base_image_color = c2 = (0.25, 0.25, 0.25, 1.0) 384 self._stick_base_image = ba.newnode( 385 'image', 386 attrs={ 387 'texture': ba.gettexture('nub'), 388 'absolute_scale': True, 389 'vr_depth': -40, 390 'position': p, 391 'scale': (image_size_2, image_size_2), 392 'color': c2, 393 }, 394 ) 395 self._stick_nub_position = p = (position[0] - center_offs, position[1]) 396 self._stick_nub_image_color = c3 = (0.4, 0.4, 0.4, 1.0) 397 self._stick_nub_image = ba.newnode( 398 'image', 399 attrs={ 400 'texture': ba.gettexture('nub'), 401 'absolute_scale': True, 402 'position': p, 403 'scale': (nub_size, nub_size), 404 'color': c3, 405 }, 406 ) 407 self.control_ui_nodes = [ 408 self.jump_image, 409 self.punch_image, 410 self.bomb_image, 411 self.pickup_image, 412 self._stick_base_image, 413 self._stick_nub_image, 414 ] 415 for n in self.control_ui_nodes: 416 n.opacity = 0.0 417 self._read_entries() 418 419 def set_stick_image_position(self, x: float, y: float) -> None: 420 421 # Clamp this to a circle. 422 len_squared = x * x + y * y 423 if len_squared > 1.0: 424 length = math.sqrt(len_squared) 425 mult = 1.0 / length 426 x *= mult 427 y *= mult 428 429 self.stick_image_position_x = x 430 self.stick_image_position_y = y 431 offs = 50.0 432 assert self._scale is not None 433 p = [ 434 self._stick_nub_position[0] + x * offs * self._scale, 435 self._stick_nub_position[1] + y * offs * self._scale, 436 ] 437 c = list(self._stick_nub_image_color) 438 if abs(x) > 0.1 or abs(y) > 0.1: 439 c[0] *= 2.0 440 c[1] *= 4.0 441 c[2] *= 2.0 442 assert self._stick_nub_image is not None 443 self._stick_nub_image.position = p 444 self._stick_nub_image.color = c 445 c = list(self._stick_base_image_color) 446 if abs(x) > 0.1 or abs(y) > 0.1: 447 c[0] *= 1.5 448 c[1] *= 1.5 449 c[2] *= 1.5 450 assert self._stick_base_image is not None 451 self._stick_base_image.color = c 452 453 def _read_entries(self) -> None: 454 try: 455 456 class Reset: 457 def __init__(self) -> None: 458 pass 459 460 def run(self, a: TutorialActivity) -> None: 461 462 # if we're looping, print out how long each cycle took 463 # print out how long each cycle took.. 464 if a.last_start_time is not None: 465 tval = ( 466 ba.time( 467 ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS 468 ) 469 - a.last_start_time 470 ) 471 assert isinstance(tval, int) 472 diff = tval 473 a.cycle_times.append(diff) 474 ba.screenmessage( 475 'cycle time: ' 476 + str(diff) 477 + ' (average: ' 478 + str(sum(a.cycle_times) / len(a.cycle_times)) 479 + ')' 480 ) 481 tval = ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS) 482 assert isinstance(tval, int) 483 a.last_start_time = tval 484 485 assert a.text 486 a.text.text = '' 487 for spaz in list(a.spazzes.values()): 488 spaz.handlemessage(ba.DieMessage(immediate=True)) 489 a.spazzes = {} 490 a.current_spaz = None 491 for n in a.control_ui_nodes: 492 n.opacity = 0.0 493 a.set_stick_image_position(0, 0) 494 495 # Can be used for debugging. 496 class SetSpeed: 497 def __init__(self, speed: int): 498 self._speed = speed 499 500 def run(self, a: TutorialActivity) -> None: 501 print('setting to', self._speed) 502 ba.internal.set_debug_speed_exponent(self._speed) 503 504 class RemoveGloves: 505 def __init__(self) -> None: 506 pass 507 508 def run(self, a: TutorialActivity) -> None: 509 # pylint: disable=protected-access 510 assert a.current_spaz is not None 511 # noinspection PyProtectedMember 512 a.current_spaz._gloves_wear_off() 513 514 class KillSpaz: 515 def __init__(self, num: int, explode: bool = False): 516 self._num = num 517 self._explode = explode 518 519 def run(self, a: TutorialActivity) -> None: 520 if self._explode: 521 a.spazzes[self._num].shatter() 522 del a.spazzes[self._num] 523 524 class SpawnSpaz: 525 def __init__( 526 self, 527 num: int, 528 position: Sequence[float], 529 color: Sequence[float] = (1.0, 1.0, 1.0), 530 make_current: bool = False, 531 relative_to: int | None = None, 532 name: str | ba.Lstr = '', 533 flash: bool = True, 534 angle: float = 0.0, 535 ): 536 self._num = num 537 self._position = position 538 self._make_current = make_current 539 self._color = color 540 self._relative_to = relative_to 541 self._name = name 542 self._flash = flash 543 self._angle = angle 544 545 def run(self, a: TutorialActivity) -> None: 546 547 # if they gave a 'relative to' spaz, position is relative 548 # to them 549 pos: Sequence[float] 550 if self._relative_to is not None: 551 snode = a.spazzes[self._relative_to].node 552 assert snode 553 their_pos = snode.position 554 pos = ( 555 their_pos[0] + self._position[0], 556 their_pos[1] + self._position[1], 557 their_pos[2] + self._position[2], 558 ) 559 else: 560 pos = self._position 561 562 # if there's already a spaz at this spot, insta-kill it 563 if self._num in a.spazzes: 564 a.spazzes[self._num].handlemessage( 565 ba.DieMessage(immediate=True) 566 ) 567 568 s = a.spazzes[self._num] = basespaz.Spaz( 569 color=self._color, 570 start_invincible=self._flash, 571 demo_mode=True, 572 ) 573 574 # FIXME: Should extend spaz to support Lstr names. 575 assert s.node 576 if isinstance(self._name, ba.Lstr): 577 s.node.name = self._name.evaluate() 578 else: 579 s.node.name = self._name 580 s.node.name_color = self._color 581 s.handlemessage(ba.StandMessage(pos, self._angle)) 582 if self._make_current: 583 a.current_spaz = s 584 if self._flash: 585 ba.playsound(a.spawn_sound, position=pos) 586 587 class Powerup: 588 def __init__( 589 self, 590 num: int, 591 position: Sequence[float], 592 color: Sequence[float] = (1.0, 1.0, 1.0), 593 make_current: bool = False, 594 relative_to: int | None = None, 595 ): 596 self._position = position 597 self._relative_to = relative_to 598 599 def run(self, a: TutorialActivity) -> None: 600 # If they gave a 'relative to' spaz, position is relative 601 # to them. 602 pos: Sequence[float] 603 if self._relative_to is not None: 604 snode = a.spazzes[self._relative_to].node 605 assert snode 606 their_pos = snode.position 607 pos = ( 608 their_pos[0] + self._position[0], 609 their_pos[1] + self._position[1], 610 their_pos[2] + self._position[2], 611 ) 612 else: 613 pos = self._position 614 from bastd.actor import powerupbox 615 616 powerupbox.PowerupBox( 617 position=pos, poweruptype='punch' 618 ).autoretain() 619 620 class Delay: 621 def __init__(self, time: int) -> None: 622 self._time = time 623 624 def run(self, a: TutorialActivity) -> int: 625 return self._time 626 627 class AnalyticsScreen: 628 def __init__(self, screen: str) -> None: 629 self._screen = screen 630 631 def run(self, a: TutorialActivity) -> None: 632 ba.set_analytics_screen(self._screen) 633 634 class DelayOld: 635 def __init__(self, time: int) -> None: 636 self._time = time 637 638 def run(self, a: TutorialActivity) -> int: 639 return int(0.9 * self._time) 640 641 class DelayOld2: 642 def __init__(self, time: int) -> None: 643 self._time = time 644 645 def run(self, a: TutorialActivity) -> int: 646 return int(0.8 * self._time) 647 648 class End: 649 def __init__(self) -> None: 650 pass 651 652 def run(self, a: TutorialActivity) -> None: 653 ba.internal.increment_analytics_count('Tutorial finish') 654 a.end() 655 656 class Move: 657 def __init__(self, x: float, y: float): 658 self._x = float(x) 659 self._y = float(y) 660 661 def run(self, a: TutorialActivity) -> None: 662 s = a.current_spaz 663 assert s 664 # FIXME: Game should take floats for this. 665 x_clamped = self._x 666 y_clamped = self._y 667 s.on_move_left_right(x_clamped) 668 s.on_move_up_down(y_clamped) 669 a.set_stick_image_position(self._x, self._y) 670 671 class MoveLR: 672 def __init__(self, x: float): 673 self._x = float(x) 674 675 def run(self, a: TutorialActivity) -> None: 676 s = a.current_spaz 677 assert s 678 # FIXME: Game should take floats for this. 679 x_clamped = self._x 680 s.on_move_left_right(x_clamped) 681 a.set_stick_image_position( 682 self._x, a.stick_image_position_y 683 ) 684 685 class MoveUD: 686 def __init__(self, y: float): 687 self._y = float(y) 688 689 def run(self, a: TutorialActivity) -> None: 690 s = a.current_spaz 691 assert s 692 # FIXME: Game should take floats for this. 693 y_clamped = self._y 694 s.on_move_up_down(y_clamped) 695 a.set_stick_image_position( 696 a.stick_image_position_x, self._y 697 ) 698 699 class Bomb(ButtonPress): 700 def __init__( 701 self, 702 delay: int = 0, 703 release: bool = True, 704 release_delay: int = 500, 705 ): 706 ButtonPress.__init__( 707 self, 708 'bomb', 709 delay=delay, 710 release=release, 711 release_delay=release_delay, 712 ) 713 714 class Jump(ButtonPress): 715 def __init__( 716 self, 717 delay: int = 0, 718 release: bool = True, 719 release_delay: int = 500, 720 ): 721 ButtonPress.__init__( 722 self, 723 'jump', 724 delay=delay, 725 release=release, 726 release_delay=release_delay, 727 ) 728 729 class Punch(ButtonPress): 730 def __init__( 731 self, 732 delay: int = 0, 733 release: bool = True, 734 release_delay: int = 500, 735 ): 736 ButtonPress.__init__( 737 self, 738 'punch', 739 delay=delay, 740 release=release, 741 release_delay=release_delay, 742 ) 743 744 class PickUp(ButtonPress): 745 def __init__( 746 self, 747 delay: int = 0, 748 release: bool = True, 749 release_delay: int = 500, 750 ): 751 ButtonPress.__init__( 752 self, 753 'pickUp', 754 delay=delay, 755 release=release, 756 release_delay=release_delay, 757 ) 758 759 class Run(ButtonPress): 760 def __init__( 761 self, 762 delay: int = 0, 763 release: bool = True, 764 release_delay: int = 500, 765 ): 766 ButtonPress.__init__( 767 self, 768 'run', 769 delay=delay, 770 release=release, 771 release_delay=release_delay, 772 ) 773 774 class BombRelease(ButtonRelease): 775 def __init__(self, delay: int = 0): 776 super().__init__('bomb', delay=delay) 777 778 class JumpRelease(ButtonRelease): 779 def __init__(self, delay: int = 0): 780 super().__init__('jump', delay=delay) 781 782 class PunchRelease(ButtonRelease): 783 def __init__(self, delay: int = 0): 784 super().__init__('punch', delay=delay) 785 786 class PickUpRelease(ButtonRelease): 787 def __init__(self, delay: int = 0): 788 super().__init__('pickUp', delay=delay) 789 790 class RunRelease(ButtonRelease): 791 def __init__(self, delay: int = 0): 792 super().__init__('run', delay=delay) 793 794 class ShowControls: 795 def __init__(self) -> None: 796 pass 797 798 def run(self, a: TutorialActivity) -> None: 799 for n in a.control_ui_nodes: 800 ba.animate(n, 'opacity', {0.0: 0.0, 1.0: 1.0}) 801 802 class Text: 803 def __init__(self, text: str | ba.Lstr): 804 self.text = text 805 806 def run(self, a: TutorialActivity) -> None: 807 assert a.text 808 a.text.text = self.text 809 810 class PrintPos: 811 def __init__(self, spaz_num: int | None = None): 812 self._spaz_num = spaz_num 813 814 def run(self, a: TutorialActivity) -> None: 815 if self._spaz_num is None: 816 s = a.current_spaz 817 else: 818 s = a.spazzes[self._spaz_num] 819 assert s and s.node 820 t = list(s.node.position) 821 print('RestorePos(' + str((t[0], t[1] - 1.0, t[2])) + '),') 822 823 class RestorePos: 824 def __init__(self, pos: Sequence[float]) -> None: 825 self._pos = pos 826 827 def run(self, a: TutorialActivity) -> None: 828 s = a.current_spaz 829 assert s 830 s.handlemessage(ba.StandMessage(self._pos, 0)) 831 832 class Celebrate: 833 def __init__( 834 self, 835 celebrate_type: str = 'both', 836 spaz_num: int | None = None, 837 duration: int = 1000, 838 ): 839 self._spaz_num = spaz_num 840 self._celebrate_type = celebrate_type 841 self._duration = duration 842 843 def run(self, a: TutorialActivity) -> None: 844 if self._spaz_num is None: 845 s = a.current_spaz 846 else: 847 s = a.spazzes[self._spaz_num] 848 assert s and s.node 849 if self._celebrate_type == 'right': 850 s.node.handlemessage('celebrate_r', self._duration) 851 elif self._celebrate_type == 'left': 852 s.node.handlemessage('celebrate_l', self._duration) 853 elif self._celebrate_type == 'both': 854 s.node.handlemessage('celebrate', self._duration) 855 else: 856 raise Exception( 857 'invalid celebrate type ' + self._celebrate_type 858 ) 859 860 self._entries = deque( 861 [ 862 Reset(), 863 SpawnSpaz(0, (0, 5.5, -3.0), make_current=True), 864 DelayOld(1000), 865 AnalyticsScreen('Tutorial Section 1'), 866 Text( 867 ba.Lstr(resource=self._r + '.phrase01Text') 868 ), # hi there 869 Celebrate('left'), 870 DelayOld(2000), 871 Text( 872 ba.Lstr( 873 resource=self._r + '.phrase02Text', 874 subs=[ 875 ('${APP_NAME}', ba.Lstr(resource='titleText')) 876 ], 877 ) 878 ), # welcome to <appname> 879 DelayOld(80), 880 Run(release=False), 881 Jump(release=False), 882 MoveLR(1), 883 MoveUD(0), 884 DelayOld(70), 885 RunRelease(), 886 JumpRelease(), 887 DelayOld(60), 888 MoveUD(1), 889 DelayOld(30), 890 MoveLR(0), 891 DelayOld(90), 892 MoveLR(-1), 893 DelayOld(20), 894 MoveUD(0), 895 DelayOld(70), 896 MoveUD(-1), 897 DelayOld(20), 898 MoveLR(0), 899 DelayOld(80), 900 MoveUD(0), 901 DelayOld(1500), 902 Text( 903 ba.Lstr(resource=self._r + '.phrase03Text') 904 ), # here's a few tips 905 DelayOld(1000), 906 ShowControls(), 907 DelayOld(1000), 908 Jump(), 909 DelayOld(1000), 910 Jump(), 911 DelayOld(1000), 912 AnalyticsScreen('Tutorial Section 2'), 913 Text( 914 ba.Lstr( 915 resource=self._r + '.phrase04Text', 916 subs=[ 917 ('${APP_NAME}', ba.Lstr(resource='titleText')) 918 ], 919 ) 920 ), # many things are based on physics 921 DelayOld(20), 922 MoveUD(0), 923 DelayOld(60), 924 MoveLR(0), 925 DelayOld(10), 926 MoveLR(0), 927 MoveUD(0), 928 DelayOld(10), 929 MoveLR(0), 930 MoveUD(0), 931 DelayOld(20), 932 MoveUD(-0.0575579), 933 DelayOld(10), 934 MoveUD(-0.207831), 935 DelayOld(30), 936 MoveUD(-0.309793), 937 DelayOld(10), 938 MoveUD(-0.474502), 939 DelayOld(10), 940 MoveLR(0.00390637), 941 MoveUD(-0.647053), 942 DelayOld(20), 943 MoveLR(-0.0745262), 944 MoveUD(-0.819605), 945 DelayOld(10), 946 MoveLR(-0.168645), 947 MoveUD(-0.937254), 948 DelayOld(30), 949 MoveLR(-0.294137), 950 MoveUD(-1), 951 DelayOld(10), 952 MoveLR(-0.411786), 953 DelayOld(10), 954 MoveLR(-0.639241), 955 DelayOld(30), 956 MoveLR(-0.75689), 957 DelayOld(10), 958 MoveLR(-0.905911), 959 DelayOld(20), 960 MoveLR(-1), 961 DelayOld(50), 962 MoveUD(-0.960784), 963 DelayOld(20), 964 MoveUD(-0.819605), 965 MoveUD(-0.61568), 966 DelayOld(20), 967 MoveUD(-0.427442), 968 DelayOld(20), 969 MoveUD(-0.231361), 970 DelayOld(10), 971 MoveUD(-0.00390637), 972 DelayOld(30), 973 MoveUD(0.333354), 974 MoveUD(0.584338), 975 DelayOld(20), 976 MoveUD(0.764733), 977 DelayOld(30), 978 MoveLR(-0.803949), 979 MoveUD(0.913755), 980 DelayOld(10), 981 MoveLR(-0.647084), 982 MoveUD(0.992187), 983 DelayOld(20), 984 MoveLR(-0.435316), 985 MoveUD(1), 986 DelayOld(20), 987 MoveLR(-0.168645), 988 MoveUD(0.976501), 989 MoveLR(0.0744957), 990 MoveUD(0.905911), 991 DelayOld(20), 992 MoveLR(0.270577), 993 MoveUD(0.843165), 994 DelayOld(20), 995 MoveLR(0.435286), 996 MoveUD(0.780419), 997 DelayOld(10), 998 MoveLR(0.66274), 999 MoveUD(0.647084), 1000 DelayOld(30), 1001 MoveLR(0.803919), 1002 MoveUD(0.458846), 1003 MoveLR(0.929411), 1004 MoveUD(0.223548), 1005 DelayOld(20), 1006 MoveLR(0.95294), 1007 MoveUD(0.137272), 1008 DelayOld(20), 1009 MoveLR(1), 1010 MoveUD(-0.0509659), 1011 DelayOld(20), 1012 MoveUD(-0.247047), 1013 DelayOld(20), 1014 MoveUD(-0.443129), 1015 DelayOld(20), 1016 MoveUD(-0.694113), 1017 MoveUD(-0.921567), 1018 DelayOld(30), 1019 MoveLR(0.858821), 1020 MoveUD(-1), 1021 DelayOld(10), 1022 MoveLR(0.68627), 1023 DelayOld(10), 1024 MoveLR(0.364696), 1025 DelayOld(20), 1026 MoveLR(0.0509659), 1027 DelayOld(20), 1028 MoveLR(-0.223548), 1029 DelayOld(10), 1030 MoveLR(-0.600024), 1031 MoveUD(-0.913724), 1032 DelayOld(30), 1033 MoveLR(-0.858852), 1034 MoveUD(-0.717643), 1035 MoveLR(-1), 1036 MoveUD(-0.474502), 1037 DelayOld(20), 1038 MoveUD(-0.396069), 1039 DelayOld(20), 1040 MoveUD(-0.286264), 1041 DelayOld(20), 1042 MoveUD(-0.137242), 1043 DelayOld(20), 1044 MoveUD(0.0353099), 1045 DelayOld(10), 1046 MoveUD(0.32551), 1047 DelayOld(20), 1048 MoveUD(0.592181), 1049 DelayOld(10), 1050 MoveUD(0.851009), 1051 DelayOld(10), 1052 MoveUD(1), 1053 DelayOld(30), 1054 MoveLR(-0.764733), 1055 DelayOld(20), 1056 MoveLR(-0.403943), 1057 MoveLR(-0.145116), 1058 DelayOld(30), 1059 MoveLR(0.0901822), 1060 MoveLR(0.32548), 1061 DelayOld(30), 1062 MoveLR(0.560778), 1063 MoveUD(0.929441), 1064 DelayOld(20), 1065 MoveLR(0.709799), 1066 MoveUD(0.73336), 1067 MoveLR(0.803919), 1068 MoveUD(0.545122), 1069 DelayOld(20), 1070 MoveLR(0.882351), 1071 MoveUD(0.356883), 1072 DelayOld(10), 1073 MoveLR(0.968627), 1074 MoveUD(0.113742), 1075 DelayOld(20), 1076 MoveLR(0.992157), 1077 MoveUD(-0.0823389), 1078 DelayOld(30), 1079 MoveUD(-0.309793), 1080 DelayOld(10), 1081 MoveUD(-0.545091), 1082 DelayOld(20), 1083 MoveLR(0.882351), 1084 MoveUD(-0.874508), 1085 DelayOld(20), 1086 MoveLR(0.756859), 1087 MoveUD(-1), 1088 DelayOld(10), 1089 MoveLR(0.576464), 1090 DelayOld(20), 1091 MoveLR(0.254891), 1092 DelayOld(10), 1093 MoveLR(-0.0274667), 1094 DelayOld(10), 1095 MoveLR(-0.356883), 1096 DelayOld(30), 1097 MoveLR(-0.592181), 1098 MoveLR(-0.827479), 1099 MoveUD(-0.921567), 1100 DelayOld(20), 1101 MoveLR(-1), 1102 MoveUD(-0.749016), 1103 DelayOld(20), 1104 MoveUD(-0.61568), 1105 DelayOld(10), 1106 MoveUD(-0.403912), 1107 DelayOld(20), 1108 MoveUD(-0.207831), 1109 DelayOld(10), 1110 MoveUD(0.121586), 1111 DelayOld(30), 1112 MoveUD(0.34904), 1113 DelayOld(10), 1114 MoveUD(0.560808), 1115 DelayOld(10), 1116 MoveUD(0.827479), 1117 DelayOld(30), 1118 MoveUD(1), 1119 DelayOld(20), 1120 MoveLR(-0.976501), 1121 MoveLR(-0.670614), 1122 DelayOld(20), 1123 MoveLR(-0.239235), 1124 DelayOld(20), 1125 MoveLR(0.160772), 1126 DelayOld(20), 1127 MoveLR(0.443129), 1128 DelayOld(10), 1129 MoveLR(0.68627), 1130 MoveUD(0.976501), 1131 DelayOld(30), 1132 MoveLR(0.929411), 1133 MoveUD(0.73336), 1134 MoveLR(1), 1135 MoveUD(0.482376), 1136 DelayOld(20), 1137 MoveUD(0.34904), 1138 DelayOld(10), 1139 MoveUD(0.160802), 1140 DelayOld(30), 1141 MoveUD(-0.0744957), 1142 DelayOld(10), 1143 MoveUD(-0.333323), 1144 DelayOld(20), 1145 MoveUD(-0.647053), 1146 DelayOld(20), 1147 MoveUD(-0.937254), 1148 DelayOld(10), 1149 MoveLR(0.858821), 1150 MoveUD(-1), 1151 DelayOld(10), 1152 MoveLR(0.576464), 1153 DelayOld(30), 1154 MoveLR(0.184301), 1155 DelayOld(10), 1156 MoveLR(-0.121586), 1157 DelayOld(10), 1158 MoveLR(-0.474532), 1159 DelayOld(30), 1160 MoveLR(-0.670614), 1161 MoveLR(-0.851009), 1162 DelayOld(30), 1163 MoveLR(-1), 1164 MoveUD(-0.968627), 1165 DelayOld(20), 1166 MoveUD(-0.843135), 1167 DelayOld(10), 1168 MoveUD(-0.631367), 1169 DelayOld(20), 1170 MoveUD(-0.403912), 1171 MoveUD(-0.176458), 1172 DelayOld(20), 1173 MoveUD(0.0902127), 1174 DelayOld(20), 1175 MoveUD(0.380413), 1176 DelayOld(10), 1177 MoveUD(0.717673), 1178 DelayOld(30), 1179 MoveUD(1), 1180 DelayOld(10), 1181 MoveLR(-0.741203), 1182 DelayOld(20), 1183 MoveLR(-0.458846), 1184 DelayOld(10), 1185 MoveLR(-0.145116), 1186 DelayOld(10), 1187 MoveLR(0.0980255), 1188 DelayOld(20), 1189 MoveLR(0.294107), 1190 DelayOld(30), 1191 MoveLR(0.466659), 1192 MoveLR(0.717643), 1193 MoveUD(0.796106), 1194 DelayOld(20), 1195 MoveLR(0.921567), 1196 MoveUD(0.443159), 1197 DelayOld(20), 1198 MoveLR(1), 1199 MoveUD(0.145116), 1200 DelayOld(10), 1201 MoveUD(-0.0274361), 1202 DelayOld(30), 1203 MoveUD(-0.223518), 1204 MoveUD(-0.427442), 1205 DelayOld(20), 1206 MoveUD(-0.874508), 1207 DelayOld(20), 1208 MoveUD(-1), 1209 DelayOld(10), 1210 MoveLR(0.929411), 1211 DelayOld(20), 1212 MoveLR(0.68627), 1213 DelayOld(20), 1214 MoveLR(0.364696), 1215 DelayOld(20), 1216 MoveLR(0.0431227), 1217 DelayOld(10), 1218 MoveLR(-0.333354), 1219 DelayOld(20), 1220 MoveLR(-0.639241), 1221 DelayOld(20), 1222 MoveLR(-0.968657), 1223 MoveUD(-0.968627), 1224 DelayOld(20), 1225 MoveLR(-1), 1226 MoveUD(-0.890194), 1227 MoveUD(-0.866665), 1228 DelayOld(20), 1229 MoveUD(-0.749016), 1230 DelayOld(20), 1231 MoveUD(-0.529405), 1232 DelayOld(20), 1233 MoveUD(-0.30195), 1234 DelayOld(10), 1235 MoveUD(-0.00390637), 1236 DelayOld(10), 1237 MoveUD(0.262764), 1238 DelayOld(30), 1239 MoveLR(-0.600024), 1240 MoveUD(0.458846), 1241 DelayOld(10), 1242 MoveLR(-0.294137), 1243 MoveUD(0.482376), 1244 DelayOld(20), 1245 MoveLR(-0.200018), 1246 MoveUD(0.505905), 1247 DelayOld(10), 1248 MoveLR(-0.145116), 1249 MoveUD(0.545122), 1250 DelayOld(20), 1251 MoveLR(-0.0353099), 1252 MoveUD(0.584338), 1253 DelayOld(20), 1254 MoveLR(0.137242), 1255 MoveUD(0.592181), 1256 DelayOld(20), 1257 MoveLR(0.30195), 1258 DelayOld(10), 1259 MoveLR(0.490188), 1260 DelayOld(10), 1261 MoveLR(0.599994), 1262 MoveUD(0.529435), 1263 DelayOld(30), 1264 MoveLR(0.66274), 1265 MoveUD(0.3961), 1266 DelayOld(20), 1267 MoveLR(0.670583), 1268 MoveUD(0.231391), 1269 MoveLR(0.68627), 1270 MoveUD(0.0745262), 1271 Move(0, -0.01), 1272 DelayOld(100), 1273 Move(0, 0), 1274 DelayOld(1000), 1275 Text( 1276 ba.Lstr(resource=self._r + '.phrase05Text') 1277 ), # for example when you punch.. 1278 DelayOld(510), 1279 Move(0, -0.01), 1280 DelayOld(100), 1281 Move(0, 0), 1282 DelayOld(500), 1283 SpawnSpaz( 1284 0, 1285 (-0.09249162673950195, 4.337906360626221, -2.3), 1286 make_current=True, 1287 flash=False, 1288 ), 1289 SpawnSpaz( 1290 1, 1291 (-3.1, 4.3, -2.0), 1292 make_current=False, 1293 color=(1, 1, 0.4), 1294 name=ba.Lstr(resource=self._r + '.randomName1Text'), 1295 ), 1296 Move(-1.0, 0), 1297 DelayOld(1050), 1298 Move(0, -0.01), 1299 DelayOld(100), 1300 Move(0, 0), 1301 DelayOld(1000), 1302 Text( 1303 ba.Lstr(resource=self._r + '.phrase06Text') 1304 ), # your damage is based 1305 DelayOld(1200), 1306 Move(-0.05, 0), 1307 DelayOld(200), 1308 Punch(), 1309 DelayOld(800), 1310 Punch(), 1311 DelayOld(800), 1312 Punch(), 1313 DelayOld(800), 1314 Move(0, -0.01), 1315 DelayOld(100), 1316 Move(0, 0), 1317 Text( 1318 ba.Lstr( 1319 resource=self._r + '.phrase07Text', 1320 subs=[ 1321 ( 1322 '${NAME}', 1323 ba.Lstr( 1324 resource=self._r + '.randomName1Text' 1325 ), 1326 ) 1327 ], 1328 ) 1329 ), # see that didn't hurt fred 1330 DelayOld(2000), 1331 Celebrate('right', spaz_num=1), 1332 DelayOld(1400), 1333 Text( 1334 ba.Lstr(resource=self._r + '.phrase08Text') 1335 ), # lets jump and spin to get more speed 1336 DelayOld(30), 1337 MoveLR(0), 1338 DelayOld(40), 1339 MoveLR(0), 1340 DelayOld(40), 1341 MoveLR(0), 1342 DelayOld(130), 1343 MoveLR(0), 1344 DelayOld(100), 1345 MoveLR(0), 1346 DelayOld(10), 1347 MoveLR(0.0480667), 1348 DelayOld(40), 1349 MoveLR(0.056093), 1350 MoveLR(0.0681173), 1351 DelayOld(30), 1352 MoveLR(0.0801416), 1353 DelayOld(10), 1354 MoveLR(0.184301), 1355 DelayOld(10), 1356 MoveLR(0.207831), 1357 DelayOld(20), 1358 MoveLR(0.231361), 1359 DelayOld(30), 1360 MoveLR(0.239204), 1361 DelayOld(30), 1362 MoveLR(0.254891), 1363 DelayOld(40), 1364 MoveLR(0.270577), 1365 DelayOld(10), 1366 MoveLR(0.30195), 1367 DelayOld(20), 1368 MoveLR(0.341166), 1369 DelayOld(30), 1370 MoveLR(0.388226), 1371 MoveLR(0.435286), 1372 DelayOld(30), 1373 MoveLR(0.490188), 1374 DelayOld(10), 1375 MoveLR(0.560778), 1376 DelayOld(20), 1377 MoveLR(0.599994), 1378 DelayOld(10), 1379 MoveLR(0.647053), 1380 DelayOld(10), 1381 MoveLR(0.68627), 1382 DelayOld(30), 1383 MoveLR(0.733329), 1384 DelayOld(20), 1385 MoveLR(0.764702), 1386 DelayOld(10), 1387 MoveLR(0.827448), 1388 DelayOld(20), 1389 MoveLR(0.874508), 1390 DelayOld(20), 1391 MoveLR(0.929411), 1392 DelayOld(10), 1393 MoveLR(1), 1394 DelayOld(830), 1395 MoveUD(0.0274667), 1396 DelayOld(10), 1397 MoveLR(0.95294), 1398 MoveUD(0.113742), 1399 DelayOld(30), 1400 MoveLR(0.780389), 1401 MoveUD(0.184332), 1402 DelayOld(10), 1403 MoveLR(0.27842), 1404 MoveUD(0.0745262), 1405 DelayOld(20), 1406 MoveLR(0), 1407 MoveUD(0), 1408 DelayOld(390), 1409 MoveLR(0), 1410 MoveLR(0), 1411 DelayOld(20), 1412 MoveLR(0), 1413 DelayOld(20), 1414 MoveLR(0), 1415 DelayOld(10), 1416 MoveLR(-0.0537431), 1417 DelayOld(20), 1418 MoveLR(-0.215705), 1419 DelayOld(30), 1420 MoveLR(-0.388256), 1421 MoveLR(-0.529435), 1422 DelayOld(30), 1423 MoveLR(-0.694143), 1424 DelayOld(20), 1425 MoveLR(-0.851009), 1426 MoveUD(0.0588397), 1427 DelayOld(10), 1428 MoveLR(-1), 1429 MoveUD(0.0745262), 1430 Run(release=False), 1431 DelayOld(200), 1432 MoveUD(0.0509964), 1433 DelayOld(30), 1434 MoveUD(0.0117801), 1435 DelayOld(20), 1436 MoveUD(-0.0901822), 1437 MoveUD(-0.372539), 1438 DelayOld(30), 1439 MoveLR(-0.898068), 1440 MoveUD(-0.890194), 1441 Jump(release=False), 1442 DelayOld(20), 1443 MoveLR(-0.647084), 1444 MoveUD(-1), 1445 MoveLR(-0.427473), 1446 DelayOld(20), 1447 MoveLR(-0.00393689), 1448 DelayOld(10), 1449 MoveLR(0.537248), 1450 DelayOld(30), 1451 MoveLR(1), 1452 DelayOld(50), 1453 RunRelease(), 1454 JumpRelease(), 1455 DelayOld(50), 1456 MoveUD(-0.921567), 1457 MoveUD(-0.749016), 1458 DelayOld(30), 1459 MoveUD(-0.552934), 1460 DelayOld(10), 1461 MoveUD(-0.247047), 1462 DelayOld(20), 1463 MoveUD(0.200018), 1464 DelayOld(20), 1465 MoveUD(0.670614), 1466 MoveUD(1), 1467 DelayOld(70), 1468 MoveLR(0.97647), 1469 DelayOld(20), 1470 MoveLR(0.764702), 1471 DelayOld(20), 1472 MoveLR(0.364696), 1473 DelayOld(20), 1474 MoveLR(0.00390637), 1475 MoveLR(-0.309824), 1476 DelayOld(20), 1477 MoveLR(-0.576495), 1478 DelayOld(30), 1479 MoveLR(-0.898068), 1480 DelayOld(10), 1481 MoveLR(-1), 1482 MoveUD(0.905911), 1483 DelayOld(20), 1484 MoveUD(0.498062), 1485 DelayOld(20), 1486 MoveUD(0.0274667), 1487 MoveUD(-0.403912), 1488 DelayOld(20), 1489 MoveUD(-1), 1490 Run(release=False), 1491 Jump(release=False), 1492 DelayOld(10), 1493 Punch(release=False), 1494 DelayOld(70), 1495 JumpRelease(), 1496 DelayOld(110), 1497 MoveLR(-0.976501), 1498 RunRelease(), 1499 PunchRelease(), 1500 DelayOld(10), 1501 MoveLR(-0.952971), 1502 DelayOld(20), 1503 MoveLR(-0.905911), 1504 MoveLR(-0.827479), 1505 DelayOld(20), 1506 MoveLR(-0.75689), 1507 DelayOld(30), 1508 MoveLR(-0.73336), 1509 MoveLR(-0.694143), 1510 DelayOld(20), 1511 MoveLR(-0.670614), 1512 DelayOld(30), 1513 MoveLR(-0.66277), 1514 DelayOld(10), 1515 MoveUD(-0.960784), 1516 DelayOld(20), 1517 MoveLR(-0.623554), 1518 MoveUD(-0.874508), 1519 DelayOld(10), 1520 MoveLR(-0.545122), 1521 MoveUD(-0.694113), 1522 DelayOld(20), 1523 MoveLR(-0.505905), 1524 MoveUD(-0.474502), 1525 DelayOld(20), 1526 MoveLR(-0.458846), 1527 MoveUD(-0.356853), 1528 MoveLR(-0.364727), 1529 MoveUD(-0.27842), 1530 DelayOld(20), 1531 MoveLR(0.00390637), 1532 Move(0, 0), 1533 DelayOld(1000), 1534 Text( 1535 ba.Lstr(resource=self._r + '.phrase09Text') 1536 ), # ah that's better 1537 DelayOld(1900), 1538 AnalyticsScreen('Tutorial Section 3'), 1539 Text( 1540 ba.Lstr(resource=self._r + '.phrase10Text') 1541 ), # running also helps 1542 DelayOld(100), 1543 SpawnSpaz( 1544 0, (-3.2, 4.3, -4.4), make_current=True, flash=False 1545 ), 1546 SpawnSpaz( 1547 1, 1548 (3.3, 4.2, -5.8), 1549 make_current=False, 1550 color=(0.9, 0.5, 1.0), 1551 name=ba.Lstr(resource=self._r + '.randomName2Text'), 1552 ), 1553 DelayOld(1800), 1554 Text( 1555 ba.Lstr(resource=self._r + '.phrase11Text') 1556 ), # hold ANY button to run 1557 DelayOld(300), 1558 MoveUD(0), 1559 DelayOld(20), 1560 MoveUD(-0.0520646), 1561 DelayOld(20), 1562 MoveLR(0), 1563 MoveUD(-0.223518), 1564 Run(release=False), 1565 Jump(release=False), 1566 DelayOld(10), 1567 MoveLR(0.0980255), 1568 MoveUD(-0.309793), 1569 DelayOld(30), 1570 MoveLR(0.160772), 1571 MoveUD(-0.427442), 1572 DelayOld(20), 1573 MoveLR(0.231361), 1574 MoveUD(-0.545091), 1575 DelayOld(10), 1576 MoveLR(0.317637), 1577 MoveUD(-0.678426), 1578 DelayOld(20), 1579 MoveLR(0.396069), 1580 MoveUD(-0.819605), 1581 MoveLR(0.482345), 1582 MoveUD(-0.913724), 1583 DelayOld(20), 1584 MoveLR(0.560778), 1585 MoveUD(-1), 1586 DelayOld(20), 1587 MoveLR(0.607837), 1588 DelayOld(10), 1589 MoveLR(0.623524), 1590 DelayOld(30), 1591 MoveLR(0.647053), 1592 DelayOld(20), 1593 MoveLR(0.670583), 1594 MoveLR(0.694113), 1595 DelayOld(30), 1596 MoveLR(0.733329), 1597 DelayOld(20), 1598 MoveLR(0.764702), 1599 MoveLR(0.788232), 1600 DelayOld(20), 1601 MoveLR(0.827448), 1602 DelayOld(10), 1603 MoveLR(0.858821), 1604 DelayOld(20), 1605 MoveLR(0.921567), 1606 DelayOld(30), 1607 MoveLR(0.97647), 1608 MoveLR(1), 1609 DelayOld(130), 1610 MoveUD(-0.960784), 1611 DelayOld(20), 1612 MoveUD(-0.921567), 1613 DelayOld(30), 1614 MoveUD(-0.866665), 1615 MoveUD(-0.819605), 1616 DelayOld(30), 1617 MoveUD(-0.772546), 1618 MoveUD(-0.725486), 1619 DelayOld(30), 1620 MoveUD(-0.631367), 1621 DelayOld(10), 1622 MoveUD(-0.552934), 1623 DelayOld(20), 1624 MoveUD(-0.474502), 1625 DelayOld(10), 1626 MoveUD(-0.403912), 1627 DelayOld(30), 1628 MoveUD(-0.356853), 1629 DelayOld(30), 1630 MoveUD(-0.34901), 1631 DelayOld(20), 1632 MoveUD(-0.333323), 1633 DelayOld(20), 1634 MoveUD(-0.32548), 1635 DelayOld(10), 1636 MoveUD(-0.30195), 1637 DelayOld(20), 1638 MoveUD(-0.27842), 1639 DelayOld(30), 1640 MoveUD(-0.254891), 1641 MoveUD(-0.231361), 1642 DelayOld(30), 1643 MoveUD(-0.207831), 1644 DelayOld(20), 1645 MoveUD(-0.199988), 1646 MoveUD(-0.176458), 1647 DelayOld(30), 1648 MoveUD(-0.137242), 1649 MoveUD(-0.0823389), 1650 DelayOld(20), 1651 MoveUD(-0.0274361), 1652 DelayOld(20), 1653 MoveUD(0.00393689), 1654 DelayOld(40), 1655 MoveUD(0.0353099), 1656 DelayOld(20), 1657 MoveUD(0.113742), 1658 DelayOld(10), 1659 MoveUD(0.137272), 1660 DelayOld(20), 1661 MoveUD(0.160802), 1662 MoveUD(0.184332), 1663 DelayOld(20), 1664 MoveUD(0.207862), 1665 DelayOld(30), 1666 MoveUD(0.247078), 1667 MoveUD(0.262764), 1668 DelayOld(20), 1669 MoveUD(0.270608), 1670 DelayOld(30), 1671 MoveUD(0.294137), 1672 MoveUD(0.32551), 1673 DelayOld(30), 1674 MoveUD(0.37257), 1675 Celebrate('left', 1), 1676 DelayOld(20), 1677 MoveUD(0.498062), 1678 MoveUD(0.560808), 1679 DelayOld(30), 1680 MoveUD(0.654927), 1681 MoveUD(0.694143), 1682 DelayOld(30), 1683 MoveUD(0.741203), 1684 DelayOld(20), 1685 MoveUD(0.780419), 1686 MoveUD(0.819636), 1687 DelayOld(20), 1688 MoveUD(0.843165), 1689 DelayOld(20), 1690 MoveUD(0.882382), 1691 DelayOld(10), 1692 MoveUD(0.913755), 1693 DelayOld(30), 1694 MoveUD(0.968657), 1695 MoveUD(1), 1696 DelayOld(560), 1697 Punch(release=False), 1698 DelayOld(210), 1699 MoveUD(0.968657), 1700 DelayOld(30), 1701 MoveUD(0.75689), 1702 PunchRelease(), 1703 DelayOld(20), 1704 MoveLR(0.95294), 1705 MoveUD(0.435316), 1706 RunRelease(), 1707 JumpRelease(), 1708 MoveLR(0.811762), 1709 MoveUD(0.270608), 1710 DelayOld(20), 1711 MoveLR(0.670583), 1712 MoveUD(0.160802), 1713 DelayOld(20), 1714 MoveLR(0.466659), 1715 MoveUD(0.0588397), 1716 DelayOld(10), 1717 MoveLR(0.317637), 1718 MoveUD(-0.00390637), 1719 DelayOld(20), 1720 MoveLR(0.0801416), 1721 DelayOld(10), 1722 MoveLR(0), 1723 DelayOld(20), 1724 MoveLR(0), 1725 DelayOld(30), 1726 MoveLR(0), 1727 DelayOld(30), 1728 MoveLR(0), 1729 DelayOld(20), 1730 MoveLR(0), 1731 DelayOld(100), 1732 MoveLR(0), 1733 DelayOld(30), 1734 MoveUD(0), 1735 DelayOld(30), 1736 MoveUD(0), 1737 DelayOld(50), 1738 MoveUD(0), 1739 MoveUD(0), 1740 DelayOld(30), 1741 MoveLR(0), 1742 MoveUD(-0.0520646), 1743 MoveLR(0), 1744 MoveUD(-0.0640889), 1745 DelayOld(20), 1746 MoveLR(0), 1747 MoveUD(-0.0881375), 1748 DelayOld(30), 1749 MoveLR(-0.0498978), 1750 MoveUD(-0.199988), 1751 MoveLR(-0.121586), 1752 MoveUD(-0.207831), 1753 DelayOld(20), 1754 MoveLR(-0.145116), 1755 MoveUD(-0.223518), 1756 DelayOld(30), 1757 MoveLR(-0.152959), 1758 MoveUD(-0.231361), 1759 MoveLR(-0.192175), 1760 MoveUD(-0.262734), 1761 DelayOld(30), 1762 MoveLR(-0.200018), 1763 MoveUD(-0.27842), 1764 DelayOld(20), 1765 MoveLR(-0.239235), 1766 MoveUD(-0.30195), 1767 MoveUD(-0.309793), 1768 DelayOld(40), 1769 MoveUD(-0.333323), 1770 DelayOld(10), 1771 MoveUD(-0.34901), 1772 DelayOld(30), 1773 MoveUD(-0.372539), 1774 MoveUD(-0.396069), 1775 DelayOld(20), 1776 MoveUD(-0.443129), 1777 DelayOld(20), 1778 MoveUD(-0.458815), 1779 DelayOld(10), 1780 MoveUD(-0.474502), 1781 DelayOld(50), 1782 MoveUD(-0.482345), 1783 DelayOld(30), 1784 MoveLR(-0.215705), 1785 DelayOld(30), 1786 MoveLR(-0.200018), 1787 DelayOld(10), 1788 MoveLR(-0.192175), 1789 DelayOld(10), 1790 MoveLR(-0.176489), 1791 DelayOld(30), 1792 MoveLR(-0.152959), 1793 DelayOld(20), 1794 MoveLR(-0.145116), 1795 MoveLR(-0.121586), 1796 MoveUD(-0.458815), 1797 DelayOld(30), 1798 MoveLR(-0.098056), 1799 MoveUD(-0.419599), 1800 DelayOld(10), 1801 MoveLR(-0.0745262), 1802 MoveUD(-0.333323), 1803 DelayOld(10), 1804 MoveLR(0.00390637), 1805 MoveUD(0), 1806 DelayOld(990), 1807 MoveLR(0), 1808 DelayOld(660), 1809 MoveUD(0), 1810 AnalyticsScreen('Tutorial Section 4'), 1811 Text( 1812 ba.Lstr(resource=self._r + '.phrase12Text') 1813 ), # for extra-awesome punches,... 1814 DelayOld(200), 1815 SpawnSpaz( 1816 0, 1817 ( 1818 2.368781805038452, 1819 4.337533950805664, 1820 -4.360159873962402, 1821 ), 1822 make_current=True, 1823 flash=False, 1824 ), 1825 SpawnSpaz( 1826 1, 1827 (-3.2, 4.3, -4.5), 1828 make_current=False, 1829 color=(1.0, 0.7, 0.3), 1830 # name=R.randomName3Text), 1831 name=ba.Lstr(resource=self._r + '.randomName3Text'), 1832 ), 1833 DelayOld(100), 1834 Powerup(1, (2.5, 0.0, 0), relative_to=0), 1835 Move(1, 0), 1836 DelayOld(1700), 1837 Move(0, -0.1), 1838 DelayOld(100), 1839 Move(0, 0), 1840 DelayOld(500), 1841 DelayOld(320), 1842 MoveLR(0), 1843 DelayOld(20), 1844 MoveLR(0), 1845 DelayOld(10), 1846 MoveLR(0), 1847 DelayOld(20), 1848 MoveLR(-0.333354), 1849 MoveLR(-0.592181), 1850 DelayOld(20), 1851 MoveLR(-0.788263), 1852 DelayOld(20), 1853 MoveLR(-1), 1854 MoveUD(0.0353099), 1855 MoveUD(0.0588397), 1856 DelayOld(10), 1857 Run(release=False), 1858 DelayOld(780), 1859 MoveUD(0.0274667), 1860 MoveUD(0.00393689), 1861 DelayOld(10), 1862 MoveUD(-0.00390637), 1863 DelayOld(440), 1864 MoveUD(0.0353099), 1865 DelayOld(20), 1866 MoveUD(0.0588397), 1867 DelayOld(10), 1868 MoveUD(0.0902127), 1869 DelayOld(260), 1870 MoveUD(0.0353099), 1871 DelayOld(30), 1872 MoveUD(0.00393689), 1873 DelayOld(10), 1874 MoveUD(-0.00390637), 1875 MoveUD(-0.0274361), 1876 Celebrate('left', 1), 1877 DelayOld(10), 1878 MoveUD(-0.0823389), 1879 DelayOld(30), 1880 MoveUD(-0.176458), 1881 MoveUD(-0.286264), 1882 DelayOld(20), 1883 MoveUD(-0.498032), 1884 Jump(release=False), 1885 MoveUD(-0.764702), 1886 DelayOld(30), 1887 MoveLR(-0.858852), 1888 MoveUD(-1), 1889 MoveLR(-0.780419), 1890 DelayOld(20), 1891 MoveLR(-0.717673), 1892 DelayOld(10), 1893 MoveLR(-0.552965), 1894 DelayOld(10), 1895 MoveLR(-0.341197), 1896 DelayOld(10), 1897 MoveLR(-0.0274667), 1898 DelayOld(10), 1899 MoveLR(0.27842), 1900 DelayOld(20), 1901 MoveLR(0.811762), 1902 MoveLR(1), 1903 RunRelease(), 1904 JumpRelease(), 1905 DelayOld(260), 1906 MoveLR(0.95294), 1907 DelayOld(30), 1908 MoveLR(0.756859), 1909 DelayOld(10), 1910 MoveLR(0.317637), 1911 MoveLR(-0.00393689), 1912 DelayOld(10), 1913 MoveLR(-0.341197), 1914 DelayOld(10), 1915 MoveLR(-0.647084), 1916 MoveUD(-0.921567), 1917 DelayOld(10), 1918 MoveLR(-1), 1919 MoveUD(-0.599994), 1920 MoveUD(-0.474502), 1921 DelayOld(10), 1922 MoveUD(-0.309793), 1923 DelayOld(10), 1924 MoveUD(-0.160772), 1925 MoveUD(-0.0352794), 1926 Delay(10), 1927 MoveUD(0.176489), 1928 Delay(10), 1929 MoveUD(0.607868), 1930 Run(release=False), 1931 Jump(release=False), 1932 DelayOld(20), 1933 MoveUD(1), 1934 DelayOld(30), 1935 MoveLR(-0.921598), 1936 DelayOld(10), 1937 Punch(release=False), 1938 MoveLR(-0.639241), 1939 DelayOld(10), 1940 MoveLR(-0.223548), 1941 DelayOld(10), 1942 MoveLR(0.254891), 1943 DelayOld(10), 1944 MoveLR(0.741172), 1945 MoveLR(1), 1946 DelayOld(40), 1947 JumpRelease(), 1948 DelayOld(40), 1949 MoveUD(0.976501), 1950 DelayOld(10), 1951 MoveUD(0.73336), 1952 DelayOld(10), 1953 MoveUD(0.309824), 1954 DelayOld(20), 1955 MoveUD(-0.184301), 1956 DelayOld(20), 1957 MoveUD(-0.811762), 1958 MoveUD(-1), 1959 KillSpaz(1, explode=True), 1960 DelayOld(10), 1961 RunRelease(), 1962 PunchRelease(), 1963 DelayOld(110), 1964 MoveLR(0.97647), 1965 MoveLR(0.898038), 1966 DelayOld(20), 1967 MoveLR(0.788232), 1968 DelayOld(20), 1969 MoveLR(0.670583), 1970 DelayOld(10), 1971 MoveLR(0.505875), 1972 DelayOld(10), 1973 MoveLR(0.32548), 1974 DelayOld(20), 1975 MoveLR(0.137242), 1976 DelayOld(10), 1977 MoveLR(-0.00393689), 1978 DelayOld(10), 1979 MoveLR(-0.215705), 1980 MoveLR(-0.356883), 1981 DelayOld(20), 1982 MoveLR(-0.451003), 1983 DelayOld(10), 1984 MoveLR(-0.552965), 1985 DelayOld(20), 1986 MoveLR(-0.670614), 1987 MoveLR(-0.780419), 1988 DelayOld(10), 1989 MoveLR(-0.898068), 1990 DelayOld(20), 1991 MoveLR(-1), 1992 DelayOld(370), 1993 MoveLR(-0.976501), 1994 DelayOld(10), 1995 MoveLR(-0.952971), 1996 DelayOld(10), 1997 MoveLR(-0.929441), 1998 MoveLR(-0.898068), 1999 DelayOld(30), 2000 MoveLR(-0.874538), 2001 DelayOld(10), 2002 MoveLR(-0.851009), 2003 DelayOld(10), 2004 MoveLR(-0.835322), 2005 MoveUD(-0.968627), 2006 DelayOld(10), 2007 MoveLR(-0.827479), 2008 MoveUD(-0.960784), 2009 DelayOld(20), 2010 MoveUD(-0.945097), 2011 DelayOld(70), 2012 MoveUD(-0.937254), 2013 DelayOld(20), 2014 MoveUD(-0.913724), 2015 DelayOld(20), 2016 MoveUD(-0.890194), 2017 MoveLR(-0.780419), 2018 MoveUD(-0.827448), 2019 DelayOld(20), 2020 MoveLR(0.317637), 2021 MoveUD(0.3961), 2022 MoveLR(0.0195929), 2023 MoveUD(0.056093), 2024 DelayOld(20), 2025 MoveUD(0), 2026 DelayOld(750), 2027 MoveLR(0), 2028 Text( 2029 ba.Lstr( 2030 resource=self._r + '.phrase13Text', 2031 subs=[ 2032 ( 2033 '${NAME}', 2034 ba.Lstr( 2035 resource=self._r + '.randomName3Text' 2036 ), 2037 ) 2038 ], 2039 ) 2040 ), # whoops sorry bill 2041 RemoveGloves(), 2042 DelayOld(2000), 2043 AnalyticsScreen('Tutorial Section 5'), 2044 Text( 2045 ba.Lstr( 2046 resource=self._r + '.phrase14Text', 2047 subs=[ 2048 ( 2049 '${NAME}', 2050 ba.Lstr( 2051 resource=self._r + '.randomName4Text' 2052 ), 2053 ) 2054 ], 2055 ) 2056 ), # you can pick up and throw things such as chuck here 2057 SpawnSpaz( 2058 0, 2059 (-4.0, 4.3, -2.5), 2060 make_current=True, 2061 flash=False, 2062 angle=90, 2063 ), 2064 SpawnSpaz( 2065 1, 2066 (5, 0, -1.0), 2067 relative_to=0, 2068 make_current=False, 2069 color=(0.4, 1.0, 0.7), 2070 name=ba.Lstr(resource=self._r + '.randomName4Text'), 2071 ), 2072 DelayOld(1000), 2073 Celebrate('left', 1, duration=1000), 2074 Move(1, 0.2), 2075 DelayOld(2000), 2076 PickUp(), 2077 DelayOld(200), 2078 Move(0.5, 1.0), 2079 DelayOld(1200), 2080 PickUp(), 2081 Move(0, 0), 2082 DelayOld(1000), 2083 Celebrate('left'), 2084 DelayOld(1500), 2085 Move(0, -1.0), 2086 DelayOld(800), 2087 Move(0, 0), 2088 DelayOld(800), 2089 SpawnSpaz( 2090 0, 2091 (1.5, 4.3, -4.0), 2092 make_current=True, 2093 flash=False, 2094 angle=0, 2095 ), 2096 AnalyticsScreen('Tutorial Section 6'), 2097 Text( 2098 ba.Lstr(resource=self._r + '.phrase15Text') 2099 ), # lastly there's bombs 2100 DelayOld(1900), 2101 Text( 2102 ba.Lstr(resource=self._r + '.phrase16Text') 2103 ), # throwing bombs takes practice 2104 DelayOld(2000), 2105 Bomb(), 2106 Move(-0.1, -0.1), 2107 DelayOld(100), 2108 Move(0, 0), 2109 DelayOld(500), 2110 DelayOld(1000), 2111 Bomb(), 2112 DelayOld(2000), 2113 Text( 2114 ba.Lstr(resource=self._r + '.phrase17Text') 2115 ), # not a very good throw 2116 DelayOld(3000), 2117 Text( 2118 ba.Lstr(resource=self._r + '.phrase18Text') 2119 ), # moving helps you get distance 2120 DelayOld(1000), 2121 Bomb(), 2122 DelayOld(500), 2123 Move(-0.3, 0), 2124 DelayOld(100), 2125 Move(-0.6, 0), 2126 DelayOld(100), 2127 Move(-1, 0), 2128 DelayOld(800), 2129 Bomb(), 2130 DelayOld(400), 2131 Move(0, -0.1), 2132 DelayOld(100), 2133 Move(0, 0), 2134 DelayOld(2500), 2135 Text( 2136 ba.Lstr(resource=self._r + '.phrase19Text') 2137 ), # jumping helps you get height 2138 DelayOld(2000), 2139 Bomb(), 2140 DelayOld(500), 2141 Move(1, 0), 2142 DelayOld(300), 2143 Jump(release_delay=250), 2144 DelayOld(500), 2145 Jump(release_delay=250), 2146 DelayOld(550), 2147 Jump(release_delay=250), 2148 DelayOld(160), 2149 Punch(), 2150 DelayOld(500), 2151 Move(0, -0.1), 2152 DelayOld(100), 2153 Move(0, 0), 2154 DelayOld(2000), 2155 Text( 2156 ba.Lstr(resource=self._r + '.phrase20Text') 2157 ), # whiplash your bombs 2158 DelayOld(1000), 2159 Bomb(release=False), 2160 DelayOld2(80), 2161 RunRelease(), 2162 BombRelease(), 2163 DelayOld2(620), 2164 MoveLR(0), 2165 DelayOld2(10), 2166 MoveLR(0), 2167 DelayOld2(40), 2168 MoveLR(0), 2169 DelayOld2(10), 2170 MoveLR(-0.0537431), 2171 MoveUD(0), 2172 DelayOld2(20), 2173 MoveLR(-0.262764), 2174 DelayOld2(20), 2175 MoveLR(-0.498062), 2176 DelayOld2(10), 2177 MoveLR(-0.639241), 2178 DelayOld2(20), 2179 MoveLR(-0.73336), 2180 DelayOld2(10), 2181 MoveLR(-0.843165), 2182 MoveUD(-0.0352794), 2183 DelayOld2(30), 2184 MoveLR(-1), 2185 DelayOld2(10), 2186 MoveUD(-0.0588092), 2187 DelayOld2(10), 2188 MoveUD(-0.160772), 2189 DelayOld2(20), 2190 MoveUD(-0.286264), 2191 DelayOld2(20), 2192 MoveUD(-0.427442), 2193 DelayOld2(10), 2194 MoveUD(-0.623524), 2195 DelayOld2(20), 2196 MoveUD(-0.843135), 2197 DelayOld2(10), 2198 MoveUD(-1), 2199 DelayOld2(40), 2200 MoveLR(-0.890225), 2201 DelayOld2(10), 2202 MoveLR(-0.670614), 2203 DelayOld2(20), 2204 MoveLR(-0.435316), 2205 DelayOld2(20), 2206 MoveLR(-0.184332), 2207 DelayOld2(10), 2208 MoveLR(0.00390637), 2209 DelayOld2(20), 2210 MoveLR(0.223518), 2211 DelayOld2(10), 2212 MoveLR(0.388226), 2213 DelayOld2(20), 2214 MoveLR(0.560778), 2215 DelayOld2(20), 2216 MoveLR(0.717643), 2217 DelayOld2(10), 2218 MoveLR(0.890194), 2219 DelayOld2(20), 2220 MoveLR(1), 2221 DelayOld2(30), 2222 MoveUD(-0.968627), 2223 DelayOld2(20), 2224 MoveUD(-0.898038), 2225 DelayOld2(10), 2226 MoveUD(-0.741172), 2227 DelayOld2(20), 2228 MoveUD(-0.498032), 2229 DelayOld2(20), 2230 MoveUD(-0.247047), 2231 DelayOld2(10), 2232 MoveUD(0.00393689), 2233 DelayOld2(20), 2234 MoveUD(0.239235), 2235 DelayOld2(20), 2236 MoveUD(0.458846), 2237 DelayOld2(10), 2238 MoveUD(0.70983), 2239 DelayOld2(30), 2240 MoveUD(1), 2241 DelayOld2(10), 2242 MoveLR(0.827448), 2243 DelayOld2(10), 2244 MoveLR(0.678426), 2245 DelayOld2(20), 2246 MoveLR(0.396069), 2247 DelayOld2(10), 2248 MoveLR(0.0980255), 2249 DelayOld2(20), 2250 MoveLR(-0.160802), 2251 DelayOld2(20), 2252 MoveLR(-0.388256), 2253 DelayOld2(10), 2254 MoveLR(-0.545122), 2255 DelayOld2(30), 2256 MoveLR(-0.73336), 2257 DelayOld2(10), 2258 MoveLR(-0.945128), 2259 DelayOld2(10), 2260 MoveLR(-1), 2261 DelayOld2(50), 2262 MoveUD(0.960814), 2263 DelayOld2(20), 2264 MoveUD(0.890225), 2265 DelayOld2(10), 2266 MoveUD(0.749046), 2267 DelayOld2(20), 2268 MoveUD(0.623554), 2269 DelayOld2(20), 2270 MoveUD(0.498062), 2271 DelayOld2(10), 2272 MoveUD(0.34904), 2273 DelayOld2(20), 2274 MoveUD(0.239235), 2275 DelayOld2(20), 2276 MoveUD(0.137272), 2277 DelayOld2(10), 2278 MoveUD(0.0117801), 2279 DelayOld2(20), 2280 MoveUD(-0.0117496), 2281 DelayOld2(10), 2282 MoveUD(-0.0274361), 2283 DelayOld2(90), 2284 MoveUD(-0.0352794), 2285 Run(release=False), 2286 Jump(release=False), 2287 Delay(80), 2288 Punch(release=False), 2289 DelayOld2(60), 2290 MoveLR(-0.968657), 2291 DelayOld2(20), 2292 MoveLR(-0.835322), 2293 DelayOld2(10), 2294 MoveLR(-0.70983), 2295 JumpRelease(), 2296 DelayOld2(30), 2297 MoveLR(-0.592181), 2298 MoveUD(-0.0588092), 2299 DelayOld2(10), 2300 MoveLR(-0.490219), 2301 MoveUD(-0.0744957), 2302 DelayOld2(10), 2303 MoveLR(-0.41963), 2304 DelayOld2(20), 2305 MoveLR(0), 2306 MoveUD(0), 2307 DelayOld2(20), 2308 MoveUD(0), 2309 PunchRelease(), 2310 RunRelease(), 2311 DelayOld(500), 2312 Move(0, -0.1), 2313 DelayOld(100), 2314 Move(0, 0), 2315 DelayOld(2000), 2316 AnalyticsScreen('Tutorial Section 7'), 2317 Text( 2318 ba.Lstr(resource=self._r + '.phrase21Text') 2319 ), # timing your bombs can be tricky 2320 Move(-1, 0), 2321 DelayOld(1000), 2322 Move(0, -0.1), 2323 DelayOld(100), 2324 Move(0, 0), 2325 SpawnSpaz( 2326 0, 2327 (-0.7, 4.3, -3.9), 2328 make_current=True, 2329 flash=False, 2330 angle=-30, 2331 ), 2332 SpawnSpaz( 2333 1, 2334 (6.5, 0, -0.75), 2335 relative_to=0, 2336 make_current=False, 2337 color=(0.3, 0.8, 1.0), 2338 name=ba.Lstr(resource=self._r + '.randomName5Text'), 2339 ), 2340 DelayOld2(1000), 2341 Move(-1, 0), 2342 DelayOld2(1800), 2343 Bomb(), 2344 Move(0, 0), 2345 DelayOld2(300), 2346 Move(1, 0), 2347 DelayOld2(600), 2348 Jump(), 2349 DelayOld2(150), 2350 Punch(), 2351 DelayOld2(800), 2352 Move(-1, 0), 2353 DelayOld2(1000), 2354 Move(0, 0), 2355 DelayOld2(1500), 2356 Text(ba.Lstr(resource=self._r + '.phrase22Text')), # dang 2357 Delay(1500), 2358 Text(''), 2359 Delay(200), 2360 Text( 2361 ba.Lstr(resource=self._r + '.phrase23Text') 2362 ), # try cooking off 2363 Delay(1500), 2364 Bomb(), 2365 Delay(800), 2366 Move(1, 0.12), 2367 Delay(1100), 2368 Jump(), 2369 Delay(100), 2370 Punch(), 2371 Delay(100), 2372 Move(0, -0.1), 2373 Delay(100), 2374 Move(0, 0), 2375 Delay(2000), 2376 Text( 2377 ba.Lstr(resource=self._r + '.phrase24Text') 2378 ), # hooray nicely cooked 2379 Celebrate(), 2380 DelayOld(2000), 2381 KillSpaz(1), 2382 Text(''), 2383 Move(0.5, -0.5), 2384 DelayOld(1000), 2385 Move(0, -0.1), 2386 DelayOld(100), 2387 Move(0, 0), 2388 DelayOld(1000), 2389 AnalyticsScreen('Tutorial Section 8'), 2390 Text( 2391 ba.Lstr(resource=self._r + '.phrase25Text') 2392 ), # well that's just about it 2393 DelayOld(2000), 2394 Text( 2395 ba.Lstr(resource=self._r + '.phrase26Text') 2396 ), # go get em tiger 2397 DelayOld(2000), 2398 Text( 2399 ba.Lstr(resource=self._r + '.phrase27Text') 2400 ), # remember you training 2401 DelayOld(3000), 2402 Text( 2403 ba.Lstr(resource=self._r + '.phrase28Text') 2404 ), # well maybe 2405 DelayOld(1600), 2406 Text( 2407 ba.Lstr(resource=self._r + '.phrase29Text') 2408 ), # good luck 2409 Celebrate('right', duration=10000), 2410 DelayOld(1000), 2411 AnalyticsScreen('Tutorial Complete'), 2412 End(), 2413 ] 2414 ) 2415 2416 except Exception: 2417 ba.print_exception() 2418 2419 # If we read some, exec them. 2420 if self._entries: 2421 self._run_next_entry() 2422 # Otherwise try again in a few seconds. 2423 else: 2424 self._read_entries_timer = ba.Timer( 2425 3.0, ba.WeakCall(self._read_entries) 2426 ) 2427 2428 def _run_next_entry(self) -> None: 2429 2430 while self._entries: 2431 entry = self._entries.popleft() 2432 try: 2433 result = entry.run(self) 2434 except Exception: 2435 result = None 2436 ba.print_exception() 2437 2438 # If the entry returns an int value, set a timer; 2439 # otherwise just keep going. 2440 if result is not None: 2441 self._entry_timer = ba.Timer( 2442 result, 2443 ba.WeakCall(self._run_next_entry), 2444 timeformat=ba.TimeFormat.MILLISECONDS, 2445 ) 2446 return 2447 2448 # Done with these entries.. start over soon. 2449 self._read_entries_timer = ba.Timer( 2450 1.0, ba.WeakCall(self._read_entries) 2451 ) 2452 2453 def _update_skip_votes(self) -> None: 2454 count = sum(1 for player in self.players if player.pressed) 2455 assert self._skip_count_text 2456 self._skip_count_text.text = ( 2457 ba.Lstr( 2458 resource=self._r + '.skipVoteCountText', 2459 subs=[ 2460 ('${COUNT}', str(count)), 2461 ('${TOTAL}', str(len(self.players))), 2462 ], 2463 ) 2464 if count > 0 2465 else '' 2466 ) 2467 if ( 2468 count >= len(self.players) 2469 and self.players 2470 and not self._have_skipped 2471 ): 2472 ba.internal.increment_analytics_count('Tutorial skip') 2473 ba.set_analytics_screen('Tutorial Skip') 2474 self._have_skipped = True 2475 ba.playsound(ba.getsound('swish')) 2476 # self._skip_count_text.text = self._r.skippingText 2477 self._skip_count_text.text = ba.Lstr( 2478 resource=self._r + '.skippingText' 2479 ) 2480 assert self._skip_text 2481 self._skip_text.text = '' 2482 self.end() 2483 2484 def _player_pressed_button(self, player: Player) -> None: 2485 2486 # Special case: if there's only one player, we give them a 2487 # warning on their first press (some players were thinking the 2488 # on-screen guide meant they were supposed to press something). 2489 if len(self.players) == 1 and not self._issued_warning: 2490 self._issued_warning = True 2491 assert self._skip_text 2492 self._skip_text.text = ba.Lstr( 2493 resource=self._r + '.skipConfirmText' 2494 ) 2495 self._skip_text.color = (1, 1, 1) 2496 self._skip_text.scale = 1.3 2497 incr = 50 2498 t = incr 2499 for _i in range(6): 2500 ba.timer( 2501 t, 2502 ba.Call(setattr, self._skip_text, 'color', (1, 0.5, 0.1)), 2503 timeformat=ba.TimeFormat.MILLISECONDS, 2504 ) 2505 t += incr 2506 ba.timer( 2507 t, 2508 ba.Call(setattr, self._skip_text, 'color', (1, 1, 0)), 2509 timeformat=ba.TimeFormat.MILLISECONDS, 2510 ) 2511 t += incr 2512 ba.timer(6.0, ba.WeakCall(self._revert_confirm)) 2513 return 2514 2515 player.pressed = True 2516 2517 # test... 2518 if not all(self.players): 2519 ba.print_error( 2520 'Nonexistent player in _player_pressed_button: ' 2521 + str([str(p) for p in self.players]) 2522 + ': we are ' 2523 + str(player) 2524 ) 2525 2526 self._update_skip_votes() 2527 2528 def _revert_confirm(self) -> None: 2529 assert self._skip_text 2530 self._skip_text.text = ba.Lstr( 2531 resource=self._r + '.toSkipPressAnythingText' 2532 ) 2533 self._skip_text.color = (1, 1, 1) 2534 self._issued_warning = False 2535 2536 def on_player_join(self, player: Player) -> None: 2537 super().on_player_join(player) 2538 2539 # We just wanna know if this player presses anything. 2540 player.assigninput( 2541 ( 2542 ba.InputType.JUMP_PRESS, 2543 ba.InputType.PUNCH_PRESS, 2544 ba.InputType.BOMB_PRESS, 2545 ba.InputType.PICK_UP_PRESS, 2546 ), 2547 ba.Call(self._player_pressed_button, player), 2548 ) 2549 2550 def on_player_leave(self, player: Player) -> None: 2551 if not all(self.players): 2552 ba.print_error( 2553 'Nonexistent player in on_player_leave: ' 2554 + str([str(p) for p in self.players]) 2555 + ': we are ' 2556 + str(player) 2557 ) 2558 super().on_player_leave(player) 2559 # our leaving may influence the vote total needed/etc 2560 self._update_skip_votes()
36class ButtonPress: 37 def __init__( 38 self, 39 button: str, 40 delay: int = 0, 41 release: bool = True, 42 release_delay: int = 0, 43 ): 44 self._button = button 45 self._delay = delay 46 self._release = release 47 self._release_delay = release_delay 48 49 def run(self, a: TutorialActivity) -> None: 50 s = a.current_spaz 51 assert s is not None 52 img: ba.Node | None 53 release_call: Callable[[], None] | None 54 color: Sequence[float] | None 55 if self._button == 'punch': 56 call = s.on_punch_press 57 release_call = s.on_punch_release 58 img = a.punch_image 59 color = a.punch_image_color 60 elif self._button == 'jump': 61 call = s.on_jump_press 62 release_call = s.on_jump_release 63 img = a.jump_image 64 color = a.jump_image_color 65 elif self._button == 'bomb': 66 call = s.on_bomb_press 67 release_call = s.on_bomb_release 68 img = a.bomb_image 69 color = a.bomb_image_color 70 elif self._button == 'pickUp': 71 call = s.on_pickup_press 72 release_call = s.on_pickup_release 73 img = a.pickup_image 74 color = a.pickup_image_color 75 elif self._button == 'run': 76 call = ba.Call(s.on_run, 1.0) 77 release_call = ba.Call(s.on_run, 0.0) 78 img = None 79 color = None 80 else: 81 raise Exception(f'invalid button: {self._button}') 82 83 brightness = 4.0 84 if color is not None: 85 c_bright = list(color) 86 c_bright[0] *= brightness 87 c_bright[1] *= brightness 88 c_bright[2] *= brightness 89 else: 90 c_bright = [1.0, 1.0, 1.0] 91 92 if self._delay == 0: 93 call() 94 if img is not None: 95 img.color = c_bright 96 img.vr_depth = -40 97 else: 98 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 99 if img is not None: 100 ba.timer( 101 self._delay, 102 ba.Call(_safesetattr, img, 'color', c_bright), 103 timeformat=ba.TimeFormat.MILLISECONDS, 104 ) 105 ba.timer( 106 self._delay, 107 ba.Call(_safesetattr, img, 'vr_depth', -30), 108 timeformat=ba.TimeFormat.MILLISECONDS, 109 ) 110 if self._release: 111 if self._delay == 0 and self._release_delay == 0: 112 release_call() 113 else: 114 ba.timer( 115 0.001 * (self._delay + self._release_delay), release_call 116 ) 117 if img is not None: 118 ba.timer( 119 self._delay + self._release_delay + 100, 120 ba.Call(_safesetattr, img, 'color', color), 121 timeformat=ba.TimeFormat.MILLISECONDS, 122 ) 123 ba.timer( 124 self._delay + self._release_delay + 100, 125 ba.Call(_safesetattr, img, 'vr_depth', -20), 126 timeformat=ba.TimeFormat.MILLISECONDS, 127 )
49 def run(self, a: TutorialActivity) -> None: 50 s = a.current_spaz 51 assert s is not None 52 img: ba.Node | None 53 release_call: Callable[[], None] | None 54 color: Sequence[float] | None 55 if self._button == 'punch': 56 call = s.on_punch_press 57 release_call = s.on_punch_release 58 img = a.punch_image 59 color = a.punch_image_color 60 elif self._button == 'jump': 61 call = s.on_jump_press 62 release_call = s.on_jump_release 63 img = a.jump_image 64 color = a.jump_image_color 65 elif self._button == 'bomb': 66 call = s.on_bomb_press 67 release_call = s.on_bomb_release 68 img = a.bomb_image 69 color = a.bomb_image_color 70 elif self._button == 'pickUp': 71 call = s.on_pickup_press 72 release_call = s.on_pickup_release 73 img = a.pickup_image 74 color = a.pickup_image_color 75 elif self._button == 'run': 76 call = ba.Call(s.on_run, 1.0) 77 release_call = ba.Call(s.on_run, 0.0) 78 img = None 79 color = None 80 else: 81 raise Exception(f'invalid button: {self._button}') 82 83 brightness = 4.0 84 if color is not None: 85 c_bright = list(color) 86 c_bright[0] *= brightness 87 c_bright[1] *= brightness 88 c_bright[2] *= brightness 89 else: 90 c_bright = [1.0, 1.0, 1.0] 91 92 if self._delay == 0: 93 call() 94 if img is not None: 95 img.color = c_bright 96 img.vr_depth = -40 97 else: 98 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 99 if img is not None: 100 ba.timer( 101 self._delay, 102 ba.Call(_safesetattr, img, 'color', c_bright), 103 timeformat=ba.TimeFormat.MILLISECONDS, 104 ) 105 ba.timer( 106 self._delay, 107 ba.Call(_safesetattr, img, 'vr_depth', -30), 108 timeformat=ba.TimeFormat.MILLISECONDS, 109 ) 110 if self._release: 111 if self._delay == 0 and self._release_delay == 0: 112 release_call() 113 else: 114 ba.timer( 115 0.001 * (self._delay + self._release_delay), release_call 116 ) 117 if img is not None: 118 ba.timer( 119 self._delay + self._release_delay + 100, 120 ba.Call(_safesetattr, img, 'color', color), 121 timeformat=ba.TimeFormat.MILLISECONDS, 122 ) 123 ba.timer( 124 self._delay + self._release_delay + 100, 125 ba.Call(_safesetattr, img, 'vr_depth', -20), 126 timeformat=ba.TimeFormat.MILLISECONDS, 127 )
130class ButtonRelease: 131 def __init__(self, button: str, delay: int = 0): 132 self._button = button 133 self._delay = delay 134 135 def run(self, a: TutorialActivity) -> None: 136 s = a.current_spaz 137 assert s is not None 138 call: Callable[[], None] | None 139 img: ba.Node | None 140 color: Sequence[float] | None 141 if self._button == 'punch': 142 call = s.on_punch_release 143 img = a.punch_image 144 color = a.punch_image_color 145 elif self._button == 'jump': 146 call = s.on_jump_release 147 img = a.jump_image 148 color = a.jump_image_color 149 elif self._button == 'bomb': 150 call = s.on_bomb_release 151 img = a.bomb_image 152 color = a.bomb_image_color 153 elif self._button == 'pickUp': 154 call = s.on_pickup_press 155 img = a.pickup_image 156 color = a.pickup_image_color 157 elif self._button == 'run': 158 call = ba.Call(s.on_run, 0.0) 159 img = None 160 color = None 161 else: 162 raise Exception('invalid button: ' + self._button) 163 if self._delay == 0: 164 call() 165 else: 166 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 167 if img is not None: 168 ba.timer( 169 self._delay + 100, 170 ba.Call(_safesetattr, img, 'color', color), 171 timeformat=ba.TimeFormat.MILLISECONDS, 172 ) 173 ba.timer( 174 self._delay + 100, 175 ba.Call(_safesetattr, img, 'vr_depth', -20), 176 timeformat=ba.TimeFormat.MILLISECONDS, 177 )
135 def run(self, a: TutorialActivity) -> None: 136 s = a.current_spaz 137 assert s is not None 138 call: Callable[[], None] | None 139 img: ba.Node | None 140 color: Sequence[float] | None 141 if self._button == 'punch': 142 call = s.on_punch_release 143 img = a.punch_image 144 color = a.punch_image_color 145 elif self._button == 'jump': 146 call = s.on_jump_release 147 img = a.jump_image 148 color = a.jump_image_color 149 elif self._button == 'bomb': 150 call = s.on_bomb_release 151 img = a.bomb_image 152 color = a.bomb_image_color 153 elif self._button == 'pickUp': 154 call = s.on_pickup_press 155 img = a.pickup_image 156 color = a.pickup_image_color 157 elif self._button == 'run': 158 call = ba.Call(s.on_run, 0.0) 159 img = None 160 color = None 161 else: 162 raise Exception('invalid button: ' + self._button) 163 if self._delay == 0: 164 call() 165 else: 166 ba.timer(self._delay, call, timeformat=ba.TimeFormat.MILLISECONDS) 167 if img is not None: 168 ba.timer( 169 self._delay + 100, 170 ba.Call(_safesetattr, img, 'color', color), 171 timeformat=ba.TimeFormat.MILLISECONDS, 172 ) 173 ba.timer( 174 self._delay + 100, 175 ba.Call(_safesetattr, img, 'vr_depth', -20), 176 timeformat=ba.TimeFormat.MILLISECONDS, 177 )
180class Player(ba.Player['Team']): 181 """Our player type for this game.""" 182 183 def __init__(self) -> None: 184 self.pressed = False
Our player type for this game.
Inherited Members
- ba._player.Player
- actor
- on_expire
- team
- customdata
- sessionplayer
- node
- position
- exists
- getname
- is_alive
- get_icon
- assigninput
- resetinput
187class Team(ba.Team[Player]): 188 """Our team type for this game.""" 189 190 def __init__(self) -> None: 191 pass
Our team type for this game.
Inherited Members
- ba._team.Team
- manual_init
- customdata
- on_expire
- sessionteam
194class TutorialActivity(ba.Activity[Player, Team]): 195 def __init__(self, settings: dict | None = None): 196 from bastd.maps import Rampage 197 198 if settings is None: 199 settings = {} 200 super().__init__(settings) 201 self.current_spaz: basespaz.Spaz | None = None 202 self._benchmark_type = getattr(ba.getsession(), 'benchmark_type', None) 203 self.last_start_time: int | None = None 204 self.cycle_times: list[int] = [] 205 self.allow_pausing = True 206 self.allow_kick_idle_players = False 207 self._issued_warning = False 208 self._map_type = Rampage 209 self._map_type.preload() 210 self._jump_button_tex = ba.gettexture('buttonJump') 211 self._pick_up_button_tex = ba.gettexture('buttonPickUp') 212 self._bomb_button_tex = ba.gettexture('buttonBomb') 213 self._punch_button_tex = ba.gettexture('buttonPunch') 214 self._r = 'tutorial' 215 self._have_skipped = False 216 self.stick_image_position_x = self.stick_image_position_y = 0.0 217 self.spawn_sound = ba.getsound('spawn') 218 self.map: ba.Map | None = None 219 self.text: ba.Node | None = None 220 self._skip_text: ba.Node | None = None 221 self._skip_count_text: ba.Node | None = None 222 self._scale: float | None = None 223 self._stick_base_position: tuple[float, float] = (0.0, 0.0) 224 self._stick_nub_position: tuple[float, float] = (0.0, 0.0) 225 self._stick_base_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 226 self._stick_nub_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 227 self._time: int = -1 228 self.punch_image_color = (1.0, 1.0, 1.0) 229 self.punch_image: ba.Node | None = None 230 self.bomb_image: ba.Node | None = None 231 self.jump_image: ba.Node | None = None 232 self.pickup_image: ba.Node | None = None 233 self._stick_base_image: ba.Node | None = None 234 self._stick_nub_image: ba.Node | None = None 235 self.bomb_image_color = (1.0, 1.0, 1.0) 236 self.pickup_image_color = (1.0, 1.0, 1.0) 237 self.control_ui_nodes: list[ba.Node] = [] 238 self.spazzes: dict[int, basespaz.Spaz] = {} 239 self.jump_image_color = (1.0, 1.0, 1.0) 240 self._entries: deque[Any] = deque() 241 self._read_entries_timer: ba.Timer | None = None 242 self._entry_timer: ba.Timer | None = None 243 244 def on_transition_in(self) -> None: 245 super().on_transition_in() 246 ba.setmusic(ba.MusicType.CHAR_SELECT, continuous=True) 247 self.map = self._map_type() 248 249 def on_begin(self) -> None: 250 super().on_begin() 251 252 ba.set_analytics_screen('Tutorial Start') 253 ba.internal.increment_analytics_count('Tutorial start') 254 255 if bool(False): 256 # Buttons on top. 257 text_y = 140 258 buttons_y = 250 259 else: 260 # Buttons on bottom. 261 text_y = 260 262 buttons_y = 160 263 264 # Need different versions of this: taps/buttons/keys. 265 self.text = ba.newnode( 266 'text', 267 attrs={ 268 'text': '', 269 'scale': 1.9, 270 'position': (0, text_y), 271 'maxwidth': 500, 272 'flatness': 0.0, 273 'shadow': 0.5, 274 'h_align': 'center', 275 'v_align': 'center', 276 'v_attach': 'center', 277 }, 278 ) 279 280 # Need different versions of this: taps/buttons/keys. 281 txt = ( 282 ba.Lstr(resource=self._r + '.cpuBenchmarkText') 283 if self._benchmark_type == 'cpu' 284 else ba.Lstr(resource=self._r + '.toSkipPressAnythingText') 285 ) 286 t = self._skip_text = ba.newnode( 287 'text', 288 attrs={ 289 'text': txt, 290 'maxwidth': 900, 291 'scale': 1.1, 292 'vr_depth': 100, 293 'position': (0, 30), 294 'h_align': 'center', 295 'v_align': 'center', 296 'v_attach': 'bottom', 297 }, 298 ) 299 ba.animate(t, 'opacity', {1.0: 0.0, 2.0: 0.7}) 300 self._skip_count_text = ba.newnode( 301 'text', 302 attrs={ 303 'text': '', 304 'scale': 1.4, 305 'vr_depth': 90, 306 'position': (0, 70), 307 'h_align': 'center', 308 'v_align': 'center', 309 'v_attach': 'bottom', 310 }, 311 ) 312 313 ouya = False 314 315 self._scale = scale = 0.6 316 center_offs = 130.0 * scale 317 offs = 65.0 * scale 318 position = (0, buttons_y) 319 image_size = 90.0 * scale 320 image_size_2 = 220.0 * scale 321 nub_size = 110.0 * scale 322 p = (position[0] + center_offs, position[1] - offs) 323 324 def _sc(r: float, g: float, b: float) -> tuple[float, float, float]: 325 return 0.6 * r, 0.6 * g, 0.6 * b 326 327 self.jump_image_color = c = _sc(0.4, 1, 0.4) 328 self.jump_image = ba.newnode( 329 'image', 330 attrs={ 331 'texture': self._jump_button_tex, 332 'absolute_scale': True, 333 'vr_depth': -20, 334 'position': p, 335 'scale': (image_size, image_size), 336 'color': c, 337 }, 338 ) 339 p = (position[0] + center_offs - offs, position[1]) 340 self.punch_image_color = c = ( 341 _sc(0.2, 0.6, 1) if ouya else _sc(1, 0.7, 0.3) 342 ) 343 self.punch_image = ba.newnode( 344 'image', 345 attrs={ 346 'texture': ba.gettexture('buttonPunch'), 347 'absolute_scale': True, 348 'vr_depth': -20, 349 'position': p, 350 'scale': (image_size, image_size), 351 'color': c, 352 }, 353 ) 354 p = (position[0] + center_offs + offs, position[1]) 355 self.bomb_image_color = c = _sc(1, 0.3, 0.3) 356 self.bomb_image = ba.newnode( 357 'image', 358 attrs={ 359 'texture': ba.gettexture('buttonBomb'), 360 'absolute_scale': True, 361 'vr_depth': -20, 362 'position': p, 363 'scale': (image_size, image_size), 364 'color': c, 365 }, 366 ) 367 p = (position[0] + center_offs, position[1] + offs) 368 self.pickup_image_color = c = ( 369 _sc(1, 0.8, 0.3) if ouya else _sc(0.5, 0.5, 1) 370 ) 371 self.pickup_image = ba.newnode( 372 'image', 373 attrs={ 374 'texture': ba.gettexture('buttonPickUp'), 375 'absolute_scale': True, 376 'vr_depth': -20, 377 'position': p, 378 'scale': (image_size, image_size), 379 'color': c, 380 }, 381 ) 382 383 self._stick_base_position = p = (position[0] - center_offs, position[1]) 384 self._stick_base_image_color = c2 = (0.25, 0.25, 0.25, 1.0) 385 self._stick_base_image = ba.newnode( 386 'image', 387 attrs={ 388 'texture': ba.gettexture('nub'), 389 'absolute_scale': True, 390 'vr_depth': -40, 391 'position': p, 392 'scale': (image_size_2, image_size_2), 393 'color': c2, 394 }, 395 ) 396 self._stick_nub_position = p = (position[0] - center_offs, position[1]) 397 self._stick_nub_image_color = c3 = (0.4, 0.4, 0.4, 1.0) 398 self._stick_nub_image = ba.newnode( 399 'image', 400 attrs={ 401 'texture': ba.gettexture('nub'), 402 'absolute_scale': True, 403 'position': p, 404 'scale': (nub_size, nub_size), 405 'color': c3, 406 }, 407 ) 408 self.control_ui_nodes = [ 409 self.jump_image, 410 self.punch_image, 411 self.bomb_image, 412 self.pickup_image, 413 self._stick_base_image, 414 self._stick_nub_image, 415 ] 416 for n in self.control_ui_nodes: 417 n.opacity = 0.0 418 self._read_entries() 419 420 def set_stick_image_position(self, x: float, y: float) -> None: 421 422 # Clamp this to a circle. 423 len_squared = x * x + y * y 424 if len_squared > 1.0: 425 length = math.sqrt(len_squared) 426 mult = 1.0 / length 427 x *= mult 428 y *= mult 429 430 self.stick_image_position_x = x 431 self.stick_image_position_y = y 432 offs = 50.0 433 assert self._scale is not None 434 p = [ 435 self._stick_nub_position[0] + x * offs * self._scale, 436 self._stick_nub_position[1] + y * offs * self._scale, 437 ] 438 c = list(self._stick_nub_image_color) 439 if abs(x) > 0.1 or abs(y) > 0.1: 440 c[0] *= 2.0 441 c[1] *= 4.0 442 c[2] *= 2.0 443 assert self._stick_nub_image is not None 444 self._stick_nub_image.position = p 445 self._stick_nub_image.color = c 446 c = list(self._stick_base_image_color) 447 if abs(x) > 0.1 or abs(y) > 0.1: 448 c[0] *= 1.5 449 c[1] *= 1.5 450 c[2] *= 1.5 451 assert self._stick_base_image is not None 452 self._stick_base_image.color = c 453 454 def _read_entries(self) -> None: 455 try: 456 457 class Reset: 458 def __init__(self) -> None: 459 pass 460 461 def run(self, a: TutorialActivity) -> None: 462 463 # if we're looping, print out how long each cycle took 464 # print out how long each cycle took.. 465 if a.last_start_time is not None: 466 tval = ( 467 ba.time( 468 ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS 469 ) 470 - a.last_start_time 471 ) 472 assert isinstance(tval, int) 473 diff = tval 474 a.cycle_times.append(diff) 475 ba.screenmessage( 476 'cycle time: ' 477 + str(diff) 478 + ' (average: ' 479 + str(sum(a.cycle_times) / len(a.cycle_times)) 480 + ')' 481 ) 482 tval = ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS) 483 assert isinstance(tval, int) 484 a.last_start_time = tval 485 486 assert a.text 487 a.text.text = '' 488 for spaz in list(a.spazzes.values()): 489 spaz.handlemessage(ba.DieMessage(immediate=True)) 490 a.spazzes = {} 491 a.current_spaz = None 492 for n in a.control_ui_nodes: 493 n.opacity = 0.0 494 a.set_stick_image_position(0, 0) 495 496 # Can be used for debugging. 497 class SetSpeed: 498 def __init__(self, speed: int): 499 self._speed = speed 500 501 def run(self, a: TutorialActivity) -> None: 502 print('setting to', self._speed) 503 ba.internal.set_debug_speed_exponent(self._speed) 504 505 class RemoveGloves: 506 def __init__(self) -> None: 507 pass 508 509 def run(self, a: TutorialActivity) -> None: 510 # pylint: disable=protected-access 511 assert a.current_spaz is not None 512 # noinspection PyProtectedMember 513 a.current_spaz._gloves_wear_off() 514 515 class KillSpaz: 516 def __init__(self, num: int, explode: bool = False): 517 self._num = num 518 self._explode = explode 519 520 def run(self, a: TutorialActivity) -> None: 521 if self._explode: 522 a.spazzes[self._num].shatter() 523 del a.spazzes[self._num] 524 525 class SpawnSpaz: 526 def __init__( 527 self, 528 num: int, 529 position: Sequence[float], 530 color: Sequence[float] = (1.0, 1.0, 1.0), 531 make_current: bool = False, 532 relative_to: int | None = None, 533 name: str | ba.Lstr = '', 534 flash: bool = True, 535 angle: float = 0.0, 536 ): 537 self._num = num 538 self._position = position 539 self._make_current = make_current 540 self._color = color 541 self._relative_to = relative_to 542 self._name = name 543 self._flash = flash 544 self._angle = angle 545 546 def run(self, a: TutorialActivity) -> None: 547 548 # if they gave a 'relative to' spaz, position is relative 549 # to them 550 pos: Sequence[float] 551 if self._relative_to is not None: 552 snode = a.spazzes[self._relative_to].node 553 assert snode 554 their_pos = snode.position 555 pos = ( 556 their_pos[0] + self._position[0], 557 their_pos[1] + self._position[1], 558 their_pos[2] + self._position[2], 559 ) 560 else: 561 pos = self._position 562 563 # if there's already a spaz at this spot, insta-kill it 564 if self._num in a.spazzes: 565 a.spazzes[self._num].handlemessage( 566 ba.DieMessage(immediate=True) 567 ) 568 569 s = a.spazzes[self._num] = basespaz.Spaz( 570 color=self._color, 571 start_invincible=self._flash, 572 demo_mode=True, 573 ) 574 575 # FIXME: Should extend spaz to support Lstr names. 576 assert s.node 577 if isinstance(self._name, ba.Lstr): 578 s.node.name = self._name.evaluate() 579 else: 580 s.node.name = self._name 581 s.node.name_color = self._color 582 s.handlemessage(ba.StandMessage(pos, self._angle)) 583 if self._make_current: 584 a.current_spaz = s 585 if self._flash: 586 ba.playsound(a.spawn_sound, position=pos) 587 588 class Powerup: 589 def __init__( 590 self, 591 num: int, 592 position: Sequence[float], 593 color: Sequence[float] = (1.0, 1.0, 1.0), 594 make_current: bool = False, 595 relative_to: int | None = None, 596 ): 597 self._position = position 598 self._relative_to = relative_to 599 600 def run(self, a: TutorialActivity) -> None: 601 # If they gave a 'relative to' spaz, position is relative 602 # to them. 603 pos: Sequence[float] 604 if self._relative_to is not None: 605 snode = a.spazzes[self._relative_to].node 606 assert snode 607 their_pos = snode.position 608 pos = ( 609 their_pos[0] + self._position[0], 610 their_pos[1] + self._position[1], 611 their_pos[2] + self._position[2], 612 ) 613 else: 614 pos = self._position 615 from bastd.actor import powerupbox 616 617 powerupbox.PowerupBox( 618 position=pos, poweruptype='punch' 619 ).autoretain() 620 621 class Delay: 622 def __init__(self, time: int) -> None: 623 self._time = time 624 625 def run(self, a: TutorialActivity) -> int: 626 return self._time 627 628 class AnalyticsScreen: 629 def __init__(self, screen: str) -> None: 630 self._screen = screen 631 632 def run(self, a: TutorialActivity) -> None: 633 ba.set_analytics_screen(self._screen) 634 635 class DelayOld: 636 def __init__(self, time: int) -> None: 637 self._time = time 638 639 def run(self, a: TutorialActivity) -> int: 640 return int(0.9 * self._time) 641 642 class DelayOld2: 643 def __init__(self, time: int) -> None: 644 self._time = time 645 646 def run(self, a: TutorialActivity) -> int: 647 return int(0.8 * self._time) 648 649 class End: 650 def __init__(self) -> None: 651 pass 652 653 def run(self, a: TutorialActivity) -> None: 654 ba.internal.increment_analytics_count('Tutorial finish') 655 a.end() 656 657 class Move: 658 def __init__(self, x: float, y: float): 659 self._x = float(x) 660 self._y = float(y) 661 662 def run(self, a: TutorialActivity) -> None: 663 s = a.current_spaz 664 assert s 665 # FIXME: Game should take floats for this. 666 x_clamped = self._x 667 y_clamped = self._y 668 s.on_move_left_right(x_clamped) 669 s.on_move_up_down(y_clamped) 670 a.set_stick_image_position(self._x, self._y) 671 672 class MoveLR: 673 def __init__(self, x: float): 674 self._x = float(x) 675 676 def run(self, a: TutorialActivity) -> None: 677 s = a.current_spaz 678 assert s 679 # FIXME: Game should take floats for this. 680 x_clamped = self._x 681 s.on_move_left_right(x_clamped) 682 a.set_stick_image_position( 683 self._x, a.stick_image_position_y 684 ) 685 686 class MoveUD: 687 def __init__(self, y: float): 688 self._y = float(y) 689 690 def run(self, a: TutorialActivity) -> None: 691 s = a.current_spaz 692 assert s 693 # FIXME: Game should take floats for this. 694 y_clamped = self._y 695 s.on_move_up_down(y_clamped) 696 a.set_stick_image_position( 697 a.stick_image_position_x, self._y 698 ) 699 700 class Bomb(ButtonPress): 701 def __init__( 702 self, 703 delay: int = 0, 704 release: bool = True, 705 release_delay: int = 500, 706 ): 707 ButtonPress.__init__( 708 self, 709 'bomb', 710 delay=delay, 711 release=release, 712 release_delay=release_delay, 713 ) 714 715 class Jump(ButtonPress): 716 def __init__( 717 self, 718 delay: int = 0, 719 release: bool = True, 720 release_delay: int = 500, 721 ): 722 ButtonPress.__init__( 723 self, 724 'jump', 725 delay=delay, 726 release=release, 727 release_delay=release_delay, 728 ) 729 730 class Punch(ButtonPress): 731 def __init__( 732 self, 733 delay: int = 0, 734 release: bool = True, 735 release_delay: int = 500, 736 ): 737 ButtonPress.__init__( 738 self, 739 'punch', 740 delay=delay, 741 release=release, 742 release_delay=release_delay, 743 ) 744 745 class PickUp(ButtonPress): 746 def __init__( 747 self, 748 delay: int = 0, 749 release: bool = True, 750 release_delay: int = 500, 751 ): 752 ButtonPress.__init__( 753 self, 754 'pickUp', 755 delay=delay, 756 release=release, 757 release_delay=release_delay, 758 ) 759 760 class Run(ButtonPress): 761 def __init__( 762 self, 763 delay: int = 0, 764 release: bool = True, 765 release_delay: int = 500, 766 ): 767 ButtonPress.__init__( 768 self, 769 'run', 770 delay=delay, 771 release=release, 772 release_delay=release_delay, 773 ) 774 775 class BombRelease(ButtonRelease): 776 def __init__(self, delay: int = 0): 777 super().__init__('bomb', delay=delay) 778 779 class JumpRelease(ButtonRelease): 780 def __init__(self, delay: int = 0): 781 super().__init__('jump', delay=delay) 782 783 class PunchRelease(ButtonRelease): 784 def __init__(self, delay: int = 0): 785 super().__init__('punch', delay=delay) 786 787 class PickUpRelease(ButtonRelease): 788 def __init__(self, delay: int = 0): 789 super().__init__('pickUp', delay=delay) 790 791 class RunRelease(ButtonRelease): 792 def __init__(self, delay: int = 0): 793 super().__init__('run', delay=delay) 794 795 class ShowControls: 796 def __init__(self) -> None: 797 pass 798 799 def run(self, a: TutorialActivity) -> None: 800 for n in a.control_ui_nodes: 801 ba.animate(n, 'opacity', {0.0: 0.0, 1.0: 1.0}) 802 803 class Text: 804 def __init__(self, text: str | ba.Lstr): 805 self.text = text 806 807 def run(self, a: TutorialActivity) -> None: 808 assert a.text 809 a.text.text = self.text 810 811 class PrintPos: 812 def __init__(self, spaz_num: int | None = None): 813 self._spaz_num = spaz_num 814 815 def run(self, a: TutorialActivity) -> None: 816 if self._spaz_num is None: 817 s = a.current_spaz 818 else: 819 s = a.spazzes[self._spaz_num] 820 assert s and s.node 821 t = list(s.node.position) 822 print('RestorePos(' + str((t[0], t[1] - 1.0, t[2])) + '),') 823 824 class RestorePos: 825 def __init__(self, pos: Sequence[float]) -> None: 826 self._pos = pos 827 828 def run(self, a: TutorialActivity) -> None: 829 s = a.current_spaz 830 assert s 831 s.handlemessage(ba.StandMessage(self._pos, 0)) 832 833 class Celebrate: 834 def __init__( 835 self, 836 celebrate_type: str = 'both', 837 spaz_num: int | None = None, 838 duration: int = 1000, 839 ): 840 self._spaz_num = spaz_num 841 self._celebrate_type = celebrate_type 842 self._duration = duration 843 844 def run(self, a: TutorialActivity) -> None: 845 if self._spaz_num is None: 846 s = a.current_spaz 847 else: 848 s = a.spazzes[self._spaz_num] 849 assert s and s.node 850 if self._celebrate_type == 'right': 851 s.node.handlemessage('celebrate_r', self._duration) 852 elif self._celebrate_type == 'left': 853 s.node.handlemessage('celebrate_l', self._duration) 854 elif self._celebrate_type == 'both': 855 s.node.handlemessage('celebrate', self._duration) 856 else: 857 raise Exception( 858 'invalid celebrate type ' + self._celebrate_type 859 ) 860 861 self._entries = deque( 862 [ 863 Reset(), 864 SpawnSpaz(0, (0, 5.5, -3.0), make_current=True), 865 DelayOld(1000), 866 AnalyticsScreen('Tutorial Section 1'), 867 Text( 868 ba.Lstr(resource=self._r + '.phrase01Text') 869 ), # hi there 870 Celebrate('left'), 871 DelayOld(2000), 872 Text( 873 ba.Lstr( 874 resource=self._r + '.phrase02Text', 875 subs=[ 876 ('${APP_NAME}', ba.Lstr(resource='titleText')) 877 ], 878 ) 879 ), # welcome to <appname> 880 DelayOld(80), 881 Run(release=False), 882 Jump(release=False), 883 MoveLR(1), 884 MoveUD(0), 885 DelayOld(70), 886 RunRelease(), 887 JumpRelease(), 888 DelayOld(60), 889 MoveUD(1), 890 DelayOld(30), 891 MoveLR(0), 892 DelayOld(90), 893 MoveLR(-1), 894 DelayOld(20), 895 MoveUD(0), 896 DelayOld(70), 897 MoveUD(-1), 898 DelayOld(20), 899 MoveLR(0), 900 DelayOld(80), 901 MoveUD(0), 902 DelayOld(1500), 903 Text( 904 ba.Lstr(resource=self._r + '.phrase03Text') 905 ), # here's a few tips 906 DelayOld(1000), 907 ShowControls(), 908 DelayOld(1000), 909 Jump(), 910 DelayOld(1000), 911 Jump(), 912 DelayOld(1000), 913 AnalyticsScreen('Tutorial Section 2'), 914 Text( 915 ba.Lstr( 916 resource=self._r + '.phrase04Text', 917 subs=[ 918 ('${APP_NAME}', ba.Lstr(resource='titleText')) 919 ], 920 ) 921 ), # many things are based on physics 922 DelayOld(20), 923 MoveUD(0), 924 DelayOld(60), 925 MoveLR(0), 926 DelayOld(10), 927 MoveLR(0), 928 MoveUD(0), 929 DelayOld(10), 930 MoveLR(0), 931 MoveUD(0), 932 DelayOld(20), 933 MoveUD(-0.0575579), 934 DelayOld(10), 935 MoveUD(-0.207831), 936 DelayOld(30), 937 MoveUD(-0.309793), 938 DelayOld(10), 939 MoveUD(-0.474502), 940 DelayOld(10), 941 MoveLR(0.00390637), 942 MoveUD(-0.647053), 943 DelayOld(20), 944 MoveLR(-0.0745262), 945 MoveUD(-0.819605), 946 DelayOld(10), 947 MoveLR(-0.168645), 948 MoveUD(-0.937254), 949 DelayOld(30), 950 MoveLR(-0.294137), 951 MoveUD(-1), 952 DelayOld(10), 953 MoveLR(-0.411786), 954 DelayOld(10), 955 MoveLR(-0.639241), 956 DelayOld(30), 957 MoveLR(-0.75689), 958 DelayOld(10), 959 MoveLR(-0.905911), 960 DelayOld(20), 961 MoveLR(-1), 962 DelayOld(50), 963 MoveUD(-0.960784), 964 DelayOld(20), 965 MoveUD(-0.819605), 966 MoveUD(-0.61568), 967 DelayOld(20), 968 MoveUD(-0.427442), 969 DelayOld(20), 970 MoveUD(-0.231361), 971 DelayOld(10), 972 MoveUD(-0.00390637), 973 DelayOld(30), 974 MoveUD(0.333354), 975 MoveUD(0.584338), 976 DelayOld(20), 977 MoveUD(0.764733), 978 DelayOld(30), 979 MoveLR(-0.803949), 980 MoveUD(0.913755), 981 DelayOld(10), 982 MoveLR(-0.647084), 983 MoveUD(0.992187), 984 DelayOld(20), 985 MoveLR(-0.435316), 986 MoveUD(1), 987 DelayOld(20), 988 MoveLR(-0.168645), 989 MoveUD(0.976501), 990 MoveLR(0.0744957), 991 MoveUD(0.905911), 992 DelayOld(20), 993 MoveLR(0.270577), 994 MoveUD(0.843165), 995 DelayOld(20), 996 MoveLR(0.435286), 997 MoveUD(0.780419), 998 DelayOld(10), 999 MoveLR(0.66274), 1000 MoveUD(0.647084), 1001 DelayOld(30), 1002 MoveLR(0.803919), 1003 MoveUD(0.458846), 1004 MoveLR(0.929411), 1005 MoveUD(0.223548), 1006 DelayOld(20), 1007 MoveLR(0.95294), 1008 MoveUD(0.137272), 1009 DelayOld(20), 1010 MoveLR(1), 1011 MoveUD(-0.0509659), 1012 DelayOld(20), 1013 MoveUD(-0.247047), 1014 DelayOld(20), 1015 MoveUD(-0.443129), 1016 DelayOld(20), 1017 MoveUD(-0.694113), 1018 MoveUD(-0.921567), 1019 DelayOld(30), 1020 MoveLR(0.858821), 1021 MoveUD(-1), 1022 DelayOld(10), 1023 MoveLR(0.68627), 1024 DelayOld(10), 1025 MoveLR(0.364696), 1026 DelayOld(20), 1027 MoveLR(0.0509659), 1028 DelayOld(20), 1029 MoveLR(-0.223548), 1030 DelayOld(10), 1031 MoveLR(-0.600024), 1032 MoveUD(-0.913724), 1033 DelayOld(30), 1034 MoveLR(-0.858852), 1035 MoveUD(-0.717643), 1036 MoveLR(-1), 1037 MoveUD(-0.474502), 1038 DelayOld(20), 1039 MoveUD(-0.396069), 1040 DelayOld(20), 1041 MoveUD(-0.286264), 1042 DelayOld(20), 1043 MoveUD(-0.137242), 1044 DelayOld(20), 1045 MoveUD(0.0353099), 1046 DelayOld(10), 1047 MoveUD(0.32551), 1048 DelayOld(20), 1049 MoveUD(0.592181), 1050 DelayOld(10), 1051 MoveUD(0.851009), 1052 DelayOld(10), 1053 MoveUD(1), 1054 DelayOld(30), 1055 MoveLR(-0.764733), 1056 DelayOld(20), 1057 MoveLR(-0.403943), 1058 MoveLR(-0.145116), 1059 DelayOld(30), 1060 MoveLR(0.0901822), 1061 MoveLR(0.32548), 1062 DelayOld(30), 1063 MoveLR(0.560778), 1064 MoveUD(0.929441), 1065 DelayOld(20), 1066 MoveLR(0.709799), 1067 MoveUD(0.73336), 1068 MoveLR(0.803919), 1069 MoveUD(0.545122), 1070 DelayOld(20), 1071 MoveLR(0.882351), 1072 MoveUD(0.356883), 1073 DelayOld(10), 1074 MoveLR(0.968627), 1075 MoveUD(0.113742), 1076 DelayOld(20), 1077 MoveLR(0.992157), 1078 MoveUD(-0.0823389), 1079 DelayOld(30), 1080 MoveUD(-0.309793), 1081 DelayOld(10), 1082 MoveUD(-0.545091), 1083 DelayOld(20), 1084 MoveLR(0.882351), 1085 MoveUD(-0.874508), 1086 DelayOld(20), 1087 MoveLR(0.756859), 1088 MoveUD(-1), 1089 DelayOld(10), 1090 MoveLR(0.576464), 1091 DelayOld(20), 1092 MoveLR(0.254891), 1093 DelayOld(10), 1094 MoveLR(-0.0274667), 1095 DelayOld(10), 1096 MoveLR(-0.356883), 1097 DelayOld(30), 1098 MoveLR(-0.592181), 1099 MoveLR(-0.827479), 1100 MoveUD(-0.921567), 1101 DelayOld(20), 1102 MoveLR(-1), 1103 MoveUD(-0.749016), 1104 DelayOld(20), 1105 MoveUD(-0.61568), 1106 DelayOld(10), 1107 MoveUD(-0.403912), 1108 DelayOld(20), 1109 MoveUD(-0.207831), 1110 DelayOld(10), 1111 MoveUD(0.121586), 1112 DelayOld(30), 1113 MoveUD(0.34904), 1114 DelayOld(10), 1115 MoveUD(0.560808), 1116 DelayOld(10), 1117 MoveUD(0.827479), 1118 DelayOld(30), 1119 MoveUD(1), 1120 DelayOld(20), 1121 MoveLR(-0.976501), 1122 MoveLR(-0.670614), 1123 DelayOld(20), 1124 MoveLR(-0.239235), 1125 DelayOld(20), 1126 MoveLR(0.160772), 1127 DelayOld(20), 1128 MoveLR(0.443129), 1129 DelayOld(10), 1130 MoveLR(0.68627), 1131 MoveUD(0.976501), 1132 DelayOld(30), 1133 MoveLR(0.929411), 1134 MoveUD(0.73336), 1135 MoveLR(1), 1136 MoveUD(0.482376), 1137 DelayOld(20), 1138 MoveUD(0.34904), 1139 DelayOld(10), 1140 MoveUD(0.160802), 1141 DelayOld(30), 1142 MoveUD(-0.0744957), 1143 DelayOld(10), 1144 MoveUD(-0.333323), 1145 DelayOld(20), 1146 MoveUD(-0.647053), 1147 DelayOld(20), 1148 MoveUD(-0.937254), 1149 DelayOld(10), 1150 MoveLR(0.858821), 1151 MoveUD(-1), 1152 DelayOld(10), 1153 MoveLR(0.576464), 1154 DelayOld(30), 1155 MoveLR(0.184301), 1156 DelayOld(10), 1157 MoveLR(-0.121586), 1158 DelayOld(10), 1159 MoveLR(-0.474532), 1160 DelayOld(30), 1161 MoveLR(-0.670614), 1162 MoveLR(-0.851009), 1163 DelayOld(30), 1164 MoveLR(-1), 1165 MoveUD(-0.968627), 1166 DelayOld(20), 1167 MoveUD(-0.843135), 1168 DelayOld(10), 1169 MoveUD(-0.631367), 1170 DelayOld(20), 1171 MoveUD(-0.403912), 1172 MoveUD(-0.176458), 1173 DelayOld(20), 1174 MoveUD(0.0902127), 1175 DelayOld(20), 1176 MoveUD(0.380413), 1177 DelayOld(10), 1178 MoveUD(0.717673), 1179 DelayOld(30), 1180 MoveUD(1), 1181 DelayOld(10), 1182 MoveLR(-0.741203), 1183 DelayOld(20), 1184 MoveLR(-0.458846), 1185 DelayOld(10), 1186 MoveLR(-0.145116), 1187 DelayOld(10), 1188 MoveLR(0.0980255), 1189 DelayOld(20), 1190 MoveLR(0.294107), 1191 DelayOld(30), 1192 MoveLR(0.466659), 1193 MoveLR(0.717643), 1194 MoveUD(0.796106), 1195 DelayOld(20), 1196 MoveLR(0.921567), 1197 MoveUD(0.443159), 1198 DelayOld(20), 1199 MoveLR(1), 1200 MoveUD(0.145116), 1201 DelayOld(10), 1202 MoveUD(-0.0274361), 1203 DelayOld(30), 1204 MoveUD(-0.223518), 1205 MoveUD(-0.427442), 1206 DelayOld(20), 1207 MoveUD(-0.874508), 1208 DelayOld(20), 1209 MoveUD(-1), 1210 DelayOld(10), 1211 MoveLR(0.929411), 1212 DelayOld(20), 1213 MoveLR(0.68627), 1214 DelayOld(20), 1215 MoveLR(0.364696), 1216 DelayOld(20), 1217 MoveLR(0.0431227), 1218 DelayOld(10), 1219 MoveLR(-0.333354), 1220 DelayOld(20), 1221 MoveLR(-0.639241), 1222 DelayOld(20), 1223 MoveLR(-0.968657), 1224 MoveUD(-0.968627), 1225 DelayOld(20), 1226 MoveLR(-1), 1227 MoveUD(-0.890194), 1228 MoveUD(-0.866665), 1229 DelayOld(20), 1230 MoveUD(-0.749016), 1231 DelayOld(20), 1232 MoveUD(-0.529405), 1233 DelayOld(20), 1234 MoveUD(-0.30195), 1235 DelayOld(10), 1236 MoveUD(-0.00390637), 1237 DelayOld(10), 1238 MoveUD(0.262764), 1239 DelayOld(30), 1240 MoveLR(-0.600024), 1241 MoveUD(0.458846), 1242 DelayOld(10), 1243 MoveLR(-0.294137), 1244 MoveUD(0.482376), 1245 DelayOld(20), 1246 MoveLR(-0.200018), 1247 MoveUD(0.505905), 1248 DelayOld(10), 1249 MoveLR(-0.145116), 1250 MoveUD(0.545122), 1251 DelayOld(20), 1252 MoveLR(-0.0353099), 1253 MoveUD(0.584338), 1254 DelayOld(20), 1255 MoveLR(0.137242), 1256 MoveUD(0.592181), 1257 DelayOld(20), 1258 MoveLR(0.30195), 1259 DelayOld(10), 1260 MoveLR(0.490188), 1261 DelayOld(10), 1262 MoveLR(0.599994), 1263 MoveUD(0.529435), 1264 DelayOld(30), 1265 MoveLR(0.66274), 1266 MoveUD(0.3961), 1267 DelayOld(20), 1268 MoveLR(0.670583), 1269 MoveUD(0.231391), 1270 MoveLR(0.68627), 1271 MoveUD(0.0745262), 1272 Move(0, -0.01), 1273 DelayOld(100), 1274 Move(0, 0), 1275 DelayOld(1000), 1276 Text( 1277 ba.Lstr(resource=self._r + '.phrase05Text') 1278 ), # for example when you punch.. 1279 DelayOld(510), 1280 Move(0, -0.01), 1281 DelayOld(100), 1282 Move(0, 0), 1283 DelayOld(500), 1284 SpawnSpaz( 1285 0, 1286 (-0.09249162673950195, 4.337906360626221, -2.3), 1287 make_current=True, 1288 flash=False, 1289 ), 1290 SpawnSpaz( 1291 1, 1292 (-3.1, 4.3, -2.0), 1293 make_current=False, 1294 color=(1, 1, 0.4), 1295 name=ba.Lstr(resource=self._r + '.randomName1Text'), 1296 ), 1297 Move(-1.0, 0), 1298 DelayOld(1050), 1299 Move(0, -0.01), 1300 DelayOld(100), 1301 Move(0, 0), 1302 DelayOld(1000), 1303 Text( 1304 ba.Lstr(resource=self._r + '.phrase06Text') 1305 ), # your damage is based 1306 DelayOld(1200), 1307 Move(-0.05, 0), 1308 DelayOld(200), 1309 Punch(), 1310 DelayOld(800), 1311 Punch(), 1312 DelayOld(800), 1313 Punch(), 1314 DelayOld(800), 1315 Move(0, -0.01), 1316 DelayOld(100), 1317 Move(0, 0), 1318 Text( 1319 ba.Lstr( 1320 resource=self._r + '.phrase07Text', 1321 subs=[ 1322 ( 1323 '${NAME}', 1324 ba.Lstr( 1325 resource=self._r + '.randomName1Text' 1326 ), 1327 ) 1328 ], 1329 ) 1330 ), # see that didn't hurt fred 1331 DelayOld(2000), 1332 Celebrate('right', spaz_num=1), 1333 DelayOld(1400), 1334 Text( 1335 ba.Lstr(resource=self._r + '.phrase08Text') 1336 ), # lets jump and spin to get more speed 1337 DelayOld(30), 1338 MoveLR(0), 1339 DelayOld(40), 1340 MoveLR(0), 1341 DelayOld(40), 1342 MoveLR(0), 1343 DelayOld(130), 1344 MoveLR(0), 1345 DelayOld(100), 1346 MoveLR(0), 1347 DelayOld(10), 1348 MoveLR(0.0480667), 1349 DelayOld(40), 1350 MoveLR(0.056093), 1351 MoveLR(0.0681173), 1352 DelayOld(30), 1353 MoveLR(0.0801416), 1354 DelayOld(10), 1355 MoveLR(0.184301), 1356 DelayOld(10), 1357 MoveLR(0.207831), 1358 DelayOld(20), 1359 MoveLR(0.231361), 1360 DelayOld(30), 1361 MoveLR(0.239204), 1362 DelayOld(30), 1363 MoveLR(0.254891), 1364 DelayOld(40), 1365 MoveLR(0.270577), 1366 DelayOld(10), 1367 MoveLR(0.30195), 1368 DelayOld(20), 1369 MoveLR(0.341166), 1370 DelayOld(30), 1371 MoveLR(0.388226), 1372 MoveLR(0.435286), 1373 DelayOld(30), 1374 MoveLR(0.490188), 1375 DelayOld(10), 1376 MoveLR(0.560778), 1377 DelayOld(20), 1378 MoveLR(0.599994), 1379 DelayOld(10), 1380 MoveLR(0.647053), 1381 DelayOld(10), 1382 MoveLR(0.68627), 1383 DelayOld(30), 1384 MoveLR(0.733329), 1385 DelayOld(20), 1386 MoveLR(0.764702), 1387 DelayOld(10), 1388 MoveLR(0.827448), 1389 DelayOld(20), 1390 MoveLR(0.874508), 1391 DelayOld(20), 1392 MoveLR(0.929411), 1393 DelayOld(10), 1394 MoveLR(1), 1395 DelayOld(830), 1396 MoveUD(0.0274667), 1397 DelayOld(10), 1398 MoveLR(0.95294), 1399 MoveUD(0.113742), 1400 DelayOld(30), 1401 MoveLR(0.780389), 1402 MoveUD(0.184332), 1403 DelayOld(10), 1404 MoveLR(0.27842), 1405 MoveUD(0.0745262), 1406 DelayOld(20), 1407 MoveLR(0), 1408 MoveUD(0), 1409 DelayOld(390), 1410 MoveLR(0), 1411 MoveLR(0), 1412 DelayOld(20), 1413 MoveLR(0), 1414 DelayOld(20), 1415 MoveLR(0), 1416 DelayOld(10), 1417 MoveLR(-0.0537431), 1418 DelayOld(20), 1419 MoveLR(-0.215705), 1420 DelayOld(30), 1421 MoveLR(-0.388256), 1422 MoveLR(-0.529435), 1423 DelayOld(30), 1424 MoveLR(-0.694143), 1425 DelayOld(20), 1426 MoveLR(-0.851009), 1427 MoveUD(0.0588397), 1428 DelayOld(10), 1429 MoveLR(-1), 1430 MoveUD(0.0745262), 1431 Run(release=False), 1432 DelayOld(200), 1433 MoveUD(0.0509964), 1434 DelayOld(30), 1435 MoveUD(0.0117801), 1436 DelayOld(20), 1437 MoveUD(-0.0901822), 1438 MoveUD(-0.372539), 1439 DelayOld(30), 1440 MoveLR(-0.898068), 1441 MoveUD(-0.890194), 1442 Jump(release=False), 1443 DelayOld(20), 1444 MoveLR(-0.647084), 1445 MoveUD(-1), 1446 MoveLR(-0.427473), 1447 DelayOld(20), 1448 MoveLR(-0.00393689), 1449 DelayOld(10), 1450 MoveLR(0.537248), 1451 DelayOld(30), 1452 MoveLR(1), 1453 DelayOld(50), 1454 RunRelease(), 1455 JumpRelease(), 1456 DelayOld(50), 1457 MoveUD(-0.921567), 1458 MoveUD(-0.749016), 1459 DelayOld(30), 1460 MoveUD(-0.552934), 1461 DelayOld(10), 1462 MoveUD(-0.247047), 1463 DelayOld(20), 1464 MoveUD(0.200018), 1465 DelayOld(20), 1466 MoveUD(0.670614), 1467 MoveUD(1), 1468 DelayOld(70), 1469 MoveLR(0.97647), 1470 DelayOld(20), 1471 MoveLR(0.764702), 1472 DelayOld(20), 1473 MoveLR(0.364696), 1474 DelayOld(20), 1475 MoveLR(0.00390637), 1476 MoveLR(-0.309824), 1477 DelayOld(20), 1478 MoveLR(-0.576495), 1479 DelayOld(30), 1480 MoveLR(-0.898068), 1481 DelayOld(10), 1482 MoveLR(-1), 1483 MoveUD(0.905911), 1484 DelayOld(20), 1485 MoveUD(0.498062), 1486 DelayOld(20), 1487 MoveUD(0.0274667), 1488 MoveUD(-0.403912), 1489 DelayOld(20), 1490 MoveUD(-1), 1491 Run(release=False), 1492 Jump(release=False), 1493 DelayOld(10), 1494 Punch(release=False), 1495 DelayOld(70), 1496 JumpRelease(), 1497 DelayOld(110), 1498 MoveLR(-0.976501), 1499 RunRelease(), 1500 PunchRelease(), 1501 DelayOld(10), 1502 MoveLR(-0.952971), 1503 DelayOld(20), 1504 MoveLR(-0.905911), 1505 MoveLR(-0.827479), 1506 DelayOld(20), 1507 MoveLR(-0.75689), 1508 DelayOld(30), 1509 MoveLR(-0.73336), 1510 MoveLR(-0.694143), 1511 DelayOld(20), 1512 MoveLR(-0.670614), 1513 DelayOld(30), 1514 MoveLR(-0.66277), 1515 DelayOld(10), 1516 MoveUD(-0.960784), 1517 DelayOld(20), 1518 MoveLR(-0.623554), 1519 MoveUD(-0.874508), 1520 DelayOld(10), 1521 MoveLR(-0.545122), 1522 MoveUD(-0.694113), 1523 DelayOld(20), 1524 MoveLR(-0.505905), 1525 MoveUD(-0.474502), 1526 DelayOld(20), 1527 MoveLR(-0.458846), 1528 MoveUD(-0.356853), 1529 MoveLR(-0.364727), 1530 MoveUD(-0.27842), 1531 DelayOld(20), 1532 MoveLR(0.00390637), 1533 Move(0, 0), 1534 DelayOld(1000), 1535 Text( 1536 ba.Lstr(resource=self._r + '.phrase09Text') 1537 ), # ah that's better 1538 DelayOld(1900), 1539 AnalyticsScreen('Tutorial Section 3'), 1540 Text( 1541 ba.Lstr(resource=self._r + '.phrase10Text') 1542 ), # running also helps 1543 DelayOld(100), 1544 SpawnSpaz( 1545 0, (-3.2, 4.3, -4.4), make_current=True, flash=False 1546 ), 1547 SpawnSpaz( 1548 1, 1549 (3.3, 4.2, -5.8), 1550 make_current=False, 1551 color=(0.9, 0.5, 1.0), 1552 name=ba.Lstr(resource=self._r + '.randomName2Text'), 1553 ), 1554 DelayOld(1800), 1555 Text( 1556 ba.Lstr(resource=self._r + '.phrase11Text') 1557 ), # hold ANY button to run 1558 DelayOld(300), 1559 MoveUD(0), 1560 DelayOld(20), 1561 MoveUD(-0.0520646), 1562 DelayOld(20), 1563 MoveLR(0), 1564 MoveUD(-0.223518), 1565 Run(release=False), 1566 Jump(release=False), 1567 DelayOld(10), 1568 MoveLR(0.0980255), 1569 MoveUD(-0.309793), 1570 DelayOld(30), 1571 MoveLR(0.160772), 1572 MoveUD(-0.427442), 1573 DelayOld(20), 1574 MoveLR(0.231361), 1575 MoveUD(-0.545091), 1576 DelayOld(10), 1577 MoveLR(0.317637), 1578 MoveUD(-0.678426), 1579 DelayOld(20), 1580 MoveLR(0.396069), 1581 MoveUD(-0.819605), 1582 MoveLR(0.482345), 1583 MoveUD(-0.913724), 1584 DelayOld(20), 1585 MoveLR(0.560778), 1586 MoveUD(-1), 1587 DelayOld(20), 1588 MoveLR(0.607837), 1589 DelayOld(10), 1590 MoveLR(0.623524), 1591 DelayOld(30), 1592 MoveLR(0.647053), 1593 DelayOld(20), 1594 MoveLR(0.670583), 1595 MoveLR(0.694113), 1596 DelayOld(30), 1597 MoveLR(0.733329), 1598 DelayOld(20), 1599 MoveLR(0.764702), 1600 MoveLR(0.788232), 1601 DelayOld(20), 1602 MoveLR(0.827448), 1603 DelayOld(10), 1604 MoveLR(0.858821), 1605 DelayOld(20), 1606 MoveLR(0.921567), 1607 DelayOld(30), 1608 MoveLR(0.97647), 1609 MoveLR(1), 1610 DelayOld(130), 1611 MoveUD(-0.960784), 1612 DelayOld(20), 1613 MoveUD(-0.921567), 1614 DelayOld(30), 1615 MoveUD(-0.866665), 1616 MoveUD(-0.819605), 1617 DelayOld(30), 1618 MoveUD(-0.772546), 1619 MoveUD(-0.725486), 1620 DelayOld(30), 1621 MoveUD(-0.631367), 1622 DelayOld(10), 1623 MoveUD(-0.552934), 1624 DelayOld(20), 1625 MoveUD(-0.474502), 1626 DelayOld(10), 1627 MoveUD(-0.403912), 1628 DelayOld(30), 1629 MoveUD(-0.356853), 1630 DelayOld(30), 1631 MoveUD(-0.34901), 1632 DelayOld(20), 1633 MoveUD(-0.333323), 1634 DelayOld(20), 1635 MoveUD(-0.32548), 1636 DelayOld(10), 1637 MoveUD(-0.30195), 1638 DelayOld(20), 1639 MoveUD(-0.27842), 1640 DelayOld(30), 1641 MoveUD(-0.254891), 1642 MoveUD(-0.231361), 1643 DelayOld(30), 1644 MoveUD(-0.207831), 1645 DelayOld(20), 1646 MoveUD(-0.199988), 1647 MoveUD(-0.176458), 1648 DelayOld(30), 1649 MoveUD(-0.137242), 1650 MoveUD(-0.0823389), 1651 DelayOld(20), 1652 MoveUD(-0.0274361), 1653 DelayOld(20), 1654 MoveUD(0.00393689), 1655 DelayOld(40), 1656 MoveUD(0.0353099), 1657 DelayOld(20), 1658 MoveUD(0.113742), 1659 DelayOld(10), 1660 MoveUD(0.137272), 1661 DelayOld(20), 1662 MoveUD(0.160802), 1663 MoveUD(0.184332), 1664 DelayOld(20), 1665 MoveUD(0.207862), 1666 DelayOld(30), 1667 MoveUD(0.247078), 1668 MoveUD(0.262764), 1669 DelayOld(20), 1670 MoveUD(0.270608), 1671 DelayOld(30), 1672 MoveUD(0.294137), 1673 MoveUD(0.32551), 1674 DelayOld(30), 1675 MoveUD(0.37257), 1676 Celebrate('left', 1), 1677 DelayOld(20), 1678 MoveUD(0.498062), 1679 MoveUD(0.560808), 1680 DelayOld(30), 1681 MoveUD(0.654927), 1682 MoveUD(0.694143), 1683 DelayOld(30), 1684 MoveUD(0.741203), 1685 DelayOld(20), 1686 MoveUD(0.780419), 1687 MoveUD(0.819636), 1688 DelayOld(20), 1689 MoveUD(0.843165), 1690 DelayOld(20), 1691 MoveUD(0.882382), 1692 DelayOld(10), 1693 MoveUD(0.913755), 1694 DelayOld(30), 1695 MoveUD(0.968657), 1696 MoveUD(1), 1697 DelayOld(560), 1698 Punch(release=False), 1699 DelayOld(210), 1700 MoveUD(0.968657), 1701 DelayOld(30), 1702 MoveUD(0.75689), 1703 PunchRelease(), 1704 DelayOld(20), 1705 MoveLR(0.95294), 1706 MoveUD(0.435316), 1707 RunRelease(), 1708 JumpRelease(), 1709 MoveLR(0.811762), 1710 MoveUD(0.270608), 1711 DelayOld(20), 1712 MoveLR(0.670583), 1713 MoveUD(0.160802), 1714 DelayOld(20), 1715 MoveLR(0.466659), 1716 MoveUD(0.0588397), 1717 DelayOld(10), 1718 MoveLR(0.317637), 1719 MoveUD(-0.00390637), 1720 DelayOld(20), 1721 MoveLR(0.0801416), 1722 DelayOld(10), 1723 MoveLR(0), 1724 DelayOld(20), 1725 MoveLR(0), 1726 DelayOld(30), 1727 MoveLR(0), 1728 DelayOld(30), 1729 MoveLR(0), 1730 DelayOld(20), 1731 MoveLR(0), 1732 DelayOld(100), 1733 MoveLR(0), 1734 DelayOld(30), 1735 MoveUD(0), 1736 DelayOld(30), 1737 MoveUD(0), 1738 DelayOld(50), 1739 MoveUD(0), 1740 MoveUD(0), 1741 DelayOld(30), 1742 MoveLR(0), 1743 MoveUD(-0.0520646), 1744 MoveLR(0), 1745 MoveUD(-0.0640889), 1746 DelayOld(20), 1747 MoveLR(0), 1748 MoveUD(-0.0881375), 1749 DelayOld(30), 1750 MoveLR(-0.0498978), 1751 MoveUD(-0.199988), 1752 MoveLR(-0.121586), 1753 MoveUD(-0.207831), 1754 DelayOld(20), 1755 MoveLR(-0.145116), 1756 MoveUD(-0.223518), 1757 DelayOld(30), 1758 MoveLR(-0.152959), 1759 MoveUD(-0.231361), 1760 MoveLR(-0.192175), 1761 MoveUD(-0.262734), 1762 DelayOld(30), 1763 MoveLR(-0.200018), 1764 MoveUD(-0.27842), 1765 DelayOld(20), 1766 MoveLR(-0.239235), 1767 MoveUD(-0.30195), 1768 MoveUD(-0.309793), 1769 DelayOld(40), 1770 MoveUD(-0.333323), 1771 DelayOld(10), 1772 MoveUD(-0.34901), 1773 DelayOld(30), 1774 MoveUD(-0.372539), 1775 MoveUD(-0.396069), 1776 DelayOld(20), 1777 MoveUD(-0.443129), 1778 DelayOld(20), 1779 MoveUD(-0.458815), 1780 DelayOld(10), 1781 MoveUD(-0.474502), 1782 DelayOld(50), 1783 MoveUD(-0.482345), 1784 DelayOld(30), 1785 MoveLR(-0.215705), 1786 DelayOld(30), 1787 MoveLR(-0.200018), 1788 DelayOld(10), 1789 MoveLR(-0.192175), 1790 DelayOld(10), 1791 MoveLR(-0.176489), 1792 DelayOld(30), 1793 MoveLR(-0.152959), 1794 DelayOld(20), 1795 MoveLR(-0.145116), 1796 MoveLR(-0.121586), 1797 MoveUD(-0.458815), 1798 DelayOld(30), 1799 MoveLR(-0.098056), 1800 MoveUD(-0.419599), 1801 DelayOld(10), 1802 MoveLR(-0.0745262), 1803 MoveUD(-0.333323), 1804 DelayOld(10), 1805 MoveLR(0.00390637), 1806 MoveUD(0), 1807 DelayOld(990), 1808 MoveLR(0), 1809 DelayOld(660), 1810 MoveUD(0), 1811 AnalyticsScreen('Tutorial Section 4'), 1812 Text( 1813 ba.Lstr(resource=self._r + '.phrase12Text') 1814 ), # for extra-awesome punches,... 1815 DelayOld(200), 1816 SpawnSpaz( 1817 0, 1818 ( 1819 2.368781805038452, 1820 4.337533950805664, 1821 -4.360159873962402, 1822 ), 1823 make_current=True, 1824 flash=False, 1825 ), 1826 SpawnSpaz( 1827 1, 1828 (-3.2, 4.3, -4.5), 1829 make_current=False, 1830 color=(1.0, 0.7, 0.3), 1831 # name=R.randomName3Text), 1832 name=ba.Lstr(resource=self._r + '.randomName3Text'), 1833 ), 1834 DelayOld(100), 1835 Powerup(1, (2.5, 0.0, 0), relative_to=0), 1836 Move(1, 0), 1837 DelayOld(1700), 1838 Move(0, -0.1), 1839 DelayOld(100), 1840 Move(0, 0), 1841 DelayOld(500), 1842 DelayOld(320), 1843 MoveLR(0), 1844 DelayOld(20), 1845 MoveLR(0), 1846 DelayOld(10), 1847 MoveLR(0), 1848 DelayOld(20), 1849 MoveLR(-0.333354), 1850 MoveLR(-0.592181), 1851 DelayOld(20), 1852 MoveLR(-0.788263), 1853 DelayOld(20), 1854 MoveLR(-1), 1855 MoveUD(0.0353099), 1856 MoveUD(0.0588397), 1857 DelayOld(10), 1858 Run(release=False), 1859 DelayOld(780), 1860 MoveUD(0.0274667), 1861 MoveUD(0.00393689), 1862 DelayOld(10), 1863 MoveUD(-0.00390637), 1864 DelayOld(440), 1865 MoveUD(0.0353099), 1866 DelayOld(20), 1867 MoveUD(0.0588397), 1868 DelayOld(10), 1869 MoveUD(0.0902127), 1870 DelayOld(260), 1871 MoveUD(0.0353099), 1872 DelayOld(30), 1873 MoveUD(0.00393689), 1874 DelayOld(10), 1875 MoveUD(-0.00390637), 1876 MoveUD(-0.0274361), 1877 Celebrate('left', 1), 1878 DelayOld(10), 1879 MoveUD(-0.0823389), 1880 DelayOld(30), 1881 MoveUD(-0.176458), 1882 MoveUD(-0.286264), 1883 DelayOld(20), 1884 MoveUD(-0.498032), 1885 Jump(release=False), 1886 MoveUD(-0.764702), 1887 DelayOld(30), 1888 MoveLR(-0.858852), 1889 MoveUD(-1), 1890 MoveLR(-0.780419), 1891 DelayOld(20), 1892 MoveLR(-0.717673), 1893 DelayOld(10), 1894 MoveLR(-0.552965), 1895 DelayOld(10), 1896 MoveLR(-0.341197), 1897 DelayOld(10), 1898 MoveLR(-0.0274667), 1899 DelayOld(10), 1900 MoveLR(0.27842), 1901 DelayOld(20), 1902 MoveLR(0.811762), 1903 MoveLR(1), 1904 RunRelease(), 1905 JumpRelease(), 1906 DelayOld(260), 1907 MoveLR(0.95294), 1908 DelayOld(30), 1909 MoveLR(0.756859), 1910 DelayOld(10), 1911 MoveLR(0.317637), 1912 MoveLR(-0.00393689), 1913 DelayOld(10), 1914 MoveLR(-0.341197), 1915 DelayOld(10), 1916 MoveLR(-0.647084), 1917 MoveUD(-0.921567), 1918 DelayOld(10), 1919 MoveLR(-1), 1920 MoveUD(-0.599994), 1921 MoveUD(-0.474502), 1922 DelayOld(10), 1923 MoveUD(-0.309793), 1924 DelayOld(10), 1925 MoveUD(-0.160772), 1926 MoveUD(-0.0352794), 1927 Delay(10), 1928 MoveUD(0.176489), 1929 Delay(10), 1930 MoveUD(0.607868), 1931 Run(release=False), 1932 Jump(release=False), 1933 DelayOld(20), 1934 MoveUD(1), 1935 DelayOld(30), 1936 MoveLR(-0.921598), 1937 DelayOld(10), 1938 Punch(release=False), 1939 MoveLR(-0.639241), 1940 DelayOld(10), 1941 MoveLR(-0.223548), 1942 DelayOld(10), 1943 MoveLR(0.254891), 1944 DelayOld(10), 1945 MoveLR(0.741172), 1946 MoveLR(1), 1947 DelayOld(40), 1948 JumpRelease(), 1949 DelayOld(40), 1950 MoveUD(0.976501), 1951 DelayOld(10), 1952 MoveUD(0.73336), 1953 DelayOld(10), 1954 MoveUD(0.309824), 1955 DelayOld(20), 1956 MoveUD(-0.184301), 1957 DelayOld(20), 1958 MoveUD(-0.811762), 1959 MoveUD(-1), 1960 KillSpaz(1, explode=True), 1961 DelayOld(10), 1962 RunRelease(), 1963 PunchRelease(), 1964 DelayOld(110), 1965 MoveLR(0.97647), 1966 MoveLR(0.898038), 1967 DelayOld(20), 1968 MoveLR(0.788232), 1969 DelayOld(20), 1970 MoveLR(0.670583), 1971 DelayOld(10), 1972 MoveLR(0.505875), 1973 DelayOld(10), 1974 MoveLR(0.32548), 1975 DelayOld(20), 1976 MoveLR(0.137242), 1977 DelayOld(10), 1978 MoveLR(-0.00393689), 1979 DelayOld(10), 1980 MoveLR(-0.215705), 1981 MoveLR(-0.356883), 1982 DelayOld(20), 1983 MoveLR(-0.451003), 1984 DelayOld(10), 1985 MoveLR(-0.552965), 1986 DelayOld(20), 1987 MoveLR(-0.670614), 1988 MoveLR(-0.780419), 1989 DelayOld(10), 1990 MoveLR(-0.898068), 1991 DelayOld(20), 1992 MoveLR(-1), 1993 DelayOld(370), 1994 MoveLR(-0.976501), 1995 DelayOld(10), 1996 MoveLR(-0.952971), 1997 DelayOld(10), 1998 MoveLR(-0.929441), 1999 MoveLR(-0.898068), 2000 DelayOld(30), 2001 MoveLR(-0.874538), 2002 DelayOld(10), 2003 MoveLR(-0.851009), 2004 DelayOld(10), 2005 MoveLR(-0.835322), 2006 MoveUD(-0.968627), 2007 DelayOld(10), 2008 MoveLR(-0.827479), 2009 MoveUD(-0.960784), 2010 DelayOld(20), 2011 MoveUD(-0.945097), 2012 DelayOld(70), 2013 MoveUD(-0.937254), 2014 DelayOld(20), 2015 MoveUD(-0.913724), 2016 DelayOld(20), 2017 MoveUD(-0.890194), 2018 MoveLR(-0.780419), 2019 MoveUD(-0.827448), 2020 DelayOld(20), 2021 MoveLR(0.317637), 2022 MoveUD(0.3961), 2023 MoveLR(0.0195929), 2024 MoveUD(0.056093), 2025 DelayOld(20), 2026 MoveUD(0), 2027 DelayOld(750), 2028 MoveLR(0), 2029 Text( 2030 ba.Lstr( 2031 resource=self._r + '.phrase13Text', 2032 subs=[ 2033 ( 2034 '${NAME}', 2035 ba.Lstr( 2036 resource=self._r + '.randomName3Text' 2037 ), 2038 ) 2039 ], 2040 ) 2041 ), # whoops sorry bill 2042 RemoveGloves(), 2043 DelayOld(2000), 2044 AnalyticsScreen('Tutorial Section 5'), 2045 Text( 2046 ba.Lstr( 2047 resource=self._r + '.phrase14Text', 2048 subs=[ 2049 ( 2050 '${NAME}', 2051 ba.Lstr( 2052 resource=self._r + '.randomName4Text' 2053 ), 2054 ) 2055 ], 2056 ) 2057 ), # you can pick up and throw things such as chuck here 2058 SpawnSpaz( 2059 0, 2060 (-4.0, 4.3, -2.5), 2061 make_current=True, 2062 flash=False, 2063 angle=90, 2064 ), 2065 SpawnSpaz( 2066 1, 2067 (5, 0, -1.0), 2068 relative_to=0, 2069 make_current=False, 2070 color=(0.4, 1.0, 0.7), 2071 name=ba.Lstr(resource=self._r + '.randomName4Text'), 2072 ), 2073 DelayOld(1000), 2074 Celebrate('left', 1, duration=1000), 2075 Move(1, 0.2), 2076 DelayOld(2000), 2077 PickUp(), 2078 DelayOld(200), 2079 Move(0.5, 1.0), 2080 DelayOld(1200), 2081 PickUp(), 2082 Move(0, 0), 2083 DelayOld(1000), 2084 Celebrate('left'), 2085 DelayOld(1500), 2086 Move(0, -1.0), 2087 DelayOld(800), 2088 Move(0, 0), 2089 DelayOld(800), 2090 SpawnSpaz( 2091 0, 2092 (1.5, 4.3, -4.0), 2093 make_current=True, 2094 flash=False, 2095 angle=0, 2096 ), 2097 AnalyticsScreen('Tutorial Section 6'), 2098 Text( 2099 ba.Lstr(resource=self._r + '.phrase15Text') 2100 ), # lastly there's bombs 2101 DelayOld(1900), 2102 Text( 2103 ba.Lstr(resource=self._r + '.phrase16Text') 2104 ), # throwing bombs takes practice 2105 DelayOld(2000), 2106 Bomb(), 2107 Move(-0.1, -0.1), 2108 DelayOld(100), 2109 Move(0, 0), 2110 DelayOld(500), 2111 DelayOld(1000), 2112 Bomb(), 2113 DelayOld(2000), 2114 Text( 2115 ba.Lstr(resource=self._r + '.phrase17Text') 2116 ), # not a very good throw 2117 DelayOld(3000), 2118 Text( 2119 ba.Lstr(resource=self._r + '.phrase18Text') 2120 ), # moving helps you get distance 2121 DelayOld(1000), 2122 Bomb(), 2123 DelayOld(500), 2124 Move(-0.3, 0), 2125 DelayOld(100), 2126 Move(-0.6, 0), 2127 DelayOld(100), 2128 Move(-1, 0), 2129 DelayOld(800), 2130 Bomb(), 2131 DelayOld(400), 2132 Move(0, -0.1), 2133 DelayOld(100), 2134 Move(0, 0), 2135 DelayOld(2500), 2136 Text( 2137 ba.Lstr(resource=self._r + '.phrase19Text') 2138 ), # jumping helps you get height 2139 DelayOld(2000), 2140 Bomb(), 2141 DelayOld(500), 2142 Move(1, 0), 2143 DelayOld(300), 2144 Jump(release_delay=250), 2145 DelayOld(500), 2146 Jump(release_delay=250), 2147 DelayOld(550), 2148 Jump(release_delay=250), 2149 DelayOld(160), 2150 Punch(), 2151 DelayOld(500), 2152 Move(0, -0.1), 2153 DelayOld(100), 2154 Move(0, 0), 2155 DelayOld(2000), 2156 Text( 2157 ba.Lstr(resource=self._r + '.phrase20Text') 2158 ), # whiplash your bombs 2159 DelayOld(1000), 2160 Bomb(release=False), 2161 DelayOld2(80), 2162 RunRelease(), 2163 BombRelease(), 2164 DelayOld2(620), 2165 MoveLR(0), 2166 DelayOld2(10), 2167 MoveLR(0), 2168 DelayOld2(40), 2169 MoveLR(0), 2170 DelayOld2(10), 2171 MoveLR(-0.0537431), 2172 MoveUD(0), 2173 DelayOld2(20), 2174 MoveLR(-0.262764), 2175 DelayOld2(20), 2176 MoveLR(-0.498062), 2177 DelayOld2(10), 2178 MoveLR(-0.639241), 2179 DelayOld2(20), 2180 MoveLR(-0.73336), 2181 DelayOld2(10), 2182 MoveLR(-0.843165), 2183 MoveUD(-0.0352794), 2184 DelayOld2(30), 2185 MoveLR(-1), 2186 DelayOld2(10), 2187 MoveUD(-0.0588092), 2188 DelayOld2(10), 2189 MoveUD(-0.160772), 2190 DelayOld2(20), 2191 MoveUD(-0.286264), 2192 DelayOld2(20), 2193 MoveUD(-0.427442), 2194 DelayOld2(10), 2195 MoveUD(-0.623524), 2196 DelayOld2(20), 2197 MoveUD(-0.843135), 2198 DelayOld2(10), 2199 MoveUD(-1), 2200 DelayOld2(40), 2201 MoveLR(-0.890225), 2202 DelayOld2(10), 2203 MoveLR(-0.670614), 2204 DelayOld2(20), 2205 MoveLR(-0.435316), 2206 DelayOld2(20), 2207 MoveLR(-0.184332), 2208 DelayOld2(10), 2209 MoveLR(0.00390637), 2210 DelayOld2(20), 2211 MoveLR(0.223518), 2212 DelayOld2(10), 2213 MoveLR(0.388226), 2214 DelayOld2(20), 2215 MoveLR(0.560778), 2216 DelayOld2(20), 2217 MoveLR(0.717643), 2218 DelayOld2(10), 2219 MoveLR(0.890194), 2220 DelayOld2(20), 2221 MoveLR(1), 2222 DelayOld2(30), 2223 MoveUD(-0.968627), 2224 DelayOld2(20), 2225 MoveUD(-0.898038), 2226 DelayOld2(10), 2227 MoveUD(-0.741172), 2228 DelayOld2(20), 2229 MoveUD(-0.498032), 2230 DelayOld2(20), 2231 MoveUD(-0.247047), 2232 DelayOld2(10), 2233 MoveUD(0.00393689), 2234 DelayOld2(20), 2235 MoveUD(0.239235), 2236 DelayOld2(20), 2237 MoveUD(0.458846), 2238 DelayOld2(10), 2239 MoveUD(0.70983), 2240 DelayOld2(30), 2241 MoveUD(1), 2242 DelayOld2(10), 2243 MoveLR(0.827448), 2244 DelayOld2(10), 2245 MoveLR(0.678426), 2246 DelayOld2(20), 2247 MoveLR(0.396069), 2248 DelayOld2(10), 2249 MoveLR(0.0980255), 2250 DelayOld2(20), 2251 MoveLR(-0.160802), 2252 DelayOld2(20), 2253 MoveLR(-0.388256), 2254 DelayOld2(10), 2255 MoveLR(-0.545122), 2256 DelayOld2(30), 2257 MoveLR(-0.73336), 2258 DelayOld2(10), 2259 MoveLR(-0.945128), 2260 DelayOld2(10), 2261 MoveLR(-1), 2262 DelayOld2(50), 2263 MoveUD(0.960814), 2264 DelayOld2(20), 2265 MoveUD(0.890225), 2266 DelayOld2(10), 2267 MoveUD(0.749046), 2268 DelayOld2(20), 2269 MoveUD(0.623554), 2270 DelayOld2(20), 2271 MoveUD(0.498062), 2272 DelayOld2(10), 2273 MoveUD(0.34904), 2274 DelayOld2(20), 2275 MoveUD(0.239235), 2276 DelayOld2(20), 2277 MoveUD(0.137272), 2278 DelayOld2(10), 2279 MoveUD(0.0117801), 2280 DelayOld2(20), 2281 MoveUD(-0.0117496), 2282 DelayOld2(10), 2283 MoveUD(-0.0274361), 2284 DelayOld2(90), 2285 MoveUD(-0.0352794), 2286 Run(release=False), 2287 Jump(release=False), 2288 Delay(80), 2289 Punch(release=False), 2290 DelayOld2(60), 2291 MoveLR(-0.968657), 2292 DelayOld2(20), 2293 MoveLR(-0.835322), 2294 DelayOld2(10), 2295 MoveLR(-0.70983), 2296 JumpRelease(), 2297 DelayOld2(30), 2298 MoveLR(-0.592181), 2299 MoveUD(-0.0588092), 2300 DelayOld2(10), 2301 MoveLR(-0.490219), 2302 MoveUD(-0.0744957), 2303 DelayOld2(10), 2304 MoveLR(-0.41963), 2305 DelayOld2(20), 2306 MoveLR(0), 2307 MoveUD(0), 2308 DelayOld2(20), 2309 MoveUD(0), 2310 PunchRelease(), 2311 RunRelease(), 2312 DelayOld(500), 2313 Move(0, -0.1), 2314 DelayOld(100), 2315 Move(0, 0), 2316 DelayOld(2000), 2317 AnalyticsScreen('Tutorial Section 7'), 2318 Text( 2319 ba.Lstr(resource=self._r + '.phrase21Text') 2320 ), # timing your bombs can be tricky 2321 Move(-1, 0), 2322 DelayOld(1000), 2323 Move(0, -0.1), 2324 DelayOld(100), 2325 Move(0, 0), 2326 SpawnSpaz( 2327 0, 2328 (-0.7, 4.3, -3.9), 2329 make_current=True, 2330 flash=False, 2331 angle=-30, 2332 ), 2333 SpawnSpaz( 2334 1, 2335 (6.5, 0, -0.75), 2336 relative_to=0, 2337 make_current=False, 2338 color=(0.3, 0.8, 1.0), 2339 name=ba.Lstr(resource=self._r + '.randomName5Text'), 2340 ), 2341 DelayOld2(1000), 2342 Move(-1, 0), 2343 DelayOld2(1800), 2344 Bomb(), 2345 Move(0, 0), 2346 DelayOld2(300), 2347 Move(1, 0), 2348 DelayOld2(600), 2349 Jump(), 2350 DelayOld2(150), 2351 Punch(), 2352 DelayOld2(800), 2353 Move(-1, 0), 2354 DelayOld2(1000), 2355 Move(0, 0), 2356 DelayOld2(1500), 2357 Text(ba.Lstr(resource=self._r + '.phrase22Text')), # dang 2358 Delay(1500), 2359 Text(''), 2360 Delay(200), 2361 Text( 2362 ba.Lstr(resource=self._r + '.phrase23Text') 2363 ), # try cooking off 2364 Delay(1500), 2365 Bomb(), 2366 Delay(800), 2367 Move(1, 0.12), 2368 Delay(1100), 2369 Jump(), 2370 Delay(100), 2371 Punch(), 2372 Delay(100), 2373 Move(0, -0.1), 2374 Delay(100), 2375 Move(0, 0), 2376 Delay(2000), 2377 Text( 2378 ba.Lstr(resource=self._r + '.phrase24Text') 2379 ), # hooray nicely cooked 2380 Celebrate(), 2381 DelayOld(2000), 2382 KillSpaz(1), 2383 Text(''), 2384 Move(0.5, -0.5), 2385 DelayOld(1000), 2386 Move(0, -0.1), 2387 DelayOld(100), 2388 Move(0, 0), 2389 DelayOld(1000), 2390 AnalyticsScreen('Tutorial Section 8'), 2391 Text( 2392 ba.Lstr(resource=self._r + '.phrase25Text') 2393 ), # well that's just about it 2394 DelayOld(2000), 2395 Text( 2396 ba.Lstr(resource=self._r + '.phrase26Text') 2397 ), # go get em tiger 2398 DelayOld(2000), 2399 Text( 2400 ba.Lstr(resource=self._r + '.phrase27Text') 2401 ), # remember you training 2402 DelayOld(3000), 2403 Text( 2404 ba.Lstr(resource=self._r + '.phrase28Text') 2405 ), # well maybe 2406 DelayOld(1600), 2407 Text( 2408 ba.Lstr(resource=self._r + '.phrase29Text') 2409 ), # good luck 2410 Celebrate('right', duration=10000), 2411 DelayOld(1000), 2412 AnalyticsScreen('Tutorial Complete'), 2413 End(), 2414 ] 2415 ) 2416 2417 except Exception: 2418 ba.print_exception() 2419 2420 # If we read some, exec them. 2421 if self._entries: 2422 self._run_next_entry() 2423 # Otherwise try again in a few seconds. 2424 else: 2425 self._read_entries_timer = ba.Timer( 2426 3.0, ba.WeakCall(self._read_entries) 2427 ) 2428 2429 def _run_next_entry(self) -> None: 2430 2431 while self._entries: 2432 entry = self._entries.popleft() 2433 try: 2434 result = entry.run(self) 2435 except Exception: 2436 result = None 2437 ba.print_exception() 2438 2439 # If the entry returns an int value, set a timer; 2440 # otherwise just keep going. 2441 if result is not None: 2442 self._entry_timer = ba.Timer( 2443 result, 2444 ba.WeakCall(self._run_next_entry), 2445 timeformat=ba.TimeFormat.MILLISECONDS, 2446 ) 2447 return 2448 2449 # Done with these entries.. start over soon. 2450 self._read_entries_timer = ba.Timer( 2451 1.0, ba.WeakCall(self._read_entries) 2452 ) 2453 2454 def _update_skip_votes(self) -> None: 2455 count = sum(1 for player in self.players if player.pressed) 2456 assert self._skip_count_text 2457 self._skip_count_text.text = ( 2458 ba.Lstr( 2459 resource=self._r + '.skipVoteCountText', 2460 subs=[ 2461 ('${COUNT}', str(count)), 2462 ('${TOTAL}', str(len(self.players))), 2463 ], 2464 ) 2465 if count > 0 2466 else '' 2467 ) 2468 if ( 2469 count >= len(self.players) 2470 and self.players 2471 and not self._have_skipped 2472 ): 2473 ba.internal.increment_analytics_count('Tutorial skip') 2474 ba.set_analytics_screen('Tutorial Skip') 2475 self._have_skipped = True 2476 ba.playsound(ba.getsound('swish')) 2477 # self._skip_count_text.text = self._r.skippingText 2478 self._skip_count_text.text = ba.Lstr( 2479 resource=self._r + '.skippingText' 2480 ) 2481 assert self._skip_text 2482 self._skip_text.text = '' 2483 self.end() 2484 2485 def _player_pressed_button(self, player: Player) -> None: 2486 2487 # Special case: if there's only one player, we give them a 2488 # warning on their first press (some players were thinking the 2489 # on-screen guide meant they were supposed to press something). 2490 if len(self.players) == 1 and not self._issued_warning: 2491 self._issued_warning = True 2492 assert self._skip_text 2493 self._skip_text.text = ba.Lstr( 2494 resource=self._r + '.skipConfirmText' 2495 ) 2496 self._skip_text.color = (1, 1, 1) 2497 self._skip_text.scale = 1.3 2498 incr = 50 2499 t = incr 2500 for _i in range(6): 2501 ba.timer( 2502 t, 2503 ba.Call(setattr, self._skip_text, 'color', (1, 0.5, 0.1)), 2504 timeformat=ba.TimeFormat.MILLISECONDS, 2505 ) 2506 t += incr 2507 ba.timer( 2508 t, 2509 ba.Call(setattr, self._skip_text, 'color', (1, 1, 0)), 2510 timeformat=ba.TimeFormat.MILLISECONDS, 2511 ) 2512 t += incr 2513 ba.timer(6.0, ba.WeakCall(self._revert_confirm)) 2514 return 2515 2516 player.pressed = True 2517 2518 # test... 2519 if not all(self.players): 2520 ba.print_error( 2521 'Nonexistent player in _player_pressed_button: ' 2522 + str([str(p) for p in self.players]) 2523 + ': we are ' 2524 + str(player) 2525 ) 2526 2527 self._update_skip_votes() 2528 2529 def _revert_confirm(self) -> None: 2530 assert self._skip_text 2531 self._skip_text.text = ba.Lstr( 2532 resource=self._r + '.toSkipPressAnythingText' 2533 ) 2534 self._skip_text.color = (1, 1, 1) 2535 self._issued_warning = False 2536 2537 def on_player_join(self, player: Player) -> None: 2538 super().on_player_join(player) 2539 2540 # We just wanna know if this player presses anything. 2541 player.assigninput( 2542 ( 2543 ba.InputType.JUMP_PRESS, 2544 ba.InputType.PUNCH_PRESS, 2545 ba.InputType.BOMB_PRESS, 2546 ba.InputType.PICK_UP_PRESS, 2547 ), 2548 ba.Call(self._player_pressed_button, player), 2549 ) 2550 2551 def on_player_leave(self, player: Player) -> None: 2552 if not all(self.players): 2553 ba.print_error( 2554 'Nonexistent player in on_player_leave: ' 2555 + str([str(p) for p in self.players]) 2556 + ': we are ' 2557 + str(player) 2558 ) 2559 super().on_player_leave(player) 2560 # our leaving may influence the vote total needed/etc 2561 self._update_skip_votes()
Units of execution wrangled by a ba.Session.
Category: Gameplay Classes
Examples of Activities include games, score-screens, cutscenes, etc. A ba.Session has one 'current' Activity at any time, though their existence can overlap during transitions.
195 def __init__(self, settings: dict | None = None): 196 from bastd.maps import Rampage 197 198 if settings is None: 199 settings = {} 200 super().__init__(settings) 201 self.current_spaz: basespaz.Spaz | None = None 202 self._benchmark_type = getattr(ba.getsession(), 'benchmark_type', None) 203 self.last_start_time: int | None = None 204 self.cycle_times: list[int] = [] 205 self.allow_pausing = True 206 self.allow_kick_idle_players = False 207 self._issued_warning = False 208 self._map_type = Rampage 209 self._map_type.preload() 210 self._jump_button_tex = ba.gettexture('buttonJump') 211 self._pick_up_button_tex = ba.gettexture('buttonPickUp') 212 self._bomb_button_tex = ba.gettexture('buttonBomb') 213 self._punch_button_tex = ba.gettexture('buttonPunch') 214 self._r = 'tutorial' 215 self._have_skipped = False 216 self.stick_image_position_x = self.stick_image_position_y = 0.0 217 self.spawn_sound = ba.getsound('spawn') 218 self.map: ba.Map | None = None 219 self.text: ba.Node | None = None 220 self._skip_text: ba.Node | None = None 221 self._skip_count_text: ba.Node | None = None 222 self._scale: float | None = None 223 self._stick_base_position: tuple[float, float] = (0.0, 0.0) 224 self._stick_nub_position: tuple[float, float] = (0.0, 0.0) 225 self._stick_base_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 226 self._stick_nub_image_color: Sequence[float] = (1.0, 1.0, 1.0, 1.0) 227 self._time: int = -1 228 self.punch_image_color = (1.0, 1.0, 1.0) 229 self.punch_image: ba.Node | None = None 230 self.bomb_image: ba.Node | None = None 231 self.jump_image: ba.Node | None = None 232 self.pickup_image: ba.Node | None = None 233 self._stick_base_image: ba.Node | None = None 234 self._stick_nub_image: ba.Node | None = None 235 self.bomb_image_color = (1.0, 1.0, 1.0) 236 self.pickup_image_color = (1.0, 1.0, 1.0) 237 self.control_ui_nodes: list[ba.Node] = [] 238 self.spazzes: dict[int, basespaz.Spaz] = {} 239 self.jump_image_color = (1.0, 1.0, 1.0) 240 self._entries: deque[Any] = deque() 241 self._read_entries_timer: ba.Timer | None = None 242 self._entry_timer: ba.Timer | None = None
Creates an Activity in the current ba.Session.
The activity will not be actually run until ba.Session.setactivity is called. 'settings' should be a dict of key/value pairs specific to the activity.
Activities should preload as much of their media/etc as possible in their constructor, but none of it should actually be used until they are transitioned in.
Whether idle players can potentially be kicked (should not happen in menus/etc).
244 def on_transition_in(self) -> None: 245 super().on_transition_in() 246 ba.setmusic(ba.MusicType.CHAR_SELECT, continuous=True) 247 self.map = self._map_type()
Called when the Activity is first becoming visible.
Upon this call, the Activity should fade in backgrounds, start playing music, etc. It does not yet have access to players or teams, however. They remain owned by the previous Activity up until ba.Activity.on_begin() is called.
249 def on_begin(self) -> None: 250 super().on_begin() 251 252 ba.set_analytics_screen('Tutorial Start') 253 ba.internal.increment_analytics_count('Tutorial start') 254 255 if bool(False): 256 # Buttons on top. 257 text_y = 140 258 buttons_y = 250 259 else: 260 # Buttons on bottom. 261 text_y = 260 262 buttons_y = 160 263 264 # Need different versions of this: taps/buttons/keys. 265 self.text = ba.newnode( 266 'text', 267 attrs={ 268 'text': '', 269 'scale': 1.9, 270 'position': (0, text_y), 271 'maxwidth': 500, 272 'flatness': 0.0, 273 'shadow': 0.5, 274 'h_align': 'center', 275 'v_align': 'center', 276 'v_attach': 'center', 277 }, 278 ) 279 280 # Need different versions of this: taps/buttons/keys. 281 txt = ( 282 ba.Lstr(resource=self._r + '.cpuBenchmarkText') 283 if self._benchmark_type == 'cpu' 284 else ba.Lstr(resource=self._r + '.toSkipPressAnythingText') 285 ) 286 t = self._skip_text = ba.newnode( 287 'text', 288 attrs={ 289 'text': txt, 290 'maxwidth': 900, 291 'scale': 1.1, 292 'vr_depth': 100, 293 'position': (0, 30), 294 'h_align': 'center', 295 'v_align': 'center', 296 'v_attach': 'bottom', 297 }, 298 ) 299 ba.animate(t, 'opacity', {1.0: 0.0, 2.0: 0.7}) 300 self._skip_count_text = ba.newnode( 301 'text', 302 attrs={ 303 'text': '', 304 'scale': 1.4, 305 'vr_depth': 90, 306 'position': (0, 70), 307 'h_align': 'center', 308 'v_align': 'center', 309 'v_attach': 'bottom', 310 }, 311 ) 312 313 ouya = False 314 315 self._scale = scale = 0.6 316 center_offs = 130.0 * scale 317 offs = 65.0 * scale 318 position = (0, buttons_y) 319 image_size = 90.0 * scale 320 image_size_2 = 220.0 * scale 321 nub_size = 110.0 * scale 322 p = (position[0] + center_offs, position[1] - offs) 323 324 def _sc(r: float, g: float, b: float) -> tuple[float, float, float]: 325 return 0.6 * r, 0.6 * g, 0.6 * b 326 327 self.jump_image_color = c = _sc(0.4, 1, 0.4) 328 self.jump_image = ba.newnode( 329 'image', 330 attrs={ 331 'texture': self._jump_button_tex, 332 'absolute_scale': True, 333 'vr_depth': -20, 334 'position': p, 335 'scale': (image_size, image_size), 336 'color': c, 337 }, 338 ) 339 p = (position[0] + center_offs - offs, position[1]) 340 self.punch_image_color = c = ( 341 _sc(0.2, 0.6, 1) if ouya else _sc(1, 0.7, 0.3) 342 ) 343 self.punch_image = ba.newnode( 344 'image', 345 attrs={ 346 'texture': ba.gettexture('buttonPunch'), 347 'absolute_scale': True, 348 'vr_depth': -20, 349 'position': p, 350 'scale': (image_size, image_size), 351 'color': c, 352 }, 353 ) 354 p = (position[0] + center_offs + offs, position[1]) 355 self.bomb_image_color = c = _sc(1, 0.3, 0.3) 356 self.bomb_image = ba.newnode( 357 'image', 358 attrs={ 359 'texture': ba.gettexture('buttonBomb'), 360 'absolute_scale': True, 361 'vr_depth': -20, 362 'position': p, 363 'scale': (image_size, image_size), 364 'color': c, 365 }, 366 ) 367 p = (position[0] + center_offs, position[1] + offs) 368 self.pickup_image_color = c = ( 369 _sc(1, 0.8, 0.3) if ouya else _sc(0.5, 0.5, 1) 370 ) 371 self.pickup_image = ba.newnode( 372 'image', 373 attrs={ 374 'texture': ba.gettexture('buttonPickUp'), 375 'absolute_scale': True, 376 'vr_depth': -20, 377 'position': p, 378 'scale': (image_size, image_size), 379 'color': c, 380 }, 381 ) 382 383 self._stick_base_position = p = (position[0] - center_offs, position[1]) 384 self._stick_base_image_color = c2 = (0.25, 0.25, 0.25, 1.0) 385 self._stick_base_image = ba.newnode( 386 'image', 387 attrs={ 388 'texture': ba.gettexture('nub'), 389 'absolute_scale': True, 390 'vr_depth': -40, 391 'position': p, 392 'scale': (image_size_2, image_size_2), 393 'color': c2, 394 }, 395 ) 396 self._stick_nub_position = p = (position[0] - center_offs, position[1]) 397 self._stick_nub_image_color = c3 = (0.4, 0.4, 0.4, 1.0) 398 self._stick_nub_image = ba.newnode( 399 'image', 400 attrs={ 401 'texture': ba.gettexture('nub'), 402 'absolute_scale': True, 403 'position': p, 404 'scale': (nub_size, nub_size), 405 'color': c3, 406 }, 407 ) 408 self.control_ui_nodes = [ 409 self.jump_image, 410 self.punch_image, 411 self.bomb_image, 412 self.pickup_image, 413 self._stick_base_image, 414 self._stick_nub_image, 415 ] 416 for n in self.control_ui_nodes: 417 n.opacity = 0.0 418 self._read_entries()
Called once the previous ba.Activity has finished transitioning out.
At this point the activity's initial players and teams are filled in and it should begin its actual game logic.
420 def set_stick_image_position(self, x: float, y: float) -> None: 421 422 # Clamp this to a circle. 423 len_squared = x * x + y * y 424 if len_squared > 1.0: 425 length = math.sqrt(len_squared) 426 mult = 1.0 / length 427 x *= mult 428 y *= mult 429 430 self.stick_image_position_x = x 431 self.stick_image_position_y = y 432 offs = 50.0 433 assert self._scale is not None 434 p = [ 435 self._stick_nub_position[0] + x * offs * self._scale, 436 self._stick_nub_position[1] + y * offs * self._scale, 437 ] 438 c = list(self._stick_nub_image_color) 439 if abs(x) > 0.1 or abs(y) > 0.1: 440 c[0] *= 2.0 441 c[1] *= 4.0 442 c[2] *= 2.0 443 assert self._stick_nub_image is not None 444 self._stick_nub_image.position = p 445 self._stick_nub_image.color = c 446 c = list(self._stick_base_image_color) 447 if abs(x) > 0.1 or abs(y) > 0.1: 448 c[0] *= 1.5 449 c[1] *= 1.5 450 c[2] *= 1.5 451 assert self._stick_base_image is not None 452 self._stick_base_image.color = c
2537 def on_player_join(self, player: Player) -> None: 2538 super().on_player_join(player) 2539 2540 # We just wanna know if this player presses anything. 2541 player.assigninput( 2542 ( 2543 ba.InputType.JUMP_PRESS, 2544 ba.InputType.PUNCH_PRESS, 2545 ba.InputType.BOMB_PRESS, 2546 ba.InputType.PICK_UP_PRESS, 2547 ), 2548 ba.Call(self._player_pressed_button, player), 2549 )
Called when a new ba.Player has joined the Activity.
(including the initial set of Players)
2551 def on_player_leave(self, player: Player) -> None: 2552 if not all(self.players): 2553 ba.print_error( 2554 'Nonexistent player in on_player_leave: ' 2555 + str([str(p) for p in self.players]) 2556 + ': we are ' 2557 + str(player) 2558 ) 2559 super().on_player_leave(player) 2560 # our leaving may influence the vote total needed/etc 2561 self._update_skip_votes()
Called when a ba.Player is leaving the Activity.
Inherited Members
- ba._activity.Activity
- settings_raw
- teams
- players
- announce_player_deaths
- is_joining_activity
- use_fixed_vr_overlay
- slow_motion
- inherits_slow_motion
- inherits_music
- inherits_vr_camera_offset
- inherits_vr_overlay_center
- inherits_tint
- allow_mid_activity_joins
- transition_time
- can_show_ad_on_death
- globalsnode
- stats
- on_expire
- customdata
- expired
- playertype
- teamtype
- retain_actor
- add_actor_weak_ref
- session
- on_team_join
- on_team_leave
- on_transition_out
- handlemessage
- has_transitioned_in
- has_begun
- has_ended
- is_transitioning_out
- transition_out
- end
- create_player
- create_team
- ba._dependency.DependencyComponent
- dep_is_present
- get_dynamic_deps