github.com/df-mc/dragonfly@v0.9.13/server/item/enchantment/damage.go (about) 1 package enchantment 2 3 import ( 4 "github.com/df-mc/dragonfly/server/item" 5 "github.com/df-mc/dragonfly/server/world" 6 "math" 7 ) 8 9 // AffectedDamageSource represents a world.DamageSource whose damage may be 10 // affected by an enchantment. A world.DamageSource does not need to implement 11 // AffectedDamageSource to let Protection affect the damage. This happens 12 // depending on the (world.DamageSource).ReducedByResistance() method. 13 type AffectedDamageSource interface { 14 world.DamageSource 15 // AffectedByEnchantment specifies if a world.DamageSource is affected by 16 // the item.EnchantmentType passed. 17 AffectedByEnchantment(e item.EnchantmentType) bool 18 } 19 20 // DamageModifier is an item.EnchantmentType that can reduce damage through a 21 // modifier if an AffectedDamageSource returns true for it. 22 type DamageModifier interface { 23 Modifier() float64 24 } 25 26 // ProtectionFactor calculates the combined protection factor for a slice of 27 // item.Enchantment. The factor depends on the world.DamageSource passed and is 28 // in a range of [0, 0.8], where 0.8 means incoming damage would be reduced by 29 // 80%. 30 func ProtectionFactor(src world.DamageSource, enchantments []item.Enchantment) float64 { 31 f := 0.0 32 for _, e := range enchantments { 33 t := e.Type() 34 modifier, ok := t.(DamageModifier) 35 if !ok { 36 continue 37 } 38 reduced := false 39 if _, ok := t.(Protection); ok && src.ReducedByResistance() { 40 // Special case for Protection, because it applies to all damage 41 // sources by default, except those not reduced by resistance. 42 reduced = true 43 } else if asrc, ok := src.(AffectedDamageSource); ok && asrc.AffectedByEnchantment(t) { 44 reduced = true 45 } 46 47 if reduced { 48 f += float64(e.Level()) * modifier.Modifier() 49 } 50 } 51 return math.Min(f, 0.8) 52 }