github.com/df-mc/dragonfly@v0.9.13/server/item/firework.go (about) 1 package item 2 3 import ( 4 "github.com/df-mc/dragonfly/server/block/cube" 5 "github.com/df-mc/dragonfly/server/world" 6 "github.com/df-mc/dragonfly/server/world/sound" 7 "github.com/go-gl/mathgl/mgl64" 8 "math/rand" 9 "time" 10 ) 11 12 // Firework is an item (and entity) used for creating decorative explosions, boosting when flying with elytra, and 13 // loading into a crossbow as ammunition. 14 type Firework struct { 15 // Duration is the flight duration of the firework. 16 Duration time.Duration 17 // Explosions is the list of explosions the firework should create when launched. 18 Explosions []FireworkExplosion 19 } 20 21 // Use ... 22 func (f Firework) Use(w *world.World, user User, ctx *UseContext) bool { 23 if g, ok := user.(interface { 24 Gliding() bool 25 }); !ok || !g.Gliding() { 26 return false 27 } 28 29 pos := user.Position() 30 31 w.PlaySound(pos, sound.FireworkLaunch{}) 32 create := w.EntityRegistry().Config().Firework 33 w.AddEntity(create(pos, user.Rotation(), true, f, user)) 34 35 ctx.SubtractFromCount(1) 36 return true 37 } 38 39 // UseOnBlock ... 40 func (f Firework) UseOnBlock(blockPos cube.Pos, _ cube.Face, clickPos mgl64.Vec3, w *world.World, user User, ctx *UseContext) bool { 41 pos := blockPos.Vec3().Add(clickPos) 42 create := w.EntityRegistry().Config().Firework 43 w.AddEntity(create(pos, cube.Rotation{rand.Float64() * 360, 90}, false, f, user)) 44 w.PlaySound(pos, sound.FireworkLaunch{}) 45 46 ctx.SubtractFromCount(1) 47 return true 48 } 49 50 // EncodeNBT ... 51 func (f Firework) EncodeNBT() map[string]any { 52 explosions := make([]any, 0, len(f.Explosions)) 53 for _, explosion := range f.Explosions { 54 explosions = append(explosions, explosion.EncodeNBT()) 55 } 56 return map[string]any{"Fireworks": map[string]any{ 57 "Explosions": explosions, 58 "Flight": uint8((f.Duration/10 - time.Millisecond*50).Milliseconds() / 50), 59 }} 60 } 61 62 // DecodeNBT ... 63 func (f Firework) DecodeNBT(data map[string]any) any { 64 if fireworks, ok := data["Fireworks"].(map[string]any); ok { 65 if explosions, ok := fireworks["Explosions"].([]any); ok { 66 f.Explosions = make([]FireworkExplosion, len(explosions)) 67 for i, explosion := range f.Explosions { 68 f.Explosions[i] = explosion.DecodeNBT(explosions[i].(map[string]any)).(FireworkExplosion) 69 } 70 } 71 if durationTicks, ok := fireworks["Flight"].(uint8); ok { 72 f.Duration = (time.Duration(durationTicks)*time.Millisecond*50 + time.Millisecond*50) * 10 73 } 74 } 75 return f 76 } 77 78 // RandomisedDuration returns the randomised flight duration of the firework. 79 func (f Firework) RandomisedDuration() time.Duration { 80 return f.Duration + time.Duration(rand.Intn(int(time.Millisecond*600))) 81 } 82 83 // EncodeItem ... 84 func (Firework) EncodeItem() (name string, meta int16) { 85 return "minecraft:firework_rocket", 0 86 }