mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add ParticleEmitter Component
This commit is contained in:
parent
7aebff26e0
commit
42a10a6059
@ -2,7 +2,8 @@ use crate::{
|
||||
comp::{
|
||||
ability::Stage,
|
||||
item::{armor::Protection, Item, ItemKind},
|
||||
Body, CharacterState, EnergySource, Gravity, LightEmitter, Projectile, StateUpdate,
|
||||
Body, CharacterState, EnergySource, Gravity, LightEmitter, ParticleEmitter, Projectile,
|
||||
StateUpdate,
|
||||
},
|
||||
states::{triple_strike::*, *},
|
||||
sys::character_behavior::JoinData,
|
||||
@ -61,6 +62,7 @@ pub enum CharacterAbility {
|
||||
projectile: Projectile,
|
||||
projectile_body: Body,
|
||||
projectile_light: Option<LightEmitter>,
|
||||
projectile_particles: Option<ParticleEmitter>,
|
||||
projectile_gravity: Option<Gravity>,
|
||||
},
|
||||
Boost {
|
||||
@ -247,6 +249,7 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
projectile,
|
||||
projectile_body,
|
||||
projectile_light,
|
||||
projectile_particles,
|
||||
projectile_gravity,
|
||||
energy_cost: _,
|
||||
} => CharacterState::BasicRanged(basic_ranged::Data {
|
||||
@ -258,6 +261,7 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
projectile: projectile.clone(),
|
||||
projectile_body: *projectile_body,
|
||||
projectile_light: *projectile_light,
|
||||
projectile_particles: *projectile_particles,
|
||||
projectile_gravity: *projectile_gravity,
|
||||
}),
|
||||
CharacterAbility::Boost { duration, only_up } => CharacterState::Boost(boost::Data {
|
||||
|
@ -2,7 +2,8 @@
|
||||
// version in voxygen\src\meta.rs in order to reset save files to being empty
|
||||
|
||||
use crate::comp::{
|
||||
body::object, projectile, Body, CharacterAbility, Gravity, LightEmitter, Projectile,
|
||||
body::object, projectile, Body, CharacterAbility, Gravity, HealthChange, HealthSource,
|
||||
LightEmitter, Projectile, ParticleEmitter,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -179,6 +180,7 @@ impl Tool {
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::Arrow),
|
||||
projectile_light: None,
|
||||
projectile_particles: None,
|
||||
projectile_gravity: Some(Gravity(0.2)),
|
||||
},
|
||||
ChargedRanged {
|
||||
@ -193,6 +195,8 @@ impl Tool {
|
||||
recover_duration: Duration::from_millis(500),
|
||||
projectile_body: Body::Object(object::Body::Arrow),
|
||||
projectile_light: None,
|
||||
projectile_particles: None,
|
||||
projectile_gravity: Some(Gravity(0.05)),
|
||||
},
|
||||
],
|
||||
Dagger(_) => vec![
|
||||
@ -261,40 +265,68 @@ impl Tool {
|
||||
col: (0.85, 0.5, 0.11).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile_gravity: None,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: 400,
|
||||
holdable: true,
|
||||
prepare_duration: Duration::from_millis(800),
|
||||
recover_duration: Duration::from_millis(50),
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![
|
||||
projectile::Effect::Explode {
|
||||
power: 1.4 * self.base_power(),
|
||||
},
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Explode {
|
||||
power: 1.4 * self.base_power(),
|
||||
},
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(20),
|
||||
owner: None,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::BoltFireBig),
|
||||
projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
|
||||
projectile_gravity: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
projectile::Effect::RewardEnergy(150),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(20),
|
||||
owner: None,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::BoltFire),
|
||||
projectile_light: Some(LightEmitter {
|
||||
col: (0.85, 0.5, 0.11).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile_particles: Some(ParticleEmitter {
|
||||
mode: 0,
|
||||
}),
|
||||
projectile_gravity: None,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: 400,
|
||||
holdable: true,
|
||||
prepare_duration: Duration::from_millis(800),
|
||||
recover_duration: Duration::from_millis(50),
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![
|
||||
projectile::Effect::Explode { power: 1.4 },
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Explode { power: 1.4 },
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(20),
|
||||
owner: None,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::BoltFireBig),
|
||||
projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile_particles: Some(ParticleEmitter {
|
||||
mode: 0,
|
||||
}),
|
||||
projectile_gravity: None,
|
||||
},
|
||||
],
|
||||
Staff(StaffKind::Sceptre) => vec![
|
||||
BasicMelee {
|
||||
energy_cost: 0,
|
||||
buildup_duration: Duration::from_millis(0),
|
||||
recover_duration: Duration::from_millis(300),
|
||||
base_healthchange: -1,
|
||||
range: 10.0,
|
||||
max_angle: 45.0,
|
||||
},
|
||||
BasicMelee {
|
||||
energy_cost: 350,
|
||||
buildup_duration: Duration::from_millis(0),
|
||||
recover_duration: Duration::from_millis(1000),
|
||||
base_healthchange: 15,
|
||||
range: 10.0,
|
||||
max_angle: 45.0,
|
||||
},
|
||||
],
|
||||
Shield(_) => vec![
|
||||
BasicMelee {
|
||||
energy_cost: 0,
|
||||
@ -313,35 +345,15 @@ impl Tool {
|
||||
duration: Duration::from_millis(50),
|
||||
only_up: false,
|
||||
},
|
||||
CharacterAbility::Boost {
|
||||
duration: Duration::from_millis(50),
|
||||
only_up: true,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: 0,
|
||||
holdable: false,
|
||||
prepare_duration: Duration::from_millis(0),
|
||||
recover_duration: Duration::from_millis(10),
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Stick,
|
||||
projectile::Effect::Possess,
|
||||
],
|
||||
time_left: Duration::from_secs(10),
|
||||
owner: None,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::ArrowSnake),
|
||||
projectile_light: Some(LightEmitter {
|
||||
col: (0.0, 1.0, 0.33).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile_gravity: None,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
projectile_body: Body::Object(object::Body::ArrowSnake),
|
||||
projectile_light: Some(LightEmitter {
|
||||
col: (0.0, 1.0, 0.33).into(),
|
||||
..Default::default()
|
||||
}),
|
||||
projectile_particles: None,
|
||||
projectile_gravity: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
Empty => vec![BasicMelee {
|
||||
energy_cost: 0,
|
||||
|
@ -53,4 +53,4 @@ pub use player::{Player, MAX_MOUNT_RANGE_SQR};
|
||||
pub use projectile::Projectile;
|
||||
pub use skills::{Skill, SkillGroup, SkillGroupType, SkillSet};
|
||||
pub use stats::{Exp, HealthChange, HealthSource, Level, Stats};
|
||||
pub use visual::{LightAnimation, LightEmitter};
|
||||
pub use visual::{LightAnimation, LightEmitter, ParticleEmitter};
|
||||
|
@ -46,3 +46,37 @@ impl Default for LightAnimation {
|
||||
impl Component for LightAnimation {
|
||||
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ParticleEmitter {
|
||||
|
||||
/// Mode 1: sprinkler (inital_velocity, lifespan)
|
||||
/// Mode 2: smoke (initial_position, boyancy_const, wind, lifespan)
|
||||
pub mode: u8, // enum?
|
||||
|
||||
// pub vertices: Vec<i8>,
|
||||
// pub texture: RasterFooBar,
|
||||
|
||||
// // mode 1 -- sprinkler.
|
||||
// pub initial_position: [i8; 3],
|
||||
// pub initial_velocity: [i8; 3],
|
||||
// pub lifespan: u32, // in ticks?
|
||||
|
||||
// // mode 2 -- smoke
|
||||
// pub initial_position: [i8; 3],
|
||||
// pub boyancy_const: [i8; 3],
|
||||
// pub wind_sway: [i8; 3],
|
||||
}
|
||||
|
||||
impl Default for ParticleEmitter {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mode: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ParticleEmitter {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
@ -43,6 +43,7 @@ pub enum ServerEvent {
|
||||
dir: Dir,
|
||||
body: comp::Body,
|
||||
light: Option<comp::LightEmitter>,
|
||||
particles: Option<comp::ParticleEmitter>,
|
||||
projectile: comp::Projectile,
|
||||
gravity: Option<comp::Gravity>,
|
||||
},
|
||||
|
@ -15,6 +15,7 @@ sum_type! {
|
||||
Stats(comp::Stats),
|
||||
Energy(comp::Energy),
|
||||
LightEmitter(comp::LightEmitter),
|
||||
ParticleEmitter(comp::ParticleEmitter),
|
||||
Item(comp::Item),
|
||||
Scale(comp::Scale),
|
||||
Group(comp::Group),
|
||||
@ -42,6 +43,7 @@ sum_type! {
|
||||
Stats(PhantomData<comp::Stats>),
|
||||
Energy(PhantomData<comp::Energy>),
|
||||
LightEmitter(PhantomData<comp::LightEmitter>),
|
||||
ParticleEmitter(PhantomData<comp::ParticleEmitter>),
|
||||
Item(PhantomData<comp::Item>),
|
||||
Scale(PhantomData<comp::Scale>),
|
||||
Group(PhantomData<comp::Group>),
|
||||
@ -69,6 +71,7 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPacket::Stats(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Energy(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::ParticleEmitter(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Group(comp) => sync::handle_insert(comp, entity, world),
|
||||
@ -94,6 +97,7 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPacket::Stats(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Energy(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::ParticleEmitter(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Group(comp) => sync::handle_modify(comp, entity, world),
|
||||
@ -121,6 +125,9 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPhantom::LightEmitter(_) => {
|
||||
sync::handle_remove::<comp::LightEmitter>(entity, world)
|
||||
},
|
||||
EcsCompPhantom::ParticleEmitter(_) => {
|
||||
sync::handle_remove::<comp::ParticleEmitter>(entity, world)
|
||||
},
|
||||
EcsCompPhantom::Item(_) => sync::handle_remove::<comp::Item>(entity, world),
|
||||
EcsCompPhantom::Scale(_) => sync::handle_remove::<comp::Scale>(entity, world),
|
||||
EcsCompPhantom::Group(_) => sync::handle_remove::<comp::Group>(entity, world),
|
||||
|
@ -113,6 +113,7 @@ impl State {
|
||||
ecs.register::<comp::Energy>();
|
||||
ecs.register::<comp::CanBuild>();
|
||||
ecs.register::<comp::LightEmitter>();
|
||||
ecs.register::<comp::ParticleEmitter>();
|
||||
ecs.register::<comp::Item>();
|
||||
ecs.register::<comp::Scale>();
|
||||
ecs.register::<comp::Mounting>();
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
comp::{Body, CharacterState, Gravity, LightEmitter, Projectile, StateUpdate},
|
||||
comp::{Body, CharacterState, Gravity, LightEmitter, ParticleEmitter, Projectile, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::utils::*,
|
||||
sys::character_behavior::*,
|
||||
@ -20,6 +20,7 @@ pub struct Data {
|
||||
pub projectile: Projectile,
|
||||
pub projectile_body: Body,
|
||||
pub projectile_light: Option<LightEmitter>,
|
||||
pub projectile_particles: Option<ParticleEmitter>,
|
||||
pub projectile_gravity: Option<Gravity>,
|
||||
/// Whether the attack fired already
|
||||
pub exhausted: bool,
|
||||
@ -48,6 +49,7 @@ impl CharacterBehavior for Data {
|
||||
projectile: self.projectile.clone(),
|
||||
projectile_body: self.projectile_body,
|
||||
projectile_light: self.projectile_light,
|
||||
projectile_particles: self.projectile_particles,
|
||||
projectile_gravity: self.projectile_gravity,
|
||||
exhausted: false,
|
||||
});
|
||||
@ -61,6 +63,7 @@ impl CharacterBehavior for Data {
|
||||
body: self.projectile_body,
|
||||
projectile,
|
||||
light: self.projectile_light,
|
||||
particles: self.projectile_particles,
|
||||
gravity: self.projectile_gravity,
|
||||
});
|
||||
|
||||
@ -72,6 +75,7 @@ impl CharacterBehavior for Data {
|
||||
projectile: self.projectile.clone(),
|
||||
projectile_body: self.projectile_body,
|
||||
projectile_light: self.projectile_light,
|
||||
projectile_particles: self.projectile_particles,
|
||||
projectile_gravity: self.projectile_gravity,
|
||||
exhausted: true,
|
||||
});
|
||||
@ -88,6 +92,7 @@ impl CharacterBehavior for Data {
|
||||
projectile: self.projectile.clone(),
|
||||
projectile_body: self.projectile_body,
|
||||
projectile_light: self.projectile_light,
|
||||
projectile_particles: self.projectile_particles,
|
||||
projectile_gravity: self.projectile_gravity,
|
||||
exhausted: true,
|
||||
});
|
||||
|
@ -910,6 +910,7 @@ fn handle_light(
|
||||
.create_entity_synced()
|
||||
.with(pos)
|
||||
.with(comp::ForceUpdate)
|
||||
.with(comp::ParticleEmitter { mode: 0 })
|
||||
.with(light_emitter);
|
||||
if let Some(light_offset) = light_offset_opt {
|
||||
builder.with(light_offset).build();
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{sys, Server, StateExt};
|
||||
use common::{
|
||||
comp::{
|
||||
self, group, Agent, Alignment, Body, Gravity, Item, ItemDrop, LightEmitter, Loadout, Pos,
|
||||
Projectile, Scale, Stats, Vel, WaypointArea,
|
||||
self, Agent, Alignment, Body, Gravity, Item, ItemDrop, LightEmitter, Loadout,
|
||||
ParticleEmitter, Pos, Projectile, Scale, Stats, Vel, WaypointArea,
|
||||
},
|
||||
util::Dir,
|
||||
};
|
||||
@ -77,6 +77,7 @@ pub fn handle_shoot(
|
||||
dir: Dir,
|
||||
body: Body,
|
||||
light: Option<LightEmitter>,
|
||||
particles: Option<ParticleEmitter>,
|
||||
projectile: Projectile,
|
||||
gravity: Option<Gravity>,
|
||||
) {
|
||||
@ -96,6 +97,9 @@ pub fn handle_shoot(
|
||||
if let Some(light) = light {
|
||||
builder = builder.with(light)
|
||||
}
|
||||
if let Some(particles) = particles {
|
||||
builder = builder.with(particles)
|
||||
}
|
||||
if let Some(gravity) = gravity {
|
||||
builder = builder.with(gravity)
|
||||
}
|
||||
@ -113,6 +117,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
|
||||
flicker: 1.0,
|
||||
animated: true,
|
||||
})
|
||||
.with(ParticleEmitter { mode: 0 })
|
||||
.with(WaypointArea::default())
|
||||
.build();
|
||||
}
|
||||
|
@ -61,9 +61,10 @@ impl Server {
|
||||
dir,
|
||||
body,
|
||||
light,
|
||||
particles,
|
||||
projectile,
|
||||
gravity,
|
||||
} => handle_shoot(self, entity, dir, body, light, projectile, gravity),
|
||||
} => handle_shoot(self, entity, dir, body, light, particles, projectile, gravity),
|
||||
ServerEvent::Damage { uid, change } => handle_damage(&self, uid, change),
|
||||
ServerEvent::Destroy { entity, cause } => handle_destroy(self, entity, cause),
|
||||
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
||||
|
@ -1,8 +1,9 @@
|
||||
use super::SysTimer;
|
||||
use common::{
|
||||
comp::{
|
||||
Body, CanBuild, CharacterState, Collider, Energy, Gravity, Group, Item, LightEmitter,
|
||||
Loadout, Mass, MountState, Mounting, Ori, Player, Pos, Scale, Stats, Sticky, Vel,
|
||||
Alignment, Body, CanBuild, CharacterState, Collider, Energy, Gravity, Item, LightEmitter,
|
||||
Loadout, Mass, MountState, Mounting, Ori, ParticleEmitter, Player, Pos, Scale, Stats,
|
||||
Sticky, Vel,
|
||||
},
|
||||
msg::EcsCompPacket,
|
||||
sync::{CompSyncPackage, EntityPackage, EntitySyncPackage, Uid, UpdateTracker, WorldSyncExt},
|
||||
@ -44,6 +45,7 @@ pub struct TrackedComps<'a> {
|
||||
pub energy: ReadStorage<'a, Energy>,
|
||||
pub can_build: ReadStorage<'a, CanBuild>,
|
||||
pub light_emitter: ReadStorage<'a, LightEmitter>,
|
||||
pub particle_emitter: ReadStorage<'a, ParticleEmitter>,
|
||||
pub item: ReadStorage<'a, Item>,
|
||||
pub scale: ReadStorage<'a, Scale>,
|
||||
pub mounting: ReadStorage<'a, Mounting>,
|
||||
@ -92,6 +94,10 @@ impl<'a> TrackedComps<'a> {
|
||||
.get(entity)
|
||||
.copied()
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.particle_emitter
|
||||
.get(entity)
|
||||
.copied()
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.item.get(entity).cloned().map(|c| comps.push(c.into()));
|
||||
self.scale
|
||||
.get(entity)
|
||||
@ -147,6 +153,7 @@ pub struct ReadTrackers<'a> {
|
||||
pub energy: ReadExpect<'a, UpdateTracker<Energy>>,
|
||||
pub can_build: ReadExpect<'a, UpdateTracker<CanBuild>>,
|
||||
pub light_emitter: ReadExpect<'a, UpdateTracker<LightEmitter>>,
|
||||
pub particle_emitter: ReadExpect<'a, UpdateTracker<ParticleEmitter>>,
|
||||
pub item: ReadExpect<'a, UpdateTracker<Item>>,
|
||||
pub scale: ReadExpect<'a, UpdateTracker<Scale>>,
|
||||
pub mounting: ReadExpect<'a, UpdateTracker<Mounting>>,
|
||||
@ -180,6 +187,12 @@ impl<'a> ReadTrackers<'a> {
|
||||
&comps.light_emitter,
|
||||
filter,
|
||||
)
|
||||
.with_component(
|
||||
&comps.uid,
|
||||
&*self.particle_emitter,
|
||||
&comps.particle_emitter,
|
||||
filter,
|
||||
)
|
||||
.with_component(&comps.uid, &*self.item, &comps.item, filter)
|
||||
.with_component(&comps.uid, &*self.scale, &comps.scale, filter)
|
||||
.with_component(&comps.uid, &*self.mounting, &comps.mounting, filter)
|
||||
@ -210,6 +223,7 @@ pub struct WriteTrackers<'a> {
|
||||
energy: WriteExpect<'a, UpdateTracker<Energy>>,
|
||||
can_build: WriteExpect<'a, UpdateTracker<CanBuild>>,
|
||||
light_emitter: WriteExpect<'a, UpdateTracker<LightEmitter>>,
|
||||
particle_emitter: WriteExpect<'a, UpdateTracker<ParticleEmitter>>,
|
||||
item: WriteExpect<'a, UpdateTracker<Item>>,
|
||||
scale: WriteExpect<'a, UpdateTracker<Scale>>,
|
||||
mounting: WriteExpect<'a, UpdateTracker<Mounting>>,
|
||||
@ -232,6 +246,9 @@ fn record_changes(comps: &TrackedComps, trackers: &mut WriteTrackers) {
|
||||
trackers.energy.record_changes(&comps.energy);
|
||||
trackers.can_build.record_changes(&comps.can_build);
|
||||
trackers.light_emitter.record_changes(&comps.light_emitter);
|
||||
trackers
|
||||
.particle_emitter
|
||||
.record_changes(&comps.particle_emitter);
|
||||
trackers.item.record_changes(&comps.item);
|
||||
trackers.scale.record_changes(&comps.scale);
|
||||
trackers.mounting.record_changes(&comps.mounting);
|
||||
@ -287,6 +304,7 @@ pub fn register_trackers(world: &mut World) {
|
||||
world.register_tracker::<Energy>();
|
||||
world.register_tracker::<CanBuild>();
|
||||
world.register_tracker::<LightEmitter>();
|
||||
world.register_tracker::<ParticleEmitter>();
|
||||
world.register_tracker::<Item>();
|
||||
world.register_tracker::<Scale>();
|
||||
world.register_tracker::<Mounting>();
|
||||
|
Loading…
Reference in New Issue
Block a user