forked from feather-rs/feather
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmod.rs
More file actions
182 lines (150 loc) · 5.12 KB
/
mod.rs
File metadata and controls
182 lines (150 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Dealing with entities, including associated components and events.
//! Submodules here are implementations of specific entities, such as items,
//! block entities, monsters, etc. Player entities are handled in `crate::player`,
//! not here.
mod mob;
mod object;
pub use mob::*;
pub use object::*;
use crate::game::Game;
use feather_core::entity::EntityData;
use feather_core::{Packet, Position};
use fecs::{EntityBuilder, EntityRef, IntoQuery, Read, World, Write};
use std::ops::{Deref, DerefMut};
use std::sync::atomic::{AtomicI32, Ordering};
/// ID of an entity. This value is generally unique.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct EntityId(pub i32);
/// Entity ID counter, used to create new entity IDs.
pub static ENTITY_ID_COUNTER: AtomicI32 = AtomicI32::new(0);
/// The velocity of an entity.
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Velocity(pub glm::DVec3);
/// The velocity of an entity on the previous tick.
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct PreviousVelocity(pub glm::DVec3);
impl Default for Velocity {
fn default() -> Self {
Self(glm::vec3(0.0, 0.0, 0.0))
}
}
impl Deref for Velocity {
type Target = glm::DVec3;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Velocity {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Default for PreviousVelocity {
fn default() -> Self {
Self(glm::vec3(0.0, 0.0, 0.0))
}
}
impl Deref for PreviousVelocity {
type Target = glm::DVec3;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PreviousVelocity {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
/// The display name of an entity.
///
/// Note that unnamed entities do not have this component.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Name(pub String);
/// Position of an entity on the last tick.
///
/// This is updated by `position_reset` system.
#[derive(Debug, Clone, Copy)]
pub struct PreviousPosition(pub Position);
pub trait PacketCreatorFn: Fn(&EntityRef) -> Box<dyn Packet> + Send + Sync + 'static {}
impl<F> PacketCreatorFn for F where F: Fn(&EntityRef) -> Box<dyn Packet> + Send + Sync + 'static {}
/// Component which defines a function returning a packet to send
/// to clients when the entity comes within range. This packet
/// spawns the entity on the client.
pub struct SpawnPacketCreator(pub &'static dyn PacketCreatorFn);
impl SpawnPacketCreator {
/// Returns the packet to send to clients when the entity is to be
/// sent to the client.
pub fn get(&self, accessor: &EntityRef) -> Box<dyn Packet> {
let f = self.0;
f(accessor)
}
}
/// Component which defines a function returning a packet to send
/// to _all_ clients when the entity is created or the client joins.
/// This packet is sent before that returned by `SpawnPacketCreator`,
/// and it differs in that the packet is broadcasted globally
/// rather than to nearby clients.
///
/// Another difference is that the packet from `SpawnPacketCreator` is not sent
/// to its own entity, while that from `CreationPacketCreator` is.
///
/// An example of a use case for this packet is the `PlayerInfo` packet
/// sent when a player joins—it is sent to all players, not just those
/// that are able to see the player.
pub struct CreationPacketCreator(pub &'static dyn PacketCreatorFn);
impl CreationPacketCreator {
/// Returns the packet to send to clients when the entity is created.
pub fn get(&self, accessor: &EntityRef) -> Box<dyn Packet> {
let f = self.0;
f(accessor)
}
}
pub trait ComponentSerializerFn:
Fn(&Game, &EntityRef) -> EntityData + Send + Sync + 'static
{
}
impl<F> ComponentSerializerFn for F where
F: Fn(&Game, &EntityRef) -> EntityData + Send + Sync + 'static
{
}
/// Component which stores a function needed to convert an entity's
/// components to the serializable `EntityData`.
pub struct ComponentSerializer(pub &'static dyn ComponentSerializerFn);
impl ComponentSerializer {
pub fn serialize(&self, game: &Game, accessor: &EntityRef) -> EntityData {
let f = self.0;
f(game, accessor)
}
}
#[system]
pub fn previous_position_velocity_reset(world: &mut World) {
<(Read<Position>, Write<PreviousPosition>)>::query().par_for_each_mut(
world.inner_mut(),
|(pos, mut previous_pos)| {
previous_pos.0 = *pos;
},
);
<(Read<Velocity>, Write<PreviousVelocity>)>::query().par_for_each_mut(
world.inner_mut(),
|(vel, mut previous_vel)| {
previous_vel.0 = vel.0;
},
);
}
/// Inserts the base components for an entity into an `EntityBuilder`.
///
/// This currently includes:
/// * Velocity (0) and PreviousVelocity
/// * Entity ID for the protocol
pub fn base() -> EntityBuilder {
let id = new_id();
EntityBuilder::new()
.with(EntityId(id))
.with(Velocity::default())
.with(PreviousVelocity::default())
.with(PreviousPosition(position!(0.0, 0.0, 0.0)))
}
/// Returns a new entity ID.
pub fn new_id() -> i32 {
ENTITY_ID_COUNTER.fetch_add(1, Ordering::Relaxed)
}