crimsonland 0.1.0.dev8__py3-none-any.whl → 0.1.0.dev10__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/demo.py CHANGED
@@ -475,6 +475,9 @@ class DemoView:
475
475
  player = self._world.players[idx]
476
476
  player.pos_x = float(x)
477
477
  player.pos_y = float(y)
478
+ # Keep aim anchored to the spawn position so demo aim starts stable.
479
+ player.aim_x = float(x)
480
+ player.aim_y = float(y)
478
481
  weapon_assign_player(player, int(weapon_id))
479
482
  self._demo_targets = [None] * len(self._world.players)
480
483
 
@@ -549,7 +552,8 @@ class DemoView:
549
552
 
550
553
  def _setup_variant_0(self) -> None:
551
554
  self._demo_time_limit_ms = 4000
552
- weapon_id = 12
555
+ # demo_setup_variant_0 uses weapon_id=0x0B.
556
+ weapon_id = 11
553
557
  self._setup_world_players(
554
558
  [
555
559
  (448.0, 384.0, weapon_id),
@@ -567,7 +571,8 @@ class DemoView:
567
571
 
568
572
  def _setup_variant_1(self) -> None:
569
573
  self._demo_time_limit_ms = 5000
570
- weapon_id = 6
574
+ # demo_setup_variant_1 uses weapon_id=0x05.
575
+ weapon_id = 5
571
576
  self._setup_world_players(
572
577
  [
573
578
  (490.0, 448.0, weapon_id),
@@ -586,7 +591,8 @@ class DemoView:
586
591
 
587
592
  def _setup_variant_2(self) -> None:
588
593
  self._demo_time_limit_ms = 5000
589
- weapon_id = 22
594
+ # demo_setup_variant_2 uses weapon_id=0x15.
595
+ weapon_id = 21
590
596
  self._setup_world_players([(512.0, 512.0, weapon_id)])
591
597
  y = 128
592
598
  i = 0
@@ -601,7 +607,8 @@ class DemoView:
601
607
 
602
608
  def _setup_variant_3(self) -> None:
603
609
  self._demo_time_limit_ms = 4000
604
- weapon_id = 19
610
+ # demo_setup_variant_3 uses weapon_id=0x12.
611
+ weapon_id = 18
605
612
  self._setup_world_players([(512.0, 512.0, weapon_id)])
606
613
  for idx in range(20):
607
614
  x = float(self._crand_mod(200) + 32)
@@ -881,10 +888,10 @@ class DemoView:
881
888
  def _update_world(self, dt: float) -> None:
882
889
  if not self._world.players:
883
890
  return
884
- inputs = self._build_demo_inputs()
891
+ inputs = self._build_demo_inputs(dt)
885
892
  self._world.update(dt, inputs=inputs, auto_pick_perks=False, game_mode=0, perk_progression_enabled=False)
886
893
 
887
- def _build_demo_inputs(self) -> list[PlayerInput]:
894
+ def _build_demo_inputs(self, dt: float) -> list[PlayerInput]:
888
895
  players = self._world.players
889
896
  creatures = self._world.creatures.entries
890
897
  if len(self._demo_targets) != len(players):
@@ -892,42 +899,77 @@ class DemoView:
892
899
  center_x = float(self._world.world_size) * 0.5
893
900
  center_y = float(self._world.world_size) * 0.5
894
901
 
902
+ dt = float(dt)
903
+
904
+ def _turn_towards_heading(cur: float, target: float) -> tuple[float, float]:
905
+ cur = cur % math.tau
906
+ target = target % math.tau
907
+ delta = (target - cur + math.pi) % math.tau - math.pi
908
+ diff = abs(delta)
909
+ if diff <= 1e-9:
910
+ return cur, 0.0
911
+ step = dt * diff * 5.0
912
+ cur = (cur + step) % math.tau if delta > 0.0 else (cur - step) % math.tau
913
+ return cur, diff
914
+
895
915
  inputs: list[PlayerInput] = []
896
916
  for idx, player in enumerate(players):
897
917
  target_idx = self._select_demo_target(idx, player, creatures)
898
- aim_x = center_x
899
- aim_y = center_y
900
918
  target = None
901
919
  if target_idx is not None and 0 <= target_idx < len(creatures):
902
920
  candidate = creatures[target_idx]
903
- if candidate.hp > 0.0:
921
+ if candidate.active and candidate.hp > 0.0:
904
922
  target = candidate
905
- aim_x = candidate.x
906
- aim_y = candidate.y
907
-
908
- move_x, move_y = 0.0, 0.0
909
- to_cx = center_x - player.pos_x
910
- to_cy = center_y - player.pos_y
911
- nx, ny, d = _normalize(to_cx, to_cy)
912
- if d > 120.0:
913
- move_x += nx
914
- move_y += ny
915
923
 
924
+ # Aim: ease the aim point toward the target.
925
+ aim_x = float(player.aim_x)
926
+ aim_y = float(player.aim_y)
927
+ auto_fire = False
916
928
  if target is not None:
917
- rx = player.pos_x - target.x
918
- ry = player.pos_y - target.y
919
- rnx, rny, rd = _normalize(rx, ry)
920
- if 0.0 < rd < 160.0:
921
- strength = (160.0 - rd) / 160.0
922
- move_x += rnx * (1.5 * strength)
923
- move_y += rny * (1.5 * strength)
924
-
925
- orbit_dir = -1.0 if (player.index % 2) else 1.0
926
- ox, oy, _ = _normalize(-(player.pos_y - center_y), player.pos_x - center_x)
927
- move_x += ox * 0.55 * orbit_dir
928
- move_y += oy * 0.55 * orbit_dir
929
-
930
- fire_down = target is not None
929
+ aim_dx = float(target.x) - aim_x
930
+ aim_dy = float(target.y) - aim_y
931
+ aim_dir_x, aim_dir_y, aim_dist = _normalize(aim_dx, aim_dy)
932
+ if aim_dist >= 4.0:
933
+ step = aim_dist * 6.0 * dt
934
+ aim_x += aim_dir_x * step
935
+ aim_y += aim_dir_y * step
936
+ else:
937
+ aim_x = float(target.x)
938
+ aim_y = float(target.y)
939
+ auto_fire = aim_dist < 128.0
940
+ else:
941
+ ax, ay, amag = _normalize(float(player.pos_x) - center_x, float(player.pos_y) - center_y)
942
+ if amag <= 1e-6:
943
+ ax, ay = 0.0, -1.0
944
+ aim_x = float(player.pos_x) + ax * 60.0
945
+ aim_y = float(player.pos_y) + ay * 60.0
946
+
947
+ # Movement:
948
+ # - orbit center if no target
949
+ # - chase target when near center
950
+ # - return to center when too far
951
+ if target is None:
952
+ move_dx = -(float(player.pos_y) - center_y)
953
+ move_dy = float(player.pos_x) - center_x
954
+ else:
955
+ center_dist = math.hypot(float(player.pos_x) - center_x, float(player.pos_y) - center_y)
956
+ if center_dist <= 300.0:
957
+ move_dx = float(target.x) - float(player.pos_x)
958
+ move_dy = float(target.y) - float(player.pos_y)
959
+ else:
960
+ move_dx = center_x - float(player.pos_x)
961
+ move_dy = center_y - float(player.pos_y)
962
+
963
+ desired_x, desired_y, desired_mag = _normalize(move_dx, move_dy)
964
+ if desired_mag <= 1e-6:
965
+ move_x = 0.0
966
+ move_y = 0.0
967
+ else:
968
+ desired_heading = math.atan2(desired_y, desired_x) + math.pi / 2.0
969
+ smoothed_heading, angle_diff = _turn_towards_heading(float(player.heading), desired_heading)
970
+ move_mag = max(0.001, (math.pi - angle_diff) / math.pi)
971
+ move_x = math.cos(smoothed_heading - math.pi / 2.0) * move_mag
972
+ move_y = math.sin(smoothed_heading - math.pi / 2.0) * move_mag
931
973
 
932
974
  inputs.append(
933
975
  PlayerInput(
@@ -935,8 +977,8 @@ class DemoView:
935
977
  move_y=move_y,
936
978
  aim_x=aim_x,
937
979
  aim_y=aim_y,
938
- fire_down=fire_down,
939
- fire_pressed=fire_down,
980
+ fire_down=auto_fire,
981
+ fire_pressed=auto_fire,
940
982
  reload_pressed=False,
941
983
  )
942
984
  )
crimson/gameplay.py CHANGED
@@ -974,8 +974,8 @@ def perk_apply(
974
974
  weapon_id = int(current)
975
975
  for _ in range(100):
976
976
  candidate = int(weapon_pick_random_available(state))
977
- if candidate != 0 and candidate != current:
978
- weapon_id = candidate
977
+ weapon_id = candidate
978
+ if candidate != int(WeaponId.PISTOL) and candidate != current:
979
979
  break
980
980
  weapon_assign_player(owner, weapon_id, state=state)
981
981
  return
@@ -1929,7 +1929,9 @@ def player_update(player: PlayerState, input_state: PlayerInput, dt: float, stat
1929
1929
  raw_move_x = float(input_state.move_x)
1930
1930
  raw_move_y = float(input_state.move_y)
1931
1931
  raw_mag = math.hypot(raw_move_x, raw_move_y)
1932
- moving_input = raw_mag > 0.2
1932
+ # Demo/autoplay uses very small analog magnitudes to represent turn-in-place and
1933
+ # heading alignment slowdown; don't apply a deadzone there.
1934
+ moving_input = raw_mag > (0.0 if state.demo_mode_active else 0.2)
1933
1935
 
1934
1936
  if moving_input:
1935
1937
  inv = 1.0 / raw_mag if raw_mag > 1e-9 else 0.0
@@ -939,24 +939,20 @@ class WorldRenderer:
939
939
  # Native: chain reach is derived from the streak scale (`fVar29 * perk_scale * 40.0`).
940
940
  radius = effect_scale * perk_scale * 40.0
941
941
 
942
- # Pick a stable set of targets so the arc visuals don't flicker.
943
- candidates: list[tuple[float, object]] = []
944
- for creature in self.creatures.entries:
945
- if not creature.active or float(creature.hp) <= 0.0:
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:
946
946
  continue
947
- if float(getattr(creature, "hitbox_size", 0.0)) < 5.0:
947
+ if float(getattr(creature, "hitbox_size", 0.0)) <= 5.0:
948
948
  continue
949
949
  d = math.hypot(float(creature.x) - pos_x, float(creature.y) - pos_y)
950
950
  threshold = float(creature.size) * 0.142857149 + 3.0
951
- if d > radius + threshold:
952
- continue
953
- candidates.append((d, creature))
954
-
955
- candidates.sort(key=lambda item: item[0])
956
- targets = [creature for _d, creature in candidates[:8]]
951
+ if d - radius < threshold:
952
+ targets.append(creature)
957
953
 
958
- inner = 10.0 * perk_scale * scale
959
- outer = 14.0 * perk_scale * scale
954
+ inner_half = 10.0 * perk_scale * scale
955
+ outer_half = 14.0 * perk_scale * scale
960
956
  u = 0.625
961
957
  v0 = 0.0
962
958
  v1 = 0.25
@@ -980,7 +976,7 @@ class WorldRenderer:
980
976
  py = nx
981
977
 
982
978
  # Outer strip (softer).
983
- half = outer * 0.5
979
+ half = outer_half
984
980
  off_x = px * half
985
981
  off_y = py * half
986
982
  x0 = sx - off_x
@@ -992,7 +988,7 @@ class WorldRenderer:
992
988
  x3 = tx - off_x
993
989
  y3 = ty - off_y
994
990
 
995
- outer_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha * 0.5))
991
+ outer_tint = self._color_from_rgba((0.5, 0.6, 1.0, base_alpha))
996
992
  rl.rl_color4ub(outer_tint.r, outer_tint.g, outer_tint.b, outer_tint.a)
997
993
  rl.rl_tex_coord2f(u, v0)
998
994
  rl.rl_vertex2f(x0, y0)
@@ -1004,7 +1000,7 @@ class WorldRenderer:
1004
1000
  rl.rl_vertex2f(x3, y3)
1005
1001
 
1006
1002
  # Inner strip (brighter).
1007
- half = inner * 0.5
1003
+ half = inner_half
1008
1004
  off_x = px * half
1009
1005
  off_y = py * half
1010
1006
  x0 = sx - off_x
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: crimsonland
3
- Version: 0.1.0.dev8
3
+ Version: 0.1.0.dev10
4
4
  Requires-Dist: construct>=2.10.70
5
5
  Requires-Dist: pillow>=12.1.0
6
6
  Requires-Dist: platformdirs>=4.5.1
@@ -12,7 +12,7 @@ crimson/creatures/damage.py,sha256=pjKIX32nGDVPnFaWCce0LNZ-UZXZqJpNvwHwq-DCWbE,3
12
12
  crimson/creatures/runtime.py,sha256=1FagJNwGWJuOXZEv4VaWak2IktNskSof82WCYJqui-U,40733
13
13
  crimson/creatures/spawn.py,sha256=ikgtr4sM2KdA2-eyxYdVmobcuZN6aA7xK7ceaIl7RSw,90059
14
14
  crimson/debug.py,sha256=vtfr0_HQHpiB5h57jAsl9cWyYxErSbZQ2uazcL1sJhU,127
15
- crimson/demo.py,sha256=IzBcqiIilzC4PAEH6VwMpfb6y13HfieUOOfL1_kUwe0,52497
15
+ crimson/demo.py,sha256=MqphRCD7dJX092uS2lNRzph3XyEL2ciw8dwnv6p4t9o,54709
16
16
  crimson/demo_trial.py,sha256=BuoKB1DB-cPZ8jBp4x9gmxWF6tvhXMYRqJ9hMYrhxH4,4651
17
17
  crimson/effects.py,sha256=tjOOZopqTI7TTOBREfIUfUhjoa3YqIoFJAPj5oJlW9Y,34056
18
18
  crimson/effects_atlas.py,sha256=Ko1O7z-1jGkH_KSeb8RrR2EtAs4V8vfo70ofhqbFak4,2104
@@ -31,7 +31,7 @@ crimson/frontend/transitions.py,sha256=-sAJUDqNZ943zXlqtvJ6jCg2YH8dSi8k7qK8caAfO
31
31
  crimson/game.py,sha256=6rIXJkYO5FL_z-fDZKTdDfJrb4fkKfWSaaxphUros2c,97712
32
32
  crimson/game_modes.py,sha256=qW7Tt97lSBmGrt0F17Ni5h8vRyngBzyS9XwWM1TFIEI,255
33
33
  crimson/game_world.py,sha256=nfKGcm3LHChPGLHJsurDFAATrHmhRvTmgxcLzUN9m5I,25440
34
- crimson/gameplay.py,sha256=xL1ZKQVRVn_nQ-c7Y_Qj-ggv22Je_By7gX_qbPg0VsY,90027
34
+ crimson/gameplay.py,sha256=qgOyIed8Y_STBuVHOG8mQnI1Ccncm_ddDLY49YFr3TU,90228
35
35
  crimson/input_codes.py,sha256=PmSWFZIit8unTBWk3uwifpHWMuk0qMg1ueKX3MGC7D0,5379
36
36
  crimson/modes/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
37
37
  crimson/modes/base_gameplay_mode.py,sha256=dZwKv6qO0GGVEaUP8fNXNsKdvOko1N-2sQA2U8R2fDA,10092
@@ -61,7 +61,7 @@ crimson/quests/timeline.py,sha256=leK898fPt3zq52v-O6dK4c-wJBcY-E6v-y57Fk3kJ3Q,40
61
61
  crimson/quests/types.py,sha256=iSrz8VSiRZh1pUDSyq37ir7B28c0HF8DjdF6OJ3FoBo,1772
62
62
  crimson/render/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
63
63
  crimson/render/terrain_fx.py,sha256=MpBV6ukGwGqDluIO86BQhHRVWUvcFOi8MV-z_TfLsiw,2705
64
- crimson/render/world_renderer.py,sha256=9Gq2uya5duQAv4ievnqbGjJ2kXSAohVUwC36poDAp8M,88852
64
+ crimson/render/world_renderer.py,sha256=6NCNGJScrULtIQQiHfweBj5y1eEpYttiiuJmXkLM_rY,88655
65
65
  crimson/sim/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
66
66
  crimson/sim/world_defs.py,sha256=HiMl--THnII3BTpt6mWAd20Xu-SRzCyHcs5pCR8aMbU,2195
67
67
  crimson/sim/world_state.py,sha256=h_PPaomj-1KPscPsW3zZ07tVFb3DYPM-FQq3pepMGng,15653
@@ -133,7 +133,7 @@ grim/sfx.py,sha256=cpn2Mmeio7BSDgbStSft-eZchO9Ot2MrK6iXJqxlLqU,7836
133
133
  grim/sfx_map.py,sha256=FM5iBzKkG30Vtu78SRavVNgXMbGK7ZFcQ8i6lgMlzVw,4697
134
134
  grim/terrain_render.py,sha256=EZ7ySYJyTZwXcrJx1mKbY3ewZtPi7Y270XnZgGJyZG8,31509
135
135
  grim/view.py,sha256=oF4pHZehBqOxPjKMU28TDg3qATh_amMIRJp-vMQnpn4,334
136
- crimsonland-0.1.0.dev8.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
137
- crimsonland-0.1.0.dev8.dist-info/entry_points.txt,sha256=jzzcExxiE9xpt4Iw2nbB1lwTv2Zj4H14WJTIPMkAjoE,77
138
- crimsonland-0.1.0.dev8.dist-info/METADATA,sha256=6ALOUljgYCIetA5lP2ivj6868urGHIRlDoTDfMkwoCs,243
139
- crimsonland-0.1.0.dev8.dist-info/RECORD,,
136
+ crimsonland-0.1.0.dev10.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
137
+ crimsonland-0.1.0.dev10.dist-info/entry_points.txt,sha256=jzzcExxiE9xpt4Iw2nbB1lwTv2Zj4H14WJTIPMkAjoE,77
138
+ crimsonland-0.1.0.dev10.dist-info/METADATA,sha256=xNSAt3Nut0XvHvFtZwIJ15spc2KmWrCJFf_jPhxGkkQ,244
139
+ crimsonland-0.1.0.dev10.dist-info/RECORD,,