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
crimson/views/bonuses.py
CHANGED
|
@@ -6,8 +6,9 @@ import pyray as rl
|
|
|
6
6
|
|
|
7
7
|
from ..bonuses import BONUS_TABLE, BonusMeta
|
|
8
8
|
from ..weapons import WEAPON_TABLE
|
|
9
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
9
10
|
from .registry import register_view
|
|
10
|
-
from grim.fonts.small import SmallFontData,
|
|
11
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
11
12
|
from grim.view import View, ViewContext
|
|
12
13
|
|
|
13
14
|
UI_TEXT_SCALE = 1.0
|
|
@@ -46,24 +47,6 @@ class BonusIconView:
|
|
|
46
47
|
self._texture: rl.Texture | None = None
|
|
47
48
|
self._small: SmallFontData | None = None
|
|
48
49
|
|
|
49
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
50
|
-
if self._small is not None:
|
|
51
|
-
return int(self._small.cell_size * scale)
|
|
52
|
-
return int(20 * scale)
|
|
53
|
-
|
|
54
|
-
def _draw_ui_text(
|
|
55
|
-
self,
|
|
56
|
-
text: str,
|
|
57
|
-
x: float,
|
|
58
|
-
y: float,
|
|
59
|
-
color: rl.Color,
|
|
60
|
-
scale: float = UI_TEXT_SCALE,
|
|
61
|
-
) -> None:
|
|
62
|
-
if self._small is not None:
|
|
63
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
64
|
-
else:
|
|
65
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
66
|
-
|
|
67
50
|
def open(self) -> None:
|
|
68
51
|
self._missing_assets.clear()
|
|
69
52
|
self._small = load_small_font(self._assets_root, self._missing_assets)
|
|
@@ -88,10 +71,10 @@ class BonusIconView:
|
|
|
88
71
|
rl.clear_background(rl.Color(12, 12, 14, 255))
|
|
89
72
|
if self._missing_assets:
|
|
90
73
|
message = "Missing assets: " + ", ".join(self._missing_assets)
|
|
91
|
-
self.
|
|
74
|
+
draw_ui_text(self._small, message, 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
92
75
|
return
|
|
93
76
|
if self._texture is None:
|
|
94
|
-
self.
|
|
77
|
+
draw_ui_text(self._small, "No bonuses texture loaded.", 24, 24, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
95
78
|
return
|
|
96
79
|
|
|
97
80
|
margin = 24
|
|
@@ -149,41 +132,45 @@ class BonusIconView:
|
|
|
149
132
|
|
|
150
133
|
info_x = x + draw_w + panel_gap
|
|
151
134
|
info_y = margin
|
|
152
|
-
self.
|
|
153
|
-
info_y += self.
|
|
135
|
+
draw_ui_text(self._small, "bonuses.png (grid 4x4)", info_x, info_y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
136
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 12
|
|
154
137
|
|
|
155
138
|
if hovered_index is not None:
|
|
156
139
|
group = BONUS_ICON_GROUPS.get(hovered_index)
|
|
157
|
-
self.
|
|
158
|
-
info_y += self.
|
|
140
|
+
draw_ui_text(self._small, f"icon_id {hovered_index}", info_x, info_y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
141
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 6
|
|
159
142
|
if group is None:
|
|
160
|
-
self.
|
|
161
|
-
info_y += self.
|
|
143
|
+
draw_ui_text(self._small, "no bonus mapping", info_x, info_y, scale=UI_TEXT_SCALE, color=UI_HINT_COLOR)
|
|
144
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 6
|
|
162
145
|
else:
|
|
163
146
|
for entry in group.bonuses:
|
|
164
147
|
bonus_id = int(entry.bonus_id)
|
|
165
148
|
amount = entry.default_amount
|
|
166
149
|
amount_label = f" default={amount}" if amount is not None else ""
|
|
167
|
-
|
|
150
|
+
draw_ui_text(
|
|
151
|
+
self._small,
|
|
168
152
|
f"id {bonus_id:02d} {entry.name}{amount_label}",
|
|
169
153
|
info_x,
|
|
170
154
|
info_y,
|
|
171
|
-
|
|
155
|
+
scale=UI_TEXT_SCALE,
|
|
156
|
+
color=UI_TEXT_COLOR,
|
|
172
157
|
)
|
|
173
|
-
info_y += self.
|
|
158
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 4
|
|
174
159
|
if entry.description:
|
|
175
|
-
|
|
160
|
+
draw_ui_text(
|
|
161
|
+
self._small,
|
|
176
162
|
entry.description,
|
|
177
163
|
info_x,
|
|
178
164
|
info_y,
|
|
179
|
-
|
|
165
|
+
scale=UI_TEXT_SCALE,
|
|
166
|
+
color=UI_HINT_COLOR,
|
|
180
167
|
)
|
|
181
|
-
info_y += self.
|
|
168
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 4
|
|
182
169
|
info_y += 8
|
|
183
170
|
|
|
184
171
|
if WEAPON_BONUS is not None:
|
|
185
|
-
self.
|
|
186
|
-
info_y += self.
|
|
172
|
+
draw_ui_text(self._small, "Weapon bonus icon", info_x, info_y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
173
|
+
info_y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 4
|
|
187
174
|
weapon_id = WEAPON_BONUS.default_amount
|
|
188
175
|
weapon_name = None
|
|
189
176
|
if weapon_id is not None:
|
|
@@ -193,7 +180,7 @@ class BonusIconView:
|
|
|
193
180
|
break
|
|
194
181
|
name_label = f" ({weapon_name})" if weapon_name else ""
|
|
195
182
|
weapon_label = f"icon_id = -1 → ui_wicons (default weapon {weapon_id}{name_label})"
|
|
196
|
-
self.
|
|
183
|
+
draw_ui_text(self._small, weapon_label, info_x, info_y, scale=UI_TEXT_SCALE, color=UI_HINT_COLOR)
|
|
197
184
|
|
|
198
185
|
|
|
199
186
|
@register_view("bonuses", "Bonus icon preview")
|
crimson/views/camera_debug.py
CHANGED
|
@@ -11,10 +11,11 @@ import pyray as rl
|
|
|
11
11
|
from grim.assets import resolve_asset_path
|
|
12
12
|
from grim.config import ensure_crimson_cfg
|
|
13
13
|
from grim.terrain_render import GroundRenderer
|
|
14
|
-
from grim.fonts.small import SmallFontData,
|
|
14
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
15
15
|
from grim.view import View, ViewContext
|
|
16
16
|
|
|
17
17
|
from ..paths import default_runtime_dir
|
|
18
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
18
19
|
from .registry import register_view
|
|
19
20
|
|
|
20
21
|
|
|
@@ -58,24 +59,6 @@ class CameraDebugView:
|
|
|
58
59
|
self._log_path: Path | None = None
|
|
59
60
|
self._log_file = None
|
|
60
61
|
|
|
61
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
62
|
-
if self._small is not None:
|
|
63
|
-
return int(self._small.cell_size * scale)
|
|
64
|
-
return int(20 * scale)
|
|
65
|
-
|
|
66
|
-
def _draw_ui_text(
|
|
67
|
-
self,
|
|
68
|
-
text: str,
|
|
69
|
-
x: float,
|
|
70
|
-
y: float,
|
|
71
|
-
color: rl.Color,
|
|
72
|
-
scale: float = UI_TEXT_SCALE,
|
|
73
|
-
) -> None:
|
|
74
|
-
if self._small is not None:
|
|
75
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
76
|
-
else:
|
|
77
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
78
|
-
|
|
79
62
|
def _load_runtime_config(self) -> None:
|
|
80
63
|
runtime_dir = default_runtime_dir()
|
|
81
64
|
if not runtime_dir.is_dir():
|
|
@@ -276,7 +259,7 @@ class CameraDebugView:
|
|
|
276
259
|
rl.clear_background(clear_color)
|
|
277
260
|
|
|
278
261
|
if self._renderer is None:
|
|
279
|
-
self.
|
|
262
|
+
draw_ui_text(self._small, "Ground renderer not initialized.", 16, 16, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
280
263
|
return
|
|
281
264
|
|
|
282
265
|
cam_x, cam_y, scale_x, scale_y, screen_w, screen_h = self._world_params()
|
|
@@ -327,31 +310,35 @@ class CameraDebugView:
|
|
|
327
310
|
# HUD
|
|
328
311
|
x = 16.0
|
|
329
312
|
y = 16.0
|
|
330
|
-
line = self.
|
|
313
|
+
line = ui_line_height(self._small, scale=UI_TEXT_SCALE)
|
|
331
314
|
mode = "config" if self._use_config_screen else "window"
|
|
332
|
-
|
|
315
|
+
draw_ui_text(
|
|
316
|
+
self._small,
|
|
333
317
|
f"window={int(out_w)}x{int(rl.get_screen_height())} camera={int(screen_w)}x{int(screen_h)} ({mode})",
|
|
334
318
|
x,
|
|
335
319
|
y,
|
|
336
|
-
|
|
320
|
+
scale=UI_TEXT_SCALE,
|
|
321
|
+
color=UI_TEXT_COLOR,
|
|
337
322
|
)
|
|
338
323
|
y += line
|
|
339
|
-
|
|
324
|
+
draw_ui_text(
|
|
325
|
+
self._small,
|
|
340
326
|
f"config={int(self._config_screen_w)}x{int(self._config_screen_h)} "
|
|
341
327
|
f"scale={scale_x:.3f},{scale_y:.3f} tex={self._texture_scale:.2f}",
|
|
342
328
|
x,
|
|
343
329
|
y,
|
|
344
|
-
|
|
330
|
+
scale=UI_TEXT_SCALE,
|
|
331
|
+
color=UI_TEXT_COLOR,
|
|
345
332
|
)
|
|
346
333
|
y += line
|
|
347
|
-
self.
|
|
334
|
+
draw_ui_text(self._small, f"player={self._player_x:.1f},{self._player_y:.1f}", x, y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
348
335
|
y += line
|
|
349
|
-
self.
|
|
336
|
+
draw_ui_text(self._small, f"camera={cam_x:.1f},{cam_y:.1f}", x, y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
350
337
|
y += line
|
|
351
338
|
if self._log_path is not None:
|
|
352
|
-
self.
|
|
339
|
+
draw_ui_text(self._small, f"log: {self._log_path}", x, y, scale=0.9, color=UI_HINT_COLOR)
|
|
353
340
|
y += line
|
|
354
|
-
self.
|
|
341
|
+
draw_ui_text(self._small, "F1: toggle camera size (config/window)", x, y, scale=UI_TEXT_SCALE, color=UI_HINT_COLOR)
|
|
355
342
|
|
|
356
343
|
|
|
357
344
|
@register_view("camera-debug", "Camera debug")
|
crimson/views/camera_shake.py
CHANGED
|
@@ -6,7 +6,8 @@ import math
|
|
|
6
6
|
import pyray as rl
|
|
7
7
|
|
|
8
8
|
from grim.config import ensure_crimson_cfg
|
|
9
|
-
from grim.fonts.small import SmallFontData,
|
|
9
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
10
|
+
from grim.math import clamp
|
|
10
11
|
from grim.view import View, ViewContext
|
|
11
12
|
|
|
12
13
|
from ..bonuses import BonusId
|
|
@@ -14,6 +15,7 @@ from ..creatures.spawn import CreatureInit, CreatureTypeId
|
|
|
14
15
|
from ..game_world import GameWorld
|
|
15
16
|
from ..gameplay import PlayerInput, bonus_apply
|
|
16
17
|
from ..paths import default_runtime_dir
|
|
18
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
17
19
|
from .registry import register_view
|
|
18
20
|
|
|
19
21
|
|
|
@@ -25,14 +27,6 @@ UI_HINT_COLOR = rl.Color(140, 140, 140, 255)
|
|
|
25
27
|
UI_ERROR_COLOR = rl.Color(240, 80, 80, 255)
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
def _clamp(value: float, lo: float, hi: float) -> float:
|
|
29
|
-
if value < lo:
|
|
30
|
-
return lo
|
|
31
|
-
if value > hi:
|
|
32
|
-
return hi
|
|
33
|
-
return value
|
|
34
|
-
|
|
35
|
-
|
|
36
30
|
@dataclass(frozen=True, slots=True)
|
|
37
31
|
class _SpawnSpec:
|
|
38
32
|
r: float
|
|
@@ -70,29 +64,11 @@ class CameraShakeView:
|
|
|
70
64
|
self._reflex_boost_locked = False
|
|
71
65
|
self._reset_scene()
|
|
72
66
|
|
|
73
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
74
|
-
if self._small is not None:
|
|
75
|
-
return int(self._small.cell_size * scale)
|
|
76
|
-
return int(20 * scale)
|
|
77
|
-
|
|
78
|
-
def _draw_ui_text(
|
|
79
|
-
self,
|
|
80
|
-
text: str,
|
|
81
|
-
x: float,
|
|
82
|
-
y: float,
|
|
83
|
-
color: rl.Color,
|
|
84
|
-
scale: float = UI_TEXT_SCALE,
|
|
85
|
-
) -> None:
|
|
86
|
-
if self._small is not None:
|
|
87
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
88
|
-
else:
|
|
89
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
90
|
-
|
|
91
67
|
def _spawn_creature(self, *, world_x: float, world_y: float, type_id: CreatureTypeId, hp: float) -> None:
|
|
92
68
|
init = CreatureInit(
|
|
93
69
|
origin_template_id=0,
|
|
94
|
-
pos_x=
|
|
95
|
-
pos_y=
|
|
70
|
+
pos_x=clamp(world_x, 64.0, WORLD_SIZE - 64.0),
|
|
71
|
+
pos_y=clamp(world_y, 64.0, WORLD_SIZE - 64.0),
|
|
96
72
|
heading=math.pi,
|
|
97
73
|
phase_seed=0.0,
|
|
98
74
|
type_id=type_id,
|
|
@@ -205,7 +181,7 @@ class CameraShakeView:
|
|
|
205
181
|
|
|
206
182
|
if self._missing_assets:
|
|
207
183
|
message = "Missing assets: " + ", ".join(self._missing_assets)
|
|
208
|
-
self.
|
|
184
|
+
draw_ui_text(self._small, message, 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
209
185
|
|
|
210
186
|
state = self._world.state
|
|
211
187
|
cam_x, cam_y, _sx, _sy = self._world._world_params()
|
|
@@ -217,11 +193,11 @@ class CameraShakeView:
|
|
|
217
193
|
f"reflex_boost={state.bonuses.reflex_boost:.2f} creatures_alive={len(self._world.creatures.iter_active())}",
|
|
218
194
|
]
|
|
219
195
|
x = 24.0
|
|
220
|
-
y = 24.0 + float(self.
|
|
196
|
+
y = 24.0 + float(ui_line_height(self._small, scale=UI_TEXT_SCALE)) + 12.0
|
|
221
197
|
for idx, line in enumerate(lines):
|
|
222
198
|
color = UI_HINT_COLOR if idx == 0 else UI_TEXT_COLOR
|
|
223
|
-
self.
|
|
224
|
-
y += float(self.
|
|
199
|
+
draw_ui_text(self._small, line, x, y, scale=UI_TEXT_SCALE, color=color)
|
|
200
|
+
y += float(ui_line_height(self._small, scale=UI_TEXT_SCALE))
|
|
225
201
|
|
|
226
202
|
|
|
227
203
|
@register_view("camera-shake", "Camera shake")
|
|
@@ -9,11 +9,12 @@ from crimson.creatures.anim import creature_corpse_frame_for_type
|
|
|
9
9
|
from crimson.creatures.spawn import CreatureTypeId
|
|
10
10
|
from grim.assets import resolve_asset_path
|
|
11
11
|
from grim.config import ensure_crimson_cfg
|
|
12
|
-
from grim.fonts.small import SmallFontData,
|
|
12
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
13
13
|
from grim.terrain_render import GroundCorpseDecal, GroundRenderer, _maybe_alpha_test
|
|
14
14
|
from grim.view import View, ViewContext
|
|
15
15
|
|
|
16
16
|
from ..paths import default_runtime_dir
|
|
17
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
17
18
|
from .registry import register_view
|
|
18
19
|
|
|
19
20
|
|
|
@@ -61,17 +62,6 @@ class CorpseStampDebugView:
|
|
|
61
62
|
self._dump_requested = False
|
|
62
63
|
self._dump_index = 0
|
|
63
64
|
|
|
64
|
-
def _ui_line_height(self) -> int:
|
|
65
|
-
if self._small is not None:
|
|
66
|
-
return int(self._small.cell_size)
|
|
67
|
-
return 20
|
|
68
|
-
|
|
69
|
-
def _draw_ui_text(self, text: str, x: float, y: float, color: rl.Color) -> None:
|
|
70
|
-
if self._small is not None:
|
|
71
|
-
draw_small_text(self._small, text, x, y, 1.0, color)
|
|
72
|
-
else:
|
|
73
|
-
rl.draw_text(text, int(x), int(y), 20, color)
|
|
74
|
-
|
|
75
65
|
def _load_runtime_config(self) -> tuple[float, float | None, float | None]:
|
|
76
66
|
runtime_dir = default_runtime_dir()
|
|
77
67
|
if runtime_dir.is_dir():
|
|
@@ -266,12 +256,12 @@ class CorpseStampDebugView:
|
|
|
266
256
|
rl.clear_background(BG)
|
|
267
257
|
|
|
268
258
|
if self._missing_assets:
|
|
269
|
-
self.
|
|
259
|
+
draw_ui_text(self._small, "Missing assets: " + ", ".join(self._missing_assets), 24, 24, color=UI_ERROR)
|
|
270
260
|
return
|
|
271
261
|
|
|
272
262
|
ground = self._ground
|
|
273
263
|
if ground is None:
|
|
274
|
-
self.
|
|
264
|
+
draw_ui_text(self._small, "Ground renderer not initialized.", 24, 24, color=UI_ERROR)
|
|
275
265
|
return
|
|
276
266
|
|
|
277
267
|
if self._dump_requested:
|
|
@@ -287,25 +277,27 @@ class CorpseStampDebugView:
|
|
|
287
277
|
# UI
|
|
288
278
|
x = 24.0
|
|
289
279
|
y = 20.0
|
|
290
|
-
line = float(self.
|
|
280
|
+
line = float(ui_line_height(self._small))
|
|
291
281
|
step = _STEPS[self._step_index]
|
|
292
282
|
alpha_test = bool(getattr(ground, "alpha_test", True))
|
|
293
|
-
self.
|
|
283
|
+
draw_ui_text(self._small, "Corpse stamp debug (SPIDER)", x, y, color=UI_TEXT)
|
|
294
284
|
y += line
|
|
295
|
-
|
|
285
|
+
draw_ui_text(
|
|
286
|
+
self._small,
|
|
296
287
|
"N/Space: next step R: reset A: toggle alpha test Q/E: rotate P: screenshot D: dump RT",
|
|
297
288
|
x,
|
|
298
289
|
y,
|
|
299
|
-
UI_HINT,
|
|
290
|
+
color=UI_HINT,
|
|
300
291
|
)
|
|
301
292
|
y += line
|
|
302
|
-
self.
|
|
293
|
+
draw_ui_text(self._small, f"step {self._step_index + 1}/{len(_STEPS)}: {step.description}", x, y, color=UI_HINT)
|
|
303
294
|
y += line
|
|
304
|
-
|
|
295
|
+
draw_ui_text(
|
|
296
|
+
self._small,
|
|
305
297
|
f"alpha_test={'on' if alpha_test else 'off'} size={self._corpse_size:.1f} dump_index={self._dump_index}",
|
|
306
298
|
x,
|
|
307
299
|
y,
|
|
308
|
-
UI_HINT,
|
|
300
|
+
color=UI_HINT,
|
|
309
301
|
)
|
|
310
302
|
|
|
311
303
|
# Source preview (bodyset frame) in the corner for inspection.
|
crimson/views/decals_debug.py
CHANGED
|
@@ -16,11 +16,12 @@ from crimson.gameplay import GameplayState, PlayerState
|
|
|
16
16
|
from crimson.render.terrain_fx import FxQueueTextures, bake_fx_queues
|
|
17
17
|
from grim.assets import resolve_asset_path
|
|
18
18
|
from grim.config import ensure_crimson_cfg
|
|
19
|
-
from grim.fonts.small import SmallFontData,
|
|
19
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
20
20
|
from grim.terrain_render import GroundRenderer
|
|
21
21
|
from grim.view import View, ViewContext
|
|
22
22
|
|
|
23
23
|
from ..paths import default_runtime_dir
|
|
24
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
24
25
|
from .registry import register_view
|
|
25
26
|
|
|
26
27
|
|
|
@@ -113,17 +114,6 @@ class DecalsDebugView:
|
|
|
113
114
|
self._fx_queue = FxQueue()
|
|
114
115
|
self._fx_queue_rotated = FxQueueRotated()
|
|
115
116
|
|
|
116
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
117
|
-
if self._small is not None:
|
|
118
|
-
return int(self._small.cell_size * scale)
|
|
119
|
-
return int(20 * scale)
|
|
120
|
-
|
|
121
|
-
def _draw_ui_text(self, text: str, x: float, y: float, color: rl.Color, scale: float = UI_TEXT_SCALE) -> None:
|
|
122
|
-
if self._small is not None:
|
|
123
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
124
|
-
else:
|
|
125
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
126
|
-
|
|
127
117
|
def _write_stamp_log(self, payload: dict) -> None:
|
|
128
118
|
if self._stamp_log_file is None:
|
|
129
119
|
return
|
|
@@ -631,11 +621,18 @@ class DecalsDebugView:
|
|
|
631
621
|
rl.clear_background(BG_LIGHT if self._light_mode else BG_DARK)
|
|
632
622
|
|
|
633
623
|
if self._missing_assets:
|
|
634
|
-
|
|
624
|
+
draw_ui_text(
|
|
625
|
+
self._small,
|
|
626
|
+
"Missing assets: " + ", ".join(self._missing_assets),
|
|
627
|
+
24,
|
|
628
|
+
24,
|
|
629
|
+
scale=UI_TEXT_SCALE,
|
|
630
|
+
color=UI_ERROR_COLOR,
|
|
631
|
+
)
|
|
635
632
|
return
|
|
636
633
|
|
|
637
634
|
if self._ground is None:
|
|
638
|
-
self.
|
|
635
|
+
draw_ui_text(self._small, "Ground renderer not initialized.", 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
639
636
|
return
|
|
640
637
|
|
|
641
638
|
self._ground.draw(self._camera_x, self._camera_y)
|
|
@@ -697,28 +694,44 @@ class DecalsDebugView:
|
|
|
697
694
|
hint_color = UI_HINT_DARK if self._light_mode else UI_HINT_LIGHT
|
|
698
695
|
x = 16
|
|
699
696
|
y = 12
|
|
700
|
-
line = self.
|
|
701
|
-
self.
|
|
697
|
+
line = ui_line_height(self._small, scale=UI_TEXT_SCALE)
|
|
698
|
+
draw_ui_text(self._small, "Decals debug", x, y, scale=UI_TEXT_SCALE, color=text_color)
|
|
702
699
|
y += line
|
|
703
|
-
self.
|
|
700
|
+
draw_ui_text(self._small, "LMB: blood / damage enemy RMB: spawn enemy", x, y, scale=UI_TEXT_SCALE, color=hint_color)
|
|
704
701
|
y += line
|
|
705
|
-
|
|
702
|
+
draw_ui_text(
|
|
703
|
+
self._small,
|
|
706
704
|
"WASD: pan R: random seed T: random terrain G: toggle light grid C: clear L: stamp log",
|
|
707
705
|
x,
|
|
708
706
|
y,
|
|
709
|
-
|
|
707
|
+
scale=UI_TEXT_SCALE,
|
|
708
|
+
color=hint_color,
|
|
710
709
|
)
|
|
711
710
|
y += line
|
|
712
|
-
|
|
711
|
+
draw_ui_text(
|
|
712
|
+
self._small,
|
|
713
|
+
f"enemies={len([c for c in self._creatures.entries if c.active])}",
|
|
714
|
+
x,
|
|
715
|
+
y,
|
|
716
|
+
scale=UI_TEXT_SCALE,
|
|
717
|
+
color=hint_color,
|
|
718
|
+
)
|
|
713
719
|
y += line
|
|
714
720
|
if self._stamp_log_path is not None:
|
|
715
721
|
status = "on" if self._show_stamp_log else "off"
|
|
716
|
-
|
|
722
|
+
draw_ui_text(
|
|
723
|
+
self._small,
|
|
724
|
+
f"stamp log ({status}): {self._stamp_log_path}",
|
|
725
|
+
x,
|
|
726
|
+
y,
|
|
727
|
+
scale=UI_TEXT_SCALE,
|
|
728
|
+
color=hint_color,
|
|
729
|
+
)
|
|
717
730
|
y += line
|
|
718
731
|
if self._ground is not None and self._show_stamp_log:
|
|
719
732
|
stamp_log = self._ground.debug_stamp_log()
|
|
720
733
|
if stamp_log:
|
|
721
|
-
self.
|
|
734
|
+
draw_ui_text(self._small, "stamp order:", x, y, scale=UI_TEXT_SCALE, color=hint_color)
|
|
722
735
|
y += line
|
|
723
736
|
for event in stamp_log[-6:]:
|
|
724
737
|
kind = str(event.get("kind", "?"))
|
|
@@ -730,7 +743,7 @@ class DecalsDebugView:
|
|
|
730
743
|
msg = f"{kind} draws={event.get('draws')}"
|
|
731
744
|
else:
|
|
732
745
|
msg = kind
|
|
733
|
-
self.
|
|
746
|
+
draw_ui_text(self._small, msg, x, y, scale=UI_TEXT_SCALE, color=hint_color)
|
|
734
747
|
y += line
|
|
735
748
|
|
|
736
749
|
|
crimson/views/fonts.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import pyray as rl
|
|
4
|
+
from ._ui_helpers import draw_ui_text, ui_line_height
|
|
4
5
|
from .quest_title_overlay import (
|
|
5
6
|
draw_quest_title_overlay,
|
|
6
7
|
quest_title_base_scale,
|
|
@@ -41,24 +42,6 @@ class FontView:
|
|
|
41
42
|
self._grim_mono: GrimMonoFont | None = None
|
|
42
43
|
self._sample = DEFAULT_SAMPLE
|
|
43
44
|
|
|
44
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
45
|
-
if self._small is not None:
|
|
46
|
-
return int(self._small.cell_size * scale)
|
|
47
|
-
return int(20 * scale)
|
|
48
|
-
|
|
49
|
-
def _draw_ui_text(
|
|
50
|
-
self,
|
|
51
|
-
text: str,
|
|
52
|
-
x: float,
|
|
53
|
-
y: float,
|
|
54
|
-
color: rl.Color,
|
|
55
|
-
scale: float = UI_TEXT_SCALE,
|
|
56
|
-
) -> None:
|
|
57
|
-
if self._small is not None:
|
|
58
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
59
|
-
else:
|
|
60
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
61
|
-
|
|
62
45
|
def close(self) -> None:
|
|
63
46
|
if self._small is not None:
|
|
64
47
|
rl.unload_texture(self._small.texture)
|
|
@@ -83,20 +66,20 @@ class FontView:
|
|
|
83
66
|
rl.clear_background(rl.Color(12, 12, 14, 255))
|
|
84
67
|
if self._missing_assets:
|
|
85
68
|
message = "Missing assets: " + ", ".join(self._missing_assets)
|
|
86
|
-
self.
|
|
69
|
+
draw_ui_text(self._small, message, 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
87
70
|
return
|
|
88
71
|
y = 24
|
|
89
|
-
self.
|
|
90
|
-
y += self.
|
|
72
|
+
draw_ui_text(self._small, "Small font", 24, y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
73
|
+
y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 12
|
|
91
74
|
if self._small is not None:
|
|
92
75
|
draw_small_text(self._small, self._sample, 24, y, SMALL_SAMPLE_SCALE, rl.WHITE)
|
|
93
76
|
y += int(measure_small_text_height(self._small, self._sample, SMALL_SAMPLE_SCALE)) + 40
|
|
94
77
|
|
|
95
|
-
self.
|
|
96
|
-
y += self.
|
|
78
|
+
draw_ui_text(self._small, "Grim2D mono font", 24, y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
79
|
+
y += ui_line_height(self._small, scale=UI_TEXT_SCALE) + 12
|
|
97
80
|
if self._grim_mono is not None:
|
|
98
|
-
self.
|
|
99
|
-
y += self.
|
|
81
|
+
draw_ui_text(self._small, f"Filter: {GRIM_MONO_FILTER_NAME}", 24, y, scale=UI_TEXT_SCALE, color=UI_TEXT_COLOR)
|
|
82
|
+
y += ui_line_height(self._small, scale=0.9) + 6
|
|
100
83
|
mono_scale = quest_title_base_scale(rl.get_screen_width())
|
|
101
84
|
draw_grim_mono_text(self._grim_mono, self._sample, 24, y, mono_scale, rl.WHITE)
|
|
102
85
|
y += int(measure_grim_mono_text_height(self._grim_mono, self._sample, mono_scale)) + 20
|
crimson/views/ground.py
CHANGED
|
@@ -13,10 +13,11 @@ from grim.terrain_render import GroundRenderer
|
|
|
13
13
|
from ..paths import default_runtime_dir
|
|
14
14
|
from ..quests import all_quests
|
|
15
15
|
from ..quests.types import QuestDefinition
|
|
16
|
+
from ._ui_helpers import draw_ui_text
|
|
16
17
|
from .quest_title_overlay import draw_quest_title_overlay
|
|
17
18
|
from .registry import register_view
|
|
18
19
|
from grim.fonts.grim_mono import GrimMonoFont, load_grim_mono_font
|
|
19
|
-
from grim.fonts.small import SmallFontData,
|
|
20
|
+
from grim.fonts.small import SmallFontData, load_small_font
|
|
20
21
|
from grim.view import View, ViewContext
|
|
21
22
|
|
|
22
23
|
|
|
@@ -60,24 +61,6 @@ class GroundView:
|
|
|
60
61
|
self._fx_queue_rotated = FxQueueRotated()
|
|
61
62
|
self._fx_textures: FxQueueTextures | None = None
|
|
62
63
|
|
|
63
|
-
def _ui_line_height(self, scale: float = UI_TEXT_SCALE) -> int:
|
|
64
|
-
if self._small is not None:
|
|
65
|
-
return int(self._small.cell_size * scale)
|
|
66
|
-
return int(20 * scale)
|
|
67
|
-
|
|
68
|
-
def _draw_ui_text(
|
|
69
|
-
self,
|
|
70
|
-
text: str,
|
|
71
|
-
x: float,
|
|
72
|
-
y: float,
|
|
73
|
-
color: rl.Color,
|
|
74
|
-
scale: float = UI_TEXT_SCALE,
|
|
75
|
-
) -> None:
|
|
76
|
-
if self._small is not None:
|
|
77
|
-
draw_small_text(self._small, text, x, y, scale, color)
|
|
78
|
-
else:
|
|
79
|
-
rl.draw_text(text, int(x), int(y), int(20 * scale), color)
|
|
80
|
-
|
|
81
64
|
def open(self) -> None:
|
|
82
65
|
self._missing_assets.clear()
|
|
83
66
|
self._small = load_small_font(self._assets_root, self._missing_assets)
|
|
@@ -179,10 +162,10 @@ class GroundView:
|
|
|
179
162
|
rl.clear_background(rl.Color(12, 12, 14, 255))
|
|
180
163
|
if self._missing_assets:
|
|
181
164
|
message = "Missing assets: " + ", ".join(self._missing_assets)
|
|
182
|
-
self.
|
|
165
|
+
draw_ui_text(self._small, message, 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
183
166
|
return
|
|
184
167
|
if self._renderer is None:
|
|
185
|
-
self.
|
|
168
|
+
draw_ui_text(self._small, "Ground renderer not initialized.", 24, 24, scale=UI_TEXT_SCALE, color=UI_ERROR_COLOR)
|
|
186
169
|
return
|
|
187
170
|
self._renderer.draw(self._camera_x, self._camera_y)
|
|
188
171
|
self._draw_quest_title_overlay()
|