forked from feather-rs/feather
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.rs
More file actions
60 lines (52 loc) · 2.01 KB
/
init.rs
File metadata and controls
60 lines (52 loc) · 2.01 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
use crate::{chest, ShouldReplace};
use ahash::AHashMap;
use feather_core::blocks::BlockKind;
use feather_core::util::BlockPosition;
use feather_server_types::{BlockEntity, BlockUpdateEvent, EntitySpawnEvent, Game};
use fecs::{EntityBuilder, World};
use once_cell::sync::Lazy;
type BlockEntityCreator = fn(BlockPosition) -> EntityBuilder;
/// Global mapping of blocks which require block entities.
static BLOCK_ENTITY_MAP: Lazy<AHashMap<BlockKind, BlockEntityCreator>> = Lazy::new(|| {
let mut map: AHashMap<_, fn(BlockPosition) -> EntityBuilder> = AHashMap::new();
map.insert(BlockKind::Chest, chest::create);
map
});
/// When a block is created, and there is a block entity kind
/// associated with it, creates the block entity. Additionally,
/// removes any old block entity, if it existed.
#[fecs::event_handler]
pub fn on_block_update_create_block_entity(
event: &BlockUpdateEvent,
game: &mut Game,
world: &mut World,
) {
if let Some(entity) = game.block_entities.get(&event.pos).copied() {
// Determine whether we should replace the entity
// or keep the existing block entity.
if let Some(should_replace) = world.try_get::<ShouldReplace>(entity).map(|x| x.0) {
if !should_replace(event.old, event.new) {
return; // should keep existing block entity; block entities remain unchanged
}
}
game.block_entities.remove(&event.pos);
game.despawn(entity, world);
}
if let Some(init) = BLOCK_ENTITY_MAP.get(&event.new.kind()) {
// Spawn block entity
let entity = init(event.pos).build().spawn_in(world);
game.handle(world, EntitySpawnEvent { entity });
}
}
#[fecs::event_handler]
pub fn on_block_entity_create_insert_to_map(
event: &EntitySpawnEvent,
game: &mut Game,
world: &mut World,
) {
if let Some(pos) = world.try_get::<BlockPosition>(event.entity) {
if world.has::<BlockEntity>(event.entity) {
game.block_entities.insert(*pos, event.entity);
}
}
}