From fc8942cda833e4d4cfbf37be6aaabfa442b5f02c Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:58:25 -0400 Subject: [PATCH 01/13] e --- server/player/player.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/player/player.go b/server/player/player.go index 667d64b2c..f2958a958 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -529,7 +529,7 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { totalDamage := p.FinalDamageFrom(dmg, source) damageLeft := totalDamage - if a := p.absorption(); a > 0 { + if a := p.Absorption(); a > 0 { if damageLeft > a { damageLeft -= a p.SetAbsorption(0) @@ -598,7 +598,7 @@ func (p *Player) FinalDamageFrom(dmg float64, src damage.Source) float64 { return math.Max(dmg, 0) } -// SetAbsorption sets the absorption health of a player. This extra health shows as golden hearts and do not +// SetAbsorption sets the Absorption health of a player. This extra health shows as golden hearts and do not // actually increase the maximum health. Once the hearts are lost, they will not regenerate. // Nothing happens if a negative number is passed. func (p *Player) SetAbsorption(health float64) { @@ -607,8 +607,8 @@ func (p *Player) SetAbsorption(health float64) { p.session().SendAbsorption(health) } -// absorption returns the absorption health that the player has. -func (p *Player) absorption() float64 { +// Absorption returns the Absorption health that the player has. +func (p *Player) Absorption() float64 { return p.absorptionHealth.Load() } From 5db932282cc6e27a891878c05e7ef8e4c25cac61 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:59:14 -0400 Subject: [PATCH 02/13] e 2 --- server/player/player.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/player/player.go b/server/player/player.go index f2958a958..cd6bca061 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -598,7 +598,7 @@ func (p *Player) FinalDamageFrom(dmg float64, src damage.Source) float64 { return math.Max(dmg, 0) } -// SetAbsorption sets the Absorption health of a player. This extra health shows as golden hearts and do not +// SetAbsorption sets the absorption health of a player. This extra health shows as golden hearts and do not // actually increase the maximum health. Once the hearts are lost, they will not regenerate. // Nothing happens if a negative number is passed. func (p *Player) SetAbsorption(health float64) { @@ -607,7 +607,7 @@ func (p *Player) SetAbsorption(health float64) { p.session().SendAbsorption(health) } -// Absorption returns the Absorption health that the player has. +// Absorption returns the absorption health that the player has. func (p *Player) Absorption() float64 { return p.absorptionHealth.Load() } From 0f0bfc1c869b525d91631e27a5dab3ddff5fc9f0 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 02:48:30 -0400 Subject: [PATCH 03/13] pog --- server/entity/damage/source.go | 13 +++++++++++- server/item/enchantment/register.go | 2 +- server/player/player.go | 31 ++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/server/entity/damage/source.go b/server/entity/damage/source.go index 62121826b..bc9cc3595 100644 --- a/server/entity/damage/source.go +++ b/server/entity/damage/source.go @@ -1,6 +1,9 @@ package damage -import "github.com/df-mc/dragonfly/server/world" +import ( + "github.com/df-mc/dragonfly/server/entity" + "github.com/df-mc/dragonfly/server/world" +) type ( // Source represents the source of the damage dealt to an entity. This source may be passed to the Hurt() @@ -64,6 +67,12 @@ type ( // respectively. Projectile, Owner world.Entity } + + // SourceThorns is used for damage caused by thorns. + SourceThorns struct { + // Owner holds the entity wearing the thorns armour. + Owner entity.Living + } ) func (SourceCactus) ReducedByResistance() bool { return true } @@ -92,3 +101,5 @@ func (SourceLava) ReducedByResistance() bool { return true } func (SourceLava) ReducedByArmour() bool { return true } func (SourceProjectile) ReducedByResistance() bool { return true } func (SourceProjectile) ReducedByArmour() bool { return true } +func (SourceThorns) ReducedByResistance() bool { return true } +func (SourceThorns) ReducedByArmour() bool { return false } diff --git a/server/item/enchantment/register.go b/server/item/enchantment/register.go index c55e67324..0f6000582 100644 --- a/server/item/enchantment/register.go +++ b/server/item/enchantment/register.go @@ -8,7 +8,7 @@ func init() { item.RegisterEnchantment(2, FeatherFalling{}) item.RegisterEnchantment(3, BlastProtection{}) item.RegisterEnchantment(4, ProjectileProtection{}) - // TODO: (5) Thorns. + item.RegisterEnchantment(5, Thorns{}) // TODO: (6) Respiration. // TODO: (7) Depth Strider. item.RegisterEnchantment(8, AquaAffinity{}) diff --git a/server/player/player.go b/server/player/player.go index 949fca45f..d1e30a4e2 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -545,9 +545,38 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { p.Exhaust(0.1) damageToArmour := int(math.Max(math.Floor(dmg/4), 1)) + damageToAttacker := 0 + thornsArmour := make([]item.Stack, 0, 4) for slot, it := range p.armour.Slots() { + thornsArmour = append(thornsArmour, it) if _, ok := it.Item().(item.Durable); ok { - _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour)) + thornsDamage := 0 + if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Intn(99) < e.Level()*15 { + thornsDamage = 1 + if e.Level() > 10 { + damageToAttacker += e.Level() - 10 + } else { + damageToAttacker += 1 + rand.Intn(3) + } + } + _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour+thornsDamage)) + } + } + if length := len(thornsArmour); length > 0 { + slot := rand.Intn(length) + it := thornsArmour[slot] + _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, 2)) + + if damageToAttacker > 0 { + var attacker world.Entity + if s, ok := source.(damage.SourceEntityAttack); ok { + attacker = s.Attacker + } else if s, ok := source.(damage.SourceProjectile); ok { + attacker = s.Owner + } + if l, ok := attacker.(entity.Living); ok { + l.Hurt(float64(damageToAttacker), damage.SourceThorns{Owner: l}) + } } } } From 90235e33a4655c79f6a7f1b356091f0e9601d726 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 02:51:12 -0400 Subject: [PATCH 04/13] fix --- server/player/player.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/player/player.go b/server/player/player.go index d1e30a4e2..546ded37e 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -548,10 +548,10 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { damageToAttacker := 0 thornsArmour := make([]item.Stack, 0, 4) for slot, it := range p.armour.Slots() { - thornsArmour = append(thornsArmour, it) if _, ok := it.Item().(item.Durable); ok { thornsDamage := 0 if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Intn(99) < e.Level()*15 { + thornsArmour = append(thornsArmour, it) thornsDamage = 1 if e.Level() > 10 { damageToAttacker += e.Level() - 10 From a51301c243d8d636ac3eeb218252861f03fea9e7 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 02:51:51 -0400 Subject: [PATCH 05/13] forgot to add the thorns enchant! --- server/item/enchantment/thorns.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 server/item/enchantment/thorns.go diff --git a/server/item/enchantment/thorns.go b/server/item/enchantment/thorns.go new file mode 100644 index 000000000..7f2c64744 --- /dev/null +++ b/server/item/enchantment/thorns.go @@ -0,0 +1,24 @@ +package enchantment + +import ( + "github.com/df-mc/dragonfly/server/item" +) + +// Thorns is an enchantment that inflicts damage on attackers. +type Thorns struct{} + +// Name ... +func (Thorns) Name() string { + return "Thorns" +} + +// MaxLevel ... +func (Thorns) MaxLevel() int { + return 3 +} + +// CompatibleWith ... +func (Thorns) CompatibleWith(s item.Stack) bool { + _, ok := s.Item().(item.Armour) + return ok +} From 3fae4bcaf19386e65c5bb6c0627b5747099647cf Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 02:52:53 -0400 Subject: [PATCH 06/13] fix import cycle --- server/entity/damage/source.go | 3 +-- server/player/player.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/server/entity/damage/source.go b/server/entity/damage/source.go index bc9cc3595..5c43fa5ce 100644 --- a/server/entity/damage/source.go +++ b/server/entity/damage/source.go @@ -1,7 +1,6 @@ package damage import ( - "github.com/df-mc/dragonfly/server/entity" "github.com/df-mc/dragonfly/server/world" ) @@ -71,7 +70,7 @@ type ( // SourceThorns is used for damage caused by thorns. SourceThorns struct { // Owner holds the entity wearing the thorns armour. - Owner entity.Living + Owner world.Entity } ) diff --git a/server/player/player.go b/server/player/player.go index 546ded37e..e375805f9 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -575,7 +575,7 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { attacker = s.Owner } if l, ok := attacker.(entity.Living); ok { - l.Hurt(float64(damageToAttacker), damage.SourceThorns{Owner: l}) + l.Hurt(float64(damageToAttacker), damage.SourceThorns{Owner: attacker}) } } } From 5acef99588380ab21a3e7e6574c71503947bbe3f Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:20:54 -0400 Subject: [PATCH 07/13] Update player.go --- server/player/player.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/player/player.go b/server/player/player.go index e375805f9..1158a3c2d 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -545,11 +545,11 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { p.Exhaust(0.1) damageToArmour := int(math.Max(math.Floor(dmg/4), 1)) - damageToAttacker := 0 + var damageToAttacker int thornsArmour := make([]item.Stack, 0, 4) for slot, it := range p.armour.Slots() { if _, ok := it.Item().(item.Durable); ok { - thornsDamage := 0 + var thornsDamage int if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Intn(99) < e.Level()*15 { thornsArmour = append(thornsArmour, it) thornsDamage = 1 From 893a78fa7d1f7f71cac4ca62958f0ae606ca1d8e Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:24:29 -0400 Subject: [PATCH 08/13] Update thorns.go --- server/item/enchantment/thorns.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/server/item/enchantment/thorns.go b/server/item/enchantment/thorns.go index 7f2c64744..ed3c7bd7b 100644 --- a/server/item/enchantment/thorns.go +++ b/server/item/enchantment/thorns.go @@ -2,6 +2,7 @@ package enchantment import ( "github.com/df-mc/dragonfly/server/item" + "github.com/df-mc/dragonfly/server/world" ) // Thorns is an enchantment that inflicts damage on attackers. @@ -17,8 +18,18 @@ func (Thorns) MaxLevel() int { return 3 } -// CompatibleWith ... -func (Thorns) CompatibleWith(s item.Stack) bool { - _, ok := s.Item().(item.Armour) +// Rarity ... +func (Thorns) Rarity() item.EnchantmentRarity { + return item.EnchantmentRarityVeryRare +} + +// CompatibleWithEnchantment ... +func (Thorns) CompatibleWithEnchantment(item.EnchantmentType) bool { + return true +} + +// CompatibleWithItem ... +func (Thorns) CompatibleWithItem(i world.Item) bool { + _, ok := i.(item.Armour) return ok } From 0f99ddb70b9850a5ff91f819b0597807b4409f7f Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:25:05 -0400 Subject: [PATCH 09/13] Update source.go --- server/entity/damage/source.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/entity/damage/source.go b/server/entity/damage/source.go index 408e83c42..9d121d9d5 100644 --- a/server/entity/damage/source.go +++ b/server/entity/damage/source.go @@ -74,8 +74,8 @@ type ( SourceThorns struct { // Owner holds the entity wearing the thorns armour. Owner world.Entity - } - + } + // SourceBlock is used for damage caused by a block, such as an anvil. SourceBlock struct { // Block is the block that caused the damage. From 7ef4dc6e0c4a0eaa0284b0b5dd2ec555867ea1dc Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Fri, 15 Jul 2022 04:14:52 -0400 Subject: [PATCH 10/13] Update server/player/player.go Co-authored-by: DaPigGuy --- server/player/player.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/player/player.go b/server/player/player.go index 722d9db5d..d2f6db95f 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -568,7 +568,7 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { if e.Level() > 10 { damageToAttacker += e.Level() - 10 } else { - damageToAttacker += 1 + rand.Intn(3) + damageToAttacker += 1 + rand.Intn(4) } } _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour+thornsDamage)) From 6bdff3ea1e99e5496dae3652c7681f9f8df857fe Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Fri, 15 Jul 2022 04:15:28 -0400 Subject: [PATCH 11/13] Update server/player/player.go Co-authored-by: DaPigGuy --- server/player/player.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/player/player.go b/server/player/player.go index d2f6db95f..33c3a98af 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -562,7 +562,7 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { for slot, it := range p.armour.Slots() { if _, ok := it.Item().(item.Durable); ok { var thornsDamage int - if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Intn(99) < e.Level()*15 { + if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Float64() < e.Level()*0.15 { thornsArmour = append(thornsArmour, it) thornsDamage = 1 if e.Level() > 10 { From ec67700f3c3e5926689bab4edace224ffff85897 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Fri, 15 Jul 2022 18:46:14 -0400 Subject: [PATCH 12/13] fixes --- server/player/player.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/server/player/player.go b/server/player/player.go index 2432975e4..633480969 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -558,26 +558,24 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { damageToArmour := int(math.Max(math.Floor(dmg/4), 1)) var damageToAttacker int - thornsArmour := make([]item.Stack, 0, 4) + thornsArmour := map[int]item.Stack{} for slot, it := range p.armour.Slots() { if _, ok := it.Item().(item.Durable); ok { - var thornsDamage int - if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Float64() < e.Level()*0.15 { - thornsArmour = append(thornsArmour, it) - thornsDamage = 1 + if e, ok := it.Enchantment(enchantment.Thorns{}); ok && rand.Float64() < float64(e.Level())*0.15 { + damageToArmour++ + thornsArmour[slot] = it if e.Level() > 10 { damageToAttacker += e.Level() - 10 } else { damageToAttacker += 1 + rand.Intn(4) } } - _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour+thornsDamage)) + _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour)) } } - if length := len(thornsArmour); length > 0 { - slot := rand.Intn(length) - it := thornsArmour[slot] - _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, 2)) + // Damage a random thorns piece that the user is wearing. + for slot, item := range thornsArmour { + _ = p.armour.Inventory().SetItem(slot, p.damageItem(item, 2)) if damageToAttacker > 0 { var attacker world.Entity @@ -590,6 +588,7 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { l.Hurt(float64(damageToAttacker), damage.SourceThorns{Owner: attacker}) } } + break } } From f11dddb245bbba98d89d0c4cf2cbb6330112610a Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Fri, 15 Jul 2022 22:48:43 -0400 Subject: [PATCH 13/13] more stuff --- server/player/player.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server/player/player.go b/server/player/player.go index 633480969..8033fe448 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -28,6 +28,7 @@ import ( "github.com/df-mc/dragonfly/server/world/sound" "github.com/go-gl/mathgl/mgl64" "github.com/google/uuid" + "golang.org/x/exp/maps" "golang.org/x/text/language" "math" "math/rand" @@ -573,10 +574,12 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { _ = p.armour.Inventory().SetItem(slot, p.damageItem(it, damageToArmour)) } } - // Damage a random thorns piece that the user is wearing. - for slot, item := range thornsArmour { - _ = p.armour.Inventory().SetItem(slot, p.damageItem(item, 2)) + if length := len(thornsArmour); length > 0 { + slot := maps.Keys(thornsArmour)[rand.Intn(length)] + item := thornsArmour[slot] + + _ = p.armour.Inventory().SetItem(slot, p.damageItem(item, 2)) if damageToAttacker > 0 { var attacker world.Entity if s, ok := source.(damage.SourceEntityAttack); ok { @@ -588,7 +591,6 @@ func (p *Player) Hurt(dmg float64, source damage.Source) (float64, bool) { l.Hurt(float64(damageToAttacker), damage.SourceThorns{Owner: attacker}) } } - break } }