crimsonland 0.1.0.dev12__py3-none-any.whl → 0.1.0.dev13__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/assets_fetch.py +23 -8
- crimson/frontend/high_scores_layout.py +26 -0
- crimson/frontend/menu.py +22 -20
- crimson/frontend/panels/base.py +14 -26
- crimson/frontend/panels/controls.py +151 -62
- crimson/frontend/panels/credits.py +221 -0
- crimson/frontend/panels/databases.py +307 -0
- crimson/frontend/panels/options.py +4 -3
- crimson/frontend/panels/play_game.py +4 -4
- crimson/frontend/panels/stats.py +255 -296
- crimson/game.py +219 -81
- crimson/modes/quest_mode.py +10 -9
- crimson/modes/survival_mode.py +10 -9
- crimson/modes/tutorial_mode.py +10 -4
- crimson/ui/menu_panel.py +127 -0
- crimson/ui/perk_menu.py +54 -89
- crimson/ui/quest_results.py +24 -18
- crimson/views/perk_menu_debug.py +2 -2
- crimson/views/perks.py +2 -2
- {crimsonland-0.1.0.dev12.dist-info → crimsonland-0.1.0.dev13.dist-info}/METADATA +1 -1
- {crimsonland-0.1.0.dev12.dist-info → crimsonland-0.1.0.dev13.dist-info}/RECORD +23 -19
- {crimsonland-0.1.0.dev12.dist-info → crimsonland-0.1.0.dev13.dist-info}/WHEEL +0 -0
- {crimsonland-0.1.0.dev12.dist-info → crimsonland-0.1.0.dev13.dist-info}/entry_points.txt +0 -0
crimson/game.py
CHANGED
|
@@ -51,6 +51,19 @@ from .demo_trial import (
|
|
|
51
51
|
)
|
|
52
52
|
from .frontend.boot import BootView
|
|
53
53
|
from .frontend.assets import MenuAssets, _ensure_texture_cache, load_menu_assets
|
|
54
|
+
from .frontend.high_scores_layout import (
|
|
55
|
+
HS_BACK_BUTTON_X,
|
|
56
|
+
HS_BACK_BUTTON_Y,
|
|
57
|
+
HS_BUTTON_STEP_Y,
|
|
58
|
+
HS_BUTTON_X,
|
|
59
|
+
HS_BUTTON_Y0,
|
|
60
|
+
HS_LEFT_PANEL_HEIGHT,
|
|
61
|
+
HS_LEFT_PANEL_POS_X,
|
|
62
|
+
HS_LEFT_PANEL_POS_Y,
|
|
63
|
+
HS_RIGHT_PANEL_HEIGHT,
|
|
64
|
+
HS_RIGHT_PANEL_POS_X,
|
|
65
|
+
HS_RIGHT_PANEL_POS_Y,
|
|
66
|
+
)
|
|
54
67
|
from .frontend.menu import (
|
|
55
68
|
MENU_PANEL_HEIGHT,
|
|
56
69
|
MENU_PANEL_OFFSET_X,
|
|
@@ -72,6 +85,8 @@ from .frontend.menu import (
|
|
|
72
85
|
)
|
|
73
86
|
from .frontend.panels.base import PANEL_TIMELINE_END_MS, PANEL_TIMELINE_START_MS, PanelMenuView
|
|
74
87
|
from .frontend.panels.controls import ControlsMenuView
|
|
88
|
+
from .frontend.panels.credits import CreditsView
|
|
89
|
+
from .frontend.panels.databases import UnlockedPerksDatabaseView, UnlockedWeaponsDatabaseView
|
|
75
90
|
from .frontend.panels.mods import ModsMenuView
|
|
76
91
|
from .frontend.panels.options import OptionsMenuView
|
|
77
92
|
from .frontend.panels.play_game import PlayGameMenuView
|
|
@@ -80,7 +95,8 @@ from .frontend.pause_menu import PauseMenuView
|
|
|
80
95
|
from .frontend.transitions import _draw_screen_fade, _update_screen_fade
|
|
81
96
|
from .persistence.save_status import GameStatus, ensure_game_status
|
|
82
97
|
from .ui.demo_trial_overlay import DEMO_PURCHASE_URL, DemoTrialOverlayUi
|
|
83
|
-
from .ui.
|
|
98
|
+
from .ui.menu_panel import draw_classic_menu_panel
|
|
99
|
+
from .ui.perk_menu import UiButtonState, UiButtonTextureSet, button_draw, button_update, button_width
|
|
84
100
|
from .paths import default_runtime_dir
|
|
85
101
|
from .assets_fetch import download_missing_paqs
|
|
86
102
|
|
|
@@ -144,6 +160,7 @@ AUTOEXEC_NAME = "autoexec.txt"
|
|
|
144
160
|
|
|
145
161
|
QUEST_MENU_BASE_X = -5.0
|
|
146
162
|
QUEST_MENU_BASE_Y = 185.0
|
|
163
|
+
QUEST_MENU_PANEL_OFFSET_X = -63.0
|
|
147
164
|
|
|
148
165
|
QUEST_TITLE_X_OFFSET = 219.0 # 300 + 64 - 145
|
|
149
166
|
QUEST_TITLE_Y_OFFSET = 44.0 # 40 + 4
|
|
@@ -171,7 +188,7 @@ QUEST_HARDCORE_LIST_Y_SHIFT = 10.0
|
|
|
171
188
|
|
|
172
189
|
QUEST_BACK_BUTTON_X_OFFSET = 138.0
|
|
173
190
|
QUEST_BACK_BUTTON_Y_OFFSET = 212.0
|
|
174
|
-
QUEST_PANEL_HEIGHT =
|
|
191
|
+
QUEST_PANEL_HEIGHT = 378.0
|
|
175
192
|
|
|
176
193
|
|
|
177
194
|
class QuestsMenuView:
|
|
@@ -719,10 +736,10 @@ class QuestsMenuView:
|
|
|
719
736
|
if panel is None:
|
|
720
737
|
return
|
|
721
738
|
fx_detail = bool(self._state.config.data.get("fx_detail_0", 0))
|
|
722
|
-
|
|
739
|
+
draw_classic_menu_panel(
|
|
723
740
|
panel,
|
|
724
741
|
dst=rl.Rectangle(
|
|
725
|
-
float(QUEST_MENU_BASE_X +
|
|
742
|
+
float(QUEST_MENU_BASE_X + QUEST_MENU_PANEL_OFFSET_X),
|
|
726
743
|
float(QUEST_MENU_BASE_Y + MENU_PANEL_OFFSET_Y + self._widescreen_y_shift),
|
|
727
744
|
float(MENU_PANEL_WIDTH),
|
|
728
745
|
float(QUEST_PANEL_HEIGHT),
|
|
@@ -1531,14 +1548,19 @@ class QuestFailedView:
|
|
|
1531
1548
|
class HighScoresView:
|
|
1532
1549
|
def __init__(self, state: GameState) -> None:
|
|
1533
1550
|
self._state = state
|
|
1551
|
+
self._assets: MenuAssets | None = None
|
|
1534
1552
|
self._ground: GroundRenderer | None = None
|
|
1535
1553
|
self._action: str | None = None
|
|
1536
1554
|
self._cursor_pulse_time = 0.0
|
|
1555
|
+
self._widescreen_y_shift = 0.0
|
|
1556
|
+
self._timeline_ms = 0
|
|
1557
|
+
self._timeline_max_ms = PANEL_TIMELINE_START_MS
|
|
1537
1558
|
self._small_font: SmallFontData | None = None
|
|
1538
1559
|
self._button_tex: rl.Texture2D | None = None
|
|
1539
1560
|
self._button_textures: UiButtonTextureSet | None = None
|
|
1540
|
-
self.
|
|
1541
|
-
self.
|
|
1561
|
+
self._update_button = UiButtonState("Update scores", force_wide=True)
|
|
1562
|
+
self._play_button = UiButtonState("Play a game", force_wide=True)
|
|
1563
|
+
self._back_button = UiButtonState("Back", force_wide=False)
|
|
1542
1564
|
|
|
1543
1565
|
self._request: HighScoresRequest | None = None
|
|
1544
1566
|
self._records: list = []
|
|
@@ -1547,14 +1569,20 @@ class HighScoresView:
|
|
|
1547
1569
|
def open(self) -> None:
|
|
1548
1570
|
from .persistence.highscores import read_highscore_table, scores_path_for_mode
|
|
1549
1571
|
|
|
1572
|
+
layout_w = float(self._state.config.screen_width)
|
|
1573
|
+
self._widescreen_y_shift = MenuView._menu_widescreen_y_shift(layout_w)
|
|
1550
1574
|
self._action = None
|
|
1575
|
+
self._assets = load_menu_assets(self._state)
|
|
1551
1576
|
self._ground = None if self._state.pause_background is not None else ensure_menu_ground(self._state)
|
|
1552
1577
|
self._cursor_pulse_time = 0.0
|
|
1578
|
+
self._timeline_ms = 0
|
|
1579
|
+
self._timeline_max_ms = PANEL_TIMELINE_START_MS
|
|
1553
1580
|
self._small_font = None
|
|
1554
1581
|
self._scroll_index = 0
|
|
1555
1582
|
self._button_textures = None
|
|
1556
|
-
self.
|
|
1557
|
-
self.
|
|
1583
|
+
self._update_button = UiButtonState("Update scores", force_wide=True)
|
|
1584
|
+
self._play_button = UiButtonState("Play a game", force_wide=True)
|
|
1585
|
+
self._back_button = UiButtonState("Back", force_wide=False)
|
|
1558
1586
|
|
|
1559
1587
|
cache = _ensure_texture_cache(self._state)
|
|
1560
1588
|
self._button_tex = cache.get_or_load("ui_buttonMd", "ui/ui_button_128x32.jaz").texture
|
|
@@ -1595,12 +1623,18 @@ class HighScoresView:
|
|
|
1595
1623
|
if self._small_font is not None:
|
|
1596
1624
|
rl.unload_texture(self._small_font.texture)
|
|
1597
1625
|
self._small_font = None
|
|
1626
|
+
self._assets = None
|
|
1598
1627
|
self._button_tex = None
|
|
1599
1628
|
self._button_textures = None
|
|
1600
1629
|
self._request = None
|
|
1601
1630
|
self._records = []
|
|
1602
1631
|
self._scroll_index = 0
|
|
1603
1632
|
|
|
1633
|
+
def _panel_top_left(self, *, pos_x: float, pos_y: float, scale: float) -> tuple[float, float]:
|
|
1634
|
+
x0 = float(pos_x + MENU_PANEL_OFFSET_X * scale)
|
|
1635
|
+
y0 = float(pos_y + self._widescreen_y_shift + MENU_PANEL_OFFSET_Y * scale)
|
|
1636
|
+
return x0, y0
|
|
1637
|
+
|
|
1604
1638
|
def update(self, dt: float) -> None:
|
|
1605
1639
|
if self._state.audio is not None:
|
|
1606
1640
|
update_audio(self._state.audio, dt)
|
|
@@ -1608,62 +1642,83 @@ class HighScoresView:
|
|
|
1608
1642
|
self._ground.process_pending()
|
|
1609
1643
|
self._cursor_pulse_time += min(dt, 0.1) * 1.1
|
|
1610
1644
|
|
|
1611
|
-
|
|
1645
|
+
dt_ms = int(min(float(dt), 0.1) * 1000.0)
|
|
1646
|
+
if dt_ms > 0:
|
|
1647
|
+
self._timeline_ms = min(self._timeline_max_ms, int(self._timeline_ms + dt_ms))
|
|
1648
|
+
|
|
1649
|
+
enabled = self._timeline_ms >= self._timeline_max_ms
|
|
1650
|
+
|
|
1651
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_ESCAPE) and enabled:
|
|
1612
1652
|
if self._state.audio is not None:
|
|
1613
1653
|
play_sfx(self._state.audio, "sfx_ui_buttonclick", rng=self._state.rng)
|
|
1614
1654
|
self._action = "back_to_previous"
|
|
1615
1655
|
return
|
|
1616
1656
|
|
|
1617
1657
|
textures = self._button_textures
|
|
1618
|
-
if textures is not None and (textures.button_sm is not None or textures.button_md is not None):
|
|
1658
|
+
if enabled and textures is not None and (textures.button_sm is not None or textures.button_md is not None):
|
|
1619
1659
|
scale = 0.9 if float(self._state.config.screen_width) < 641.0 else 1.0
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
y0 = float(rl.get_screen_height()) - button_h - 52.0 * scale
|
|
1660
|
+
panel_x0, panel_y0 = self._panel_top_left(pos_x=HS_LEFT_PANEL_POS_X, pos_y=HS_LEFT_PANEL_POS_Y, scale=scale)
|
|
1661
|
+
|
|
1662
|
+
x0 = panel_x0 + HS_BUTTON_X * scale
|
|
1663
|
+
y0 = panel_y0 + HS_BUTTON_Y0 * scale
|
|
1625
1664
|
mouse = rl.get_mouse_position()
|
|
1626
1665
|
click = rl.is_mouse_button_pressed(rl.MOUSE_BUTTON_LEFT)
|
|
1627
|
-
|
|
1628
|
-
if button_update(self.
|
|
1666
|
+
w = button_width(None, self._update_button.label, scale=scale, force_wide=self._update_button.force_wide)
|
|
1667
|
+
if button_update(self._update_button, x=x0, y=y0, width=w, dt_ms=dt_ms, mouse=mouse, click=click):
|
|
1668
|
+
# Reload scores from disk (no view transition).
|
|
1629
1669
|
if self._state.audio is not None:
|
|
1630
1670
|
play_sfx(self._state.audio, "sfx_ui_buttonclick", rng=self._state.rng)
|
|
1631
|
-
self.
|
|
1671
|
+
self.open()
|
|
1632
1672
|
return
|
|
1673
|
+
w = button_width(None, self._play_button.label, scale=scale, force_wide=self._play_button.force_wide)
|
|
1633
1674
|
if button_update(
|
|
1634
|
-
self.
|
|
1635
|
-
x=x0
|
|
1636
|
-
y=y0,
|
|
1637
|
-
width=
|
|
1675
|
+
self._play_button,
|
|
1676
|
+
x=x0,
|
|
1677
|
+
y=y0 + HS_BUTTON_STEP_Y * scale,
|
|
1678
|
+
width=w,
|
|
1638
1679
|
dt_ms=dt_ms,
|
|
1639
1680
|
mouse=mouse,
|
|
1640
1681
|
click=click,
|
|
1641
1682
|
):
|
|
1642
1683
|
if self._state.audio is not None:
|
|
1643
1684
|
play_sfx(self._state.audio, "sfx_ui_buttonclick", rng=self._state.rng)
|
|
1644
|
-
self._action = "
|
|
1685
|
+
self._action = "open_play_game"
|
|
1686
|
+
return
|
|
1687
|
+
back_w = button_width(None, self._back_button.label, scale=scale, force_wide=self._back_button.force_wide)
|
|
1688
|
+
if button_update(
|
|
1689
|
+
self._back_button,
|
|
1690
|
+
x=panel_x0 + HS_BACK_BUTTON_X * scale,
|
|
1691
|
+
y=panel_y0 + HS_BACK_BUTTON_Y * scale,
|
|
1692
|
+
width=back_w,
|
|
1693
|
+
dt_ms=dt_ms,
|
|
1694
|
+
mouse=mouse,
|
|
1695
|
+
click=click,
|
|
1696
|
+
):
|
|
1697
|
+
if self._state.audio is not None:
|
|
1698
|
+
play_sfx(self._state.audio, "sfx_ui_buttonclick", rng=self._state.rng)
|
|
1699
|
+
self._action = "back_to_previous"
|
|
1645
1700
|
return
|
|
1646
1701
|
|
|
1647
|
-
|
|
1648
|
-
rows = self._visible_rows(font)
|
|
1702
|
+
rows = 10
|
|
1649
1703
|
max_scroll = max(0, len(self._records) - rows)
|
|
1650
1704
|
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1705
|
+
if enabled:
|
|
1706
|
+
wheel = int(rl.get_mouse_wheel_move())
|
|
1707
|
+
if wheel:
|
|
1708
|
+
self._scroll_index = max(0, min(max_scroll, int(self._scroll_index) - wheel))
|
|
1709
|
+
|
|
1710
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_UP):
|
|
1711
|
+
self._scroll_index = max(0, int(self._scroll_index) - 1)
|
|
1712
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_DOWN):
|
|
1713
|
+
self._scroll_index = min(max_scroll, int(self._scroll_index) + 1)
|
|
1714
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_PAGE_UP):
|
|
1715
|
+
self._scroll_index = max(0, int(self._scroll_index) - rows)
|
|
1716
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_PAGE_DOWN):
|
|
1717
|
+
self._scroll_index = min(max_scroll, int(self._scroll_index) + rows)
|
|
1718
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_HOME):
|
|
1719
|
+
self._scroll_index = 0
|
|
1720
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_END):
|
|
1721
|
+
self._scroll_index = max_scroll
|
|
1667
1722
|
|
|
1668
1723
|
def draw(self) -> None:
|
|
1669
1724
|
rl.clear_background(rl.BLACK)
|
|
@@ -1674,6 +1729,10 @@ class HighScoresView:
|
|
|
1674
1729
|
self._ground.draw(0.0, 0.0)
|
|
1675
1730
|
_draw_screen_fade(self._state)
|
|
1676
1731
|
|
|
1732
|
+
assets = self._assets
|
|
1733
|
+
if assets is None or assets.panel is None:
|
|
1734
|
+
return
|
|
1735
|
+
|
|
1677
1736
|
font = self._ensure_small_font()
|
|
1678
1737
|
request = self._request
|
|
1679
1738
|
mode_id = int(request.game_mode_id) if request is not None else int(self._state.config.data.get("game_mode", 1) or 1)
|
|
@@ -1681,26 +1740,64 @@ class HighScoresView:
|
|
|
1681
1740
|
quest_minor = int(request.quest_stage_minor) if request is not None else 0
|
|
1682
1741
|
highlight_rank = request.highlight_rank if request is not None else None
|
|
1683
1742
|
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1743
|
+
scale = 0.9 if float(self._state.config.screen_width) < 641.0 else 1.0
|
|
1744
|
+
fx_detail = bool(self._state.config.data.get("fx_detail_0", 0))
|
|
1745
|
+
panel_w = MENU_PANEL_WIDTH * scale
|
|
1746
|
+
_angle_rad, left_slide_x = MenuView._ui_element_anim(
|
|
1747
|
+
self,
|
|
1748
|
+
index=1,
|
|
1749
|
+
start_ms=PANEL_TIMELINE_START_MS,
|
|
1750
|
+
end_ms=PANEL_TIMELINE_END_MS,
|
|
1751
|
+
width=panel_w,
|
|
1752
|
+
direction_flag=0,
|
|
1753
|
+
)
|
|
1754
|
+
_angle_rad, right_slide_x = MenuView._ui_element_anim(
|
|
1755
|
+
self,
|
|
1756
|
+
index=2,
|
|
1757
|
+
start_ms=PANEL_TIMELINE_START_MS,
|
|
1758
|
+
end_ms=PANEL_TIMELINE_END_MS,
|
|
1759
|
+
width=panel_w,
|
|
1760
|
+
direction_flag=1,
|
|
1761
|
+
)
|
|
1762
|
+
|
|
1763
|
+
left_x0, left_y0 = self._panel_top_left(pos_x=HS_LEFT_PANEL_POS_X, pos_y=HS_LEFT_PANEL_POS_Y, scale=scale)
|
|
1764
|
+
right_x0, right_y0 = self._panel_top_left(pos_x=HS_RIGHT_PANEL_POS_X, pos_y=HS_RIGHT_PANEL_POS_Y, scale=scale)
|
|
1765
|
+
left_x0 += float(left_slide_x)
|
|
1766
|
+
right_x0 += float(right_slide_x)
|
|
1767
|
+
|
|
1768
|
+
draw_classic_menu_panel(
|
|
1769
|
+
assets.panel,
|
|
1770
|
+
dst=rl.Rectangle(left_x0, left_y0, panel_w, HS_LEFT_PANEL_HEIGHT * scale),
|
|
1771
|
+
tint=rl.WHITE,
|
|
1772
|
+
shadow=fx_detail,
|
|
1773
|
+
)
|
|
1774
|
+
draw_classic_menu_panel(
|
|
1775
|
+
assets.panel,
|
|
1776
|
+
dst=rl.Rectangle(right_x0, right_y0, panel_w, HS_RIGHT_PANEL_HEIGHT * scale),
|
|
1777
|
+
tint=rl.WHITE,
|
|
1778
|
+
shadow=fx_detail,
|
|
1779
|
+
)
|
|
1780
|
+
|
|
1781
|
+
title = "High scores - Quests" if int(mode_id) == 3 else f"High scores - {self._mode_label(mode_id, quest_major, quest_minor)}"
|
|
1782
|
+
draw_small_text(font, title, left_x0 + 269.0 * scale, left_y0 + 41.0 * scale, 1.0 * scale, rl.Color(255, 255, 255, 255))
|
|
1783
|
+
if int(mode_id) == 3:
|
|
1784
|
+
quest_label = f"{int(quest_major)}.{int(quest_minor)}: {self._quest_title(quest_major, quest_minor)}"
|
|
1785
|
+
draw_small_text(font, quest_label, left_x0 + 236.0 * scale, left_y0 + 63.0 * scale, 1.0 * scale, rl.Color(255, 255, 255, 255))
|
|
1688
1786
|
|
|
1689
1787
|
header_color = rl.Color(255, 255, 255, int(255 * 0.85))
|
|
1690
|
-
row_y0 =
|
|
1691
|
-
draw_small_text(font, "Rank",
|
|
1692
|
-
draw_small_text(font, "
|
|
1693
|
-
|
|
1694
|
-
draw_small_text(font, score_label, 320.0, row_y0, 1.0, header_color)
|
|
1788
|
+
row_y0 = left_y0 + 84.0 * scale
|
|
1789
|
+
draw_small_text(font, "Rank", left_x0 + 211.0 * scale, row_y0, 1.0 * scale, header_color)
|
|
1790
|
+
draw_small_text(font, "Score", left_x0 + 246.0 * scale, row_y0, 1.0 * scale, header_color)
|
|
1791
|
+
draw_small_text(font, "Player", left_x0 + 302.0 * scale, row_y0, 1.0 * scale, header_color)
|
|
1695
1792
|
|
|
1696
|
-
row_step =
|
|
1697
|
-
rows =
|
|
1793
|
+
row_step = 16.0 * scale
|
|
1794
|
+
rows = 10
|
|
1698
1795
|
start = max(0, int(self._scroll_index))
|
|
1699
1796
|
end = min(len(self._records), start + rows)
|
|
1700
|
-
y =
|
|
1797
|
+
y = left_y0 + 103.0 * scale
|
|
1701
1798
|
|
|
1702
1799
|
if start >= end:
|
|
1703
|
-
draw_small_text(font, "No scores yet.",
|
|
1800
|
+
draw_small_text(font, "No scores yet.", left_x0 + 211.0 * scale, y + 8.0 * scale, 1.0 * scale, rl.Color(190, 190, 200, 255))
|
|
1704
1801
|
else:
|
|
1705
1802
|
for idx in range(start, end):
|
|
1706
1803
|
entry = self._records[idx]
|
|
@@ -1714,44 +1811,82 @@ class HighScoresView:
|
|
|
1714
1811
|
if len(name) > 16:
|
|
1715
1812
|
name = name[:16]
|
|
1716
1813
|
|
|
1717
|
-
value = ""
|
|
1718
|
-
if mode_id in (2, 3):
|
|
1719
|
-
seconds = float(int(getattr(entry, "survival_elapsed_ms", 0))) * 0.001
|
|
1720
|
-
value = f"{seconds:7.2f}s"
|
|
1721
|
-
else:
|
|
1722
|
-
value = f"{int(getattr(entry, 'score_xp', 0)):7d}"
|
|
1814
|
+
value = f"{int(getattr(entry, 'score_xp', 0))}"
|
|
1723
1815
|
|
|
1724
1816
|
color = rl.Color(255, 255, 255, int(255 * 0.7))
|
|
1725
1817
|
if highlight_rank is not None and int(highlight_rank) == idx:
|
|
1726
1818
|
color = rl.Color(255, 255, 255, 255)
|
|
1727
1819
|
|
|
1728
|
-
draw_small_text(font, f"{idx + 1
|
|
1729
|
-
draw_small_text(font,
|
|
1730
|
-
draw_small_text(font,
|
|
1820
|
+
draw_small_text(font, f"{idx + 1}", left_x0 + 216.0 * scale, y, 1.0 * scale, color)
|
|
1821
|
+
draw_small_text(font, value, left_x0 + 246.0 * scale, y, 1.0 * scale, color)
|
|
1822
|
+
draw_small_text(font, name, left_x0 + 304.0 * scale, y, 1.0 * scale, color)
|
|
1731
1823
|
y += row_step
|
|
1732
1824
|
|
|
1733
1825
|
textures = self._button_textures
|
|
1734
1826
|
if textures is not None and (textures.button_sm is not None or textures.button_md is not None):
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
button_draw(
|
|
1743
|
-
|
|
1827
|
+
button_x = left_x0 + HS_BUTTON_X * scale
|
|
1828
|
+
button_y0 = left_y0 + HS_BUTTON_Y0 * scale
|
|
1829
|
+
w = button_width(None, self._update_button.label, scale=scale, force_wide=self._update_button.force_wide)
|
|
1830
|
+
button_draw(textures, font, self._update_button, x=button_x, y=button_y0, width=w, scale=scale)
|
|
1831
|
+
w = button_width(None, self._play_button.label, scale=scale, force_wide=self._play_button.force_wide)
|
|
1832
|
+
button_draw(textures, font, self._play_button, x=button_x, y=button_y0 + HS_BUTTON_STEP_Y * scale, width=w, scale=scale)
|
|
1833
|
+
w = button_width(None, self._back_button.label, scale=scale, force_wide=self._back_button.force_wide)
|
|
1834
|
+
button_draw(
|
|
1835
|
+
textures,
|
|
1836
|
+
font,
|
|
1837
|
+
self._back_button,
|
|
1838
|
+
x=left_x0 + HS_BACK_BUTTON_X * scale,
|
|
1839
|
+
y=left_y0 + HS_BACK_BUTTON_Y * scale,
|
|
1840
|
+
width=w,
|
|
1841
|
+
scale=scale,
|
|
1842
|
+
)
|
|
1744
1843
|
|
|
1745
|
-
|
|
1746
|
-
font,
|
|
1747
|
-
"UP/DOWN: Scroll PGUP/PGDN: Page ESC: Back",
|
|
1748
|
-
32.0,
|
|
1749
|
-
float(rl.get_screen_height()) - 28.0,
|
|
1750
|
-
1.0,
|
|
1751
|
-
rl.Color(190, 190, 200, 255),
|
|
1752
|
-
)
|
|
1844
|
+
self._draw_sign(assets)
|
|
1753
1845
|
_draw_menu_cursor(self._state, pulse_time=self._cursor_pulse_time)
|
|
1754
1846
|
|
|
1847
|
+
def _draw_sign(self, assets: MenuAssets) -> None:
|
|
1848
|
+
if assets.sign is None:
|
|
1849
|
+
return
|
|
1850
|
+
sign = assets.sign
|
|
1851
|
+
screen_w = float(self._state.config.screen_width)
|
|
1852
|
+
sign_scale, shift_x = MenuView._sign_layout_scale(int(screen_w))
|
|
1853
|
+
pos_x = screen_w + MENU_SIGN_POS_X_PAD
|
|
1854
|
+
pos_y = MENU_SIGN_POS_Y if screen_w > MENU_SCALE_SMALL_THRESHOLD else MENU_SIGN_POS_Y_SMALL
|
|
1855
|
+
sign_w = MENU_SIGN_WIDTH * sign_scale
|
|
1856
|
+
sign_h = MENU_SIGN_HEIGHT * sign_scale
|
|
1857
|
+
offset_x = MENU_SIGN_OFFSET_X * sign_scale + shift_x
|
|
1858
|
+
offset_y = MENU_SIGN_OFFSET_Y * sign_scale
|
|
1859
|
+
rotation_deg = 0.0
|
|
1860
|
+
fx_detail = bool(self._state.config.data.get("fx_detail_0", 0))
|
|
1861
|
+
if fx_detail:
|
|
1862
|
+
MenuView._draw_ui_quad_shadow(
|
|
1863
|
+
texture=sign,
|
|
1864
|
+
src=rl.Rectangle(0.0, 0.0, float(sign.width), float(sign.height)),
|
|
1865
|
+
dst=rl.Rectangle(pos_x + UI_SHADOW_OFFSET, pos_y + UI_SHADOW_OFFSET, sign_w, sign_h),
|
|
1866
|
+
origin=rl.Vector2(-offset_x, -offset_y),
|
|
1867
|
+
rotation_deg=rotation_deg,
|
|
1868
|
+
)
|
|
1869
|
+
MenuView._draw_ui_quad(
|
|
1870
|
+
texture=sign,
|
|
1871
|
+
src=rl.Rectangle(0.0, 0.0, float(sign.width), float(sign.height)),
|
|
1872
|
+
dst=rl.Rectangle(pos_x, pos_y, sign_w, sign_h),
|
|
1873
|
+
origin=rl.Vector2(-offset_x, -offset_y),
|
|
1874
|
+
rotation_deg=rotation_deg,
|
|
1875
|
+
tint=rl.WHITE,
|
|
1876
|
+
)
|
|
1877
|
+
|
|
1878
|
+
@staticmethod
|
|
1879
|
+
def _quest_title(major: int, minor: int) -> str:
|
|
1880
|
+
try:
|
|
1881
|
+
from .quests import quest_by_level
|
|
1882
|
+
|
|
1883
|
+
q = quest_by_level(f"{int(major)}.{int(minor)}")
|
|
1884
|
+
if q is not None and q.title:
|
|
1885
|
+
return str(q.title)
|
|
1886
|
+
except Exception:
|
|
1887
|
+
pass
|
|
1888
|
+
return "???"
|
|
1889
|
+
|
|
1755
1890
|
def take_action(self) -> str | None:
|
|
1756
1891
|
action = self._action
|
|
1757
1892
|
self._action = None
|
|
@@ -1817,6 +1952,9 @@ class GameLoopView:
|
|
|
1817
1952
|
"open_options": OptionsMenuView(state),
|
|
1818
1953
|
"open_controls": ControlsMenuView(state),
|
|
1819
1954
|
"open_statistics": StatisticsMenuView(state),
|
|
1955
|
+
"open_weapon_database": UnlockedWeaponsDatabaseView(state),
|
|
1956
|
+
"open_perk_database": UnlockedPerksDatabaseView(state),
|
|
1957
|
+
"open_credits": CreditsView(state),
|
|
1820
1958
|
"open_mods": ModsMenuView(state),
|
|
1821
1959
|
"open_other_games": PanelMenuView(
|
|
1822
1960
|
state,
|
|
@@ -1936,7 +2074,7 @@ class GameLoopView:
|
|
|
1936
2074
|
if action is not None:
|
|
1937
2075
|
view = self._front_views.get(action)
|
|
1938
2076
|
if view is not None:
|
|
1939
|
-
if action
|
|
2077
|
+
if action in {"open_high_scores", "open_weapon_database", "open_perk_database", "open_credits"}:
|
|
1940
2078
|
if (self._front_active in self._gameplay_views) and (self._state.pause_background is None):
|
|
1941
2079
|
self._state.pause_background = self._front_active
|
|
1942
2080
|
self._front_stack.append(self._front_active)
|
crimson/modes/quest_mode.py
CHANGED
|
@@ -24,7 +24,9 @@ from ..quests.types import QuestContext, QuestDefinition, SpawnEntry
|
|
|
24
24
|
from ..terrain_assets import terrain_texture_by_id
|
|
25
25
|
from ..ui.cursor import draw_aim_cursor, draw_menu_cursor
|
|
26
26
|
from ..ui.hud import draw_hud_overlay, hud_flags_for_game_mode
|
|
27
|
+
from ..ui.menu_panel import draw_classic_menu_panel
|
|
27
28
|
from ..ui.perk_menu import (
|
|
29
|
+
PERK_MENU_TRANSITION_MS,
|
|
28
30
|
PerkMenuAssets,
|
|
29
31
|
PerkMenuLayout,
|
|
30
32
|
UiButtonState,
|
|
@@ -32,10 +34,10 @@ from ..ui.perk_menu import (
|
|
|
32
34
|
button_update,
|
|
33
35
|
button_width,
|
|
34
36
|
draw_menu_item,
|
|
35
|
-
draw_menu_panel,
|
|
36
37
|
draw_ui_text,
|
|
37
38
|
load_perk_menu_assets,
|
|
38
39
|
menu_item_hit_rect,
|
|
40
|
+
perk_menu_panel_slide_x,
|
|
39
41
|
perk_menu_compute_layout,
|
|
40
42
|
ui_origin,
|
|
41
43
|
ui_scale,
|
|
@@ -78,8 +80,6 @@ PERK_PROMPT_LEVEL_UP_SHIFT_Y = -4.0
|
|
|
78
80
|
PERK_PROMPT_TEXT_MARGIN_X = 16.0
|
|
79
81
|
PERK_PROMPT_TEXT_OFFSET_Y = 8.0
|
|
80
82
|
|
|
81
|
-
PERK_MENU_TRANSITION_MS = 500.0
|
|
82
|
-
|
|
83
83
|
|
|
84
84
|
@dataclass(slots=True)
|
|
85
85
|
class _QuestRunState:
|
|
@@ -440,8 +440,7 @@ class QuestMode(BaseGameplayMode):
|
|
|
440
440
|
screen_h = float(rl.get_screen_height())
|
|
441
441
|
scale = ui_scale(screen_w, screen_h)
|
|
442
442
|
origin_x, origin_y = ui_origin(screen_w, screen_h, scale)
|
|
443
|
-
|
|
444
|
-
slide_x = (menu_t - 1.0) * (self._perk_ui_layout.panel_w * scale)
|
|
443
|
+
slide_x = perk_menu_panel_slide_x(self._perk_menu_timeline_ms, width=self._perk_ui_layout.panel_w)
|
|
445
444
|
|
|
446
445
|
mouse = self._ui_mouse_pos()
|
|
447
446
|
click = rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT)
|
|
@@ -451,12 +450,13 @@ class QuestMode(BaseGameplayMode):
|
|
|
451
450
|
computed = perk_menu_compute_layout(
|
|
452
451
|
self._perk_ui_layout,
|
|
453
452
|
screen_w=screen_w,
|
|
454
|
-
origin_x=origin_x
|
|
453
|
+
origin_x=origin_x,
|
|
455
454
|
origin_y=origin_y,
|
|
456
455
|
scale=scale,
|
|
457
456
|
choice_count=len(choices),
|
|
458
457
|
expert_owned=expert_owned,
|
|
459
458
|
master_owned=master_owned,
|
|
459
|
+
panel_slide_x=slide_x,
|
|
460
460
|
)
|
|
461
461
|
|
|
462
462
|
fx_toggle = int(self._config.data.get("fx_toggle", 0) or 0) if self._config is not None else 0
|
|
@@ -634,25 +634,26 @@ class QuestMode(BaseGameplayMode):
|
|
|
634
634
|
screen_h = float(rl.get_screen_height())
|
|
635
635
|
scale = ui_scale(screen_w, screen_h)
|
|
636
636
|
origin_x, origin_y = ui_origin(screen_w, screen_h, scale)
|
|
637
|
-
slide_x = (
|
|
637
|
+
slide_x = perk_menu_panel_slide_x(self._perk_menu_timeline_ms, width=self._perk_ui_layout.panel_w)
|
|
638
638
|
|
|
639
639
|
master_owned = int(self._player.perk_counts[int(PerkId.PERK_MASTER)]) > 0
|
|
640
640
|
expert_owned = int(self._player.perk_counts[int(PerkId.PERK_EXPERT)]) > 0
|
|
641
641
|
computed = perk_menu_compute_layout(
|
|
642
642
|
self._perk_ui_layout,
|
|
643
643
|
screen_w=screen_w,
|
|
644
|
-
origin_x=origin_x
|
|
644
|
+
origin_x=origin_x,
|
|
645
645
|
origin_y=origin_y,
|
|
646
646
|
scale=scale,
|
|
647
647
|
choice_count=len(choices),
|
|
648
648
|
expert_owned=expert_owned,
|
|
649
649
|
master_owned=master_owned,
|
|
650
|
+
panel_slide_x=slide_x,
|
|
650
651
|
)
|
|
651
652
|
|
|
652
653
|
panel_tex = self._perk_menu_assets.menu_panel
|
|
653
654
|
if panel_tex is not None:
|
|
654
655
|
fx_detail = bool(int(self._config.data.get("fx_detail_0", 0) or 0)) if self._config is not None else False
|
|
655
|
-
|
|
656
|
+
draw_classic_menu_panel(panel_tex, dst=computed.panel, shadow=fx_detail)
|
|
656
657
|
|
|
657
658
|
title_tex = self._perk_menu_assets.title_pick_perk
|
|
658
659
|
if title_tex is not None:
|
crimson/modes/survival_mode.py
CHANGED
|
@@ -19,18 +19,20 @@ from ..persistence.highscores import HighScoreRecord
|
|
|
19
19
|
from ..perks import PerkId, perk_display_description, perk_display_name
|
|
20
20
|
from ..ui.cursor import draw_aim_cursor, draw_menu_cursor
|
|
21
21
|
from ..ui.hud import draw_hud_overlay, hud_flags_for_game_mode
|
|
22
|
+
from ..ui.menu_panel import draw_classic_menu_panel
|
|
22
23
|
from ..input_codes import config_keybinds, input_code_is_down, input_code_is_pressed, player_move_fire_binds
|
|
23
24
|
from ..ui.perk_menu import (
|
|
25
|
+
PERK_MENU_TRANSITION_MS,
|
|
24
26
|
PerkMenuLayout,
|
|
25
27
|
UiButtonState,
|
|
26
28
|
button_draw,
|
|
27
29
|
button_update,
|
|
28
30
|
button_width,
|
|
29
|
-
draw_menu_panel,
|
|
30
31
|
draw_menu_item,
|
|
31
32
|
draw_ui_text,
|
|
32
33
|
load_perk_menu_assets,
|
|
33
34
|
menu_item_hit_rect,
|
|
35
|
+
perk_menu_panel_slide_x,
|
|
34
36
|
perk_menu_compute_layout,
|
|
35
37
|
ui_origin,
|
|
36
38
|
ui_scale,
|
|
@@ -69,8 +71,6 @@ PERK_PROMPT_LEVEL_UP_SHIFT_Y = -4.0
|
|
|
69
71
|
PERK_PROMPT_TEXT_MARGIN_X = 16.0
|
|
70
72
|
PERK_PROMPT_TEXT_OFFSET_Y = 8.0
|
|
71
73
|
|
|
72
|
-
PERK_MENU_TRANSITION_MS = 500.0
|
|
73
|
-
|
|
74
74
|
|
|
75
75
|
@dataclass(slots=True)
|
|
76
76
|
class _SurvivalState:
|
|
@@ -358,8 +358,7 @@ class SurvivalMode(BaseGameplayMode):
|
|
|
358
358
|
screen_h = float(rl.get_screen_height())
|
|
359
359
|
scale = ui_scale(screen_w, screen_h)
|
|
360
360
|
origin_x, origin_y = ui_origin(screen_w, screen_h, scale)
|
|
361
|
-
|
|
362
|
-
slide_x = (menu_t - 1.0) * (self._perk_ui_layout.panel_w * scale)
|
|
361
|
+
slide_x = perk_menu_panel_slide_x(self._perk_menu_timeline_ms, width=self._perk_ui_layout.panel_w)
|
|
363
362
|
|
|
364
363
|
mouse = self._ui_mouse_pos()
|
|
365
364
|
click = rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT)
|
|
@@ -369,12 +368,13 @@ class SurvivalMode(BaseGameplayMode):
|
|
|
369
368
|
computed = perk_menu_compute_layout(
|
|
370
369
|
self._perk_ui_layout,
|
|
371
370
|
screen_w=screen_w,
|
|
372
|
-
origin_x=origin_x
|
|
371
|
+
origin_x=origin_x,
|
|
373
372
|
origin_y=origin_y,
|
|
374
373
|
scale=scale,
|
|
375
374
|
choice_count=len(choices),
|
|
376
375
|
expert_owned=expert_owned,
|
|
377
376
|
master_owned=master_owned,
|
|
377
|
+
panel_slide_x=slide_x,
|
|
378
378
|
)
|
|
379
379
|
|
|
380
380
|
fx_toggle = int(self._config.data.get("fx_toggle", 0) or 0) if self._config is not None else 0
|
|
@@ -654,25 +654,26 @@ class SurvivalMode(BaseGameplayMode):
|
|
|
654
654
|
screen_h = float(rl.get_screen_height())
|
|
655
655
|
scale = ui_scale(screen_w, screen_h)
|
|
656
656
|
origin_x, origin_y = ui_origin(screen_w, screen_h, scale)
|
|
657
|
-
slide_x = (
|
|
657
|
+
slide_x = perk_menu_panel_slide_x(self._perk_menu_timeline_ms, width=self._perk_ui_layout.panel_w)
|
|
658
658
|
|
|
659
659
|
master_owned = int(self._player.perk_counts[int(PerkId.PERK_MASTER)]) > 0
|
|
660
660
|
expert_owned = int(self._player.perk_counts[int(PerkId.PERK_EXPERT)]) > 0
|
|
661
661
|
computed = perk_menu_compute_layout(
|
|
662
662
|
self._perk_ui_layout,
|
|
663
663
|
screen_w=screen_w,
|
|
664
|
-
origin_x=origin_x
|
|
664
|
+
origin_x=origin_x,
|
|
665
665
|
origin_y=origin_y,
|
|
666
666
|
scale=scale,
|
|
667
667
|
choice_count=len(choices),
|
|
668
668
|
expert_owned=expert_owned,
|
|
669
669
|
master_owned=master_owned,
|
|
670
|
+
panel_slide_x=slide_x,
|
|
670
671
|
)
|
|
671
672
|
|
|
672
673
|
panel_tex = self._perk_menu_assets.menu_panel
|
|
673
674
|
if panel_tex is not None:
|
|
674
675
|
fx_detail = bool(int(self._config.data.get("fx_detail_0", 0) or 0)) if self._config is not None else False
|
|
675
|
-
|
|
676
|
+
draw_classic_menu_panel(panel_tex, dst=computed.panel, shadow=fx_detail)
|
|
676
677
|
|
|
677
678
|
title_tex = self._perk_menu_assets.title_pick_perk
|
|
678
679
|
if title_tex is not None:
|