use rapier2d::prelude::*;
use crate::nav::navigation::NavigationSystem;
use crate::nav::spatial::SpatialGrid;
use crate::config::{EngineConfig, PLAYER_STATE_LEN};
use crate::events::CoreEvent;
use crate::map::GameMap;
use crate::rng::Rng;
use crate::snapshot::Block;
pub trait GameDef: Sized {
type Config: serde::de::DeserializeOwned;
type Sim: GameSim<Self>;
}
pub struct SimCtx<'a> {
pub world: &'a mut PhysicsWorld,
pub cfg: &'a EngineConfig,
pub map: &'a Option<GameMap>,
pub nav: &'a Option<NavigationSystem>,
pub spatial: &'a mut SpatialGrid,
pub rng: &'a mut Rng,
pub events: &'a mut Vec<CoreEvent>,
pub bodies_to_destroy: &'a mut Vec<RigidBodyHandle>,
}
#[allow(clippy::too_many_arguments)]
pub trait GameSim<G: GameDef>: Sized {
fn new(cfg: &G::Config, engine_cfg: &EngineConfig) -> Self;
fn spawn_actor(
&mut self,
world: &mut PhysicsWorld,
events: &mut Vec<CoreEvent>,
game_id: u32,
model_name: &str,
team_id: u8,
x: f32,
y: f32,
angle_deg: f32,
) -> Result<(), String>;
fn remove_actor(&mut self, world: &mut PhysicsWorld, game_id: u32);
fn reset_actor(&mut self, world: &mut PhysicsWorld, game_id: u32, team_id: u8, x: f32, y: f32, angle_deg: f32);
fn reset_all_vitals(&mut self, events: &mut Vec<CoreEvent>);
fn spawn_scripted_actor(
&mut self,
world: &mut PhysicsWorld,
rng: &mut Rng,
events: &mut Vec<CoreEvent>,
game_id: u32,
model_name: &str,
team_id: u8,
x: f32,
y: f32,
angle_deg: f32,
) -> Result<(), String>;
fn remove_scripted_actor(&mut self, world: &mut PhysicsWorld, game_id: u32);
fn apply_input(&mut self, game_id: u32, seq: u32, action: &str, key_name: &str);
fn apply_aim(&mut self, _game_id: u32, _seq: u32, _x: f32, _y: f32, _flags: u32) {}
fn last_input_seq(&self, game_id: u32) -> u32;
fn is_alive(&self, game_id: u32) -> bool;
fn actor_position(&self, world: &PhysicsWorld, game_id: u32) -> Option<[f32; 2]>;
fn prediction_state(&self, world: &PhysicsWorld, game_id: u32) -> Option<([f32; PLAYER_STATE_LEN], bool)>;
fn alive_players_flat(&self, world: &PhysicsWorld) -> Vec<f32>;
fn players_json(&self) -> String;
fn on_fixed_step(&mut self, ctx: &mut SimCtx, dt: f32);
fn on_contacts(&mut self, ctx: &mut SimCtx, pairs: &[(ColliderHandle, ColliderHandle)]);
fn on_before_destroy(&mut self, world: &PhysicsWorld, handle: RigidBodyHandle);
fn on_ai_tick(&mut self, ctx: &mut SimCtx, dt: f32);
fn refresh_cached(&mut self, world: &PhysicsWorld);
fn build_snapshot_blocks(&mut self) -> (Vec<(String, Block)>, bool);
fn remove_players_and_shots(&mut self, world: &mut PhysicsWorld) -> Vec<String>;
fn clear(&mut self);
fn serialize(&self) -> serde_json::Value;
fn deserialize(&mut self, value: serde_json::Value) -> Result<(), String>;
fn rebuild_spatial_grid(&self, world: &PhysicsWorld, spatial: &mut SpatialGrid);
}