nightshade 0.8.2

A cross-platform data-oriented game engine.
Documentation
use super::{ComponentInspector, InspectorContext, impl_simple_inspector};
use crate::ecs::navmesh::components::{NavMeshAgent, NavMeshAgentState};
use crate::prelude::*;

fn add_navmesh_agent(world: &mut World, entity: Entity) {
    world.add_components(entity, crate::ecs::world::NAVMESH_AGENT);
    world.set_navmesh_agent(entity, NavMeshAgent::default());
}

fn navmesh_agent_ui(
    world: &mut World,
    entity: Entity,
    ui: &mut egui::Ui,
    _context: &mut InspectorContext,
) {
    if let Some(agent) = world.get_navmesh_agent_mut(entity) {
        ui.label(egui::RichText::new("Properties").strong());

        ui.horizontal(|ui| {
            ui.label("Speed:");
            ui.add(
                egui::DragValue::new(&mut agent.movement_speed)
                    .speed(0.1)
                    .range(0.0..=100.0),
            );
        });

        ui.horizontal(|ui| {
            ui.label("Radius:");
            ui.add(
                egui::DragValue::new(&mut agent.agent_radius)
                    .speed(0.01)
                    .range(0.01..=10.0),
            );
        });

        ui.horizontal(|ui| {
            ui.label("Height:");
            ui.add(
                egui::DragValue::new(&mut agent.agent_height)
                    .speed(0.01)
                    .range(0.01..=10.0),
            );
        });

        ui.horizontal(|ui| {
            ui.label("Arrival Threshold:");
            ui.add(
                egui::DragValue::new(&mut agent.arrival_threshold)
                    .speed(0.01)
                    .range(0.01..=10.0),
            );
        });

        ui.horizontal(|ui| {
            ui.label("Recalc Threshold:");
            ui.add(
                egui::DragValue::new(&mut agent.path_recalculation_threshold)
                    .speed(0.1)
                    .range(0.1..=50.0),
            );
        });

        ui.separator();
        ui.label(egui::RichText::new("Status (read-only)").strong());

        let state_label = match agent.state {
            NavMeshAgentState::Idle => "Idle",
            NavMeshAgentState::PathPending => "Path Pending",
            NavMeshAgentState::Moving => "Moving",
            NavMeshAgentState::Arrived => "Arrived",
            NavMeshAgentState::NoPath => "No Path",
        };
        ui.horizontal(|ui| {
            ui.label("State:");
            ui.label(state_label);
        });

        ui.horizontal(|ui| {
            ui.label("Distance:");
            ui.label(format!("{:.2}", agent.distance_to_destination));
        });

        ui.horizontal(|ui| {
            ui.label("Waypoints:");
            ui.label(format!(
                "{}/{}",
                agent.current_waypoint_index,
                agent.current_path.len()
            ));
        });

        if agent.state != NavMeshAgentState::Idle && ui.button("Clear Destination").clicked() {
            agent.clear_destination();
        }
    }
}

impl_simple_inspector!(
    NavMeshAgentInspector,
    "NavMesh Agent",
    entity_has_navmesh_agent,
    remove_navmesh_agent,
    navmesh_agent_ui,
    custom_add => add_navmesh_agent
);