Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented explosions #562

Merged
merged 37 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3346de4
explosion/explosion.go: Third attempt at implementing explosions.
T14Raptor Jul 12, 2022
800702d
Merge remote-tracking branch 'origin/master' into feature/explosions
T14Raptor Jul 14, 2022
b172c4d
"Explodable" api
T14Raptor Jul 14, 2022
11882b2
Moved explosions to block package
T14Raptor Jul 14, 2022
61f945c
Merge branch 'master' into feature/explosions
JustTalDevelops Jul 15, 2022
4a3db7d
Merge remote-tracking branch 'origin/master' into feature/explosions
JustTalDevelops Jul 15, 2022
c8c1965
improvements
T14Raptor Jul 15, 2022
fd081cf
block: Added blast resistances for each block.
JustTalDevelops Jul 15, 2022
4da01aa
Merge remote-tracking branch 'origin/feature/explosions' into feature…
JustTalDevelops Jul 15, 2022
f0886fb
block/break_info.go: Improve doc.
JustTalDevelops Jul 15, 2022
a134491
Update server/block/explosion.go
JustTalDevelops Jul 15, 2022
489570f
block/explosion.go: Use `box` for consistency.
JustTalDevelops Jul 15, 2022
b982885
Merge remote-tracking branch 'origin/feature/explosions' into feature…
JustTalDevelops Jul 15, 2022
97b9cf6
block/break_info.go: Don't multiply hardness by 5.
T14Raptor Jul 15, 2022
83e7e71
Merge remote-tracking branch 'origin/feature/explosions' into feature…
T14Raptor Jul 15, 2022
294f673
block/break_info.go: Correct doc.
T14Raptor Jul 15, 2022
020bf23
block/explosion.go: Fix SpawnFire logic.
JustTalDevelops Jul 15, 2022
c026aa5
damage/source.go: Doc SourceExplosion.
JustTalDevelops Jul 15, 2022
011b7f4
player/player.go: Implement ExplodableEntity.
T14Raptor Jul 15, 2022
9cd90fe
Merge remote-tracking branch 'origin/feature/explosions' into feature…
T14Raptor Jul 15, 2022
7a9f47a
player/player.go: Directly set velocity.
JustTalDevelops Jul 15, 2022
d6fabcc
player/player.go: Revert "Directly set velocity".
JustTalDevelops Jul 15, 2022
659a0ca
block/explosion.go: Change Radius field back to Size.
T14Raptor Jul 16, 2022
1c01f45
Merge remote-tracking branch 'origin/feature/explosions' into feature…
T14Raptor Jul 16, 2022
e5e5fa9
Fixes
T14Raptor Jul 16, 2022
cc79531
block/explosions.go: Fixed exposure?
T14Raptor Jul 18, 2022
cb9b588
Merge remote-tracking branch 'origin/master' into feature/explosions
T14Raptor Jul 18, 2022
3a4180a
Merge branch 'master' into feature/explosions
JustTalDevelops Jul 26, 2022
c4f7ec8
block/block.go: Blame GitHub!
JustTalDevelops Jul 26, 2022
cb209b1
block/explosion.go: Divide blast resistance by 5.
T14Raptor Jul 26, 2022
c29385b
player/player.go: Fixed explosion knockback when in creative.
T14Raptor Jul 26, 2022
a2c0bfd
Merge branch 'master' into feature/explosions
JustTalDevelops Jul 26, 2022
c9e5e51
block/explosion.go: Various improvements.
JustTalDevelops Jul 29, 2022
e68e396
Merge branch 'master' into feature/explosions
JustTalDevelops Jul 29, 2022
8fbaf19
model/thin.go: Fix refactor.
JustTalDevelops Jul 29, 2022
df0f525
Merge remote-tracking branch 'origin/feature/explosions' into feature…
JustTalDevelops Jul 29, 2022
3e57c34
Merge branch 'master' into feature/explosions
JustTalDevelops Jul 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/block/ancient_debris.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type AncientDebris struct {
func (a AncientDebris) BreakInfo() BreakInfo {
return newBreakInfo(30, func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierDiamond.HarvestLevel
}, pickaxeEffective, oneOf(a))
}, pickaxeEffective, oneOf(a)).withBlastResistance(3600)
}

// SmeltInfo ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/anvil.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (a Anvil) Model() world.BlockModel {

// BreakInfo ...
func (a Anvil) BreakInfo() BreakInfo {
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(a))
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(a)).withBlastResistance(6000)
}

// Activate ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/basalt.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (b Basalt) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.

