bauiv1lib.coop.tournamentbutton
Defines button for co-op games.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Defines button for co-op games.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8import copy 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from typing import Any, Callable 14 15 16class TournamentButton: 17 """Button showing a tournament in coop window.""" 18 19 def __init__( 20 self, 21 parent: bui.Widget, 22 x: float, 23 y: float, 24 select: bool, 25 on_pressed: Callable[[TournamentButton], None], 26 ) -> None: 27 # pylint: disable=too-many-positional-arguments 28 self._r = 'coopSelectWindow' 29 sclx = 300 30 scly = 195.0 31 self.on_pressed = on_pressed 32 self.lsbt = bui.getmesh('level_select_button_transparent') 33 self.lsbo = bui.getmesh('level_select_button_opaque') 34 self.allow_ads = False 35 self.tournament_id: str | None = None 36 self.time_remaining: int = 0 37 self.has_time_remaining: bool = False 38 self.leader: Any = None 39 self.required_league: str | None = None 40 self.button = btn = bui.buttonwidget( 41 parent=parent, 42 position=(x + 23, y + 4), 43 size=(sclx, scly), 44 label='', 45 button_type='square', 46 autoselect=True, 47 on_activate_call=bui.WeakCall(self._pressed), 48 ) 49 bui.widget( 50 edit=btn, 51 show_buffer_bottom=50, 52 show_buffer_top=50, 53 show_buffer_left=400, 54 show_buffer_right=200, 55 ) 56 if select: 57 bui.containerwidget( 58 edit=parent, selected_child=btn, visible_child=btn 59 ) 60 image_width = sclx * 0.85 * 0.75 61 62 self.image = bui.imagewidget( 63 parent=parent, 64 draw_controller=btn, 65 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 66 size=(image_width, image_width * 0.5), 67 mesh_transparent=self.lsbt, 68 mesh_opaque=self.lsbo, 69 texture=bui.gettexture('black'), 70 opacity=0.2, 71 mask_texture=bui.gettexture('mapPreviewMask'), 72 ) 73 74 self.lock_image = bui.imagewidget( 75 parent=parent, 76 draw_controller=btn, 77 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 78 size=(image_width * 0.5, image_width * 0.5), 79 texture=bui.gettexture('lock'), 80 opacity=0.0, 81 ) 82 83 self.button_text = bui.textwidget( 84 parent=parent, 85 draw_controller=btn, 86 position=(x + 20 + sclx * 0.5, y + scly - 35), 87 size=(0, 0), 88 h_align='center', 89 text='-', 90 v_align='center', 91 maxwidth=sclx * 0.76, 92 scale=0.85, 93 color=(0.8, 1.0, 0.8, 1.0), 94 ) 95 96 header_color = (0.43, 0.4, 0.5, 1) 97 value_color = (0.6, 0.6, 0.6, 1) 98 99 x_offs = 0 100 bui.textwidget( 101 parent=parent, 102 draw_controller=btn, 103 position=(x + 360, y + scly - 20), 104 size=(0, 0), 105 h_align='center', 106 text=bui.Lstr(resource=f'{self._r}.entryFeeText'), 107 v_align='center', 108 maxwidth=100, 109 scale=0.9, 110 color=header_color, 111 flatness=1.0, 112 ) 113 114 self.entry_fee_text_top = bui.textwidget( 115 parent=parent, 116 draw_controller=btn, 117 position=(x + 360, y + scly - 60), 118 size=(0, 0), 119 h_align='center', 120 text='-', 121 v_align='center', 122 maxwidth=60, 123 scale=1.3, 124 color=value_color, 125 flatness=1.0, 126 ) 127 self.entry_fee_text_or = bui.textwidget( 128 parent=parent, 129 draw_controller=btn, 130 position=(x + 360, y + scly - 90), 131 size=(0, 0), 132 h_align='center', 133 text='', 134 v_align='center', 135 maxwidth=60, 136 scale=0.5, 137 color=value_color, 138 flatness=1.0, 139 ) 140 self.entry_fee_text_remaining = bui.textwidget( 141 parent=parent, 142 draw_controller=btn, 143 position=(x + 360, y + scly - 90), 144 size=(0, 0), 145 h_align='center', 146 text='', 147 v_align='center', 148 maxwidth=60, 149 scale=0.5, 150 color=value_color, 151 flatness=1.0, 152 ) 153 154 self.entry_fee_ad_image = bui.imagewidget( 155 parent=parent, 156 size=(40, 40), 157 draw_controller=btn, 158 position=(x + 360 - 20, y + scly - 140), 159 opacity=0.0, 160 texture=bui.gettexture('tv'), 161 ) 162 163 x_offs += 50 164 165 bui.textwidget( 166 parent=parent, 167 draw_controller=btn, 168 position=(x + 447 + x_offs, y + scly - 20), 169 size=(0, 0), 170 h_align='center', 171 text=bui.Lstr(resource=f'{self._r}.prizesText'), 172 v_align='center', 173 maxwidth=130, 174 scale=0.9, 175 color=header_color, 176 flatness=1.0, 177 ) 178 179 self.button_x = x 180 self.button_y = y 181 self.button_scale_y = scly 182 183 xo2 = 0 184 prize_value_scale = 1.5 185 186 self.prize_range_1_text = bui.textwidget( 187 parent=parent, 188 draw_controller=btn, 189 position=(x + 355 + xo2 + x_offs, y + scly - 93), 190 size=(0, 0), 191 h_align='right', 192 v_align='center', 193 maxwidth=50, 194 text='-', 195 scale=0.8, 196 color=header_color, 197 flatness=1.0, 198 ) 199 self.prize_value_1_text = bui.textwidget( 200 parent=parent, 201 draw_controller=btn, 202 position=(x + 380 + xo2 + x_offs, y + scly - 93), 203 size=(0, 0), 204 h_align='left', 205 text='-', 206 v_align='center', 207 maxwidth=100, 208 scale=prize_value_scale, 209 color=value_color, 210 flatness=1.0, 211 ) 212 213 self.prize_range_2_text = bui.textwidget( 214 parent=parent, 215 draw_controller=btn, 216 position=(x + 355 + xo2 + x_offs, y + scly - 93), 217 size=(0, 0), 218 h_align='right', 219 v_align='center', 220 maxwidth=50, 221 scale=0.8, 222 color=header_color, 223 flatness=1.0, 224 ) 225 self.prize_value_2_text = bui.textwidget( 226 parent=parent, 227 draw_controller=btn, 228 position=(x + 380 + xo2 + x_offs, y + scly - 93), 229 size=(0, 0), 230 h_align='left', 231 text='', 232 v_align='center', 233 maxwidth=100, 234 scale=prize_value_scale, 235 color=value_color, 236 flatness=1.0, 237 ) 238 239 self.prize_range_3_text = bui.textwidget( 240 parent=parent, 241 draw_controller=btn, 242 position=(x + 355 + xo2 + x_offs, y + scly - 93), 243 size=(0, 0), 244 h_align='right', 245 v_align='center', 246 maxwidth=50, 247 scale=0.8, 248 color=header_color, 249 flatness=1.0, 250 ) 251 self.prize_value_3_text = bui.textwidget( 252 parent=parent, 253 draw_controller=btn, 254 position=(x + 380 + xo2 + x_offs, y + scly - 93), 255 size=(0, 0), 256 h_align='left', 257 text='', 258 v_align='center', 259 maxwidth=100, 260 scale=prize_value_scale, 261 color=value_color, 262 flatness=1.0, 263 ) 264 265 bui.textwidget( 266 parent=parent, 267 draw_controller=btn, 268 position=(x + 620 + x_offs, y + scly - 20), 269 size=(0, 0), 270 h_align='center', 271 text=bui.Lstr(resource=f'{self._r}.currentBestText'), 272 v_align='center', 273 maxwidth=180, 274 scale=0.9, 275 color=header_color, 276 flatness=1.0, 277 ) 278 self.current_leader_name_text = bui.textwidget( 279 parent=parent, 280 draw_controller=btn, 281 position=( 282 x + 620 + x_offs - (170 / 1.4) * 0.5, 283 y + scly - 60 - 40 * 0.5, 284 ), 285 selectable=True, 286 click_activate=True, 287 autoselect=True, 288 on_activate_call=bui.WeakCall(self._show_leader), 289 size=(170 / 1.4, 40), 290 h_align='center', 291 text='-', 292 v_align='center', 293 maxwidth=170, 294 glow_type='uniform', 295 scale=1.4, 296 color=value_color, 297 flatness=1.0, 298 ) 299 self.current_leader_score_text = bui.textwidget( 300 parent=parent, 301 draw_controller=btn, 302 position=(x + 620 + x_offs, y + scly - 113 + 10), 303 size=(0, 0), 304 h_align='center', 305 text='-', 306 v_align='center', 307 maxwidth=170, 308 scale=1.8, 309 color=value_color, 310 flatness=1.0, 311 ) 312 313 self.more_scores_button = bui.buttonwidget( 314 parent=parent, 315 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 316 color=(0.5, 0.5, 0.6), 317 textcolor=(0.7, 0.7, 0.8), 318 label='-', 319 size=(120, 40), 320 autoselect=True, 321 up_widget=self.current_leader_name_text, 322 text_scale=0.6, 323 on_activate_call=bui.WeakCall(self._show_scores), 324 ) 325 bui.widget( 326 edit=self.current_leader_name_text, 327 down_widget=self.more_scores_button, 328 ) 329 330 bui.textwidget( 331 parent=parent, 332 draw_controller=btn, 333 position=(x + 820 + x_offs, y + scly - 20), 334 size=(0, 0), 335 h_align='center', 336 text=bui.Lstr(resource=f'{self._r}.timeRemainingText'), 337 v_align='center', 338 maxwidth=180, 339 scale=0.9, 340 color=header_color, 341 flatness=1.0, 342 ) 343 self.time_remaining_value_text = bui.textwidget( 344 parent=parent, 345 draw_controller=btn, 346 position=(x + 820 + x_offs, y + scly - 68), 347 size=(0, 0), 348 h_align='center', 349 text='-', 350 v_align='center', 351 maxwidth=180, 352 scale=2.0, 353 color=value_color, 354 flatness=1.0, 355 ) 356 self.time_remaining_out_of_text = bui.textwidget( 357 parent=parent, 358 draw_controller=btn, 359 position=(x + 820 + x_offs, y + scly - 110), 360 size=(0, 0), 361 h_align='center', 362 text='-', 363 v_align='center', 364 maxwidth=120, 365 scale=0.72, 366 color=(0.4, 0.4, 0.5), 367 flatness=1.0, 368 ) 369 370 def _pressed(self) -> None: 371 self.on_pressed(self) 372 373 def _show_leader(self) -> None: 374 # pylint: disable=cyclic-import 375 from bauiv1lib.account.viewer import AccountViewerWindow 376 377 tournament_id = self.tournament_id 378 379 # FIXME: This assumes a single player entry in leader; should expand 380 # this to work with multiple. 381 if ( 382 tournament_id is None 383 or self.leader is None 384 or len(self.leader[2]) != 1 385 ): 386 bui.getsound('error').play() 387 return 388 bui.getsound('swish').play() 389 AccountViewerWindow( 390 account_id=self.leader[2][0].get('a', None), 391 profile_id=self.leader[2][0].get('p', None), 392 position=self.current_leader_name_text.get_screen_space_center(), 393 ) 394 395 def _show_scores(self) -> None: 396 # pylint: disable=cyclic-import 397 from bauiv1lib.tournamentscores import TournamentScoresWindow 398 399 tournament_id = self.tournament_id 400 if tournament_id is None: 401 bui.getsound('error').play() 402 return 403 404 TournamentScoresWindow( 405 tournament_id=tournament_id, 406 position=self.more_scores_button.get_screen_space_center(), 407 ) 408 409 def update_for_data(self, entry: dict[str, Any]) -> None: 410 """Update for new incoming data.""" 411 # pylint: disable=too-many-statements 412 # pylint: disable=too-many-locals 413 # pylint: disable=too-many-branches 414 415 plus = bui.app.plus 416 assert plus is not None 417 418 assert bui.app.classic is not None 419 prize_y_offs = ( 420 34 421 if 'prizeRange3' in entry 422 else 20 if 'prizeRange2' in entry else 12 423 ) 424 x_offs = 90 425 426 # pylint: disable=useless-suppression 427 # pylint: disable=unbalanced-tuple-unpacking 428 ( 429 pr1, 430 pv1, 431 pr2, 432 pv2, 433 pr3, 434 pv3, 435 ) = bui.app.classic.get_tournament_prize_strings(entry) 436 # pylint: enable=unbalanced-tuple-unpacking 437 # pylint: enable=useless-suppression 438 439 enabled = 'requiredLeague' not in entry 440 bui.buttonwidget( 441 edit=self.button, 442 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 443 ) 444 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 445 bui.textwidget( 446 edit=self.prize_range_1_text, 447 text='-' if pr1 == '' else pr1, 448 position=( 449 self.button_x + 365 + x_offs, 450 self.button_y + self.button_scale_y - 93 + prize_y_offs, 451 ), 452 ) 453 454 # We want to draw values containing tickets a bit smaller 455 # (scratch that; we now draw medals a bit bigger). 456 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 457 prize_value_scale_large = 1.0 458 prize_value_scale_small = 1.0 459 460 bui.textwidget( 461 edit=self.prize_value_1_text, 462 text='-' if pv1 == '' else pv1, 463 scale=( 464 prize_value_scale_large 465 if ticket_char not in pv1 466 else prize_value_scale_small 467 ), 468 position=( 469 self.button_x + 380 + x_offs, 470 self.button_y + self.button_scale_y - 93 + prize_y_offs, 471 ), 472 ) 473 474 bui.textwidget( 475 edit=self.prize_range_2_text, 476 text=pr2, 477 position=( 478 self.button_x + 365 + x_offs, 479 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 480 ), 481 ) 482 bui.textwidget( 483 edit=self.prize_value_2_text, 484 text=pv2, 485 scale=( 486 prize_value_scale_large 487 if ticket_char not in pv2 488 else prize_value_scale_small 489 ), 490 position=( 491 self.button_x + 380 + x_offs, 492 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 493 ), 494 ) 495 496 bui.textwidget( 497 edit=self.prize_range_3_text, 498 text=pr3, 499 position=( 500 self.button_x + 365 + x_offs, 501 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 502 ), 503 ) 504 bui.textwidget( 505 edit=self.prize_value_3_text, 506 text=pv3, 507 scale=( 508 prize_value_scale_large 509 if ticket_char not in pv3 510 else prize_value_scale_small 511 ), 512 position=( 513 self.button_x + 380 + x_offs, 514 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 515 ), 516 ) 517 518 leader_name = '-' 519 leader_score: str | bui.Lstr = '-' 520 if entry['scores']: 521 score = self.leader = copy.deepcopy(entry['scores'][0]) 522 leader_name = score[1] 523 leader_score = ( 524 bui.timestring((score[0] * 10) / 1000.0, centi=True) 525 if entry['scoreType'] == 'time' 526 else str(score[0]) 527 ) 528 else: 529 self.leader = None 530 531 bui.textwidget( 532 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 533 ) 534 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 535 bui.buttonwidget( 536 edit=self.more_scores_button, 537 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 538 ) 539 out_of_time_text: str | bui.Lstr = ( 540 '-' 541 if 'totalTime' not in entry 542 else bui.Lstr( 543 resource=f'{self._r}.ofTotalTimeText', 544 subs=[ 545 ( 546 '${TOTAL}', 547 bui.timestring(entry['totalTime'], centi=False), 548 ) 549 ], 550 ) 551 ) 552 bui.textwidget( 553 edit=self.time_remaining_out_of_text, text=out_of_time_text 554 ) 555 556 self.time_remaining = entry['timeRemaining'] 557 self.has_time_remaining = entry is not None 558 self.tournament_id = entry['tournamentID'] 559 self.required_league = ( 560 None if 'requiredLeague' not in entry else entry['requiredLeague'] 561 ) 562 563 assert bui.app.classic is not None 564 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 565 'game' 566 ] 567 568 if game is None: 569 bui.textwidget(edit=self.button_text, text='-') 570 bui.imagewidget( 571 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 572 ) 573 else: 574 campaignname, levelname = game.split(':') 575 campaign = bui.app.classic.getcampaign(campaignname) 576 max_players = bui.app.classic.accounts.tournament_info[ 577 self.tournament_id 578 ]['maxPlayers'] 579 txt = bui.Lstr( 580 value='${A} ${B}', 581 subs=[ 582 ('${A}', campaign.getlevel(levelname).displayname), 583 ( 584 '${B}', 585 bui.Lstr( 586 resource='playerCountAbbreviatedText', 587 subs=[('${COUNT}', str(max_players))], 588 ), 589 ), 590 ], 591 ) 592 bui.textwidget(edit=self.button_text, text=txt) 593 bui.imagewidget( 594 edit=self.image, 595 texture=bui.gettexture( 596 campaign.getlevel(levelname).preview_texture_name 597 ), 598 opacity=1.0 if enabled else 0.5, 599 ) 600 601 fee = entry['fee'] 602 603 if fee is None: 604 fee_var = None 605 elif fee == 4: 606 fee_var = 'price.tournament_entry_4' 607 elif fee == 3: 608 fee_var = 'price.tournament_entry_3' 609 elif fee == 2: 610 fee_var = 'price.tournament_entry_2' 611 elif fee == 1: 612 fee_var = 'price.tournament_entry_1' 613 else: 614 if fee != 0: 615 print('Unknown fee value:', fee) 616 fee_var = 'price.tournament_entry_0' 617 618 self.allow_ads = allow_ads = entry['allowAds'] 619 620 final_fee: int | None = ( 621 None 622 if fee_var is None 623 else plus.get_v1_account_misc_read_val(fee_var, '?') 624 ) 625 626 final_fee_str: str | bui.Lstr 627 if fee_var is None: 628 final_fee_str = '' 629 else: 630 if final_fee == 0: 631 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 632 else: 633 final_fee_str = bui.charstr( 634 bui.SpecialChar.TICKET_BACKING 635 ) + str(final_fee) 636 637 assert bui.app.classic is not None 638 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 639 self.tournament_id 640 ]['adTriesRemaining'] 641 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 642 self.tournament_id 643 ]['freeTriesRemaining'] 644 645 # Now, if this fee allows ads and we support video ads, show 646 # the 'or ad' version. 647 if allow_ads and plus.has_video_ads(): 648 ads_enabled = plus.have_incentivized_ad() 649 bui.imagewidget( 650 edit=self.entry_fee_ad_image, 651 opacity=1.0 if ads_enabled else 0.25, 652 ) 653 or_text = ( 654 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 655 .evaluate() 656 .strip() 657 ) 658 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 659 bui.textwidget( 660 edit=self.entry_fee_text_top, 661 position=( 662 self.button_x + 360, 663 self.button_y + self.button_scale_y - 60, 664 ), 665 scale=1.3, 666 text=final_fee_str, 667 ) 668 669 # Possibly show number of ad-plays remaining. 670 bui.textwidget( 671 edit=self.entry_fee_text_remaining, 672 position=( 673 self.button_x + 360, 674 self.button_y + self.button_scale_y - 146, 675 ), 676 text=( 677 '' 678 if ad_tries_remaining in [None, 0] 679 else ('' + str(ad_tries_remaining)) 680 ), 681 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 682 ) 683 else: 684 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 685 bui.textwidget(edit=self.entry_fee_text_or, text='') 686 bui.textwidget( 687 edit=self.entry_fee_text_top, 688 position=( 689 self.button_x + 360, 690 self.button_y + self.button_scale_y - 80, 691 ), 692 scale=1.3, 693 text=final_fee_str, 694 ) 695 696 # Possibly show number of free-plays remaining. 697 bui.textwidget( 698 edit=self.entry_fee_text_remaining, 699 position=( 700 self.button_x + 360, 701 self.button_y + self.button_scale_y - 100, 702 ), 703 text=( 704 '' 705 if (free_tries_remaining in [None, 0] or final_fee != 0) 706 else ('' + str(free_tries_remaining)) 707 ), 708 color=(0.6, 0.6, 0.6, 1), 709 )
class
TournamentButton:
17class TournamentButton: 18 """Button showing a tournament in coop window.""" 19 20 def __init__( 21 self, 22 parent: bui.Widget, 23 x: float, 24 y: float, 25 select: bool, 26 on_pressed: Callable[[TournamentButton], None], 27 ) -> None: 28 # pylint: disable=too-many-positional-arguments 29 self._r = 'coopSelectWindow' 30 sclx = 300 31 scly = 195.0 32 self.on_pressed = on_pressed 33 self.lsbt = bui.getmesh('level_select_button_transparent') 34 self.lsbo = bui.getmesh('level_select_button_opaque') 35 self.allow_ads = False 36 self.tournament_id: str | None = None 37 self.time_remaining: int = 0 38 self.has_time_remaining: bool = False 39 self.leader: Any = None 40 self.required_league: str | None = None 41 self.button = btn = bui.buttonwidget( 42 parent=parent, 43 position=(x + 23, y + 4), 44 size=(sclx, scly), 45 label='', 46 button_type='square', 47 autoselect=True, 48 on_activate_call=bui.WeakCall(self._pressed), 49 ) 50 bui.widget( 51 edit=btn, 52 show_buffer_bottom=50, 53 show_buffer_top=50, 54 show_buffer_left=400, 55 show_buffer_right=200, 56 ) 57 if select: 58 bui.containerwidget( 59 edit=parent, selected_child=btn, visible_child=btn 60 ) 61 image_width = sclx * 0.85 * 0.75 62 63 self.image = bui.imagewidget( 64 parent=parent, 65 draw_controller=btn, 66 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 67 size=(image_width, image_width * 0.5), 68 mesh_transparent=self.lsbt, 69 mesh_opaque=self.lsbo, 70 texture=bui.gettexture('black'), 71 opacity=0.2, 72 mask_texture=bui.gettexture('mapPreviewMask'), 73 ) 74 75 self.lock_image = bui.imagewidget( 76 parent=parent, 77 draw_controller=btn, 78 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 79 size=(image_width * 0.5, image_width * 0.5), 80 texture=bui.gettexture('lock'), 81 opacity=0.0, 82 ) 83 84 self.button_text = bui.textwidget( 85 parent=parent, 86 draw_controller=btn, 87 position=(x + 20 + sclx * 0.5, y + scly - 35), 88 size=(0, 0), 89 h_align='center', 90 text='-', 91 v_align='center', 92 maxwidth=sclx * 0.76, 93 scale=0.85, 94 color=(0.8, 1.0, 0.8, 1.0), 95 ) 96 97 header_color = (0.43, 0.4, 0.5, 1) 98 value_color = (0.6, 0.6, 0.6, 1) 99 100 x_offs = 0 101 bui.textwidget( 102 parent=parent, 103 draw_controller=btn, 104 position=(x + 360, y + scly - 20), 105 size=(0, 0), 106 h_align='center', 107 text=bui.Lstr(resource=f'{self._r}.entryFeeText'), 108 v_align='center', 109 maxwidth=100, 110 scale=0.9, 111 color=header_color, 112 flatness=1.0, 113 ) 114 115 self.entry_fee_text_top = bui.textwidget( 116 parent=parent, 117 draw_controller=btn, 118 position=(x + 360, y + scly - 60), 119 size=(0, 0), 120 h_align='center', 121 text='-', 122 v_align='center', 123 maxwidth=60, 124 scale=1.3, 125 color=value_color, 126 flatness=1.0, 127 ) 128 self.entry_fee_text_or = bui.textwidget( 129 parent=parent, 130 draw_controller=btn, 131 position=(x + 360, y + scly - 90), 132 size=(0, 0), 133 h_align='center', 134 text='', 135 v_align='center', 136 maxwidth=60, 137 scale=0.5, 138 color=value_color, 139 flatness=1.0, 140 ) 141 self.entry_fee_text_remaining = bui.textwidget( 142 parent=parent, 143 draw_controller=btn, 144 position=(x + 360, y + scly - 90), 145 size=(0, 0), 146 h_align='center', 147 text='', 148 v_align='center', 149 maxwidth=60, 150 scale=0.5, 151 color=value_color, 152 flatness=1.0, 153 ) 154 155 self.entry_fee_ad_image = bui.imagewidget( 156 parent=parent, 157 size=(40, 40), 158 draw_controller=btn, 159 position=(x + 360 - 20, y + scly - 140), 160 opacity=0.0, 161 texture=bui.gettexture('tv'), 162 ) 163 164 x_offs += 50 165 166 bui.textwidget( 167 parent=parent, 168 draw_controller=btn, 169 position=(x + 447 + x_offs, y + scly - 20), 170 size=(0, 0), 171 h_align='center', 172 text=bui.Lstr(resource=f'{self._r}.prizesText'), 173 v_align='center', 174 maxwidth=130, 175 scale=0.9, 176 color=header_color, 177 flatness=1.0, 178 ) 179 180 self.button_x = x 181 self.button_y = y 182 self.button_scale_y = scly 183 184 xo2 = 0 185 prize_value_scale = 1.5 186 187 self.prize_range_1_text = bui.textwidget( 188 parent=parent, 189 draw_controller=btn, 190 position=(x + 355 + xo2 + x_offs, y + scly - 93), 191 size=(0, 0), 192 h_align='right', 193 v_align='center', 194 maxwidth=50, 195 text='-', 196 scale=0.8, 197 color=header_color, 198 flatness=1.0, 199 ) 200 self.prize_value_1_text = bui.textwidget( 201 parent=parent, 202 draw_controller=btn, 203 position=(x + 380 + xo2 + x_offs, y + scly - 93), 204 size=(0, 0), 205 h_align='left', 206 text='-', 207 v_align='center', 208 maxwidth=100, 209 scale=prize_value_scale, 210 color=value_color, 211 flatness=1.0, 212 ) 213 214 self.prize_range_2_text = bui.textwidget( 215 parent=parent, 216 draw_controller=btn, 217 position=(x + 355 + xo2 + x_offs, y + scly - 93), 218 size=(0, 0), 219 h_align='right', 220 v_align='center', 221 maxwidth=50, 222 scale=0.8, 223 color=header_color, 224 flatness=1.0, 225 ) 226 self.prize_value_2_text = bui.textwidget( 227 parent=parent, 228 draw_controller=btn, 229 position=(x + 380 + xo2 + x_offs, y + scly - 93), 230 size=(0, 0), 231 h_align='left', 232 text='', 233 v_align='center', 234 maxwidth=100, 235 scale=prize_value_scale, 236 color=value_color, 237 flatness=1.0, 238 ) 239 240 self.prize_range_3_text = bui.textwidget( 241 parent=parent, 242 draw_controller=btn, 243 position=(x + 355 + xo2 + x_offs, y + scly - 93), 244 size=(0, 0), 245 h_align='right', 246 v_align='center', 247 maxwidth=50, 248 scale=0.8, 249 color=header_color, 250 flatness=1.0, 251 ) 252 self.prize_value_3_text = bui.textwidget( 253 parent=parent, 254 draw_controller=btn, 255 position=(x + 380 + xo2 + x_offs, y + scly - 93), 256 size=(0, 0), 257 h_align='left', 258 text='', 259 v_align='center', 260 maxwidth=100, 261 scale=prize_value_scale, 262 color=value_color, 263 flatness=1.0, 264 ) 265 266 bui.textwidget( 267 parent=parent, 268 draw_controller=btn, 269 position=(x + 620 + x_offs, y + scly - 20), 270 size=(0, 0), 271 h_align='center', 272 text=bui.Lstr(resource=f'{self._r}.currentBestText'), 273 v_align='center', 274 maxwidth=180, 275 scale=0.9, 276 color=header_color, 277 flatness=1.0, 278 ) 279 self.current_leader_name_text = bui.textwidget( 280 parent=parent, 281 draw_controller=btn, 282 position=( 283 x + 620 + x_offs - (170 / 1.4) * 0.5, 284 y + scly - 60 - 40 * 0.5, 285 ), 286 selectable=True, 287 click_activate=True, 288 autoselect=True, 289 on_activate_call=bui.WeakCall(self._show_leader), 290 size=(170 / 1.4, 40), 291 h_align='center', 292 text='-', 293 v_align='center', 294 maxwidth=170, 295 glow_type='uniform', 296 scale=1.4, 297 color=value_color, 298 flatness=1.0, 299 ) 300 self.current_leader_score_text = bui.textwidget( 301 parent=parent, 302 draw_controller=btn, 303 position=(x + 620 + x_offs, y + scly - 113 + 10), 304 size=(0, 0), 305 h_align='center', 306 text='-', 307 v_align='center', 308 maxwidth=170, 309 scale=1.8, 310 color=value_color, 311 flatness=1.0, 312 ) 313 314 self.more_scores_button = bui.buttonwidget( 315 parent=parent, 316 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 317 color=(0.5, 0.5, 0.6), 318 textcolor=(0.7, 0.7, 0.8), 319 label='-', 320 size=(120, 40), 321 autoselect=True, 322 up_widget=self.current_leader_name_text, 323 text_scale=0.6, 324 on_activate_call=bui.WeakCall(self._show_scores), 325 ) 326 bui.widget( 327 edit=self.current_leader_name_text, 328 down_widget=self.more_scores_button, 329 ) 330 331 bui.textwidget( 332 parent=parent, 333 draw_controller=btn, 334 position=(x + 820 + x_offs, y + scly - 20), 335 size=(0, 0), 336 h_align='center', 337 text=bui.Lstr(resource=f'{self._r}.timeRemainingText'), 338 v_align='center', 339 maxwidth=180, 340 scale=0.9, 341 color=header_color, 342 flatness=1.0, 343 ) 344 self.time_remaining_value_text = bui.textwidget( 345 parent=parent, 346 draw_controller=btn, 347 position=(x + 820 + x_offs, y + scly - 68), 348 size=(0, 0), 349 h_align='center', 350 text='-', 351 v_align='center', 352 maxwidth=180, 353 scale=2.0, 354 color=value_color, 355 flatness=1.0, 356 ) 357 self.time_remaining_out_of_text = bui.textwidget( 358 parent=parent, 359 draw_controller=btn, 360 position=(x + 820 + x_offs, y + scly - 110), 361 size=(0, 0), 362 h_align='center', 363 text='-', 364 v_align='center', 365 maxwidth=120, 366 scale=0.72, 367 color=(0.4, 0.4, 0.5), 368 flatness=1.0, 369 ) 370 371 def _pressed(self) -> None: 372 self.on_pressed(self) 373 374 def _show_leader(self) -> None: 375 # pylint: disable=cyclic-import 376 from bauiv1lib.account.viewer import AccountViewerWindow 377 378 tournament_id = self.tournament_id 379 380 # FIXME: This assumes a single player entry in leader; should expand 381 # this to work with multiple. 382 if ( 383 tournament_id is None 384 or self.leader is None 385 or len(self.leader[2]) != 1 386 ): 387 bui.getsound('error').play() 388 return 389 bui.getsound('swish').play() 390 AccountViewerWindow( 391 account_id=self.leader[2][0].get('a', None), 392 profile_id=self.leader[2][0].get('p', None), 393 position=self.current_leader_name_text.get_screen_space_center(), 394 ) 395 396 def _show_scores(self) -> None: 397 # pylint: disable=cyclic-import 398 from bauiv1lib.tournamentscores import TournamentScoresWindow 399 400 tournament_id = self.tournament_id 401 if tournament_id is None: 402 bui.getsound('error').play() 403 return 404 405 TournamentScoresWindow( 406 tournament_id=tournament_id, 407 position=self.more_scores_button.get_screen_space_center(), 408 ) 409 410 def update_for_data(self, entry: dict[str, Any]) -> None: 411 """Update for new incoming data.""" 412 # pylint: disable=too-many-statements 413 # pylint: disable=too-many-locals 414 # pylint: disable=too-many-branches 415 416 plus = bui.app.plus 417 assert plus is not None 418 419 assert bui.app.classic is not None 420 prize_y_offs = ( 421 34 422 if 'prizeRange3' in entry 423 else 20 if 'prizeRange2' in entry else 12 424 ) 425 x_offs = 90 426 427 # pylint: disable=useless-suppression 428 # pylint: disable=unbalanced-tuple-unpacking 429 ( 430 pr1, 431 pv1, 432 pr2, 433 pv2, 434 pr3, 435 pv3, 436 ) = bui.app.classic.get_tournament_prize_strings(entry) 437 # pylint: enable=unbalanced-tuple-unpacking 438 # pylint: enable=useless-suppression 439 440 enabled = 'requiredLeague' not in entry 441 bui.buttonwidget( 442 edit=self.button, 443 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 444 ) 445 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 446 bui.textwidget( 447 edit=self.prize_range_1_text, 448 text='-' if pr1 == '' else pr1, 449 position=( 450 self.button_x + 365 + x_offs, 451 self.button_y + self.button_scale_y - 93 + prize_y_offs, 452 ), 453 ) 454 455 # We want to draw values containing tickets a bit smaller 456 # (scratch that; we now draw medals a bit bigger). 457 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 458 prize_value_scale_large = 1.0 459 prize_value_scale_small = 1.0 460 461 bui.textwidget( 462 edit=self.prize_value_1_text, 463 text='-' if pv1 == '' else pv1, 464 scale=( 465 prize_value_scale_large 466 if ticket_char not in pv1 467 else prize_value_scale_small 468 ), 469 position=( 470 self.button_x + 380 + x_offs, 471 self.button_y + self.button_scale_y - 93 + prize_y_offs, 472 ), 473 ) 474 475 bui.textwidget( 476 edit=self.prize_range_2_text, 477 text=pr2, 478 position=( 479 self.button_x + 365 + x_offs, 480 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 481 ), 482 ) 483 bui.textwidget( 484 edit=self.prize_value_2_text, 485 text=pv2, 486 scale=( 487 prize_value_scale_large 488 if ticket_char not in pv2 489 else prize_value_scale_small 490 ), 491 position=( 492 self.button_x + 380 + x_offs, 493 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 494 ), 495 ) 496 497 bui.textwidget( 498 edit=self.prize_range_3_text, 499 text=pr3, 500 position=( 501 self.button_x + 365 + x_offs, 502 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 503 ), 504 ) 505 bui.textwidget( 506 edit=self.prize_value_3_text, 507 text=pv3, 508 scale=( 509 prize_value_scale_large 510 if ticket_char not in pv3 511 else prize_value_scale_small 512 ), 513 position=( 514 self.button_x + 380 + x_offs, 515 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 516 ), 517 ) 518 519 leader_name = '-' 520 leader_score: str | bui.Lstr = '-' 521 if entry['scores']: 522 score = self.leader = copy.deepcopy(entry['scores'][0]) 523 leader_name = score[1] 524 leader_score = ( 525 bui.timestring((score[0] * 10) / 1000.0, centi=True) 526 if entry['scoreType'] == 'time' 527 else str(score[0]) 528 ) 529 else: 530 self.leader = None 531 532 bui.textwidget( 533 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 534 ) 535 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 536 bui.buttonwidget( 537 edit=self.more_scores_button, 538 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 539 ) 540 out_of_time_text: str | bui.Lstr = ( 541 '-' 542 if 'totalTime' not in entry 543 else bui.Lstr( 544 resource=f'{self._r}.ofTotalTimeText', 545 subs=[ 546 ( 547 '${TOTAL}', 548 bui.timestring(entry['totalTime'], centi=False), 549 ) 550 ], 551 ) 552 ) 553 bui.textwidget( 554 edit=self.time_remaining_out_of_text, text=out_of_time_text 555 ) 556 557 self.time_remaining = entry['timeRemaining'] 558 self.has_time_remaining = entry is not None 559 self.tournament_id = entry['tournamentID'] 560 self.required_league = ( 561 None if 'requiredLeague' not in entry else entry['requiredLeague'] 562 ) 563 564 assert bui.app.classic is not None 565 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 566 'game' 567 ] 568 569 if game is None: 570 bui.textwidget(edit=self.button_text, text='-') 571 bui.imagewidget( 572 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 573 ) 574 else: 575 campaignname, levelname = game.split(':') 576 campaign = bui.app.classic.getcampaign(campaignname) 577 max_players = bui.app.classic.accounts.tournament_info[ 578 self.tournament_id 579 ]['maxPlayers'] 580 txt = bui.Lstr( 581 value='${A} ${B}', 582 subs=[ 583 ('${A}', campaign.getlevel(levelname).displayname), 584 ( 585 '${B}', 586 bui.Lstr( 587 resource='playerCountAbbreviatedText', 588 subs=[('${COUNT}', str(max_players))], 589 ), 590 ), 591 ], 592 ) 593 bui.textwidget(edit=self.button_text, text=txt) 594 bui.imagewidget( 595 edit=self.image, 596 texture=bui.gettexture( 597 campaign.getlevel(levelname).preview_texture_name 598 ), 599 opacity=1.0 if enabled else 0.5, 600 ) 601 602 fee = entry['fee'] 603 604 if fee is None: 605 fee_var = None 606 elif fee == 4: 607 fee_var = 'price.tournament_entry_4' 608 elif fee == 3: 609 fee_var = 'price.tournament_entry_3' 610 elif fee == 2: 611 fee_var = 'price.tournament_entry_2' 612 elif fee == 1: 613 fee_var = 'price.tournament_entry_1' 614 else: 615 if fee != 0: 616 print('Unknown fee value:', fee) 617 fee_var = 'price.tournament_entry_0' 618 619 self.allow_ads = allow_ads = entry['allowAds'] 620 621 final_fee: int | None = ( 622 None 623 if fee_var is None 624 else plus.get_v1_account_misc_read_val(fee_var, '?') 625 ) 626 627 final_fee_str: str | bui.Lstr 628 if fee_var is None: 629 final_fee_str = '' 630 else: 631 if final_fee == 0: 632 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 633 else: 634 final_fee_str = bui.charstr( 635 bui.SpecialChar.TICKET_BACKING 636 ) + str(final_fee) 637 638 assert bui.app.classic is not None 639 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 640 self.tournament_id 641 ]['adTriesRemaining'] 642 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 643 self.tournament_id 644 ]['freeTriesRemaining'] 645 646 # Now, if this fee allows ads and we support video ads, show 647 # the 'or ad' version. 648 if allow_ads and plus.has_video_ads(): 649 ads_enabled = plus.have_incentivized_ad() 650 bui.imagewidget( 651 edit=self.entry_fee_ad_image, 652 opacity=1.0 if ads_enabled else 0.25, 653 ) 654 or_text = ( 655 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 656 .evaluate() 657 .strip() 658 ) 659 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 660 bui.textwidget( 661 edit=self.entry_fee_text_top, 662 position=( 663 self.button_x + 360, 664 self.button_y + self.button_scale_y - 60, 665 ), 666 scale=1.3, 667 text=final_fee_str, 668 ) 669 670 # Possibly show number of ad-plays remaining. 671 bui.textwidget( 672 edit=self.entry_fee_text_remaining, 673 position=( 674 self.button_x + 360, 675 self.button_y + self.button_scale_y - 146, 676 ), 677 text=( 678 '' 679 if ad_tries_remaining in [None, 0] 680 else ('' + str(ad_tries_remaining)) 681 ), 682 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 683 ) 684 else: 685 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 686 bui.textwidget(edit=self.entry_fee_text_or, text='') 687 bui.textwidget( 688 edit=self.entry_fee_text_top, 689 position=( 690 self.button_x + 360, 691 self.button_y + self.button_scale_y - 80, 692 ), 693 scale=1.3, 694 text=final_fee_str, 695 ) 696 697 # Possibly show number of free-plays remaining. 698 bui.textwidget( 699 edit=self.entry_fee_text_remaining, 700 position=( 701 self.button_x + 360, 702 self.button_y + self.button_scale_y - 100, 703 ), 704 text=( 705 '' 706 if (free_tries_remaining in [None, 0] or final_fee != 0) 707 else ('' + str(free_tries_remaining)) 708 ), 709 color=(0.6, 0.6, 0.6, 1), 710 )
Button showing a tournament in coop window.
TournamentButton( parent: _bauiv1.Widget, x: float, y: float, select: bool, on_pressed: Callable[[TournamentButton], NoneType])
20 def __init__( 21 self, 22 parent: bui.Widget, 23 x: float, 24 y: float, 25 select: bool, 26 on_pressed: Callable[[TournamentButton], None], 27 ) -> None: 28 # pylint: disable=too-many-positional-arguments 29 self._r = 'coopSelectWindow' 30 sclx = 300 31 scly = 195.0 32 self.on_pressed = on_pressed 33 self.lsbt = bui.getmesh('level_select_button_transparent') 34 self.lsbo = bui.getmesh('level_select_button_opaque') 35 self.allow_ads = False 36 self.tournament_id: str | None = None 37 self.time_remaining: int = 0 38 self.has_time_remaining: bool = False 39 self.leader: Any = None 40 self.required_league: str | None = None 41 self.button = btn = bui.buttonwidget( 42 parent=parent, 43 position=(x + 23, y + 4), 44 size=(sclx, scly), 45 label='', 46 button_type='square', 47 autoselect=True, 48 on_activate_call=bui.WeakCall(self._pressed), 49 ) 50 bui.widget( 51 edit=btn, 52 show_buffer_bottom=50, 53 show_buffer_top=50, 54 show_buffer_left=400, 55 show_buffer_right=200, 56 ) 57 if select: 58 bui.containerwidget( 59 edit=parent, selected_child=btn, visible_child=btn 60 ) 61 image_width = sclx * 0.85 * 0.75 62 63 self.image = bui.imagewidget( 64 parent=parent, 65 draw_controller=btn, 66 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 67 size=(image_width, image_width * 0.5), 68 mesh_transparent=self.lsbt, 69 mesh_opaque=self.lsbo, 70 texture=bui.gettexture('black'), 71 opacity=0.2, 72 mask_texture=bui.gettexture('mapPreviewMask'), 73 ) 74 75 self.lock_image = bui.imagewidget( 76 parent=parent, 77 draw_controller=btn, 78 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 79 size=(image_width * 0.5, image_width * 0.5), 80 texture=bui.gettexture('lock'), 81 opacity=0.0, 82 ) 83 84 self.button_text = bui.textwidget( 85 parent=parent, 86 draw_controller=btn, 87 position=(x + 20 + sclx * 0.5, y + scly - 35), 88 size=(0, 0), 89 h_align='center', 90 text='-', 91 v_align='center', 92 maxwidth=sclx * 0.76, 93 scale=0.85, 94 color=(0.8, 1.0, 0.8, 1.0), 95 ) 96 97 header_color = (0.43, 0.4, 0.5, 1) 98 value_color = (0.6, 0.6, 0.6, 1) 99 100 x_offs = 0 101 bui.textwidget( 102 parent=parent, 103 draw_controller=btn, 104 position=(x + 360, y + scly - 20), 105 size=(0, 0), 106 h_align='center', 107 text=bui.Lstr(resource=f'{self._r}.entryFeeText'), 108 v_align='center', 109 maxwidth=100, 110 scale=0.9, 111 color=header_color, 112 flatness=1.0, 113 ) 114 115 self.entry_fee_text_top = bui.textwidget( 116 parent=parent, 117 draw_controller=btn, 118 position=(x + 360, y + scly - 60), 119 size=(0, 0), 120 h_align='center', 121 text='-', 122 v_align='center', 123 maxwidth=60, 124 scale=1.3, 125 color=value_color, 126 flatness=1.0, 127 ) 128 self.entry_fee_text_or = bui.textwidget( 129 parent=parent, 130 draw_controller=btn, 131 position=(x + 360, y + scly - 90), 132 size=(0, 0), 133 h_align='center', 134 text='', 135 v_align='center', 136 maxwidth=60, 137 scale=0.5, 138 color=value_color, 139 flatness=1.0, 140 ) 141 self.entry_fee_text_remaining = bui.textwidget( 142 parent=parent, 143 draw_controller=btn, 144 position=(x + 360, y + scly - 90), 145 size=(0, 0), 146 h_align='center', 147 text='', 148 v_align='center', 149 maxwidth=60, 150 scale=0.5, 151 color=value_color, 152 flatness=1.0, 153 ) 154 155 self.entry_fee_ad_image = bui.imagewidget( 156 parent=parent, 157 size=(40, 40), 158 draw_controller=btn, 159 position=(x + 360 - 20, y + scly - 140), 160 opacity=0.0, 161 texture=bui.gettexture('tv'), 162 ) 163 164 x_offs += 50 165 166 bui.textwidget( 167 parent=parent, 168 draw_controller=btn, 169 position=(x + 447 + x_offs, y + scly - 20), 170 size=(0, 0), 171 h_align='center', 172 text=bui.Lstr(resource=f'{self._r}.prizesText'), 173 v_align='center', 174 maxwidth=130, 175 scale=0.9, 176 color=header_color, 177 flatness=1.0, 178 ) 179 180 self.button_x = x 181 self.button_y = y 182 self.button_scale_y = scly 183 184 xo2 = 0 185 prize_value_scale = 1.5 186 187 self.prize_range_1_text = bui.textwidget( 188 parent=parent, 189 draw_controller=btn, 190 position=(x + 355 + xo2 + x_offs, y + scly - 93), 191 size=(0, 0), 192 h_align='right', 193 v_align='center', 194 maxwidth=50, 195 text='-', 196 scale=0.8, 197 color=header_color, 198 flatness=1.0, 199 ) 200 self.prize_value_1_text = bui.textwidget( 201 parent=parent, 202 draw_controller=btn, 203 position=(x + 380 + xo2 + x_offs, y + scly - 93), 204 size=(0, 0), 205 h_align='left', 206 text='-', 207 v_align='center', 208 maxwidth=100, 209 scale=prize_value_scale, 210 color=value_color, 211 flatness=1.0, 212 ) 213 214 self.prize_range_2_text = bui.textwidget( 215 parent=parent, 216 draw_controller=btn, 217 position=(x + 355 + xo2 + x_offs, y + scly - 93), 218 size=(0, 0), 219 h_align='right', 220 v_align='center', 221 maxwidth=50, 222 scale=0.8, 223 color=header_color, 224 flatness=1.0, 225 ) 226 self.prize_value_2_text = bui.textwidget( 227 parent=parent, 228 draw_controller=btn, 229 position=(x + 380 + xo2 + x_offs, y + scly - 93), 230 size=(0, 0), 231 h_align='left', 232 text='', 233 v_align='center', 234 maxwidth=100, 235 scale=prize_value_scale, 236 color=value_color, 237 flatness=1.0, 238 ) 239 240 self.prize_range_3_text = bui.textwidget( 241 parent=parent, 242 draw_controller=btn, 243 position=(x + 355 + xo2 + x_offs, y + scly - 93), 244 size=(0, 0), 245 h_align='right', 246 v_align='center', 247 maxwidth=50, 248 scale=0.8, 249 color=header_color, 250 flatness=1.0, 251 ) 252 self.prize_value_3_text = bui.textwidget( 253 parent=parent, 254 draw_controller=btn, 255 position=(x + 380 + xo2 + x_offs, y + scly - 93), 256 size=(0, 0), 257 h_align='left', 258 text='', 259 v_align='center', 260 maxwidth=100, 261 scale=prize_value_scale, 262 color=value_color, 263 flatness=1.0, 264 ) 265 266 bui.textwidget( 267 parent=parent, 268 draw_controller=btn, 269 position=(x + 620 + x_offs, y + scly - 20), 270 size=(0, 0), 271 h_align='center', 272 text=bui.Lstr(resource=f'{self._r}.currentBestText'), 273 v_align='center', 274 maxwidth=180, 275 scale=0.9, 276 color=header_color, 277 flatness=1.0, 278 ) 279 self.current_leader_name_text = bui.textwidget( 280 parent=parent, 281 draw_controller=btn, 282 position=( 283 x + 620 + x_offs - (170 / 1.4) * 0.5, 284 y + scly - 60 - 40 * 0.5, 285 ), 286 selectable=True, 287 click_activate=True, 288 autoselect=True, 289 on_activate_call=bui.WeakCall(self._show_leader), 290 size=(170 / 1.4, 40), 291 h_align='center', 292 text='-', 293 v_align='center', 294 maxwidth=170, 295 glow_type='uniform', 296 scale=1.4, 297 color=value_color, 298 flatness=1.0, 299 ) 300 self.current_leader_score_text = bui.textwidget( 301 parent=parent, 302 draw_controller=btn, 303 position=(x + 620 + x_offs, y + scly - 113 + 10), 304 size=(0, 0), 305 h_align='center', 306 text='-', 307 v_align='center', 308 maxwidth=170, 309 scale=1.8, 310 color=value_color, 311 flatness=1.0, 312 ) 313 314 self.more_scores_button = bui.buttonwidget( 315 parent=parent, 316 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 317 color=(0.5, 0.5, 0.6), 318 textcolor=(0.7, 0.7, 0.8), 319 label='-', 320 size=(120, 40), 321 autoselect=True, 322 up_widget=self.current_leader_name_text, 323 text_scale=0.6, 324 on_activate_call=bui.WeakCall(self._show_scores), 325 ) 326 bui.widget( 327 edit=self.current_leader_name_text, 328 down_widget=self.more_scores_button, 329 ) 330 331 bui.textwidget( 332 parent=parent, 333 draw_controller=btn, 334 position=(x + 820 + x_offs, y + scly - 20), 335 size=(0, 0), 336 h_align='center', 337 text=bui.Lstr(resource=f'{self._r}.timeRemainingText'), 338 v_align='center', 339 maxwidth=180, 340 scale=0.9, 341 color=header_color, 342 flatness=1.0, 343 ) 344 self.time_remaining_value_text = bui.textwidget( 345 parent=parent, 346 draw_controller=btn, 347 position=(x + 820 + x_offs, y + scly - 68), 348 size=(0, 0), 349 h_align='center', 350 text='-', 351 v_align='center', 352 maxwidth=180, 353 scale=2.0, 354 color=value_color, 355 flatness=1.0, 356 ) 357 self.time_remaining_out_of_text = bui.textwidget( 358 parent=parent, 359 draw_controller=btn, 360 position=(x + 820 + x_offs, y + scly - 110), 361 size=(0, 0), 362 h_align='center', 363 text='-', 364 v_align='center', 365 maxwidth=120, 366 scale=0.72, 367 color=(0.4, 0.4, 0.5), 368 flatness=1.0, 369 )
def
update_for_data(self, entry: dict[str, typing.Any]) -> None:
410 def update_for_data(self, entry: dict[str, Any]) -> None: 411 """Update for new incoming data.""" 412 # pylint: disable=too-many-statements 413 # pylint: disable=too-many-locals 414 # pylint: disable=too-many-branches 415 416 plus = bui.app.plus 417 assert plus is not None 418 419 assert bui.app.classic is not None 420 prize_y_offs = ( 421 34 422 if 'prizeRange3' in entry 423 else 20 if 'prizeRange2' in entry else 12 424 ) 425 x_offs = 90 426 427 # pylint: disable=useless-suppression 428 # pylint: disable=unbalanced-tuple-unpacking 429 ( 430 pr1, 431 pv1, 432 pr2, 433 pv2, 434 pr3, 435 pv3, 436 ) = bui.app.classic.get_tournament_prize_strings(entry) 437 # pylint: enable=unbalanced-tuple-unpacking 438 # pylint: enable=useless-suppression 439 440 enabled = 'requiredLeague' not in entry 441 bui.buttonwidget( 442 edit=self.button, 443 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 444 ) 445 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 446 bui.textwidget( 447 edit=self.prize_range_1_text, 448 text='-' if pr1 == '' else pr1, 449 position=( 450 self.button_x + 365 + x_offs, 451 self.button_y + self.button_scale_y - 93 + prize_y_offs, 452 ), 453 ) 454 455 # We want to draw values containing tickets a bit smaller 456 # (scratch that; we now draw medals a bit bigger). 457 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 458 prize_value_scale_large = 1.0 459 prize_value_scale_small = 1.0 460 461 bui.textwidget( 462 edit=self.prize_value_1_text, 463 text='-' if pv1 == '' else pv1, 464 scale=( 465 prize_value_scale_large 466 if ticket_char not in pv1 467 else prize_value_scale_small 468 ), 469 position=( 470 self.button_x + 380 + x_offs, 471 self.button_y + self.button_scale_y - 93 + prize_y_offs, 472 ), 473 ) 474 475 bui.textwidget( 476 edit=self.prize_range_2_text, 477 text=pr2, 478 position=( 479 self.button_x + 365 + x_offs, 480 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 481 ), 482 ) 483 bui.textwidget( 484 edit=self.prize_value_2_text, 485 text=pv2, 486 scale=( 487 prize_value_scale_large 488 if ticket_char not in pv2 489 else prize_value_scale_small 490 ), 491 position=( 492 self.button_x + 380 + x_offs, 493 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 494 ), 495 ) 496 497 bui.textwidget( 498 edit=self.prize_range_3_text, 499 text=pr3, 500 position=( 501 self.button_x + 365 + x_offs, 502 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 503 ), 504 ) 505 bui.textwidget( 506 edit=self.prize_value_3_text, 507 text=pv3, 508 scale=( 509 prize_value_scale_large 510 if ticket_char not in pv3 511 else prize_value_scale_small 512 ), 513 position=( 514 self.button_x + 380 + x_offs, 515 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 516 ), 517 ) 518 519 leader_name = '-' 520 leader_score: str | bui.Lstr = '-' 521 if entry['scores']: 522 score = self.leader = copy.deepcopy(entry['scores'][0]) 523 leader_name = score[1] 524 leader_score = ( 525 bui.timestring((score[0] * 10) / 1000.0, centi=True) 526 if entry['scoreType'] == 'time' 527 else str(score[0]) 528 ) 529 else: 530 self.leader = None 531 532 bui.textwidget( 533 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 534 ) 535 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 536 bui.buttonwidget( 537 edit=self.more_scores_button, 538 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 539 ) 540 out_of_time_text: str | bui.Lstr = ( 541 '-' 542 if 'totalTime' not in entry 543 else bui.Lstr( 544 resource=f'{self._r}.ofTotalTimeText', 545 subs=[ 546 ( 547 '${TOTAL}', 548 bui.timestring(entry['totalTime'], centi=False), 549 ) 550 ], 551 ) 552 ) 553 bui.textwidget( 554 edit=self.time_remaining_out_of_text, text=out_of_time_text 555 ) 556 557 self.time_remaining = entry['timeRemaining'] 558 self.has_time_remaining = entry is not None 559 self.tournament_id = entry['tournamentID'] 560 self.required_league = ( 561 None if 'requiredLeague' not in entry else entry['requiredLeague'] 562 ) 563 564 assert bui.app.classic is not None 565 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 566 'game' 567 ] 568 569 if game is None: 570 bui.textwidget(edit=self.button_text, text='-') 571 bui.imagewidget( 572 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 573 ) 574 else: 575 campaignname, levelname = game.split(':') 576 campaign = bui.app.classic.getcampaign(campaignname) 577 max_players = bui.app.classic.accounts.tournament_info[ 578 self.tournament_id 579 ]['maxPlayers'] 580 txt = bui.Lstr( 581 value='${A} ${B}', 582 subs=[ 583 ('${A}', campaign.getlevel(levelname).displayname), 584 ( 585 '${B}', 586 bui.Lstr( 587 resource='playerCountAbbreviatedText', 588 subs=[('${COUNT}', str(max_players))], 589 ), 590 ), 591 ], 592 ) 593 bui.textwidget(edit=self.button_text, text=txt) 594 bui.imagewidget( 595 edit=self.image, 596 texture=bui.gettexture( 597 campaign.getlevel(levelname).preview_texture_name 598 ), 599 opacity=1.0 if enabled else 0.5, 600 ) 601 602 fee = entry['fee'] 603 604 if fee is None: 605 fee_var = None 606 elif fee == 4: 607 fee_var = 'price.tournament_entry_4' 608 elif fee == 3: 609 fee_var = 'price.tournament_entry_3' 610 elif fee == 2: 611 fee_var = 'price.tournament_entry_2' 612 elif fee == 1: 613 fee_var = 'price.tournament_entry_1' 614 else: 615 if fee != 0: 616 print('Unknown fee value:', fee) 617 fee_var = 'price.tournament_entry_0' 618 619 self.allow_ads = allow_ads = entry['allowAds'] 620 621 final_fee: int | None = ( 622 None 623 if fee_var is None 624 else plus.get_v1_account_misc_read_val(fee_var, '?') 625 ) 626 627 final_fee_str: str | bui.Lstr 628 if fee_var is None: 629 final_fee_str = '' 630 else: 631 if final_fee == 0: 632 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 633 else: 634 final_fee_str = bui.charstr( 635 bui.SpecialChar.TICKET_BACKING 636 ) + str(final_fee) 637 638 assert bui.app.classic is not None 639 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 640 self.tournament_id 641 ]['adTriesRemaining'] 642 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 643 self.tournament_id 644 ]['freeTriesRemaining'] 645 646 # Now, if this fee allows ads and we support video ads, show 647 # the 'or ad' version. 648 if allow_ads and plus.has_video_ads(): 649 ads_enabled = plus.have_incentivized_ad() 650 bui.imagewidget( 651 edit=self.entry_fee_ad_image, 652 opacity=1.0 if ads_enabled else 0.25, 653 ) 654 or_text = ( 655 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 656 .evaluate() 657 .strip() 658 ) 659 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 660 bui.textwidget( 661 edit=self.entry_fee_text_top, 662 position=( 663 self.button_x + 360, 664 self.button_y + self.button_scale_y - 60, 665 ), 666 scale=1.3, 667 text=final_fee_str, 668 ) 669 670 # Possibly show number of ad-plays remaining. 671 bui.textwidget( 672 edit=self.entry_fee_text_remaining, 673 position=( 674 self.button_x + 360, 675 self.button_y + self.button_scale_y - 146, 676 ), 677 text=( 678 '' 679 if ad_tries_remaining in [None, 0] 680 else ('' + str(ad_tries_remaining)) 681 ), 682 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 683 ) 684 else: 685 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 686 bui.textwidget(edit=self.entry_fee_text_or, text='') 687 bui.textwidget( 688 edit=self.entry_fee_text_top, 689 position=( 690 self.button_x + 360, 691 self.button_y + self.button_scale_y - 80, 692 ), 693 scale=1.3, 694 text=final_fee_str, 695 ) 696 697 # Possibly show number of free-plays remaining. 698 bui.textwidget( 699 edit=self.entry_fee_text_remaining, 700 position=( 701 self.button_x + 360, 702 self.button_y + self.button_scale_y - 100, 703 ), 704 text=( 705 '' 706 if (free_tries_remaining in [None, 0] or final_fee != 0) 707 else ('' + str(free_tries_remaining)) 708 ), 709 color=(0.6, 0.6, 0.6, 1), 710 )
Update for new incoming data.