crimsonland 0.1.0.dev14__py3-none-any.whl → 0.1.0.dev16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crimson/cli.py +63 -0
- crimson/creatures/damage.py +111 -36
- crimson/creatures/runtime.py +246 -156
- crimson/creatures/spawn.py +7 -3
- crimson/debug.py +9 -0
- crimson/demo.py +38 -45
- crimson/effects.py +7 -13
- crimson/frontend/high_scores_layout.py +81 -0
- crimson/frontend/panels/base.py +4 -1
- crimson/frontend/panels/controls.py +0 -15
- crimson/frontend/panels/databases.py +291 -3
- crimson/frontend/panels/mods.py +0 -15
- crimson/frontend/panels/play_game.py +0 -16
- crimson/game.py +689 -3
- crimson/gameplay.py +921 -569
- crimson/modes/base_gameplay_mode.py +33 -12
- crimson/modes/components/__init__.py +2 -0
- crimson/modes/components/highscore_record_builder.py +58 -0
- crimson/modes/components/perk_menu_controller.py +325 -0
- crimson/modes/quest_mode.py +94 -272
- crimson/modes/rush_mode.py +12 -43
- crimson/modes/survival_mode.py +109 -330
- crimson/modes/tutorial_mode.py +46 -247
- crimson/modes/typo_mode.py +11 -38
- crimson/oracle.py +396 -0
- crimson/perks.py +5 -2
- crimson/player_damage.py +95 -36
- crimson/projectiles.py +539 -320
- crimson/render/projectile_draw_registry.py +637 -0
- crimson/render/projectile_render_registry.py +110 -0
- crimson/render/secondary_projectile_draw_registry.py +206 -0
- crimson/render/world_renderer.py +58 -707
- crimson/sim/world_state.py +118 -61
- crimson/typo/spawns.py +5 -12
- crimson/ui/demo_trial_overlay.py +3 -11
- crimson/ui/formatting.py +24 -0
- crimson/ui/game_over.py +12 -58
- crimson/ui/hud.py +72 -39
- crimson/ui/layout.py +20 -0
- crimson/ui/perk_menu.py +9 -34
- crimson/ui/quest_results.py +28 -70
- crimson/ui/text_input.py +20 -0
- crimson/views/_ui_helpers.py +27 -0
- crimson/views/aim_debug.py +15 -32
- crimson/views/animations.py +18 -28
- crimson/views/arsenal_debug.py +22 -32
- crimson/views/bonuses.py +23 -36
- crimson/views/camera_debug.py +16 -29
- crimson/views/camera_shake.py +9 -33
- crimson/views/corpse_stamp_debug.py +13 -21
- crimson/views/decals_debug.py +36 -23
- crimson/views/fonts.py +8 -25
- crimson/views/ground.py +4 -21
- crimson/views/lighting_debug.py +42 -45
- crimson/views/particles.py +33 -42
- crimson/views/perk_menu_debug.py +3 -10
- crimson/views/player.py +50 -44
- crimson/views/player_sprite_debug.py +24 -31
- crimson/views/projectile_fx.py +57 -52
- crimson/views/projectile_render_debug.py +24 -33
- crimson/views/projectiles.py +24 -37
- crimson/views/spawn_plan.py +13 -29
- crimson/views/sprites.py +14 -29
- crimson/views/terrain.py +6 -23
- crimson/views/ui.py +7 -24
- crimson/views/wicons.py +28 -33
- {crimsonland-0.1.0.dev14.dist-info → crimsonland-0.1.0.dev16.dist-info}/METADATA +1 -1
- {crimsonland-0.1.0.dev14.dist-info → crimsonland-0.1.0.dev16.dist-info}/RECORD +73 -62
- {crimsonland-0.1.0.dev14.dist-info → crimsonland-0.1.0.dev16.dist-info}/WHEEL +1 -1
- grim/config.py +29 -1
- grim/console.py +7 -10
- grim/math.py +12 -0
- {crimsonland-0.1.0.dev14.dist-info → crimsonland-0.1.0.dev16.dist-info}/entry_points.txt +0 -0
|
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
import pyray as rl
|
|
6
6
|
|
|
7
7
|
from grim.audio import play_sfx, update_audio
|
|
8
|
-
from grim.fonts.small import SmallFontData, draw_small_text, load_small_font
|
|
8
|
+
from grim.fonts.small import SmallFontData, draw_small_text, load_small_font, measure_small_text_width
|
|
9
9
|
|
|
10
10
|
from ...ui.menu_panel import draw_classic_menu_panel
|
|
11
11
|
from ...ui.perk_menu import UiButtonState, UiButtonTextureSet, button_draw, button_update, button_width
|
|
@@ -274,34 +274,322 @@ class _DatabaseBaseView:
|
|
|
274
274
|
|
|
275
275
|
|
|
276
276
|
class UnlockedWeaponsDatabaseView(_DatabaseBaseView):
|
|
277
|
+
def __init__(self, state: GameState) -> None:
|
|
278
|
+
super().__init__(state)
|
|
279
|
+
self._wicons_tex: rl.Texture2D | None = None
|
|
280
|
+
self._weapon_ids: list[int] = []
|
|
281
|
+
self._selected_weapon_id: int = 2
|
|
282
|
+
|
|
283
|
+
def open(self) -> None:
|
|
284
|
+
super().open()
|
|
285
|
+
self._weapon_ids = self._build_weapon_database_ids()
|
|
286
|
+
self._selected_weapon_id = 2 if 2 in self._weapon_ids else (self._weapon_ids[0] if self._weapon_ids else 2)
|
|
287
|
+
|
|
288
|
+
if self._wicons_tex is not None:
|
|
289
|
+
rl.unload_texture(self._wicons_tex)
|
|
290
|
+
self._wicons_tex = None
|
|
291
|
+
wicons_path = self._state.assets_dir / "crimson" / "ui" / "ui_wicons.png"
|
|
292
|
+
if wicons_path.is_file():
|
|
293
|
+
self._wicons_tex = rl.load_texture(str(wicons_path))
|
|
294
|
+
|
|
295
|
+
def close(self) -> None:
|
|
296
|
+
if self._wicons_tex is not None:
|
|
297
|
+
rl.unload_texture(self._wicons_tex)
|
|
298
|
+
self._wicons_tex = None
|
|
299
|
+
super().close()
|
|
300
|
+
|
|
277
301
|
def _back_button_pos(self) -> tuple[float, float]:
|
|
278
302
|
# state_15: ui_buttonSm bbox [270,507]..[352,539] => relative to left panel (-98,194): (368, 313)
|
|
279
303
|
return (368.0, 313.0)
|
|
280
304
|
|
|
281
305
|
def _draw_contents(self, left_x0: float, left_y0: float, right_x0: float, right_y0: float, *, scale: float, font: SmallFontData) -> None:
|
|
306
|
+
text_scale = 1.0 * scale
|
|
307
|
+
text_color = rl.Color(255, 255, 255, int(255 * 0.8))
|
|
308
|
+
|
|
282
309
|
# state_15 title at (153,244) => relative to left panel (-98,194): (251,50)
|
|
283
310
|
draw_small_text(
|
|
284
311
|
font,
|
|
285
312
|
"Unlocked Weapons Database",
|
|
286
313
|
left_x0 + 251.0 * scale,
|
|
287
314
|
left_y0 + 50.0 * scale,
|
|
288
|
-
|
|
315
|
+
text_scale,
|
|
289
316
|
rl.Color(255, 255, 255, 255),
|
|
290
317
|
)
|
|
291
318
|
|
|
319
|
+
weapon_ids = self._weapon_ids
|
|
320
|
+
count = len(weapon_ids)
|
|
321
|
+
weapon_label = "weapon" if count == 1 else "weapons"
|
|
322
|
+
draw_small_text(
|
|
323
|
+
font,
|
|
324
|
+
f"{count} {weapon_label} in database",
|
|
325
|
+
left_x0 + 210.0 * scale,
|
|
326
|
+
left_y0 + 80.0 * scale,
|
|
327
|
+
text_scale,
|
|
328
|
+
text_color,
|
|
329
|
+
)
|
|
330
|
+
draw_small_text(
|
|
331
|
+
font,
|
|
332
|
+
"Weapon",
|
|
333
|
+
left_x0 + 210.0 * scale,
|
|
334
|
+
left_y0 + 108.0 * scale,
|
|
335
|
+
text_scale,
|
|
336
|
+
text_color,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
# List items (oracle shows 9-row list widget; render the top slice for now).
|
|
340
|
+
list_x = left_x0 + 218.0 * scale
|
|
341
|
+
list_y0 = left_y0 + 130.0 * scale
|
|
342
|
+
row_step = 16.0 * scale
|
|
343
|
+
for row, weapon_id in enumerate(weapon_ids[:9]):
|
|
344
|
+
name, _icon = self._weapon_label_and_icon(weapon_id)
|
|
345
|
+
draw_small_text(font, name, list_x, list_y0 + float(row) * row_step, text_scale, text_color)
|
|
346
|
+
|
|
347
|
+
weapon_id = int(self._selected_weapon_id)
|
|
348
|
+
name, icon_index = self._weapon_label_and_icon(weapon_id)
|
|
349
|
+
weapon = self._weapon_entry(weapon_id)
|
|
350
|
+
draw_small_text(
|
|
351
|
+
font,
|
|
352
|
+
f"wepno #{weapon_id}",
|
|
353
|
+
right_x0 + 240.0 * scale,
|
|
354
|
+
right_y0 + 32.0 * scale,
|
|
355
|
+
text_scale,
|
|
356
|
+
text_color,
|
|
357
|
+
)
|
|
358
|
+
draw_small_text(font, name, right_x0 + 50.0 * scale, right_y0 + 50.0 * scale, text_scale, text_color)
|
|
359
|
+
if icon_index is not None:
|
|
360
|
+
self._draw_wicon(icon_index, x=right_x0 + 82.0 * scale, y=right_y0 + 82.0 * scale, scale=scale)
|
|
361
|
+
|
|
362
|
+
if weapon is not None:
|
|
363
|
+
rpm = self._weapon_rpm(weapon)
|
|
364
|
+
reload_time = weapon.reload_time
|
|
365
|
+
clip_size = weapon.clip_size
|
|
366
|
+
if rpm is not None:
|
|
367
|
+
draw_small_text(
|
|
368
|
+
font,
|
|
369
|
+
f"Firerate: {rpm} rpm",
|
|
370
|
+
right_x0 + 66.0 * scale,
|
|
371
|
+
right_y0 + 128.0 * scale,
|
|
372
|
+
text_scale,
|
|
373
|
+
text_color,
|
|
374
|
+
)
|
|
375
|
+
if reload_time is not None:
|
|
376
|
+
draw_small_text(
|
|
377
|
+
font,
|
|
378
|
+
f"Reload time: {reload_time:g} secs",
|
|
379
|
+
right_x0 + 66.0 * scale,
|
|
380
|
+
right_y0 + 146.0 * scale,
|
|
381
|
+
text_scale,
|
|
382
|
+
text_color,
|
|
383
|
+
)
|
|
384
|
+
if clip_size is not None:
|
|
385
|
+
draw_small_text(
|
|
386
|
+
font,
|
|
387
|
+
f"Clip size: {int(clip_size)}",
|
|
388
|
+
right_x0 + 66.0 * scale,
|
|
389
|
+
right_y0 + 164.0 * scale,
|
|
390
|
+
text_scale,
|
|
391
|
+
text_color,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
def _build_weapon_database_ids(self) -> list[int]:
|
|
395
|
+
try:
|
|
396
|
+
from ...weapons import WEAPON_TABLE
|
|
397
|
+
except Exception:
|
|
398
|
+
return []
|
|
399
|
+
status = self._state.status
|
|
400
|
+
used: list[int] = []
|
|
401
|
+
for weapon in WEAPON_TABLE:
|
|
402
|
+
if weapon.name is None:
|
|
403
|
+
continue
|
|
404
|
+
weapon_id = int(weapon.weapon_id)
|
|
405
|
+
try:
|
|
406
|
+
if status.weapon_usage_count(weapon_id) != 0:
|
|
407
|
+
used.append(weapon_id)
|
|
408
|
+
except Exception:
|
|
409
|
+
continue
|
|
410
|
+
used.sort()
|
|
411
|
+
return used
|
|
412
|
+
|
|
413
|
+
def _weapon_entry(self, weapon_id: int) -> object | None:
|
|
414
|
+
try:
|
|
415
|
+
from ...weapons import WEAPON_BY_ID
|
|
416
|
+
except Exception:
|
|
417
|
+
return None
|
|
418
|
+
return WEAPON_BY_ID.get(int(weapon_id))
|
|
419
|
+
|
|
420
|
+
def _weapon_rpm(self, weapon: object) -> int | None:
|
|
421
|
+
try:
|
|
422
|
+
cooldown = getattr(weapon, "shot_cooldown", None)
|
|
423
|
+
if cooldown is None:
|
|
424
|
+
return None
|
|
425
|
+
cooldown = float(cooldown)
|
|
426
|
+
except Exception:
|
|
427
|
+
return None
|
|
428
|
+
if cooldown <= 0.0:
|
|
429
|
+
return None
|
|
430
|
+
return int(60.0 / cooldown)
|
|
431
|
+
|
|
432
|
+
def _draw_wicon(self, icon_index: int, *, x: float, y: float, scale: float) -> None:
|
|
433
|
+
tex = self._wicons_tex
|
|
434
|
+
if tex is None:
|
|
435
|
+
return
|
|
436
|
+
idx = int(icon_index)
|
|
437
|
+
if idx < 0 or idx > 31:
|
|
438
|
+
return
|
|
439
|
+
cols = 4
|
|
440
|
+
rows = 8
|
|
441
|
+
icon_w = float(tex.width) / float(cols)
|
|
442
|
+
icon_h = float(tex.height) / float(rows)
|
|
443
|
+
src_x = float(idx % cols) * icon_w
|
|
444
|
+
src_y = float(idx // cols) * icon_h
|
|
445
|
+
rl.draw_texture_pro(
|
|
446
|
+
tex,
|
|
447
|
+
rl.Rectangle(src_x, src_y, icon_w, icon_h),
|
|
448
|
+
rl.Rectangle(float(x), float(y), icon_w * scale, icon_h * scale),
|
|
449
|
+
rl.Vector2(0.0, 0.0),
|
|
450
|
+
0.0,
|
|
451
|
+
rl.WHITE,
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
@staticmethod
|
|
455
|
+
def _weapon_label_and_icon(weapon_id: int) -> tuple[str, int | None]:
|
|
456
|
+
try:
|
|
457
|
+
from ...weapons import WEAPON_BY_ID
|
|
458
|
+
except Exception:
|
|
459
|
+
WEAPON_BY_ID = {}
|
|
460
|
+
weapon = WEAPON_BY_ID.get(int(weapon_id))
|
|
461
|
+
if weapon is None:
|
|
462
|
+
return f"Weapon {int(weapon_id)}", None
|
|
463
|
+
name = weapon.name or f"weapon_{int(weapon.weapon_id)}"
|
|
464
|
+
return name, weapon.icon_index
|
|
465
|
+
|
|
292
466
|
|
|
293
467
|
class UnlockedPerksDatabaseView(_DatabaseBaseView):
|
|
468
|
+
def __init__(self, state: GameState) -> None:
|
|
469
|
+
super().__init__(state)
|
|
470
|
+
self._perk_ids: list[int] = []
|
|
471
|
+
self._selected_perk_id: int = 4
|
|
472
|
+
|
|
473
|
+
def open(self) -> None:
|
|
474
|
+
super().open()
|
|
475
|
+
self._perk_ids = self._build_perk_database_ids()
|
|
476
|
+
self._selected_perk_id = 4 if 4 in self._perk_ids else (self._perk_ids[0] if self._perk_ids else 4)
|
|
477
|
+
|
|
294
478
|
def _back_button_pos(self) -> tuple[float, float]:
|
|
295
479
|
# state_16: ui_buttonSm bbox [258,509]..[340,541] => relative to left panel (-98,194): (356, 315)
|
|
296
480
|
return (356.0, 315.0)
|
|
297
481
|
|
|
298
482
|
def _draw_contents(self, left_x0: float, left_y0: float, right_x0: float, right_y0: float, *, scale: float, font: SmallFontData) -> None:
|
|
483
|
+
text_scale = 1.0 * scale
|
|
484
|
+
text_color = rl.Color(255, 255, 255, int(255 * 0.8))
|
|
485
|
+
|
|
299
486
|
# state_16 title at (163,244) => relative to left panel (-98,194): (261,50)
|
|
300
487
|
draw_small_text(
|
|
301
488
|
font,
|
|
302
489
|
"Unlocked Perks Database",
|
|
303
490
|
left_x0 + 261.0 * scale,
|
|
304
491
|
left_y0 + 50.0 * scale,
|
|
305
|
-
|
|
492
|
+
text_scale,
|
|
306
493
|
rl.Color(255, 255, 255, 255),
|
|
307
494
|
)
|
|
495
|
+
|
|
496
|
+
perk_ids = self._perk_ids
|
|
497
|
+
count = len(perk_ids)
|
|
498
|
+
perk_label = "perk" if count == 1 else "perks"
|
|
499
|
+
draw_small_text(
|
|
500
|
+
font,
|
|
501
|
+
f"{count} {perk_label} in database",
|
|
502
|
+
left_x0 + 210.0 * scale,
|
|
503
|
+
left_y0 + 78.0 * scale,
|
|
504
|
+
text_scale,
|
|
505
|
+
text_color,
|
|
506
|
+
)
|
|
507
|
+
draw_small_text(
|
|
508
|
+
font,
|
|
509
|
+
"Perks",
|
|
510
|
+
left_x0 + 210.0 * scale,
|
|
511
|
+
left_y0 + 106.0 * scale,
|
|
512
|
+
text_scale,
|
|
513
|
+
text_color,
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
list_x = left_x0 + 218.0 * scale
|
|
517
|
+
list_y0 = left_y0 + 128.0 * scale
|
|
518
|
+
row_step = 16.0 * scale
|
|
519
|
+
for row, perk_id in enumerate(perk_ids[:9]):
|
|
520
|
+
draw_small_text(font, self._perk_name(perk_id), list_x, list_y0 + float(row) * row_step, text_scale, text_color)
|
|
521
|
+
|
|
522
|
+
perk_id = int(self._selected_perk_id)
|
|
523
|
+
perk_name = self._perk_name(perk_id)
|
|
524
|
+
draw_small_text(
|
|
525
|
+
font,
|
|
526
|
+
f"perkno #{perk_id}",
|
|
527
|
+
right_x0 + 224.0 * scale,
|
|
528
|
+
right_y0 + 32.0 * scale,
|
|
529
|
+
text_scale,
|
|
530
|
+
text_color,
|
|
531
|
+
)
|
|
532
|
+
draw_small_text(font, perk_name, right_x0 + 93.0 * scale, right_y0 + 50.0 * scale, text_scale, text_color)
|
|
533
|
+
|
|
534
|
+
desc_x = right_x0 + 50.0 * scale
|
|
535
|
+
desc_y = right_y0 + 72.0 * scale
|
|
536
|
+
max_w = float(rl.get_screen_width()) - desc_x - 4.0 * scale
|
|
537
|
+
desc = self._perk_desc(perk_id)
|
|
538
|
+
first_line = self._truncate_small_line(font, desc, max_w, scale=text_scale)
|
|
539
|
+
if first_line:
|
|
540
|
+
draw_small_text(font, first_line, desc_x, desc_y, text_scale, text_color)
|
|
541
|
+
|
|
542
|
+
def _build_perk_database_ids(self) -> list[int]:
|
|
543
|
+
try:
|
|
544
|
+
from ...gameplay import PERK_COUNT_SIZE, perks_rebuild_available
|
|
545
|
+
except Exception:
|
|
546
|
+
return []
|
|
547
|
+
|
|
548
|
+
# Avoid spinning up a full GameplayState; perks_rebuild_available only needs these fields.
|
|
549
|
+
class _Stub:
|
|
550
|
+
status: object | None
|
|
551
|
+
perk_available: list[bool]
|
|
552
|
+
_perk_available_unlock_index: int
|
|
553
|
+
|
|
554
|
+
stub = _Stub()
|
|
555
|
+
stub.status = self._state.status
|
|
556
|
+
stub.perk_available = [False] * int(PERK_COUNT_SIZE)
|
|
557
|
+
stub._perk_available_unlock_index = -1
|
|
558
|
+
perks_rebuild_available(stub) # type: ignore[arg-type]
|
|
559
|
+
|
|
560
|
+
perk_ids = [idx for idx, available in enumerate(stub.perk_available) if available and idx > 0]
|
|
561
|
+
perk_ids.sort()
|
|
562
|
+
return perk_ids
|
|
563
|
+
|
|
564
|
+
@staticmethod
|
|
565
|
+
def _perk_name(perk_id: int) -> str:
|
|
566
|
+
try:
|
|
567
|
+
from ...perks import perk_display_name
|
|
568
|
+
|
|
569
|
+
return perk_display_name(int(perk_id))
|
|
570
|
+
except Exception:
|
|
571
|
+
return f"Perk {int(perk_id)}"
|
|
572
|
+
|
|
573
|
+
@staticmethod
|
|
574
|
+
def _perk_desc(perk_id: int) -> str:
|
|
575
|
+
try:
|
|
576
|
+
from ...perks import perk_display_description
|
|
577
|
+
|
|
578
|
+
return perk_display_description(int(perk_id))
|
|
579
|
+
except Exception:
|
|
580
|
+
return ""
|
|
581
|
+
|
|
582
|
+
@staticmethod
|
|
583
|
+
def _truncate_small_line(font: SmallFontData, text: str, max_width: float, *, scale: float) -> str:
|
|
584
|
+
text = str(text).strip()
|
|
585
|
+
if not text:
|
|
586
|
+
return ""
|
|
587
|
+
words = text.split()
|
|
588
|
+
line = ""
|
|
589
|
+
for word in words:
|
|
590
|
+
candidate = word if not line else f"{line} {word}"
|
|
591
|
+
if measure_small_text_width(font, candidate, float(scale)) <= float(max_width):
|
|
592
|
+
line = candidate
|
|
593
|
+
continue
|
|
594
|
+
break
|
|
595
|
+
return line
|
crimson/frontend/panels/mods.py
CHANGED
|
@@ -12,9 +12,7 @@ from ..menu import (
|
|
|
12
12
|
MENU_PANEL_OFFSET_Y,
|
|
13
13
|
MENU_PANEL_WIDTH,
|
|
14
14
|
MenuView,
|
|
15
|
-
_draw_menu_cursor,
|
|
16
15
|
)
|
|
17
|
-
from ..transitions import _draw_screen_fade
|
|
18
16
|
from .base import PANEL_TIMELINE_END_MS, PANEL_TIMELINE_START_MS, PanelMenuView
|
|
19
17
|
|
|
20
18
|
if TYPE_CHECKING:
|
|
@@ -31,19 +29,6 @@ class ModsMenuView(PanelMenuView):
|
|
|
31
29
|
super().open()
|
|
32
30
|
self._lines = self._build_lines()
|
|
33
31
|
|
|
34
|
-
def draw(self) -> None:
|
|
35
|
-
self._draw_background()
|
|
36
|
-
_draw_screen_fade(self._state)
|
|
37
|
-
assets = self._assets
|
|
38
|
-
entry = self._entry
|
|
39
|
-
if assets is None or entry is None:
|
|
40
|
-
return
|
|
41
|
-
self._draw_panel()
|
|
42
|
-
self._draw_entry(entry)
|
|
43
|
-
self._draw_sign()
|
|
44
|
-
self._draw_contents()
|
|
45
|
-
_draw_menu_cursor(self._state, pulse_time=self._cursor_pulse_time)
|
|
46
|
-
|
|
47
32
|
def _ensure_small_font(self) -> SmallFontData:
|
|
48
33
|
if self._small_font is not None:
|
|
49
34
|
return self._small_font
|
|
@@ -17,9 +17,7 @@ from ..menu import (
|
|
|
17
17
|
MENU_LABEL_WIDTH,
|
|
18
18
|
MENU_PANEL_WIDTH,
|
|
19
19
|
MenuView,
|
|
20
|
-
_draw_menu_cursor,
|
|
21
20
|
)
|
|
22
|
-
from ..transitions import _draw_screen_fade
|
|
23
21
|
from .base import PANEL_TIMELINE_END_MS, PANEL_TIMELINE_START_MS, PanelMenuView
|
|
24
22
|
|
|
25
23
|
if TYPE_CHECKING:
|
|
@@ -169,20 +167,6 @@ class PlayGameMenuView(PanelMenuView):
|
|
|
169
167
|
continue
|
|
170
168
|
self._tooltip_ms[key] = max(0, self._tooltip_ms[key] - dt_ms * 2)
|
|
171
169
|
|
|
172
|
-
def draw(self) -> None:
|
|
173
|
-
self._draw_background()
|
|
174
|
-
_draw_screen_fade(self._state)
|
|
175
|
-
assets = self._assets
|
|
176
|
-
entry = self._entry
|
|
177
|
-
if assets is None or entry is None:
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
self._draw_panel()
|
|
181
|
-
self._draw_entry(entry)
|
|
182
|
-
self._draw_sign()
|
|
183
|
-
self._draw_contents()
|
|
184
|
-
_draw_menu_cursor(self._state, pulse_time=self._cursor_pulse_time)
|
|
185
|
-
|
|
186
170
|
def _begin_close_transition(self, action: str) -> None:
|
|
187
171
|
if self._dirty:
|
|
188
172
|
try:
|