steel_core/entity/mob_effect/
heal_or_harm.rs1use steel_registry::vanilla_damage_types;
4
5use super::{InstantaneousMobEffect, MobEffectBehavior};
6use crate::entity::LivingEntity;
7use crate::entity::damage::DamageSource;
8use crate::world::World;
9
10pub struct HealOrHarmBehavior {
12 pub is_harm: bool,
14}
15
16const BASE_HEAL_AMOUNT: i32 = 4;
18const BASE_HARM_AMOUNT: i32 = 6;
20
21impl MobEffectBehavior for HealOrHarmBehavior {
22 fn as_instantaneous(&self) -> Option<&dyn InstantaneousMobEffect> {
23 Some(self)
24 }
25
26 fn apply_effect_tick(&self, world: &World, user: &dyn LivingEntity, amplifier: i32) -> bool {
29 if self.is_harm == user.is_inverted_heal_and_harm() {
30 let amount = BASE_HEAL_AMOUNT.wrapping_shl(amplifier as u32).max(0);
33 user.heal(amount as f32);
34 } else {
35 user.hurt(
36 world,
37 &DamageSource::environment(&vanilla_damage_types::MAGIC),
38 BASE_HARM_AMOUNT.wrapping_shl(amplifier as u32) as f32,
39 );
40 }
41 true
42 }
43}
44
45impl InstantaneousMobEffect for HealOrHarmBehavior {
46 fn apply_instantaneous(
51 &self,
52 world: &World,
53 user: &dyn LivingEntity,
54 amplifier: i32,
55 direct_entity: Option<i32>,
56 causing_entity: Option<i32>,
57 scale: f32,
58 ) {
59 if self.is_harm == user.is_inverted_heal_and_harm() {
60 let amount =
61 (scale * (BASE_HEAL_AMOUNT.wrapping_shl(amplifier as u32) as f32) + 0.5) as i32;
62 user.heal(amount as f32);
63 } else {
64 let mut source = DamageSource::environment(if direct_entity.is_some() {
65 &vanilla_damage_types::INDIRECT_MAGIC
66 } else {
67 &vanilla_damage_types::MAGIC
68 });
69 if let Some(entity_id) = direct_entity {
70 source = source.with_direct_entity(entity_id);
71 }
72 if let Some(entity_id) = causing_entity {
73 source = source.with_causing_entity(entity_id);
74 }
75 let amount =
78 (scale * (BASE_HARM_AMOUNT.wrapping_shl(amplifier as u32) as f32) + 0.5) as i32;
79 user.hurt(world, &source, amount as f32);
80 }
81 }
82}