//! Icon marker on the map. For information about icons see [Icon](crate::) use super::icon_texture_manager::IconTextureManager; use crate::client::colours::DEFAULT_COLOURS; use crate::client::map::Mappable; use crate::client::transform::Transform; use crate::math::Vec2; use crate::world::{Component, Icon}; use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle}; use std::ops::{Deref, DerefMut}; use std::rc::Rc; /// Describes an icon in the world and can be drawn. #[derive(Clone)] pub struct IconMark { icon: Icon, selected: bool, textures: Rc, } impl IconMark { /// Create a new icon marker. Requires the icon textures that are used to render this icon, as well as all /// the information necessary to describe the icon itself. pub fn new( id: usize, position: Vec2, rotation: f64, renderer: Rc, ) -> Self { Self::from_icon( Icon { id, position, rotation, }, renderer, ) } /// Like `new()`, but with the icon data bundled into the icon type. pub fn from_icon(icon: Icon, textures: Rc) -> Self { Self { icon, selected: false, textures, } } } impl Mappable for IconMark { fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { let (texture, info) = self.textures.get(self.id); // Round the position to whole pixels to fix rotation problems. let mut position_px = transform.point_m_to_px(&(self.position - (info.anchor / info.pixels_per_m))); position_px.x = position_px.x.floor(); position_px.y = position_px.y.floor(); rld.draw_texture_ex( texture, position_px, self.rotation as f32, (transform.pixels_per_m() / info.pixels_per_m) as f32, if self.selected() { DEFAULT_COLOURS.icon_selected } else { DEFAULT_COLOURS.icon_normal }, ); } fn set_selected(&mut self, selected: bool) { self.selected = selected; } fn selected(&self) -> bool { self.selected } fn as_component(&self) -> &dyn Component { self.deref() } } impl Deref for IconMark { type Target = Icon; fn deref(&self) -> &Self::Target { &self.icon } } impl DerefMut for IconMark { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.icon } }