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