github.com/df-mc/dragonfly@v0.9.13/server/world/entity.go (about) 1 package world 2 3 import ( 4 "github.com/df-mc/dragonfly/server/block/cube" 5 "github.com/go-gl/mathgl/mgl64" 6 "golang.org/x/exp/maps" 7 "io" 8 "time" 9 ) 10 11 // Entity represents an entity in the world, typically an object that may be moved around and can be 12 // interacted with by other entities. 13 // Viewers of a world may view an entity when near it. 14 type Entity interface { 15 io.Closer 16 17 // Type returns the EntityType of the Entity. 18 Type() EntityType 19 20 // Position returns the current position of the entity in the world. 21 Position() mgl64.Vec3 22 // Rotation returns the yaw and pitch of the entity in degrees. Yaw is horizontal rotation (rotation around the 23 // vertical axis, 0 when facing forward), pitch is vertical rotation (rotation around the horizontal axis, also 0 24 // when facing forward). 25 Rotation() cube.Rotation 26 // World returns the current world of the entity. This is always the world that the entity can actually be 27 // found in. 28 World() *World 29 } 30 31 // EntityType is the type of Entity. It specifies the name, encoded entity 32 // ID and bounding box of an Entity. 33 type EntityType interface { 34 // EncodeEntity converts the entity to its encoded representation: It 35 // returns the type of the Minecraft entity, for example 36 // 'minecraft:falling_block'. 37 EncodeEntity() string 38 // BBox returns the bounding box of an Entity with this EntityType. 39 BBox(e Entity) cube.BBox 40 } 41 42 // SaveableEntityType is an EntityType that may be saved to disk by decoding 43 // and encoding from/to NBT. 44 type SaveableEntityType interface { 45 EntityType 46 // DecodeNBT reads the fields from the NBT data map passed and converts it 47 // to an Entity of the same EntityType. 48 DecodeNBT(m map[string]any) Entity 49 // EncodeNBT encodes the Entity of the same EntityType passed to a map of 50 // properties that can be encoded to NBT. 51 EncodeNBT(e Entity) map[string]any 52 } 53 54 // TickerEntity represents an entity that has a Tick method which should be called every time the entity is 55 // ticked every 20th of a second. 56 type TickerEntity interface { 57 Entity 58 // Tick ticks the entity with the current World and tick passed. 59 Tick(w *World, current int64) 60 } 61 62 // EntityAction represents an action that may be performed by an entity. Typically, these actions are sent to 63 // viewers in a world so that they can see these actions. 64 type EntityAction interface { 65 EntityAction() 66 } 67 68 // DamageSource represents the source of the damage dealt to an entity. This 69 // source may be passed to the Hurt() method of an entity in order to deal 70 // damage to an entity with a specific source. 71 type DamageSource interface { 72 // ReducedByArmour checks if the source of damage may be reduced if the 73 // receiver of the damage is wearing armour. 74 ReducedByArmour() bool 75 // ReducedByResistance specifies if the Source is affected by the resistance 76 // effect. If false, damage dealt to an entity with this source will not be 77 // lowered if the entity has the resistance effect. 78 ReducedByResistance() bool 79 // Fire specifies if the Source is fire related and should be ignored when 80 // an entity has the fire resistance effect. 81 Fire() bool 82 } 83 84 // HealingSource represents a source of healing for an entity. This source may 85 // be passed to the Heal() method of a living entity. 86 type HealingSource interface { 87 HealingSource() 88 } 89 90 // EntityRegistry is a mapping that EntityTypes may be registered to. It is used 91 // for loading entities from disk in a World's Provider. 92 type EntityRegistry struct { 93 conf EntityRegistryConfig 94 ent map[string]EntityType 95 } 96 97 // EntityRegistryConfig holds functions used by the block and item packages to 98 // create entities as a result of their behaviour. ALL functions of 99 // EntityRegistryConfig must be filled out for the behaviour of these blocks and 100 // items not to fail. 101 type EntityRegistryConfig struct { 102 Item func(it any, pos, vel mgl64.Vec3) Entity 103 FallingBlock func(bl Block, pos mgl64.Vec3) Entity 104 TNT func(pos mgl64.Vec3, fuse time.Duration) Entity 105 BottleOfEnchanting func(pos, vel mgl64.Vec3, owner Entity) Entity 106 Arrow func(pos, vel mgl64.Vec3, rot cube.Rotation, damage float64, owner Entity, critical, disallowPickup, obtainArrowOnPickup bool, punchLevel int, tip any) Entity 107 Egg func(pos, vel mgl64.Vec3, owner Entity) Entity 108 EnderPearl func(pos, vel mgl64.Vec3, owner Entity) Entity 109 Firework func(pos mgl64.Vec3, rot cube.Rotation, attached bool, firework Item, owner Entity) Entity 110 LingeringPotion func(pos, vel mgl64.Vec3, t any, owner Entity) Entity 111 Snowball func(pos, vel mgl64.Vec3, owner Entity) Entity 112 SplashPotion func(pos, vel mgl64.Vec3, t any, owner Entity) Entity 113 Lightning func(pos mgl64.Vec3) Entity 114 } 115 116 // New creates an EntityRegistry using conf and the EntityTypes passed. 117 func (conf EntityRegistryConfig) New(ent []EntityType) EntityRegistry { 118 m := make(map[string]EntityType, len(ent)) 119 for _, e := range ent { 120 name := e.EncodeEntity() 121 if _, ok := m[name]; ok { 122 panic("cannot register the same entity (" + name + ") twice") 123 } 124 m[name] = e 125 } 126 return EntityRegistry{conf: conf, ent: m} 127 } 128 129 // Config returns the EntityRegistryConfig that was used to create the 130 // EntityRegistry. 131 func (reg EntityRegistry) Config() EntityRegistryConfig { 132 return reg.conf 133 } 134 135 // Lookup looks up an EntityType by its name. If found, the EntityType is 136 // returned and the bool is true. The bool is false otherwise. 137 func (reg EntityRegistry) Lookup(name string) (EntityType, bool) { 138 t, ok := reg.ent[name] 139 return t, ok 140 } 141 142 // Types returns all EntityTypes passed upon construction of the EntityRegistry. 143 func (reg EntityRegistry) Types() []EntityType { 144 return maps.Values(reg.ent) 145 }