aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArne Dußin2021-02-04 21:57:09 +0100
committerArne Dußin2021-02-04 21:57:09 +0100
commitfffdf4a6dd69f16176698f8b42db7dfe2a054e26 (patch)
tree44d3852efbfa781e80cbb422f62607891052e5ac /src
parentf77418497c141f2b12942002756612c5fdbe6f28 (diff)
downloadgraf_karto-net.tar.gz
graf_karto-net.zip
Fix crash when drawing rect with no areanet
Diffstat (limited to 'src')
-rw-r--r--src/client/tool/rect_room_tool.rs37
-rw-r--r--src/math/rect.rs9
2 files changed, 30 insertions, 16 deletions
diff --git a/src/client/tool/rect_room_tool.rs b/src/client/tool/rect_room_tool.rs
index 41f2a91..60bf246 100644
--- a/src/client/tool/rect_room_tool.rs
+++ b/src/client/tool/rect_room_tool.rs
@@ -6,9 +6,11 @@ use super::Tool;
use crate::client::colours::DEFAULT_COLOURS;
use crate::client::map::Map;
use crate::client::transform::Transform;
+use crate::client::FLOAT_MARGIN;
use crate::math::{Rect, Vec2};
use crate::net::{Cargo, Connection};
use crate::world::Room;
+use float_cmp::ApproxEq;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
/// The tool to create simple, rectangular rooms.
@@ -29,6 +31,19 @@ impl RectRoomTool {
}
}
+/* Try to create a rectangle from the given points, but only if they don't create
+ * a rectangle with no area.
+ */
+fn try_into_bounding_rect(pos1: Vec2<f64>, pos2: Vec2<f64>) -> Option<Rect<f64>> {
+ let bounding_rect = Rect::bounding_rect(pos1, pos2);
+
+ if !bounding_rect.area().approx_eq(0., FLOAT_MARGIN) {
+ Some(bounding_rect)
+ } else {
+ None
+ }
+}
+
impl Tool for RectRoomTool {
fn deactivate(&mut self) {
self.unfinished_rect = None;
@@ -57,15 +72,10 @@ impl Tool for RectRoomTool {
) {
// Try to finish the rectangle if it has been started.
if let Some((pos1, pos2)) = self.unfinished_rect {
- if pos1 == pos2 {
- warn!("Cannot place rectangle with start and endpoint being the same");
- return;
+ if let Some(rect) = try_into_bounding_rect(pos1, pos2) {
+ server.send(Cargo::AddRoom(Room::new(rect.into())));
+ self.unfinished_rect = None;
}
-
- server.send(Cargo::AddRoom(Room::new(
- Rect::bounding_rect(pos1, pos2).into(),
- )));
- self.unfinished_rect = None;
} else {
self.unfinished_rect = Some((*mouse_pos_m, *mouse_pos_m));
}
@@ -73,15 +83,10 @@ impl Tool for RectRoomTool {
fn finish(&mut self, _map: &mut Map, server: &Connection<Cargo>) {
if let Some((pos1, pos2)) = self.unfinished_rect {
- if pos1 == pos2 {
- warn!("Cannot place rectangle with start and endpoint being the same");
- return;
+ if let Some(rect) = try_into_bounding_rect(pos1, pos2) {
+ server.send(Cargo::AddRoom(Room::new(rect.into())));
+ self.unfinished_rect = None;
}
-
- server.send(Cargo::AddRoom(Room::new(
- Rect::bounding_rect(pos1, pos2).into(),
- )));
- self.unfinished_rect = None;
}
}
diff --git a/src/math/rect.rs b/src/math/rect.rs
index a8326bc..288c19d 100644
--- a/src/math/rect.rs
+++ b/src/math/rect.rs
@@ -3,6 +3,7 @@
use super::{ExactSurface, LineSegment, Polygon, Vec2};
//use alga::general::{Additive, Identity};
use nalgebra::{RealField, Scalar};
+use num_traits::sign::{self, Signed};
use num_traits::{NumCast, ToPrimitive, Zero};
use serde::{Deserialize, Serialize};
use std::ops::{Add, AddAssign, Sub};
@@ -147,6 +148,14 @@ impl<T: Scalar + Copy> Rect<T> {
Vec2::new(T::zero(), move_y)
}
}
+
+ /// Calculate the area of the rectangle.
+ pub fn area(&self) -> T
+ where
+ T: Signed,
+ {
+ sign::abs(self.w) * sign::abs(self.h)
+ }
}
impl<T: Scalar + Copy> ExactSurface<T> for Rect<T>