the work
This commit is contained in:
@ -8,8 +8,9 @@ pub struct ContactingLadder{
|
|||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
#[derive(Clone,Hash,Eq,PartialEq)]
|
||||||
pub enum ContactingBehaviour{
|
pub enum ContactingBehaviour{
|
||||||
Surf,
|
Surf,
|
||||||
Cling,//usable as a zipline, or other weird and wonderful things
|
|
||||||
Ladder(ContactingLadder),
|
Ladder(ContactingLadder),
|
||||||
|
NoJump,
|
||||||
|
Cling,//usable as a zipline, or other weird and wonderful things
|
||||||
Elastic(u32),//[1/2^32,1] 0=None (elasticity+1)/2^32
|
Elastic(u32),//[1/2^32,1] 0=None (elasticity+1)/2^32
|
||||||
}
|
}
|
||||||
//you have this effect while intersecting
|
//you have this effect while intersecting
|
||||||
|
@ -1,12 +1,23 @@
|
|||||||
use std::collections::{HashSet,HashMap};
|
use std::collections::{HashSet,HashMap};
|
||||||
use crate::model::ModelId;
|
use crate::model::ModelId;
|
||||||
use crate::gameplay_style;
|
use crate::gameplay_style;
|
||||||
|
use crate::updatable::Updatable;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct StageElement{
|
pub struct StageElement{
|
||||||
stage:StageId,//which stage spawn to send to
|
stage:StageId,//which stage spawn to send to
|
||||||
force:bool,//allow setting to lower spawn id i.e. 7->3
|
force:bool,//allow setting to lower spawn id i.e. 7->3
|
||||||
behaviour:StageElementBehaviour
|
behaviour:StageElementBehaviour
|
||||||
}
|
}
|
||||||
|
impl StageElement{
|
||||||
|
pub fn new(stage_id:u32,force:bool,behaviour:StageElementBehaviour)->Self{
|
||||||
|
Self{
|
||||||
|
stage:StageId(stage_id),
|
||||||
|
force,
|
||||||
|
behaviour,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
#[derive(Clone,Hash,Eq,PartialEq)]
|
||||||
pub enum StageElementBehaviour{
|
pub enum StageElementBehaviour{
|
||||||
@ -20,25 +31,63 @@ pub enum StageElementBehaviour{
|
|||||||
Checkpoint,//this is a combined behaviour for Ordered & Unordered in case a model is used multiple times or for both.
|
Checkpoint,//this is a combined behaviour for Ordered & Unordered in case a model is used multiple times or for both.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
|
pub struct CheckpointId(usize);
|
||||||
|
#[derive(Clone,Hash,Eq,PartialEq)]
|
||||||
pub struct StageId(u32);
|
pub struct StageId(u32);
|
||||||
pub struct Stage{
|
pub struct Stage{
|
||||||
spawn:ModelId,
|
spawn:ModelId,
|
||||||
|
//open world support lol
|
||||||
|
ordered_checkpoints_count:u32,
|
||||||
//other behaviour models of this stage can have
|
//other behaviour models of this stage can have
|
||||||
ordered_checkpoints:Vec<ModelId>,
|
ordered_checkpoints:HashMap<CheckpointId,ModelId>,
|
||||||
unordered_checkpoints:HashSet<ModelId>,
|
unordered_checkpoints:HashSet<ModelId>,
|
||||||
}
|
}
|
||||||
|
#[derive(Default)]
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
pub struct StageUpdate{
|
||||||
pub enum ZoneBehaviour{
|
//other behaviour models of this stage can have
|
||||||
Finish,
|
ordered_checkpoints:HashMap<CheckpointId,ModelId>,
|
||||||
Anitcheat,
|
unordered_checkpoints:HashSet<ModelId>,
|
||||||
}
|
}
|
||||||
|
impl Updatable<&StageUpdate> for Stage{
|
||||||
|
fn insert(&mut self,update:&StageUpdate){
|
||||||
|
for (&checkpoint,&model) in &update.ordered_checkpoints{
|
||||||
|
self.ordered_checkpoints.insert(checkpoint,model);
|
||||||
|
}
|
||||||
|
for &checkpoint in &update.unordered_checkpoints{
|
||||||
|
self.unordered_checkpoints.insert(checkpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn remove(&mut self,update:&StageUpdate){
|
||||||
|
for (checkpoint,_) in &update.ordered_checkpoints{
|
||||||
|
self.ordered_checkpoints.remove(checkpoint);
|
||||||
|
}
|
||||||
|
for model in &update.unordered_checkpoints{
|
||||||
|
self.unordered_checkpoints.remove(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
|
pub enum Zone{
|
||||||
|
Start,
|
||||||
|
Finish,
|
||||||
|
Anticheat,
|
||||||
|
}
|
||||||
|
#[derive(Clone,Hash,Eq,PartialEq)]
|
||||||
pub struct ModeId(u32);
|
pub struct ModeId(u32);
|
||||||
|
impl ModeId{
|
||||||
|
pub const MAIN:Self=Self(0);
|
||||||
|
pub const BONUS:Self=Self(1);
|
||||||
|
pub const fn mode(mode_id:u32)->Self{
|
||||||
|
Self(mode_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct Mode{
|
pub struct Mode{
|
||||||
style:gameplay_style::StyleModifiers,
|
style:gameplay_style::StyleModifiers,
|
||||||
start:ModelId,
|
start:ModelId,//when you press reset you go here
|
||||||
zones:HashMap<ModelId,ZoneBehaviour>,
|
zones:HashMap<ModelId,Zone>,
|
||||||
stages:Vec<Stage>,
|
stages:Vec<Stage>,//when you load the map you go to stages[0].spawn
|
||||||
//mutually exlusive stage element behaviour
|
//mutually exlusive stage element behaviour
|
||||||
elements:HashMap<ModelId,StageElement>,
|
elements:HashMap<ModelId,StageElement>,
|
||||||
jump_limit:HashMap<ModelId,u32>,
|
jump_limit:HashMap<ModelId,u32>,
|
||||||
@ -47,23 +96,25 @@ impl Mode{
|
|||||||
pub fn get_spawn_model_id(&self,stage:StageId)->Option<ModelId>{
|
pub fn get_spawn_model_id(&self,stage:StageId)->Option<ModelId>{
|
||||||
self.stages.get(stage.0 as usize).map(|s|s.spawn)
|
self.stages.get(stage.0 as usize).map(|s|s.spawn)
|
||||||
}
|
}
|
||||||
|
//TODO: put this in the SNF
|
||||||
pub fn denormalize_data(&mut self){
|
pub fn denormalize_data(&mut self){
|
||||||
//expand and index normalized data
|
//expand and index normalized data
|
||||||
|
self.zones.insert(self.start,Zone::Start);
|
||||||
for (stage_id,stage) in self.stages.iter().enumerate(){
|
for (stage_id,stage) in self.stages.iter().enumerate(){
|
||||||
self.elements.insert(stage.spawn,StageElement{
|
self.elements.insert(stage.spawn,StageElement{
|
||||||
stage:StageId(stage_id as u32),
|
stage:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::SpawnAt,
|
behaviour:StageElementBehaviour::SpawnAt,
|
||||||
});
|
});
|
||||||
for &model_id in &stage.ordered_checkpoints{
|
for (_,&model) in &stage.ordered_checkpoints{
|
||||||
self.elements.insert(model_id,StageElement{
|
self.elements.insert(model,StageElement{
|
||||||
stage:StageId(stage_id as u32),
|
stage:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::Checkpoint,
|
behaviour:StageElementBehaviour::Checkpoint,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for &model_id in &stage.unordered_checkpoints{
|
for &model in &stage.unordered_checkpoints{
|
||||||
self.elements.insert(model_id,StageElement{
|
self.elements.insert(model,StageElement{
|
||||||
stage:StageId(stage_id as u32),
|
stage:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::Checkpoint,
|
behaviour:StageElementBehaviour::Checkpoint,
|
||||||
@ -72,19 +123,102 @@ impl Mode{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//this would be nice as a macro
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ModeUpdate{
|
||||||
|
zones:HashMap<ModelId,Zone>,
|
||||||
|
stages:HashMap<StageId,StageUpdate>,
|
||||||
|
//mutually exlusive stage element behaviour
|
||||||
|
elements:HashMap<ModelId,StageElement>,
|
||||||
|
jump_limit:HashMap<ModelId,u32>,
|
||||||
|
}
|
||||||
|
impl Updatable<&ModeUpdate> for Mode{
|
||||||
|
fn insert(&mut self,update:&ModeUpdate){
|
||||||
|
for (&model,&zone) in &update.zones{
|
||||||
|
self.zones.insert(model,zone);
|
||||||
|
}
|
||||||
|
for (stage,stage_update) in &update.stages{
|
||||||
|
if let Some(stage)=self.stages.get_mut(stage.0 as usize){
|
||||||
|
stage.insert(stage_update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (&model,stage_element) in &update.elements{
|
||||||
|
self.elements.insert(model,stage_element.clone());
|
||||||
|
}
|
||||||
|
for (&model,&limit) in &update.jump_limit{
|
||||||
|
self.jump_limit.insert(model,limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn remove(&mut self,update:&ModeUpdate){
|
||||||
|
for (model,_) in &update.zones{
|
||||||
|
self.zones.remove(model);
|
||||||
|
}
|
||||||
|
for (stage,stage_update) in &update.stages{
|
||||||
|
if let Some(stage)=self.stages.get_mut(stage.0 as usize){
|
||||||
|
stage.remove(stage_update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (model,_) in &update.elements{
|
||||||
|
self.elements.remove(model);
|
||||||
|
}
|
||||||
|
for (model,_) in &update.jump_limit{
|
||||||
|
self.jump_limit.remove(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ModeUpdate{
|
||||||
|
pub fn zone(model_id:ModelId,zone:Zone)->Self{
|
||||||
|
let mut mu=Self::default();
|
||||||
|
mu.zones.insert(model_id,zone);
|
||||||
|
mu
|
||||||
|
}
|
||||||
|
pub fn stage(stage_id:StageId,stage_update:StageUpdate)->Self{
|
||||||
|
let mut mu=Self::default();
|
||||||
|
mu.stages.insert(stage_id,stage_update);
|
||||||
|
mu
|
||||||
|
}
|
||||||
|
pub fn element(model_id:ModelId,element:StageElement)->Self{
|
||||||
|
let mut mu=Self::default();
|
||||||
|
mu.elements.insert(model_id,element);
|
||||||
|
mu
|
||||||
|
}
|
||||||
|
pub fn jump_limit(model_id:ModelId,jump_limit:u32)->Self{
|
||||||
|
let mut mu=Self::default();
|
||||||
|
mu.jump_limit.insert(model_id,jump_limit);
|
||||||
|
mu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Modes{
|
pub struct Modes{
|
||||||
modes:Vec<Mode>,
|
modes:Vec<Mode>,
|
||||||
}
|
}
|
||||||
impl Modes{
|
impl Modes{
|
||||||
pub fn clear(&mut self){
|
pub fn new(modes:Vec<Mode>)->Self{
|
||||||
self.modes.clear();
|
Self{
|
||||||
|
modes,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn get_mode(&self,mode:ModeId)->Option<&Mode>{
|
pub fn get_mode(&self,mode:ModeId)->Option<&Mode>{
|
||||||
self.modes.get(mode.0 as usize)
|
self.modes.get(mode.0 as usize)
|
||||||
}
|
}
|
||||||
pub fn insert(&mut self,mode:Mode){
|
}
|
||||||
self.modes.push(mode);
|
pub struct ModesUpdate{
|
||||||
|
modes:HashMap<ModeId,ModeUpdate>,
|
||||||
|
}
|
||||||
|
impl Updatable<&ModesUpdate> for Modes{
|
||||||
|
fn insert(&mut self,update:&ModesUpdate){
|
||||||
|
for (mode,mode_update) in &update.modes{
|
||||||
|
if let Some(mode)=self.modes.get_mut(mode.0 as usize){
|
||||||
|
mode.insert(mode_update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn remove(&mut self,update:&ModesUpdate){
|
||||||
|
for (mode,mode_update) in &update.modes{
|
||||||
|
if let Some(mode)=self.modes.get_mut(mode.0 as usize){
|
||||||
|
mode.remove(mode_update);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
pub mod bvh;
|
pub mod bvh;
|
||||||
|
pub mod map;
|
||||||
pub mod aabb;
|
pub mod aabb;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod zeroes;
|
pub mod zeroes;
|
||||||
pub mod integer;
|
pub mod integer;
|
||||||
|
pub mod updatable;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
pub mod gameplay_modes;
|
pub mod gameplay_modes;
|
||||||
pub mod gameplay_style;
|
pub mod gameplay_style;
|
||||||
|
11
src/map.rs
Normal file
11
src/map.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::model;
|
||||||
|
use crate::gameplay_modes;
|
||||||
|
//this is the current map data loaded in memory
|
||||||
|
pub struct Map{
|
||||||
|
modes:gameplay_modes::Modes,
|
||||||
|
models:model::Models,
|
||||||
|
//RenderPattern
|
||||||
|
textures:HashMap<u32,Vec<u8>>,
|
||||||
|
}
|
26
src/model.rs
26
src/model.rs
@ -1,5 +1,7 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use crate::integer::{Planar64Vec3,Planar64Affine3};
|
use crate::integer::{Planar64Vec3,Planar64Affine3};
|
||||||
use crate::gameplay_attributes;
|
use crate::gameplay_attributes;
|
||||||
|
use crate::updatable::Updatable;
|
||||||
|
|
||||||
pub type TextureCoordinate=glam::Vec2;
|
pub type TextureCoordinate=glam::Vec2;
|
||||||
pub type Color4=glam::Vec4;
|
pub type Color4=glam::Vec4;
|
||||||
@ -30,6 +32,8 @@ pub struct IndexedPhysicsGroup{
|
|||||||
pub groups:Vec<GroupId>,
|
pub groups:Vec<GroupId>,
|
||||||
}
|
}
|
||||||
//This is a superset of PhysicsModel and GraphicsModel
|
//This is a superset of PhysicsModel and GraphicsModel
|
||||||
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
|
pub struct IndexedModelId(u32);
|
||||||
pub struct IndexedModel{
|
pub struct IndexedModel{
|
||||||
pub unique_pos:Vec<Planar64Vec3>,//Unit32Vec3
|
pub unique_pos:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
pub unique_normal:Vec<Planar64Vec3>,//Unit32Vec3
|
pub unique_normal:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
@ -47,8 +51,28 @@ pub struct IndexedModel{
|
|||||||
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
pub struct ModelId(u32);
|
pub struct ModelId(u32);
|
||||||
pub struct Model{
|
pub struct Model{
|
||||||
pub model:ModelId,
|
pub model:IndexedModelId,
|
||||||
pub attributes:gameplay_attributes::CollisionAttributesId,
|
pub attributes:gameplay_attributes::CollisionAttributesId,
|
||||||
pub color:Color4,//transparency is in here
|
pub color:Color4,//transparency is in here
|
||||||
pub transform:Planar64Affine3,
|
pub transform:Planar64Affine3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Models{
|
||||||
|
indexed_models:HashMap<IndexedModelId,IndexedModel>,
|
||||||
|
models:HashMap<ModelId,Model>,
|
||||||
|
}
|
||||||
|
impl Updatable<Models> for Models{
|
||||||
|
fn insert(&mut self,update:Models){
|
||||||
|
self.indexed_models.extend(update.indexed_models);
|
||||||
|
self.models.extend(update.models);
|
||||||
|
}
|
||||||
|
fn remove(&mut self,update:Models){
|
||||||
|
for (indexed_model_id,_) in &update.indexed_models{
|
||||||
|
self.indexed_models.remove(indexed_model_id);
|
||||||
|
}
|
||||||
|
for (model_id,_) in &update.models{
|
||||||
|
self.models.remove(model_id);
|
||||||
|
}
|
||||||
|
todo!("stop cloning models for remove");
|
||||||
|
}
|
||||||
|
}
|
62
src/updatable.rs
Normal file
62
src/updatable.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
pub trait Updatable<Updater>{
|
||||||
|
fn insert(&mut self,update:Updater);
|
||||||
|
fn remove(&mut self,update:Updater);
|
||||||
|
}
|
||||||
|
//what if do like this
|
||||||
|
//*
|
||||||
|
pub trait Updatable2<Updater>{
|
||||||
|
fn update(&mut self,update:Updater);
|
||||||
|
}
|
||||||
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
|
struct InnerId(u32);
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Inner{
|
||||||
|
id:InnerId,
|
||||||
|
enabled:bool,
|
||||||
|
}
|
||||||
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
|
struct OuterId(u32);
|
||||||
|
struct Outer{
|
||||||
|
id:OuterId,
|
||||||
|
inners:std::collections::HashMap<InnerId,Inner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Update<I,U>{
|
||||||
|
Insert(I),
|
||||||
|
Update(U),
|
||||||
|
Remove
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InnerUpdate{
|
||||||
|
//#[updatable(Update)]
|
||||||
|
enabled:Option<bool>,
|
||||||
|
}
|
||||||
|
struct OuterUpdate{
|
||||||
|
//#[updatable(Insert,Update,Remove)]
|
||||||
|
inners:std::collections::HashMap<InnerId,Update<Inner,InnerUpdate>>,
|
||||||
|
//#[updatable(Update)]
|
||||||
|
//inners:std::collections::HashMap<InnerId,InnerUpdate>,
|
||||||
|
}
|
||||||
|
impl Updatable2<InnerUpdate> for Inner{
|
||||||
|
fn update(&mut self,update:InnerUpdate){
|
||||||
|
if let Some(enabled)=update.enabled{
|
||||||
|
self.enabled=enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Updatable2<OuterUpdate> for Outer{
|
||||||
|
fn update(&mut self,update:OuterUpdate){
|
||||||
|
for (id,up) in update.inners{
|
||||||
|
match up{
|
||||||
|
Update::Insert(new_inner)=>self.inners.insert(id,new_inner),
|
||||||
|
Update::Update(inner_update)=>self.inners.get_mut(&id).map(|inner|{
|
||||||
|
let old=inner.clone();
|
||||||
|
inner.update(inner_update);
|
||||||
|
old
|
||||||
|
}),
|
||||||
|
Update::Remove=>self.inners.remove(&id),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*/
|
Reference in New Issue
Block a user