diff options
Diffstat (limited to 'src/client/map/room_mark.rs')
| -rw-r--r-- | src/client/map/room_mark.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/client/map/room_mark.rs b/src/client/map/room_mark.rs new file mode 100644 index 0000000..5c0ca98 --- /dev/null +++ b/src/client/map/room_mark.rs @@ -0,0 +1,81 @@ +//! Polygon rooms are the standard rooms in graf karto. They can take the form of anything that a +//! [Polygon](crate::math::Polygon) can have. + +use super::Mappable; +use crate::client::colours::DEFAULT_COLOURS; +use crate::client::transform::Transform; +use crate::client::FLOAT_MARGIN; +use crate::math::{self, Triangle}; +use crate::world::{Component, Room}; +use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; +use std::ops::Deref; + +/// A polygon room, which can be placed and modified in the world. +pub struct RoomMark { + room: Room, + // The polygon shape, but in triangles, so the polygon does not have to be triangulated every frame. + triangulated: Vec<Triangle<f64>>, + selected: bool, +} + +impl RoomMark { + /// Create a room from the given polygon data. + pub fn from_room(room: Room) -> Self { + let shape = room.shape().clone(); + Self { + room, + triangulated: math::triangulate(shape, FLOAT_MARGIN), + selected: false, + } + } + + /// Replace the room this mark describes with the new room. + pub fn set_room(&mut self, room: Room) { + self.room = room; + self.retriangulate(); + } + + /* When the internal polygon changes, it must be retriangulated to be drawn on the screen + * properly, so this function must be called any time that happens. + */ + fn retriangulate(&mut self) { + self.triangulated = math::triangulate(self.room.shape().clone(), FLOAT_MARGIN); + } +} + +impl Mappable for RoomMark { + fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { + for triangle in &self.triangulated { + rld.draw_triangle( + transform.point_m_to_px(&triangle.corners()[0]), + transform.point_m_to_px(&triangle.corners()[1]), + transform.point_m_to_px(&triangle.corners()[2]), + if self.selected() { + DEFAULT_COLOURS.room_selected + } else { + DEFAULT_COLOURS.room_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 RoomMark { + type Target = Room; + + fn deref(&self) -> &Self::Target { + &self.room + } +} |
