Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / commits / 3317416

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz

Better merge inbetween words With Claude

Christian Immanuel · 2026-06-06 10:54 · 33174162b5cd190638ebd6773fa4e4458eb41b7d

 src/systems/projectile_system.cpp | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/systems/projectile_system.cpp b/src/systems/projectile_system.cpp
index d59f0a2..89e2509 100644
--- a/src/systems/projectile_system.cpp
+++ b/src/systems/projectile_system.cpp
@@ -160,7 +160,7 @@ static bool
 check_WallTextIntercept(const Projectile& p, const Vec3& centroid, double dt,
                         Wall::Position hit_pos,
                         const DynArray<WallTextHitTest>& wall_text_hits,
-                        double aim_y, bool editor_wall,
+                        double aim_y, double aim_z, bool editor_wall,
                         size_t& out_idx)
 {
     const Vec3 next_centroid {
@@ -179,9 +179,22 @@ check_WallTextIntercept(const Projectile& p, const Vec3& centroid, double dt,
         if (wt.wall_position != hit_pos) continue;
 
         if (editor_wall) {
+            // Vertical row gate (as before): only the aimed row's words.
             const double center_y = (wt.aabb_min.y + wt.aabb_max.y) * 0.5;
             if (SDL_fabs(aim_y - center_y) > ConfigWall::line_height * 0.5)
                 continue;
+
+            // Horizontal: only shoot the word down if the aim lands in its
+            // central 2/3. Outer 1/3 each side is "between words" → merge.
+            const double center_z = (wt.aabb_min.z + wt.aabb_max.z) * 0.5;
+            const double half_z   = (wt.aabb_max.z - wt.aabb_min.z) * 0.5;
+            if (SDL_fabs(aim_z - center_z) > half_z * (2.0 / 3.0))
+                continue;
+
+            // In the central band → shoot it down (no projectile-width inflation
+            // on z, so the gap between words stays a merge zone).
+            out_idx = wt.index;
+            return true;
         }
 
         Vec3 box_min { wt.aabb_min.x - word_he.x,
@@ -324,6 +337,14 @@ editor_AimY(const Projectile& p, double plane_x)
     return p.cam_origin.y + p.dir.y * t;
 }
 
+static double
+editor_AimZ(const Projectile& p, double plane_x)
+{
+    if (SDL_fabs(p.dir.x) <= 1e-6) return Text3d::words_centroid(p.words).z;
+    const double t = (plane_x - p.cam_origin.x) / p.dir.x;
+    return p.cam_origin.z + p.dir.z * t;
+}
+
 
 static bool
 handle_WallHit(Projectile& p, const Vec3& centroid, Wall::Position hit_pos,
@@ -337,15 +358,15 @@ handle_WallHit(Projectile& p, const Vec3& centroid, Wall::Position hit_pos,
         return bounce_OffWall(p, hit_pos, ws, results);
     }
 
-    const bool editor = (Wall::role_of(hit_pos) == Wall::Role::Editor);
-    const double aim_y = editor
-        ? editor_AimY(p, wall_plane_coord(hit_pos, ws))
-        : 0.0;
+    const bool   editor = (Wall::role_of(hit_pos) == Wall::Role::Editor);
+    const double plane  = wall_plane_coord(hit_pos, ws);
+    const double aim_y  = editor ? editor_AimY(p, plane) : 0.0;
+    const double aim_z  = editor ? editor_AimZ(p, plane) : 0.0;
 
     size_t hit_idx = 0;
     if (p.words.size() == 1 &&
             check_WallTextIntercept(p, centroid, dt, hit_pos, wall_text_hits,
-                                    aim_y, editor, hit_idx)) {
+                                    aim_y, aim_z, editor, hit_idx)) {
         ProjectileResult r;
         r.landing         = ProjectileLanding::WallText;
         r.wall_pos        = hit_pos;