termcraft 0.1.0

Terminal-based 2D sandbox survival game
Documentation
pub struct Villager {
    pub x: f64,
    pub y: f64,
    pub vx: f64,
    pub vy: f64,
    pub grounded: bool,
    pub facing_right: bool,
    pub jump_cooldown: u8,
    pub wander_timer: u16,
    pub age: u64,
    pub health: f32,
    pub hit_timer: u8,
    pub last_player_damage_tick: u64,
    pub home_x: i32,
    pub home_y: i32,
}

impl Villager {
    pub fn new(x: f64, y: f64, home_x: i32, home_y: i32) -> Self {
        Self {
            x,
            y,
            vx: 0.0,
            vy: 0.0,
            grounded: false,
            facing_right: true,
            jump_cooldown: 0,
            wander_timer: 0,
            age: 0,
            health: 20.0,
            hit_timer: 0,
            last_player_damage_tick: 0,
            home_x,
            home_y,
        }
    }

    pub fn set_home(&mut self, home_x: i32, home_y: i32) {
        self.home_x = home_x;
        self.home_y = home_y;
    }

    pub fn jump(&mut self) {
        if self.grounded && self.jump_cooldown == 0 {
            self.vy = -0.56;
            self.grounded = false;
            self.jump_cooldown = 10;
        }
    }

    pub fn walk(&mut self, direction: f64) {
        self.vx = direction;
        if direction > 0.0 {
            self.facing_right = true;
        } else if direction < 0.0 {
            self.facing_right = false;
        }
    }

    pub fn update_ai(&mut self, is_day: bool) {
        use rand::Rng;

        if self.jump_cooldown > 0 {
            self.jump_cooldown -= 1;
        }

        let mut rng = rand::thread_rng();
        let home_target_x = self.home_x as f64 + 0.5;
        let home_dx = home_target_x - self.x;

        if is_day {
            if home_dx.abs() > 10.0 {
                self.walk(home_dx.signum() * 0.12);
                self.wander_timer = 16;
            } else if self.wander_timer > 0 {
                self.wander_timer -= 1;
                let home_bias = (home_dx * 0.035).clamp(-0.03, 0.03);
                let base = if self.facing_right { 0.1 } else { -0.1 };
                self.walk(base + home_bias);
            } else {
                let roll = rng.gen_range(0..100);
                if roll < 58 {
                    self.wander_timer = rng.gen_range(16..82);
                    self.facing_right = rng.gen_bool(0.5);
                    let base = if self.facing_right { 0.1 } else { -0.1 };
                    self.walk(base);
                } else {
                    self.vx = 0.0;
                }
            }
        } else if home_dx.abs() > 0.9 {
            self.wander_timer = 0;
            self.walk(home_dx.signum() * 0.12);
        } else {
            self.wander_timer = 0;
            self.vx = 0.0;
        }
    }
}