crimsonland 0.1.0.dev11__tar.gz → 0.1.0.dev12__tar.gz
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.
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/PKG-INFO +1 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/pyproject.toml +1 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/runtime.py +15 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/demo.py +47 -38
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/effects.py +46 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/boot.py +2 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/menu.py +6 -27
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/base.py +13 -3
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/controls.py +1 -3
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/mods.py +1 -3
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/options.py +35 -42
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/play_game.py +78 -70
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/stats.py +1 -3
- crimsonland-0.1.0.dev12/src/crimson/frontend/pause_menu.py +425 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/game.py +315 -446
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/gameplay.py +35 -6
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/base_gameplay_mode.py +3 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/quest_mode.py +45 -36
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/rush_mode.py +4 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/survival_mode.py +6 -2
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/tutorial_mode.py +6 -2
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/typo_mode.py +4 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/persistence/highscores.py +6 -2
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/render/world_renderer.py +1 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/sim/world_state.py +8 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/typo/spawns.py +3 -4
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/demo_trial_overlay.py +3 -3
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/game_over.py +18 -2
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/perk_menu.py +106 -14
- crimsonland-0.1.0.dev12/src/crimson/ui/quest_results.py +663 -0
- crimsonland-0.1.0.dev12/src/crimson/ui/shadow.py +39 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/particles.py +1 -1
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/weapons.py +110 -110
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/app.py +3 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/assets_fetch.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/atlas.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/audio_router.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/bonuses.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/camera.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/cli.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/ai.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/anim.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/damage.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/creatures/spawn.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/demo_trial.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/effects_atlas.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/assets.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/panels/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/frontend/transitions.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/game_modes.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/game_world.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/input_codes.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/modes/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/paths.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/perks.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/persistence/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/persistence/save_status.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/player_damage.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/projectiles.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/helpers.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/registry.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/results.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/runtime.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/tier1.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/tier2.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/tier3.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/tier4.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/tier5.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/timeline.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/quests/types.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/render/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/render/terrain_fx.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/sim/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/sim/world_defs.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/terrain_assets.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/tutorial/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/tutorial/timeline.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/typo/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/typo/names.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/typo/player.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/typo/typing.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/cursor.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/ui/hud.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/aim_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/animations.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/arsenal_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/audio_bootstrap.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/bonuses.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/camera_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/camera_shake.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/corpse_stamp_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/decals_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/empty.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/fonts.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/game_over.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/ground.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/lighting_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/perk_menu_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/perks.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/player.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/player_sprite_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/projectile_fx.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/projectile_render_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/projectiles.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/quest_title_overlay.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/registry.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/rush.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/small_font_debug.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/spawn_plan.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/sprites.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/survival.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/terrain.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/ui.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/views/wicons.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/crimson/weapon_sfx.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/assets.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/audio.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/config.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/console.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/fonts/__init__.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/fonts/grim_mono.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/fonts/small.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/input.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/jaz.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/math.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/music.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/paq.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/rand.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/sfx.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/sfx_map.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/terrain_render.py +0 -0
- {crimsonland-0.1.0.dev11 → crimsonland-0.1.0.dev12}/src/grim/view.py +0 -0
|
@@ -667,6 +667,21 @@ class CreaturePool:
|
|
|
667
667
|
elif perk_active(player, PerkId.VEINS_OF_POISON):
|
|
668
668
|
creature.flags |= CreatureFlags.SELF_DAMAGE_TICK
|
|
669
669
|
player_take_damage(state, player, float(creature.contact_damage), dt=dt, rand=rand)
|
|
670
|
+
if fx_queue is not None:
|
|
671
|
+
dx = float(player.pos_x) - float(creature.x)
|
|
672
|
+
dy = float(player.pos_y) - float(creature.y)
|
|
673
|
+
dist = math.hypot(dx, dy)
|
|
674
|
+
if dist > 1e-9:
|
|
675
|
+
dx /= dist
|
|
676
|
+
dy /= dist
|
|
677
|
+
else:
|
|
678
|
+
dx = 0.0
|
|
679
|
+
dy = 0.0
|
|
680
|
+
fx_queue.add_random(
|
|
681
|
+
pos_x=float(player.pos_x) + dx * 3.0,
|
|
682
|
+
pos_y=float(player.pos_y) + dy * 3.0,
|
|
683
|
+
rand=rand,
|
|
684
|
+
)
|
|
670
685
|
|
|
671
686
|
if (
|
|
672
687
|
bool(player.plaguebearer_active)
|
|
@@ -17,6 +17,7 @@ from grim.rand import Crand
|
|
|
17
17
|
from .game_world import GameWorld
|
|
18
18
|
from .gameplay import PlayerInput, PlayerState, weapon_assign_player
|
|
19
19
|
from .ui.cursor import draw_menu_cursor
|
|
20
|
+
from .ui.perk_menu import UiButtonState, UiButtonTextureSet, button_draw, button_update, button_width
|
|
20
21
|
from .weapons import WEAPON_TABLE, WeaponId, projectile_type_id_from_weapon_id, weapon_entry_for_projectile_type_id
|
|
21
22
|
|
|
22
23
|
WORLD_SIZE = 1024.0
|
|
@@ -123,6 +124,8 @@ class DemoView:
|
|
|
123
124
|
self._small_font: SmallFontData | None = None
|
|
124
125
|
self._purchase_active = False
|
|
125
126
|
self._purchase_url_opened = False
|
|
127
|
+
self._purchase_button = UiButtonState("Purchase", force_wide=True)
|
|
128
|
+
self._maybe_later_button = UiButtonState("Maybe later", force_wide=True)
|
|
126
129
|
self._spawn_rng = Crand(0)
|
|
127
130
|
|
|
128
131
|
def open(self) -> None:
|
|
@@ -131,6 +134,8 @@ class DemoView:
|
|
|
131
134
|
self._upsell_pulse_ms = 0
|
|
132
135
|
self._purchase_active = False
|
|
133
136
|
self._purchase_url_opened = False
|
|
137
|
+
self._purchase_button = UiButtonState("Purchase", force_wide=True)
|
|
138
|
+
self._maybe_later_button = UiButtonState("Maybe later", force_wide=True)
|
|
134
139
|
self._variant_index = 0
|
|
135
140
|
self._demo_variant_index = 0
|
|
136
141
|
self._quest_spawn_timeline_ms = 0
|
|
@@ -166,7 +171,7 @@ class DemoView:
|
|
|
166
171
|
|
|
167
172
|
if self._purchase_active:
|
|
168
173
|
self._upsell_pulse_ms += frame_dt_ms
|
|
169
|
-
self._update_purchase_screen()
|
|
174
|
+
self._update_purchase_screen(frame_dt_ms)
|
|
170
175
|
self._quest_spawn_timeline_ms += frame_dt_ms
|
|
171
176
|
if self._quest_spawn_timeline_ms > self._demo_time_limit_ms:
|
|
172
177
|
# demo_purchase_screen_update restarts the demo once the purchase screen
|
|
@@ -214,6 +219,8 @@ class DemoView:
|
|
|
214
219
|
self._quest_spawn_timeline_ms = 0
|
|
215
220
|
self._demo_time_limit_ms = max(0, int(limit_ms))
|
|
216
221
|
self._purchase_url_opened = False
|
|
222
|
+
self._purchase_button = UiButtonState("Purchase", force_wide=True)
|
|
223
|
+
self._maybe_later_button = UiButtonState("Maybe later", force_wide=True)
|
|
217
224
|
|
|
218
225
|
def _ensure_small_font(self) -> SmallFontData:
|
|
219
226
|
if self._small_font is not None:
|
|
@@ -230,18 +237,20 @@ class DemoView:
|
|
|
230
237
|
return 128.0
|
|
231
238
|
return 0.0
|
|
232
239
|
|
|
233
|
-
def _update_purchase_screen(self) -> None:
|
|
240
|
+
def _update_purchase_screen(self, dt_ms: int) -> None:
|
|
241
|
+
dt_ms = max(0, int(dt_ms))
|
|
234
242
|
if rl.is_key_pressed(rl.KeyboardKey.KEY_ESCAPE):
|
|
235
243
|
self._purchase_active = False
|
|
236
244
|
self._finished = True
|
|
237
245
|
return
|
|
238
246
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
247
|
+
font = self._ensure_small_font()
|
|
248
|
+
cache = self._ensure_cache()
|
|
249
|
+
textures = UiButtonTextureSet(
|
|
250
|
+
button_sm=cache.get_or_load("ui_buttonSm", "ui/ui_button_64x32.jaz").texture,
|
|
251
|
+
button_md=cache.get_or_load("ui_buttonMd", "ui/ui_button_128x32.jaz").texture,
|
|
252
|
+
)
|
|
253
|
+
if textures.button_sm is None and textures.button_md is None:
|
|
245
254
|
return
|
|
246
255
|
|
|
247
256
|
w = float(self._state.config.screen_width)
|
|
@@ -252,14 +261,18 @@ class DemoView:
|
|
|
252
261
|
purchase_y = button_base_y + 50.0
|
|
253
262
|
maybe_y = button_base_y + 90.0
|
|
254
263
|
|
|
255
|
-
purchase_rect = rl.Rectangle(button_x, purchase_y, float(button_tex.width), float(button_tex.height))
|
|
256
|
-
maybe_rect = rl.Rectangle(button_x, maybe_y, float(button_tex.width), float(button_tex.height))
|
|
257
|
-
|
|
258
264
|
mouse = rl.get_mouse_position()
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
265
|
+
click = rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT)
|
|
266
|
+
scale = 1.0
|
|
267
|
+
button_w = button_width(font, self._purchase_button.label, scale=scale, force_wide=self._purchase_button.force_wide)
|
|
268
|
+
if button_update(
|
|
269
|
+
self._purchase_button,
|
|
270
|
+
x=float(button_x),
|
|
271
|
+
y=float(purchase_y),
|
|
272
|
+
width=float(button_w),
|
|
273
|
+
dt_ms=float(dt_ms),
|
|
274
|
+
mouse=mouse,
|
|
275
|
+
click=bool(click),
|
|
263
276
|
):
|
|
264
277
|
if not self._purchase_url_opened:
|
|
265
278
|
self._purchase_url_opened = True
|
|
@@ -272,10 +285,14 @@ class DemoView:
|
|
|
272
285
|
if hasattr(self._state, "quit_requested"):
|
|
273
286
|
self._state.quit_requested = True
|
|
274
287
|
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
288
|
+
if button_update(
|
|
289
|
+
self._maybe_later_button,
|
|
290
|
+
x=float(button_x),
|
|
291
|
+
y=float(maybe_y),
|
|
292
|
+
width=float(button_w),
|
|
293
|
+
dt_ms=float(dt_ms),
|
|
294
|
+
mouse=mouse,
|
|
295
|
+
click=bool(click),
|
|
279
296
|
):
|
|
280
297
|
self._purchase_active = False
|
|
281
298
|
self._finished = True
|
|
@@ -294,8 +311,8 @@ class DemoView:
|
|
|
294
311
|
if hasattr(self._state, "quit_requested"):
|
|
295
312
|
self._state.quit_requested = True
|
|
296
313
|
|
|
297
|
-
# Keep
|
|
298
|
-
_ =
|
|
314
|
+
# Keep referenced to avoid unused warnings if this method grows.
|
|
315
|
+
_ = textures
|
|
299
316
|
|
|
300
317
|
def _draw_purchase_screen(self) -> None:
|
|
301
318
|
rl.clear_background(rl.BLACK)
|
|
@@ -393,29 +410,21 @@ class DemoView:
|
|
|
393
410
|
|
|
394
411
|
# Buttons on the right.
|
|
395
412
|
cache = self._ensure_cache()
|
|
396
|
-
|
|
397
|
-
|
|
413
|
+
textures = UiButtonTextureSet(
|
|
414
|
+
button_sm=cache.get_or_load("ui_buttonSm", "ui/ui_button_64x32.jaz").texture,
|
|
415
|
+
button_md=cache.get_or_load("ui_buttonMd", "ui/ui_button_128x32.jaz").texture,
|
|
416
|
+
)
|
|
417
|
+
if textures.button_sm is None and textures.button_md is None:
|
|
398
418
|
return
|
|
399
419
|
|
|
400
420
|
button_x = screen_w / 2.0 + 128.0
|
|
401
421
|
button_base_y = screen_h / 2.0 + 102.0 + wide_shift * 0.3
|
|
402
422
|
purchase_y = button_base_y + 50.0
|
|
403
423
|
maybe_y = button_base_y + 90.0
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
tint = rl.Color(255, 255, 255, 255) if hovered else rl.Color(220, 220, 220, 255)
|
|
409
|
-
rl.draw_texture(texture, int(x), int(y0), tint)
|
|
410
|
-
label_scale = 1.0
|
|
411
|
-
text_w = measure_small_text_width(small, label, label_scale)
|
|
412
|
-
text_x = x + float(texture.width) * 0.5 - text_w * 0.5 + 1.0
|
|
413
|
-
text_y = y0 + 10.0
|
|
414
|
-
alpha = 1.0 if hovered else 0.7
|
|
415
|
-
draw_small_text(small, label, text_x, text_y, label_scale, rl.Color(255, 255, 255, int(255 * alpha)))
|
|
416
|
-
|
|
417
|
-
draw_button(button_tex, "Purchase", button_x, purchase_y)
|
|
418
|
-
draw_button(button_tex, "Maybe later", button_x, maybe_y)
|
|
424
|
+
scale = 1.0
|
|
425
|
+
button_w = button_width(small, self._purchase_button.label, scale=scale, force_wide=self._purchase_button.force_wide)
|
|
426
|
+
button_draw(textures, small, self._purchase_button, x=button_x, y=purchase_y, width=button_w, scale=scale)
|
|
427
|
+
button_draw(textures, small, self._maybe_later_button, x=button_x, y=maybe_y, width=button_w, scale=scale)
|
|
419
428
|
|
|
420
429
|
# Demo purchase screen uses menu-style cursor; draw it explicitly since the OS cursor is hidden.
|
|
421
430
|
particles = cache.get_or_load("particles", "game/particles.jaz").texture
|
|
@@ -209,7 +209,7 @@ class ParticlePool:
|
|
|
209
209
|
|
|
210
210
|
size = float(getattr(creature, "size", 50.0))
|
|
211
211
|
dist = math.hypot(float(getattr(creature, "x", 0.0)) - pos_x, float(getattr(creature, "y", 0.0)) - pos_y) - radius
|
|
212
|
-
threshold = size * 0.
|
|
212
|
+
threshold = size * 0.14285715 + 3.0
|
|
213
213
|
if threshold < dist:
|
|
214
214
|
continue
|
|
215
215
|
return int(creature_idx)
|
|
@@ -721,6 +721,51 @@ class EffectPool:
|
|
|
721
721
|
|
|
722
722
|
self.free(idx)
|
|
723
723
|
|
|
724
|
+
def spawn_shell_casing(
|
|
725
|
+
self,
|
|
726
|
+
*,
|
|
727
|
+
pos_x: float,
|
|
728
|
+
pos_y: float,
|
|
729
|
+
aim_heading: float,
|
|
730
|
+
weapon_flags: int,
|
|
731
|
+
rand: Callable[[], int],
|
|
732
|
+
detail_preset: int,
|
|
733
|
+
) -> None:
|
|
734
|
+
"""Port of the casing spawn in `player_update` (effect_id 0x12)."""
|
|
735
|
+
|
|
736
|
+
if (int(weapon_flags) & 0x1) == 0:
|
|
737
|
+
return
|
|
738
|
+
|
|
739
|
+
angle = float(aim_heading) + float(int(rand()) & 0x3F) * 0.01
|
|
740
|
+
speed = float(int(rand()) & 0x3F) * 0.022727273 + 1.0
|
|
741
|
+
vel_x = math.cos(angle) * speed * 100.0
|
|
742
|
+
vel_y = math.sin(angle) * speed * 100.0
|
|
743
|
+
|
|
744
|
+
rotation = float((int(rand()) & 0x3F) - 0x20) * 0.1
|
|
745
|
+
rotation_step = (float(int(rand()) % 0x14) * 0.1 - 1.0) * 14.0
|
|
746
|
+
|
|
747
|
+
self.spawn(
|
|
748
|
+
effect_id=0x12,
|
|
749
|
+
pos_x=float(pos_x),
|
|
750
|
+
pos_y=float(pos_y),
|
|
751
|
+
vel_x=float(vel_x),
|
|
752
|
+
vel_y=float(vel_y),
|
|
753
|
+
rotation=float(rotation),
|
|
754
|
+
scale=1.0,
|
|
755
|
+
half_width=2.0,
|
|
756
|
+
half_height=2.0,
|
|
757
|
+
age=0.0,
|
|
758
|
+
lifetime=0.15,
|
|
759
|
+
flags=0x1C5,
|
|
760
|
+
color_r=1.0,
|
|
761
|
+
color_g=1.0,
|
|
762
|
+
color_b=1.0,
|
|
763
|
+
color_a=0.6,
|
|
764
|
+
rotation_step=float(rotation_step),
|
|
765
|
+
scale_step=0.0,
|
|
766
|
+
detail_preset=int(detail_preset),
|
|
767
|
+
)
|
|
768
|
+
|
|
724
769
|
def spawn_blood_splatter(
|
|
725
770
|
self,
|
|
726
771
|
*,
|
|
@@ -118,7 +118,8 @@ MENU_PREP_TEXTURES: tuple[tuple[str, str], ...] = (
|
|
|
118
118
|
("ui_checkOff", "ui/ui_checkOff.jaz"),
|
|
119
119
|
("ui_rectOff", "ui/ui_rectOff.jaz"),
|
|
120
120
|
("ui_rectOn", "ui/ui_rectOn.jaz"),
|
|
121
|
-
("
|
|
121
|
+
("ui_buttonSm", "ui/ui_button_64x32.jaz"),
|
|
122
|
+
("ui_buttonMd", "ui/ui_button_128x32.jaz"),
|
|
122
123
|
)
|
|
123
124
|
|
|
124
125
|
|
|
@@ -11,6 +11,7 @@ from grim.audio import play_music, play_sfx, stop_music, update_audio
|
|
|
11
11
|
from grim.terrain_render import GroundRenderer
|
|
12
12
|
|
|
13
13
|
from ..ui.cursor import draw_menu_cursor
|
|
14
|
+
from ..ui.shadow import UI_SHADOW_OFFSET, UI_SHADOW_TINT, draw_ui_quad_shadow # noqa: F401
|
|
14
15
|
from .assets import MenuAssets, _ensure_texture_cache, load_menu_assets
|
|
15
16
|
from .transitions import _draw_screen_fade
|
|
16
17
|
|
|
@@ -37,7 +38,10 @@ MENU_ITEM_OFFSET_X = -72.0
|
|
|
37
38
|
MENU_ITEM_OFFSET_Y = -60.0
|
|
38
39
|
MENU_PANEL_WIDTH = 512.0
|
|
39
40
|
MENU_PANEL_HEIGHT = 256.0
|
|
40
|
-
|
|
41
|
+
# ui_menu_assets_init:
|
|
42
|
+
# - ui_menuPanel starts with offset_x=+20 (ui_element_set_rect)
|
|
43
|
+
# - the menu-panel layout copy applies data_48fdb4 -= 116, so offset_x becomes -96
|
|
44
|
+
MENU_PANEL_OFFSET_X = -96.0
|
|
41
45
|
MENU_PANEL_OFFSET_Y = -82.0
|
|
42
46
|
MENU_PANEL_BASE_X = -45.0
|
|
43
47
|
MENU_PANEL_BASE_Y = 210.0
|
|
@@ -48,11 +52,6 @@ MENU_SCALE_SMALL = 0.8
|
|
|
48
52
|
MENU_SCALE_LARGE = 1.2
|
|
49
53
|
MENU_SCALE_SHIFT = 10.0
|
|
50
54
|
|
|
51
|
-
# ui_element_render (0x446c40): shadow pass uses offset (7, 7), tint 0x44444444, and
|
|
52
|
-
# blend factors (src=ZERO, dst=ONE_MINUS_SRC_ALPHA).
|
|
53
|
-
UI_SHADOW_OFFSET = 7.0
|
|
54
|
-
UI_SHADOW_TINT = rl.Color(0x44, 0x44, 0x44, 0x44)
|
|
55
|
-
|
|
56
55
|
MENU_SIGN_WIDTH = 573.44
|
|
57
56
|
MENU_SIGN_HEIGHT = 143.36
|
|
58
57
|
MENU_SIGN_OFFSET_X = -577.44
|
|
@@ -628,27 +627,7 @@ class MenuView:
|
|
|
628
627
|
origin: rl.Vector2,
|
|
629
628
|
rotation_deg: float,
|
|
630
629
|
) -> None:
|
|
631
|
-
|
|
632
|
-
# only apply them when switching the blend mode.
|
|
633
|
-
rl.rl_set_blend_factors_separate(
|
|
634
|
-
rl.RL_ZERO,
|
|
635
|
-
rl.RL_ONE_MINUS_SRC_ALPHA,
|
|
636
|
-
rl.RL_ZERO,
|
|
637
|
-
rl.RL_ONE,
|
|
638
|
-
rl.RL_FUNC_ADD,
|
|
639
|
-
rl.RL_FUNC_ADD,
|
|
640
|
-
)
|
|
641
|
-
rl.begin_blend_mode(rl.BLEND_CUSTOM_SEPARATE)
|
|
642
|
-
rl.rl_set_blend_factors_separate(
|
|
643
|
-
rl.RL_ZERO,
|
|
644
|
-
rl.RL_ONE_MINUS_SRC_ALPHA,
|
|
645
|
-
rl.RL_ZERO,
|
|
646
|
-
rl.RL_ONE,
|
|
647
|
-
rl.RL_FUNC_ADD,
|
|
648
|
-
rl.RL_FUNC_ADD,
|
|
649
|
-
)
|
|
650
|
-
rl.draw_texture_pro(texture, src, dst, origin, rotation_deg, UI_SHADOW_TINT)
|
|
651
|
-
rl.end_blend_mode()
|
|
630
|
+
draw_ui_quad_shadow(texture=texture, src=src, dst=dst, origin=origin, rotation_deg=rotation_deg)
|
|
652
631
|
|
|
653
632
|
def _draw_menu_sign(self) -> None:
|
|
654
633
|
assets = self._assets
|
|
@@ -163,9 +163,7 @@ class PanelMenuView:
|
|
|
163
163
|
entry.ready_timer_ms = min(0x100, entry.ready_timer_ms + dt_ms)
|
|
164
164
|
|
|
165
165
|
def draw(self) -> None:
|
|
166
|
-
|
|
167
|
-
if self._ground is not None:
|
|
168
|
-
self._ground.draw(0.0, 0.0)
|
|
166
|
+
self._draw_background()
|
|
169
167
|
_draw_screen_fade(self._state)
|
|
170
168
|
assets = self._assets
|
|
171
169
|
entry = self._entry
|
|
@@ -206,8 +204,20 @@ class PanelMenuView:
|
|
|
206
204
|
return _ensure_texture_cache(self._state)
|
|
207
205
|
|
|
208
206
|
def _init_ground(self) -> None:
|
|
207
|
+
if self._state.pause_background is not None:
|
|
208
|
+
self._ground = None
|
|
209
|
+
return
|
|
209
210
|
self._ground = ensure_menu_ground(self._state)
|
|
210
211
|
|
|
212
|
+
def _draw_background(self) -> None:
|
|
213
|
+
rl.clear_background(rl.BLACK)
|
|
214
|
+
pause_background = self._state.pause_background
|
|
215
|
+
if pause_background is not None:
|
|
216
|
+
pause_background.draw_pause_background()
|
|
217
|
+
return
|
|
218
|
+
if self._ground is not None:
|
|
219
|
+
self._ground.draw(0.0, 0.0)
|
|
220
|
+
|
|
211
221
|
def _draw_panel(self) -> None:
|
|
212
222
|
assets = self._assets
|
|
213
223
|
if assets is None or assets.panel is None:
|
|
@@ -32,9 +32,7 @@ class ControlsMenuView(PanelMenuView):
|
|
|
32
32
|
self._lines = self._build_lines()
|
|
33
33
|
|
|
34
34
|
def draw(self) -> None:
|
|
35
|
-
|
|
36
|
-
if self._ground is not None:
|
|
37
|
-
self._ground.draw(0.0, 0.0)
|
|
35
|
+
self._draw_background()
|
|
38
36
|
_draw_screen_fade(self._state)
|
|
39
37
|
assets = self._assets
|
|
40
38
|
entry = self._entry
|
|
@@ -32,9 +32,7 @@ class ModsMenuView(PanelMenuView):
|
|
|
32
32
|
self._lines = self._build_lines()
|
|
33
33
|
|
|
34
34
|
def draw(self) -> None:
|
|
35
|
-
|
|
36
|
-
if self._ground is not None:
|
|
37
|
-
self._ground.draw(0.0, 0.0)
|
|
35
|
+
self._draw_background()
|
|
38
36
|
_draw_screen_fade(self._state)
|
|
39
37
|
assets = self._assets
|
|
40
38
|
entry = self._entry
|
|
@@ -9,6 +9,7 @@ from grim.audio import set_music_volume, set_sfx_volume
|
|
|
9
9
|
from grim.config import apply_detail_preset
|
|
10
10
|
from grim.fonts.small import SmallFontData, draw_small_text, load_small_font, measure_small_text_width
|
|
11
11
|
|
|
12
|
+
from ...ui.perk_menu import UiButtonState, UiButtonTextureSet, button_draw, button_update, button_width
|
|
12
13
|
from ..menu import (
|
|
13
14
|
MENU_LABEL_ROW_HEIGHT,
|
|
14
15
|
MENU_LABEL_ROW_OPTIONS,
|
|
@@ -42,13 +43,15 @@ class OptionsMenuView(PanelMenuView):
|
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
def __init__(self, state: GameState) -> None:
|
|
45
|
-
super().__init__(state, title="Options")
|
|
46
|
+
super().__init__(state, title="Options", back_action="open_pause_menu")
|
|
46
47
|
self._small_font: SmallFontData | None = None
|
|
47
48
|
self._rect_on: rl.Texture2D | None = None
|
|
48
49
|
self._rect_off: rl.Texture2D | None = None
|
|
49
50
|
self._check_on: rl.Texture2D | None = None
|
|
50
51
|
self._check_off: rl.Texture2D | None = None
|
|
51
52
|
self._button_tex: rl.Texture2D | None = None
|
|
53
|
+
self._button_textures: UiButtonTextureSet | None = None
|
|
54
|
+
self._controls_button: UiButtonState = UiButtonState("Controls", force_wide=True)
|
|
52
55
|
self._slider_sfx = SliderState(10, 0, 10)
|
|
53
56
|
self._slider_music = SliderState(10, 0, 10)
|
|
54
57
|
self._slider_detail = SliderState(5, 1, 5)
|
|
@@ -64,7 +67,10 @@ class OptionsMenuView(PanelMenuView):
|
|
|
64
67
|
self._rect_off = cache.get_or_load("ui_rectOff", "ui/ui_rectOff.jaz").texture
|
|
65
68
|
self._check_on = cache.get_or_load("ui_checkOn", "ui/ui_checkOn.jaz").texture
|
|
66
69
|
self._check_off = cache.get_or_load("ui_checkOff", "ui/ui_checkOff.jaz").texture
|
|
67
|
-
self._button_tex = cache.get_or_load("
|
|
70
|
+
self._button_tex = cache.get_or_load("ui_buttonMd", "ui/ui_button_128x32.jaz").texture
|
|
71
|
+
button_sm = cache.get_or_load("ui_buttonSm", "ui/ui_button_64x32.jaz").texture
|
|
72
|
+
self._button_textures = UiButtonTextureSet(button_sm=button_sm, button_md=self._button_tex)
|
|
73
|
+
self._controls_button = UiButtonState("Controls", force_wide=True)
|
|
68
74
|
self._active_slider = None
|
|
69
75
|
self._dirty = False
|
|
70
76
|
self._sync_from_config()
|
|
@@ -118,13 +124,25 @@ class OptionsMenuView(PanelMenuView):
|
|
|
118
124
|
config.data["ui_info_texts"] = value
|
|
119
125
|
self._dirty = True
|
|
120
126
|
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
textures = self._button_textures
|
|
128
|
+
if textures is not None and textures.button_md is not None:
|
|
129
|
+
# `sub_4475d0`: controls button shares the slider column.
|
|
130
|
+
x = slider_x
|
|
131
|
+
y = base_y + 155.0 * scale
|
|
132
|
+
dt_ms = min(float(dt), 0.1) * 1000.0
|
|
133
|
+
mouse = rl.get_mouse_position()
|
|
134
|
+
click = rl.is_mouse_button_pressed(rl.MOUSE_BUTTON_LEFT)
|
|
135
|
+
width = button_width(
|
|
136
|
+
self._ensure_small_font(),
|
|
137
|
+
self._controls_button.label,
|
|
138
|
+
scale=scale,
|
|
139
|
+
force_wide=self._controls_button.force_wide,
|
|
140
|
+
)
|
|
141
|
+
if button_update(self._controls_button, x=x, y=y, width=width, dt_ms=dt_ms, mouse=mouse, click=click):
|
|
142
|
+
self._begin_close_transition("open_controls")
|
|
123
143
|
|
|
124
144
|
def draw(self) -> None:
|
|
125
|
-
|
|
126
|
-
if self._ground is not None:
|
|
127
|
-
self._ground.draw(0.0, 0.0)
|
|
145
|
+
self._draw_background()
|
|
128
146
|
_draw_screen_fade(self._state)
|
|
129
147
|
assets = self._assets
|
|
130
148
|
entry = self._entry
|
|
@@ -192,7 +210,8 @@ class OptionsMenuView(PanelMenuView):
|
|
|
192
210
|
panel_left = panel_x - origin_x
|
|
193
211
|
panel_top = panel_y - origin_y
|
|
194
212
|
base_x = panel_left + 212.0 * panel_scale
|
|
195
|
-
|
|
213
|
+
# `sub_4475d0`: title label is anchored at panel_top + 40.
|
|
214
|
+
base_y = panel_top + 40.0 * panel_scale
|
|
196
215
|
label_x = base_x + 8.0 * panel_scale
|
|
197
216
|
slider_x = label_x + 130.0 * panel_scale
|
|
198
217
|
return {
|
|
@@ -269,18 +288,6 @@ class OptionsMenuView(PanelMenuView):
|
|
|
269
288
|
return True
|
|
270
289
|
return False
|
|
271
290
|
|
|
272
|
-
def _update_controls_button(self, x: float, y: float, scale: float) -> bool:
|
|
273
|
-
tex = self._button_tex
|
|
274
|
-
if tex is None:
|
|
275
|
-
return False
|
|
276
|
-
w = float(tex.width) * scale
|
|
277
|
-
h = float(tex.height) * scale
|
|
278
|
-
mouse = rl.get_mouse_position()
|
|
279
|
-
hovered = x <= mouse.x <= x + w and y <= mouse.y <= y + h
|
|
280
|
-
if hovered and rl.is_mouse_button_pressed(rl.MOUSE_BUTTON_LEFT):
|
|
281
|
-
return True
|
|
282
|
-
return False
|
|
283
|
-
|
|
284
291
|
def _draw_options_contents(self) -> None:
|
|
285
292
|
assets = self._assets
|
|
286
293
|
if assets is None:
|
|
@@ -298,16 +305,17 @@ class OptionsMenuView(PanelMenuView):
|
|
|
298
305
|
text_color = rl.Color(255, 255, 255, int(255 * 0.8))
|
|
299
306
|
|
|
300
307
|
if labels_tex is not None:
|
|
308
|
+
title_w = 128.0
|
|
301
309
|
src = rl.Rectangle(
|
|
302
310
|
0.0,
|
|
303
311
|
float(MENU_LABEL_ROW_OPTIONS) * MENU_LABEL_ROW_HEIGHT,
|
|
304
|
-
|
|
312
|
+
title_w,
|
|
305
313
|
MENU_LABEL_ROW_HEIGHT,
|
|
306
314
|
)
|
|
307
315
|
dst = rl.Rectangle(
|
|
308
316
|
base_x,
|
|
309
317
|
base_y,
|
|
310
|
-
|
|
318
|
+
title_w * scale,
|
|
311
319
|
MENU_LABEL_ROW_HEIGHT * scale,
|
|
312
320
|
)
|
|
313
321
|
MenuView._draw_ui_quad(
|
|
@@ -363,27 +371,12 @@ class OptionsMenuView(PanelMenuView):
|
|
|
363
371
|
)
|
|
364
372
|
|
|
365
373
|
button = self._button_tex
|
|
366
|
-
|
|
367
|
-
|
|
374
|
+
textures = self._button_textures
|
|
375
|
+
if button is not None and textures is not None:
|
|
376
|
+
button_x = slider_x
|
|
368
377
|
button_y = base_y + 155.0 * scale
|
|
369
|
-
button_w =
|
|
370
|
-
|
|
371
|
-
mouse = rl.get_mouse_position()
|
|
372
|
-
hovered = button_x <= mouse.x <= button_x + button_w and button_y <= mouse.y <= button_y + button_h
|
|
373
|
-
alpha = 255 if hovered else 220
|
|
374
|
-
rl.draw_texture_pro(
|
|
375
|
-
button,
|
|
376
|
-
rl.Rectangle(0.0, 0.0, float(button.width), float(button.height)),
|
|
377
|
-
rl.Rectangle(button_x, button_y, button_w, button_h),
|
|
378
|
-
rl.Vector2(0.0, 0.0),
|
|
379
|
-
0.0,
|
|
380
|
-
rl.Color(255, 255, 255, alpha),
|
|
381
|
-
)
|
|
382
|
-
label = "Controls"
|
|
383
|
-
label_w = measure_small_text_width(font, label, text_scale)
|
|
384
|
-
text_x = button_x + (button_w - label_w) * 0.5
|
|
385
|
-
text_y = button_y + (button_h - font.cell_size * text_scale) * 0.5
|
|
386
|
-
draw_small_text(font, label, text_x, text_y, text_scale, rl.Color(20, 20, 20, 255))
|
|
378
|
+
button_w = button_width(font, self._controls_button.label, scale=scale, force_wide=self._controls_button.force_wide)
|
|
379
|
+
button_draw(textures, font, self._controls_button, x=button_x, y=button_y, width=button_w, scale=scale)
|
|
387
380
|
|
|
388
381
|
def _draw_slider(
|
|
389
382
|
self,
|