crimsonland 0.1.0.dev5__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/__init__.py +24 -0
- crimson/assets_fetch.py +60 -0
- crimson/atlas.py +92 -0
- crimson/audio_router.py +155 -0
- crimson/bonuses.py +167 -0
- crimson/camera.py +75 -0
- crimson/cli.py +380 -0
- crimson/creatures/__init__.py +8 -0
- crimson/creatures/ai.py +186 -0
- crimson/creatures/anim.py +173 -0
- crimson/creatures/damage.py +103 -0
- crimson/creatures/runtime.py +1019 -0
- crimson/creatures/spawn.py +2871 -0
- crimson/debug.py +7 -0
- crimson/demo.py +1360 -0
- crimson/demo_trial.py +140 -0
- crimson/effects.py +1086 -0
- crimson/effects_atlas.py +73 -0
- crimson/frontend/__init__.py +1 -0
- crimson/frontend/assets.py +43 -0
- crimson/frontend/boot.py +424 -0
- crimson/frontend/menu.py +700 -0
- crimson/frontend/panels/__init__.py +1 -0
- crimson/frontend/panels/base.py +410 -0
- crimson/frontend/panels/controls.py +132 -0
- crimson/frontend/panels/mods.py +128 -0
- crimson/frontend/panels/options.py +409 -0
- crimson/frontend/panels/play_game.py +627 -0
- crimson/frontend/panels/stats.py +351 -0
- crimson/frontend/transitions.py +31 -0
- crimson/game.py +2533 -0
- crimson/game_modes.py +15 -0
- crimson/game_world.py +652 -0
- crimson/gameplay.py +2467 -0
- crimson/input_codes.py +176 -0
- crimson/modes/__init__.py +1 -0
- crimson/modes/base_gameplay_mode.py +219 -0
- crimson/modes/quest_mode.py +502 -0
- crimson/modes/rush_mode.py +300 -0
- crimson/modes/survival_mode.py +792 -0
- crimson/modes/tutorial_mode.py +648 -0
- crimson/modes/typo_mode.py +472 -0
- crimson/paths.py +23 -0
- crimson/perks.py +828 -0
- crimson/persistence/__init__.py +1 -0
- crimson/persistence/highscores.py +385 -0
- crimson/persistence/save_status.py +245 -0
- crimson/player_damage.py +77 -0
- crimson/projectiles.py +1133 -0
- crimson/quests/__init__.py +18 -0
- crimson/quests/helpers.py +147 -0
- crimson/quests/registry.py +49 -0
- crimson/quests/results.py +164 -0
- crimson/quests/runtime.py +91 -0
- crimson/quests/tier1.py +620 -0
- crimson/quests/tier2.py +652 -0
- crimson/quests/tier3.py +579 -0
- crimson/quests/tier4.py +721 -0
- crimson/quests/tier5.py +886 -0
- crimson/quests/timeline.py +115 -0
- crimson/quests/types.py +70 -0
- crimson/render/__init__.py +1 -0
- crimson/render/terrain_fx.py +88 -0
- crimson/render/world_renderer.py +1941 -0
- crimson/sim/__init__.py +1 -0
- crimson/sim/world_defs.py +67 -0
- crimson/sim/world_state.py +422 -0
- crimson/terrain_assets.py +19 -0
- crimson/tutorial/__init__.py +12 -0
- crimson/tutorial/timeline.py +291 -0
- crimson/typo/__init__.py +2 -0
- crimson/typo/names.py +233 -0
- crimson/typo/player.py +43 -0
- crimson/typo/spawns.py +73 -0
- crimson/typo/typing.py +52 -0
- crimson/ui/__init__.py +3 -0
- crimson/ui/cursor.py +95 -0
- crimson/ui/demo_trial_overlay.py +235 -0
- crimson/ui/game_over.py +660 -0
- crimson/ui/hud.py +601 -0
- crimson/ui/perk_menu.py +388 -0
- crimson/views/__init__.py +40 -0
- crimson/views/aim_debug.py +276 -0
- crimson/views/animations.py +274 -0
- crimson/views/arsenal_debug.py +404 -0
- crimson/views/audio_bootstrap.py +47 -0
- crimson/views/bonuses.py +201 -0
- crimson/views/camera_debug.py +359 -0
- crimson/views/camera_shake.py +229 -0
- crimson/views/corpse_stamp_debug.py +324 -0
- crimson/views/decals_debug.py +739 -0
- crimson/views/empty.py +19 -0
- crimson/views/fonts.py +114 -0
- crimson/views/game_over.py +117 -0
- crimson/views/ground.py +259 -0
- crimson/views/lighting_debug.py +1166 -0
- crimson/views/particles.py +293 -0
- crimson/views/perk_menu_debug.py +430 -0
- crimson/views/perks.py +398 -0
- crimson/views/player.py +434 -0
- crimson/views/player_sprite_debug.py +314 -0
- crimson/views/projectile_fx.py +609 -0
- crimson/views/projectile_render_debug.py +393 -0
- crimson/views/projectiles.py +221 -0
- crimson/views/quest_title_overlay.py +108 -0
- crimson/views/registry.py +34 -0
- crimson/views/rush.py +16 -0
- crimson/views/small_font_debug.py +204 -0
- crimson/views/spawn_plan.py +363 -0
- crimson/views/sprites.py +214 -0
- crimson/views/survival.py +15 -0
- crimson/views/terrain.py +132 -0
- crimson/views/ui.py +123 -0
- crimson/views/wicons.py +166 -0
- crimson/weapon_sfx.py +63 -0
- crimson/weapons.py +860 -0
- crimsonland-0.1.0.dev5.dist-info/METADATA +9 -0
- crimsonland-0.1.0.dev5.dist-info/RECORD +139 -0
- crimsonland-0.1.0.dev5.dist-info/WHEEL +4 -0
- crimsonland-0.1.0.dev5.dist-info/entry_points.txt +4 -0
- grim/__init__.py +20 -0
- grim/app.py +92 -0
- grim/assets.py +231 -0
- grim/audio.py +106 -0
- grim/config.py +294 -0
- grim/console.py +737 -0
- grim/fonts/__init__.py +7 -0
- grim/fonts/grim_mono.py +111 -0
- grim/fonts/small.py +120 -0
- grim/input.py +44 -0
- grim/jaz.py +103 -0
- grim/math.py +17 -0
- grim/music.py +403 -0
- grim/paq.py +76 -0
- grim/rand.py +37 -0
- grim/sfx.py +276 -0
- grim/sfx_map.py +103 -0
- grim/terrain_render.py +840 -0
- grim/view.py +16 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
import pyray as rl
|
|
6
|
+
|
|
7
|
+
from grim.fonts.grim_mono import GrimMonoFont, draw_grim_mono_text
|
|
8
|
+
|
|
9
|
+
QUEST_TITLE_ALPHA = 1.0
|
|
10
|
+
QUEST_NUMBER_ALPHA_RATIO = 0.5
|
|
11
|
+
|
|
12
|
+
# Game base scale: 0.75 at 640px width, 0.8 at larger widths.
|
|
13
|
+
QUEST_TITLE_SCALE_SMALL = 0.75
|
|
14
|
+
QUEST_TITLE_SCALE_LARGE = 0.8
|
|
15
|
+
QUEST_TITLE_SCALE_THRESHOLD_PX = 640
|
|
16
|
+
|
|
17
|
+
# Title overlay baseline is centered vertically and shifted up by 32px (0x20).
|
|
18
|
+
QUEST_TITLE_Y_OFFSET = 32.0
|
|
19
|
+
|
|
20
|
+
# Number is drawn at a slightly smaller scale.
|
|
21
|
+
QUEST_NUMBER_SCALE_DELTA = 0.2
|
|
22
|
+
|
|
23
|
+
# Game X formula: x = title_x - (strlen * scale * 8.0) - (scale * 32.0) - 4.0
|
|
24
|
+
# where 8.0 = advance/2, 32.0 = base gap, 4.0 = fixed offset.
|
|
25
|
+
QUEST_NUMBER_HALF_ADVANCE = 8.0
|
|
26
|
+
QUEST_NUMBER_BASE_GAP = 32.0
|
|
27
|
+
QUEST_NUMBER_FIXED_OFFSET = 4.0
|
|
28
|
+
|
|
29
|
+
# Game Y formula: y = title_y + number_scale * (23.36 - 16.0) = title_y + number_scale * 7.36
|
|
30
|
+
QUEST_NUMBER_Y_MULTIPLIER = 7.36
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True, slots=True)
|
|
34
|
+
class QuestTitleOverlayLayout:
|
|
35
|
+
title_x: float
|
|
36
|
+
title_y: float
|
|
37
|
+
title_scale: float
|
|
38
|
+
number_x: float
|
|
39
|
+
number_y: float
|
|
40
|
+
number_scale: float
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def quest_title_base_scale(screen_width: int) -> float:
|
|
44
|
+
return QUEST_TITLE_SCALE_SMALL if screen_width <= QUEST_TITLE_SCALE_THRESHOLD_PX else QUEST_TITLE_SCALE_LARGE
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def quest_number_scale(title_scale: float) -> float:
|
|
48
|
+
return max(0.0, title_scale - QUEST_NUMBER_SCALE_DELTA)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def layout_quest_title_overlay(
|
|
52
|
+
*,
|
|
53
|
+
screen_width: float,
|
|
54
|
+
screen_height: float,
|
|
55
|
+
title: str,
|
|
56
|
+
number: str,
|
|
57
|
+
font_advance: float,
|
|
58
|
+
) -> QuestTitleOverlayLayout:
|
|
59
|
+
title_scale = quest_title_base_scale(int(screen_width))
|
|
60
|
+
number_scale = quest_number_scale(title_scale)
|
|
61
|
+
|
|
62
|
+
title_width = len(title) * font_advance * title_scale
|
|
63
|
+
# The game uses integer division for screen center (width/2, height/2) before converting to float.
|
|
64
|
+
center_x = float(int(screen_width) // 2)
|
|
65
|
+
center_y = float(int(screen_height) // 2)
|
|
66
|
+
title_x = center_x - (title_width / 2.0)
|
|
67
|
+
title_y = center_y - QUEST_TITLE_Y_OFFSET
|
|
68
|
+
|
|
69
|
+
number_x = (
|
|
70
|
+
title_x
|
|
71
|
+
- (len(number) * number_scale * QUEST_NUMBER_HALF_ADVANCE)
|
|
72
|
+
- (number_scale * QUEST_NUMBER_BASE_GAP)
|
|
73
|
+
- QUEST_NUMBER_FIXED_OFFSET
|
|
74
|
+
)
|
|
75
|
+
number_y = title_y + (number_scale * QUEST_NUMBER_Y_MULTIPLIER)
|
|
76
|
+
|
|
77
|
+
return QuestTitleOverlayLayout(
|
|
78
|
+
title_x=title_x,
|
|
79
|
+
title_y=title_y,
|
|
80
|
+
title_scale=title_scale,
|
|
81
|
+
number_x=number_x,
|
|
82
|
+
number_y=number_y,
|
|
83
|
+
number_scale=number_scale,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def draw_quest_title_overlay(font: GrimMonoFont, title: str, number: str, *, alpha: float = 1.0) -> None:
|
|
88
|
+
alpha = max(0.0, min(1.0, float(alpha)))
|
|
89
|
+
layout = layout_quest_title_overlay(
|
|
90
|
+
screen_width=rl.get_screen_width(),
|
|
91
|
+
screen_height=rl.get_screen_height(),
|
|
92
|
+
title=title,
|
|
93
|
+
number=number,
|
|
94
|
+
font_advance=font.advance,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
title_color = rl.Color(255, 255, 255, int(255 * QUEST_TITLE_ALPHA * alpha))
|
|
98
|
+
number_color = rl.Color(255, 255, 255, int(255 * QUEST_TITLE_ALPHA * QUEST_NUMBER_ALPHA_RATIO * alpha))
|
|
99
|
+
|
|
100
|
+
draw_grim_mono_text(font, title, layout.title_x, layout.title_y, layout.title_scale, title_color)
|
|
101
|
+
draw_grim_mono_text(
|
|
102
|
+
font,
|
|
103
|
+
number,
|
|
104
|
+
layout.number_x,
|
|
105
|
+
layout.number_y,
|
|
106
|
+
layout.number_scale,
|
|
107
|
+
number_color,
|
|
108
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Callable
|
|
5
|
+
|
|
6
|
+
from grim.view import View
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True, slots=True)
|
|
10
|
+
class ViewDefinition:
|
|
11
|
+
name: str
|
|
12
|
+
title: str
|
|
13
|
+
factory: Callable[..., View]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
_VIEW_REGISTRY: dict[str, ViewDefinition] = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def register_view(name: str, title: str) -> Callable[[Callable[..., View]], Callable[..., View]]:
|
|
20
|
+
def decorator(factory: Callable[..., View]) -> Callable[..., View]:
|
|
21
|
+
if name in _VIEW_REGISTRY:
|
|
22
|
+
raise ValueError(f"view already registered: {name}")
|
|
23
|
+
_VIEW_REGISTRY[name] = ViewDefinition(name=name, title=title, factory=factory)
|
|
24
|
+
return factory
|
|
25
|
+
|
|
26
|
+
return decorator
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def all_views() -> list[ViewDefinition]:
|
|
30
|
+
return [_VIEW_REGISTRY[name] for name in sorted(_VIEW_REGISTRY.keys(), key=str.casefold)]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def view_by_name(name: str) -> ViewDefinition | None:
|
|
34
|
+
return _VIEW_REGISTRY.get(name)
|
crimson/views/rush.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from grim.view import ViewContext
|
|
4
|
+
|
|
5
|
+
from ..modes.rush_mode import RushMode
|
|
6
|
+
from .registry import register_view
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RushView(RushMode):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@register_view("rush", "Rush")
|
|
14
|
+
def _create_rush_view(*, ctx: ViewContext) -> RushView:
|
|
15
|
+
return RushView(ctx)
|
|
16
|
+
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pyray as rl
|
|
6
|
+
|
|
7
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
8
|
+
from grim.view import View, ViewContext
|
|
9
|
+
|
|
10
|
+
from ..ui.perk_menu import MENU_ITEM_ALPHA_IDLE, MENU_ITEM_RGB, draw_menu_item
|
|
11
|
+
from .registry import register_view
|
|
12
|
+
|
|
13
|
+
UI_TEXT_COLOR = rl.Color(220, 220, 220, 255)
|
|
14
|
+
UI_ERROR_COLOR = rl.Color(240, 80, 80, 255)
|
|
15
|
+
|
|
16
|
+
SAMPLE_LINES = [
|
|
17
|
+
"Regeneration",
|
|
18
|
+
"My Favourite Weapon",
|
|
19
|
+
"Ammo Maniac",
|
|
20
|
+
"Pyromaniac",
|
|
21
|
+
"Evil Eyes",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
ARIAL_FONT_LOAD_SIZE = 26
|
|
25
|
+
ARIAL_FONT_DRAW_SIZE = 13
|
|
26
|
+
PIXEL_ARIAL_LOAD_SIZE = 22
|
|
27
|
+
PIXEL_ARIAL_DRAW_SIZE = 11
|
|
28
|
+
VECTOR_FONT_SPACING = 1.0
|
|
29
|
+
VECTOR_FONT_FILTER = rl.TEXTURE_FILTER_BILINEAR
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SmallFontDebugView:
|
|
33
|
+
def __init__(self, ctx: ViewContext) -> None:
|
|
34
|
+
self._assets_root = ctx.assets_dir
|
|
35
|
+
self._missing_assets: list[str] = []
|
|
36
|
+
self._small: SmallFontData | None = None
|
|
37
|
+
self._screenshot_requested = False
|
|
38
|
+
self._vector_font: rl.Font | None = None
|
|
39
|
+
self._vector_font_path: Path | None = None
|
|
40
|
+
self._vector_font_alt: rl.Font | None = None
|
|
41
|
+
self._vector_font_alt_path: Path | None = None
|
|
42
|
+
|
|
43
|
+
def open(self) -> None:
|
|
44
|
+
self._missing_assets.clear()
|
|
45
|
+
self._small = load_small_font(self._assets_root, self._missing_assets)
|
|
46
|
+
self._vector_font = None
|
|
47
|
+
self._vector_font_path = None
|
|
48
|
+
self._vector_font_alt = None
|
|
49
|
+
self._vector_font_alt_path = None
|
|
50
|
+
for candidate in (
|
|
51
|
+
self._assets_root / "crimson" / "load" / "arial.ttf",
|
|
52
|
+
self._assets_root / "fonts" / "arial.ttf",
|
|
53
|
+
self._assets_root / "arial.ttf",
|
|
54
|
+
):
|
|
55
|
+
if not candidate.is_file():
|
|
56
|
+
continue
|
|
57
|
+
try:
|
|
58
|
+
self._vector_font = rl.load_font_ex(str(candidate), ARIAL_FONT_LOAD_SIZE, None, 0)
|
|
59
|
+
rl.set_texture_filter(self._vector_font.texture, VECTOR_FONT_FILTER)
|
|
60
|
+
self._vector_font_path = candidate
|
|
61
|
+
break
|
|
62
|
+
except Exception:
|
|
63
|
+
self._vector_font = None
|
|
64
|
+
self._vector_font_path = None
|
|
65
|
+
for candidate in (
|
|
66
|
+
self._assets_root / "crimson" / "load" / "PIXEARG_.TTF",
|
|
67
|
+
self._assets_root / "fonts" / "PIXEARG_.TTF",
|
|
68
|
+
self._assets_root / "PIXEARG_.TTF",
|
|
69
|
+
):
|
|
70
|
+
if not candidate.is_file():
|
|
71
|
+
continue
|
|
72
|
+
try:
|
|
73
|
+
self._vector_font_alt = rl.load_font_ex(str(candidate), PIXEL_ARIAL_LOAD_SIZE, None, 0)
|
|
74
|
+
rl.set_texture_filter(self._vector_font_alt.texture, VECTOR_FONT_FILTER)
|
|
75
|
+
self._vector_font_alt_path = candidate
|
|
76
|
+
break
|
|
77
|
+
except Exception:
|
|
78
|
+
self._vector_font_alt = None
|
|
79
|
+
self._vector_font_alt_path = None
|
|
80
|
+
|
|
81
|
+
def close(self) -> None:
|
|
82
|
+
if self._small is not None:
|
|
83
|
+
rl.unload_texture(self._small.texture)
|
|
84
|
+
self._small = None
|
|
85
|
+
if self._vector_font is not None:
|
|
86
|
+
rl.unload_font(self._vector_font)
|
|
87
|
+
self._vector_font = None
|
|
88
|
+
self._vector_font_path = None
|
|
89
|
+
if self._vector_font_alt is not None:
|
|
90
|
+
rl.unload_font(self._vector_font_alt)
|
|
91
|
+
self._vector_font_alt = None
|
|
92
|
+
self._vector_font_alt_path = None
|
|
93
|
+
|
|
94
|
+
def update(self, dt: float) -> None:
|
|
95
|
+
del dt
|
|
96
|
+
if rl.is_key_pressed(rl.KeyboardKey.KEY_P):
|
|
97
|
+
self._screenshot_requested = True
|
|
98
|
+
|
|
99
|
+
def consume_screenshot_request(self) -> bool:
|
|
100
|
+
requested = self._screenshot_requested
|
|
101
|
+
self._screenshot_requested = False
|
|
102
|
+
return requested
|
|
103
|
+
|
|
104
|
+
def draw(self) -> None:
|
|
105
|
+
rl.clear_background(rl.Color(12, 12, 14, 255))
|
|
106
|
+
if self._missing_assets:
|
|
107
|
+
rl.draw_text(
|
|
108
|
+
"Missing assets: " + ", ".join(self._missing_assets),
|
|
109
|
+
24,
|
|
110
|
+
24,
|
|
111
|
+
20,
|
|
112
|
+
UI_ERROR_COLOR,
|
|
113
|
+
)
|
|
114
|
+
return
|
|
115
|
+
if self._small is None:
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
margin = 24
|
|
119
|
+
gap = 40
|
|
120
|
+
header_y = 20
|
|
121
|
+
row_step = 19.0
|
|
122
|
+
vector_step = row_step
|
|
123
|
+
|
|
124
|
+
rl.draw_text("smallWhite atlas", margin, header_y, 20, UI_TEXT_COLOR)
|
|
125
|
+
atlas_y = header_y + 28
|
|
126
|
+
rl.draw_texture(self._small.texture, margin, atlas_y, rl.WHITE)
|
|
127
|
+
atlas_bottom = atlas_y + self._small.texture.height
|
|
128
|
+
|
|
129
|
+
right_x = margin + self._small.texture.width + gap
|
|
130
|
+
rl.draw_text("perk menu render", right_x, header_y, 20, UI_TEXT_COLOR)
|
|
131
|
+
text_y = float(atlas_y)
|
|
132
|
+
for line in SAMPLE_LINES:
|
|
133
|
+
draw_menu_item(self._small, line, x=float(right_x), y=text_y, scale=1.0, hovered=False)
|
|
134
|
+
text_y += row_step
|
|
135
|
+
perk_list_bottom = text_y
|
|
136
|
+
section_y = perk_list_bottom + 16.0
|
|
137
|
+
|
|
138
|
+
vector_x = right_x
|
|
139
|
+
rl.draw_text("Pixel Arial (PIXEARG_.TTF)", vector_x, int(section_y), 20, UI_TEXT_COLOR)
|
|
140
|
+
if self._vector_font_alt is None:
|
|
141
|
+
hint_y = section_y + 28.0
|
|
142
|
+
rl.draw_text("Place PIXEARG_.TTF in:", vector_x, int(hint_y), 16, UI_TEXT_COLOR)
|
|
143
|
+
rl.draw_text(str(self._assets_root / "crimson" / "load"), vector_x, int(hint_y + 18), 16, UI_TEXT_COLOR)
|
|
144
|
+
rl.draw_text(str(self._assets_root / "fonts"), vector_x, int(hint_y + 36), 16, UI_TEXT_COLOR)
|
|
145
|
+
vector_list_end = hint_y + 54.0
|
|
146
|
+
else:
|
|
147
|
+
vector_y = section_y + 28.0
|
|
148
|
+
for line in SAMPLE_LINES:
|
|
149
|
+
self._draw_vector_menu_item(
|
|
150
|
+
self._vector_font_alt,
|
|
151
|
+
line,
|
|
152
|
+
x=float(vector_x),
|
|
153
|
+
y=float(vector_y),
|
|
154
|
+
font_size_px=PIXEL_ARIAL_DRAW_SIZE,
|
|
155
|
+
spacing=VECTOR_FONT_SPACING,
|
|
156
|
+
)
|
|
157
|
+
vector_y += vector_step
|
|
158
|
+
vector_list_end = vector_y
|
|
159
|
+
alt_x = vector_x
|
|
160
|
+
alt_header_y = vector_list_end + 24.0
|
|
161
|
+
rl.draw_text("Arial (ttf)", alt_x, int(alt_header_y), 20, UI_TEXT_COLOR)
|
|
162
|
+
if self._vector_font is None:
|
|
163
|
+
hint_y = alt_header_y + 28.0
|
|
164
|
+
rl.draw_text("Place arial.ttf in:", alt_x, int(hint_y), 16, UI_TEXT_COLOR)
|
|
165
|
+
rl.draw_text(str(self._assets_root / "crimson" / "load"), alt_x, int(hint_y + 18), 16, UI_TEXT_COLOR)
|
|
166
|
+
rl.draw_text(str(self._assets_root / "fonts"), alt_x, int(hint_y + 36), 16, UI_TEXT_COLOR)
|
|
167
|
+
else:
|
|
168
|
+
alt_y = alt_header_y + 28.0
|
|
169
|
+
for line in SAMPLE_LINES:
|
|
170
|
+
self._draw_vector_menu_item(
|
|
171
|
+
self._vector_font,
|
|
172
|
+
line,
|
|
173
|
+
x=float(alt_x),
|
|
174
|
+
y=float(alt_y),
|
|
175
|
+
font_size_px=ARIAL_FONT_DRAW_SIZE,
|
|
176
|
+
spacing=VECTOR_FONT_SPACING,
|
|
177
|
+
)
|
|
178
|
+
alt_y += vector_step
|
|
179
|
+
|
|
180
|
+
def _draw_vector_menu_item(
|
|
181
|
+
self,
|
|
182
|
+
font: rl.Font,
|
|
183
|
+
text: str,
|
|
184
|
+
*,
|
|
185
|
+
x: float,
|
|
186
|
+
y: float,
|
|
187
|
+
font_size_px: float,
|
|
188
|
+
spacing: float,
|
|
189
|
+
) -> None:
|
|
190
|
+
r, g, b = MENU_ITEM_RGB
|
|
191
|
+
color = rl.Color(int(r), int(g), int(b), int(255 * MENU_ITEM_ALPHA_IDLE))
|
|
192
|
+
rl.draw_text_ex(font, text, rl.Vector2(float(x), float(y)), float(font_size_px), float(spacing), color)
|
|
193
|
+
try:
|
|
194
|
+
size = rl.measure_text_ex(font, text, float(font_size_px), float(spacing))
|
|
195
|
+
width = float(size.x)
|
|
196
|
+
except Exception:
|
|
197
|
+
width = float(rl.measure_text(text, int(font_size_px)))
|
|
198
|
+
line_y = y + 13.0
|
|
199
|
+
rl.draw_line(int(x), int(line_y), int(x + width), int(line_y), color)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@register_view("small-font-debug", "Small font debug")
|
|
203
|
+
def build_small_font_debug_view(ctx: ViewContext) -> View:
|
|
204
|
+
return SmallFontDebugView(ctx)
|