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

This commit is contained in:
2026-07-09 08:33:57 +08:00
commit 26ed99fda6
845 changed files with 75419 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Absorption is a lasting effect that increases the health of an entity over
// the maximum. Once this extra health is lost, it will not regenerate.
var Absorption absorption
type absorption struct {
nopLasting
}
// Start ...
func (absorption) Start(e world.Entity, lvl int) {
if i, ok := e.(interface {
SetAbsorption(health float64)
}); ok {
i.SetAbsorption(4 * float64(lvl))
}
}
// End ...
func (absorption) End(e world.Entity, _ int) {
if i, ok := e.(interface {
SetAbsorption(health float64)
}); ok {
i.SetAbsorption(0)
}
}
// RGBA ...
func (absorption) RGBA() color.RGBA {
return color.RGBA{R: 0x25, G: 0x52, B: 0xa5, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// Blindness is a lasting effect that greatly reduces the vision range of the
// entity affected.
var Blindness blindness
type blindness struct {
nopLasting
}
// RGBA ...
func (blindness) RGBA() color.RGBA {
return color.RGBA{R: 0x1f, G: 0x1f, B: 0x23, A: 0xff}
}
+28
View File
@@ -0,0 +1,28 @@
package effect
import (
"image/color"
)
// ConduitPower is a lasting effect that grants the affected entity the ability
// to breathe underwater and allows the entity to break faster when underwater
// or in the rain. (Similarly to haste.)
var ConduitPower conduitPower
type conduitPower struct {
nopLasting
}
// Multiplier returns the mining speed multiplier from this effect.
func (conduitPower) Multiplier(lvl int) float64 {
v := 1 - float64(lvl)*0.1
if v < 0 {
v = 0
}
return v
}
// RGBA ...
func (conduitPower) RGBA() color.RGBA {
return color.RGBA{R: 0x1d, G: 0xc2, B: 0xd1, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// Darkness is a lasting effect that causes the player's vision to dim
// occasionally.
var Darkness darkness
type darkness struct {
nopLasting
}
// RGBA ...
func (darkness) RGBA() color.RGBA {
return color.RGBA{R: 0x29, G: 0x27, B: 0x21, A: 0xff}
}
+191
View File
@@ -0,0 +1,191 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
"time"
)
// LastingType represents an effect type that can have a duration. An effect
// can be made using it by calling effect.New with the LastingType.
type LastingType interface {
Type
// Start is called for lasting effects when they are initially added.
Start(e world.Entity, lvl int)
// End is called for lasting effects when they are removed.
End(e world.Entity, lvl int)
}
// Type is an effect implementation that can be applied to an entity.
type Type interface {
// RGBA returns the colour of the effect. If multiple effects are present,
// the colours will be mixed together to form a new colour.
RGBA() color.RGBA
// Apply applies the effect to an entity. Apply is called only once for
// instant effects, such as instantHealth, while it is called every tick for
// lasting effects. The Effect holding the Type is passed along with the
// current tick.
Apply(e world.Entity, eff Effect)
}
// Effect is an effect that can be added to an entity. Effects are either
// instant (applying the effect only once) or lasting (applying the effect
// every tick).
type Effect struct {
t Type
d time.Duration
lvl int
potency float64
ambient, particlesHidden bool
infinite bool
tick int
}
// NewInstant returns a new instant Effect using the Type passed. The effect
// will be applied to an entity once and will expire immediately after.
// NewInstant creates an Effect with a potency of 1.0.
func NewInstant(t Type, lvl int) Effect {
return NewInstantWithPotency(t, lvl, 1)
}
// NewInstantWithPotency returns a new instant Effect using the Type and level
// passed. The effect will be applied to an entity once and expire immediately
// after. The potency passed additionally influences the strength of the effect.
// A higher potency (> 1.0) increases the effect power, while a lower potency
// (< 1.0) reduces it.
func NewInstantWithPotency(t Type, lvl int, potency float64) Effect {
return Effect{t: t, lvl: lvl, potency: potency}
}
// New creates a new Effect using a LastingType passed. Once added to an entity, the time.Duration passed will be ticked down
// by the entity until it reaches a duration of 0.
func New(t LastingType, lvl int, d time.Duration) Effect {
return Effect{t: t, lvl: lvl, d: d}
}
// NewAmbient creates a new ambient (reduced particles, as when using a beacon) Effect using a LastingType passed. Once added
// to an entity, the time.Duration passed will be ticked down by the entity until it reaches a duration of 0.
func NewAmbient(t LastingType, lvl int, d time.Duration) Effect {
return Effect{t: t, lvl: lvl, d: d, ambient: true}
}
// NewInfinite creates a new Effect using a LastingType passed. Once added to an entity, the effect will persist indefinitely,
// until the effect is removed.
func NewInfinite(t LastingType, lvl int) Effect {
return Effect{t: t, lvl: lvl, infinite: true}
}
// WithoutParticles returns the same Effect with particles disabled. Adding the effect to players will not display the
// particles around the player.
func (e Effect) WithoutParticles() Effect {
e.particlesHidden = true
return e
}
// ParticlesHidden returns true if the Effect had its particles hidden by calling WithoutParticles.
func (e Effect) ParticlesHidden() bool {
return e.particlesHidden
}
// Level returns the level of the Effect.
func (e Effect) Level() int {
return e.lvl
}
// Duration returns the leftover duration of the Effect. The duration returned is always 0 if NewInstant or NewInfinite
// were used to create the effect.
func (e Effect) Duration() time.Duration {
return e.d
}
// Ambient returns whether the Effect is an ambient effect, leading to reduced particles shown to the client. False is
// always returned if the Effect was created using New or NewInstant.
func (e Effect) Ambient() bool {
return e.ambient
}
// Infinite returns if the Effect duration is infinite.
func (e Effect) Infinite() bool {
return e.infinite
}
// Type returns the underlying type of the Effect. It is either of the type Type or LastingType, depending on whether it
// was created using New or NewAmbient, or NewInstant.
func (e Effect) Type() Type {
return e.t
}
// TickDuration ticks the effect duration, subtracting time.Second/20 from the leftover time and returning the resulting
// Effect.
func (e Effect) TickDuration() Effect {
if _, ok := e.t.(LastingType); ok {
if !e.Infinite() {
e.d -= time.Second / 20
}
e.tick++
}
return e
}
// Tick returns the current tick of the Effect. This is the number of ticks that
// the Effect has been applied for.
func (e Effect) Tick() int {
return e.tick
}
// nopLasting is a lasting effect with no (server-side) behaviour. It does not implement the RGBA method.
type nopLasting struct{}
func (nopLasting) Apply(world.Entity, Effect) {}
func (nopLasting) End(world.Entity, int) {}
func (nopLasting) Start(world.Entity, int) {}
// ResultingColour calculates the resulting colour of the effects passed and returns a bool specifying if the
// effects were ambient effects, which will cause their particles to display less frequently.
func ResultingColour(effects []Effect) (color.RGBA, bool) {
r, g, b, a, n := 0, 0, 0, 0, 0
ambient := true
for _, e := range effects {
if e.particlesHidden {
// Don't take effects with hidden particles into account for colour
// calculation: Their particles are hidden after all.
continue
}
c := e.Type().RGBA()
r += int(c.R)
g += int(c.G)
b += int(c.B)
a += int(c.A)
n++
if !e.Ambient() {
ambient = false
}
}
if n == 0 {
return color.RGBA{R: 0x38, G: 0x5d, B: 0xc6, A: 0xff}, false
}
return color.RGBA{R: uint8(r / n), G: uint8(g / n), B: uint8(b / n), A: uint8(a / n)}, ambient
}
// living represents a living entity that has health and the ability to move around.
type living interface {
world.Entity
// Health returns the health of the entity.
Health() float64
// MaxHealth returns the maximum health of the entity.
MaxHealth() float64
// SetMaxHealth changes the maximum health of the entity to the value passed.
SetMaxHealth(v float64)
// Hurt hurts the entity for a given amount of damage. The source passed represents the cause of the
// damage, for example entity.AttackDamageSource if the entity is attacked by another entity.
// If the final damage exceeds the health that the player currently has, the entity is killed.
Hurt(damage float64, source world.DamageSource) (n float64, vulnerable bool)
// Heal heals the entity for a given amount of health. The source passed represents the cause of the
// healing, for example entity.FoodHealingSource if the entity healed by having a full food bar. If the health
// added to the original health exceeds the entity's max health, Heal may not add the full amount.
Heal(health float64, source world.HealingSource)
// speed returns the current speed of the living entity. The default value is different for each entity.
Speed() float64
// SetSpeed sets the speed of an entity to a new value.
SetSpeed(float64)
}
+30
View File
@@ -0,0 +1,30 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// FatalPoison is a lasting effect that causes the affected entity to lose
// health gradually. fatalPoison, unlike poison, can kill the entity it is
// applied to.
var FatalPoison fatalPoison
type fatalPoison struct {
nopLasting
}
// Apply ...
func (fatalPoison) Apply(e world.Entity, eff Effect) {
interval := max(50>>(eff.Level()-1), 1)
if eff.Tick()%interval == 0 {
if l, ok := e.(living); ok {
l.Hurt(1, PoisonDamageSource{Fatal: true})
}
}
}
// RGBA ...
func (fatalPoison) RGBA() color.RGBA {
return color.RGBA{R: 0x4e, G: 0x93, B: 0x31, A: 0xff}
}
+17
View File
@@ -0,0 +1,17 @@
package effect
import (
"image/color"
)
// FireResistance is a lasting effect that grants immunity to fire & lava damage.
var FireResistance fireResistance
type fireResistance struct {
nopLasting
}
// RGBA ...
func (fireResistance) RGBA() color.RGBA {
return color.RGBA{R: 0xff, G: 0x99, B: 0x00, A: 0xff}
}
+27
View File
@@ -0,0 +1,27 @@
package effect
import (
"image/color"
)
// Haste is a lasting effect that increases the mining speed of a player by 20%
// for each level of the effect.
var Haste haste
type haste struct {
nopLasting
}
// Multiplier returns the mining speed multiplier from this effect.
func (haste) Multiplier(lvl int) float64 {
v := 1 - float64(lvl)*0.1
if v < 0 {
v = 0
}
return v
}
// RGBA ...
func (haste) RGBA() color.RGBA {
return color.RGBA{R: 0xd9, G: 0xc0, B: 0x43, A: 0xff}
}
+33
View File
@@ -0,0 +1,33 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// HealthBoost causes the affected entity to have its maximum health changed
// for a specific duration.
var HealthBoost healthBoost
type healthBoost struct {
nopLasting
}
// Start ...
func (healthBoost) Start(e world.Entity, lvl int) {
if l, ok := e.(living); ok {
l.SetMaxHealth(l.MaxHealth() + 4*float64(lvl))
}
}
// End ...
func (healthBoost) End(e world.Entity, lvl int) {
if l, ok := e.(living); ok {
l.SetMaxHealth(l.MaxHealth() - 4*float64(lvl))
}
}
// RGBA ...
func (healthBoost) RGBA() color.RGBA {
return color.RGBA{R: 0xf8, G: 0x7d, B: 0x23, A: 0xff}
}
+28
View File
@@ -0,0 +1,28 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Hunger is a lasting effect that causes an affected player to gradually lose
// saturation and food.
var Hunger hunger
type hunger struct {
nopLasting
}
// Apply ...
func (hunger) Apply(e world.Entity, eff Effect) {
if i, ok := e.(interface {
Exhaust(points float64)
}); ok {
i.Exhaust(float64(eff.Level()) * 0.005)
}
}
// RGBA ...
func (hunger) RGBA() color.RGBA {
return color.RGBA{R: 0x58, G: 0x76, B: 0x53, A: 0xff}
}
+35
View File
@@ -0,0 +1,35 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// InstantDamage is an instant effect that causes a living entity to
// immediately take some damage, depending on the level and the potency of the
// effect.
var InstantDamage instantDamage
type instantDamage struct{}
// Apply ...
func (i instantDamage) Apply(e world.Entity, eff Effect) {
base := 3 << eff.Level()
if l, ok := e.(living); ok {
l.Hurt(float64(base)*eff.potency, InstantDamageSource{})
}
}
// RGBA ...
func (instantDamage) RGBA() color.RGBA {
return color.RGBA{R: 0xa9, G: 0x65, B: 0x6a, A: 0xff}
}
// InstantDamageSource is used for damage caused by an effect.instantDamage
// applied to an entity.
type InstantDamageSource struct{}
func (InstantDamageSource) ReducedByArmour() bool { return false }
func (InstantDamageSource) ReducedByResistance() bool { return true }
func (InstantDamageSource) Fire() bool { return false }
func (InstantDamageSource) IgnoreTotem() bool { return false }
+33
View File
@@ -0,0 +1,33 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// InstantHealth is an instant effect that causes the player that it is applied
// to immediately regain some health. The amount of health regained depends on
// the effect level and potency.
var InstantHealth instantHealth
type instantHealth struct{}
// Apply instantly heals the world.Entity passed for a bit of health, depending on the effect level and
// potency.
func (i instantHealth) Apply(e world.Entity, eff Effect) {
base := 2 << eff.Level()
if l, ok := e.(living); ok {
l.Heal(float64(base)*eff.potency, InstantHealingSource{})
}
}
// RGBA ...
func (instantHealth) RGBA() color.RGBA {
return color.RGBA{R: 0xf8, G: 0x24, B: 0x23, A: 0xff}
}
// InstantHealingSource is a healing source used when an entity regains
// health from an effect.instantHealth.
type InstantHealingSource struct{}
func (InstantHealingSource) HealingSource() {}
+40
View File
@@ -0,0 +1,40 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Invisibility is a lasting effect that causes the affected entity to turn
// invisible. While invisible, the entity's armour is still visible and effect
// particles will still be displayed.
var Invisibility invisibility
type invisibility struct {
nopLasting
}
// Start ...
func (invisibility) Start(e world.Entity, _ int) {
if i, ok := e.(interface {
SetInvisible()
SetVisible()
}); ok {
i.SetInvisible()
}
}
// End ...
func (invisibility) End(e world.Entity, _ int) {
if i, ok := e.(interface {
SetInvisible()
SetVisible()
}); ok {
i.SetVisible()
}
}
// RGBA ...
func (invisibility) RGBA() color.RGBA {
return color.RGBA{R: 0xf6, G: 0xf6, B: 0xf6, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// JumpBoost is a lasting effect that causes the affected entity to be able to
// jump much higher, depending on the level of the effect.
var JumpBoost jumpBoost
type jumpBoost struct {
nopLasting
}
// RGBA ...
func (jumpBoost) RGBA() color.RGBA {
return color.RGBA{R: 0xfd, G: 0xff, B: 0x84, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// Levitation is a lasting effect that causes the affected entity to slowly
// levitate upwards. It is roughly the opposite of the slowFalling effect.
var Levitation levitation
type levitation struct {
nopLasting
}
// RGBA ...
func (levitation) RGBA() color.RGBA {
return color.RGBA{R: 0xce, G: 0xff, B: 0xff, A: 0xff}
}
+24
View File
@@ -0,0 +1,24 @@
package effect
import (
"image/color"
"math"
)
// MiningFatigue is a lasting effect that decreases the mining speed of a
// player by 10% for each level of the effect.
var MiningFatigue miningFatigue
type miningFatigue struct {
nopLasting
}
// Multiplier returns the mining speed multiplier from this effect.
func (miningFatigue) Multiplier(lvl int) float64 {
return math.Pow(3, float64(lvl))
}
// RGBA ...
func (miningFatigue) RGBA() color.RGBA {
return color.RGBA{R: 0x4a, G: 0x42, B: 0x17, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// Nausea is a lasting effect that causes the screen to warp, similarly to when
// entering a nether portal.
var Nausea nausea
type nausea struct {
nopLasting
}
// RGBA ...
func (nausea) RGBA() color.RGBA {
return color.RGBA{R: 0x55, G: 0x1d, B: 0x4a, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// NightVision is a lasting effect that causes the affected entity to see in
// dark places as though they were fully lit up.
var NightVision nightVision
type nightVision struct {
nopLasting
}
// RGBA ...
func (nightVision) RGBA() color.RGBA {
return color.RGBA{R: 0xc2, G: 0xff, B: 0x66, A: 0xff}
}
+42
View File
@@ -0,0 +1,42 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Poison is a lasting effect that causes the affected entity to lose health
// gradually. poison cannot kill, unlike fatalPoison.
var Poison poison
type poison struct {
nopLasting
}
// Apply ...
func (poison) Apply(e world.Entity, eff Effect) {
interval := max(50>>(eff.Level()-1), 1)
if eff.Tick()%interval == 0 {
if l, ok := e.(living); ok && l.Health() > 1 {
l.Hurt(1, PoisonDamageSource{})
}
}
}
// RGBA ...
func (poison) RGBA() color.RGBA {
return color.RGBA{R: 0x87, G: 0xa3, B: 0x63, A: 0xff}
}
// PoisonDamageSource is used for damage caused by an effect.poison or
// effect.fatalPoison applied to an entity.
type PoisonDamageSource struct {
// Fatal specifies if the damage was caused by effect.fatalPoison and if
// the damage could therefore kill the entity.
Fatal bool
}
func (PoisonDamageSource) ReducedByResistance() bool { return true }
func (PoisonDamageSource) ReducedByArmour() bool { return false }
func (PoisonDamageSource) Fire() bool { return false }
func (PoisonDamageSource) IgnoreTotem() bool { return false }
+36
View File
@@ -0,0 +1,36 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Regeneration is an effect that causes the entity that it is added to slowly
// regenerate health. The level of the effect influences the speed with which
// the entity regenerates.
var Regeneration regeneration
type regeneration struct {
nopLasting
}
// Apply applies health to the world.Entity passed if the duration of the effect is at the right tick.
func (regeneration) Apply(e world.Entity, eff Effect) {
interval := max(50>>(eff.Level()-1), 1)
if eff.Tick()%interval == 0 {
if l, ok := e.(living); ok {
l.Heal(1, RegenerationHealingSource{})
}
}
}
// RGBA ...
func (regeneration) RGBA() color.RGBA {
return color.RGBA{R: 0xcd, G: 0x5c, B: 0xab, A: 0xff}
}
// RegenerationHealingSource is a healing source used when an entity regenerates
// health from an effect.regeneration.
type RegenerationHealingSource struct{}
func (RegenerationHealingSource) HealingSource() {}
+62
View File
@@ -0,0 +1,62 @@
package effect
// Register registers an Effect with a specific ID to translate from and to on disk and network. An Effect
// instance may be created by creating a struct instance in this package like
// effect.regeneration{}.
func Register(id int, e Type) {
effects[id] = e
effectIds[e] = id
}
// init registers all implemented effects.
func init() {
Register(1, Speed)
Register(2, Slowness)
Register(3, Haste)
Register(4, MiningFatigue)
Register(5, Strength)
Register(6, InstantHealth)
Register(7, InstantDamage)
Register(8, JumpBoost)
Register(9, Nausea)
Register(10, Regeneration)
Register(11, Resistance)
Register(12, FireResistance)
Register(13, WaterBreathing)
Register(14, Invisibility)
Register(15, Blindness)
Register(16, NightVision)
Register(17, Hunger)
Register(18, Weakness)
Register(19, Poison)
Register(20, Wither)
Register(21, HealthBoost)
Register(22, Absorption)
Register(23, Saturation)
Register(24, Levitation)
Register(25, FatalPoison)
Register(26, ConduitPower)
Register(27, SlowFalling)
// TODO: (28) Bad omen. (Requires villages ...)
// TODO: (29) Hero of the village. (Requires villages ...)
Register(30, Darkness)
}
var (
effects = map[int]Type{}
effectIds = map[Type]int{}
)
// ByID attempts to return an effect by the ID it was registered with. If found, the effect found
// is returned and the bool true.
func ByID(id int) (Type, bool) {
effect, ok := effects[id]
return effect, ok
}
// ID attempts to return the ID an effect was registered with. If found, the id is returned and
// the bool true.
func ID(e Type) (int, bool) {
id, ok := effectIds[e]
return id, ok
}
+30
View File
@@ -0,0 +1,30 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Resistance is a lasting effect that reduces the damage taken from any
// sources except for void damage or custom damage.
var Resistance resistance
type resistance struct {
nopLasting
}
// Multiplier returns a damage multiplier for the damage source passed.
func (resistance) Multiplier(e world.DamageSource, lvl int) float64 {
if !e.ReducedByResistance() {
return 1
}
if v := 1 - 0.2*float64(lvl); v >= 0 {
return v
}
return 0
}
// RGBA ...
func (resistance) RGBA() color.RGBA {
return color.RGBA{R: 0x91, G: 0x46, B: 0xf0, A: 0xff}
}
+28
View File
@@ -0,0 +1,28 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Saturation is a lasting effect that causes the affected player to regain
// food and saturation.
var Saturation saturation
type saturation struct {
nopLasting
}
// Apply ...
func (saturation) Apply(e world.Entity, eff Effect) {
if i, ok := e.(interface {
Saturate(food int, saturation float64)
}); ok {
i.Saturate(eff.Level(), 2*float64(eff.Level()))
}
}
// RGBA ...
func (saturation) RGBA() color.RGBA {
return color.RGBA{R: 0xf8, G: 0x24, B: 0x23, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// SlowFalling is a lasting effect that causes the affected entity to fall very
// slowly.
var SlowFalling slowFalling
type slowFalling struct {
nopLasting
}
// RGBA ...
func (slowFalling) RGBA() color.RGBA {
return color.RGBA{R: 0xf3, G: 0xcf, B: 0xb9, A: 0xff}
}
+41
View File
@@ -0,0 +1,41 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Slowness is a lasting effect that decreases the movement speed of a living
// entity by 15% for each level that the effect has.
var Slowness slowness
type slowness struct {
nopLasting
}
// Start ...
func (slowness) Start(e world.Entity, lvl int) {
slowness := 1 - float64(lvl)*0.15
if slowness <= 0 {
slowness = 0.00001
}
if l, ok := e.(living); ok {
l.SetSpeed(l.Speed() * slowness)
}
}
// End ...
func (slowness) End(e world.Entity, lvl int) {
slowness := 1 - float64(lvl)*0.15
if slowness <= 0 {
slowness = 0.00001
}
if l, ok := e.(living); ok {
l.SetSpeed(l.Speed() / slowness)
}
}
// RGBA ...
func (slowness) RGBA() color.RGBA {
return color.RGBA{R: 0x8b, G: 0xaf, B: 0xe0, A: 0xff}
}
+35
View File
@@ -0,0 +1,35 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Speed is a lasting effect that increases the speed of an entity by 20% for
// each level that the effect has.
var Speed speed
type speed struct {
nopLasting
}
// Start ...
func (speed) Start(e world.Entity, lvl int) {
speed := 1 + float64(lvl)*0.2
if l, ok := e.(living); ok {
l.SetSpeed(l.Speed() * speed)
}
}
// End ...
func (speed) End(e world.Entity, lvl int) {
speed := 1 + float64(lvl)*0.2
if l, ok := e.(living); ok {
l.SetSpeed(l.Speed() / speed)
}
}
// RGBA ...
func (speed) RGBA() color.RGBA {
return color.RGBA{R: 0x33, G: 0xeb, B: 0xff, A: 0xff}
}
+23
View File
@@ -0,0 +1,23 @@
package effect
import (
"image/color"
)
// Strength is a lasting effect that increases the damage dealt with melee
// attacks when applied to an entity.
var Strength strength
type strength struct {
nopLasting
}
// Multiplier returns the damage multiplier of the effect.
func (strength) Multiplier(lvl int) float64 {
return 0.3 * float64(lvl)
}
// RGBA ...
func (strength) RGBA() color.RGBA {
return color.RGBA{R: 0xff, G: 0xc7, B: 0x00, A: 0xff}
}
+18
View File
@@ -0,0 +1,18 @@
package effect
import (
"image/color"
)
// WaterBreathing is a lasting effect that allows the affected entity to breath
// underwater until the effect expires.
var WaterBreathing waterBreathing
type waterBreathing struct {
nopLasting
}
// RGBA ...
func (waterBreathing) RGBA() color.RGBA {
return color.RGBA{R: 0x98, G: 0xda, B: 0xc0, A: 0xff}
}
+27
View File
@@ -0,0 +1,27 @@
package effect
import (
"image/color"
)
// Weakness is a lasting effect that reduces the damage dealt to other entities
// with melee attacks.
var Weakness weakness
type weakness struct {
nopLasting
}
// Multiplier returns the damage multiplier of the effect.
func (weakness) Multiplier(lvl int) float64 {
v := 0.2 * float64(lvl)
if v > 1 {
v = 1
}
return v
}
// RGBA ...
func (weakness) RGBA() color.RGBA {
return color.RGBA{R: 0x48, G: 0x4d, B: 0x48, A: 0xff}
}
+38
View File
@@ -0,0 +1,38 @@
package effect
import (
"github.com/df-mc/dragonfly/server/world"
"image/color"
)
// Wither is a lasting effect that causes an entity to take continuous damage
// that is capable of killing an entity.
var Wither wither
type wither struct {
nopLasting
}
// Apply ...
func (wither) Apply(e world.Entity, eff Effect) {
interval := max(80>>eff.Level(), 1)
if eff.Tick()%interval == 0 {
if l, ok := e.(living); ok {
l.Hurt(1, WitherDamageSource{})
}
}
}
// RGBA ...
func (wither) RGBA() color.RGBA {
return color.RGBA{R: 0x73, G: 0x61, B: 0x56, A: 0xff}
}
// WitherDamageSource is used for damage caused by an effect.wither applied
// to an entity.
type WitherDamageSource struct{}
func (WitherDamageSource) ReducedByResistance() bool { return true }
func (WitherDamageSource) ReducedByArmour() bool { return false }
func (WitherDamageSource) Fire() bool { return false }
func (WitherDamageSource) IgnoreTotem() bool { return false }