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,272 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"image/color"
|
||||
"time"
|
||||
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
"github.com/df-mc/dragonfly/server/entity/effect"
|
||||
"github.com/df-mc/dragonfly/server/world"
|
||||
"github.com/go-gl/mathgl/mgl64"
|
||||
)
|
||||
|
||||
// MaxCounter represents an item that has a specific max count. By default, each item will be expected to have
|
||||
// a maximum count of 64. MaxCounter may be implemented to change this behaviour.
|
||||
type MaxCounter interface {
|
||||
// MaxCount returns the maximum number of items that a stack may be composed of. The number returned must
|
||||
// be positive.
|
||||
MaxCount() int
|
||||
}
|
||||
|
||||
// UsableOnBlock represents an item that may be used on a block. If an item implements this interface, the
|
||||
// UseOnBlock method is called whenever the item is used on a block.
|
||||
type UsableOnBlock interface {
|
||||
// UseOnBlock is called when an item is used on a block. The world passed is the world that the item was
|
||||
// used in. The user passed is the entity that used the item. Usually this entity is a player.
|
||||
// The position of the block that was clicked, along with the clicked face and the position clicked
|
||||
// relative to the corner of the block are passed.
|
||||
// UseOnBlock returns a bool indicating if the item was used successfully.
|
||||
UseOnBlock(pos cube.Pos, face cube.Face, clickPos mgl64.Vec3, tx *world.Tx, user User, ctx *UseContext) bool
|
||||
}
|
||||
|
||||
// UsableOnEntity represents an item that may be used on an entity. If an item implements this interface, the
|
||||
// UseOnEntity method is called whenever the item is used on an entity.
|
||||
type UsableOnEntity interface {
|
||||
// UseOnEntity is called when an item is used on an entity. The world passed is the world that the item is
|
||||
// used in, and the entity clicked and the user of the item are also passed.
|
||||
// UseOnEntity returns a bool indicating if the item was used successfully.
|
||||
UseOnEntity(e world.Entity, tx *world.Tx, user User, ctx *UseContext) bool
|
||||
}
|
||||
|
||||
// Usable represents an item that may be used 'in the air'. If an item implements this interface, the Use
|
||||
// method is called whenever the item is used while pointing at the air. (For example, when throwing an egg.)
|
||||
type Usable interface {
|
||||
// Use is called when the item is used in the air. The user that used the item and the world that the item
|
||||
// was used in are passed to the method.
|
||||
// Use returns a bool indicating if the item was used successfully.
|
||||
Use(tx *world.Tx, user User, ctx *UseContext) bool
|
||||
}
|
||||
|
||||
// Throwable represents a custom item that can be thrown such as a projectile. This will only have an effect on
|
||||
// non-vanilla items.
|
||||
type Throwable interface {
|
||||
// SwingAnimation returns true if the client should cause the player's arm to swing when the item is thrown.
|
||||
SwingAnimation() bool
|
||||
}
|
||||
|
||||
// OffHand represents an item that can be held in the off hand.
|
||||
type OffHand interface {
|
||||
// OffHand returns true if the item can be held in the off hand.
|
||||
OffHand() bool
|
||||
}
|
||||
|
||||
// Consumable represents an item that may be consumed by a player. If an item implements this interface, a player
|
||||
// may use and hold the item to consume it.
|
||||
type Consumable interface {
|
||||
// AlwaysConsumable specifies if the item is always consumable. Normal food can generally only be consumed
|
||||
// when the food bar is not full or when in creative mode. Returning true here means the item can always
|
||||
// be consumed, like golden apples or potions.
|
||||
AlwaysConsumable() bool
|
||||
// ConsumeDuration is the duration consuming the item takes. If the player is using the item for at least
|
||||
// this duration, the item will be consumed and have its Consume method called.
|
||||
ConsumeDuration() time.Duration
|
||||
// Consume consumes one item of the Stack that the Consumable is in. The Stack returned is added back to
|
||||
// the inventory after consuming the item. For potions, for example, an empty bottle is returned.
|
||||
Consume(tx *world.Tx, c Consumer) Stack
|
||||
}
|
||||
|
||||
// Consumer represents a User that is able to consume Consumable items.
|
||||
type Consumer interface {
|
||||
User
|
||||
// Saturate saturates the Consumer's food bar by the amount of food points passed and the saturation by
|
||||
// up to as many saturation points as passed. The final saturation will never exceed the final food level.
|
||||
Saturate(food int, saturation float64)
|
||||
// AddEffect adds an effect.Effect to the Consumer. If the effect is instant, it is applied to the Consumer
|
||||
// immediately. If not, the effect is applied to the consumer every time the Tick method is called.
|
||||
// AddEffect will overwrite any effects present if the level of the effect is higher than the existing one, or
|
||||
// if the effects' levels are equal and the new effect has a longer duration.
|
||||
AddEffect(e effect.Effect)
|
||||
// RemoveEffect removes any effect that might currently be active on the Consumer.
|
||||
RemoveEffect(e effect.Type)
|
||||
// Effects returns any effect currently applied to the Consumer. The returned effects are guaranteed not to have
|
||||
// expired when returned.
|
||||
Effects() []effect.Effect
|
||||
// Absorption returns the absorption health of the Consumer.
|
||||
Absorption() float64
|
||||
// SetAbsorption sets the absorption health of the Consumer. Absorption health is shown as golden hearts and does
|
||||
// not regenerate naturally.
|
||||
SetAbsorption(health float64)
|
||||
}
|
||||
|
||||
// DefaultConsumeDuration is the default duration that consuming an item takes. Dried kelp takes half this
|
||||
// time to be consumed.
|
||||
const DefaultConsumeDuration = (time.Second * 161) / 100
|
||||
|
||||
// Drinkable represents a custom item that can be drunk. It is used to make the client show the correct drinking
|
||||
// animation when a player is using an item. This will only have an effect on non-vanilla items.
|
||||
type Drinkable interface {
|
||||
// Drinkable returns if the item can be drunk or not.
|
||||
Drinkable() bool
|
||||
}
|
||||
|
||||
// Glinted represents a custom item that can have a permanent enchantment glint, this glint is purely cosmetic and
|
||||
// will show regardless of whether it is actually enchanted. An example of this is the enchanted golden apple.
|
||||
type Glinted interface {
|
||||
// Glinted returns whether the item has an enchantment glint.
|
||||
Glinted() bool
|
||||
}
|
||||
|
||||
// HandEquipped represents an item that can be 'hand equipped'. This means the item will show up in third person like
|
||||
// a tool, sword or stick would, giving them a different orientation in the hand and making them slightly bigger.
|
||||
type HandEquipped interface {
|
||||
// HandEquipped returns whether the item is hand equipped.
|
||||
HandEquipped() bool
|
||||
}
|
||||
|
||||
// Weapon is an item that may be used as a weapon. It has an attack damage which may be different to the 2
|
||||
// damage that attacking with an empty hand deals.
|
||||
type Weapon interface {
|
||||
// AttackDamage returns the custom attack damage to the weapon. The damage returned must not be negative.
|
||||
AttackDamage() float64
|
||||
}
|
||||
|
||||
// Cooldown represents an item that has a cooldown.
|
||||
type Cooldown interface {
|
||||
// Cooldown is the duration of the cooldown.
|
||||
Cooldown() time.Duration
|
||||
}
|
||||
|
||||
// nameable represents a block that may be named. These are often containers such as chests, which have a
|
||||
// name displayed in their interface.
|
||||
type nameable interface {
|
||||
// WithName returns the block itself, except with a custom name applied to it.
|
||||
WithName(a ...any) world.Item
|
||||
}
|
||||
|
||||
// Releaser represents an entity that can release items, such as bows.
|
||||
type Releaser interface {
|
||||
User
|
||||
// GameMode returns the gamemode of the releaser.
|
||||
GameMode() world.GameMode
|
||||
// PlaySound plays a world.Sound that only this Releaser can hear.
|
||||
PlaySound(sound world.Sound)
|
||||
}
|
||||
|
||||
// Releasable represents an item that can be released.
|
||||
type Releasable interface {
|
||||
// Release is called when an item is released.
|
||||
Release(releaser Releaser, tx *world.Tx, ctx *UseContext, duration time.Duration)
|
||||
// Requirements returns the required items to release this item.
|
||||
Requirements() []Stack
|
||||
}
|
||||
|
||||
// Chargeable represents an item that can be charged.
|
||||
type Chargeable interface {
|
||||
// Charge is called when an item is being used.
|
||||
Charge(releaser Releaser, tx *world.Tx, ctx *UseContext, duration time.Duration) bool
|
||||
// ContinueCharge continues the charge.
|
||||
ContinueCharge(releaser Releaser, tx *world.Tx, ctx *UseContext, duration time.Duration)
|
||||
// ReleaseCharge is called when an item is being released.
|
||||
ReleaseCharge(releaser Releaser, tx *world.Tx, ctx *UseContext) bool
|
||||
// CanCharge returns whether the item can currently be charged.
|
||||
CanCharge(releaser Releaser, tx *world.Tx, ctx *UseContext) bool
|
||||
}
|
||||
|
||||
// User represents an entity that is able to use an item in the world, typically entities such as players,
|
||||
// which interact with the world using an item.
|
||||
type User interface {
|
||||
Carrier
|
||||
SetHeldItems(mainHand, offHand Stack)
|
||||
|
||||
UsingItem() bool
|
||||
ReleaseItem()
|
||||
UseItem()
|
||||
}
|
||||
|
||||
// Carrier represents an entity that is able to carry an item.
|
||||
type Carrier interface {
|
||||
world.Entity
|
||||
// HeldItems returns the items currently held by the entity. Viewers of the entity will be able to see
|
||||
// these items.
|
||||
HeldItems() (mainHand, offHand Stack)
|
||||
}
|
||||
|
||||
// BeaconPayment represents an item that may be used as payment for a beacon to select effects to be broadcast
|
||||
// to surrounding players.
|
||||
type BeaconPayment interface {
|
||||
PayableForBeacon() bool
|
||||
}
|
||||
|
||||
// Compostable represents an item that may be used to fill up a composter.
|
||||
type Compostable interface {
|
||||
// CompostChance returns the chance the item will produce a layer of compost in the range of 0-1.
|
||||
CompostChance() float64
|
||||
}
|
||||
|
||||
// nopReleasable represents a releasable item that does nothing.
|
||||
type nopReleasable struct{}
|
||||
|
||||
func (nopReleasable) Release(Releaser, *world.Tx, *UseContext, time.Duration) {}
|
||||
func (nopReleasable) Requirements() []Stack {
|
||||
return []Stack{}
|
||||
}
|
||||
|
||||
// defaultFood represents a consumable item with a default consumption duration.
|
||||
type defaultFood struct{}
|
||||
|
||||
// AlwaysConsumable ...
|
||||
func (defaultFood) AlwaysConsumable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ConsumeDuration ...
|
||||
func (d defaultFood) ConsumeDuration() time.Duration {
|
||||
return DefaultConsumeDuration
|
||||
}
|
||||
|
||||
// eyePosition returns the position of the eyes of the entity if the entity implements entity.Eyed, or the
|
||||
// actual position if it doesn't.
|
||||
func eyePosition(e world.Entity) mgl64.Vec3 {
|
||||
pos := e.Position()
|
||||
if eyed, ok := e.(interface{ EyeHeight() float64 }); ok {
|
||||
pos = pos.Add(mgl64.Vec3{0, eyed.EyeHeight()})
|
||||
}
|
||||
return pos
|
||||
}
|
||||
|
||||
// torsoPosition returns the position of the torso of the entity if the entity implements entity.Torsoed, or the
|
||||
// actual position if it doesn't.
|
||||
func torsoPosition(e world.Entity) mgl64.Vec3 {
|
||||
pos := e.Position()
|
||||
if torso, ok := e.(interface{ TorsoHeight() float64 }); ok {
|
||||
pos = pos.Add(mgl64.Vec3{0, torso.TorsoHeight()})
|
||||
}
|
||||
return pos
|
||||
}
|
||||
|
||||
// Int32FromRGBA converts a color.RGBA into an int32. These int32s are present in things such as signs and dyed leather armour.
|
||||
func int32FromRGBA(x color.RGBA) int32 {
|
||||
if x.R == 0 && x.G == 0 && x.B == 0 {
|
||||
// Default to black colour. The default (0x000000) is a transparent colour. Text with this colour will not show
|
||||
// up on the sign.
|
||||
return int32(-0x1000000)
|
||||
}
|
||||
return int32(binary.BigEndian.Uint32([]byte{x.A, x.R, x.G, x.B}))
|
||||
}
|
||||
|
||||
// rgbaFromInt32 converts an int32 into a color.RGBA. These int32s are present in things such as signs and dyed leather armour.
|
||||
func rgbaFromInt32(x int32) color.RGBA {
|
||||
b := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(b, uint32(x))
|
||||
|
||||
return color.RGBA{A: b[0], R: b[1], G: b[2], B: b[3]}
|
||||
}
|
||||
|
||||
// boolByte returns 1 if the bool passed is true, or 0 if it is false.
|
||||
func boolByte(b bool) uint8 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user