Refactor power connection to work with different electric poles

This commit is contained in:
hal8174 2025-03-05 18:35:52 +01:00
parent b4ab291884
commit 642f815f9d
8 changed files with 394 additions and 144 deletions

View file

@ -1,12 +1,16 @@
use factorio_core::{
aabb::AABB,
beltoptions::Beltspeed,
misc::PositionMap,
pathfield::PathField,
prelude::*,
quaterdirection::QuaterDirection,
visualize::{Color, Visualization},
};
use std::{collections::HashMap, sync::atomic::AtomicUsize};
use std::{
collections::{HashMap, HashSet},
sync::atomic::AtomicUsize,
};
use crate::{BlueprintEntity, BlueprintPosition};
@ -68,6 +72,13 @@ impl ElectricPoleType {
ElectricPoleType::Big | ElectricPoleType::Substation => Position::new(4, 4),
}
}
fn alignment(&self) -> PositionType {
match self {
ElectricPoleType::Small | ElectricPoleType::Medium => 1,
ElectricPoleType::Big | ElectricPoleType::Substation => 0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -359,12 +370,13 @@ impl Entity {
let halve_size = self.size() / 2;
match self.direction {
DirectionType::Dir(direction) => match direction {
Direction::Up | Direction::Down => {
AABB::new(self.position - halve_size, self.position + halve_size)
}
Direction::Up | Direction::Down => AABB::new(
self.position - halve_size,
self.position + halve_size - Position::new(1, 1),
),
Direction::Right | Direction::Left => AABB::new(
self.position - Position::new(halve_size.y, halve_size.x),
self.position + Position::new(halve_size.y, halve_size.x),
self.position + Position::new(halve_size.y, halve_size.x) - Position::new(1, 1),
),
},
DirectionType::QuarterDir(_) => {
@ -415,7 +427,7 @@ impl Entity {
None,
),
ElectricPoleType::Big => {
for (dx, dy) in [(-1, -1), (1, -1), (-1, 1), (1, 1)] {
for (dx, dy) in [(-2, -2), (0, -2), (-2, 0), (0, 0)] {
v.add_symbol(
(self.position + Position::new(dx, dy)) / 2 + offset,
factorio_core::visualize::Symbol::Char('l'),
@ -588,6 +600,51 @@ impl Blueprint {
.reduce(|a, b| a.combine(b))
.unwrap()
}
pub fn placeable(&self, pos: Position, size: Position) -> bool {
let aabb = AABB::new(pos - size / 2, pos + size / 2 - Position::new(1, 1));
!self
.entities
.iter()
.any(|(_, e)| AABB::collision(e.get_aabb(), aabb))
}
pub fn placibility_map(&self) -> Placibility {
let mut blocked = PositionMap::new(self.get_aabb().unwrap(), &false);
// dbg!(self.get_aabb(), self.get_aabb().unwrap().size());
for (_, e) in self.entities.iter() {
let aabb = e.get_aabb();
for y in aabb.min().y..=aabb.max().y {
for x in aabb.min().x..=aabb.max().x {
blocked[Position::new(x, y)] = true;
}
}
}
Placibility { blocked }
}
}
#[derive(Debug)]
struct Placibility {
blocked: PositionMap<bool>,
}
impl Placibility {
pub fn placeable(&self, pos: Position, size: Position) -> bool {
let aabb = AABB::new(pos - size / 2, pos + size / 2 - Position::new(1, 1));
for y in aabb.min().y..=aabb.max().y {
for x in aabb.min().x..=aabb.max().x {
if !self.blocked.get_aabb().contains_pos(Position::new(x, y))
|| self.blocked[Position::new(x, y)] == true
{
return false;
}
}
}
true
}
}
impl Default for Blueprint {