// -*- coding: utf-8 -*- // // Copyright 2021 Michael Büsch // // Derived from https://github.com/mlochen/dungeon.git // Copyright (C) 2020 Marco Lochen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // use crate::player::Player; use crate::vec2d::Vec2D; use crate::world::World; pub struct Wall { dir: Vec2D, pos: Vec2D, p1: Vec2D, p2: Vec2D, } impl Wall { pub fn new(dir: Vec2D, pos: Vec2D) -> Wall { let p1 = pos - (dir * 0.5); let p2 = pos + (dir * 0.5); Wall { dir, pos, p1, p2 } } #[inline] pub fn get_dir(&self) -> Vec2D { self.dir } #[inline] pub fn get_pos(&self) -> Vec2D { self.pos } #[inline] pub fn get_p1(&self) -> Vec2D { self.p1 } #[inline] pub fn get_p2(&self) -> Vec2D { self.p2 } } pub struct VisibleWallsIter<'a> { world: &'a World, player: &'a Player, index: usize, } impl<'a> VisibleWallsIter<'a> { pub fn new(world: &'a World, player: &'a Player) -> VisibleWallsIter<'a> { VisibleWallsIter { world, player, index: 0, } } pub fn sorted_by_distance(&mut self, ascending: bool) -> Vec<&'a Wall> { let player_pos = self.player.get_pos(); let mut walls: Vec<&Wall> = self.collect(); walls.sort_unstable_by(|a, b| { let alen = (player_pos - a.get_pos()).len(); let blen = (player_pos - b.get_pos()).len(); if ascending { alen.partial_cmp(&blen).unwrap() } else { blen.partial_cmp(&alen).unwrap() } }); walls } } impl<'a> Iterator for VisibleWallsIter<'a> { type Item = &'a Wall; fn next(&mut self) -> Option { let walls = self.world.get_walls(); while self.index < walls.len() { let wall = &walls[self.index]; self.index += 1; if self.player.wall_is_in_fov(wall) { return Some(wall); } } None } } // vim: ts=4 sw=4 expandtab