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