Skip to content

Commit 3265c3c

Browse files
authored
Merge pull request #17 from temper-mc/feature/proper-block-placing
Basic block placing
2 parents 7a157e3 + 21f3414 commit 3265c3c

File tree

25 files changed

+683
-106
lines changed

25 files changed

+683
-106
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ members = [
3434
"src/game_systems/src/packets",
3535
"src/game_systems/src/physics",
3636
"src/game_systems/src/player",
37+
"src/game_systems/src/world",
38+
"src/world/block-placing",
3739
"src/inventories",
3840
"src/messages",
3941
"src/net/codec",

src/app/runtime/src/game_loop.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use temper_config::server_config::get_global_config;
1818
use temper_game_systems::{
1919
LanPinger, chunk_unloader, keep_alive_system, register_background_systems,
2020
register_mob_systems, register_packet_handlers, register_physics_systems,
21-
register_player_systems, register_shutdown_systems, update_player_ping, world_sync,
21+
register_player_systems, register_shutdown_systems, register_world_systems, update_player_ping,
22+
world_sync,
2223
};
2324
use temper_messages::register_messages;
2425
use temper_net_runtime::connection::{NewConnection, handle_connection};
@@ -259,6 +260,7 @@ fn build_timed_scheduler() -> Scheduler {
259260
register_background_systems(s); // Systems that run in the background (day cycle, chunk sending, etc.)
260261
register_physics_systems(s); // Physics systems (movement, collision, etc.)
261262
register_mob_systems(s); // Mob AI and behavior
263+
register_world_systems(s); // World updates (block changes, redstone, etc.)
262264
};
263265
let tick_period = Duration::from_secs(1) / get_global_config().tps;
264266
timed.register(

src/base/macros/src/block/mod.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ pub fn block(input: TokenStream) -> TokenStream {
162162

163163
if matched.is_empty() {
164164
let properties = get_properties(&filtered_names);
165-
if properties.is_empty() {
166-
return syn::Error::new_spanned(
165+
return if properties.is_empty() {
166+
syn::Error::new_spanned(
167167
name_str.clone(),
168168
format!(
169169
"block '{}' has no properties but the following properties were given: {}",
@@ -172,18 +172,18 @@ pub fn block(input: TokenStream) -> TokenStream {
172172
),
173173
)
174174
.to_compile_error()
175-
.into();
175+
.into()
176176
} else {
177-
return syn::Error::new_spanned(
178-
name_str.clone(),
179-
format!(
180-
"no variant of block '{}' matches the specified properties. Available properties: {}",
181-
name_str.clone(), pretty_print_props(&properties)
182-
),
183-
)
184-
.to_compile_error()
185-
.into();
186-
}
177+
syn::Error::new_spanned(
178+
name_str.clone(),
179+
format!(
180+
"no variant of block '{}' matches the specified properties. Available properties: {}",
181+
name_str.clone(), pretty_print_props(&properties)
182+
),
183+
)
184+
.to_compile_error()
185+
.into()
186+
};
187187
}
188188
if matched.len() > 1 {
189189
return syn::Error::new_spanned(

src/base/macros/src/item/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use quote::quote;
2+
use simd_json::prelude::*;
3+
4+
const REGISTRY_FILE: &[u8] = include_bytes!("../../../../../assets/data/registries.json");
5+
6+
pub(super) fn item(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
7+
let mut buf = REGISTRY_FILE.to_vec();
8+
9+
let parsed = simd_json::to_owned_value(&mut buf).unwrap();
10+
11+
let target_name = syn::parse_macro_input!(input as syn::LitStr).value();
12+
13+
let prefixed_name = if target_name.starts_with("minecraft:") {
14+
target_name.clone()
15+
} else {
16+
format!("minecraft:{}", target_name)
17+
};
18+
19+
let id = parsed
20+
.get("minecraft:item")
21+
.expect("Failed to get 'minecraft:item' from registries.json")
22+
.get("entries")
23+
.expect("Failed to get 'entries' from 'minecraft:item' in registries.json")
24+
.get(&prefixed_name)
25+
.unwrap_or_else(|| {
26+
panic!(
27+
"Failed to find item 'minecraft:{}' in registries.json",
28+
prefixed_name
29+
)
30+
})
31+
.get_i32("protocol_id")
32+
.unwrap_or_else(|| {
33+
panic!(
34+
"Failed to get 'protocol_id' for item 'minecraft:{}' in registries.json",
35+
prefixed_name
36+
)
37+
});
38+
39+
quote! {
40+
temper_inventories::item::ItemID(temper_codec::net_types::var_int::VarInt(#id))
41+
}
42+
.into()
43+
}

src/base/macros/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use proc_macro::TokenStream;
66
mod block;
77
mod commands;
88
mod helpers;
9+
mod item;
910
mod misc;
1011
mod nbt;
1112
mod net;
@@ -155,3 +156,18 @@ pub fn match_block(input: TokenStream) -> TokenStream {
155156
pub fn enum_discriminant(input: TokenStream) -> TokenStream {
156157
misc::discriminant::enum_discriminant_derive(input)
157158
}
159+
160+
/// A macro to lookup item IDs at compile time.
161+
/// Feed in the item name as a string literal, and it will output a [`temper_inventories::item::ItemID`] struct with the correct ID for that item.
162+
/// Usage:
163+
/// ```ignore
164+
/// # use temper_inventories::item::ItemID;
165+
/// # use temper_macros::item;
166+
/// let item_id = item!("apple");
167+
/// assert_eq!(item_id, ItemID::new(temper_codec::VarInt::new(857)));
168+
/// ```
169+
/// The `minecraft:` namespace is optional and will be added automatically if not present.
170+
#[proc_macro]
171+
pub fn item(input: TokenStream) -> TokenStream {
172+
item::item(input)
173+
}

src/core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ temper-nbt = { workspace = true }
2121
temper-macros = { workspace = true }
2222
serde = { workspace = true }
2323
serde_json = { workspace = true }
24+
once_cell = { workspace = true }

src/core/src/block_state_id.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ use ahash::RandomState;
33
use bitcode_derive::{Decode, Encode};
44
use deepsize::DeepSizeOf;
55
use lazy_static::lazy_static;
6+
use once_cell::sync::Lazy;
67
use std::collections::HashMap;
78
use std::fmt::Display;
89
use std::process::exit;
10+
use std::str::FromStr;
911
use temper_codec::net_types::var_int::VarInt;
1012
use tracing::{error, warn};
1113

@@ -109,6 +111,10 @@ impl BlockData {
109111
.to_block_data()
110112
.expect("Block state ID not found in block mappings file")
111113
}
114+
115+
pub fn try_to_block_state_id(&self) -> Option<BlockStateId> {
116+
Some(BlockStateId::from_block_data(self))
117+
}
112118
}
113119
impl From<BlockData> for BlockStateId {
114120
fn from(block_data: BlockData) -> Self {
@@ -144,3 +150,19 @@ impl Default for BlockStateId {
144150
Self(0)
145151
}
146152
}
153+
154+
const ITEM_TO_BLOCK_MAPPING_FILE: &str =
155+
include_str!("../../../assets/data/item_to_block_mapping.json");
156+
pub static ITEM_TO_BLOCK_MAPPING: Lazy<HashMap<i32, BlockStateId>> = Lazy::new(|| {
157+
let str_form: HashMap<String, String> = serde_json::from_str(ITEM_TO_BLOCK_MAPPING_FILE)
158+
.expect("Failed to parse item_to_block_mapping.json");
159+
str_form
160+
.into_iter()
161+
.map(|(k, v)| {
162+
(
163+
i32::from_str(&k).unwrap(),
164+
BlockStateId::new(u32::from_str(&v).unwrap()),
165+
)
166+
})
167+
.collect()
168+
});

src/core/src/pos.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use bitcode_derive::{Decode, Encode};
1515
use deepsize::DeepSizeOf;
1616
use temper_codec::net_types::network_position::NetworkPosition;
1717

18-
#[derive(Clone, Copy)]
18+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1919
pub struct BlockPos {
2020
/// (i26, i12, i26)
2121
pub pos: IVec3,

src/game_systems/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ packets = { path = "./src/packets" }
1010
physics = { path = "./src/physics" }
1111
player = { path = "./src/player" }
1212
shutdown = { path = "./src/shutdown" }
13+
world = { path = "./src/world" }
1314

1415
bevy_ecs = { workspace = true }
1516

src/game_systems/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ pub use packets::register_packet_handlers;
77
pub use physics::register_physics_systems;
88
pub use player::{register_player_systems, update_player_ping};
99
pub use shutdown::register_shutdown_systems;
10+
pub use world::register_world_systems;

0 commit comments

Comments
 (0)