crimsonland 0.1.0.dev2__tar.gz → 0.1.0.dev4__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.dev2 → crimsonland-0.1.0.dev4}/PKG-INFO +1 -1
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/pyproject.toml +1 -1
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/audio_router.py +3 -1
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/projectiles.py +1 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/render/world_renderer.py +368 -31
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/sim/world_defs.py +16 -5
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/assets_fetch.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/atlas.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/bonuses.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/camera.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/cli.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/ai.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/anim.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/damage.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/runtime.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/creatures/spawn.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/demo.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/demo_trial.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/effects.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/effects_atlas.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/assets.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/boot.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/menu.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/base.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/controls.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/mods.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/options.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/play_game.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/panels/stats.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/frontend/transitions.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/game.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/game_modes.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/game_world.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/gameplay.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/input_codes.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/base_gameplay_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/quest_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/rush_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/survival_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/tutorial_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/modes/typo_mode.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/paths.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/perks.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/persistence/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/persistence/highscores.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/persistence/save_status.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/player_damage.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/helpers.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/registry.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/results.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/runtime.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/tier1.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/tier2.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/tier3.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/tier4.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/tier5.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/timeline.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/quests/types.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/render/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/render/terrain_fx.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/sim/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/sim/world_state.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/terrain_assets.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/tutorial/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/tutorial/timeline.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/typo/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/typo/names.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/typo/player.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/typo/spawns.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/typo/typing.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/cursor.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/demo_trial_overlay.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/game_over.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/hud.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/ui/perk_menu.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/aim_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/animations.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/arsenal_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/audio_bootstrap.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/bonuses.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/camera_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/camera_shake.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/corpse_stamp_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/decals_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/empty.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/fonts.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/game_over.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/ground.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/lighting_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/particles.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/perk_menu_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/perks.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/player.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/player_sprite_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/projectile_fx.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/projectile_render_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/projectiles.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/quest_title_overlay.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/registry.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/rush.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/small_font_debug.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/spawn_plan.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/sprites.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/survival.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/terrain.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/ui.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/wicons.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/weapon_sfx.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/weapons.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/app.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/assets.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/audio.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/config.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/console.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/fonts/__init__.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/fonts/grim_mono.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/fonts/small.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/input.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/jaz.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/math.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/music.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/paq.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/rand.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/sfx.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/sfx_map.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/terrain_render.py +0 -0
- {crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/grim/view.py +0 -0
|
@@ -111,7 +111,9 @@ class AudioRouter:
|
|
|
111
111
|
beam_types: frozenset[int],
|
|
112
112
|
rand: Callable[[], int],
|
|
113
113
|
) -> str | None:
|
|
114
|
-
|
|
114
|
+
weapon = WEAPON_BY_ID.get(int(type_id))
|
|
115
|
+
ammo_class = weapon.ammo_class if weapon is not None else None
|
|
116
|
+
if ammo_class == 4:
|
|
115
117
|
return "sfx_shock_hit_01"
|
|
116
118
|
return self._rand_choice(rand, _BULLET_HIT_SFX)
|
|
117
119
|
|
|
@@ -17,7 +17,14 @@ from ..effects_atlas import EFFECT_ID_ATLAS_TABLE_BY_ID, SIZE_CODE_GRID
|
|
|
17
17
|
from ..gameplay import bonus_find_aim_hover_entry, perk_active
|
|
18
18
|
from ..perks import PerkId
|
|
19
19
|
from ..projectiles import ProjectileTypeId
|
|
20
|
-
from ..sim.world_defs import
|
|
20
|
+
from ..sim.world_defs import (
|
|
21
|
+
BEAM_TYPES,
|
|
22
|
+
CREATURE_ANIM,
|
|
23
|
+
CREATURE_ASSET,
|
|
24
|
+
ION_TYPES,
|
|
25
|
+
KNOWN_PROJ_FRAMES,
|
|
26
|
+
PLASMA_PARTICLE_TYPES,
|
|
27
|
+
)
|
|
21
28
|
from ..weapons import WEAPON_BY_ID
|
|
22
29
|
|
|
23
30
|
if TYPE_CHECKING:
|
|
@@ -683,6 +690,366 @@ class WorldRenderer:
|
|
|
683
690
|
if drawn:
|
|
684
691
|
return
|
|
685
692
|
|
|
693
|
+
if type_id in PLASMA_PARTICLE_TYPES and self.particles_texture is not None:
|
|
694
|
+
particles_texture = self.particles_texture
|
|
695
|
+
atlas = EFFECT_ID_ATLAS_TABLE_BY_ID.get(0x0D)
|
|
696
|
+
if atlas is not None:
|
|
697
|
+
grid = SIZE_CODE_GRID.get(int(atlas.size_code))
|
|
698
|
+
if grid:
|
|
699
|
+
cell_w = float(particles_texture.width) / float(grid)
|
|
700
|
+
cell_h = float(particles_texture.height) / float(grid)
|
|
701
|
+
frame = int(atlas.frame)
|
|
702
|
+
col = frame % grid
|
|
703
|
+
row = frame // grid
|
|
704
|
+
src = rl.Rectangle(
|
|
705
|
+
cell_w * float(col),
|
|
706
|
+
cell_h * float(row),
|
|
707
|
+
max(0.0, cell_w - 2.0),
|
|
708
|
+
max(0.0, cell_h - 2.0),
|
|
709
|
+
)
|
|
710
|
+
|
|
711
|
+
speed_scale = float(getattr(proj, "speed_scale", 1.0))
|
|
712
|
+
fx_detail_1 = bool(self.config.data.get("fx_detail_1", 0)) if self.config is not None else True
|
|
713
|
+
|
|
714
|
+
rgb = (1.0, 1.0, 1.0)
|
|
715
|
+
spacing = 2.1
|
|
716
|
+
seg_limit = 3
|
|
717
|
+
tail_size = 12.0
|
|
718
|
+
head_size = 16.0
|
|
719
|
+
head_alpha_mul = 0.45
|
|
720
|
+
aura_rgb = rgb
|
|
721
|
+
aura_size = 120.0
|
|
722
|
+
aura_alpha_mul = 0.15
|
|
723
|
+
|
|
724
|
+
if type_id == int(ProjectileTypeId.PLASMA_RIFLE):
|
|
725
|
+
spacing = 2.5
|
|
726
|
+
seg_limit = 8
|
|
727
|
+
tail_size = 22.0
|
|
728
|
+
head_size = 56.0
|
|
729
|
+
aura_size = 256.0
|
|
730
|
+
aura_alpha_mul = 0.3
|
|
731
|
+
elif type_id == int(ProjectileTypeId.PLASMA_MINIGUN):
|
|
732
|
+
spacing = 2.1
|
|
733
|
+
seg_limit = 3
|
|
734
|
+
tail_size = 12.0
|
|
735
|
+
head_size = 16.0
|
|
736
|
+
aura_size = 120.0
|
|
737
|
+
aura_alpha_mul = 0.15
|
|
738
|
+
elif type_id == int(ProjectileTypeId.PLASMA_CANNON):
|
|
739
|
+
spacing = 2.6
|
|
740
|
+
seg_limit = 18
|
|
741
|
+
tail_size = 44.0
|
|
742
|
+
head_size = 84.0
|
|
743
|
+
aura_size = 256.0
|
|
744
|
+
# In the decompile, cannon reuses the tail alpha for the aura (0.4).
|
|
745
|
+
aura_alpha_mul = 0.4
|
|
746
|
+
elif type_id == int(ProjectileTypeId.SPIDER_PLASMA):
|
|
747
|
+
rgb = (0.3, 1.0, 0.3)
|
|
748
|
+
aura_rgb = rgb
|
|
749
|
+
elif type_id == int(ProjectileTypeId.SHRINKIFIER):
|
|
750
|
+
rgb = (0.3, 0.3, 1.0)
|
|
751
|
+
aura_rgb = rgb
|
|
752
|
+
|
|
753
|
+
if life >= 0.4:
|
|
754
|
+
# Reconstruct the tail length heuristic used by the native render path.
|
|
755
|
+
seg_count = int(float(getattr(proj, "base_damage", 0.0)))
|
|
756
|
+
if seg_count < 0:
|
|
757
|
+
seg_count = 0
|
|
758
|
+
seg_count //= 5
|
|
759
|
+
if seg_count > seg_limit:
|
|
760
|
+
seg_count = seg_limit
|
|
761
|
+
|
|
762
|
+
# The stored projectile angle is rotated by +pi/2 vs travel direction.
|
|
763
|
+
dir_x = math.cos(angle + math.pi / 2.0) * speed_scale
|
|
764
|
+
dir_y = math.sin(angle + math.pi / 2.0) * speed_scale
|
|
765
|
+
|
|
766
|
+
tail_tint = self._color_from_rgba((rgb[0], rgb[1], rgb[2], alpha * 0.4))
|
|
767
|
+
head_tint = self._color_from_rgba((rgb[0], rgb[1], rgb[2], alpha * head_alpha_mul))
|
|
768
|
+
aura_tint = self._color_from_rgba((aura_rgb[0], aura_rgb[1], aura_rgb[2], alpha * aura_alpha_mul))
|
|
769
|
+
|
|
770
|
+
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
771
|
+
|
|
772
|
+
if seg_count > 0:
|
|
773
|
+
size = tail_size * scale
|
|
774
|
+
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
775
|
+
step_x = dir_x * spacing
|
|
776
|
+
step_y = dir_y * spacing
|
|
777
|
+
for idx in range(seg_count):
|
|
778
|
+
px = pos_x + float(idx) * step_x
|
|
779
|
+
py = pos_y + float(idx) * step_y
|
|
780
|
+
psx, psy = self.world_to_screen(px, py)
|
|
781
|
+
dst = rl.Rectangle(float(psx), float(psy), float(size), float(size))
|
|
782
|
+
rl.draw_texture_pro(particles_texture, src, dst, origin, 0.0, tail_tint)
|
|
783
|
+
|
|
784
|
+
size = head_size * scale
|
|
785
|
+
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
786
|
+
dst = rl.Rectangle(float(sx), float(sy), float(size), float(size))
|
|
787
|
+
rl.draw_texture_pro(particles_texture, src, dst, origin, 0.0, head_tint)
|
|
788
|
+
|
|
789
|
+
if fx_detail_1:
|
|
790
|
+
size = aura_size * scale
|
|
791
|
+
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
792
|
+
dst = rl.Rectangle(float(sx), float(sy), float(size), float(size))
|
|
793
|
+
rl.draw_texture_pro(particles_texture, src, dst, origin, 0.0, aura_tint)
|
|
794
|
+
|
|
795
|
+
rl.end_blend_mode()
|
|
796
|
+
return
|
|
797
|
+
|
|
798
|
+
fade = clamp(life * 2.5, 0.0, 1.0)
|
|
799
|
+
fade_alpha = fade * alpha
|
|
800
|
+
if fade_alpha > 1e-3:
|
|
801
|
+
tint = self._color_from_rgba((1.0, 1.0, 1.0, fade_alpha))
|
|
802
|
+
size = 56.0 * scale
|
|
803
|
+
dst = rl.Rectangle(float(sx), float(sy), float(size), float(size))
|
|
804
|
+
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
805
|
+
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
806
|
+
rl.draw_texture_pro(particles_texture, src, dst, origin, 0.0, tint)
|
|
807
|
+
rl.end_blend_mode()
|
|
808
|
+
return
|
|
809
|
+
|
|
810
|
+
if type_id in BEAM_TYPES and texture is not None:
|
|
811
|
+
# Ion weapons and Fire Bullets use the projs.png streak effect (and Ion adds chain arcs on impact).
|
|
812
|
+
grid = 4
|
|
813
|
+
frame = 2
|
|
814
|
+
|
|
815
|
+
is_fire_bullets = type_id == int(ProjectileTypeId.FIRE_BULLETS)
|
|
816
|
+
is_ion = type_id in ION_TYPES
|
|
817
|
+
|
|
818
|
+
ox = float(getattr(proj, "origin_x", pos_x))
|
|
819
|
+
oy = float(getattr(proj, "origin_y", pos_y))
|
|
820
|
+
dx = pos_x - ox
|
|
821
|
+
dy = pos_y - oy
|
|
822
|
+
dist = math.hypot(dx, dy)
|
|
823
|
+
if dist <= 1e-6:
|
|
824
|
+
return
|
|
825
|
+
|
|
826
|
+
dir_x = dx / dist
|
|
827
|
+
dir_y = dy / dist
|
|
828
|
+
|
|
829
|
+
# In the native renderer, Ion Gun Master increases the chain effect thickness and reach.
|
|
830
|
+
perk_scale = 1.0
|
|
831
|
+
if any(perk_active(player, PerkId.ION_GUN_MASTER) for player in self.players):
|
|
832
|
+
perk_scale = 1.2
|
|
833
|
+
|
|
834
|
+
if life >= 0.4:
|
|
835
|
+
base_alpha = alpha
|
|
836
|
+
effect_scale = 1.0
|
|
837
|
+
else:
|
|
838
|
+
fade = clamp(life * 2.5, 0.0, 1.0)
|
|
839
|
+
base_alpha = fade * alpha
|
|
840
|
+
if type_id == int(ProjectileTypeId.ION_MINIGUN):
|
|
841
|
+
effect_scale = 1.05
|
|
842
|
+
elif type_id == int(ProjectileTypeId.ION_RIFLE):
|
|
843
|
+
effect_scale = 2.2
|
|
844
|
+
elif type_id == int(ProjectileTypeId.ION_CANNON):
|
|
845
|
+
effect_scale = 3.5
|
|
846
|
+
else:
|
|
847
|
+
effect_scale = 0.8
|
|
848
|
+
|
|
849
|
+
if base_alpha <= 1e-3:
|
|
850
|
+
return
|
|
851
|
+
|
|
852
|
+
streak_rgb = (1.0, 0.6, 0.1) if is_fire_bullets else (0.5, 0.6, 1.0)
|
|
853
|
+
head_rgb = (1.0, 1.0, 0.7)
|
|
854
|
+
|
|
855
|
+
# Only draw the last 256 units of the path.
|
|
856
|
+
start = 0.0
|
|
857
|
+
span = dist
|
|
858
|
+
if dist > 256.0:
|
|
859
|
+
start = dist - 256.0
|
|
860
|
+
span = 256.0
|
|
861
|
+
|
|
862
|
+
step = min(effect_scale * 3.1, 9.0)
|
|
863
|
+
sprite_scale = effect_scale * scale
|
|
864
|
+
|
|
865
|
+
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
866
|
+
|
|
867
|
+
s = start
|
|
868
|
+
while s < dist:
|
|
869
|
+
t = (s - start) / span if span > 1e-6 else 1.0
|
|
870
|
+
seg_alpha = t * base_alpha
|
|
871
|
+
if seg_alpha > 1e-3:
|
|
872
|
+
px = ox + dir_x * s
|
|
873
|
+
py = oy + dir_y * s
|
|
874
|
+
psx, psy = self.world_to_screen(px, py)
|
|
875
|
+
tint = self._color_from_rgba((streak_rgb[0], streak_rgb[1], streak_rgb[2], seg_alpha))
|
|
876
|
+
self._draw_atlas_sprite(
|
|
877
|
+
texture,
|
|
878
|
+
grid=grid,
|
|
879
|
+
frame=frame,
|
|
880
|
+
x=psx,
|
|
881
|
+
y=psy,
|
|
882
|
+
scale=sprite_scale,
|
|
883
|
+
rotation_rad=angle,
|
|
884
|
+
tint=tint,
|
|
885
|
+
)
|
|
886
|
+
s += step
|
|
887
|
+
|
|
888
|
+
head_tint = self._color_from_rgba((head_rgb[0], head_rgb[1], head_rgb[2], base_alpha))
|
|
889
|
+
self._draw_atlas_sprite(
|
|
890
|
+
texture,
|
|
891
|
+
grid=grid,
|
|
892
|
+
frame=frame,
|
|
893
|
+
x=sx,
|
|
894
|
+
y=sy,
|
|
895
|
+
scale=sprite_scale,
|
|
896
|
+
rotation_rad=angle,
|
|
897
|
+
tint=head_tint,
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
# Ion-only: impact core + chain arcs. (Fire Bullets renders an extra particles.png overlay in a later pass.)
|
|
901
|
+
if is_fire_bullets and life >= 0.4 and self.particles_texture is not None:
|
|
902
|
+
particles_texture = self.particles_texture
|
|
903
|
+
atlas = EFFECT_ID_ATLAS_TABLE_BY_ID.get(0x0D)
|
|
904
|
+
if atlas is not None:
|
|
905
|
+
grid = SIZE_CODE_GRID.get(int(atlas.size_code))
|
|
906
|
+
if grid:
|
|
907
|
+
cell_w = float(particles_texture.width) / float(grid)
|
|
908
|
+
cell_h = float(particles_texture.height) / float(grid)
|
|
909
|
+
frame = int(atlas.frame)
|
|
910
|
+
col = frame % grid
|
|
911
|
+
row = frame // grid
|
|
912
|
+
src = rl.Rectangle(
|
|
913
|
+
cell_w * float(col),
|
|
914
|
+
cell_h * float(row),
|
|
915
|
+
max(0.0, cell_w - 2.0),
|
|
916
|
+
max(0.0, cell_h - 2.0),
|
|
917
|
+
)
|
|
918
|
+
tint = self._color_from_rgba((1.0, 1.0, 1.0, alpha))
|
|
919
|
+
size = 64.0 * scale
|
|
920
|
+
dst = rl.Rectangle(float(sx), float(sy), float(size), float(size))
|
|
921
|
+
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
922
|
+
rl.draw_texture_pro(particles_texture, src, dst, origin, float(angle * _RAD_TO_DEG), tint)
|
|
923
|
+
|
|
924
|
+
if is_ion and life < 0.4:
|
|
925
|
+
core_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
|
|
926
|
+
self._draw_atlas_sprite(
|
|
927
|
+
texture,
|
|
928
|
+
grid=grid,
|
|
929
|
+
frame=frame,
|
|
930
|
+
x=sx,
|
|
931
|
+
y=sy,
|
|
932
|
+
scale=1.0 * scale,
|
|
933
|
+
rotation_rad=angle,
|
|
934
|
+
tint=core_tint,
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
if type_id == int(ProjectileTypeId.ION_RIFLE):
|
|
938
|
+
radius = 88.0
|
|
939
|
+
elif type_id == int(ProjectileTypeId.ION_MINIGUN):
|
|
940
|
+
radius = 60.0
|
|
941
|
+
else:
|
|
942
|
+
radius = 128.0
|
|
943
|
+
radius *= perk_scale
|
|
944
|
+
|
|
945
|
+
# Pick a stable set of targets so the arc visuals don't flicker.
|
|
946
|
+
candidates: list[tuple[float, object]] = []
|
|
947
|
+
for creature in self.creatures.entries:
|
|
948
|
+
if not creature.active or float(creature.hp) <= 0.0:
|
|
949
|
+
continue
|
|
950
|
+
if float(getattr(creature, "hitbox_size", 0.0)) < 5.0:
|
|
951
|
+
continue
|
|
952
|
+
d = math.hypot(float(creature.x) - pos_x, float(creature.y) - pos_y)
|
|
953
|
+
threshold = float(creature.size) * 0.142857149 + 3.0
|
|
954
|
+
if d > radius + threshold:
|
|
955
|
+
continue
|
|
956
|
+
candidates.append((d, creature))
|
|
957
|
+
|
|
958
|
+
candidates.sort(key=lambda item: item[0])
|
|
959
|
+
targets = [creature for _d, creature in candidates[:8]]
|
|
960
|
+
|
|
961
|
+
inner = 10.0 * perk_scale * scale
|
|
962
|
+
outer = 14.0 * perk_scale * scale
|
|
963
|
+
u = 0.625
|
|
964
|
+
v0 = 0.0
|
|
965
|
+
v1 = 0.25
|
|
966
|
+
|
|
967
|
+
glow_targets: list[object] = []
|
|
968
|
+
rl.rl_set_texture(texture.id)
|
|
969
|
+
rl.rl_begin(rl.RL_QUADS)
|
|
970
|
+
|
|
971
|
+
for creature in targets:
|
|
972
|
+
tx, ty = self.world_to_screen(float(creature.x), float(creature.y))
|
|
973
|
+
ddx = tx - sx
|
|
974
|
+
ddy = ty - sy
|
|
975
|
+
dlen = math.hypot(ddx, ddy)
|
|
976
|
+
if dlen <= 1e-3:
|
|
977
|
+
continue
|
|
978
|
+
glow_targets.append(creature)
|
|
979
|
+
inv = 1.0 / dlen
|
|
980
|
+
nx = ddx * inv
|
|
981
|
+
ny = ddy * inv
|
|
982
|
+
px = -ny
|
|
983
|
+
py = nx
|
|
984
|
+
|
|
985
|
+
# Outer strip (softer).
|
|
986
|
+
half = outer * 0.5
|
|
987
|
+
off_x = px * half
|
|
988
|
+
off_y = py * half
|
|
989
|
+
x0 = sx - off_x
|
|
990
|
+
y0 = sy - off_y
|
|
991
|
+
x1 = sx + off_x
|
|
992
|
+
y1 = sy + off_y
|
|
993
|
+
x2 = tx + off_x
|
|
994
|
+
y2 = ty + off_y
|
|
995
|
+
x3 = tx - off_x
|
|
996
|
+
y3 = ty - off_y
|
|
997
|
+
|
|
998
|
+
outer_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha * 0.5))
|
|
999
|
+
rl.rl_color4ub(outer_tint.r, outer_tint.g, outer_tint.b, outer_tint.a)
|
|
1000
|
+
rl.rl_tex_coord2f(u, v0)
|
|
1001
|
+
rl.rl_vertex2f(x0, y0)
|
|
1002
|
+
rl.rl_tex_coord2f(u, v1)
|
|
1003
|
+
rl.rl_vertex2f(x1, y1)
|
|
1004
|
+
rl.rl_tex_coord2f(u, v1)
|
|
1005
|
+
rl.rl_vertex2f(x2, y2)
|
|
1006
|
+
rl.rl_tex_coord2f(u, v0)
|
|
1007
|
+
rl.rl_vertex2f(x3, y3)
|
|
1008
|
+
|
|
1009
|
+
# Inner strip (brighter).
|
|
1010
|
+
half = inner * 0.5
|
|
1011
|
+
off_x = px * half
|
|
1012
|
+
off_y = py * half
|
|
1013
|
+
x0 = sx - off_x
|
|
1014
|
+
y0 = sy - off_y
|
|
1015
|
+
x1 = sx + off_x
|
|
1016
|
+
y1 = sy + off_y
|
|
1017
|
+
x2 = tx + off_x
|
|
1018
|
+
y2 = ty + off_y
|
|
1019
|
+
x3 = tx - off_x
|
|
1020
|
+
y3 = ty - off_y
|
|
1021
|
+
|
|
1022
|
+
inner_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
|
|
1023
|
+
rl.rl_color4ub(inner_tint.r, inner_tint.g, inner_tint.b, inner_tint.a)
|
|
1024
|
+
rl.rl_tex_coord2f(u, v0)
|
|
1025
|
+
rl.rl_vertex2f(x0, y0)
|
|
1026
|
+
rl.rl_tex_coord2f(u, v1)
|
|
1027
|
+
rl.rl_vertex2f(x1, y1)
|
|
1028
|
+
rl.rl_tex_coord2f(u, v1)
|
|
1029
|
+
rl.rl_vertex2f(x2, y2)
|
|
1030
|
+
rl.rl_tex_coord2f(u, v0)
|
|
1031
|
+
rl.rl_vertex2f(x3, y3)
|
|
1032
|
+
|
|
1033
|
+
rl.rl_end()
|
|
1034
|
+
rl.rl_set_texture(0)
|
|
1035
|
+
|
|
1036
|
+
for creature in glow_targets:
|
|
1037
|
+
tx, ty = self.world_to_screen(float(creature.x), float(creature.y))
|
|
1038
|
+
target_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
|
|
1039
|
+
self._draw_atlas_sprite(
|
|
1040
|
+
texture,
|
|
1041
|
+
grid=grid,
|
|
1042
|
+
frame=frame,
|
|
1043
|
+
x=tx,
|
|
1044
|
+
y=ty,
|
|
1045
|
+
scale=sprite_scale,
|
|
1046
|
+
rotation_rad=0.0,
|
|
1047
|
+
tint=target_tint,
|
|
1048
|
+
)
|
|
1049
|
+
|
|
1050
|
+
rl.end_blend_mode()
|
|
1051
|
+
return
|
|
1052
|
+
|
|
686
1053
|
mapping = KNOWN_PROJ_FRAMES.get(type_id)
|
|
687
1054
|
if texture is None or mapping is None:
|
|
688
1055
|
rl.draw_circle(int(sx), int(sy), max(1.0, 3.0 * scale), rl.Color(240, 220, 160, int(255 * alpha + 0.5)))
|
|
@@ -699,36 +1066,6 @@ class WorldRenderer:
|
|
|
699
1066
|
elif type_id == ProjectileTypeId.BLADE_GUN:
|
|
700
1067
|
color = rl.Color(240, 120, 255, 255)
|
|
701
1068
|
|
|
702
|
-
if type_id in BEAM_TYPES and life >= 0.4:
|
|
703
|
-
ox = float(getattr(proj, "origin_x", 0.0))
|
|
704
|
-
oy = float(getattr(proj, "origin_y", 0.0))
|
|
705
|
-
dx = float(getattr(proj, "pos_x", 0.0)) - ox
|
|
706
|
-
dy = float(getattr(proj, "pos_y", 0.0)) - oy
|
|
707
|
-
dist = math.hypot(dx, dy)
|
|
708
|
-
if dist > 1e-6:
|
|
709
|
-
step = 14.0
|
|
710
|
-
seg_count = max(1, int(dist // step) + 1)
|
|
711
|
-
dir_x = dx / dist
|
|
712
|
-
dir_y = dy / dist
|
|
713
|
-
for idx in range(seg_count):
|
|
714
|
-
t = float(idx) / float(max(1, seg_count - 1))
|
|
715
|
-
px = ox + dir_x * dist * t
|
|
716
|
-
py = oy + dir_y * dist * t
|
|
717
|
-
seg_alpha = int(clamp(220.0 * (1.0 - t * 0.75) * alpha, 0.0, 255.0) + 0.5)
|
|
718
|
-
tint = rl.Color(color.r, color.g, color.b, seg_alpha)
|
|
719
|
-
psx, psy = self.world_to_screen(px, py)
|
|
720
|
-
self._draw_atlas_sprite(
|
|
721
|
-
texture,
|
|
722
|
-
grid=grid,
|
|
723
|
-
frame=frame,
|
|
724
|
-
x=psx,
|
|
725
|
-
y=psy,
|
|
726
|
-
scale=0.55 * scale,
|
|
727
|
-
rotation_rad=angle,
|
|
728
|
-
tint=tint,
|
|
729
|
-
)
|
|
730
|
-
return
|
|
731
|
-
|
|
732
1069
|
alpha_byte = int(clamp(clamp(life / 0.4, 0.0, 1.0) * 255.0 * alpha, 0.0, 255.0) + 0.5)
|
|
733
1070
|
tint = rl.Color(color.r, color.g, color.b, alpha_byte)
|
|
734
1071
|
self._draw_atlas_sprite(
|
|
@@ -43,14 +43,25 @@ KNOWN_PROJ_FRAMES: dict[int, tuple[int, int]] = {
|
|
|
43
43
|
ProjectileTypeId.ION_RIFLE: (4, 2),
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
PLASMA_PARTICLE_TYPES = frozenset(
|
|
47
|
+
{
|
|
48
|
+
ProjectileTypeId.PLASMA_RIFLE,
|
|
49
|
+
ProjectileTypeId.PLASMA_MINIGUN,
|
|
50
|
+
ProjectileTypeId.PLASMA_CANNON,
|
|
51
|
+
ProjectileTypeId.SPIDER_PLASMA,
|
|
52
|
+
ProjectileTypeId.SHRINKIFIER,
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
ION_TYPES = frozenset(
|
|
47
57
|
{
|
|
48
58
|
ProjectileTypeId.ION_RIFLE,
|
|
49
59
|
ProjectileTypeId.ION_MINIGUN,
|
|
50
60
|
ProjectileTypeId.ION_CANNON,
|
|
51
|
-
ProjectileTypeId.SHRINKIFIER,
|
|
52
|
-
ProjectileTypeId.FIRE_BULLETS,
|
|
53
|
-
ProjectileTypeId.BLADE_GUN,
|
|
54
|
-
ProjectileTypeId.SPLITTER_GUN,
|
|
55
61
|
}
|
|
56
62
|
)
|
|
63
|
+
|
|
64
|
+
FIRE_BULLETS_TYPES = frozenset({ProjectileTypeId.FIRE_BULLETS})
|
|
65
|
+
|
|
66
|
+
# "Beam" in the original renderer is really the Ion/Fire streak + chain UV family.
|
|
67
|
+
BEAM_TYPES = ION_TYPES | FIRE_BULLETS_TYPES
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crimsonland-0.1.0.dev2 → crimsonland-0.1.0.dev4}/src/crimson/views/projectile_render_debug.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|