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,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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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 }
|
||||
@@ -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() {}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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 }
|
||||
@@ -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() {}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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 }
|
||||
Reference in New Issue
Block a user