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.
Files changed (139) hide show
  1. crimson/__init__.py +24 -0
  2. crimson/assets_fetch.py +60 -0
  3. crimson/atlas.py +92 -0
  4. crimson/audio_router.py +155 -0
  5. crimson/bonuses.py +167 -0
  6. crimson/camera.py +75 -0
  7. crimson/cli.py +380 -0
  8. crimson/creatures/__init__.py +8 -0
  9. crimson/creatures/ai.py +186 -0
  10. crimson/creatures/anim.py +173 -0
  11. crimson/creatures/damage.py +103 -0
  12. crimson/creatures/runtime.py +1019 -0
  13. crimson/creatures/spawn.py +2871 -0
  14. crimson/debug.py +7 -0
  15. crimson/demo.py +1360 -0
  16. crimson/demo_trial.py +140 -0
  17. crimson/effects.py +1086 -0
  18. crimson/effects_atlas.py +73 -0
  19. crimson/frontend/__init__.py +1 -0
  20. crimson/frontend/assets.py +43 -0
  21. crimson/frontend/boot.py +424 -0
  22. crimson/frontend/menu.py +700 -0
  23. crimson/frontend/panels/__init__.py +1 -0
  24. crimson/frontend/panels/base.py +410 -0
  25. crimson/frontend/panels/controls.py +132 -0
  26. crimson/frontend/panels/mods.py +128 -0
  27. crimson/frontend/panels/options.py +409 -0
  28. crimson/frontend/panels/play_game.py +627 -0
  29. crimson/frontend/panels/stats.py +351 -0
  30. crimson/frontend/transitions.py +31 -0
  31. crimson/game.py +2533 -0
  32. crimson/game_modes.py +15 -0
  33. crimson/game_world.py +652 -0
  34. crimson/gameplay.py +2467 -0
  35. crimson/input_codes.py +176 -0
  36. crimson/modes/__init__.py +1 -0
  37. crimson/modes/base_gameplay_mode.py +219 -0
  38. crimson/modes/quest_mode.py +502 -0
  39. crimson/modes/rush_mode.py +300 -0
  40. crimson/modes/survival_mode.py +792 -0
  41. crimson/modes/tutorial_mode.py +648 -0
  42. crimson/modes/typo_mode.py +472 -0
  43. crimson/paths.py +23 -0
  44. crimson/perks.py +828 -0
  45. crimson/persistence/__init__.py +1 -0
  46. crimson/persistence/highscores.py +385 -0
  47. crimson/persistence/save_status.py +245 -0
  48. crimson/player_damage.py +77 -0
  49. crimson/projectiles.py +1133 -0
  50. crimson/quests/__init__.py +18 -0
  51. crimson/quests/helpers.py +147 -0
  52. crimson/quests/registry.py +49 -0
  53. crimson/quests/results.py +164 -0
  54. crimson/quests/runtime.py +91 -0
  55. crimson/quests/tier1.py +620 -0
  56. crimson/quests/tier2.py +652 -0
  57. crimson/quests/tier3.py +579 -0
  58. crimson/quests/tier4.py +721 -0
  59. crimson/quests/tier5.py +886 -0
  60. crimson/quests/timeline.py +115 -0
  61. crimson/quests/types.py +70 -0
  62. crimson/render/__init__.py +1 -0
  63. crimson/render/terrain_fx.py +88 -0
  64. crimson/render/world_renderer.py +1941 -0
  65. crimson/sim/__init__.py +1 -0
  66. crimson/sim/world_defs.py +67 -0
  67. crimson/sim/world_state.py +422 -0
  68. crimson/terrain_assets.py +19 -0
  69. crimson/tutorial/__init__.py +12 -0
  70. crimson/tutorial/timeline.py +291 -0
  71. crimson/typo/__init__.py +2 -0
  72. crimson/typo/names.py +233 -0
  73. crimson/typo/player.py +43 -0
  74. crimson/typo/spawns.py +73 -0
  75. crimson/typo/typing.py +52 -0
  76. crimson/ui/__init__.py +3 -0
  77. crimson/ui/cursor.py +95 -0
  78. crimson/ui/demo_trial_overlay.py +235 -0
  79. crimson/ui/game_over.py +660 -0
  80. crimson/ui/hud.py +601 -0
  81. crimson/ui/perk_menu.py +388 -0
  82. crimson/views/__init__.py +40 -0
  83. crimson/views/aim_debug.py +276 -0
  84. crimson/views/animations.py +274 -0
  85. crimson/views/arsenal_debug.py +404 -0
  86. crimson/views/audio_bootstrap.py +47 -0
  87. crimson/views/bonuses.py +201 -0
  88. crimson/views/camera_debug.py +359 -0
  89. crimson/views/camera_shake.py +229 -0
  90. crimson/views/corpse_stamp_debug.py +324 -0
  91. crimson/views/decals_debug.py +739 -0
  92. crimson/views/empty.py +19 -0
  93. crimson/views/fonts.py +114 -0
  94. crimson/views/game_over.py +117 -0
  95. crimson/views/ground.py +259 -0
  96. crimson/views/lighting_debug.py +1166 -0
  97. crimson/views/particles.py +293 -0
  98. crimson/views/perk_menu_debug.py +430 -0
  99. crimson/views/perks.py +398 -0
  100. crimson/views/player.py +434 -0
  101. crimson/views/player_sprite_debug.py +314 -0
  102. crimson/views/projectile_fx.py +609 -0
  103. crimson/views/projectile_render_debug.py +393 -0
  104. crimson/views/projectiles.py +221 -0
  105. crimson/views/quest_title_overlay.py +108 -0
  106. crimson/views/registry.py +34 -0
  107. crimson/views/rush.py +16 -0
  108. crimson/views/small_font_debug.py +204 -0
  109. crimson/views/spawn_plan.py +363 -0
  110. crimson/views/sprites.py +214 -0
  111. crimson/views/survival.py +15 -0
  112. crimson/views/terrain.py +132 -0
  113. crimson/views/ui.py +123 -0
  114. crimson/views/wicons.py +166 -0
  115. crimson/weapon_sfx.py +63 -0
  116. crimson/weapons.py +860 -0
  117. crimsonland-0.1.0.dev5.dist-info/METADATA +9 -0
  118. crimsonland-0.1.0.dev5.dist-info/RECORD +139 -0
  119. crimsonland-0.1.0.dev5.dist-info/WHEEL +4 -0
  120. crimsonland-0.1.0.dev5.dist-info/entry_points.txt +4 -0
  121. grim/__init__.py +20 -0
  122. grim/app.py +92 -0
  123. grim/assets.py +231 -0
  124. grim/audio.py +106 -0
  125. grim/config.py +294 -0
  126. grim/console.py +737 -0
  127. grim/fonts/__init__.py +7 -0
  128. grim/fonts/grim_mono.py +111 -0
  129. grim/fonts/small.py +120 -0
  130. grim/input.py +44 -0
  131. grim/jaz.py +103 -0
  132. grim/math.py +17 -0
  133. grim/music.py +403 -0
  134. grim/paq.py +76 -0
  135. grim/rand.py +37 -0
  136. grim/sfx.py +276 -0
  137. grim/sfx_map.py +103 -0
  138. grim/terrain_render.py +840 -0
  139. grim/view.py +16 -0
