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

Added a way of knowing who ignites a TNT #848

Merged
merged 16 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/block/fire.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (f Fire) burn(from, to cube.Pos, w *world.World, r *rand.Rand, chanceBound
return
}
if t, ok := flammable.(TNT); ok {
t.Ignite(to, w)
t.Ignite(to, w, nil)
return
}
w.SetBlock(to, nil, nil)
Expand Down
20 changes: 14 additions & 6 deletions server/block/tnt.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,36 @@ import (
// TNT is an explosive block that can be primed to generate an explosion.
type TNT struct {
solid
igniter world.Entity
}

// Activate ...
func (t TNT) Activate(pos cube.Pos, _ cube.Face, w *world.World, u item.User, ctx *item.UseContext) bool {
held, _ := u.HeldItems()
if _, ok := held.Enchantment(enchantment.FireAspect{}); ok {
t.Ignite(pos, w)
t.Ignite(pos, w, u)
ctx.DamageItem(1)
return true
}
return false
}

// Ignite ...
func (t TNT) Ignite(pos cube.Pos, w *world.World) bool {
spawnTnt(pos, w, time.Second*4)
func (t TNT) Ignite(pos cube.Pos, w *world.World, igniter world.Entity) bool {
t.igniter = igniter
spawnTnt(pos, w, time.Second*4, t.igniter)
return true
}

// Igniter returns the entity that ignited the TNT.
// It is nil if ignited by a world source like fire.
func (t TNT) Igniter() world.Entity {
return t.igniter
}

// Explode ...
func (t TNT) Explode(_ mgl64.Vec3, pos cube.Pos, w *world.World, _ ExplosionConfig) {
spawnTnt(pos, w, time.Second/2+time.Duration(rand.Intn(int(time.Second+time.Second/2))))
spawnTnt(pos, w, time.Second/2+time.Duration(rand.Intn(int(time.Second+time.Second/2))), t.igniter)
}

// BreakInfo ...
Expand All @@ -59,8 +67,8 @@ func (t TNT) EncodeBlock() (name string, properties map[string]interface{}) {
}

// spawnTnt creates a new TNT entity at the given position with the given fuse duration.
func spawnTnt(pos cube.Pos, w *world.World, fuse time.Duration) {
func spawnTnt(pos cube.Pos, w *world.World, fuse time.Duration, igniter world.Entity) {
w.PlaySound(pos.Vec3Centre(), sound.TNT{})
w.SetBlock(pos, nil, nil)
w.AddEntity(w.EntityRegistry().Config().TNT(pos.Vec3Centre(), fuse))
w.AddEntity(w.EntityRegistry().Config().TNT(pos.Vec3Centre(), fuse, igniter))
}
2 changes: 1 addition & 1 deletion server/entity/projectile.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (lt *ProjectileBehaviour) Tick(e *Ent) *Movement {
case trace.BlockResult:
bpos := r.BlockPosition()
if t, ok := w.Block(bpos).(block.TNT); ok && e.OnFireDuration() > 0 {
t.Ignite(bpos, w)
t.Ignite(bpos, w, e)
}
if lt.conf.SurviveBlockCollision {
lt.hitBlockSurviving(e, r, m)
Expand Down
4 changes: 2 additions & 2 deletions server/entity/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ var conf = world.EntityRegistryConfig{
FallingBlock: func(bl world.Block, pos mgl64.Vec3) world.Entity {
return NewFallingBlock(bl, pos)
},
TNT: func(pos mgl64.Vec3, fuse time.Duration) world.Entity {
return NewTNT(pos, fuse)
TNT: func(pos mgl64.Vec3, fuse time.Duration, igniter world.Entity) world.Entity {
return NewTNT(pos, fuse, igniter)
},
BottleOfEnchanting: func(pos, vel mgl64.Vec3, owner world.Entity) world.Entity {
b := NewBottleOfEnchanting(pos, owner)
Expand Down
16 changes: 11 additions & 5 deletions server/entity/tnt.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
)

// NewTNT creates a new primed TNT entity.
func NewTNT(pos mgl64.Vec3, fuse time.Duration) *Ent {
func NewTNT(pos mgl64.Vec3, fuse time.Duration, igniter world.Entity) *Ent {
config := tntConf
config.ExistenceDuration = fuse
ent := Config{Behaviour: config.New()}.New(TNTType{}, pos)
ent := Config{Behaviour: config.New()}.New(TNTType{igniter: igniter}, pos)

angle := rand.Float64() * math.Pi * 2
ent.vel = mgl64.Vec3{-math.Sin(angle) * 0.02, 0.1, -math.Cos(angle) * 0.02}
Expand All @@ -35,16 +35,22 @@ func explodeTNT(e *Ent) {
}

// TNTType is a world.EntityType implementation for TNT.
type TNTType struct{}
type TNTType struct {
igniter world.Entity
}
RestartFU marked this conversation as resolved.
Show resolved Hide resolved

// Igniter returns the entity that ignited the TNT.
// It is nil if ignited by a world source like fire.
func (t TNTType) Igniter() world.Entity { return t.igniter }

func (TNTType) EncodeEntity() string { return "minecraft:tnt" }
func (TNTType) NetworkOffset() float64 { return 0.49 }
func (TNTType) BBox(world.Entity) cube.BBox {
return cube.Box(-0.49, 0, -0.49, 0.49, 0.98, 0.49)
}

func (TNTType) DecodeNBT(m map[string]any) world.Entity {
tnt := NewTNT(nbtconv.Vec3(m, "Pos"), nbtconv.TickDuration[uint8](m, "Fuse"))
func (t TNTType) DecodeNBT(m map[string]any) world.Entity {
tnt := NewTNT(nbtconv.Vec3(m, "Pos"), nbtconv.TickDuration[uint8](m, "Fuse"), t.igniter)
tnt.vel = nbtconv.Vec3(m, "Motion")
return tnt
}
Expand Down
4 changes: 2 additions & 2 deletions server/item/fire_charge.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ func (f FireCharge) EncodeItem() (name string, meta int16) {
}

// UseOnBlock ...
func (f FireCharge) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, _ User, ctx *UseContext) bool {
if l, ok := w.Block(pos).(ignitable); ok && l.Ignite(pos, w) {
func (f FireCharge) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, u User, ctx *UseContext) bool {
if l, ok := w.Block(pos).(ignitable); ok && l.Ignite(pos, w, u) {
ctx.SubtractFromCount(1)
w.PlaySound(pos.Vec3Centre(), sound.FireCharge{})
return true
Expand Down
6 changes: 3 additions & 3 deletions server/item/flint_and_steel.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ func (f FlintAndSteel) DurabilityInfo() DurabilityInfo {
// ignitable represents a block that can be lit by a fire emitter, such as flint and steel.
type ignitable interface {
// Ignite is called when the block is lit by flint and steel.
Ignite(pos cube.Pos, w *world.World) bool
Ignite(pos cube.Pos, w *world.World, igniter world.Entity) bool
}

// UseOnBlock ...
func (f FlintAndSteel) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, _ User, ctx *UseContext) bool {
func (f FlintAndSteel) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, u User, ctx *UseContext) bool {
ctx.DamageItem(1)
if l, ok := w.Block(pos).(ignitable); ok && l.Ignite(pos, w) {
if l, ok := w.Block(pos).(ignitable); ok && l.Ignite(pos, w, u) {
return true
} else if s := pos.Side(face); w.Block(s) == air() {
w.PlaySound(s.Vec3Centre(), sound.Ignite{})
Expand Down
2 changes: 1 addition & 1 deletion server/world/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type EntityRegistry struct {
type EntityRegistryConfig struct {
Item func(it any, pos, vel mgl64.Vec3) Entity
FallingBlock func(bl Block, pos mgl64.Vec3) Entity
TNT func(pos mgl64.Vec3, fuse time.Duration) Entity
TNT func(pos mgl64.Vec3, fuse time.Duration, igniter Entity) Entity
BottleOfEnchanting func(pos, vel mgl64.Vec3, owner Entity) Entity
Arrow func(pos, vel mgl64.Vec3, rot cube.Rotation, damage float64, owner Entity, critical, disallowPickup, obtainArrowOnPickup bool, punchLevel int, tip any) Entity
Egg func(pos, vel mgl64.Vec3, owner Entity) Entity
Expand Down
Loading