|
|
|
@ -144,17 +144,7 @@ where
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn tile_on_same_axis(&self, pos: (i32, i32)) -> bool { |
|
|
|
|
if self.dir.is_x_dir() { |
|
|
|
|
if pos.1 != self.front_tile.1 { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if pos.0 != self.front_tile.0 { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
true |
|
|
|
|
self.dir.is_on_same_axis(pos, self.front_tile) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn extend_to(&mut self, tile_pos: (i32, i32)) -> bool { |
|
|
|
@ -247,13 +237,42 @@ where
|
|
|
|
|
true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn iter<F: FnMut((i32, i32), Entity)>(&self, f: &mut F) { |
|
|
|
|
pub fn iter_all<F: FnMut((i32, i32), Entity)>(&self, f: &mut F) { |
|
|
|
|
self.t.iter(|pos, _free, entity| { |
|
|
|
|
let pos = self.dir.offs2pos(self.t_origin, pos); |
|
|
|
|
f(pos, entity); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn iter_visible<F: FnMut((i32, i32), Entity)>(&self, f: &mut F) { |
|
|
|
|
match self.typ { |
|
|
|
|
BeltType::Basic => { |
|
|
|
|
self.t.iter(|pos, _free, entity| { |
|
|
|
|
let pos = self.dir.offs2pos(self.t_origin, pos); |
|
|
|
|
f(pos, entity); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
BeltType::Underground => { |
|
|
|
|
let front = self.front_tile(); |
|
|
|
|
let back = self.back_tile(); |
|
|
|
|
let front_a = self.dir.tile_front_px(front); |
|
|
|
|
let front_b = self.dir.tile_front_px_offs(front, -(BELT_TILE_SIZE_PX / 2)); |
|
|
|
|
|
|
|
|
|
let back_a = self.dir.tile_front_px_offs(back, -(BELT_TILE_SIZE_PX / 2)); |
|
|
|
|
let back_b = self.dir.tile_back_px(back); |
|
|
|
|
|
|
|
|
|
self.t.iter(|pos, _free, entity| { |
|
|
|
|
let pos = self.dir.offs2pos(self.t_origin, pos); |
|
|
|
|
if self.dir.pos_in_axis_range(front_a, front_b, pos) { |
|
|
|
|
f(pos, entity); |
|
|
|
|
} else if self.dir.pos_in_axis_range(back_a, back_b, pos) { |
|
|
|
|
f(pos, entity); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn iter_tiles<F: FnMut(Dir, (i32, i32))>(&self, f: &mut F) { |
|
|
|
|
if self.t.length() == 0 { |
|
|
|
|
return; |
|
|
|
@ -525,7 +544,14 @@ where
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn remove_belt_at_tile(&mut self, tile_pos: (i32, i32)) -> Option<Vec<Entity>> { |
|
|
|
|
let belt_id = self.get_belt_at_tile(tile_pos).map(|b| b.id())?; |
|
|
|
|
let belt_id = { |
|
|
|
|
let belt = self.get_belt_at_tile(tile_pos)?; |
|
|
|
|
if !belt.is_basic_belt() { |
|
|
|
|
return None; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
belt.id() |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let mut belt = self.unmount_belt(belt_id)?; |
|
|
|
|
|
|
|
|
@ -564,9 +590,18 @@ where
|
|
|
|
|
|
|
|
|
|
fn unmount_belt(&mut self, belt_id: u64) -> Option<Belt<Entity>> { |
|
|
|
|
let belt = self.belts.remove(&belt_id)?; |
|
|
|
|
belt.iter_tiles(&mut |_, tile_pos| { |
|
|
|
|
self.pos2id.remove(&tile_pos); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
match belt.belt_type() { |
|
|
|
|
BeltType::Basic => { |
|
|
|
|
belt.iter_tiles(&mut |_, tile_pos| { |
|
|
|
|
self.pos2id.remove(&tile_pos); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
BeltType::Underground => { |
|
|
|
|
self.pos2id.insert(belt.front_tile(), belt_id); |
|
|
|
|
self.pos2id.insert(belt.back_tile(), belt_id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Some(belt) |
|
|
|
|
} |
|
|
|
@ -576,9 +611,25 @@ where
|
|
|
|
|
self.next_id += 1; |
|
|
|
|
belt.update_id(belt_id); |
|
|
|
|
|
|
|
|
|
belt.iter_tiles(&mut |_, tile_pos| { |
|
|
|
|
self.pos2id.insert(tile_pos, belt_id); |
|
|
|
|
}); |
|
|
|
|
match belt.belt_type() { |
|
|
|
|
BeltType::Basic => { |
|
|
|
|
belt.iter_tiles(&mut |_, tile_pos| { |
|
|
|
|
self.pos2id.insert(tile_pos, belt_id); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
BeltType::Underground => { |
|
|
|
|
println!( |
|
|
|
|
"MOUNT UNDERGR BELT: {:?} {:?} {:?} => {:?}", |
|
|
|
|
belt_id, |
|
|
|
|
belt.dir(), |
|
|
|
|
belt.front_tile(), |
|
|
|
|
belt.back_tile() |
|
|
|
|
); |
|
|
|
|
self.pos2id.insert(belt.front_tile(), belt_id); |
|
|
|
|
self.pos2id.insert(belt.back_tile(), belt_id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.belts.insert(belt_id, belt); |
|
|
|
|
belt_id |
|
|
|
|
} |
|
|
|
@ -644,13 +695,30 @@ where
|
|
|
|
|
|
|
|
|
|
pub fn iter_tiles<F: FnMut(Dir, (i32, i32))>(&self, mut f: F) { |
|
|
|
|
for (_, belt) in self.belts.iter() { |
|
|
|
|
belt.iter_tiles(&mut f); |
|
|
|
|
match belt.belt_type() { |
|
|
|
|
BeltType::Basic => { |
|
|
|
|
belt.iter_tiles(&mut f); |
|
|
|
|
} |
|
|
|
|
BeltType::Underground => { |
|
|
|
|
f(belt.dir(), belt.front_tile()); |
|
|
|
|
f(belt.dir(), belt.back_tile()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn iter_underground_tiles<F: FnMut(Dir, bool, (i32, i32))>(&self, mut f: F) { |
|
|
|
|
for (_, belt) in self.belts.iter() { |
|
|
|
|
if belt.belt_type() == BeltType::Underground { |
|
|
|
|
f(belt.dir(), true, belt.back_tile()); |
|
|
|
|
f(belt.dir(), false, belt.front_tile()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn iter<F: FnMut((i32, i32), Entity)>(&self, mut f: F) { |
|
|
|
|
for (_, belt) in self.belts.iter() { |
|
|
|
|
belt.iter(&mut f); |
|
|
|
|
belt.iter_visible(&mut f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -727,6 +795,27 @@ where
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn insert_underground_from_to( |
|
|
|
|
&mut self, |
|
|
|
|
from_tile_pos: (i32, i32), |
|
|
|
|
to_tile_pos: (i32, i32), |
|
|
|
|
) -> u64 { |
|
|
|
|
let dir = Dir::from_poses(from_tile_pos, to_tile_pos); |
|
|
|
|
if !dir.is_on_same_axis(from_tile_pos, to_tile_pos) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let length = dir.diff(from_tile_pos, to_tile_pos).abs(); |
|
|
|
|
|
|
|
|
|
let mut belt = Belt::new(0, dir); |
|
|
|
|
belt.extend(1); |
|
|
|
|
belt.set_type(BeltType::Underground); |
|
|
|
|
belt.set_front(from_tile_pos); |
|
|
|
|
belt.extend_to(to_tile_pos); |
|
|
|
|
|
|
|
|
|
self.mount_belt(belt) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn insert_belt_at_tile(&mut self, tile_pos: (i32, i32), dir: Dir) -> u64 { |
|
|
|
|
let pos = ( |
|
|
|
|
tile_pos.0 * BELT_TILE_SIZE_PX, |
|
|
|
@ -866,7 +955,7 @@ mod test {
|
|
|
|
|
|
|
|
|
|
fn e_ents(b: &Belt<Chem>) -> Vec<(i32, i32, Chem)> { |
|
|
|
|
let mut v2 = vec![]; |
|
|
|
|
b.iter(&mut |pos, ent| { |
|
|
|
|
b.iter_visible(&mut |pos, ent| { |
|
|
|
|
v2.push((pos.0, pos.1, ent)); |
|
|
|
|
}); |
|
|
|
|
v2 |
|
|
|
@ -2794,4 +2883,39 @@ mod test {
|
|
|
|
|
// assert!(b.probe_insert(&mut ph, Chem::H2O));
|
|
|
|
|
// assert_eq!(ents(&b), vec![(-1, 0, Chem::Fe2O3), (15, 0, Chem::H2O)]);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_build() { |
|
|
|
|
// TODO: Check if building across straight belts works properly in all directions.
|
|
|
|
|
// Also perpendicular and in line!
|
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_visible_items() { |
|
|
|
|
// TODO: Check if the first and last halfs are visible only
|
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_visible_tiles() { |
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_remove() { |
|
|
|
|
// TODO: check if it is removed cleanly
|
|
|
|
|
// TODO: check if removing adjacent normal belts does not break it
|
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_move_onto_no_jump() { |
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn check_belts_under_move_off_no_jump() { |
|
|
|
|
assert!(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|