Skip to content

Commit 9e05eee

Browse files
committed
Merge branch 'refs/heads/master' into feature/entity-improvements
2 parents b7e9a58 + 16b0d3e commit 9e05eee

File tree

13 files changed

+137
-52
lines changed

13 files changed

+137
-52
lines changed

server/block/action.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ type ContinueCrackAction struct {
2626
// StopCrackAction is a world.BlockAction to make the cracks forming in a block stop and disappear.
2727
type StopCrackAction struct{ action }
2828

29+
// DecoratedPotWobbleAction is a world.BlockAction to make a decorated pot wobble when interacted with.
30+
type DecoratedPotWobbleAction struct {
31+
action
32+
DecoratedPot DecoratedPot
33+
// Success is whether an item was successfully inserted into the decorated pot.
34+
Success bool
35+
}
36+
2937
// action implements the Action interface. Structures in this package may embed it to gets its functionality
3038
// out of the box.
3139
type action struct{}

server/block/block.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ type EntityInsider interface {
7474
EntityInside(pos cube.Pos, tx *world.Tx, e world.Entity)
7575
}
7676

77+
// ProjectileHitter represents a block that handles being hit by a projectile.
78+
type ProjectileHitter interface {
79+
// ProjectileHit is called when a projectile hits the block.
80+
ProjectileHit(pos cube.Pos, tx *world.Tx, e world.Entity, face cube.Face)
81+
}
82+
7783
// Frictional represents a block that may have a custom friction value. Friction is used for entity drag when the
7884
// entity is on ground. If a block does not implement this interface, it should be assumed that its friction is 0.6.
7985
type Frictional interface {

server/block/break_info.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,12 @@ func breakBlock(b world.Block, pos cube.Pos, tx *world.Tx) {
248248
}
249249

250250
func breakBlockNoDrops(b world.Block, pos cube.Pos, tx *world.Tx) {
251+
if breakable, ok := b.(Breakable); ok {
252+
breakHandler := breakable.BreakInfo().BreakHandler
253+
if breakHandler != nil {
254+
breakHandler(pos, tx, nil)
255+
}
256+
}
251257
tx.SetBlock(pos, nil, nil)
252258
tx.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: b})
253259
}

