Skip to main content

steel_core/behavior/blocks/building/
magma_block.rs

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