2023-05-08 18:56:50 +00:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
use engine::prelude::{
|
2023-05-09 14:39:53 +00:00
|
|
|
cgmath::{vec2, vec3, Vector2, Vector3},
|
2023-05-08 18:56:50 +00:00
|
|
|
*,
|
|
|
|
};
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
use crate::{game::MillGame, objects::Objects};
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
|
|
|
pub struct BoardSlot {
|
|
|
|
pub state: BoardSlotState,
|
|
|
|
pub position: Vector2<f32>,
|
|
|
|
pub slot_marker: Option<Entity>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BoardSlot {
|
|
|
|
pub const SLOT_MARKER_SIZE: f32 = 1.5;
|
|
|
|
|
|
|
|
pub fn new(position: Vector2<f32>, scene: &mut Scene) -> Result<Self> {
|
|
|
|
let mut marker = scene.engine().assets().empty_entity();
|
|
|
|
|
|
|
|
let meshes = vec![Self::create_mesh(&scene.engine(), Color::Black)?];
|
|
|
|
|
|
|
|
let draw = Draw::new(meshes);
|
|
|
|
marker.insert_component(draw);
|
|
|
|
|
|
|
|
let mut location = Location::from_entity(&mut marker);
|
|
|
|
location.set_position(position.extend(MillGame::OFFSET_TO_BOARD));
|
|
|
|
marker.insert_component(location);
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
state: BoardSlotState::default(),
|
|
|
|
position,
|
|
|
|
slot_marker: Some(scene.add_entity(marker)?),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn invalid() -> Self {
|
|
|
|
Self {
|
|
|
|
state: BoardSlotState::Invalid,
|
|
|
|
position: vec2(0.0, 0.0),
|
|
|
|
slot_marker: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_mesh(engine: &Arc<Engine>, color: Color) -> Result<AssetMesh> {
|
|
|
|
let mut mesh = AssetMesh::new(
|
|
|
|
engine.device(),
|
|
|
|
engine.settings().graphics_info()?.render_type,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let vertex_buffer = Buffer::builder()
|
|
|
|
.set_data(&Objects::create_flat_quad([
|
|
|
|
vec2(-Self::SLOT_MARKER_SIZE * 0.5, -Self::SLOT_MARKER_SIZE * 0.5),
|
|
|
|
vec2(Self::SLOT_MARKER_SIZE * 0.5, -Self::SLOT_MARKER_SIZE * 0.5),
|
|
|
|
vec2(Self::SLOT_MARKER_SIZE * 0.5, Self::SLOT_MARKER_SIZE * 0.5),
|
|
|
|
vec2(-Self::SLOT_MARKER_SIZE * 0.5, Self::SLOT_MARKER_SIZE * 0.5),
|
|
|
|
]))
|
|
|
|
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
|
|
|
.set_memory_usage(MemoryUsage::CpuOnly)
|
|
|
|
.build(engine.device().clone())?;
|
|
|
|
|
|
|
|
let a: [f32; 3] = color.into();
|
|
|
|
|
|
|
|
mesh.add_primitive(
|
|
|
|
vertex_buffer,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
PrimitiveMaterial {
|
|
|
|
color: [a[0], a[1], a[2], 1.0],
|
|
|
|
metallic_factor: 0.2,
|
|
|
|
emissive_factor: [0.2, 0.2, 0.2],
|
|
|
|
roughness_factor: 0.8,
|
|
|
|
alpha_mode: AlphaMode::Opaque,
|
|
|
|
alpha_cut_off: 0.5,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(mesh)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
|
|
pub enum BoardSlotState {
|
|
|
|
Invalid,
|
|
|
|
Empty,
|
|
|
|
Black(Entity),
|
|
|
|
White(Entity),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for BoardSlotState {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::Empty
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-08 18:56:50 +00:00
|
|
|
pub struct Board {
|
2023-05-09 16:58:07 +00:00
|
|
|
_board: Entity,
|
2023-05-09 14:39:53 +00:00
|
|
|
center: Vector3<f32>,
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
_connection_lines: Vec<Entity>,
|
2023-05-09 14:39:53 +00:00
|
|
|
|
|
|
|
slots: [[[BoardSlot; 3]; 3]; 3],
|
|
|
|
white_start_slots: [Vector2<f32>; 9],
|
|
|
|
black_start_slots: [Vector2<f32>; 9],
|
2023-05-08 18:56:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Board {
|
2023-05-09 16:58:07 +00:00
|
|
|
pub fn new(engine: &Arc<Engine>, scene: &mut SceneHandle) -> Result<Self> {
|
2023-05-08 18:56:50 +00:00
|
|
|
let mut board_entity = engine.assets().empty_entity();
|
|
|
|
|
|
|
|
let meshes = vec![Self::create_board_base(&engine)?];
|
|
|
|
|
|
|
|
let draw = Draw::new(meshes);
|
|
|
|
board_entity.insert_component(draw);
|
|
|
|
|
|
|
|
let location = Location::from_entity(&mut board_entity);
|
|
|
|
board_entity.insert_component(location);
|
|
|
|
|
|
|
|
let mut board = None;
|
2023-05-09 14:39:53 +00:00
|
|
|
let mut slots = None;
|
|
|
|
|
2023-05-08 18:56:50 +00:00
|
|
|
scene.on_scene(|scene| {
|
|
|
|
board = Some(scene.add_entity(board_entity)?);
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
slots = Some([
|
|
|
|
[
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(-15.0, -15.0), scene)?, // 0 0 0
|
|
|
|
BoardSlot::new(vec2(-10.0, -10.0), scene)?, // 0 0 1
|
|
|
|
BoardSlot::new(vec2(-5.0, -5.0), scene)?, // 0 0 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(-15.0, 0.0), scene)?, // 0 1 0
|
|
|
|
BoardSlot::new(vec2(-10.0, 0.0), scene)?, // 0 1 1
|
|
|
|
BoardSlot::new(vec2(-5.0, 0.0), scene)?, // 0 1 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(-15.0, 15.0), scene)?, // 0 2 0
|
|
|
|
BoardSlot::new(vec2(-10.0, 10.0), scene)?, // 0 2 1
|
|
|
|
BoardSlot::new(vec2(-5.0, 5.0), scene)?, // 0 2 2
|
|
|
|
],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(0.0, -15.0), scene)?, // 1 0 0
|
|
|
|
BoardSlot::new(vec2(0.0, -10.0), scene)?, // 1 0 1
|
|
|
|
BoardSlot::new(vec2(0.0, -5.0), scene)?, // 1 0 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::invalid(), // 1 1 0
|
|
|
|
BoardSlot::invalid(), // 1 1 1
|
|
|
|
BoardSlot::invalid(), // 1 1 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(0.0, 15.0), scene)?, // 1 2 0
|
|
|
|
BoardSlot::new(vec2(0.0, 10.0), scene)?, // 1 2 1
|
|
|
|
BoardSlot::new(vec2(0.0, 5.0), scene)?, // 1 2 2
|
|
|
|
],
|
|
|
|
],
|
|
|
|
[
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(15.0, -15.0), scene)?, // 2 0 0
|
|
|
|
BoardSlot::new(vec2(10.0, -10.0), scene)?, // 2 0 1
|
|
|
|
BoardSlot::new(vec2(5.0, -5.0), scene)?, // 2 0 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(15.0, 0.0), scene)?, // 2 1 0
|
|
|
|
BoardSlot::new(vec2(10.0, 0.0), scene)?, // 2 1 1
|
|
|
|
BoardSlot::new(vec2(5.0, 0.0), scene)?, // 2 1 2
|
|
|
|
],
|
|
|
|
[
|
|
|
|
BoardSlot::new(vec2(15.0, 15.0), scene)?, // 2 2 0
|
|
|
|
BoardSlot::new(vec2(10.0, 10.0), scene)?, // 2 2 1
|
|
|
|
BoardSlot::new(vec2(5.0, 5.0), scene)?, // 2 2 2
|
|
|
|
],
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
2023-05-08 18:56:50 +00:00
|
|
|
Ok(())
|
|
|
|
})?;
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
let distance = 20.0;
|
|
|
|
|
|
|
|
let white_start_slots = [
|
|
|
|
vec2(-16.0, distance),
|
|
|
|
vec2(-12.0, distance),
|
|
|
|
vec2(-8.0, distance),
|
|
|
|
vec2(-4.0, distance),
|
|
|
|
vec2(0.0, distance),
|
|
|
|
vec2(4.0, distance),
|
|
|
|
vec2(8.0, distance),
|
|
|
|
vec2(12.0, distance),
|
|
|
|
vec2(16.0, distance),
|
|
|
|
];
|
|
|
|
|
|
|
|
let black_start_slots = [
|
|
|
|
vec2(-16.0, -distance),
|
|
|
|
vec2(-12.0, -distance),
|
|
|
|
vec2(-8.0, -distance),
|
|
|
|
vec2(-4.0, -distance),
|
|
|
|
vec2(0.0, -distance),
|
|
|
|
vec2(4.0, -distance),
|
|
|
|
vec2(8.0, -distance),
|
|
|
|
vec2(12.0, -distance),
|
|
|
|
vec2(16.0, -distance),
|
|
|
|
];
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
Ok(Self {
|
|
|
|
_board: board.unwrap(),
|
2023-05-09 14:39:53 +00:00
|
|
|
center: vec3(0.0, 0.0, 0.0),
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
_connection_lines: Self::create_connection_lines(scene, Color::Black)?,
|
2023-05-09 14:39:53 +00:00
|
|
|
|
|
|
|
slots: slots.unwrap(),
|
|
|
|
white_start_slots,
|
|
|
|
black_start_slots,
|
2023-05-09 16:58:07 +00:00
|
|
|
})
|
2023-05-08 18:56:50 +00:00
|
|
|
}
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
pub fn center(&self) -> Vector3<f32> {
|
|
|
|
self.center
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn white_start_slots(&self) -> &[Vector2<f32>; 9] {
|
|
|
|
&self.white_start_slots
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn black_start_slots(&self) -> &[Vector2<f32>; 9] {
|
|
|
|
&self.black_start_slots
|
|
|
|
}
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
pub fn slots(&mut self) -> &mut [[[BoardSlot; 3]; 3]; 3] {
|
|
|
|
&mut self.slots
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn close_to_marker(&mut self, position: Vector2<f32>) -> Option<&mut BoardSlot> {
|
2023-05-09 14:39:53 +00:00
|
|
|
const DISTANCE: f32 = 1.25;
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
for outer in self.slots.iter_mut() {
|
|
|
|
for inner in outer.iter_mut() {
|
|
|
|
for slot in inner.iter_mut() {
|
2023-05-09 14:39:53 +00:00
|
|
|
if slot.state != BoardSlotState::Invalid {
|
|
|
|
if (slot.position - position).magnitude() <= DISTANCE {
|
2023-05-09 16:58:07 +00:00
|
|
|
return Some(slot);
|
2023-05-09 14:39:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-09 16:58:07 +00:00
|
|
|
None
|
2023-05-09 14:39:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Board {
|
2023-05-08 18:56:50 +00:00
|
|
|
fn create_board_base(engine: &Arc<Engine>) -> Result<AssetMesh> {
|
|
|
|
let mut board_base = AssetMesh::new(
|
|
|
|
engine.device(),
|
|
|
|
engine.settings().graphics_info()?.render_type,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let vertex_buffer = Buffer::builder()
|
2023-05-09 14:39:53 +00:00
|
|
|
.set_data(&Objects::create_cuboid(
|
|
|
|
vec3(-22.5, -25.0, -2.0),
|
|
|
|
vec3(45.0, 50.0, 2.0),
|
2023-05-08 18:56:50 +00:00
|
|
|
))
|
|
|
|
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
|
|
|
.set_memory_usage(MemoryUsage::CpuOnly)
|
|
|
|
.build(engine.device().clone())?;
|
|
|
|
|
|
|
|
let color = Color::try_from("#b77b2b")?;
|
|
|
|
let a: [f32; 3] = color.into();
|
|
|
|
|
|
|
|
board_base.add_primitive(
|
|
|
|
vertex_buffer,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
PrimitiveMaterial {
|
|
|
|
color: [a[0], a[1], a[2], 1.0],
|
|
|
|
metallic_factor: 0.2,
|
2023-05-09 14:39:53 +00:00
|
|
|
emissive_factor: [0.5, 0.5, 0.5],
|
2023-05-08 18:56:50 +00:00
|
|
|
roughness_factor: 0.8,
|
|
|
|
alpha_mode: AlphaMode::Opaque,
|
|
|
|
alpha_cut_off: 0.5,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(board_base)
|
|
|
|
}
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
fn create_connection_lines(scene: &mut SceneHandle, color: Color) -> Result<Vec<Entity>> {
|
|
|
|
let mut entities = Vec::new();
|
|
|
|
|
|
|
|
scene.on_scene(|scene| {
|
|
|
|
let mut lines = scene.engine().assets().empty_entity();
|
|
|
|
|
|
|
|
let draw = Draw::new(vec![{
|
|
|
|
let mut mesh = AssetMesh::new(
|
|
|
|
scene.engine().device(),
|
|
|
|
scene.engine().settings().graphics_info()?.render_type,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let vertex_buffer = Buffer::builder()
|
|
|
|
.set_data(
|
|
|
|
&[
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-15.25, -15.25),
|
|
|
|
vec2(15.25, -15.25),
|
|
|
|
vec2(15.25, -14.75),
|
|
|
|
vec2(-15.25, -14.75),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-10.25, -10.25),
|
|
|
|
vec2(10.25, -10.25),
|
|
|
|
vec2(10.25, -9.75),
|
|
|
|
vec2(-10.25, -9.75),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-5.25, -5.25),
|
|
|
|
vec2(5.25, -5.25),
|
|
|
|
vec2(5.25, -4.75),
|
|
|
|
vec2(-5.25, -4.75),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-15.25, 14.75),
|
|
|
|
vec2(15.25, 14.75),
|
|
|
|
vec2(15.25, 15.25),
|
|
|
|
vec2(-15.25, 15.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-10.25, 9.75),
|
|
|
|
vec2(10.25, 9.75),
|
|
|
|
vec2(10.25, 10.25),
|
|
|
|
vec2(-10.25, 10.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-5.25, 4.75),
|
|
|
|
vec2(5.25, 4.75),
|
|
|
|
vec2(5.25, 5.25),
|
|
|
|
vec2(-5.25, 5.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-14.75, -15.25),
|
|
|
|
vec2(-14.75, 15.25),
|
|
|
|
vec2(-15.25, 15.25),
|
|
|
|
vec2(-15.25, -15.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-9.75, -10.25),
|
|
|
|
vec2(-9.75, 10.25),
|
|
|
|
vec2(-10.25, 10.25),
|
|
|
|
vec2(-10.25, -10.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-4.75, -5.25),
|
|
|
|
vec2(-4.75, 5.25),
|
|
|
|
vec2(-5.25, 5.25),
|
|
|
|
vec2(-5.25, -5.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(15.25, -15.25),
|
|
|
|
vec2(15.25, 15.25),
|
|
|
|
vec2(14.75, 15.25),
|
|
|
|
vec2(14.75, -15.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(10.25, -10.25),
|
|
|
|
vec2(10.25, 10.25),
|
|
|
|
vec2(9.75, 10.25),
|
|
|
|
vec2(9.75, -10.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(5.25, -5.25),
|
|
|
|
vec2(5.25, 5.25),
|
|
|
|
vec2(4.75, 5.25),
|
|
|
|
vec2(4.75, -5.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(0.25, -15.25),
|
|
|
|
vec2(0.25, -4.75),
|
|
|
|
vec2(-0.25, -4.75),
|
|
|
|
vec2(-0.25, -15.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-0.25, 15.25),
|
|
|
|
vec2(-0.25, 4.75),
|
|
|
|
vec2(0.25, 4.75),
|
|
|
|
vec2(0.25, 15.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(-15.25, -0.25),
|
|
|
|
vec2(-4.75, -0.25),
|
|
|
|
vec2(-4.75, 0.25),
|
|
|
|
vec2(-15.25, 0.25),
|
|
|
|
]),
|
|
|
|
Objects::create_flat_quad([
|
|
|
|
vec2(15.25, 0.25),
|
|
|
|
vec2(4.75, 0.25),
|
|
|
|
vec2(4.75, -0.25),
|
|
|
|
vec2(15.25, -0.25),
|
|
|
|
]),
|
|
|
|
]
|
|
|
|
.concat(),
|
|
|
|
)
|
|
|
|
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
|
|
|
.set_memory_usage(MemoryUsage::CpuOnly)
|
|
|
|
.build(scene.engine().device().clone())?;
|
|
|
|
|
|
|
|
let a: [f32; 3] = color.into();
|
|
|
|
|
|
|
|
mesh.add_primitive(
|
|
|
|
vertex_buffer,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
PrimitiveMaterial {
|
|
|
|
color: [a[0], a[1], a[2], 1.0],
|
|
|
|
metallic_factor: 0.2,
|
|
|
|
emissive_factor: [0.2, 0.2, 0.2],
|
|
|
|
roughness_factor: 0.8,
|
|
|
|
alpha_mode: AlphaMode::Opaque,
|
|
|
|
alpha_cut_off: 0.5,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
mesh
|
|
|
|
}]);
|
|
|
|
lines.insert_component(draw);
|
|
|
|
|
|
|
|
let mut location = Location::from_entity(&mut lines);
|
|
|
|
location.set_offset(vec3(0.0, 0.0, MillGame::OFFSET_TO_BOARD));
|
|
|
|
lines.insert_component(location);
|
|
|
|
|
|
|
|
entities.push(scene.add_entity(lines)?);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok(entities)
|
2023-05-08 18:56:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Map for Board {
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
"MillBoard"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_walkability(
|
|
|
|
&self,
|
|
|
|
_position: cgmath::Vector2<f32>,
|
|
|
|
_direction: cgmath::Vector2<f32>,
|
|
|
|
_radius: f32,
|
|
|
|
) -> Result<bool> {
|
|
|
|
Ok(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_height(&self, _x: f32, _y: f32) -> Result<f32> {
|
|
|
|
Ok(0.0)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn spawn_positions(&self) -> Result<Vec<cgmath::Vector3<f32>>> {
|
|
|
|
Ok(vec![])
|
|
|
|
}
|
|
|
|
|
|
|
|
fn leave_markers(&self) -> Result<Vec<Entity>> {
|
|
|
|
Ok(vec![])
|
|
|
|
}
|
|
|
|
|
2023-05-09 14:39:53 +00:00
|
|
|
fn disable(&self, _scene: &mut Scene) -> Result<()> {
|
|
|
|
unreachable!()
|
2023-05-08 18:56:50 +00:00
|
|
|
}
|
|
|
|
}
|