Skip to content

Commit

Permalink
Implemented explosions (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
T14Raptor committed Jul 29, 2022
1 parent 0105384 commit b281564
Show file tree
Hide file tree
Showing 72 changed files with 433 additions and 98 deletions.
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
}

// 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
Loading

0 comments on commit b281564

Please sign in to comment.