use crate::*;
impl TileFlags {
pub fn flip_x(&mut self) {
match self.contains(TileFlags::ROTATE) {
false => self.toggle(TileFlags::FLIP_X),
true => self.toggle(TileFlags::FLIP_Y),
}
}
pub fn flip_y(&mut self) {
match self.contains(TileFlags::ROTATE) {
false => self.toggle(TileFlags::FLIP_Y),
true => self.toggle(TileFlags::FLIP_X),
}
}
pub fn rotate_cw(&mut self) {
if self.contains(TileFlags::ROTATE) {
self.toggle(TileFlags::FLIP_Y | TileFlags::FLIP_X);
}
self.toggle(TileFlags::ROTATE);
}
pub fn rotate_ccw(&mut self) {
if !self.contains(TileFlags::ROTATE) {
self.toggle(TileFlags::FLIP_Y | TileFlags::FLIP_X);
}
self.toggle(TileFlags::ROTATE);
}
pub fn flip_x_physics(&mut self) {
if self.contains(TileFlags::ROTATE) {
self.toggle(TileFlags::FLIP_Y | TileFlags::FLIP_X);
}
}
pub fn flip_y_physics(&mut self) {
if !self.contains(TileFlags::ROTATE) {
self.toggle(TileFlags::FLIP_Y | TileFlags::FLIP_X);
}
}
}
trait TilePrivate {
fn mirror_id(id: u8) -> u8 {
id
}
fn directional_physics_tile(_id: u8) -> bool {
false
}
}
impl TilePrivate for Tile {}
fn mirror_lasers(mut id: u8) -> u8 {
if (203..=205).contains(&id) {
id += (206 - id) * 2;
} else if (207..=209).contains(&id) {
id -= (id - 206) * 2;
}
id
}
impl TilePrivate for GameTile {
fn mirror_id(id: u8) -> u8 {
mirror_lasers(id)
}
fn directional_physics_tile(id: u8) -> bool {
matches!(id, 60 | 61 | 64 | 65 | 67 | 224 | 225)
}
}
impl TilePrivate for Tele {}
impl TilePrivate for Switch {
fn mirror_id(id: u8) -> u8 {
mirror_lasers(id)
}
fn directional_physics_tile(id: u8) -> bool {
matches!(id, 224 | 225)
}
}
impl TilePrivate for Tune {}
pub trait TileFlips: AnyTile {
fn flip_x(&mut self);
fn flip_y(&mut self);
fn rotate_cw(&mut self);
fn rotate_ccw(&mut self);
}
impl<T: AnyTile + TilePrivate> TileFlips for T {
fn flip_x(&mut self) {
let id = self.id();
if let Some(flags) = self.flags_mut() {
if T::directional_physics_tile(id) {
flags.flip_x_physics();
} else {
flags.flip_x();
}
*self.id_mut() = T::mirror_id(*self.id_mut());
}
}
fn flip_y(&mut self) {
let id = self.id();
if let Some(flags) = self.flags_mut() {
if T::directional_physics_tile(id) {
flags.flip_y_physics();
} else {
flags.flip_y();
}
*self.id_mut() = T::mirror_id(*self.id_mut());
}
}
fn rotate_cw(&mut self) {
if let Some(flags) = self.flags_mut() {
flags.rotate_cw();
}
}
fn rotate_ccw(&mut self) {
if let Some(flags) = self.flags_mut() {
flags.rotate_ccw();
}
}
}
impl TileFlips for Speedup {
fn flip_x(&mut self) {
let mut angle = i16::from(self.angle);
angle = 180 - angle;
if angle < 0 {
angle += 360;
}
self.angle = angle.into();
}
fn flip_y(&mut self) {
let mut angle = i16::from(self.angle);
angle = 180 - angle;
angle *= -1;
angle = 180 - angle;
angle %= 360;
self.angle = angle.into();
}
fn rotate_cw(&mut self) {
let mut angle = i16::from(self.angle);
angle += 90;
angle %= 360;
self.angle = angle.into();
}
fn rotate_ccw(&mut self) {
let mut angle = i16::from(self.angle);
angle += 270;
angle %= 360;
self.angle = angle.into();
}
}