sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
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.gzBetter merge inbetween words With Claude
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;