// BreakInfo ...
func (b Basalt) BreakInfo() BreakInfo {
return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(b))
return newBreakInfo(1.25, pickaxeHarvestable, pickaxeEffective, oneOf(b)).withBlastResistance(21)
}

// EncodeItem ...
Expand Down
55 changes: 52 additions & 3 deletions server/block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package block
import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/block/model"
"github.com/df-mc/dragonfly/server/entity"
"github.com/df-mc/dragonfly/server/entity/damage"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/df-mc/dragonfly/server/world/sound"
"github.com/go-gl/mathgl/mgl64"
"math/rand"
"time"
)

Expand Down Expand Up @@ -84,7 +86,7 @@ func calculateFace(user item.User, placePos cube.Pos) cube.Face {
pos := cube.PosFromVec3(userPos)
if abs(pos[0]-placePos[0]) < 2 && abs(pos[2]-placePos[2]) < 2 {
y := userPos[1]
if eyed, ok := user.(entity.Eyed); ok {
if eyed, ok := user.(interface{ EyeHeight() float64 }); ok {
y += eyed.EyeHeight()
}

Expand Down Expand Up @@ -203,7 +205,17 @@ func (g gravityAffected) fall(b world.Block, pos cube.Pos, w *world.World) {
_, liquid := w.Liquid(pos.Side(cube.FaceDown))
if air || liquid {
w.SetBlock(pos, nil, nil)
w.AddEntity(entity.NewFallingBlock(b, pos.Vec3Middle()))

ent, ok := world.EntityByName("minecraft:falling_block")
if !ok {
return
}

if p, ok := ent.(interface {
New(bl world.Block, pos mgl64.Vec3) world.Entity
}); ok {
w.AddEntity(p.New(b, pos.Vec3Centre()))
}
}
}

Expand Down Expand Up @@ -232,6 +244,43 @@ func newFlammabilityInfo(encouragement, flammability int, lavaFlammable bool) Fl
}
}

// livingEntity ...
type livingEntity interface {
// AttackImmune checks if the entity is currently immune to entity attacks. Entities typically turn
// immune for half a second after being attacked.
AttackImmune() bool
// Hurt hurts the entity for a given amount of damage. The source passed represents the cause of the
// damage, for example damage.SourceEntityAttack if the entity is attacked by another entity.
// If the final damage exceeds the health that the entity currently has, the entity is killed.
// Hurt returns the final amount of damage dealt to the Living entity and returns whether the Living entity
// was vulnerable to the damage at all.
Hurt(damage float64, src damage.Source) (n float64, vulnerable bool)
}

// flammableEntity ...
type flammableEntity interface {
// OnFireDuration returns duration of fire in ticks.
OnFireDuration() time.Duration
// SetOnFire sets the entity on fire for the specified duration.
SetOnFire(duration time.Duration)
// Extinguish extinguishes the entity.
Extinguish()
}

// dropItem ...
func dropItem(w *world.World, it item.Stack, pos mgl64.Vec3) {
ent, ok := world.EntityByName("minecraft:item")
if !ok {
return
}

if p, ok := ent.(interface {
New(it item.Stack, pos, vel mgl64.Vec3) world.Entity
}); ok {
w.AddEntity(p.New(it, pos, mgl64.Vec3{rand.Float64()*0.2 - 0.1, 0.2, rand.Float64()*0.2 - 0.1}))
}
}

// bass is a struct that may be embedded for blocks that create a bass sound.
type bass struct{}

Expand Down
21 changes: 16 additions & 5 deletions server/block/break_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,20 @@ type BreakInfo struct {
Drops func(t item.Tool, enchantments []item.Enchantment) []item.Stack
// XPDrops is the range of XP a block can drop when broken.
XPDrops XPDropRange
// BlastResistance is the blast resistance of the block, which influences the block's ability to withstand an
// explosive blast.
BlastResistance float64
T14Raptor marked this conversation as resolved.
Show resolved Hide resolved
}

// newBreakInfo creates a BreakInfo struct with the properties passed. The XPDrops field is 0 by default.
// newBreakInfo creates a BreakInfo struct with the properties passed. The XPDrops field is 0 by default. The blast
// resistance is set to the block's hardness*5 by default.
func newBreakInfo(hardness float64, harvestable func(item.Tool) bool, effective func(item.Tool) bool, drops func(item.Tool, []item.Enchantment) []item.Stack) BreakInfo {
return BreakInfo{
Hardness: hardness,
Harvestable: harvestable,
Effective: effective,
Drops: drops,
Hardness: hardness,
BlastResistance: hardness * 5,
Harvestable: harvestable,
Effective: effective,
Drops: drops,
}
}

Expand All @@ -103,6 +108,12 @@ func (b BreakInfo) withXPDropRange(min, max int) BreakInfo {
return b
}

// withBlastResistance sets the BlastResistance field of the BreakInfo struct to the passed value.
func (b BreakInfo) withBlastResistance(res float64) BreakInfo {
b.BlastResistance = res
return b
}

// XPDropRange holds the min & max XP drop amounts of blocks.
type XPDropRange [2]int

Expand Down
2 changes: 1 addition & 1 deletion server/block/bricks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Bricks struct {

// BreakInfo ...
func (b Bricks) BreakInfo() BreakInfo {
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(b))
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(b)).withBlastResistance(30)
}

