//! Walls, solid barriers that are generally unclimbable. //! //! This interpretation is generally up to the GM to decide, but generally speaking, a wall cannot be //! crossed by a player. If special conditions apply (for instance, when the player wants to scale the //! wall), a check is necessary. If a check is not necessary, then maybe you were not thinking about //! a wall. use super::Mappable; use crate::client::colours::DEFAULT_COLOURS; use crate::client::transform::Transform; use crate::math::Vec2; use crate::world::{Component, Wall}; use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; use std::ops::{Deref, DerefMut}; /// A solid wall a player cannot go through, except if special conditions apply. pub struct WallMark { wall: Wall, selected: bool, round_start: bool, round_end: bool, } impl WallMark { /// Create a new wall from the deserialised data and information known from internal sources. pub fn from_wall(wall: Wall, round_start: bool, round_end: bool) -> Self { Self { wall, selected: false, round_start, round_end, } } /// Set the internal wall of this wall mark. pub fn set_wall(&mut self, wall: Wall) { // XXX: Rounded edges?? self.wall = wall; } /// Get the internal data for serialisation pub fn data(&self) -> &Wall { &self.wall } } fn draw_round_corner( rld: &mut RaylibDrawHandle, pos_px: Vec2, transform: &Transform, selected: bool, ) { rld.draw_circle_v( pos_px, transform.length_m_to_px(0.05) as f32, if selected { DEFAULT_COLOURS.wall_selected } else { DEFAULT_COLOURS.wall_normal }, ); } impl Mappable for WallMark { fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { let start_px = transform.point_m_to_px(&self.wall.shape().start); let end_px = transform.point_m_to_px(&self.wall.shape().end); rld.draw_line_ex( start_px, end_px, transform.length_m_to_px(0.1) as f32, if self.selected() { DEFAULT_COLOURS.wall_selected } else { DEFAULT_COLOURS.wall_normal }, ); if self.round_start { draw_round_corner(rld, start_px, transform, self.selected()); } if self.round_end { draw_round_corner(rld, end_px, transform, self.selected()); } } 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 WallMark { type Target = Wall; fn deref(&self) -> &Self::Target { &self.wall } } impl DerefMut for WallMark { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.wall } }