server/block/brewing_stand.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (b BrewingStand) DecodeNBT(data map[string]any) any {
114114

115115
// BreakInfo ...
116116
func (b BrewingStand) BreakInfo() BreakInfo {
117-
return newBreakInfo(0.5, alwaysHarvestable, pickaxeEffective, oneOf(b)).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
117+
return newBreakInfo(0.5, alwaysHarvestable, pickaxeEffective, oneOf(BrewingStand{})).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
118118
for _, i := range b.Inventory(tx, pos).Clear() {
119119
dropItem(tx, i, pos.Vec3Centre())
120120
}

server/block/campfire.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,22 @@ func (Campfire) SideClosed(cube.Pos, cube.Pos, *world.Tx) bool {
5151
// BreakInfo ...
5252
func (c Campfire) BreakInfo() BreakInfo {
5353
return newBreakInfo(2, alwaysHarvestable, axeEffective, func(t item.Tool, enchantments []item.Enchantment) []item.Stack {
54-
var drops []item.Stack
5554
if hasSilkTouch(enchantments) {
56-
drops = append(drops, item.NewStack(c, 1))
57-
} else {
58-
switch c.Type {
59-
case NormalFire():
60-
drops = append(drops, item.NewStack(item.Charcoal{}, 2))
61-
case SoulFire():
62-
drops = append(drops, item.NewStack(SoulSoil{}, 1))
63-
}
55+
return []item.Stack{item.NewStack(Campfire{Type: c.Type}, 1)}
56+
}
57+
switch c.Type {
58+
case NormalFire():
59+
return []item.Stack{item.NewStack(item.Charcoal{}, 2)}
60+
case SoulFire():
61+
return []item.Stack{item.NewStack(SoulSoil{}, 1)}
6462
}
63+
panic("should never happen")
64+
}).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
6565
for _, v := range c.Items {
6666
if !v.Item.Empty() {
67-
drops = append(drops, v.Item)
67+
dropItem(tx, v.Item, pos.Vec3Centre())
6868
}
6969
}
70-
return drops
7170
})
7271
}
7372

@@ -133,6 +132,10 @@ func (c Campfire) Activate(pos cube.Pos, _ cube.Face, tx *world.Tx, u item.User,
133132
return false
134133
}
135134

135+
if _, ok = tx.Liquid(pos); ok {
136+
return false
137+
}
138+
136139
for i, it := range c.Items {
137140
if it.Item.Empty() {
138141
c.Items[i] = CampfireItem{
@@ -198,9 +201,22 @@ func (c Campfire) Tick(_ int64, pos cube.Pos, tx *world.Tx) {
198201

199202
// NeighbourUpdateTick ...
200203
func (c Campfire) NeighbourUpdateTick(pos, _ cube.Pos, tx *world.Tx) {
201-
_, ok := tx.Liquid(pos)
202-
liquid, okTwo := tx.Liquid(pos.Side(cube.FaceUp))
203-
if (ok || (okTwo && liquid.LiquidType() == "water")) && !c.Extinguished {
204+
if _, ok := tx.Liquid(pos); ok {
205+
var updated bool
206+
for i, it := range c.Items {
207+
if !it.Item.Empty() {
208+
dropItem(tx, it.Item, pos.Vec3Centre())
209+
c.Items[i].Item, updated = item.Stack{}, true
210+
}
211+
}
212+
if !c.Extinguished {
213+
c.extinguish(pos, tx)
214+
} else if updated {
215+
tx.SetBlock(pos, c, nil)
216+
}
217+
return
218+
}
219+
if liquid, ok := tx.Liquid(pos.Side(cube.FaceUp)); ok && liquid.LiquidType() == "water" && !c.Extinguished {
204220
c.extinguish(pos, tx)
205221
}
206222
}

server/block/decorated_pot.go

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"github.com/df-mc/dragonfly/server/internal/nbtconv"
88
"github.com/df-mc/dragonfly/server/item"
99
"github.com/df-mc/dragonfly/server/world"
10+
"github.com/df-mc/dragonfly/server/world/particle"
11+
"github.com/df-mc/dragonfly/server/world/sound"
1012
"github.com/go-gl/mathgl/mgl64"
1113
)
1214

@@ -31,6 +33,23 @@ type DecoratedPot struct {
3133
Decorations [4]PotDecoration
3234
}
3335

36+
// ProjectileHit ...
37+
func (p DecoratedPot) ProjectileHit(pos cube.Pos, tx *world.Tx, _ world.Entity, _ cube.Face) {
38+
for _, d := range p.Decorations {
39+
if d == nil {
40+
dropItem(tx, item.NewStack(item.Brick{}, 1), pos.Vec3Centre())
41+
continue
42+
}
43+
dropItem(tx, item.NewStack(d, 1), pos.Vec3Centre())
44+
}
45+
breakBlockNoDrops(p, pos, tx)
46+
}
47+
48+
// Pick ...
49+
func (p DecoratedPot) Pick() item.Stack {
50+
return item.NewStack(DecoratedPot{Decorations: p.Decorations}, 1)
51+
}
52+
3453
// ExtractItem ...
3554
func (p DecoratedPot) ExtractItem(h Hopper, pos cube.Pos, tx *world.Tx) bool {
3655
if p.Item.Empty() {
@@ -61,10 +80,25 @@ func (p DecoratedPot) InsertItem(h Hopper, pos cube.Pos, tx *world.Tx) bool {
6180
return false
6281
}
6382

83+
// wobble ...
84+
func (p DecoratedPot) wobble(pos cube.Pos, tx *world.Tx, success bool) {
85+
for _, v := range tx.Viewers(pos.Vec3Centre()) {
86+
v.ViewBlockAction(pos, DecoratedPotWobbleAction{DecoratedPot: p, Success: success})
87+
}
88+
89+
if success {
90+
tx.AddParticle(pos.Vec3Middle().Add(mgl64.Vec3{0, 1.2}), particle.DustPlume{})
91+
tx.PlaySound(pos.Vec3Centre(), sound.DecoratedPotInserted{Progress: float64(p.Item.Count()) / float64(p.Item.MaxCount())})
92+
} else {
93+
tx.PlaySound(pos.Vec3Centre(), sound.DecoratedPotInsertFailed{})
94+
}
95+
}
96+
6497
// Activate ...
6598
func (p DecoratedPot) Activate(pos cube.Pos, _ cube.Face, tx *world.Tx, u item.User, ctx *item.UseContext) bool {
6699
held, _ := u.HeldItems()
67100
if held.Empty() || !p.Item.Comparable(held) || p.Item.Count() == p.Item.MaxCount() {
101+
p.wobble(pos, tx, false)
68102
return false
69103
}
70104

@@ -74,27 +108,14 @@ func (p DecoratedPot) Activate(pos cube.Pos, _ cube.Face, tx *world.Tx, u item.U
74108
p.Item = p.Item.Grow(1)
75109
}
76110
tx.SetBlock(pos, p, nil)
111+
p.wobble(pos, tx, true)
77112
ctx.SubtractFromCount(1)
78113
return true
79114
}
80115

81116
// BreakInfo ...
82117
func (p DecoratedPot) BreakInfo() BreakInfo {
83-
return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(tool item.Tool, enchantments []item.Enchantment) []item.Stack {
84-
if hasSilkTouch(enchantments) {
85-
p.Item = item.Stack{}
86-
return []item.Stack{item.NewStack(p, 1)}
87-
}
88-
var drops []item.Stack
89-
for _, d := range p.Decorations {
90-
if d == nil {
91-
drops = append(drops, item.NewStack(item.Brick{}, 1))
92-
continue
93-
}
94-
drops = append(drops, item.NewStack(d, 1))
95-
}
96-
return drops
97-
}).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
118+
return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(DecoratedPot{Decorations: p.Decorations})).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
98119
if !p.Item.Empty() {
99120
dropItem(tx, p.Item, pos.Vec3Centre())
100121
}

server/block/explosion.go

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137,27 +137,16 @@ func (c ExplosionConfig) Explode(tx *world.Tx, explosionPos mgl64.Vec3) {
137137
if explodable, ok := bl.(Explodable); ok {
138138
explodable.Explode(explosionPos, pos, tx, c)
139139
} else if breakable, ok := bl.(Breakable); ok {
140+
breakHandler := breakable.BreakInfo().BreakHandler
141+
if breakHandler != nil {
142+
breakHandler(pos, tx, nil)
143+
}
140144
tx.SetBlock(pos, nil, nil)
141145
if c.ItemDropChance > r.Float64() {
142146
for _, drop := range breakable.BreakInfo().Drops(item.ToolNone{}, nil) {
143147
dropItem(tx, drop, pos.Vec3Centre())
144148
}
145149
}
146-
147-
if container, ok := bl.(Container); ok {
148-
if cb, ok := bl.(Chest); ok {
149-
if cb.Paired() {
150-
pairPos := cb.pairPos(pos)
151-
if _, pair, ok := cb.unpair(tx, pos); ok {
152-
cb.paired = false
153-
tx.SetBlock(pairPos, pair, nil)
154-
}
155-
}
156-
}
157-
for _, i := range container.Inventory(tx, pos).Clear() {
158-
dropItem(tx, i, pos.Vec3())
159-
}
160-
}
161150
}
162151
}
163152
if c.SpawnFire {

server/block/jukebox.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,7 @@ func (j Jukebox) FuelInfo() item.FuelInfo {
5555

5656
// BreakInfo ...
5757
func (j Jukebox) BreakInfo() BreakInfo {
58-
d := []item.Stack{item.NewStack(Jukebox{}, 1)}
59-
if !j.Item.Empty() {
60-
d = append(d, j.Item)
61-
}
62-
return newBreakInfo(0.8, alwaysHarvestable, axeEffective, simpleDrops(d...)).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
58+
return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(Jukebox{})).withBlastResistance(30).withBreakHandler(func(pos cube.Pos, tx *world.Tx, u item.User) {
6359
if _, hasDisc := j.Disc(); hasDisc {
6460
dropItem(tx, j.Item, pos.Vec3())
6561
tx.PlaySound(pos.Vec3Centre(), sound.MusicDiscEnd{})

server/block/tnt.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ type TNT struct {
1616
solid
1717
}
1818

19+
// ProjectileHit ...
20+
func (t TNT) ProjectileHit(pos cube.Pos, tx *world.Tx, e world.Entity, _ cube.Face) {
21+
if f, ok := e.(flammableEntity); ok && f.OnFireDuration() > 0 {
22+
t.Ignite(pos, tx, nil)
23+
}
24+
}
25+
1926
// Activate ...
2027
func (t TNT) Activate(pos cube.Pos, _ cube.Face, tx *world.Tx, u item.User, ctx *item.UseContext) bool {
2128
held, _ := u.HeldItems()

server/entity/projectile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ func (lt *ProjectileBehaviour) Tick(e *Ent, tx *world.Tx) *Movement {
172172
}
173173
case trace.BlockResult:
174174
bpos := r.BlockPosition()
175-
if t, ok := tx.Block(bpos).(block.TNT); ok && e.OnFireDuration() > 0 {
176-
t.Ignite(bpos, tx, nil)
175+
if h, ok := tx.Block(bpos).(block.ProjectileHitter); ok {
176+
h.ProjectileHit(bpos, tx, e, r.Face())
177177
}
178178
if lt.conf.SurviveBlockCollision {
179179
lt.hitBlockSurviving(e, r, m, tx)

0 commit comments

Comments
 (0)