use bevy hierarchy system
This commit is contained in:
parent
35413b563c
commit
cfe2631578
15 changed files with 246 additions and 643 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use bevy_ecs::{entity::Entity, world::World};
|
||||
use bevy_ecs::{prelude::*, relationship::RelatedSpawner};
|
||||
use strum::Display;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -186,8 +186,8 @@ impl ArmourDto {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn spawn(self, world: &mut World) -> Entity {
|
||||
let mut commands = world.spawn(draw_id());
|
||||
pub fn spawn(self, spawner: &mut RelatedSpawner<'_, ChildOf>) -> Entity {
|
||||
let mut commands = spawner.spawn(draw_id());
|
||||
|
||||
commands.insert((
|
||||
Name(self.name.to_string()),
|
||||
|
|
|
|||
|
|
@ -52,19 +52,6 @@ pub struct PlayerDto {
|
|||
|
||||
impl PlayerDto {
|
||||
pub fn spawn(self, world: &mut World) -> EntityWorldMut<'_> {
|
||||
let primary = self.weapons.primary.map(|p| p.spawn(world));
|
||||
let secondary = self.weapons.secondary.map(|s| s.spawn(world));
|
||||
let melee = self.weapons.melee.map(|m| m.spawn(world));
|
||||
let temporary = self.weapons.temporary.map(|m| m.spawn(world));
|
||||
let fists = WeaponDto::FISTS.spawn(world);
|
||||
let kick = WeaponDto::KITCHEN_KNIFE.spawn(world);
|
||||
|
||||
let head = self.armour.helmet.map(|a| a.spawn(world));
|
||||
let torso = self.armour.body.map(|a| a.spawn(world));
|
||||
let legs = self.armour.pants.map(|a| a.spawn(world));
|
||||
let hands = self.armour.gloves.map(|a| a.spawn(world));
|
||||
let feet = self.armour.boots.map(|a| a.spawn(world));
|
||||
|
||||
let mut commands = world.spawn(draw_id());
|
||||
|
||||
commands.insert((
|
||||
|
|
@ -85,22 +72,48 @@ impl PlayerDto {
|
|||
faction,
|
||||
});
|
||||
|
||||
commands.insert(Weapons {
|
||||
primary,
|
||||
secondary,
|
||||
melee,
|
||||
temporary,
|
||||
kick,
|
||||
fists,
|
||||
let mut weapons = None;
|
||||
commands.with_children(|spawner| {
|
||||
let primary = self.weapons.primary.map(|p| p.spawn(spawner));
|
||||
let secondary = self.weapons.secondary.map(|s| s.spawn(spawner));
|
||||
let melee = self.weapons.melee.map(|m| m.spawn(spawner));
|
||||
let temporary = self.weapons.temporary.map(|m| m.spawn(spawner));
|
||||
let fists = WeaponDto::FISTS.spawn(spawner);
|
||||
let kick = WeaponDto::KICK.spawn(spawner);
|
||||
|
||||
weapons = Some(Weapons {
|
||||
primary,
|
||||
secondary,
|
||||
melee,
|
||||
temporary,
|
||||
kick,
|
||||
fists,
|
||||
});
|
||||
});
|
||||
if let Some(weapons) = weapons {
|
||||
commands.insert(weapons);
|
||||
}
|
||||
|
||||
let mut armour = None;
|
||||
commands.with_children(|spawner| {
|
||||
let head = self.armour.helmet.map(|a| a.spawn(spawner));
|
||||
let torso = self.armour.body.map(|a| a.spawn(spawner));
|
||||
let legs = self.armour.pants.map(|a| a.spawn(spawner));
|
||||
let hands = self.armour.gloves.map(|a| a.spawn(spawner));
|
||||
let feet = self.armour.boots.map(|a| a.spawn(spawner));
|
||||
|
||||
armour = Some(PlayerArmour {
|
||||
torso,
|
||||
head,
|
||||
legs,
|
||||
feet,
|
||||
hands,
|
||||
})
|
||||
});
|
||||
|
||||
commands.insert(PlayerArmour {
|
||||
torso,
|
||||
head,
|
||||
legs,
|
||||
feet,
|
||||
hands,
|
||||
});
|
||||
if let Some(armour) = armour {
|
||||
commands.insert(armour);
|
||||
}
|
||||
|
||||
commands
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_ecs::{prelude::*, relationship::RelatedSpawner};
|
||||
|
||||
use crate::{
|
||||
bundle::{
|
||||
|
|
@ -252,8 +252,8 @@ impl WeaponDto {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn spawn(self, world: &mut World) -> Entity {
|
||||
let mut commands = world.spawn(draw_id());
|
||||
pub fn spawn(self, spawner: &mut RelatedSpawner<'_, ChildOf>) -> Entity {
|
||||
let mut commands = spawner.spawn(draw_id());
|
||||
|
||||
let verb = match self.kind {
|
||||
WeaponSlot::Primary | WeaponSlot::Secondary => WeaponVerb::Fired,
|
||||
|
|
|
|||
|
|
@ -1,178 +0,0 @@
|
|||
use bevy_ecs::{
|
||||
prelude::*,
|
||||
system::{Command, EntityCommands},
|
||||
};
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
pub struct Parent(Entity);
|
||||
|
||||
impl Parent {
|
||||
pub fn get(&self) -> Entity {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Default)]
|
||||
pub struct Children(Vec<Entity>);
|
||||
|
||||
impl Children {
|
||||
pub fn get(&self) -> &[Entity] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
struct AddChild {
|
||||
parent: Entity,
|
||||
child: Entity,
|
||||
}
|
||||
|
||||
impl Command for AddChild {
|
||||
fn apply(self, world: &mut World) {
|
||||
let mut parent = world.entity_mut(self.parent);
|
||||
if let Some(mut children) = parent.get_mut::<Children>() {
|
||||
children.0.push(self.child);
|
||||
} else {
|
||||
parent.insert(Children(vec![self.child]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AddChildren {
|
||||
parent: Entity,
|
||||
children: Vec<Entity>,
|
||||
}
|
||||
|
||||
impl Command for AddChildren {
|
||||
fn apply(mut self, world: &mut World) {
|
||||
let mut parent = world.entity_mut(self.parent);
|
||||
if let Some(mut children) = parent.get_mut::<Children>() {
|
||||
children.0.append(&mut self.children);
|
||||
} else {
|
||||
parent.insert(Children(self.children));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RemoveChild {
|
||||
parent: Entity,
|
||||
child: Entity,
|
||||
}
|
||||
|
||||
impl Command for RemoveChild {
|
||||
fn apply(self, world: &mut World) {
|
||||
let mut parent = world.entity_mut(self.parent);
|
||||
let mut children = parent
|
||||
.get_mut::<Children>()
|
||||
.expect("Parent component has no children");
|
||||
children.0.retain(|child| *child != self.child);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HierarchyBuilder {
|
||||
fn add_child(&mut self, child: Entity) -> &mut Self;
|
||||
|
||||
fn add_children(&mut self, children: impl AsRef<[Entity]>) -> &mut Self;
|
||||
|
||||
fn remove_child(&mut self, child: Entity) -> &mut Self;
|
||||
|
||||
fn set_parent(&mut self, parent: Entity) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'a> HierarchyBuilder for EntityCommands<'a> {
|
||||
fn add_child(&mut self, child: Entity) -> &mut Self {
|
||||
let parent = self.id();
|
||||
self.commands().queue(AddChild { parent, child });
|
||||
self.commands().entity(child).insert(Parent(parent));
|
||||
self
|
||||
}
|
||||
|
||||
fn add_children(&mut self, children: impl AsRef<[Entity]>) -> &mut Self {
|
||||
let children = children.as_ref();
|
||||
let parent = self.id();
|
||||
self.commands().queue(AddChildren {
|
||||
parent,
|
||||
children: children.to_owned(),
|
||||
});
|
||||
self.commands().insert_batch(
|
||||
children
|
||||
.iter()
|
||||
.map(|e| (*e, Parent(parent)))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
self
|
||||
}
|
||||
|
||||
fn remove_child(&mut self, child: Entity) -> &mut Self {
|
||||
let parent = self.id();
|
||||
self.commands().queue(RemoveChild { parent, child });
|
||||
self.commands().entity(child).remove::<Parent>();
|
||||
self
|
||||
}
|
||||
|
||||
fn set_parent(&mut self, parent: Entity) -> &mut Self {
|
||||
let child = self.id();
|
||||
self.commands().queue(AddChild { parent, child });
|
||||
self.commands().entity(child).insert(Parent(parent));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w> HierarchyBuilder for EntityWorldMut<'w> {
|
||||
fn add_child(&mut self, child: Entity) -> &mut Self {
|
||||
let parent_id = self.id();
|
||||
unsafe {
|
||||
self.world_mut()
|
||||
.entity_mut(child)
|
||||
.insert(Parent(parent_id))
|
||||
.update_location();
|
||||
}
|
||||
if let Some(mut children) = self.get_mut::<Children>() {
|
||||
children.0.push(child);
|
||||
self
|
||||
} else {
|
||||
self.insert(Children(vec![child]))
|
||||
}
|
||||
}
|
||||
|
||||
fn add_children(&mut self, children: impl AsRef<[Entity]>) -> &mut Self {
|
||||
let parent_id = self.id();
|
||||
unsafe {
|
||||
for child in children.as_ref() {
|
||||
self.world_mut()
|
||||
.entity_mut(*child)
|
||||
.insert(Parent(parent_id))
|
||||
.update_location();
|
||||
}
|
||||
}
|
||||
if let Some(mut old_children) = self.get_mut::<Children>() {
|
||||
old_children.0.append(&mut children.as_ref().to_owned());
|
||||
self
|
||||
} else {
|
||||
self.insert(Children(children.as_ref().to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_child(&mut self, child: Entity) -> &mut Self {
|
||||
unsafe {
|
||||
self.world_mut()
|
||||
.entity_mut(child)
|
||||
.remove::<Parent>()
|
||||
.update_location();
|
||||
}
|
||||
if let Some(mut children) = self.get_mut::<Children>() {
|
||||
children.0.retain(|c| *c != child);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn set_parent(&mut self, parent: Entity) -> &mut Self {
|
||||
let child_id = self.id();
|
||||
unsafe {
|
||||
self.world_mut()
|
||||
.entity_mut(parent)
|
||||
.add_child(child_id)
|
||||
.update_location()
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
pub mod bundle;
|
||||
pub mod dto;
|
||||
// pub mod hierarchy;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue