1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Implement basic battle arena functionality #32

This commit is contained in:
NG (Graham)
2025-08-30 21:36:01 -04:00
parent 1403a6e3d0
commit 7f9ed8bf35
41 changed files with 1836 additions and 327 deletions

View File

@@ -0,0 +1,92 @@
pub struct CubeLocationsParser;
pub struct CubeLocationInfo {
pub x: u8,
pub y: u8,
pub z: u8,
extras: u8,
}
impl CubeLocationInfo {
pub fn orientation(&self) -> u8 {
self.extras & 0x7F
}
pub fn is_destroyed(&self) -> bool {
self.extras & 0x80 != 0
}
}
impl CubeLocationsParser {
pub fn with_cubes<'a, I: std::iter::Iterator<Item=&'a crate::persist::Cube>>(_iter: I) -> Self {
Self
}
pub fn locations_of(&self, r: &mut dyn std::io::Read, cube_id: u32) -> Vec<CubeLocationInfo> {
match super::parser::Cube::parse_list(r) {
Ok(cubes) => {
cubes.into_iter()
.filter(|x| x.id == cube_id)
.map(|cube| CubeLocationInfo {
x: cube.x,
y: cube.y,
z: cube.z,
extras: cube.orientation,
})
.collect()
}
Err(e) => {
log::error!("Failed to parse cube data to find cube locations: {}", e);
Vec::default()
}
}
}
pub fn locations_of_by_distance_to_first(&self, r: &mut dyn std::io::Read, locations_of_id: u32, distance_to_id: u32) -> Vec<CubeLocationInfo> {
match super::parser::Cube::parse_list(r) {
Ok(cubes) => {
if let Some(target) = cubes.iter().filter(|x| x.id == distance_to_id).next() {
let target_x = target.x as f32;
let target_y = target.y as f32;
let target_z = target.z as f32;
let mut relevant_cubes: Vec<(f32, CubeLocationInfo)> = cubes.into_iter()
.filter(|x| x.id == locations_of_id)
.map(|cube| {
let distance = (
(cube.x as f32 - target_x).powi(2)
+ (cube.y as f32 - target_y).powi(2)
+ (cube.z as f32 - target_z).powi(2)
).sqrt();
(distance, CubeLocationInfo {
x: cube.x,
y: cube.y,
z: cube.z,
extras: cube.orientation,
})
})
.collect();
relevant_cubes.sort_by_key(|(distance, _)| (distance * 1_000_000.0) as i64);
relevant_cubes.into_iter()
.map(|(_, cube)| cube)
.collect()
} else {
log::warn!("No cube with id {} to calculate distance", distance_to_id);
cubes.into_iter()
.filter(|x| x.id == locations_of_id)
.map(|cube| CubeLocationInfo {
x: cube.x,
y: cube.y,
z: cube.z,
extras: cube.orientation,
})
.collect()
}
}
Err(e) => {
log::error!("Failed to parse cube data to find cube locations: {}", e);
Vec::default()
}
}
}
}

View File

@@ -6,9 +6,15 @@ pub use weapon_list::WeaponListParser;
mod cpu_count;
pub use cpu_count::CpuListParser;
mod locations_of;
pub use locations_of::{CubeLocationsParser, CubeLocationInfo};
//pub mod prefabs;
pub struct CubeParsers {
weapon_list: std::sync::Arc<WeaponListParser>,
cpu_counter: std::sync::Arc<CpuListParser>,
locations: std::sync::Arc<CubeLocationsParser>,
}
impl CubeParsers {
@@ -17,6 +23,7 @@ impl CubeParsers {
Self {
weapon_list: std::sync::Arc::new(WeaponListParser::with_cubes(cubes.values())),
cpu_counter: std::sync::Arc::new(CpuListParser::with_cubes(cubes.values())),
locations: std::sync::Arc::new(CubeLocationsParser::with_cubes(cubes.values())),
}
}
@@ -27,4 +34,8 @@ impl CubeParsers {
pub fn cpu_counter(&self) -> std::sync::Arc<CpuListParser> {
self.cpu_counter.clone()
}
pub fn locations_of(&self) -> std::sync::Arc<CubeLocationsParser> {
self.locations.clone()
}
}

View File

@@ -1,5 +1,7 @@
#![allow(dead_code)]
use std::io::Write;
pub struct Cube {
pub id: u32,
pub x: u8,
@@ -35,6 +37,22 @@ impl Cube {
}
Ok(cubes)
}
pub fn dump(&self, w: &mut dyn std::io::Write) -> std::io::Result<usize> {
w.write_all(&self.id.to_le_bytes())?;
w.write_all(&[self.x, self.y, self.z, self.orientation])?;
Ok(8)
}
pub fn dump_list(items: Vec<Self>) -> std::io::Result<Vec<u8>> {
let mut buf = Vec::with_capacity(4 + (items.len() * 8));
let mut dumped = std::io::Cursor::new(&mut buf);
dumped.write_all(&(items.len() as u32).to_le_bytes())?;
for item in items {
item.dump(&mut dumped)?;
}
Ok(buf)
}
}
pub struct Colour {