crimsonland 0.1.0.dev5__py3-none-any.whl → 0.1.0.dev11__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/audio_router.py +12 -2
- crimson/creatures/anim.py +1 -0
- crimson/demo.py +79 -37
- crimson/effects.py +1 -1
- crimson/game.py +5 -0
- crimson/gameplay.py +91 -31
- crimson/modes/base_gameplay_mode.py +75 -1
- crimson/modes/quest_mode.py +471 -44
- crimson/modes/rush_mode.py +12 -3
- crimson/modes/survival_mode.py +13 -2
- crimson/modes/tutorial_mode.py +12 -1
- crimson/modes/typo_mode.py +12 -4
- crimson/projectiles.py +224 -61
- crimson/render/world_renderer.py +172 -36
- crimson/ui/hud.py +274 -51
- crimson/views/arsenal_debug.py +46 -1
- crimson/views/player.py +2 -2
- {crimsonland-0.1.0.dev5.dist-info → crimsonland-0.1.0.dev11.dist-info}/METADATA +1 -1
- {crimsonland-0.1.0.dev5.dist-info → crimsonland-0.1.0.dev11.dist-info}/RECORD +22 -22
- grim/console.py +14 -0
- {crimsonland-0.1.0.dev5.dist-info → crimsonland-0.1.0.dev11.dist-info}/WHEEL +0 -0
- {crimsonland-0.1.0.dev5.dist-info → crimsonland-0.1.0.dev11.dist-info}/entry_points.txt +0 -0
crimson/render/world_renderer.py
CHANGED
|
@@ -452,13 +452,13 @@ class WorldRenderer:
|
|
|
452
452
|
):
|
|
453
453
|
atlas = EFFECT_ID_ATLAS_TABLE_BY_ID.get(0x10)
|
|
454
454
|
if atlas is not None:
|
|
455
|
-
|
|
456
|
-
if
|
|
455
|
+
aura_grid = SIZE_CODE_GRID.get(int(atlas.size_code))
|
|
456
|
+
if aura_grid:
|
|
457
457
|
frame = int(atlas.frame)
|
|
458
|
-
col = frame %
|
|
459
|
-
row = frame //
|
|
460
|
-
cell_w = float(self.particles_texture.width) / float(
|
|
461
|
-
cell_h = float(self.particles_texture.height) / float(
|
|
458
|
+
col = frame % aura_grid
|
|
459
|
+
row = frame // aura_grid
|
|
460
|
+
cell_w = float(self.particles_texture.width) / float(aura_grid)
|
|
461
|
+
cell_h = float(self.particles_texture.height) / float(aura_grid)
|
|
462
462
|
src = rl.Rectangle(
|
|
463
463
|
cell_w * float(col),
|
|
464
464
|
cell_h * float(row),
|
|
@@ -922,6 +922,7 @@ class WorldRenderer:
|
|
|
922
922
|
origin = rl.Vector2(size * 0.5, size * 0.5)
|
|
923
923
|
rl.draw_texture_pro(particles_texture, src, dst, origin, float(angle * _RAD_TO_DEG), tint)
|
|
924
924
|
else:
|
|
925
|
+
# Native draws a small blue "core" at the head during the fade stage (life_timer < 0.4).
|
|
925
926
|
core_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
|
|
926
927
|
self._draw_atlas_sprite(
|
|
927
928
|
texture,
|
|
@@ -935,32 +936,23 @@ class WorldRenderer:
|
|
|
935
936
|
)
|
|
936
937
|
|
|
937
938
|
if is_ion:
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
# Pick a stable set of targets so the arc visuals don't flicker.
|
|
947
|
-
candidates: list[tuple[float, object]] = []
|
|
948
|
-
for creature in self.creatures.entries:
|
|
949
|
-
if not creature.active or float(creature.hp) <= 0.0:
|
|
939
|
+
# Native: chain reach is derived from the streak scale (`fVar29 * perk_scale * 40.0`).
|
|
940
|
+
radius = effect_scale * perk_scale * 40.0
|
|
941
|
+
|
|
942
|
+
# Native iterates via creature_find_in_radius(pos, radius, start_index) in pool order.
|
|
943
|
+
targets: list[object] = []
|
|
944
|
+
for creature in self.creatures.entries[1:]:
|
|
945
|
+
if not creature.active:
|
|
950
946
|
continue
|
|
951
|
-
if float(getattr(creature, "hitbox_size", 0.0))
|
|
947
|
+
if float(getattr(creature, "hitbox_size", 0.0)) <= 5.0:
|
|
952
948
|
continue
|
|
953
949
|
d = math.hypot(float(creature.x) - pos_x, float(creature.y) - pos_y)
|
|
954
950
|
threshold = float(creature.size) * 0.142857149 + 3.0
|
|
955
|
-
if d
|
|
956
|
-
|
|
957
|
-
candidates.append((d, creature))
|
|
958
|
-
|
|
959
|
-
candidates.sort(key=lambda item: item[0])
|
|
960
|
-
targets = [creature for _d, creature in candidates[:8]]
|
|
951
|
+
if d - radius < threshold:
|
|
952
|
+
targets.append(creature)
|
|
961
953
|
|
|
962
|
-
|
|
963
|
-
|
|
954
|
+
inner_half = 10.0 * perk_scale * scale
|
|
955
|
+
outer_half = 14.0 * perk_scale * scale
|
|
964
956
|
u = 0.625
|
|
965
957
|
v0 = 0.0
|
|
966
958
|
v1 = 0.25
|
|
@@ -984,7 +976,7 @@ class WorldRenderer:
|
|
|
984
976
|
py = nx
|
|
985
977
|
|
|
986
978
|
# Outer strip (softer).
|
|
987
|
-
half =
|
|
979
|
+
half = outer_half
|
|
988
980
|
off_x = px * half
|
|
989
981
|
off_y = py * half
|
|
990
982
|
x0 = sx - off_x
|
|
@@ -996,7 +988,7 @@ class WorldRenderer:
|
|
|
996
988
|
x3 = tx - off_x
|
|
997
989
|
y3 = ty - off_y
|
|
998
990
|
|
|
999
|
-
outer_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha
|
|
991
|
+
outer_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
|
|
1000
992
|
rl.rl_color4ub(outer_tint.r, outer_tint.g, outer_tint.b, outer_tint.a)
|
|
1001
993
|
rl.rl_tex_coord2f(u, v0)
|
|
1002
994
|
rl.rl_vertex2f(x0, y0)
|
|
@@ -1008,7 +1000,7 @@ class WorldRenderer:
|
|
|
1008
1000
|
rl.rl_vertex2f(x3, y3)
|
|
1009
1001
|
|
|
1010
1002
|
# Inner strip (brighter).
|
|
1011
|
-
half =
|
|
1003
|
+
half = inner_half
|
|
1012
1004
|
off_x = px * half
|
|
1013
1005
|
off_y = py * half
|
|
1014
1006
|
x0 = sx - off_x
|
|
@@ -1346,6 +1338,99 @@ class WorldRenderer:
|
|
|
1346
1338
|
rl.end_blend_mode()
|
|
1347
1339
|
return True
|
|
1348
1340
|
|
|
1341
|
+
def _draw_sharpshooter_laser_sight(
|
|
1342
|
+
self,
|
|
1343
|
+
*,
|
|
1344
|
+
cam_x: float,
|
|
1345
|
+
cam_y: float,
|
|
1346
|
+
scale_x: float,
|
|
1347
|
+
scale_y: float,
|
|
1348
|
+
scale: float,
|
|
1349
|
+
alpha: float,
|
|
1350
|
+
) -> None:
|
|
1351
|
+
"""Laser sight overlay for the Sharpshooter perk (`projectile_render` @ 0x00422c70)."""
|
|
1352
|
+
|
|
1353
|
+
alpha = clamp(float(alpha), 0.0, 1.0)
|
|
1354
|
+
if alpha <= 1e-3:
|
|
1355
|
+
return
|
|
1356
|
+
if self.bullet_trail_texture is None:
|
|
1357
|
+
return
|
|
1358
|
+
|
|
1359
|
+
players = self.players
|
|
1360
|
+
if not players:
|
|
1361
|
+
return
|
|
1362
|
+
|
|
1363
|
+
tail_alpha = int(clamp(alpha * 0.5, 0.0, 1.0) * 255.0 + 0.5)
|
|
1364
|
+
head_alpha = int(clamp(alpha * 0.2, 0.0, 1.0) * 255.0 + 0.5)
|
|
1365
|
+
tail = rl.Color(255, 0, 0, tail_alpha)
|
|
1366
|
+
head = rl.Color(255, 0, 0, head_alpha)
|
|
1367
|
+
|
|
1368
|
+
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
1369
|
+
rl.rl_set_texture(self.bullet_trail_texture.id)
|
|
1370
|
+
rl.rl_begin(rl.RL_QUADS)
|
|
1371
|
+
|
|
1372
|
+
for player in players:
|
|
1373
|
+
if float(getattr(player, "health", 0.0)) <= 0.0:
|
|
1374
|
+
continue
|
|
1375
|
+
if not perk_active(player, PerkId.SHARPSHOOTER):
|
|
1376
|
+
continue
|
|
1377
|
+
|
|
1378
|
+
aim_heading = float(getattr(player, "aim_heading", 0.0))
|
|
1379
|
+
dir_x = math.cos(aim_heading - math.pi / 2.0)
|
|
1380
|
+
dir_y = math.sin(aim_heading - math.pi / 2.0)
|
|
1381
|
+
|
|
1382
|
+
start_x = float(getattr(player, "pos_x", 0.0)) + dir_x * 15.0
|
|
1383
|
+
start_y = float(getattr(player, "pos_y", 0.0)) + dir_y * 15.0
|
|
1384
|
+
end_x = float(getattr(player, "pos_x", 0.0)) + dir_x * 512.0
|
|
1385
|
+
end_y = float(getattr(player, "pos_y", 0.0)) + dir_y * 512.0
|
|
1386
|
+
|
|
1387
|
+
sx0 = (start_x + cam_x) * scale_x
|
|
1388
|
+
sy0 = (start_y + cam_y) * scale_y
|
|
1389
|
+
sx1 = (end_x + cam_x) * scale_x
|
|
1390
|
+
sy1 = (end_y + cam_y) * scale_y
|
|
1391
|
+
|
|
1392
|
+
dx = sx1 - sx0
|
|
1393
|
+
dy = sy1 - sy0
|
|
1394
|
+
dist = math.hypot(dx, dy)
|
|
1395
|
+
if dist <= 1e-3:
|
|
1396
|
+
continue
|
|
1397
|
+
|
|
1398
|
+
thickness = max(1.0, 2.0 * scale)
|
|
1399
|
+
half = thickness * 0.5
|
|
1400
|
+
inv = 1.0 / dist
|
|
1401
|
+
nx = dx * inv
|
|
1402
|
+
ny = dy * inv
|
|
1403
|
+
px = -ny
|
|
1404
|
+
py = nx
|
|
1405
|
+
ox = px * half
|
|
1406
|
+
oy = py * half
|
|
1407
|
+
|
|
1408
|
+
x0 = sx0 - ox
|
|
1409
|
+
y0 = sy0 - oy
|
|
1410
|
+
x1 = sx0 + ox
|
|
1411
|
+
y1 = sy0 + oy
|
|
1412
|
+
x2 = sx1 + ox
|
|
1413
|
+
y2 = sy1 + oy
|
|
1414
|
+
x3 = sx1 - ox
|
|
1415
|
+
y3 = sy1 - oy
|
|
1416
|
+
|
|
1417
|
+
rl.rl_color4ub(tail.r, tail.g, tail.b, tail.a)
|
|
1418
|
+
rl.rl_tex_coord2f(0.0, 0.0)
|
|
1419
|
+
rl.rl_vertex2f(x0, y0)
|
|
1420
|
+
rl.rl_color4ub(tail.r, tail.g, tail.b, tail.a)
|
|
1421
|
+
rl.rl_tex_coord2f(1.0, 0.0)
|
|
1422
|
+
rl.rl_vertex2f(x1, y1)
|
|
1423
|
+
rl.rl_color4ub(head.r, head.g, head.b, head.a)
|
|
1424
|
+
rl.rl_tex_coord2f(1.0, 0.5)
|
|
1425
|
+
rl.rl_vertex2f(x2, y2)
|
|
1426
|
+
rl.rl_color4ub(head.r, head.g, head.b, head.a)
|
|
1427
|
+
rl.rl_tex_coord2f(0.0, 0.5)
|
|
1428
|
+
rl.rl_vertex2f(x3, y3)
|
|
1429
|
+
|
|
1430
|
+
rl.rl_end()
|
|
1431
|
+
rl.rl_set_texture(0)
|
|
1432
|
+
rl.end_blend_mode()
|
|
1433
|
+
|
|
1349
1434
|
def _draw_secondary_projectile(self, proj: object, *, scale: float, alpha: float = 1.0) -> None:
|
|
1350
1435
|
alpha = clamp(float(alpha), 0.0, 1.0)
|
|
1351
1436
|
if alpha <= 1e-3:
|
|
@@ -1436,11 +1521,53 @@ class WorldRenderer:
|
|
|
1436
1521
|
rl.draw_circle(int(sx), int(sy), max(1.0, 12.0 * scale), rl.Color(200, 120, 255, int(255 * alpha + 0.5)))
|
|
1437
1522
|
return
|
|
1438
1523
|
if proj_type == 3:
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1524
|
+
# Secondary projectile detonation visuals (secondary_projectile_update + render).
|
|
1525
|
+
t = clamp(float(getattr(proj, "vel_x", 0.0)), 0.0, 1.0)
|
|
1526
|
+
det_scale = float(getattr(proj, "vel_y", 1.0))
|
|
1527
|
+
fade = (1.0 - t) * alpha
|
|
1528
|
+
if fade <= 1e-3 or det_scale <= 1e-6:
|
|
1529
|
+
return
|
|
1530
|
+
if self.particles_texture is None:
|
|
1531
|
+
radius = det_scale * t * 80.0
|
|
1532
|
+
alpha_byte = int(clamp((1.0 - t) * 180.0 * alpha, 0.0, 255.0) + 0.5)
|
|
1533
|
+
color = rl.Color(255, 180, 100, alpha_byte)
|
|
1534
|
+
rl.draw_circle_lines(int(sx), int(sy), max(1.0, radius * scale), color)
|
|
1535
|
+
return
|
|
1536
|
+
|
|
1537
|
+
atlas = EFFECT_ID_ATLAS_TABLE_BY_ID.get(0x0D)
|
|
1538
|
+
if atlas is None:
|
|
1539
|
+
return
|
|
1540
|
+
grid = SIZE_CODE_GRID.get(int(atlas.size_code))
|
|
1541
|
+
if not grid:
|
|
1542
|
+
return
|
|
1543
|
+
frame = int(atlas.frame)
|
|
1544
|
+
col = frame % grid
|
|
1545
|
+
row = frame // grid
|
|
1546
|
+
cell_w = float(self.particles_texture.width) / float(grid)
|
|
1547
|
+
cell_h = float(self.particles_texture.height) / float(grid)
|
|
1548
|
+
src = rl.Rectangle(
|
|
1549
|
+
cell_w * float(col),
|
|
1550
|
+
cell_h * float(row),
|
|
1551
|
+
max(0.0, cell_w - 2.0),
|
|
1552
|
+
max(0.0, cell_h - 2.0),
|
|
1553
|
+
)
|
|
1554
|
+
|
|
1555
|
+
def _draw_detonation_quad(*, size: float, alpha_mul: float) -> None:
|
|
1556
|
+
a = fade * alpha_mul
|
|
1557
|
+
if a <= 1e-3:
|
|
1558
|
+
return
|
|
1559
|
+
dst_size = size * scale
|
|
1560
|
+
if dst_size <= 1e-3:
|
|
1561
|
+
return
|
|
1562
|
+
tint = self._color_from_rgba((1.0, 0.6, 0.1, a))
|
|
1563
|
+
dst = rl.Rectangle(float(sx), float(sy), float(dst_size), float(dst_size))
|
|
1564
|
+
origin = rl.Vector2(float(dst_size) * 0.5, float(dst_size) * 0.5)
|
|
1565
|
+
rl.draw_texture_pro(self.particles_texture, src, dst, origin, 0.0, tint)
|
|
1566
|
+
|
|
1567
|
+
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
1568
|
+
_draw_detonation_quad(size=det_scale * t * 64.0, alpha_mul=1.0)
|
|
1569
|
+
_draw_detonation_quad(size=det_scale * t * 200.0, alpha_mul=0.3)
|
|
1570
|
+
rl.end_blend_mode()
|
|
1444
1571
|
return
|
|
1445
1572
|
rl.draw_circle(int(sx), int(sy), max(1.0, 4.0 * scale), rl.Color(200, 200, 220, int(200 * alpha + 0.5)))
|
|
1446
1573
|
|
|
@@ -1488,7 +1615,7 @@ class WorldRenderer:
|
|
|
1488
1615
|
rl.begin_blend_mode(rl.BLEND_ADDITIVE)
|
|
1489
1616
|
|
|
1490
1617
|
if fx_detail_1 and src_large is not None:
|
|
1491
|
-
alpha_byte = int(clamp(alpha * 0.
|
|
1618
|
+
alpha_byte = int(clamp(alpha * 0.065, 0.0, 1.0) * 255.0 + 0.5)
|
|
1492
1619
|
tint = rl.Color(255, 255, 255, alpha_byte)
|
|
1493
1620
|
for idx, entry in enumerate(particles):
|
|
1494
1621
|
if not entry.active or (idx % 2) or int(entry.style_id) == 8:
|
|
@@ -1893,6 +2020,15 @@ class WorldRenderer:
|
|
|
1893
2020
|
if player.health > 0.0:
|
|
1894
2021
|
draw_player(player)
|
|
1895
2022
|
|
|
2023
|
+
self._draw_sharpshooter_laser_sight(
|
|
2024
|
+
cam_x=cam_x,
|
|
2025
|
+
cam_y=cam_y,
|
|
2026
|
+
scale_x=scale_x,
|
|
2027
|
+
scale_y=scale_y,
|
|
2028
|
+
scale=scale,
|
|
2029
|
+
alpha=entity_alpha,
|
|
2030
|
+
)
|
|
2031
|
+
|
|
1896
2032
|
for proj_index, proj in enumerate(self.state.projectiles.entries):
|
|
1897
2033
|
if not proj.active:
|
|
1898
2034
|
continue
|