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,119 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
"github.com/df-mc/dragonfly/server/item/potion"
|
||||
"github.com/df-mc/dragonfly/server/world"
|
||||
"github.com/df-mc/dragonfly/server/world/sound"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Bow is a ranged weapon that fires arrows.
|
||||
type Bow struct{}
|
||||
|
||||
// MaxCount always returns 1.
|
||||
func (Bow) MaxCount() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// DurabilityInfo ...
|
||||
func (Bow) DurabilityInfo() DurabilityInfo {
|
||||
return DurabilityInfo{
|
||||
MaxDurability: 385,
|
||||
BrokenItem: simpleItem(Stack{}),
|
||||
}
|
||||
}
|
||||
|
||||
// FuelInfo ...
|
||||
func (Bow) FuelInfo() FuelInfo {
|
||||
return newFuelInfo(time.Second * 10)
|
||||
}
|
||||
|
||||
// Release ...
|
||||
func (Bow) Release(releaser Releaser, tx *world.Tx, ctx *UseContext, duration time.Duration) {
|
||||
creative := releaser.GameMode().CreativeInventory()
|
||||
ticks := duration.Milliseconds() / 50
|
||||
if ticks < 3 {
|
||||
// The player must hold the bow for at least three ticks.
|
||||
return
|
||||
}
|
||||
|
||||
d := float64(ticks) / 20
|
||||
force := math.Min((d*d+d*2)/3, 1)
|
||||
if force < 0.1 {
|
||||
// The force must be at least 0.1.
|
||||
return
|
||||
}
|
||||
|
||||
arrow, ok := ctx.FirstFunc(func(stack Stack) bool {
|
||||
_, ok := stack.Item().(Arrow)
|
||||
return ok
|
||||
})
|
||||
if !ok && !creative {
|
||||
// No arrows in inventory and not in creative mode.
|
||||
return
|
||||
}
|
||||
|
||||
var tip potion.Potion
|
||||
if !arrow.Empty() {
|
||||
// Arrow is empty if not found in the creative inventory.
|
||||
tip = arrow.Item().(Arrow).Tip
|
||||
}
|
||||
|
||||
held, _ := releaser.HeldItems()
|
||||
damage, punchLevel, burnDuration, consume := 2.0, 0, time.Duration(0), !creative
|
||||
for _, enchant := range held.Enchantments() {
|
||||
if f, ok := enchant.Type().(interface{ BurnDuration() time.Duration }); ok {
|
||||
burnDuration = f.BurnDuration()
|
||||
}
|
||||
if _, ok := enchant.Type().(interface{ KnockBackMultiplier() float64 }); ok {
|
||||
punchLevel = enchant.Level()
|
||||
}
|
||||
if p, ok := enchant.Type().(interface{ PowerDamage(int) float64 }); ok {
|
||||
damage += p.PowerDamage(enchant.Level())
|
||||
}
|
||||
if i, ok := enchant.Type().(interface{ ConsumesArrows() bool }); ok && !i.ConsumesArrows() {
|
||||
consume = false
|
||||
}
|
||||
}
|
||||
|
||||
create := tx.World().EntityRegistry().Config().Arrow
|
||||
opts := world.EntitySpawnOpts{
|
||||
Position: eyePosition(releaser),
|
||||
Velocity: releaser.Rotation().Vec3().Mul(force * 5),
|
||||
Rotation: releaser.Rotation().Neg(),
|
||||
}
|
||||
projectile := tx.AddEntity(create(opts, world.ArrowSpawnConfig{
|
||||
Damage: damage,
|
||||
Owner: releaser,
|
||||
Critical: force >= 1,
|
||||
ObtainArrowOnPickup: !creative && consume,
|
||||
PunchLevel: punchLevel,
|
||||
Tip: tip,
|
||||
}))
|
||||
if f, ok := projectile.(interface{ SetOnFire(duration time.Duration) }); ok {
|
||||
f.SetOnFire(burnDuration)
|
||||
}
|
||||
|
||||
ctx.DamageItem(1)
|
||||
if consume {
|
||||
ctx.Consume(arrow.Grow(-arrow.Count() + 1))
|
||||
}
|
||||
|
||||
tx.PlaySound(releaser.Position(), sound.BowShoot{})
|
||||
}
|
||||
|
||||
// EnchantmentValue ...
|
||||
func (Bow) EnchantmentValue() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Requirements returns the required items to release this item.
|
||||
func (Bow) Requirements() []Stack {
|
||||
return []Stack{NewStack(Arrow{}, 1)}
|
||||
}
|
||||
|
||||
// EncodeItem ...
|
||||
func (Bow) EncodeItem() (name string, meta int16) {
|
||||
return "minecraft:bow", 0
|
||||
}
|
||||
Reference in New Issue
Block a user