#pragma once #include "systems/aim.hpp" #include "text/token.hpp" #include "utils/globals.hpp" #include "wall/wall.hpp" namespace Nimbin { static constexpr uint8_t BOUNCED_X = 1 << 0; static constexpr uint8_t BOUNCED_Z = 1 << 1; enum class ProjectileLanding : uint8_t { None, Floor, ProgramInput, Wall, WallText, }; struct Projectile { DynArray words; Vec3 vel{}; Vec3 dir{}; Vec3 prev_centroid{}; Vec3 launch_origin{}; Vec3 aim_point {}; Vec3 track_local {}; Vec3 track_last {}; double yaw; double stick_t = 0.0; double step_dt = 0.0; Text::Token::Data* track_obj = nullptr; bool sticking = false; bool collided = false; bool program_stick = false; uint8_t bounce_state = 0; Wall::Position stick_wall { Wall::Position::PosX }; }; struct WallTextHitTest { Vec3 aabb_Min; Vec3 aabb_Max; size_t index; Wall::Position wall_position; }; struct ProjectileResult { DynArray words; ProjectileLanding landing = ProjectileLanding::None; Vec3 aim_point {}; Vec3 vel {}; size_t wall_text_index = 0; bool use_aim = false; Wall::Position wall_pos = Wall::Position::NegZ; }; struct ProjectileSystem { void launch(DynArray& out, DynArray words, const Vec3& fwd, const Aim::Result& aim); void update(DynArray& projectiles, DynArray& results, const DynArray& wall_text_hits, double dt, bool program_running); }; } // namespace Nimbin