bastd.ui.kiosk
UI functionality for running the game in kiosk mode.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI functionality for running the game in kiosk mode.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import ba 10import ba.internal 11 12if TYPE_CHECKING: 13 pass 14 15 16class KioskWindow(ba.Window): 17 """Kiosk mode window.""" 18 19 def __init__(self, transition: str = 'in_right'): 20 # pylint: disable=too-many-locals, too-many-statements 21 from bastd.ui.confirm import QuitWindow 22 23 self._width = 720.0 24 self._height = 340.0 25 26 def _do_cancel() -> None: 27 QuitWindow(swish=True, back=True) 28 29 super().__init__( 30 root_widget=ba.containerwidget( 31 size=(self._width, self._height), 32 transition=transition, 33 on_cancel_call=_do_cancel, 34 background=False, 35 stack_offset=(0, -130), 36 ) 37 ) 38 39 self._r = 'kioskWindow' 40 41 self._show_multiplayer = False 42 43 # Let's reset all random player names every time we hit the main menu. 44 ba.internal.reset_random_player_names() 45 46 # Reset achievements too (at least locally). 47 ba.app.config['Achievements'] = {} 48 49 t_delay_base = 0.0 50 t_delay_scale = 0.0 51 if not ba.app.did_menu_intro: 52 t_delay_base = 1.0 53 t_delay_scale = 1.0 54 55 model_opaque = ba.getmodel('level_select_button_opaque') 56 model_transparent = ba.getmodel('level_select_button_transparent') 57 mask_tex = ba.gettexture('mapPreviewMask') 58 59 y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0) 60 b_width = 250.0 61 b_height = 200.0 62 b_space = 280.0 63 b_v = 80.0 + y_extra 64 label_height = 130.0 + y_extra 65 img_width = 180.0 66 img_v = 158.0 + y_extra 67 68 if self._show_multiplayer: 69 tdelay = t_delay_base + t_delay_scale * 1.3 70 ba.textwidget( 71 parent=self._root_widget, 72 size=(0, 0), 73 position=(self._width * 0.5, self._height + y_extra - 44), 74 transition_delay=tdelay, 75 text=ba.Lstr(resource=self._r + '.singlePlayerExamplesText'), 76 flatness=1.0, 77 scale=1.2, 78 h_align='center', 79 v_align='center', 80 shadow=1.0, 81 ) 82 else: 83 tdelay = t_delay_base + t_delay_scale * 0.7 84 ba.textwidget( 85 parent=self._root_widget, 86 size=(0, 0), 87 position=(self._width * 0.5, self._height + y_extra - 34), 88 transition_delay=tdelay, 89 text=( 90 ba.Lstr( 91 resource='demoText', 92 fallback_resource='mainMenu.demoMenuText', 93 ) 94 if ba.app.demo_mode 95 else 'ARCADE' 96 ), 97 flatness=1.0, 98 scale=1.2, 99 h_align='center', 100 v_align='center', 101 shadow=1.0, 102 ) 103 h = self._width * 0.5 - b_space 104 tdelay = t_delay_base + t_delay_scale * 0.7 105 self._b1 = btn = ba.buttonwidget( 106 parent=self._root_widget, 107 autoselect=True, 108 size=(b_width, b_height), 109 on_activate_call=ba.Call(self._do_game, 'easy'), 110 transition_delay=tdelay, 111 position=(h - b_width * 0.5, b_v), 112 label='', 113 button_type='square', 114 ) 115 ba.textwidget( 116 parent=self._root_widget, 117 draw_controller=btn, 118 transition_delay=tdelay, 119 size=(0, 0), 120 position=(h, label_height), 121 maxwidth=b_width * 0.7, 122 text=ba.Lstr(resource=self._r + '.easyText'), 123 scale=1.3, 124 h_align='center', 125 v_align='center', 126 ) 127 ba.imagewidget( 128 parent=self._root_widget, 129 draw_controller=btn, 130 size=(img_width, 0.5 * img_width), 131 transition_delay=tdelay, 132 position=(h - img_width * 0.5, img_v), 133 texture=ba.gettexture('doomShroomPreview'), 134 model_opaque=model_opaque, 135 model_transparent=model_transparent, 136 mask_texture=mask_tex, 137 ) 138 h = self._width * 0.5 139 tdelay = t_delay_base + t_delay_scale * 0.65 140 self._b2 = btn = ba.buttonwidget( 141 parent=self._root_widget, 142 autoselect=True, 143 size=(b_width, b_height), 144 on_activate_call=ba.Call(self._do_game, 'medium'), 145 position=(h - b_width * 0.5, b_v), 146 label='', 147 button_type='square', 148 transition_delay=tdelay, 149 ) 150 ba.textwidget( 151 parent=self._root_widget, 152 draw_controller=btn, 153 transition_delay=tdelay, 154 size=(0, 0), 155 position=(h, label_height), 156 maxwidth=b_width * 0.7, 157 text=ba.Lstr(resource=self._r + '.mediumText'), 158 scale=1.3, 159 h_align='center', 160 v_align='center', 161 ) 162 ba.imagewidget( 163 parent=self._root_widget, 164 draw_controller=btn, 165 size=(img_width, 0.5 * img_width), 166 transition_delay=tdelay, 167 position=(h - img_width * 0.5, img_v), 168 texture=ba.gettexture('footballStadiumPreview'), 169 model_opaque=model_opaque, 170 model_transparent=model_transparent, 171 mask_texture=mask_tex, 172 ) 173 h = self._width * 0.5 + b_space 174 tdelay = t_delay_base + t_delay_scale * 0.6 175 self._b3 = btn = ba.buttonwidget( 176 parent=self._root_widget, 177 autoselect=True, 178 size=(b_width, b_height), 179 on_activate_call=ba.Call(self._do_game, 'hard'), 180 transition_delay=tdelay, 181 position=(h - b_width * 0.5, b_v), 182 label='', 183 button_type='square', 184 ) 185 ba.textwidget( 186 parent=self._root_widget, 187 draw_controller=btn, 188 transition_delay=tdelay, 189 size=(0, 0), 190 position=(h, label_height), 191 maxwidth=b_width * 0.7, 192 text='Hard', 193 scale=1.3, 194 h_align='center', 195 v_align='center', 196 ) 197 ba.imagewidget( 198 parent=self._root_widget, 199 draw_controller=btn, 200 transition_delay=tdelay, 201 size=(img_width, 0.5 * img_width), 202 position=(h - img_width * 0.5, img_v), 203 texture=ba.gettexture('courtyardPreview'), 204 model_opaque=model_opaque, 205 model_transparent=model_transparent, 206 mask_texture=mask_tex, 207 ) 208 if not ba.app.did_menu_intro: 209 ba.app.did_menu_intro = True 210 211 self._b4: ba.Widget | None 212 self._b5: ba.Widget | None 213 self._b6: ba.Widget | None 214 215 if bool(False): 216 ba.textwidget( 217 parent=self._root_widget, 218 size=(0, 0), 219 position=(self._width * 0.5, self._height + y_extra - 44), 220 transition_delay=tdelay, 221 text=ba.Lstr(resource=self._r + '.versusExamplesText'), 222 flatness=1.0, 223 scale=1.2, 224 h_align='center', 225 v_align='center', 226 shadow=1.0, 227 ) 228 h = self._width * 0.5 - b_space 229 tdelay = t_delay_base + t_delay_scale * 0.7 230 self._b4 = btn = ba.buttonwidget( 231 parent=self._root_widget, 232 autoselect=True, 233 size=(b_width, b_height), 234 on_activate_call=ba.Call(self._do_game, 'ctf'), 235 transition_delay=tdelay, 236 position=(h - b_width * 0.5, b_v), 237 label='', 238 button_type='square', 239 ) 240 ba.textwidget( 241 parent=self._root_widget, 242 draw_controller=btn, 243 transition_delay=tdelay, 244 size=(0, 0), 245 position=(h, label_height), 246 maxwidth=b_width * 0.7, 247 text=ba.Lstr(translate=('gameNames', 'Capture the Flag')), 248 scale=1.3, 249 h_align='center', 250 v_align='center', 251 ) 252 ba.imagewidget( 253 parent=self._root_widget, 254 draw_controller=btn, 255 size=(img_width, 0.5 * img_width), 256 transition_delay=tdelay, 257 position=(h - img_width * 0.5, img_v), 258 texture=ba.gettexture('bridgitPreview'), 259 model_opaque=model_opaque, 260 model_transparent=model_transparent, 261 mask_texture=mask_tex, 262 ) 263 264 h = self._width * 0.5 265 tdelay = t_delay_base + t_delay_scale * 0.65 266 self._b5 = btn = ba.buttonwidget( 267 parent=self._root_widget, 268 autoselect=True, 269 size=(b_width, b_height), 270 on_activate_call=ba.Call(self._do_game, 'hockey'), 271 position=(h - b_width * 0.5, b_v), 272 label='', 273 button_type='square', 274 transition_delay=tdelay, 275 ) 276 ba.textwidget( 277 parent=self._root_widget, 278 draw_controller=btn, 279 transition_delay=tdelay, 280 size=(0, 0), 281 position=(h, label_height), 282 maxwidth=b_width * 0.7, 283 text=ba.Lstr(translate=('gameNames', 'Hockey')), 284 scale=1.3, 285 h_align='center', 286 v_align='center', 287 ) 288 ba.imagewidget( 289 parent=self._root_widget, 290 draw_controller=btn, 291 size=(img_width, 0.5 * img_width), 292 transition_delay=tdelay, 293 position=(h - img_width * 0.5, img_v), 294 texture=ba.gettexture('hockeyStadiumPreview'), 295 model_opaque=model_opaque, 296 model_transparent=model_transparent, 297 mask_texture=mask_tex, 298 ) 299 h = self._width * 0.5 + b_space 300 tdelay = t_delay_base + t_delay_scale * 0.6 301 self._b6 = btn = ba.buttonwidget( 302 parent=self._root_widget, 303 autoselect=True, 304 size=(b_width, b_height), 305 on_activate_call=ba.Call(self._do_game, 'epic'), 306 transition_delay=tdelay, 307 position=(h - b_width * 0.5, b_v), 308 label='', 309 button_type='square', 310 ) 311 ba.textwidget( 312 parent=self._root_widget, 313 draw_controller=btn, 314 transition_delay=tdelay, 315 size=(0, 0), 316 position=(h, label_height), 317 maxwidth=b_width * 0.7, 318 text=ba.Lstr(resource=self._r + '.epicModeText'), 319 scale=1.3, 320 h_align='center', 321 v_align='center', 322 ) 323 ba.imagewidget( 324 parent=self._root_widget, 325 draw_controller=btn, 326 transition_delay=tdelay, 327 size=(img_width, 0.5 * img_width), 328 position=(h - img_width * 0.5, img_v), 329 texture=ba.gettexture('tipTopPreview'), 330 model_opaque=model_opaque, 331 model_transparent=model_transparent, 332 mask_texture=mask_tex, 333 ) 334 else: 335 self._b4 = self._b5 = self._b6 = None 336 337 self._b7: ba.Widget | None 338 if ba.app.arcade_mode: 339 self._b7 = ba.buttonwidget( 340 parent=self._root_widget, 341 autoselect=True, 342 size=(b_width, 50), 343 color=(0.45, 0.55, 0.45), 344 textcolor=(0.7, 0.8, 0.7), 345 scale=0.5, 346 position=(self._width * 0.5 - 60.0, b_v - 70.0), 347 transition_delay=tdelay, 348 label=ba.Lstr(resource=self._r + '.fullMenuText'), 349 on_activate_call=self._do_full_menu, 350 ) 351 else: 352 self._b7 = None 353 self._restore_state() 354 self._update() 355 self._update_timer = ba.Timer( 356 1.0, 357 ba.WeakCall(self._update), 358 timetype=ba.TimeType.REAL, 359 repeat=True, 360 ) 361 362 def _restore_state(self) -> None: 363 sel_name = ba.app.ui.window_states.get(type(self)) 364 sel: ba.Widget | None 365 if sel_name == 'b1': 366 sel = self._b1 367 elif sel_name == 'b2': 368 sel = self._b2 369 elif sel_name == 'b3': 370 sel = self._b3 371 elif sel_name == 'b4': 372 sel = self._b4 373 elif sel_name == 'b5': 374 sel = self._b5 375 elif sel_name == 'b6': 376 sel = self._b6 377 elif sel_name == 'b7': 378 sel = self._b7 379 else: 380 sel = self._b1 381 if sel: 382 ba.containerwidget(edit=self._root_widget, selected_child=sel) 383 384 def _save_state(self) -> None: 385 sel = self._root_widget.get_selected_child() 386 if sel == self._b1: 387 sel_name = 'b1' 388 elif sel == self._b2: 389 sel_name = 'b2' 390 elif sel == self._b3: 391 sel_name = 'b3' 392 elif sel == self._b4: 393 sel_name = 'b4' 394 elif sel == self._b5: 395 sel_name = 'b5' 396 elif sel == self._b6: 397 sel_name = 'b6' 398 elif sel == self._b7: 399 sel_name = 'b7' 400 else: 401 sel_name = 'b1' 402 ba.app.ui.window_states[type(self)] = sel_name 403 404 def _update(self) -> None: 405 # Kiosk-mode is designed to be used signed-out... try for force 406 # the issue. 407 if ba.internal.get_v1_account_state() == 'signed_in': 408 # _bs.sign_out() 409 # FIXME: Try to delete player profiles here too. 410 pass 411 else: 412 # Also make sure there's no player profiles. 413 appconfig = ba.app.config 414 appconfig['Player Profiles'] = {} 415 416 def _do_game(self, mode: str) -> None: 417 self._save_state() 418 if mode in ['epic', 'ctf', 'hockey']: 419 appconfig = ba.app.config 420 if 'Team Tournament Playlists' not in appconfig: 421 appconfig['Team Tournament Playlists'] = {} 422 if 'Free-for-All Playlists' not in appconfig: 423 appconfig['Free-for-All Playlists'] = {} 424 appconfig['Show Tutorial'] = False 425 if mode == 'epic': 426 appconfig['Free-for-All Playlists']['Just Epic Elim'] = [ 427 { 428 'settings': { 429 'Epic Mode': 1, 430 'Lives Per Player': 1, 431 'Respawn Times': 1.0, 432 'Time Limit': 0, 433 'map': 'Tip Top', 434 }, 435 'type': 'bs_elimination.EliminationGame', 436 } 437 ] 438 appconfig['Free-for-All Playlist Selection'] = 'Just Epic Elim' 439 ba.internal.fade_screen( 440 False, 441 endcall=ba.Call( 442 ba.pushcall, 443 ba.Call( 444 ba.internal.new_host_session, ba.FreeForAllSession 445 ), 446 ), 447 ) 448 else: 449 if mode == 'ctf': 450 appconfig['Team Tournament Playlists']['Just CTF'] = [ 451 { 452 'settings': { 453 'Epic Mode': False, 454 'Flag Idle Return Time': 30, 455 'Flag Touch Return Time': 0, 456 'Respawn Times': 1.0, 457 'Score to Win': 3, 458 'Time Limit': 0, 459 'map': 'Bridgit', 460 }, 461 'type': 'bs_capture_the_flag.CTFGame', 462 } 463 ] 464 appconfig['Team Tournament Playlist Selection'] = 'Just CTF' 465 else: 466 appconfig['Team Tournament Playlists']['Just Hockey'] = [ 467 { 468 'settings': { 469 'Respawn Times': 1.0, 470 'Score to Win': 1, 471 'Time Limit': 0, 472 'map': 'Hockey Stadium', 473 }, 474 'type': 'bs_hockey.HockeyGame', 475 } 476 ] 477 appconfig[ 478 'Team Tournament Playlist Selection' 479 ] = 'Just Hockey' 480 ba.internal.fade_screen( 481 False, 482 endcall=ba.Call( 483 ba.pushcall, 484 ba.Call( 485 ba.internal.new_host_session, ba.DualTeamSession 486 ), 487 ), 488 ) 489 ba.containerwidget(edit=self._root_widget, transition='out_left') 490 return 491 492 game = ( 493 'Easy:Onslaught Training' 494 if mode == 'easy' 495 else 'Easy:Rookie Football' 496 if mode == 'medium' 497 else 'Easy:Uber Onslaught' 498 ) 499 cfg = ba.app.config 500 cfg['Selected Coop Game'] = game 501 cfg.commit() 502 if ba.app.launch_coop_game(game, force=True): 503 ba.containerwidget(edit=self._root_widget, transition='out_left') 504 505 def _do_full_menu(self) -> None: 506 from bastd.ui.mainmenu import MainMenuWindow 507 508 self._save_state() 509 ba.containerwidget(edit=self._root_widget, transition='out_left') 510 ba.app.did_menu_intro = True # prevent delayed transition-in 511 ba.app.ui.set_main_menu_window(MainMenuWindow().get_root_widget())
class
KioskWindow(ba.ui.Window):
17class KioskWindow(ba.Window): 18 """Kiosk mode window.""" 19 20 def __init__(self, transition: str = 'in_right'): 21 # pylint: disable=too-many-locals, too-many-statements 22 from bastd.ui.confirm import QuitWindow 23 24 self._width = 720.0 25 self._height = 340.0 26 27 def _do_cancel() -> None: 28 QuitWindow(swish=True, back=True) 29 30 super().__init__( 31 root_widget=ba.containerwidget( 32 size=(self._width, self._height), 33 transition=transition, 34 on_cancel_call=_do_cancel, 35 background=False, 36 stack_offset=(0, -130), 37 ) 38 ) 39 40 self._r = 'kioskWindow' 41 42 self._show_multiplayer = False 43 44 # Let's reset all random player names every time we hit the main menu. 45 ba.internal.reset_random_player_names() 46 47 # Reset achievements too (at least locally). 48 ba.app.config['Achievements'] = {} 49 50 t_delay_base = 0.0 51 t_delay_scale = 0.0 52 if not ba.app.did_menu_intro: 53 t_delay_base = 1.0 54 t_delay_scale = 1.0 55 56 model_opaque = ba.getmodel('level_select_button_opaque') 57 model_transparent = ba.getmodel('level_select_button_transparent') 58 mask_tex = ba.gettexture('mapPreviewMask') 59 60 y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0) 61 b_width = 250.0 62 b_height = 200.0 63 b_space = 280.0 64 b_v = 80.0 + y_extra 65 label_height = 130.0 + y_extra 66 img_width = 180.0 67 img_v = 158.0 + y_extra 68 69 if self._show_multiplayer: 70 tdelay = t_delay_base + t_delay_scale * 1.3 71 ba.textwidget( 72 parent=self._root_widget, 73 size=(0, 0), 74 position=(self._width * 0.5, self._height + y_extra - 44), 75 transition_delay=tdelay, 76 text=ba.Lstr(resource=self._r + '.singlePlayerExamplesText'), 77 flatness=1.0, 78 scale=1.2, 79 h_align='center', 80 v_align='center', 81 shadow=1.0, 82 ) 83 else: 84 tdelay = t_delay_base + t_delay_scale * 0.7 85 ba.textwidget( 86 parent=self._root_widget, 87 size=(0, 0), 88 position=(self._width * 0.5, self._height + y_extra - 34), 89 transition_delay=tdelay, 90 text=( 91 ba.Lstr( 92 resource='demoText', 93 fallback_resource='mainMenu.demoMenuText', 94 ) 95 if ba.app.demo_mode 96 else 'ARCADE' 97 ), 98 flatness=1.0, 99 scale=1.2, 100 h_align='center', 101 v_align='center', 102 shadow=1.0, 103 ) 104 h = self._width * 0.5 - b_space 105 tdelay = t_delay_base + t_delay_scale * 0.7 106 self._b1 = btn = ba.buttonwidget( 107 parent=self._root_widget, 108 autoselect=True, 109 size=(b_width, b_height), 110 on_activate_call=ba.Call(self._do_game, 'easy'), 111 transition_delay=tdelay, 112 position=(h - b_width * 0.5, b_v), 113 label='', 114 button_type='square', 115 ) 116 ba.textwidget( 117 parent=self._root_widget, 118 draw_controller=btn, 119 transition_delay=tdelay, 120 size=(0, 0), 121 position=(h, label_height), 122 maxwidth=b_width * 0.7, 123 text=ba.Lstr(resource=self._r + '.easyText'), 124 scale=1.3, 125 h_align='center', 126 v_align='center', 127 ) 128 ba.imagewidget( 129 parent=self._root_widget, 130 draw_controller=btn, 131 size=(img_width, 0.5 * img_width), 132 transition_delay=tdelay, 133 position=(h - img_width * 0.5, img_v), 134 texture=ba.gettexture('doomShroomPreview'), 135 model_opaque=model_opaque, 136 model_transparent=model_transparent, 137 mask_texture=mask_tex, 138 ) 139 h = self._width * 0.5 140 tdelay = t_delay_base + t_delay_scale * 0.65 141 self._b2 = btn = ba.buttonwidget( 142 parent=self._root_widget, 143 autoselect=True, 144 size=(b_width, b_height), 145 on_activate_call=ba.Call(self._do_game, 'medium'), 146 position=(h - b_width * 0.5, b_v), 147 label='', 148 button_type='square', 149 transition_delay=tdelay, 150 ) 151 ba.textwidget( 152 parent=self._root_widget, 153 draw_controller=btn, 154 transition_delay=tdelay, 155 size=(0, 0), 156 position=(h, label_height), 157 maxwidth=b_width * 0.7, 158 text=ba.Lstr(resource=self._r + '.mediumText'), 159 scale=1.3, 160 h_align='center', 161 v_align='center', 162 ) 163 ba.imagewidget( 164 parent=self._root_widget, 165 draw_controller=btn, 166 size=(img_width, 0.5 * img_width), 167 transition_delay=tdelay, 168 position=(h - img_width * 0.5, img_v), 169 texture=ba.gettexture('footballStadiumPreview'), 170 model_opaque=model_opaque, 171 model_transparent=model_transparent, 172 mask_texture=mask_tex, 173 ) 174 h = self._width * 0.5 + b_space 175 tdelay = t_delay_base + t_delay_scale * 0.6 176 self._b3 = btn = ba.buttonwidget( 177 parent=self._root_widget, 178 autoselect=True, 179 size=(b_width, b_height), 180 on_activate_call=ba.Call(self._do_game, 'hard'), 181 transition_delay=tdelay, 182 position=(h - b_width * 0.5, b_v), 183 label='', 184 button_type='square', 185 ) 186 ba.textwidget( 187 parent=self._root_widget, 188 draw_controller=btn, 189 transition_delay=tdelay, 190 size=(0, 0), 191 position=(h, label_height), 192 maxwidth=b_width * 0.7, 193 text='Hard', 194 scale=1.3, 195 h_align='center', 196 v_align='center', 197 ) 198 ba.imagewidget( 199 parent=self._root_widget, 200 draw_controller=btn, 201 transition_delay=tdelay, 202 size=(img_width, 0.5 * img_width), 203 position=(h - img_width * 0.5, img_v), 204 texture=ba.gettexture('courtyardPreview'), 205 model_opaque=model_opaque, 206 model_transparent=model_transparent, 207 mask_texture=mask_tex, 208 ) 209 if not ba.app.did_menu_intro: 210 ba.app.did_menu_intro = True 211 212 self._b4: ba.Widget | None 213 self._b5: ba.Widget | None 214 self._b6: ba.Widget | None 215 216 if bool(False): 217 ba.textwidget( 218 parent=self._root_widget, 219 size=(0, 0), 220 position=(self._width * 0.5, self._height + y_extra - 44), 221 transition_delay=tdelay, 222 text=ba.Lstr(resource=self._r + '.versusExamplesText'), 223 flatness=1.0, 224 scale=1.2, 225 h_align='center', 226 v_align='center', 227 shadow=1.0, 228 ) 229 h = self._width * 0.5 - b_space 230 tdelay = t_delay_base + t_delay_scale * 0.7 231 self._b4 = btn = ba.buttonwidget( 232 parent=self._root_widget, 233 autoselect=True, 234 size=(b_width, b_height), 235 on_activate_call=ba.Call(self._do_game, 'ctf'), 236 transition_delay=tdelay, 237 position=(h - b_width * 0.5, b_v), 238 label='', 239 button_type='square', 240 ) 241 ba.textwidget( 242 parent=self._root_widget, 243 draw_controller=btn, 244 transition_delay=tdelay, 245 size=(0, 0), 246 position=(h, label_height), 247 maxwidth=b_width * 0.7, 248 text=ba.Lstr(translate=('gameNames', 'Capture the Flag')), 249 scale=1.3, 250 h_align='center', 251 v_align='center', 252 ) 253 ba.imagewidget( 254 parent=self._root_widget, 255 draw_controller=btn, 256 size=(img_width, 0.5 * img_width), 257 transition_delay=tdelay, 258 position=(h - img_width * 0.5, img_v), 259 texture=ba.gettexture('bridgitPreview'), 260 model_opaque=model_opaque, 261 model_transparent=model_transparent, 262 mask_texture=mask_tex, 263 ) 264 265 h = self._width * 0.5 266 tdelay = t_delay_base + t_delay_scale * 0.65 267 self._b5 = btn = ba.buttonwidget( 268 parent=self._root_widget, 269 autoselect=True, 270 size=(b_width, b_height), 271 on_activate_call=ba.Call(self._do_game, 'hockey'), 272 position=(h - b_width * 0.5, b_v), 273 label='', 274 button_type='square', 275 transition_delay=tdelay, 276 ) 277 ba.textwidget( 278 parent=self._root_widget, 279 draw_controller=btn, 280 transition_delay=tdelay, 281 size=(0, 0), 282 position=(h, label_height), 283 maxwidth=b_width * 0.7, 284 text=ba.Lstr(translate=('gameNames', 'Hockey')), 285 scale=1.3, 286 h_align='center', 287 v_align='center', 288 ) 289 ba.imagewidget( 290 parent=self._root_widget, 291 draw_controller=btn, 292 size=(img_width, 0.5 * img_width), 293 transition_delay=tdelay, 294 position=(h - img_width * 0.5, img_v), 295 texture=ba.gettexture('hockeyStadiumPreview'), 296 model_opaque=model_opaque, 297 model_transparent=model_transparent, 298 mask_texture=mask_tex, 299 ) 300 h = self._width * 0.5 + b_space 301 tdelay = t_delay_base + t_delay_scale * 0.6 302 self._b6 = btn = ba.buttonwidget( 303 parent=self._root_widget, 304 autoselect=True, 305 size=(b_width, b_height), 306 on_activate_call=ba.Call(self._do_game, 'epic'), 307 transition_delay=tdelay, 308 position=(h - b_width * 0.5, b_v), 309 label='', 310 button_type='square', 311 ) 312 ba.textwidget( 313 parent=self._root_widget, 314 draw_controller=btn, 315 transition_delay=tdelay, 316 size=(0, 0), 317 position=(h, label_height), 318 maxwidth=b_width * 0.7, 319 text=ba.Lstr(resource=self._r + '.epicModeText'), 320 scale=1.3, 321 h_align='center', 322 v_align='center', 323 ) 324 ba.imagewidget( 325 parent=self._root_widget, 326 draw_controller=btn, 327 transition_delay=tdelay, 328 size=(img_width, 0.5 * img_width), 329 position=(h - img_width * 0.5, img_v), 330 texture=ba.gettexture('tipTopPreview'), 331 model_opaque=model_opaque, 332 model_transparent=model_transparent, 333 mask_texture=mask_tex, 334 ) 335 else: 336 self._b4 = self._b5 = self._b6 = None 337 338 self._b7: ba.Widget | None 339 if ba.app.arcade_mode: 340 self._b7 = ba.buttonwidget( 341 parent=self._root_widget, 342 autoselect=True, 343 size=(b_width, 50), 344 color=(0.45, 0.55, 0.45), 345 textcolor=(0.7, 0.8, 0.7), 346 scale=0.5, 347 position=(self._width * 0.5 - 60.0, b_v - 70.0), 348 transition_delay=tdelay, 349 label=ba.Lstr(resource=self._r + '.fullMenuText'), 350 on_activate_call=self._do_full_menu, 351 ) 352 else: 353 self._b7 = None 354 self._restore_state() 355 self._update() 356 self._update_timer = ba.Timer( 357 1.0, 358 ba.WeakCall(self._update), 359 timetype=ba.TimeType.REAL, 360 repeat=True, 361 ) 362 363 def _restore_state(self) -> None: 364 sel_name = ba.app.ui.window_states.get(type(self)) 365 sel: ba.Widget | None 366 if sel_name == 'b1': 367 sel = self._b1 368 elif sel_name == 'b2': 369 sel = self._b2 370 elif sel_name == 'b3': 371 sel = self._b3 372 elif sel_name == 'b4': 373 sel = self._b4 374 elif sel_name == 'b5': 375 sel = self._b5 376 elif sel_name == 'b6': 377 sel = self._b6 378 elif sel_name == 'b7': 379 sel = self._b7 380 else: 381 sel = self._b1 382 if sel: 383 ba.containerwidget(edit=self._root_widget, selected_child=sel) 384 385 def _save_state(self) -> None: 386 sel = self._root_widget.get_selected_child() 387 if sel == self._b1: 388 sel_name = 'b1' 389 elif sel == self._b2: 390 sel_name = 'b2' 391 elif sel == self._b3: 392 sel_name = 'b3' 393 elif sel == self._b4: 394 sel_name = 'b4' 395 elif sel == self._b5: 396 sel_name = 'b5' 397 elif sel == self._b6: 398 sel_name = 'b6' 399 elif sel == self._b7: 400 sel_name = 'b7' 401 else: 402 sel_name = 'b1' 403 ba.app.ui.window_states[type(self)] = sel_name 404 405 def _update(self) -> None: 406 # Kiosk-mode is designed to be used signed-out... try for force 407 # the issue. 408 if ba.internal.get_v1_account_state() == 'signed_in': 409 # _bs.sign_out() 410 # FIXME: Try to delete player profiles here too. 411 pass 412 else: 413 # Also make sure there's no player profiles. 414 appconfig = ba.app.config 415 appconfig['Player Profiles'] = {} 416 417 def _do_game(self, mode: str) -> None: 418 self._save_state() 419 if mode in ['epic', 'ctf', 'hockey']: 420 appconfig = ba.app.config 421 if 'Team Tournament Playlists' not in appconfig: 422 appconfig['Team Tournament Playlists'] = {} 423 if 'Free-for-All Playlists' not in appconfig: 424 appconfig['Free-for-All Playlists'] = {} 425 appconfig['Show Tutorial'] = False 426 if mode == 'epic': 427 appconfig['Free-for-All Playlists']['Just Epic Elim'] = [ 428 { 429 'settings': { 430 'Epic Mode': 1, 431 'Lives Per Player': 1, 432 'Respawn Times': 1.0, 433 'Time Limit': 0, 434 'map': 'Tip Top', 435 }, 436 'type': 'bs_elimination.EliminationGame', 437 } 438 ] 439 appconfig['Free-for-All Playlist Selection'] = 'Just Epic Elim' 440 ba.internal.fade_screen( 441 False, 442 endcall=ba.Call( 443 ba.pushcall, 444 ba.Call( 445 ba.internal.new_host_session, ba.FreeForAllSession 446 ), 447 ), 448 ) 449 else: 450 if mode == 'ctf': 451 appconfig['Team Tournament Playlists']['Just CTF'] = [ 452 { 453 'settings': { 454 'Epic Mode': False, 455 'Flag Idle Return Time': 30, 456 'Flag Touch Return Time': 0, 457 'Respawn Times': 1.0, 458 'Score to Win': 3, 459 'Time Limit': 0, 460 'map': 'Bridgit', 461 }, 462 'type': 'bs_capture_the_flag.CTFGame', 463 } 464 ] 465 appconfig['Team Tournament Playlist Selection'] = 'Just CTF' 466 else: 467 appconfig['Team Tournament Playlists']['Just Hockey'] = [ 468 { 469 'settings': { 470 'Respawn Times': 1.0, 471 'Score to Win': 1, 472 'Time Limit': 0, 473 'map': 'Hockey Stadium', 474 }, 475 'type': 'bs_hockey.HockeyGame', 476 } 477 ] 478 appconfig[ 479 'Team Tournament Playlist Selection' 480 ] = 'Just Hockey' 481 ba.internal.fade_screen( 482 False, 483 endcall=ba.Call( 484 ba.pushcall, 485 ba.Call( 486 ba.internal.new_host_session, ba.DualTeamSession 487 ), 488 ), 489 ) 490 ba.containerwidget(edit=self._root_widget, transition='out_left') 491 return 492 493 game = ( 494 'Easy:Onslaught Training' 495 if mode == 'easy' 496 else 'Easy:Rookie Football' 497 if mode == 'medium' 498 else 'Easy:Uber Onslaught' 499 ) 500 cfg = ba.app.config 501 cfg['Selected Coop Game'] = game 502 cfg.commit() 503 if ba.app.launch_coop_game(game, force=True): 504 ba.containerwidget(edit=self._root_widget, transition='out_left') 505 506 def _do_full_menu(self) -> None: 507 from bastd.ui.mainmenu import MainMenuWindow 508 509 self._save_state() 510 ba.containerwidget(edit=self._root_widget, transition='out_left') 511 ba.app.did_menu_intro = True # prevent delayed transition-in 512 ba.app.ui.set_main_menu_window(MainMenuWindow().get_root_widget())
Kiosk mode window.
KioskWindow(transition: str = 'in_right')
20 def __init__(self, transition: str = 'in_right'): 21 # pylint: disable=too-many-locals, too-many-statements 22 from bastd.ui.confirm import QuitWindow 23 24 self._width = 720.0 25 self._height = 340.0 26 27 def _do_cancel() -> None: 28 QuitWindow(swish=True, back=True) 29 30 super().__init__( 31 root_widget=ba.containerwidget( 32 size=(self._width, self._height), 33 transition=transition, 34 on_cancel_call=_do_cancel, 35 background=False, 36 stack_offset=(0, -130), 37 ) 38 ) 39 40 self._r = 'kioskWindow' 41 42 self._show_multiplayer = False 43 44 # Let's reset all random player names every time we hit the main menu. 45 ba.internal.reset_random_player_names() 46 47 # Reset achievements too (at least locally). 48 ba.app.config['Achievements'] = {} 49 50 t_delay_base = 0.0 51 t_delay_scale = 0.0 52 if not ba.app.did_menu_intro: 53 t_delay_base = 1.0 54 t_delay_scale = 1.0 55 56 model_opaque = ba.getmodel('level_select_button_opaque') 57 model_transparent = ba.getmodel('level_select_button_transparent') 58 mask_tex = ba.gettexture('mapPreviewMask') 59 60 y_extra = 130.0 + (0.0 if self._show_multiplayer else -130.0) 61 b_width = 250.0 62 b_height = 200.0 63 b_space = 280.0 64 b_v = 80.0 + y_extra 65 label_height = 130.0 + y_extra 66 img_width = 180.0 67 img_v = 158.0 + y_extra 68 69 if self._show_multiplayer: 70 tdelay = t_delay_base + t_delay_scale * 1.3 71 ba.textwidget( 72 parent=self._root_widget, 73 size=(0, 0), 74 position=(self._width * 0.5, self._height + y_extra - 44), 75 transition_delay=tdelay, 76 text=ba.Lstr(resource=self._r + '.singlePlayerExamplesText'), 77 flatness=1.0, 78 scale=1.2, 79 h_align='center', 80 v_align='center', 81 shadow=1.0, 82 ) 83 else: 84 tdelay = t_delay_base + t_delay_scale * 0.7 85 ba.textwidget( 86 parent=self._root_widget, 87 size=(0, 0), 88 position=(self._width * 0.5, self._height + y_extra - 34), 89 transition_delay=tdelay, 90 text=( 91 ba.Lstr( 92 resource='demoText', 93 fallback_resource='mainMenu.demoMenuText', 94 ) 95 if ba.app.demo_mode 96 else 'ARCADE' 97 ), 98 flatness=1.0, 99 scale=1.2, 100 h_align='center', 101 v_align='center', 102 shadow=1.0, 103 ) 104 h = self._width * 0.5 - b_space 105 tdelay = t_delay_base + t_delay_scale * 0.7 106 self._b1 = btn = ba.buttonwidget( 107 parent=self._root_widget, 108 autoselect=True, 109 size=(b_width, b_height), 110 on_activate_call=ba.Call(self._do_game, 'easy'), 111 transition_delay=tdelay, 112 position=(h - b_width * 0.5, b_v), 113 label='', 114 button_type='square', 115 ) 116 ba.textwidget( 117 parent=self._root_widget, 118 draw_controller=btn, 119 transition_delay=tdelay, 120 size=(0, 0), 121 position=(h, label_height), 122 maxwidth=b_width * 0.7, 123 text=ba.Lstr(resource=self._r + '.easyText'), 124 scale=1.3, 125 h_align='center', 126 v_align='center', 127 ) 128 ba.imagewidget( 129 parent=self._root_widget, 130 draw_controller=btn, 131 size=(img_width, 0.5 * img_width), 132 transition_delay=tdelay, 133 position=(h - img_width * 0.5, img_v), 134 texture=ba.gettexture('doomShroomPreview'), 135 model_opaque=model_opaque, 136 model_transparent=model_transparent, 137 mask_texture=mask_tex, 138 ) 139 h = self._width * 0.5 140 tdelay = t_delay_base + t_delay_scale * 0.65 141 self._b2 = btn = ba.buttonwidget( 142 parent=self._root_widget, 143 autoselect=True, 144 size=(b_width, b_height), 145 on_activate_call=ba.Call(self._do_game, 'medium'), 146 position=(h - b_width * 0.5, b_v), 147 label='', 148 button_type='square', 149 transition_delay=tdelay, 150 ) 151 ba.textwidget( 152 parent=self._root_widget, 153 draw_controller=btn, 154 transition_delay=tdelay, 155 size=(0, 0), 156 position=(h, label_height), 157 maxwidth=b_width * 0.7, 158 text=ba.Lstr(resource=self._r + '.mediumText'), 159 scale=1.3, 160 h_align='center', 161 v_align='center', 162 ) 163 ba.imagewidget( 164 parent=self._root_widget, 165 draw_controller=btn, 166 size=(img_width, 0.5 * img_width), 167 transition_delay=tdelay, 168 position=(h - img_width * 0.5, img_v), 169 texture=ba.gettexture('footballStadiumPreview'), 170 model_opaque=model_opaque, 171 model_transparent=model_transparent, 172 mask_texture=mask_tex, 173 ) 174 h = self._width * 0.5 + b_space 175 tdelay = t_delay_base + t_delay_scale * 0.6 176 self._b3 = btn = ba.buttonwidget( 177 parent=self._root_widget, 178 autoselect=True, 179 size=(b_width, b_height), 180 on_activate_call=ba.Call(self._do_game, 'hard'), 181 transition_delay=tdelay, 182 position=(h - b_width * 0.5, b_v), 183 label='', 184 button_type='square', 185 ) 186 ba.textwidget( 187 parent=self._root_widget, 188 draw_controller=btn, 189 transition_delay=tdelay, 190 size=(0, 0), 191 position=(h, label_height), 192 maxwidth=b_width * 0.7, 193 text='Hard', 194 scale=1.3, 195 h_align='center', 196 v_align='center', 197 ) 198 ba.imagewidget( 199 parent=self._root_widget, 200 draw_controller=btn, 201 transition_delay=tdelay, 202 size=(img_width, 0.5 * img_width), 203 position=(h - img_width * 0.5, img_v), 204 texture=ba.gettexture('courtyardPreview'), 205 model_opaque=model_opaque, 206 model_transparent=model_transparent, 207 mask_texture=mask_tex, 208 ) 209 if not ba.app.did_menu_intro: 210 ba.app.did_menu_intro = True 211 212 self._b4: ba.Widget | None 213 self._b5: ba.Widget | None 214 self._b6: ba.Widget | None 215 216 if bool(False): 217 ba.textwidget( 218 parent=self._root_widget, 219 size=(0, 0), 220 position=(self._width * 0.5, self._height + y_extra - 44), 221 transition_delay=tdelay, 222 text=ba.Lstr(resource=self._r + '.versusExamplesText'), 223 flatness=1.0, 224 scale=1.2, 225 h_align='center', 226 v_align='center', 227 shadow=1.0, 228 ) 229 h = self._width * 0.5 - b_space 230 tdelay = t_delay_base + t_delay_scale * 0.7 231 self._b4 = btn = ba.buttonwidget( 232 parent=self._root_widget, 233 autoselect=True, 234 size=(b_width, b_height), 235 on_activate_call=ba.Call(self._do_game, 'ctf'), 236 transition_delay=tdelay, 237 position=(h - b_width * 0.5, b_v), 238 label='', 239 button_type='square', 240 ) 241 ba.textwidget( 242 parent=self._root_widget, 243 draw_controller=btn, 244 transition_delay=tdelay, 245 size=(0, 0), 246 position=(h, label_height), 247 maxwidth=b_width * 0.7, 248 text=ba.Lstr(translate=('gameNames', 'Capture the Flag')), 249 scale=1.3, 250 h_align='center', 251 v_align='center', 252 ) 253 ba.imagewidget( 254 parent=self._root_widget, 255 draw_controller=btn, 256 size=(img_width, 0.5 * img_width), 257 transition_delay=tdelay, 258 position=(h - img_width * 0.5, img_v), 259 texture=ba.gettexture('bridgitPreview'), 260 model_opaque=model_opaque, 261 model_transparent=model_transparent, 262 mask_texture=mask_tex, 263 ) 264 265 h = self._width * 0.5 266 tdelay = t_delay_base + t_delay_scale * 0.65 267 self._b5 = btn = ba.buttonwidget( 268 parent=self._root_widget, 269 autoselect=True, 270 size=(b_width, b_height), 271 on_activate_call=ba.Call(self._do_game, 'hockey'), 272 position=(h - b_width * 0.5, b_v), 273 label='', 274 button_type='square', 275 transition_delay=tdelay, 276 ) 277 ba.textwidget( 278 parent=self._root_widget, 279 draw_controller=btn, 280 transition_delay=tdelay, 281 size=(0, 0), 282 position=(h, label_height), 283 maxwidth=b_width * 0.7, 284 text=ba.Lstr(translate=('gameNames', 'Hockey')), 285 scale=1.3, 286 h_align='center', 287 v_align='center', 288 ) 289 ba.imagewidget( 290 parent=self._root_widget, 291 draw_controller=btn, 292 size=(img_width, 0.5 * img_width), 293 transition_delay=tdelay, 294 position=(h - img_width * 0.5, img_v), 295 texture=ba.gettexture('hockeyStadiumPreview'), 296 model_opaque=model_opaque, 297 model_transparent=model_transparent, 298 mask_texture=mask_tex, 299 ) 300 h = self._width * 0.5 + b_space 301 tdelay = t_delay_base + t_delay_scale * 0.6 302 self._b6 = btn = ba.buttonwidget( 303 parent=self._root_widget, 304 autoselect=True, 305 size=(b_width, b_height), 306 on_activate_call=ba.Call(self._do_game, 'epic'), 307 transition_delay=tdelay, 308 position=(h - b_width * 0.5, b_v), 309 label='', 310 button_type='square', 311 ) 312 ba.textwidget( 313 parent=self._root_widget, 314 draw_controller=btn, 315 transition_delay=tdelay, 316 size=(0, 0), 317 position=(h, label_height), 318 maxwidth=b_width * 0.7, 319 text=ba.Lstr(resource=self._r + '.epicModeText'), 320 scale=1.3, 321 h_align='center', 322 v_align='center', 323 ) 324 ba.imagewidget( 325 parent=self._root_widget, 326 draw_controller=btn, 327 transition_delay=tdelay, 328 size=(img_width, 0.5 * img_width), 329 position=(h - img_width * 0.5, img_v), 330 texture=ba.gettexture('tipTopPreview'), 331 model_opaque=model_opaque, 332 model_transparent=model_transparent, 333 mask_texture=mask_tex, 334 ) 335 else: 336 self._b4 = self._b5 = self._b6 = None 337 338 self._b7: ba.Widget | None 339 if ba.app.arcade_mode: 340 self._b7 = ba.buttonwidget( 341 parent=self._root_widget, 342 autoselect=True, 343 size=(b_width, 50), 344 color=(0.45, 0.55, 0.45), 345 textcolor=(0.7, 0.8, 0.7), 346 scale=0.5, 347 position=(self._width * 0.5 - 60.0, b_v - 70.0), 348 transition_delay=tdelay, 349 label=ba.Lstr(resource=self._r + '.fullMenuText'), 350 on_activate_call=self._do_full_menu, 351 ) 352 else: 353 self._b7 = None 354 self._restore_state() 355 self._update() 356 self._update_timer = ba.Timer( 357 1.0, 358 ba.WeakCall(self._update), 359 timetype=ba.TimeType.REAL, 360 repeat=True, 361 )
Inherited Members
- ba.ui.Window
- get_root_widget