bastd.ui.creditslist
Provides a window to display game credits.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a window to display game credits.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8 9import _ba 10import ba 11 12if TYPE_CHECKING: 13 from typing import Sequence 14 15 16class CreditsListWindow(ba.Window): 17 """Window for displaying game credits.""" 18 19 def __init__(self, origin_widget: ba.Widget | None = None): 20 # pylint: disable=too-many-locals 21 # pylint: disable=too-many-statements 22 import json 23 ba.set_analytics_screen('Credits Window') 24 25 # if they provided an origin-widget, scale up from that 26 scale_origin: tuple[float, float] | None 27 if origin_widget is not None: 28 self._transition_out = 'out_scale' 29 scale_origin = origin_widget.get_screen_space_center() 30 transition = 'in_scale' 31 else: 32 self._transition_out = 'out_right' 33 scale_origin = None 34 transition = 'in_right' 35 36 uiscale = ba.app.ui.uiscale 37 width = 870 if uiscale is ba.UIScale.SMALL else 670 38 x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 39 height = 398 if uiscale is ba.UIScale.SMALL else 500 40 41 self._r = 'creditsWindow' 42 super().__init__(root_widget=ba.containerwidget( 43 size=(width, height), 44 transition=transition, 45 toolbar_visibility='menu_minimal', 46 scale_origin_stack_offset=scale_origin, 47 scale=(2.0 if uiscale is ba.UIScale.SMALL else 48 1.3 if uiscale is ba.UIScale.MEDIUM else 1.0), 49 stack_offset=(0, -8) if uiscale is ba.UIScale.SMALL else (0, 0))) 50 51 if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL: 52 ba.containerwidget(edit=self._root_widget, 53 on_cancel_call=self._back) 54 else: 55 btn = ba.buttonwidget( 56 parent=self._root_widget, 57 position=(40 + x_inset, height - 58 (68 if uiscale is ba.UIScale.SMALL else 62)), 59 size=(140, 60), 60 scale=0.8, 61 label=ba.Lstr(resource='backText'), 62 button_type='back', 63 on_activate_call=self._back, 64 autoselect=True) 65 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 66 67 ba.buttonwidget( 68 edit=btn, 69 button_type='backSmall', 70 position=(40 + x_inset, height - 71 (68 if uiscale is ba.UIScale.SMALL else 62) + 5), 72 size=(60, 48), 73 label=ba.charstr(ba.SpecialChar.BACK)) 74 75 ba.textwidget(parent=self._root_widget, 76 position=(0, height - 77 (59 if uiscale is ba.UIScale.SMALL else 54)), 78 size=(width, 30), 79 text=ba.Lstr(resource=self._r + '.titleText', 80 subs=[('${APP_NAME}', 81 ba.Lstr(resource='titleText'))]), 82 h_align='center', 83 color=ba.app.ui.title_color, 84 maxwidth=330, 85 v_align='center') 86 87 scroll = ba.scrollwidget(parent=self._root_widget, 88 position=(40 + x_inset, 35), 89 size=(width - (80 + 2 * x_inset), 90 height - 100), 91 capture_arrows=True) 92 93 if ba.app.ui.use_toolbars: 94 ba.widget(edit=scroll, 95 right_widget=_ba.get_special_widget('party_button')) 96 if uiscale is ba.UIScale.SMALL: 97 ba.widget(edit=scroll, 98 left_widget=_ba.get_special_widget('back_button')) 99 100 def _format_names(names2: Sequence[str], inset: float) -> str: 101 sval = '' 102 # measure a series since there's overlaps and stuff.. 103 space_width = _ba.get_string_width(' ' * 10, 104 suppress_warning=True) / 10.0 105 spacing = 330.0 106 col1 = inset 107 col2 = col1 + spacing 108 col3 = col2 + spacing 109 line_width = 0.0 110 nline = '' 111 for name in names2: 112 # move to the next column (or row) and print 113 if line_width > col3: 114 sval += nline + '\n' 115 nline = '' 116 line_width = 0 117 118 if line_width > col2: 119 target = col3 120 elif line_width > col1: 121 target = col2 122 else: 123 target = col1 124 spacingstr = ' ' * int((target - line_width) / space_width) 125 nline += spacingstr 126 nline += name 127 line_width = _ba.get_string_width(nline, suppress_warning=True) 128 if nline != '': 129 sval += nline + '\n' 130 return sval 131 132 sound_and_music = ba.Lstr(resource=self._r + 133 '.songCreditText').evaluate() 134 sound_and_music = sound_and_music.replace( 135 '${TITLE}', "'William Tell (Trumpet Entry)'") 136 sound_and_music = sound_and_music.replace( 137 '${PERFORMER}', 'The Apollo Symphony Orchestra') 138 sound_and_music = sound_and_music.replace( 139 '${PERFORMER}', 'The Apollo Symphony Orchestra') 140 sound_and_music = sound_and_music.replace('${COMPOSER}', 141 'Gioacchino Rossini') 142 sound_and_music = sound_and_music.replace('${ARRANGER}', 'Chris Worth') 143 sound_and_music = sound_and_music.replace('${PUBLISHER}', 'BMI') 144 sound_and_music = sound_and_music.replace('${SOURCE}', 145 'www.AudioSparx.com') 146 spc = ' ' 147 sound_and_music = spc + sound_and_music.replace('\n', '\n' + spc) 148 names = [ 149 'HubOfTheUniverseProd', 'Jovica', 'LG', 'Leady', 'Percy Duke', 150 'PhreaKsAccount', 'Pogotron', 'Rock Savage', 'anamorphosis', 151 'benboncan', 'cdrk', 'chipfork', 'guitarguy1985', 'jascha', 152 'joedeshon', 'loofa', 'm_O_m', 'mich3d', 'sandyrb', 'shakaharu', 153 'sirplus', 'stickman', 'thanvannispen', 'virotic', 'zimbot' 154 ] 155 names.sort(key=lambda x: x.lower()) 156 freesound_names = _format_names(names, 90) 157 158 try: 159 with open('ba_data/data/langdata.json', 160 encoding='utf-8') as infile: 161 translation_contributors = (json.loads( 162 infile.read())['translation_contributors']) 163 except Exception: 164 ba.print_exception('Error reading translation contributors.') 165 translation_contributors = [] 166 167 translation_names = _format_names(translation_contributors, 60) 168 169 # Need to bake this out and chop it up since we're passing our 170 # 65535 vertex limit for meshes.. 171 # We can remove that limit once we drop support for GL ES2.. :-/ 172 # (or add mesh splitting under the hood) 173 credits_text = ( 174 ' ' + ba.Lstr(resource=self._r + 175 '.codingGraphicsAudioText').evaluate().replace( 176 '${NAME}', 'Eric Froemling') + '\n' 177 '\n' 178 ' ' + ba.Lstr(resource=self._r + 179 '.additionalAudioArtIdeasText').evaluate().replace( 180 '${NAME}', 'Raphael Suter') + '\n' 181 '\n' 182 ' ' + 183 ba.Lstr(resource=self._r + '.soundAndMusicText').evaluate() + '\n' 184 '\n' + sound_and_music + '\n' 185 '\n' 186 ' ' + ba.Lstr(resource=self._r + 187 '.publicDomainMusicViaText').evaluate().replace( 188 '${NAME}', 'Musopen.com') + '\n' 189 ' ' + 190 ba.Lstr(resource=self._r + 191 '.thanksEspeciallyToText').evaluate().replace( 192 '${NAME}', 'the US Army, Navy, and Marine Bands') + 193 '\n' 194 '\n' 195 ' ' + ba.Lstr(resource=self._r + 196 '.additionalMusicFromText').evaluate().replace( 197 '${NAME}', 'The YouTube Audio Library') + 198 '\n' 199 '\n' 200 ' ' + 201 ba.Lstr(resource=self._r + '.soundsText').evaluate().replace( 202 '${SOURCE}', 'Freesound.org') + '\n' 203 '\n' + freesound_names + '\n' 204 '\n' 205 ' ' + ba.Lstr(resource=self._r + 206 '.languageTranslationsText').evaluate() + '\n' 207 '\n' + '\n'.join(translation_names.splitlines()[:146]) + 208 '\n'.join(translation_names.splitlines()[146:]) + '\n' 209 '\n' 210 ' Shout Out to Awesome Mods / Modders / Contributors:\n\n' 211 ' BombDash ModPack\n' 212 ' TheMikirog & SoK - BombSquad Joyride Modpack\n' 213 ' Mrmaxmeier - BombSquad-Community-Mod-Manager\n' 214 ' Ritiek Malhotra \n' 215 ' Dliwk\n' 216 ' vishal332008\n' 217 ' itsre3\n' 218 ' Drooopyyy\n' 219 '\n' 220 ' Holiday theme vector art designed by Freepik\n' 221 '\n' 222 ' ' + 223 ba.Lstr(resource=self._r + '.specialThanksText').evaluate() + '\n' 224 '\n' 225 ' Todd, Laura, and Robert Froemling\n' 226 ' ' + 227 ba.Lstr(resource=self._r + '.allMyFamilyText').evaluate().replace( 228 '\n', '\n ') + '\n' 229 ' ' + ba.Lstr(resource=self._r + 230 '.whoeverInventedCoffeeText').evaluate() + '\n' 231 '\n' 232 ' ' + ba.Lstr(resource=self._r + '.legalText').evaluate() + '\n' 233 '\n' 234 ' ' + ba.Lstr(resource=self._r + 235 '.softwareBasedOnText').evaluate().replace( 236 '${NAME}', 'the Khronos Group') + '\n' 237 '\n' 238 ' ' 239 ' www.froemling.net\n') 240 241 txt = credits_text 242 lines = txt.splitlines() 243 line_height = 20 244 245 scale = 0.55 246 self._sub_width = width - 80 247 self._sub_height = line_height * len(lines) + 40 248 249 container = self._subcontainer = ba.containerwidget( 250 parent=scroll, 251 size=(self._sub_width, self._sub_height), 252 background=False, 253 claims_left_right=False, 254 claims_tab=False) 255 256 voffs = 0 257 for line in lines: 258 ba.textwidget(parent=container, 259 padding=4, 260 color=(0.7, 0.9, 0.7, 1.0), 261 scale=scale, 262 flatness=1.0, 263 size=(0, 0), 264 position=(0, self._sub_height - 20 + voffs), 265 h_align='left', 266 v_align='top', 267 text=ba.Lstr(value=line)) 268 voffs -= line_height 269 270 def _back(self) -> None: 271 from bastd.ui.mainmenu import MainMenuWindow 272 ba.containerwidget(edit=self._root_widget, 273 transition=self._transition_out) 274 ba.app.ui.set_main_menu_window( 275 MainMenuWindow(transition='in_left').get_root_widget())
class
CreditsListWindow(ba.ui.Window):
17class CreditsListWindow(ba.Window): 18 """Window for displaying game credits.""" 19 20 def __init__(self, origin_widget: ba.Widget | None = None): 21 # pylint: disable=too-many-locals 22 # pylint: disable=too-many-statements 23 import json 24 ba.set_analytics_screen('Credits Window') 25 26 # if they provided an origin-widget, scale up from that 27 scale_origin: tuple[float, float] | None 28 if origin_widget is not None: 29 self._transition_out = 'out_scale' 30 scale_origin = origin_widget.get_screen_space_center() 31 transition = 'in_scale' 32 else: 33 self._transition_out = 'out_right' 34 scale_origin = None 35 transition = 'in_right' 36 37 uiscale = ba.app.ui.uiscale 38 width = 870 if uiscale is ba.UIScale.SMALL else 670 39 x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 40 height = 398 if uiscale is ba.UIScale.SMALL else 500 41 42 self._r = 'creditsWindow' 43 super().__init__(root_widget=ba.containerwidget( 44 size=(width, height), 45 transition=transition, 46 toolbar_visibility='menu_minimal', 47 scale_origin_stack_offset=scale_origin, 48 scale=(2.0 if uiscale is ba.UIScale.SMALL else 49 1.3 if uiscale is ba.UIScale.MEDIUM else 1.0), 50 stack_offset=(0, -8) if uiscale is ba.UIScale.SMALL else (0, 0))) 51 52 if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL: 53 ba.containerwidget(edit=self._root_widget, 54 on_cancel_call=self._back) 55 else: 56 btn = ba.buttonwidget( 57 parent=self._root_widget, 58 position=(40 + x_inset, height - 59 (68 if uiscale is ba.UIScale.SMALL else 62)), 60 size=(140, 60), 61 scale=0.8, 62 label=ba.Lstr(resource='backText'), 63 button_type='back', 64 on_activate_call=self._back, 65 autoselect=True) 66 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 67 68 ba.buttonwidget( 69 edit=btn, 70 button_type='backSmall', 71 position=(40 + x_inset, height - 72 (68 if uiscale is ba.UIScale.SMALL else 62) + 5), 73 size=(60, 48), 74 label=ba.charstr(ba.SpecialChar.BACK)) 75 76 ba.textwidget(parent=self._root_widget, 77 position=(0, height - 78 (59 if uiscale is ba.UIScale.SMALL else 54)), 79 size=(width, 30), 80 text=ba.Lstr(resource=self._r + '.titleText', 81 subs=[('${APP_NAME}', 82 ba.Lstr(resource='titleText'))]), 83 h_align='center', 84 color=ba.app.ui.title_color, 85 maxwidth=330, 86 v_align='center') 87 88 scroll = ba.scrollwidget(parent=self._root_widget, 89 position=(40 + x_inset, 35), 90 size=(width - (80 + 2 * x_inset), 91 height - 100), 92 capture_arrows=True) 93 94 if ba.app.ui.use_toolbars: 95 ba.widget(edit=scroll, 96 right_widget=_ba.get_special_widget('party_button')) 97 if uiscale is ba.UIScale.SMALL: 98 ba.widget(edit=scroll, 99 left_widget=_ba.get_special_widget('back_button')) 100 101 def _format_names(names2: Sequence[str], inset: float) -> str: 102 sval = '' 103 # measure a series since there's overlaps and stuff.. 104 space_width = _ba.get_string_width(' ' * 10, 105 suppress_warning=True) / 10.0 106 spacing = 330.0 107 col1 = inset 108 col2 = col1 + spacing 109 col3 = col2 + spacing 110 line_width = 0.0 111 nline = '' 112 for name in names2: 113 # move to the next column (or row) and print 114 if line_width > col3: 115 sval += nline + '\n' 116 nline = '' 117 line_width = 0 118 119 if line_width > col2: 120 target = col3 121 elif line_width > col1: 122 target = col2 123 else: 124 target = col1 125 spacingstr = ' ' * int((target - line_width) / space_width) 126 nline += spacingstr 127 nline += name 128 line_width = _ba.get_string_width(nline, suppress_warning=True) 129 if nline != '': 130 sval += nline + '\n' 131 return sval 132 133 sound_and_music = ba.Lstr(resource=self._r + 134 '.songCreditText').evaluate() 135 sound_and_music = sound_and_music.replace( 136 '${TITLE}', "'William Tell (Trumpet Entry)'") 137 sound_and_music = sound_and_music.replace( 138 '${PERFORMER}', 'The Apollo Symphony Orchestra') 139 sound_and_music = sound_and_music.replace( 140 '${PERFORMER}', 'The Apollo Symphony Orchestra') 141 sound_and_music = sound_and_music.replace('${COMPOSER}', 142 'Gioacchino Rossini') 143 sound_and_music = sound_and_music.replace('${ARRANGER}', 'Chris Worth') 144 sound_and_music = sound_and_music.replace('${PUBLISHER}', 'BMI') 145 sound_and_music = sound_and_music.replace('${SOURCE}', 146 'www.AudioSparx.com') 147 spc = ' ' 148 sound_and_music = spc + sound_and_music.replace('\n', '\n' + spc) 149 names = [ 150 'HubOfTheUniverseProd', 'Jovica', 'LG', 'Leady', 'Percy Duke', 151 'PhreaKsAccount', 'Pogotron', 'Rock Savage', 'anamorphosis', 152 'benboncan', 'cdrk', 'chipfork', 'guitarguy1985', 'jascha', 153 'joedeshon', 'loofa', 'm_O_m', 'mich3d', 'sandyrb', 'shakaharu', 154 'sirplus', 'stickman', 'thanvannispen', 'virotic', 'zimbot' 155 ] 156 names.sort(key=lambda x: x.lower()) 157 freesound_names = _format_names(names, 90) 158 159 try: 160 with open('ba_data/data/langdata.json', 161 encoding='utf-8') as infile: 162 translation_contributors = (json.loads( 163 infile.read())['translation_contributors']) 164 except Exception: 165 ba.print_exception('Error reading translation contributors.') 166 translation_contributors = [] 167 168 translation_names = _format_names(translation_contributors, 60) 169 170 # Need to bake this out and chop it up since we're passing our 171 # 65535 vertex limit for meshes.. 172 # We can remove that limit once we drop support for GL ES2.. :-/ 173 # (or add mesh splitting under the hood) 174 credits_text = ( 175 ' ' + ba.Lstr(resource=self._r + 176 '.codingGraphicsAudioText').evaluate().replace( 177 '${NAME}', 'Eric Froemling') + '\n' 178 '\n' 179 ' ' + ba.Lstr(resource=self._r + 180 '.additionalAudioArtIdeasText').evaluate().replace( 181 '${NAME}', 'Raphael Suter') + '\n' 182 '\n' 183 ' ' + 184 ba.Lstr(resource=self._r + '.soundAndMusicText').evaluate() + '\n' 185 '\n' + sound_and_music + '\n' 186 '\n' 187 ' ' + ba.Lstr(resource=self._r + 188 '.publicDomainMusicViaText').evaluate().replace( 189 '${NAME}', 'Musopen.com') + '\n' 190 ' ' + 191 ba.Lstr(resource=self._r + 192 '.thanksEspeciallyToText').evaluate().replace( 193 '${NAME}', 'the US Army, Navy, and Marine Bands') + 194 '\n' 195 '\n' 196 ' ' + ba.Lstr(resource=self._r + 197 '.additionalMusicFromText').evaluate().replace( 198 '${NAME}', 'The YouTube Audio Library') + 199 '\n' 200 '\n' 201 ' ' + 202 ba.Lstr(resource=self._r + '.soundsText').evaluate().replace( 203 '${SOURCE}', 'Freesound.org') + '\n' 204 '\n' + freesound_names + '\n' 205 '\n' 206 ' ' + ba.Lstr(resource=self._r + 207 '.languageTranslationsText').evaluate() + '\n' 208 '\n' + '\n'.join(translation_names.splitlines()[:146]) + 209 '\n'.join(translation_names.splitlines()[146:]) + '\n' 210 '\n' 211 ' Shout Out to Awesome Mods / Modders / Contributors:\n\n' 212 ' BombDash ModPack\n' 213 ' TheMikirog & SoK - BombSquad Joyride Modpack\n' 214 ' Mrmaxmeier - BombSquad-Community-Mod-Manager\n' 215 ' Ritiek Malhotra \n' 216 ' Dliwk\n' 217 ' vishal332008\n' 218 ' itsre3\n' 219 ' Drooopyyy\n' 220 '\n' 221 ' Holiday theme vector art designed by Freepik\n' 222 '\n' 223 ' ' + 224 ba.Lstr(resource=self._r + '.specialThanksText').evaluate() + '\n' 225 '\n' 226 ' Todd, Laura, and Robert Froemling\n' 227 ' ' + 228 ba.Lstr(resource=self._r + '.allMyFamilyText').evaluate().replace( 229 '\n', '\n ') + '\n' 230 ' ' + ba.Lstr(resource=self._r + 231 '.whoeverInventedCoffeeText').evaluate() + '\n' 232 '\n' 233 ' ' + ba.Lstr(resource=self._r + '.legalText').evaluate() + '\n' 234 '\n' 235 ' ' + ba.Lstr(resource=self._r + 236 '.softwareBasedOnText').evaluate().replace( 237 '${NAME}', 'the Khronos Group') + '\n' 238 '\n' 239 ' ' 240 ' www.froemling.net\n') 241 242 txt = credits_text 243 lines = txt.splitlines() 244 line_height = 20 245 246 scale = 0.55 247 self._sub_width = width - 80 248 self._sub_height = line_height * len(lines) + 40 249 250 container = self._subcontainer = ba.containerwidget( 251 parent=scroll, 252 size=(self._sub_width, self._sub_height), 253 background=False, 254 claims_left_right=False, 255 claims_tab=False) 256 257 voffs = 0 258 for line in lines: 259 ba.textwidget(parent=container, 260 padding=4, 261 color=(0.7, 0.9, 0.7, 1.0), 262 scale=scale, 263 flatness=1.0, 264 size=(0, 0), 265 position=(0, self._sub_height - 20 + voffs), 266 h_align='left', 267 v_align='top', 268 text=ba.Lstr(value=line)) 269 voffs -= line_height 270 271 def _back(self) -> None: 272 from bastd.ui.mainmenu import MainMenuWindow 273 ba.containerwidget(edit=self._root_widget, 274 transition=self._transition_out) 275 ba.app.ui.set_main_menu_window( 276 MainMenuWindow(transition='in_left').get_root_widget())
Window for displaying game credits.
CreditsListWindow(origin_widget: _ba.Widget | None = None)
20 def __init__(self, origin_widget: ba.Widget | None = None): 21 # pylint: disable=too-many-locals 22 # pylint: disable=too-many-statements 23 import json 24 ba.set_analytics_screen('Credits Window') 25 26 # if they provided an origin-widget, scale up from that 27 scale_origin: tuple[float, float] | None 28 if origin_widget is not None: 29 self._transition_out = 'out_scale' 30 scale_origin = origin_widget.get_screen_space_center() 31 transition = 'in_scale' 32 else: 33 self._transition_out = 'out_right' 34 scale_origin = None 35 transition = 'in_right' 36 37 uiscale = ba.app.ui.uiscale 38 width = 870 if uiscale is ba.UIScale.SMALL else 670 39 x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 40 height = 398 if uiscale is ba.UIScale.SMALL else 500 41 42 self._r = 'creditsWindow' 43 super().__init__(root_widget=ba.containerwidget( 44 size=(width, height), 45 transition=transition, 46 toolbar_visibility='menu_minimal', 47 scale_origin_stack_offset=scale_origin, 48 scale=(2.0 if uiscale is ba.UIScale.SMALL else 49 1.3 if uiscale is ba.UIScale.MEDIUM else 1.0), 50 stack_offset=(0, -8) if uiscale is ba.UIScale.SMALL else (0, 0))) 51 52 if ba.app.ui.use_toolbars and uiscale is ba.UIScale.SMALL: 53 ba.containerwidget(edit=self._root_widget, 54 on_cancel_call=self._back) 55 else: 56 btn = ba.buttonwidget( 57 parent=self._root_widget, 58 position=(40 + x_inset, height - 59 (68 if uiscale is ba.UIScale.SMALL else 62)), 60 size=(140, 60), 61 scale=0.8, 62 label=ba.Lstr(resource='backText'), 63 button_type='back', 64 on_activate_call=self._back, 65 autoselect=True) 66 ba.containerwidget(edit=self._root_widget, cancel_button=btn) 67 68 ba.buttonwidget( 69 edit=btn, 70 button_type='backSmall', 71 position=(40 + x_inset, height - 72 (68 if uiscale is ba.UIScale.SMALL else 62) + 5), 73 size=(60, 48), 74 label=ba.charstr(ba.SpecialChar.BACK)) 75 76 ba.textwidget(parent=self._root_widget, 77 position=(0, height - 78 (59 if uiscale is ba.UIScale.SMALL else 54)), 79 size=(width, 30), 80 text=ba.Lstr(resource=self._r + '.titleText', 81 subs=[('${APP_NAME}', 82 ba.Lstr(resource='titleText'))]), 83 h_align='center', 84 color=ba.app.ui.title_color, 85 maxwidth=330, 86 v_align='center') 87 88 scroll = ba.scrollwidget(parent=self._root_widget, 89 position=(40 + x_inset, 35), 90 size=(width - (80 + 2 * x_inset), 91 height - 100), 92 capture_arrows=True) 93 94 if ba.app.ui.use_toolbars: 95 ba.widget(edit=scroll, 96 right_widget=_ba.get_special_widget('party_button')) 97 if uiscale is ba.UIScale.SMALL: 98 ba.widget(edit=scroll, 99 left_widget=_ba.get_special_widget('back_button')) 100 101 def _format_names(names2: Sequence[str], inset: float) -> str: 102 sval = '' 103 # measure a series since there's overlaps and stuff.. 104 space_width = _ba.get_string_width(' ' * 10, 105 suppress_warning=True) / 10.0 106 spacing = 330.0 107 col1 = inset 108 col2 = col1 + spacing 109 col3 = col2 + spacing 110 line_width = 0.0 111 nline = '' 112 for name in names2: 113 # move to the next column (or row) and print 114 if line_width > col3: 115 sval += nline + '\n' 116 nline = '' 117 line_width = 0 118 119 if line_width > col2: 120 target = col3 121 elif line_width > col1: 122 target = col2 123 else: 124 target = col1 125 spacingstr = ' ' * int((target - line_width) / space_width) 126 nline += spacingstr 127 nline += name 128 line_width = _ba.get_string_width(nline, suppress_warning=True) 129 if nline != '': 130 sval += nline + '\n' 131 return sval 132 133 sound_and_music = ba.Lstr(resource=self._r + 134 '.songCreditText').evaluate() 135 sound_and_music = sound_and_music.replace( 136 '${TITLE}', "'William Tell (Trumpet Entry)'") 137 sound_and_music = sound_and_music.replace( 138 '${PERFORMER}', 'The Apollo Symphony Orchestra') 139 sound_and_music = sound_and_music.replace( 140 '${PERFORMER}', 'The Apollo Symphony Orchestra') 141 sound_and_music = sound_and_music.replace('${COMPOSER}', 142 'Gioacchino Rossini') 143 sound_and_music = sound_and_music.replace('${ARRANGER}', 'Chris Worth') 144 sound_and_music = sound_and_music.replace('${PUBLISHER}', 'BMI') 145 sound_and_music = sound_and_music.replace('${SOURCE}', 146 'www.AudioSparx.com') 147 spc = ' ' 148 sound_and_music = spc + sound_and_music.replace('\n', '\n' + spc) 149 names = [ 150 'HubOfTheUniverseProd', 'Jovica', 'LG', 'Leady', 'Percy Duke', 151 'PhreaKsAccount', 'Pogotron', 'Rock Savage', 'anamorphosis', 152 'benboncan', 'cdrk', 'chipfork', 'guitarguy1985', 'jascha', 153 'joedeshon', 'loofa', 'm_O_m', 'mich3d', 'sandyrb', 'shakaharu', 154 'sirplus', 'stickman', 'thanvannispen', 'virotic', 'zimbot' 155 ] 156 names.sort(key=lambda x: x.lower()) 157 freesound_names = _format_names(names, 90) 158 159 try: 160 with open('ba_data/data/langdata.json', 161 encoding='utf-8') as infile: 162 translation_contributors = (json.loads( 163 infile.read())['translation_contributors']) 164 except Exception: 165 ba.print_exception('Error reading translation contributors.') 166 translation_contributors = [] 167 168 translation_names = _format_names(translation_contributors, 60) 169 170 # Need to bake this out and chop it up since we're passing our 171 # 65535 vertex limit for meshes.. 172 # We can remove that limit once we drop support for GL ES2.. :-/ 173 # (or add mesh splitting under the hood) 174 credits_text = ( 175 ' ' + ba.Lstr(resource=self._r + 176 '.codingGraphicsAudioText').evaluate().replace( 177 '${NAME}', 'Eric Froemling') + '\n' 178 '\n' 179 ' ' + ba.Lstr(resource=self._r + 180 '.additionalAudioArtIdeasText').evaluate().replace( 181 '${NAME}', 'Raphael Suter') + '\n' 182 '\n' 183 ' ' + 184 ba.Lstr(resource=self._r + '.soundAndMusicText').evaluate() + '\n' 185 '\n' + sound_and_music + '\n' 186 '\n' 187 ' ' + ba.Lstr(resource=self._r + 188 '.publicDomainMusicViaText').evaluate().replace( 189 '${NAME}', 'Musopen.com') + '\n' 190 ' ' + 191 ba.Lstr(resource=self._r + 192 '.thanksEspeciallyToText').evaluate().replace( 193 '${NAME}', 'the US Army, Navy, and Marine Bands') + 194 '\n' 195 '\n' 196 ' ' + ba.Lstr(resource=self._r + 197 '.additionalMusicFromText').evaluate().replace( 198 '${NAME}', 'The YouTube Audio Library') + 199 '\n' 200 '\n' 201 ' ' + 202 ba.Lstr(resource=self._r + '.soundsText').evaluate().replace( 203 '${SOURCE}', 'Freesound.org') + '\n' 204 '\n' + freesound_names + '\n' 205 '\n' 206 ' ' + ba.Lstr(resource=self._r + 207 '.languageTranslationsText').evaluate() + '\n' 208 '\n' + '\n'.join(translation_names.splitlines()[:146]) + 209 '\n'.join(translation_names.splitlines()[146:]) + '\n' 210 '\n' 211 ' Shout Out to Awesome Mods / Modders / Contributors:\n\n' 212 ' BombDash ModPack\n' 213 ' TheMikirog & SoK - BombSquad Joyride Modpack\n' 214 ' Mrmaxmeier - BombSquad-Community-Mod-Manager\n' 215 ' Ritiek Malhotra \n' 216 ' Dliwk\n' 217 ' vishal332008\n' 218 ' itsre3\n' 219 ' Drooopyyy\n' 220 '\n' 221 ' Holiday theme vector art designed by Freepik\n' 222 '\n' 223 ' ' + 224 ba.Lstr(resource=self._r + '.specialThanksText').evaluate() + '\n' 225 '\n' 226 ' Todd, Laura, and Robert Froemling\n' 227 ' ' + 228 ba.Lstr(resource=self._r + '.allMyFamilyText').evaluate().replace( 229 '\n', '\n ') + '\n' 230 ' ' + ba.Lstr(resource=self._r + 231 '.whoeverInventedCoffeeText').evaluate() + '\n' 232 '\n' 233 ' ' + ba.Lstr(resource=self._r + '.legalText').evaluate() + '\n' 234 '\n' 235 ' ' + ba.Lstr(resource=self._r + 236 '.softwareBasedOnText').evaluate().replace( 237 '${NAME}', 'the Khronos Group') + '\n' 238 '\n' 239 ' ' 240 ' www.froemling.net\n') 241 242 txt = credits_text 243 lines = txt.splitlines() 244 line_height = 20 245 246 scale = 0.55 247 self._sub_width = width - 80 248 self._sub_height = line_height * len(lines) + 40 249 250 container = self._subcontainer = ba.containerwidget( 251 parent=scroll, 252 size=(self._sub_width, self._sub_height), 253 background=False, 254 claims_left_right=False, 255 claims_tab=False) 256 257 voffs = 0 258 for line in lines: 259 ba.textwidget(parent=container, 260 padding=4, 261 color=(0.7, 0.9, 0.7, 1.0), 262 scale=scale, 263 flatness=1.0, 264 size=(0, 0), 265 position=(0, self._sub_height - 20 + voffs), 266 h_align='left', 267 v_align='top', 268 text=ba.Lstr(value=line)) 269 voffs -= line_height
Inherited Members
- ba.ui.Window
- get_root_widget