fix: prevent integer underflows in Land::derelativize

This commit is contained in:
Nat 2024-12-04 14:40:07 -08:00
parent dee8a15a7a
commit 5bc8a39543
1 changed files with 22 additions and 2 deletions

View File

@ -16,8 +16,28 @@ impl Land {
(x % self.width, y % self.height)
}
pub fn derelativize(&self, tree: &Tree, relative_x: u16, relative_y: u16) -> (u16, u16) {
((tree.position.0 + relative_x) % self.width, (tree.position.1 + relative_y) % self.height)
pub fn derelativize(&self, position: (u16, u16), relative_x: i16, relative_y: i16) -> (u16, u16) {
// Note: we don't need to worry about integer overflows directly
// because land itself cannot exceed integer limits in size and
// so that check's implicitly handled with the modulo operator.
// Underflows are a bit trickier to catch, though
let absolute_x = if relative_x < 0 && position.0 - relative_x.unsigned_abs() > position.0 {
(self.width - (relative_x.unsigned_abs() - position.0)) % self.width
} else if relative_x < 0 {
(position.0 - relative_x.unsigned_abs()) % self.height
} else {
(position.0 + relative_x.unsigned_abs()) % self.height
};
let absolute_y = if relative_y < 0 && position.1 - relative_y.unsigned_abs() > position.1 {
(self.height - (relative_y.unsigned_abs() - position.1)) % self.height
} else if relative_x < 0 {
(position.1 - relative_y.unsigned_abs()) % self.height
} else {
(position.1 + relative_y.unsigned_abs()) % self.height
};
return (absolute_x, absolute_y);
}
pub fn sow(&mut self, x: u16, y: u16, value: u16) {