diff --git a/server/entity/falling_block.go b/server/entity/falling_block.go index d98512b0b..d0538e072 100644 --- a/server/entity/falling_block.go +++ b/server/entity/falling_block.go @@ -10,7 +10,7 @@ import ( // NewFallingBlock creates a new FallingBlock entity. func NewFallingBlock(block world.Block, pos mgl64.Vec3) *Ent { - return Config{Behaviour: fallingBlockConf.New(block, FallingBlockBehaviour{block: block}.DefaultTick)}.New(FallingBlockType{}, pos) + return Config{Behaviour: fallingBlockConf.New(block, FallingBlockBehaviorDefault)}.New(FallingBlockType{}, pos) } var fallingBlockConf = FallingBlockBehaviourConfig{ diff --git a/server/entity/falling_block_behaviour.go b/server/entity/falling_block_behaviour.go index 94bb3834f..ca771f903 100644 --- a/server/entity/falling_block_behaviour.go +++ b/server/entity/falling_block_behaviour.go @@ -8,6 +8,14 @@ import ( "github.com/go-gl/mathgl/mgl64" "math" "math/rand" + "time" +) + +type FallingBlockBehaviorType int + +const ( + FallingBlockBehaviorDefault FallingBlockBehaviorType = iota + FallingBlockBehaviorTemporary ) // FallingBlockBehaviourConfig holds optional parameters for @@ -22,12 +30,12 @@ type FallingBlockBehaviourConfig struct { // New creates a FallingBlockBehaviour using the optional parameters in conf and // a block type. -func (conf FallingBlockBehaviourConfig) New(b world.Block, tick func(e *Ent)) *FallingBlockBehaviour { +func (conf FallingBlockBehaviourConfig) New(b world.Block, behaviorType FallingBlockBehaviorType) *FallingBlockBehaviour { behaviour := &FallingBlockBehaviour{block: b} behaviour.passive = PassiveBehaviourConfig{ Gravity: conf.Gravity, Drag: conf.Drag, - Tick: tick, + Tick: []func(*Ent){behaviour.DefaultTick, behaviour.TemporaryTick}[int(behaviorType)], }.New() return behaviour } @@ -43,6 +51,11 @@ func (f *FallingBlockBehaviour) Block() world.Block { return f.block } +// OnGround checks if the entity is currently on the ground. +func (f *FallingBlockBehaviour) OnGround() bool { + return f.passive.mc.OnGround() +} + // Tick implements the movement and solidification behaviour of falling blocks. func (f *FallingBlockBehaviour) Tick(e *Ent) *Movement { return f.passive.Tick(e) @@ -57,6 +70,20 @@ func (f *FallingBlockBehaviour) DefaultTick(e *Ent) { } } +// TemporaryTick checks if the falling block should only always solidify and then disappears after 3 seconds. +func (f *FallingBlockBehaviour) TemporaryTick(e *Ent) { + pos := e.Position() + bpos, w := cube.PosFromVec3(pos), e.World() + if a, ok := f.block.(Solidifiable); (ok && a.Solidifies(bpos, w)) || f.passive.mc.OnGround() { + f.passive.close = true + w.SetBlock(bpos, f.block, nil) + go func() { + time.Sleep(3 * time.Second) + w.SetBlock(bpos, block.Air{}, nil) + }() + } +} + // solidify attempts to solidify the falling block at the position passed. It // also deals damage to any entities standing at that position. If the block at // the position could not be replaced by the falling block, the block will drop