crimson/demo_trial.py ADDED
@@ -0,0 +1,140 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ DEMO_TOTAL_PLAY_TIME_MS = 2_400_000
6
+ DEMO_QUEST_GRACE_TIME_MS = 300_000
7
+
8
+
9
+ def format_demo_trial_time(ms: int) -> str:
10
+ value = int(ms)
11
+ if value < 0:
12
+ value = 0
13
+ minutes = value // 60_000
14
+ seconds = (value // 1_000) % 60
15
+ centiseconds = (value % 1_000) // 10
16
+ return f"{minutes}:{seconds:02d}.{centiseconds:02d}"
17
+
18
+
19
+ @dataclass(frozen=True, slots=True)
20
+ class DemoTrialOverlayInfo:
21
+ visible: bool
22
+ kind: str # "none" | "quest_tier_limit" | "quest_grace_left" | "time_up"
23
+ remaining_ms: int
24
+ remaining_label: str
25
+
26
+
27
+ def tick_demo_trial_timers(
28
+ *,
29
+ demo_build: bool,
30
+ game_mode_id: int,
31
+ overlay_visible: bool,
32
+ global_playtime_ms: int,
33
+ quest_grace_elapsed_ms: int,
34
+ dt_ms: int,
35
+ ) -> tuple[int, int]:
36
+ """Advance demo timers by `dt_ms` (ms), returning updated values.
37
+
38
+ This mirrors the classic behavior where:
39
+ - global playtime accumulates until it hits `DEMO_TOTAL_PLAY_TIME_MS`, then clamps
40
+ - once global time is exhausted, a quest-only grace timer becomes active
41
+ - timers do not advance while the demo trial overlay is shown
42
+ """
43
+
44
+ if not demo_build:
45
+ return int(global_playtime_ms), int(quest_grace_elapsed_ms)
46
+
47
+ if int(game_mode_id) == 8:
48
+ return int(global_playtime_ms), int(quest_grace_elapsed_ms)
49
+
50
+ used_ms = max(0, int(global_playtime_ms))
51
+ grace_ms = max(0, int(quest_grace_elapsed_ms))
52
+ if used_ms >= DEMO_TOTAL_PLAY_TIME_MS and grace_ms < 1:
53
+ grace_ms = 1
54
+ used_ms = min(DEMO_TOTAL_PLAY_TIME_MS, used_ms)
55
+
56
+ if overlay_visible:
57
+ return int(used_ms), int(grace_ms)
58
+
59
+ delta_ms = int(dt_ms)
60
+ if delta_ms <= 0:
61
+ return int(used_ms), int(grace_ms)
62
+
63
+ used_ms = min(DEMO_TOTAL_PLAY_TIME_MS, used_ms + delta_ms)
64
+ if used_ms >= DEMO_TOTAL_PLAY_TIME_MS and grace_ms < 1:
65
+ grace_ms = 1
66
+
67
+ if grace_ms > 0 and int(game_mode_id) == 3:
68
+ grace_ms += delta_ms
69
+
70
+ return int(used_ms), int(grace_ms)
71
+
72
+
73
+ def demo_trial_overlay_info(
74
+ *,
75
+ demo_build: bool,
76
+ game_mode_id: int,
77
+ global_playtime_ms: int,
78
+ quest_grace_elapsed_ms: int,
79
+ quest_stage_major: int,
80
+ quest_stage_minor: int,
81
+ ) -> DemoTrialOverlayInfo:
82
+ """Compute demo trial overlay status.
83
+
84
+ Modeled after `demo_trial_overlay_render` (0x004047c0) call sites and time formatting.
85
+
86
+ Notes:
87
+ - `global_playtime_ms` maps to `game_status_blob.game_sequence_id` (ms).
88
+ - `quest_grace_elapsed_ms` maps to `demo_trial_elapsed_ms` (ms) once activated.
89
+ """
90
+
91
+ if not demo_build:
92
+ return DemoTrialOverlayInfo(False, "none", 0, format_demo_trial_time(0))
93
+
94
+ mode_id = int(game_mode_id)
95
+ if mode_id == 8: # tutorial
96
+ return DemoTrialOverlayInfo(False, "none", 0, format_demo_trial_time(0))
97
+
98
+ used_ms = max(0, int(global_playtime_ms))
99
+ grace_ms = max(0, int(quest_grace_elapsed_ms))
100
+
101
+ global_remaining_ms = max(0, DEMO_TOTAL_PLAY_TIME_MS - used_ms)
102
+ grace_remaining_ms = max(0, DEMO_QUEST_GRACE_TIME_MS - grace_ms)
103
+
104
+ tier_locked = mode_id == 3 and (int(quest_stage_major) > 1 or int(quest_stage_minor) > 10)
105
+
106
+ if grace_ms > 0:
107
+ if grace_remaining_ms <= 0:
108
+ return DemoTrialOverlayInfo(True, "time_up", 0, format_demo_trial_time(0))
109
+ if tier_locked:
110
+ return DemoTrialOverlayInfo(
111
+ True,
112
+ "quest_tier_limit",
113
+ int(grace_remaining_ms),
114
+ format_demo_trial_time(grace_remaining_ms),
115
+ )
116
+ # During the quest-only grace period, the classic demo blocks other modes
117
+ # and points the player back to Quests.
118
+ if mode_id != 3:
119
+ return DemoTrialOverlayInfo(
120
+ True,
121
+ "quest_grace_left",
122
+ int(grace_remaining_ms),
123
+ format_demo_trial_time(grace_remaining_ms),
124
+ )
125
+ return DemoTrialOverlayInfo(False, "none", int(grace_remaining_ms), format_demo_trial_time(grace_remaining_ms))
126
+
127
+ if global_remaining_ms <= 0:
128
+ return DemoTrialOverlayInfo(True, "time_up", 0, format_demo_trial_time(0))
129
+
130
+ # Demo tier gating: the classic demo lets you play stage 1 quests only; once
131
+ # the player reaches stage > 1, it shows the upsell overlay even if time remains.
132
+ if tier_locked:
133
+ return DemoTrialOverlayInfo(
134
+ True,
135
+ "quest_tier_limit",
136
+ int(global_remaining_ms),
137
+ format_demo_trial_time(global_remaining_ms),
138
+ )
139
+
140
+ return DemoTrialOverlayInfo(False, "none", int(global_remaining_ms), format_demo_trial_time(global_remaining_ms))