// EncodeItem ...
Expand Down
3 changes: 1 addition & 2 deletions server/block/cactus.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package block
import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/block/model"
"github.com/df-mc/dragonfly/server/entity"
"github.com/df-mc/dragonfly/server/entity/damage"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
Expand Down Expand Up @@ -78,7 +77,7 @@ func (c Cactus) RandomTick(pos cube.Pos, w *world.World, r *rand.Rand) {

// EntityInside ...
func (c Cactus) EntityInside(_ cube.Pos, _ *world.World, e world.Entity) {
if l, ok := e.(entity.Living); ok && !l.AttackImmune() {
if l, ok := e.(livingEntity); ok && !l.AttackImmune() {
l.Hurt(0.5, damage.SourceBlock{Block: c})
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/block/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (c Chain) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.W

// BreakInfo ...
func (c Chain) BreakInfo() BreakInfo {
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c))
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(15)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/coal.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Coal struct {

// BreakInfo ...
func (c Coal) BreakInfo() BreakInfo {
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c))
return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(30)
}

// FlammabilityInfo ...
Expand Down
6 changes: 5 additions & 1 deletion server/block/coal_ore.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ type CoalOre struct {

// BreakInfo ...
func (c CoalOre) BreakInfo() BreakInfo {
return newBreakInfo(c.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(item.Coal{}, c)).withXPDropRange(0, 2)
i := newBreakInfo(c.Type.Hardness(), pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(item.Coal{}, c)).withXPDropRange(0, 2)
if c.Type == DeepslateOre() {
i = i.withBlastResistance(9)
}
return i
}

// SmeltInfo ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/cobblestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Cobblestone struct {

// BreakInfo ...
func (c Cobblestone) BreakInfo() BreakInfo {
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(c))
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(c)).withBlastResistance(30)
}

// SmeltInfo ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/cobblestone_stairs.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s CobblestoneStairs) Model() world.BlockModel {

// BreakInfo ...
func (s CobblestoneStairs) BreakInfo() BreakInfo {
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s))
return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/cocoa_bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (c CocoaBean) BreakInfo() BreakInfo {
return []item.Stack{item.NewStack(c, rand.Intn(2)+2)}
}
return []item.Stack{item.NewStack(c, 1)}
})
}).withBlastResistance(15)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/copper_ore.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type CopperOre struct {
func (c CopperOre) BreakInfo() BreakInfo {
return newBreakInfo(c.Type.Hardness(), func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierStone.HarvestLevel
}, pickaxeEffective, silkTouchDrop(item.NewStack(item.RawCopper{}, rand.Intn(4)+2), item.NewStack(c, 1)))
}, pickaxeEffective, silkTouchDrop(item.NewStack(item.RawCopper{}, rand.Intn(4)+2), item.NewStack(c, 1))).withBlastResistance(9)
}

// SmeltInfo ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/coral_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c CoralBlock) ScheduledTick(pos cube.Pos, w *world.World, _ *rand.Rand) {

// BreakInfo ...
func (c CoralBlock) BreakInfo() BreakInfo {
return newBreakInfo(7, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(CoralBlock{Type: c.Type, Dead: true}, c))
return newBreakInfo(7, pickaxeHarvestable, pickaxeEffective, silkTouchOneOf(CoralBlock{Type: c.Type, Dead: true}, c)).withBlastResistance(4.5)
}

// EncodeBlock ...
Expand Down
7 changes: 1 addition & 6 deletions server/block/crop.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/entity"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
"math/rand"
)

