up3
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
"github.com/df-mc/dragonfly/server/block/cube/trace"
|
||||
"github.com/df-mc/dragonfly/server/entity/effect"
|
||||
"github.com/df-mc/dragonfly/server/item/potion"
|
||||
"github.com/df-mc/dragonfly/server/world"
|
||||
"github.com/go-gl/mathgl/mgl64"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SplashableBlock is a block that can be splashed with a splash bottle.
|
||||
type SplashableBlock interface {
|
||||
world.Block
|
||||
// Splash is called when a water bottle splashes onto a block.
|
||||
Splash(tx *world.Tx, pos cube.Pos)
|
||||
}
|
||||
|
||||
// SplashableEntity is an entity that can be splashed with a splash bottle.
|
||||
type SplashableEntity interface {
|
||||
world.Entity
|
||||
// Splash is called when a water bottle splashes onto an entity.
|
||||
Splash(tx *world.Tx, pos mgl64.Vec3)
|
||||
}
|
||||
|
||||
// potionSplash returns a function that creates a potion splash with a specific
|
||||
// duration multiplier and potion type.
|
||||
func potionSplash(durMul float64, pot potion.Potion, linger bool) func(e *Ent, tx *world.Tx, res trace.Result) {
|
||||
return func(e *Ent, tx *world.Tx, res trace.Result) {
|
||||
pos := e.Position()
|
||||
effects := pot.Effects()
|
||||
box := e.H().Type().BBox(e).Translate(pos)
|
||||
|
||||
if len(effects) > 0 {
|
||||
for otherE := range filterLiving(tx.EntitiesWithin(box.GrowVec3(mgl64.Vec3{8.25, 4.25, 8.25}))) {
|
||||
otherPos := otherE.Position()
|
||||
if !otherE.H().Type().BBox(otherE).Translate(otherPos).IntersectsWith(box.GrowVec3(mgl64.Vec3{4.125, 2.125, 4.125})) {
|
||||
continue
|
||||
}
|
||||
|
||||
dist := otherPos.Sub(pos).Len()
|
||||
if dist > 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
f := 1 - dist/4
|
||||
if entityResult, ok := res.(trace.EntityResult); ok && entityResult.Entity().H() == otherE.H() {
|
||||
f = 1
|
||||
}
|
||||
|
||||
splashed := otherE.(Living)
|
||||
for _, eff := range effects {
|
||||
if _, ok := eff.Type().(effect.LastingType); !ok {
|
||||
splashed.AddEffect(effect.NewInstantWithPotency(eff.Type(), eff.Level(), f))
|
||||
continue
|
||||
}
|
||||
|
||||
dur := time.Duration(float64(eff.Duration()) * durMul * f)
|
||||
if dur < time.Second {
|
||||
continue
|
||||
}
|
||||
splashed.AddEffect(effect.New(eff.Type().(effect.LastingType), eff.Level(), dur))
|
||||
}
|
||||
}
|
||||
} else if pot == potion.Water() {
|
||||
switch result := res.(type) {
|
||||
case trace.BlockResult:
|
||||
blockPos := result.BlockPosition().Side(result.Face())
|
||||
if tx.Block(blockPos) == fire() {
|
||||
tx.SetBlock(blockPos, nil, nil)
|
||||
}
|
||||
|
||||
for _, f := range cube.HorizontalFaces() {
|
||||
if h := blockPos.Side(f); tx.Block(h) == fire() {
|
||||
tx.SetBlock(h, nil, nil)
|
||||
}
|
||||
|
||||
if b, ok := tx.Block(blockPos.Side(f)).(SplashableBlock); ok {
|
||||
b.Splash(tx, blockPos.Side(f))
|
||||
}
|
||||
}
|
||||
|
||||
resultPos := result.BlockPosition()
|
||||
if b, ok := tx.Block(resultPos).(SplashableBlock); ok {
|
||||
b.Splash(tx, resultPos)
|
||||
}
|
||||
case trace.EntityResult:
|
||||
// TODO: Damage endermen, blazes, striders and snow golems when implemented and rehydrate axolotls.
|
||||
}
|
||||
|
||||
for otherE := range filterLiving(tx.EntitiesWithin(box.GrowVec3(mgl64.Vec3{8.25, 4.25, 8.25}))) {
|
||||
if splashE, ok := otherE.(SplashableEntity); ok {
|
||||
splashE.Splash(tx, otherE.Position())
|
||||
}
|
||||
}
|
||||
}
|
||||
if linger {
|
||||
tx.AddEntity(NewAreaEffectCloud(world.EntitySpawnOpts{Position: pos}, pot))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user