steel_core/behavior/blocks/building/
magma_block.rs1use std::sync::Arc;
2
3use steel_macros::block_behavior;
4use steel_registry::blocks::BlockRef;
5use steel_registry::vanilla_damage_types;
6use steel_utils::{BlockPos, BlockStateId};
7
8use crate::{
9 behavior::{BlockBehavior, BlockPlaceContext},
10 entity::{Entity, damage::DamageSource},
11 world::World,
12};
13
14#[block_behavior]
16pub struct MagmaBlock {
17 block: BlockRef,
18}
19
20impl MagmaBlock {
21 #[must_use]
23 pub const fn new(block: BlockRef) -> Self {
24 Self { block }
25 }
26
27 #[must_use]
28 const fn step_damage_amount(
29 is_stepping_carefully: bool,
30 is_living_entity: bool,
31 ) -> Option<f32> {
32 if !is_stepping_carefully && is_living_entity {
33 Some(1.0)
34 } else {
35 None
36 }
37 }
38}
39
40impl BlockBehavior for MagmaBlock {
41 fn get_state_for_placement(&self, _context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
42 Some(self.block.default_state())
43 }
44
45 fn step_on(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity) {
46 if let Some(damage) =
47 Self::step_damage_amount(entity.is_stepping_carefully(), entity.is_living_entity())
48 {
49 entity.hurt(
50 world,
51 &DamageSource::environment(&vanilla_damage_types::HOT_FLOOR),
52 damage,
53 );
54 }
55
56 self.default_step_on(state, world, pos, entity);
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn magma_damages_non_careful_living_entities() {
66 assert_eq!(MagmaBlock::step_damage_amount(false, true), Some(1.0));
67 }
68
69 #[test]
70 fn magma_does_not_damage_careful_living_entities() {
71 assert_eq!(MagmaBlock::step_damage_amount(true, true), None);
72 }
73
74 #[test]
75 fn magma_does_not_damage_non_living_entities() {
76 assert_eq!(MagmaBlock::step_damage_amount(false, false), None);
77 }
78}