// Crop is an interface for all crops that are grown on farmland. A crop has a random chance to grow during random ticks.
Expand All @@ -33,9 +30,7 @@ func (c crop) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
w.SetBlock(pos, nil, nil)
if breakable, ok := b.(Breakable); ok {
for _, drop := range breakable.BreakInfo().Drops(item.ToolNone{}, []item.Enchantment{}) {
itemEntity := entity.NewItem(drop, pos.Vec3Centre())
itemEntity.SetVelocity(mgl64.Vec3{rand.Float64()*0.2 - 0.1, 0.2, rand.Float64()*0.2 - 0.1})
w.AddEntity(itemEntity)
dropItem(w, drop, pos.Vec3Centre())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/block/diamond.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Diamond struct {
func (d Diamond) BreakInfo() BreakInfo {
return newBreakInfo(5, func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel
}, pickaxeEffective, oneOf(d))
}, pickaxeEffective, oneOf(d)).withBlastResistance(30)
}

// PowersBeacon ...
Expand Down
6 changes: 5 additions & 1 deletion server/block/diamond_ore.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ type DiamondOre struct {

// BreakInfo ...
func (d DiamondOre) BreakInfo() BreakInfo {
return newBreakInfo(d.Type.Hardness(), func(t item.Tool) bool {
i := newBreakInfo(d.Type.Hardness(), func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel
}, pickaxeEffective, silkTouchOneOf(item.Diamond{}, d)).withXPDropRange(3, 7)
if d.Type == DeepslateOre() {
i = i.withBlastResistance(9)
}
return i
}

// SmeltInfo ...
Expand Down
6 changes: 1 addition & 5 deletions server/block/double_flower.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/entity"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/df-mc/dragonfly/server/world/particle"
"github.com/go-gl/mathgl/mgl64"
"math/rand"
)

// DoubleFlower is a two block high flower consisting of an upper and lower part.
Expand All @@ -28,9 +26,7 @@ func (d DoubleFlower) FlammabilityInfo() FlammabilityInfo {

// BoneMeal ...
func (d DoubleFlower) BoneMeal(pos cube.Pos, w *world.World) bool {
itemEntity := entity.NewItem(item.NewStack(d, 1), pos.Vec3Centre())
itemEntity.SetVelocity(mgl64.Vec3{rand.Float64()*0.2 - 0.1, 0.2, rand.Float64()*0.2 - 0.1})
w.AddEntity(itemEntity)
dropItem(w, item.NewStack(d, 1), pos.Vec3Centre())
return true
}

Expand Down
2 changes: 1 addition & 1 deletion server/block/dripstone.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Dripstone struct {

// BreakInfo ...
func (d Dripstone) BreakInfo() BreakInfo {
return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d))
return newBreakInfo(1.5, pickaxeHarvestable, pickaxeEffective, oneOf(d)).withBlastResistance(5)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/emerald.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (e Emerald) Instrument() sound.Instrument {
func (e Emerald) BreakInfo() BreakInfo {
return newBreakInfo(5, func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel
}, pickaxeEffective, oneOf(e))
}, pickaxeEffective, oneOf(e)).withBlastResistance(30)
}

// PowersBeacon ...
Expand Down
6 changes: 5 additions & 1 deletion server/block/emerald_ore.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ type EmeraldOre struct {

// BreakInfo ...
func (e EmeraldOre) BreakInfo() BreakInfo {
return newBreakInfo(e.Type.Hardness(), func(t item.Tool) bool {
i := newBreakInfo(e.Type.Hardness(), func(t item.Tool) bool {
return t.ToolType() == item.TypePickaxe && t.HarvestLevel() >= item.ToolTierIron.HarvestLevel
}, pickaxeEffective, silkTouchOneOf(item.Emerald{}, e)).withXPDropRange(3, 7)
if e.Type == DeepslateOre() {
i = i.withBlastResistance(15)
}
return i
}

// SmeltInfo ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/end_brick_stairs.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (s EndBrickStairs) Model() world.BlockModel {

// BreakInfo ...
func (s EndBrickStairs) BreakInfo() BreakInfo {
return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(s))
return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(s)).withBlastResistance(30)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/end_stone.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type EndStone struct {

// BreakInfo ...
func (e EndStone) BreakInfo() BreakInfo {
return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(e))
return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(e)).withBlastResistance(45)
}

// EncodeItem ...
Expand Down
2 changes: 1 addition & 1 deletion server/block/ender_chest.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewEnderChest() EnderChest {

// BreakInfo ...
func (c EnderChest) BreakInfo() BreakInfo {
return newBreakInfo(22.5, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(Obsidian{}, 8), item.NewStack(NewEnderChest(), 1)))
return newBreakInfo(22.5, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(Obsidian{}, 8), item.NewStack(NewEnderChest(), 1))).withBlastResistance(3000)
}

// LightEmissionLevel ...
Expand Down